Radio edit modal

This commit is contained in:
James Barnsley
2017-02-01 10:10:31 +13:00
parent cab4218da2
commit 902b9cf58c
7 changed files with 134 additions and 86 deletions

View File

@ -32,6 +32,9 @@ class DebugInfo extends React.Component{
<div className="item">
{this.props.ui.playlists ? Object.keys(this.props.ui.playlists).length : '0'}&nbsp;playlists
</div>
<div className="item">
{this.props.ui.tracks ? Object.keys(this.props.ui.tracks).length : '0'}&nbsp;tracks
</div>
<div className="item">
{this.props.ui.users ? Object.keys(this.props.ui.users).length : '0'}&nbsp;users
</div>

View File

@ -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 (
<div className="list">
{
this.state.seeds.map((seed,index) => {
seeds.map((seed,index) => {
return (
<div className="list-item" key={index+'_'+seed}>
{seed}
<FontAwesome name="close" className="pull-right destructive" onClick={() => this.removeSeed(seed)} />
<div className="list-item" key={seed.uri}>
{seed.unresolved ? <span className="grey-text">{seed.uri}</span> : <span>{seed.name}</span> }
<span className="grey-text">&nbsp;({seed.type})</span>
<FontAwesome name="close" className="pull-right destructive" onClick={() => this.removeSeed(seed.uri)} />
</div>
)
})
@ -126,19 +135,21 @@ export default class EditRadioModal extends React.Component{
return (
<div>
<h4>Edit radio</h4>
<form>
<h3>Current seeds</h3>
{this.renderSeeds()}
<form>
<h3>Add seeds</h3>
<div className="field">
<input
type="text"
placeholder="Spotify URI"
onChange={e => this.handleChange(e.target.value)}
placeholder="Comma-separated URIs"
onChange={e => this.setState({uri: e.target.value})}
value={this.state.uri} />
<button disabled={!this.state.uri_validated} onClick={e => this.addSeed()}>Add</button>
<button className="discrete" onClick={e => this.addSeed()}><FontAwesome name="check" /></button>
</div>
{this.renderSeeds()}
<div className="actions centered-text">
{this.renderActions()}
</div>

View File

@ -37,7 +37,7 @@ class Modal extends React.Component{
{ this.props.modal.name == 'create_playlist' ? <CreatePlaylistModal uiActions={this.props.uiActions} /> : null }
{ this.props.modal.name == 'edit_playlist' ? <EditPlaylistModal uiActions={this.props.uiActions} data={this.props.modal.data} /> : null }
{ this.props.modal.name == 'send_authorization' ? <SendAuthorizationModal uiActions={this.props.uiActions} pusherActions={this.props.pusherActions} data={this.props.modal.data} /> : null }
{ this.props.modal.name == 'edit_radio' ? <EditRadioModal uiActions={this.props.uiActions} pusherActions={this.props.pusherActions} data={this.props.modal.data} radio={this.props.radio} /> : null }
{ this.props.modal.name == 'edit_radio' ? <EditRadioModal uiActions={this.props.uiActions} pusherActions={this.props.pusherActions} spotifyActions={this.props.spotifyActions} data={this.props.modal.data} radio={this.props.radio} artists={this.props.artists} tracks={this.props.tracks} /> : null }
{ this.props.modal.name == 'image_zoom' ? <ImageZoomModal uiActions={this.props.uiActions} data={this.props.modal.data} /> : null }
</div>
@ -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,

View File

@ -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
});
});
}
}

View File

@ -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
**/

View File

@ -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;
}
}
}
}

View File

@ -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;