| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- import React from 'react';
- import { Switch, Route } from 'react-router-dom'
- import logo from './chad-logo-256.png';
- import './App.css';
- import Selector from './Selector.js';
- import Player from './Player.js';
- import Playlist from './Playlist.js';
- import Sound from 'react-sound';
- import MediaSession from './MediaSession.js';
- const fetchOpts = { credentials: 'same-origin' }
- class App extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- sound: {url: '', playStatus: Sound.status.STOPPED},
- activeTrack: -1,
- };
- }
- activateTrack(activeTrack) {
- if (!Array.isArray(this.state.tracks)) {
- return;
- }
- if (activeTrack < 0 || activeTrack >= this.state.tracks.length) {
- activeTrack = -1;
- }
- this.setState({activeTrack})
- }
- componentDidUpdate(prevProps, prevState) {
- const {activeTrack} = this.state;
- if (activeTrack !== prevState.activeTrack) {
- if (activeTrack !== -1 && Array.isArray(this.state.tracks)) {
- const track = this.state.tracks[activeTrack];
- if (!track) {
- console.log('Bad activeTrack', this.state.tracks, activeTrack);
- } else {
- this.setState({
- sound: {
- url: track.url,
- position: 0,
- playStatus: Sound.status.PLAYING
- },
- metadata: {
- title: track.title,
- artist: track.artist,
- album: track.album.album,
- cover: track.album.cover
- }
- })
- }
- } else {
- this.setState({
- sound: {url: '', position: 0, playStatus: Sound.status.STOPPED},
- metadata: null
- })
- }
- }
- }
- handleActivateTrack = (activeTrack) => this.activateTrack(activeTrack)
- handleControlPrev = () => this.activateTrack(this.state.activeTrack - 1)
- handleControlNext = () => this.activateTrack(this.state.activeTrack + 1)
- handleControlPlayPause = () => {
- const playStatus = (this.state.sound.playStatus === Sound.status.PLAYING
- ? Sound.status.PAUSED
- : Sound.status.PLAYING);
- this.setState({sound: Object.assign({}, this.state.sound, {playStatus: playStatus})});
- }
- handleControlStop = () => {
- this.setState({
- sound: Object.assign({}, this.state.sound, {
- playStatus: Sound.status.STOPPED,
- position: 0}),
- activeTrack: -1});
- }
- handleSoundError = (errorCode, description) => {
- console.log('sound error', errorCode, description)
- // try next track, TODO: better error handling
- this.handleControlNext();
- }
- handleSoundPlaying = (sound) => {
- this.setState({sound: Object.assign({}, this.state.sound, {
- position: sound.position,
- duration: sound.duration
- })})
- }
- handleSoundFinished = () => {
- console.log('sound finished');
- this.setState({sound: Object.assign({}, this.state.sound, {playStatus: Sound.status.STOPPED})});
- this.handleControlNext();
- }
- fetchAlbumTracks(album) {
- return fetch(`/album/${album.id}/tracks`, fetchOpts)
- .then(res => (res.ok ? res.json() : Promise.reject({message:res.statusText})))
- .then(tracks => tracks.map(t => Object.assign(t, {album})))
- }
- onPlayAlbum = (album) => {
- this.fetchAlbumTracks(album)
- .then(tracks => this.setState({tracks, activeTrack: 0}))
- .catch(error => this.setState({tracks: error.message}));
- this.setState({tracks: "Loading"})
- }
- render() {
- const playlist = (<Playlist
- open={this.state.playlistOpen}
- tracks={this.state.tracks}
- activeTrack={this.state.activeTrack}
- onActivateTrack={this.handleActivateTrack} />)
- const selector = (<Selector onPlayAlbum={this.onPlayAlbum} />)
- return (
- <div className="App">
- <header className="App-header">
- <img src={logo} className="App-logo" alt="logo" />
- <h1 className="App-title">Chad Music</h1>
- </header>
- <Switch>
- <Route exact path="/" render={() => selector} />
- <Route path="/playlist" render={() => playlist} />
- </Switch>
- <Player
- {...this.state.sound}
- {...this.state.metadata}
- onPlaylistToggle={() => this.setState({playlistOpen: !this.state.playlistOpen})}
- onPrev={this.handleControlPrev}
- onPlayPause={this.handleControlPlayPause}
- onStop={this.handleControlStop}
- onNext={this.handleControlNext} />
- <Sound {...this.state.sound}
- onError={this.handleSoundError}
- onLoading={this.handleSoundLoading}
- onPlaying={this.handleSoundPlaying}
- onFinishedPlaying={this.handleSoundFinished} />
- <MediaSession
- {...this.state.metadata}
- onPlay={this.handleControlPlayPause}
- onPause={this.handleControlPlayPause}
- onPreviousTrack={this.handleControlPrev}
- onNextTrack={this.handleControlNext}
- />
- </div>
- );
- }
- }
- export default App;
|