From 902b9cf58ce5a1c2ecf84c01f924774394e31894 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Wed, 1 Feb 2017 10:10:31 +1300 Subject: [PATCH] Radio edit modal --- src/js/components/DebugInfo.js | 3 + src/js/components/Modal/EditRadioModal.js | 103 ++++++++++++---------- src/js/components/Modal/Modal.js | 4 +- src/js/services/spotify/actions.js | 45 +++------- src/js/services/ui/reducer.js | 32 +++++++ src/scss/components/_modal.scss | 19 ++-- src/scss/global/_forms.scss | 14 +++ 7 files changed, 134 insertions(+), 86 deletions(-) diff --git a/src/js/components/DebugInfo.js b/src/js/components/DebugInfo.js index 97473e3c..ad58a8d4 100755 --- a/src/js/components/DebugInfo.js +++ b/src/js/components/DebugInfo.js @@ -32,6 +32,9 @@ class DebugInfo extends React.Component{
{this.props.ui.playlists ? Object.keys(this.props.ui.playlists).length : '0'} playlists
+
+ {this.props.ui.tracks ? Object.keys(this.props.ui.tracks).length : '0'} tracks +
{this.props.ui.users ? Object.keys(this.props.ui.users).length : '0'} users
diff --git a/src/js/components/Modal/EditRadioModal.js b/src/js/components/Modal/EditRadioModal.js index 215f563e..2e8ebe2b 100755 --- a/src/js/components/Modal/EditRadioModal.js +++ b/src/js/components/Modal/EditRadioModal.js @@ -12,8 +12,7 @@ export default class EditRadioModal extends React.Component{ this.state = { enabled: false, seeds: [], - uri: '', - uri_validated: false + uri: '' } } @@ -21,15 +20,8 @@ export default class EditRadioModal extends React.Component{ if (!this.props.radio || !this.props.radio.enabled) return null var seeds = [...this.props.radio.seed_tracks, ...this.props.radio.seed_artists, ...this.props.radio.seed_genres] this.setState({seeds: seeds, enabled: this.props.radio.enabled}) - } - handleChange(uri){ - this.setState({uri: uri}) - - var allowed_types = ['artist','track'] - if (allowed_types.indexOf(helpers.uriType(uri)) > -1){ - this.setState({uri_validated: true}) - } + this.props.spotifyActions.resolveRadioSeeds(this.props.radio) } save(){ @@ -43,60 +35,77 @@ export default class EditRadioModal extends React.Component{ } addSeed(){ - if (!this.state.uri_validated || this.state.uri == '') return null + if (this.state.uri == '') return null var seeds = Object.assign([],this.state.seeds) + var uris = this.state.uri.split(',') - if (seeds.indexOf(this.state.uri) <= -1){ - seeds.push(this.state.uri) - } else { - this.props.uiActions.createNotification('Seed already exists','bad') + for (var i = 0; i < uris.length; i++){ + if (seeds.indexOf(uris[i]) <= -1){ + seeds.push(uris[i]) + } else { + this.props.uiActions.createNotification(uris[i]+' already added','bad') + } } // commit to state this.setState({ seeds: seeds, - uri: '', - uri_validated: false + uri: '' }) } removeSeed(uri){ - var seeds = Object.assign([],this.state.seeds) - var index = seeds.indexOf(uri) - if (index > -1){ - delete seeds[index] - this.setState({seeds: seeds}) + var seeds = [] + for (var i = 0; i < this.state.seeds.length; i++){ + if (this.state.seeds[i] != uri){ + seeds.push(this.state.seeds[i]) + } } + this.setState({seeds: seeds}) } renderSeeds(){ -/* - var seeds = this.props.radio.resolved_seeds - var uri - var seeds = [] - for (var i = 0; i < this.props.radio.seed_tracks.length; i++){ - var uri = this.props.radio.seed_tracks[i] - if (this.props.radio.resolved_seeds.hasOwnProperty(uri)){ - seeds.push(this.props.radio.resolved_seeds[uri]) + + if (this.state.enabled && this.state.seeds){ + for (var i = 0; i < this.state.seeds.length; i++){ + var uri = this.state.seeds[i] + if (uri){ + if (helpers.uriType(uri) == 'artist' && this.props.artists){ + if (this.props.artists.hasOwnProperty(uri)){ + seeds.push(this.props.artists[uri]) + } else { + seeds.push({ + type: 'artist', + unresolved: true, + uri: uri + }) + } + } else if (helpers.uriType(uri) == 'track' && this.props.tracks){ + if (this.props.tracks.hasOwnProperty(uri)){ + seeds.push(this.props.tracks[uri]) + } else { + seeds.push({ + type: 'track', + unresolved: true, + uri: uri + }) + } + } + } } } - for (var i = 0; i < this.props.radio.seed_artists.length; i++){ - var uri = this.props.radio.seed_artists[i] - if (this.props.radio.resolved_seeds.hasOwnProperty(uri)){ - seeds.push(this.props.radio.resolved_seeds[uri]) - } - }*/ return (
{ - this.state.seeds.map((seed,index) => { + seeds.map((seed,index) => { return ( -
- {seed} - this.removeSeed(seed)} /> +
+ {seed.unresolved ? {seed.uri} : {seed.name} } +  ({seed.type}) + this.removeSeed(seed.uri)} />
) }) @@ -126,19 +135,21 @@ export default class EditRadioModal extends React.Component{ return (

Edit radio

-
+

Current seeds

+ {this.renderSeeds()} + + +

Add seeds

this.handleChange(e.target.value)} + placeholder="Comma-separated URIs" + onChange={e => this.setState({uri: e.target.value})} value={this.state.uri} /> - +
- {this.renderSeeds()} -
{this.renderActions()}
diff --git a/src/js/components/Modal/Modal.js b/src/js/components/Modal/Modal.js index 0d81ed11..f150a217 100755 --- a/src/js/components/Modal/Modal.js +++ b/src/js/components/Modal/Modal.js @@ -37,7 +37,7 @@ class Modal extends React.Component{ { this.props.modal.name == 'create_playlist' ? : null } { this.props.modal.name == 'edit_playlist' ? : null } { this.props.modal.name == 'send_authorization' ? : null } - { this.props.modal.name == 'edit_radio' ? : null } + { this.props.modal.name == 'edit_radio' ? : null } { this.props.modal.name == 'image_zoom' ? : null }
@@ -50,6 +50,8 @@ const mapStateToProps = (state, ownProps) => { return { modal: state.ui.modal, radio: state.ui.radio, + tracks: state.ui.tracks, + artists: state.ui.artists, playlists: state.ui.playlists, context_menu: state.ui.context_menu, mopidy_connected: state.mopidy.connected, diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index e8367d71..85a78b30 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -495,12 +495,6 @@ export function following(uri, method = 'GET'){ export function resolveRadioSeeds( radio ){ return (dispatch, getState) => { - // flush out the previous store value - dispatch({ type: 'RADIO_SEEDS_RESOLVING' }); - - var resolved_seeds = {} - var requests = [] - if (radio.seed_artists.length > 0){ var artist_ids = ''; for (var i = 0; i < radio.seed_artists.length; i++){ @@ -508,16 +502,14 @@ export function resolveRadioSeeds( radio ){ artist_ids += helpers.getFromUri('artistid', radio.seed_artists[i]) } - // add to our list of async requests - requests.push( - sendRequest( dispatch, getState, 'artists/'+ artist_ids ) - .then( response => { - if (!(response instanceof Array)) response = [response] - for (var i = 0; i < response.length; i++){ - resolved_seeds[response[i].uri] = response[i] - } + sendRequest( dispatch, getState, 'artists/'+ artist_ids ) + .then( response => { + if (!(response instanceof Array)) response = [response] + dispatch({ + type: 'ARTISTS_LOADED', + artists: response }) - ) + }) } if (radio.seed_tracks.length > 0){ @@ -527,25 +519,14 @@ export function resolveRadioSeeds( radio ){ track_ids += helpers.getFromUri('trackid', radio.seed_tracks[i]) } - // add to our list of async requests - requests.push( - sendRequest( dispatch, getState, 'tracks?ids='+ track_ids ) - .then( response => { - for (var i = 0; i < response.tracks.length; i++){ - resolved_seeds[response.tracks[i].uri] = response.tracks[i] - } + sendRequest( dispatch, getState, 'tracks?ids='+ track_ids ) + .then( response => { + dispatch({ + type: 'TRACKS_LOADED', + tracks: response.tracks }) - ) + }) } - - $.when.apply( - $, requests - ).then( () => { - dispatch({ - type: 'RADIO_SEEDS_RESOLVED', - resolved_seeds: resolved_seeds - }); - }); } } diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index ef516a5e..9730f6f3 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -357,6 +357,38 @@ export default function reducer(ui = {}, action){ + /** + * Tracks + **/ + + case 'TRACK_LOADED': + var tracks = Object.assign([], ui.tracks) + + if (tracks[action.key]){ + var track = Object.assign({}, tracks[action.key], action.track) + }else{ + var track = Object.assign({}, action.track) + } + + tracks[action.key] = track + return Object.assign({}, ui, { tracks: tracks }); + + case 'TRACKS_LOADED': + var tracks = Object.assign([], ui.tracks) + + for (var i = 0; i < action.tracks.length; i++){ + var track = action.tracks[i] + if (typeof(tracks[track.uri]) !== 'undefined'){ + track = Object.assign({}, tracks[track.uri], track) + } + tracks[track.uri] = track + } + + return Object.assign({}, ui, { tracks: tracks }); + + + + /** * Playlists **/ diff --git a/src/scss/components/_modal.scss b/src/scss/components/_modal.scss index 3d356e33..f11e5db7 100755 --- a/src/scss/components/_modal.scss +++ b/src/scss/components/_modal.scss @@ -132,13 +132,18 @@ } &.edit_radio { - .field { - position: relative; - button { - position: absolute; - top: 5px; - right: 0; - } + form { + padding-top: 60px; + .field { + position: relative; + margin-top: 10px; + button { + position: absolute; + top: 5px; + right: 0; + padding: 10px 12px; + } + } } } diff --git a/src/scss/global/_forms.scss b/src/scss/global/_forms.scss index d957b67d..23578296 100755 --- a/src/scss/global/_forms.scss +++ b/src/scss/global/_forms.scss @@ -73,6 +73,20 @@ input[type="submit"] { } } + &.discrete { + background: transparent; + color: #FFFFFF; + + &[disabled], + &[disabled="disabled"] { + background: transparent !important; + } + + &:hover { + color: $turquoise; + } + } + &.confirming, &.destructive { background: $red;