From a793830d8d23310e74c811c0660fb941bd5942ea Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Mon, 9 Oct 2017 21:08:27 +1300 Subject: [PATCH] Moving track info to it's own view --- src/js/components/Modal/Modal.js | 42 ++++-- src/js/components/Modal/TrackInfoModal.js | 58 -------- src/js/components/PlaybackControls.js | 13 +- src/js/index.js | 2 + src/js/views/Queue.js | 3 +- src/js/views/Track.js | 173 ++++++++++++++++++++++ src/scss/components/_modal.scss | 31 ++-- 7 files changed, 226 insertions(+), 96 deletions(-) delete mode 100755 src/js/components/Modal/TrackInfoModal.js create mode 100755 src/js/views/Track.js diff --git a/src/js/components/Modal/Modal.js b/src/js/components/Modal/Modal.js index f547e84e..bb0ca177 100755 --- a/src/js/components/Modal/Modal.js +++ b/src/js/components/Modal/Modal.js @@ -2,6 +2,7 @@ import React, { PropTypes } from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' +import FontAwesome from 'react-fontawesome' import * as helpers from '../../helpers' import Icon from '../Icon' @@ -16,14 +17,12 @@ import SearchURISchemesModal from './SearchURISchemesModal' import VolumeModal from './VolumeModal' import AuthorizationModal_Send from './AuthorizationModal_Send' import AuthorizationModal_Receive from './AuthorizationModal_Receive' -import TrackInfoModal from './TrackInfoModal' import * as coreActions from '../../services/core/actions' import * as uiActions from '../../services/ui/actions' import * as mopidyActions from '../../services/mopidy/actions' import * as spotifyActions from '../../services/spotify/actions' import * as pusherActions from '../../services/pusher/actions' -import * as geniusActions from '../../services/genius/actions' class Modal extends React.Component{ @@ -39,14 +38,38 @@ class Modal extends React.Component{ } } + toggleFullscreen(){ + let app = document.documentElement + if (app.requestFullscreen){ + app.requestFullscreen() + } else if (app.webkitRequestFullscreen){ + app.webkitRequestFullscreen() + } else if (app.mozRequestFullScreen){ + app.mozRequestFullScreen() + } else if (app.msRequestFullscreen){ + app.msRequestFullscreen() + } + } + render(){ - if( !this.props.modal ) return null; + if (!this.props.modal){ + return null; + } + + var can_fullscreen = false; + if (this.props.modal.name == 'kiosk_mode'){ + can_fullscreen = true; + } return (
-
this.props.uiActions.closeModal() }> - + +
+
this.props.uiActions.closeModal()}> + +
+
{ this.props.modal.name == 'add_to_playlist' ? : null } - { this.props.modal.name == 'track_info' ? : null } -
); @@ -154,8 +171,7 @@ const mapDispatchToProps = (dispatch) => { uiActions: bindActionCreators(uiActions, dispatch), pusherActions: bindActionCreators(pusherActions, dispatch), spotifyActions: bindActionCreators(spotifyActions, dispatch), - mopidyActions: bindActionCreators(mopidyActions, dispatch), - geniusActions: bindActionCreators(geniusActions, dispatch) + mopidyActions: bindActionCreators(mopidyActions, dispatch) } } diff --git a/src/js/components/Modal/TrackInfoModal.js b/src/js/components/Modal/TrackInfoModal.js deleted file mode 100755 index 7a4977f0..00000000 --- a/src/js/components/Modal/TrackInfoModal.js +++ /dev/null @@ -1,58 +0,0 @@ - -import React, { PropTypes } from 'react' -import FontAwesome from 'react-fontawesome' - -import Icon from '../Icon' -import ArtistSentence from '../ArtistSentence' -import * as helpers from '../../helpers' - -export default class TrackInfoModal extends React.Component{ - - constructor(props){ - super(props) - } - - componentDidMount(){ - if (this.props.current_track && !this.props.current_track.lyrics){ - this.props.geniusActions.getTrackLyrics(this.props.current_track); - } - } - - componentWillReceiveProps(nextProps){ - if (nextProps.current_track && nextProps.current_track.uri !== this.props.current_track.uri && !nextProps.current_track.lyrics){ - this.props.geniusActions.getTrackLyrics(nextProps.current_track); - } - } - - renderLyrics(track){ - if (helpers.isLoading(this.props.load_queue,['genius_'])){ - return ( -
-
-
- ); - } else if (!track){ - return
Could not load track
- } else if (!track.lyrics){ - return
No lyrics available
- } else { - return
- } - } - - render(){ - if (this.props.current_track){ - var track = this.props.current_track; - } else { - var track = null - } - - return ( -
-

Track info

- {track ?

{track.name} by

: null} - {this.renderLyrics(track)} -
- ) - } -} \ No newline at end of file diff --git a/src/js/components/PlaybackControls.js b/src/js/components/PlaybackControls.js index 7328adc3..681230d6 100755 --- a/src/js/components/PlaybackControls.js +++ b/src/js/components/PlaybackControls.js @@ -59,18 +59,7 @@ class PlaybackControls extends React.Component{ handleThumbnailClick(e){ e.preventDefault(); - this.props.uiActions.openModal('kiosk_mode') - - let app = document.documentElement - if (app.requestFullscreen){ - app.requestFullscreen() - } else if (app.webkitRequestFullscreen){ - app.webkitRequestFullscreen() - } else if (app.mozRequestFullScreen){ - app.mozRequestFullScreen() - } else if (app.msRequestFullscreen){ - app.msRequestFullscreen() - } + this.props.uiActions.openModal('kiosk_mode'); } render(){ diff --git a/src/js/index.js b/src/js/index.js index 45c10293..718c037d 100755 --- a/src/js/index.js +++ b/src/js/index.js @@ -17,6 +17,7 @@ import Album from './views/Album' import Artist from './views/Artist' import Playlist from './views/Playlist' import User from './views/User' +import Track from './views/Track' import Queue from './views/Queue' import QueueHistory from './views/QueueHistory' import Settings from './views/Settings' @@ -70,6 +71,7 @@ ReactDOM.render( + diff --git a/src/js/views/Queue.js b/src/js/views/Queue.js index 031f7fb0..c5e53e9e 100755 --- a/src/js/views/Queue.js +++ b/src/js/views/Queue.js @@ -119,8 +119,7 @@ class Queue extends React.Component{
{ this.renderArtwork(image) }
- {this.props.current_track ? this.props.current_track.name : -} -   this.props.uiActions.openModal('track_info')} /> + {this.props.current_track ? {this.props.current_track.name} : -}
{this.props.current_track ? : }
diff --git a/src/js/views/Track.js b/src/js/views/Track.js new file mode 100755 index 00000000..dd8d2305 --- /dev/null +++ b/src/js/views/Track.js @@ -0,0 +1,173 @@ + +import React, { PropTypes } from 'react' +import { connect } from 'react-redux' +import { bindActionCreators } from 'redux' +import FontAwesome from 'react-fontawesome' + +import Header from '../components/Header' +import TrackList from '../components/TrackList' +import Thumbnail from '../components/Thumbnail' +import Parallax from '../components/Parallax' +import ArtistSentence from '../components/ArtistSentence' +import ArtistGrid from '../components/ArtistGrid' +import FollowButton from '../components/FollowButton' +import Dater from '../components/Dater' +import LazyLoadListener from '../components/LazyLoadListener' +import ContextMenuTrigger from '../components/ContextMenuTrigger' + +import * as helpers from '../helpers' +import * as uiActions from '../services/ui/actions' +import * as mopidyActions from '../services/mopidy/actions' +import * as spotifyActions from '../services/spotify/actions' +import * as geniusActions from '../services/genius/actions' + +class Track extends React.Component{ + + constructor(props) { + super(props); + } + + componentDidMount(){ + this.loadTrack(); + } + + handleContextMenu(e){ + e.preventDefault() + var data = { uris: [this.props.params.uri] } + this.props.uiActions.showContextMenu( e, data, 'track', 'click' ) + } + + componentWillReceiveProps( nextProps ){ + + // if our URI has changed, fetch new album + if( nextProps.params.uri != this.props.params.uri ){ + this.loadTrack( nextProps ) + + // if mopidy has just connected AND we're a local album, go get + } else if (!this.props.mopidy_connected && nextProps.mopidy_connected){ + if( helpers.uriSource( this.props.params.uri ) != 'spotify' ){ + this.loadTrack( nextProps ) + } + } else if (!nextProps.track.lyrics && nextProps.track.artists && !this.props.track.artists){ + this.props.geniusActions.getTrackLyrics(nextProps.track); + } + } + + handleContextMenu(e){ + var data = { + e: e, + context: 'track', + items: [this.props.track], + uris: [this.props.params.uri] + } + this.props.uiActions.showContextMenu(data) + } + + loadTrack( props = this.props ){ + switch (helpers.uriSource(props.params.uri)){ + + case 'spotify': + if (props.track){ + console.info('Loading track from index') + }else{ + this.props.spotifyActions.getTrack( props.params.uri ); + } + break; + } + } + + play(){ + this.props.mopidyActions.playURIs([this.props.params.uri], this.props.params.uri) + } + + renderLyrics(){ + if (helpers.isLoading(this.props.load_queue,['genius_'])){ + return ( +
+
+
+ ); + } else if (!this.props.track.lyrics){ + return
No lyrics available
+ } else { + return
+ } + } + + render(){ + if (helpers.isLoading(this.props.load_queue,['spotify_track/'+helpers.getFromUri('trackid',this.props.params.uri)])){ + return ( +
+
+
+ ) + } + + if (!this.props.track){ + return null + } + + return ( +
+ + {this.props.slim_mode ?
this.handleContextMenu(e)} uiActions={this.props.uiActions} /> : null} + +
+ +
+ +
+ +

{ this.props.track.name }

+ +
    + { !this.props.slim_mode ?
  • {helpers.uriSource( this.props.params.uri )} track
  • : null } +
  • +
+
+ +
+ + {this.props.slim_mode ? null : this.handleContextMenu(e)} />} +
+ + {this.renderLyrics()} + +
+ ) + } +} + + +/** + * Export our component + * + * We also integrate our global store, using connect() + **/ + +const mapStateToProps = (state, ownProps) => { + return { + slim_mode: state.ui.slim_mode, + load_queue: state.ui.load_queue, + track: (state.core.tracks && state.core.tracks[ownProps.params.uri] !== undefined ? state.core.tracks[ownProps.params.uri] : false), + tracks: state.core.tracks, + artists: state.core.artists, + albums: state.core.albums, + spotify_library_albums: state.spotify.library_albums, + local_library_albums: state.mopidy.library_albums, + spotify_authorized: state.spotify.authorization, + mopidy_connected: state.mopidy.connected + }; +} + +const mapDispatchToProps = (dispatch) => { + return { + uiActions: bindActionCreators(uiActions, dispatch), + uiActions: bindActionCreators(uiActions, dispatch), + mopidyActions: bindActionCreators(mopidyActions, dispatch), + spotifyActions: bindActionCreators(spotifyActions, dispatch), + geniusActions: bindActionCreators(geniusActions, dispatch) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(Track) \ No newline at end of file diff --git a/src/scss/components/_modal.scss b/src/scss/components/_modal.scss index e29490a9..656be70d 100755 --- a/src/scss/components/_modal.scss +++ b/src/scss/components/_modal.scss @@ -15,27 +15,36 @@ background: $overlay_dark; overflow-y: scroll; - .close-modal { - @include animate(); + .controls { position: absolute; top: 10px; right: 10px; - opacity: 0.5; - cursor: pointer; - padding: 20px; z-index: 99; - img { - width: 30px; - } + .control { + @include animate(); + display: block; + float: right; + opacity: 0.5; + cursor: pointer; + padding: 20px; - &:hover { - opacity: 1; + img { + width: 30px; + } + + &:hover { + opacity: 1; + } + + .fa { + font-size: 24px; + } } } .content { - padding: 10vh 25%; + padding: 80px 25%; margin: 0 auto; width: 50%; color: $white;