import React from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import Modal from './Modal'; 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 { uriSource } from '../../util/helpers'; class EditPlaylist extends React.Component { constructor(props) { super(props); this.state = { error: null, name: '', description: '', image: null, public: false, collaborative: false, }; } componentDidMount() { this.props.uiActions.setWindowTitle('Edit playlist'); if (this.props.playlist) { this.setState({ name: this.props.playlist.name, description: this.props.playlist.description, public: (this.props.playlist.public == true), collaborative: (this.props.playlist.collaborative == true), }); } else { switch (helpers.uriSource(this.props.uri)) { case 'spotify': this.props.spotifyActions.getPlaylist(this.props.uri); this.props.spotifyActions.following(this.props.uri); break; default: if (this.props.mopidy_connected) { this.props.mopidyActions.getPlaylist(this.props.uri); } break; } } } componentWillReceiveProps(nextProps) { // Playlist just loaded if (!this.props.playlist && nextProps.playlist) { this.setState({ name: nextProps.playlist.name, description: nextProps.playlist.description, public: (nextProps.playlist.public == true), collaborative: (nextProps.playlist.collaborative == true), }); // Mopidy just connected, and we don't have the playlist yet } else if (this.props.mopidy_connected != nextProps.mopidy_connected && !nextProps.playlist) { this.props.mopidyActions.getPlaylist(this.props.uri); } } savePlaylist(e) { e.preventDefault(); if (!this.state.name || this.state.name == '') { this.setState({ error: 'Name is required' }); return false; } this.props.coreActions.savePlaylist( this.props.uri, this.state.name, this.state.description, this.state.public, this.state.collaborative, this.state.image, ); window.history.back(); return false; } setImage(e) { const self = this; // Create a file-reader to import the selected image as a base64 string const file_reader = new FileReader(); // Once the image is loaded, convert the result file_reader.addEventListener('load', (e) => { const image_base64 = e.target.result.replace('data:image/jpeg;base64,', ''); self.setState({ image: image_base64 }); }); // This calls the filereader to load the file file_reader.readAsDataURL(e.target.files[0]); } renderFields() { switch (uriSource(this.props.uri)) { case 'spotify': return (
Name
this.setState({ name: e.target.value })} value={this.state.name} />
Description
this.setState({ description: e.target.value })} value={this.state.description} />
Cover image
this.setImage(e)} />
JPEG only, 256kB max. Leave empty to keep cover image unchanged.
Options
); break; default: return (
Name
this.setState({ name: e.target.value })} value={this.state.name} />
); } } render() { return (

Edit playlist

{this.state.error ?

{this.state.error}

: null}
this.savePlaylist(e)}> {this.renderFields()}
); } } const mapStateToProps = (state, ownProps) => { // Decode the URI, and then re-encode selected characters // This is needed as Mopidy encodes *some* characters in playlist URIs (but not other characters) // We need to retain ":" because this a reserved URI separator let uri = decodeURIComponent(ownProps.match.params.uri); uri = uri.replace(/\s/g, '%20'); // space uri = uri.replace(/\[/g, '%5B'); // [ uri = uri.replace(/\]/g, '%5D'); // ] uri = uri.replace(/\(/g, '%28'); // ( uri = uri.replace(/\)/g, '%29'); // ) uri = uri.replace(/\#/g, '%23'); // # return { uri, mopidy_connected: state.mopidy.connected, playlist: (state.core.playlists[uri] !== undefined ? state.core.playlists[uri] : null), playlists: state.core.playlists, }; }; const mapDispatchToProps = (dispatch) => ({ coreActions: bindActionCreators(coreActions, dispatch), uiActions: bindActionCreators(uiActions, dispatch), mopidyActions: bindActionCreators(mopidyActions, dispatch), spotifyActions: bindActionCreators(spotifyActions, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(EditPlaylist);