Files
Iris/src/js/views/modals/AddToQueue.js

261 lines
6.8 KiB
JavaScript
Raw Normal View History

2017-03-08 09:13:24 +13:00
2019-09-05 15:36:11 +12:00
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
2018-07-09 19:09:12 +12:00
import Modal from './Modal';
2019-09-05 15:36:11 +12:00
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 { I18n, i18n } from '../../locale';
import { uriType } from '../../util/helpers';
import Icon from '../../components/Icon';
import TextField from '../../components/Fields/TextField';
import LinksSentence from '../../components/LinksSentence';
const UriListItem = ({
uri,
tracks,
albums,
remove,
}) => {
const type = uriType(uri);
let item = null;
switch (type) {
case 'track':
item = tracks[uri];
break;
case 'album':
item = albums[uri];
break;
default:
break;
}
return (
<div className="list__item list__item--no-interaction">
{item ? item.name : <span className="mid_grey-text">{uri}</span>}
{item && item.artists && (
<I18n path="common.by" contentAfter>
<LinksSentence nolinks items={item.artists} />
</I18n>
)}
<span className="mid_grey-text">{` (${type})`}</span>
<button
className="button button--discrete button--destructive button--tiny pull-right"
type="button"
onClick={() => remove(uri)}
>
<Icon name="delete" />
<I18n path="actions.remove" />
</button>
</div>
);
};
2017-03-08 09:13:24 +13:00
class AddToQueue extends React.Component {
2019-09-05 15:36:11 +12:00
constructor(props) {
super(props);
this.state = {
text: '',
error: '',
uris: [],
2019-09-05 15:36:11 +12:00
next: false,
};
}
2017-03-08 09:13:24 +13:00
2019-09-05 15:36:11 +12:00
componentDidMount() {
const {
uiActions: {
setWindowTitle,
},
} = this.props;
setWindowTitle(i18n('modal.add_to_queue.title'));
2019-09-05 15:36:11 +12:00
}
2017-03-08 09:13:24 +13:00
onSubmit = (e) => {
const {
uris,
next,
} = this.state;
const {
mopidyActions: {
enqueueURIs,
},
} = this.props;
2019-09-05 15:36:11 +12:00
e.preventDefault();
enqueueURIs(uris, null, next);
2019-09-05 15:36:11 +12:00
window.history.back();
}
2018-07-13 16:48:41 +12:00
onChange = (text) => {
this.setState({ text });
}
addRandom = () => {
const {
mopidyActions: {
addToQueue_getRandomTracks,
},
} = this.props;
addToQueue_getRandomTracks(20);
}
addUris = () => {
const {
text,
} = this.state;
const {
coreActions: {
loadItem,
},
} = this.props;
const uris = text.split(',');
const validatedUris = uris.filter((uri) => uriType(uri));
validatedUris.forEach((uri) => {
loadItem(uri);
});
this.setState({ uris: validatedUris, text: '' });
}
removeUri = (uri) => {
const {
uris,
} = this.state;
this.setState({ uris: uris.filter((item) => item !== uri) });
}
render = () => {
const {
tracks,
albums,
} = this.props;
const {
uris,
text,
error,
next,
} = this.state;
2019-09-05 15:36:11 +12:00
return (
<Modal className="modal--add-to-queue">
<h1>
<I18n path="modal.add_to_queue.title" />
</h1>
<h2 className="mid_grey-text">
<I18n path="modal.add_to_queue.subtitle" />
</h2>
2017-03-08 09:13:24 +13:00
<form onSubmit={this.onSubmit}>
<div className="field text">
<div className="name">
<I18n path="fields.uri" />
</div>
<div className="input">
<TextField
onChange={this.onChange}
value={text}
/>
<span className="button discrete add-uri no-hover" onClick={this.addUris}>
<Icon name="add" />
<I18n path="actions.add" />
</span>
{error && <span className="description error">{error}</span>}
</div>
</div>
<div className="field text">
<div className="name">
<I18n path="fields.items_to_add.label" />
</div>
<div className="input">
{uris.length ? (
<div className="list">
{uris.map((uri, index) => (
<UriListItem
uri={uri}
tracks={tracks}
albums={albums}
remove={this.removeUri}
key={`${uri}_${index}`}
/>
))}
</div>
) : (
<span className="text mid_grey-text">
<I18n path="fields.items_to_add.placeholder" />
</span>
)}
</div>
</div>
2019-09-05 15:36:11 +12:00
<div className="field radio white">
<div className="name">
<I18n path="modal.add_to_queue.position.label" />
2019-09-05 15:36:11 +12:00
</div>
<div className="input">
<label>
<input
type="radio"
name="next"
checked={!next}
onChange={() => this.setState({ next: false })}
2019-09-05 15:36:11 +12:00
/>
<span className="label">
<I18n path="modal.add_to_queue.position.end" />
</span>
2019-09-05 15:36:11 +12:00
</label>
<label>
<input
type="radio"
name="next"
checked={next}
onChange={() => this.setState({ next: true })}
2019-09-05 15:36:11 +12:00
/>
<span className="label">
<I18n path="modal.add_to_queue.position.next" />
</span>
2019-09-05 15:36:11 +12:00
</label>
</div>
</div>
2017-03-08 09:13:24 +13:00
2019-09-05 15:36:11 +12:00
<div className="actions centered-text">
<button
type="button"
className="button button--grey button--large"
onClick={this.addRandom}
>
<I18n path="modal.add_to_queue.add_random" />
</button>
<button type="submit" className="button button--primary button--large">
<I18n path="actions.add" />
</button>
2019-09-05 15:36:11 +12:00
</div>
</form>
</Modal>
);
}
2018-07-09 19:09:12 +12:00
}
const mapStateToProps = (state) => ({
2019-09-05 15:36:11 +12:00
mopidy_connected: state.mopidy.connected,
albums: state.core.albums,
tracks: state.core.tracks,
2019-09-05 15:36:11 +12:00
});
2018-07-09 19:09:12 +12:00
2019-09-05 15:36:11 +12:00
const mapDispatchToProps = (dispatch) => ({
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch),
});
2018-07-09 19:09:12 +12:00
export default connect(mapStateToProps, mapDispatchToProps)(AddToQueue);