Auto eslint fix

This commit is contained in:
James Barnsley
2019-09-05 15:36:11 +12:00
parent 4513a0d109
commit e4d53a2d35
126 changed files with 23283 additions and 23573 deletions

View File

@ -1,105 +1,114 @@
import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Link from '../../components/Link'
import ReactGA from 'react-ga'
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
import Thumbnail from '../../components/Thumbnail';
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 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 helpers from '../../helpers';
class AddToPlaylist extends React.Component{
class AddToPlaylist extends React.Component {
constructor(props) {
super(props);
constructor(props){
super(props)
if (!this.props.spotify_library_playlists) {
this.props.spotifyActions.getLibraryPlaylists();
}
if (!this.props.spotify_library_playlists){
this.props.spotifyActions.getLibraryPlaylists()
}
if (!this.props.mopidy_library_playlists && this.props.mopidy_connected){
this.props.mopidyActions.getLibraryPlaylists()
}
}
if (!this.props.mopidy_library_playlists && this.props.mopidy_connected) {
this.props.mopidyActions.getLibraryPlaylists();
}
}
playlistSelected(playlist_uri){
this.props.coreActions.addTracksToPlaylist(playlist_uri, this.props.uris);
window.history.back();
}
playlistSelected(playlist_uri) {
this.props.coreActions.addTracksToPlaylist(playlist_uri, this.props.uris);
window.history.back();
}
render(){
if (!this.props.playlists ) return <div className="empty">No editable playlists</div>
var playlists = []
for (var uri in this.props.playlists){
if (this.props.playlists[uri].can_edit ) playlists.push(this.props.playlists[uri] )
}
render() {
if (!this.props.playlists) return <div className="empty">No editable playlists</div>;
let playlists = [];
for (const uri in this.props.playlists) {
if (this.props.playlists[uri].can_edit) playlists.push(this.props.playlists[uri]);
}
playlists = helpers.sortItems(playlists, 'name')
playlists = helpers.sortItems(playlists, 'name');
var loader = null
if (this.props.spotify_library_playlists_status == 'running'){
loader = (
<div className='lazy-loader body-loader loading'>
<div className="loader"></div>
</div>
)
}
let loader = null;
if (this.props.spotify_library_playlists_status == 'running') {
loader = (
<div className="lazy-loader body-loader loading">
<div className="loader" />
</div>
);
}
return (
<Modal className="modal--add-to-playlist">
<h1>Add to playlist</h1>
<h2 className="mid_grey-text">Select playlist to add {this.props.uris.length} track{this.props.uris.length>1?'s':null} to</h2>
{playlists.length <= 0 ? <div className="no-results">No playlists available</div> : null}
<div className="list small playlists">
{
playlists.map(playlist => {
return (
<div className="list__item" key={playlist.uri} onClick={ () => this.playlistSelected(playlist.uri) }>
<Thumbnail images={playlist.images} size="small" />
<h4 className="list__item__name">{ playlist.name }</h4>
<ul className="list__item__details details">
<li><Icon type="fontawesome" className="source" name={helpers.sourceIcon(playlist.uri)} /></li>
<li>{ playlist.tracks_total ? <span className="mid_grey-text">&nbsp;{ playlist.tracks_total } tracks</span> : null }</li>
</ul>
</div>
)
})
return (
<Modal className="modal--add-to-playlist">
<h1>Add to playlist</h1>
<h2 className="mid_grey-text">
Select playlist to add
{this.props.uris.length}
{' '}
track
{this.props.uris.length > 1 ? 's' : null}
{' '}
to
</h2>
{playlists.length <= 0 ? <div className="no-results">No playlists available</div> : null}
<div className="list small playlists">
{
playlists.map((playlist) => (
<div className="list__item" key={playlist.uri} onClick={() => this.playlistSelected(playlist.uri)}>
<Thumbnail images={playlist.images} size="small" />
<h4 className="list__item__name">{ playlist.name }</h4>
<ul className="list__item__details details">
<li><Icon type="fontawesome" className="source" name={helpers.sourceIcon(playlist.uri)} /></li>
<li>
{ playlist.tracks_total ? (
<span className="mid_grey-text">
{ playlist.tracks_total }
{' '}
tracks
</span>
) : null }
</li>
</ul>
</div>
))
}
</div>
{loader}
</Modal>
)
}
</div>
{loader}
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
uris: (ownProps.match.params.uris ? decodeURIComponent(ownProps.match.params.uris).split(',') : []),
mopidy_connected: state.mopidy.connected,
mopidy_uri_schemes: state.mopidy.uri_schemes,
mopidy_library_playlists: state.mopidy.library_playlists,
mopidy_library_playlists_status: (state.ui.processes.MOPIDY_LIBRARY_PLAYLISTS_PROCESSOR !== undefined ? state.ui.processes.MOPIDY_LIBRARY_PLAYLISTS_PROCESSOR.status : null),
spotify_library_playlists: state.spotify.library_playlists,
spotify_library_playlists_status: (state.ui.processes.SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR !== undefined ? state.ui.processes.SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR.status : null),
load_queue: state.ui.load_queue,
me_id: (state.spotify.me ? state.spotify.me.id : false),
playlists: state.core.playlists
}
}
const mapStateToProps = (state, ownProps) => ({
uris: (ownProps.match.params.uris ? decodeURIComponent(ownProps.match.params.uris).split(',') : []),
mopidy_connected: state.mopidy.connected,
mopidy_uri_schemes: state.mopidy.uri_schemes,
mopidy_library_playlists: state.mopidy.library_playlists,
mopidy_library_playlists_status: (state.ui.processes.MOPIDY_LIBRARY_PLAYLISTS_PROCESSOR !== undefined ? state.ui.processes.MOPIDY_LIBRARY_PLAYLISTS_PROCESSOR.status : null),
spotify_library_playlists: state.spotify.library_playlists,
spotify_library_playlists_status: (state.ui.processes.SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR !== undefined ? state.ui.processes.SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR.status : null),
load_queue: state.ui.load_queue,
me_id: (state.spotify.me ? state.spotify.me.id : false),
playlists: state.core.playlists,
});
const mapDispatchToProps = (dispatch) => {
return {
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(AddToPlaylist)
export default connect(mapStateToProps, mapDispatchToProps)(AddToPlaylist);

View File

@ -1,104 +1,102 @@
import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Link from '../../components/Link'
import ReactGA from 'react-ga'
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
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 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 helpers from '../../helpers';
class AddToQueue extends React.Component{
class AddToQueue extends React.Component {
constructor(props) {
super(props);
this.state = {
uris: '',
next: false,
};
}
constructor(props){
super(props)
this.state = {
uris: '',
next: false
}
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Add to queue');
}
componentDidMount(){
this.props.uiActions.setWindowTitle("Add to queue");
}
handleSubmit(e) {
e.preventDefault();
const uris = this.state.uris.split(',');
this.props.mopidyActions.enqueueURIs(uris, null, this.state.next);
window.history.back();
}
handleSubmit(e){
e.preventDefault();
var uris = this.state.uris.split(',');
this.props.mopidyActions.enqueueURIs(uris, null, this.state.next);
window.history.back();
}
render() {
return (
<Modal className="modal--add-to-queue">
<h1>Add to queue</h1>
<h2 className="mid_grey-text">Add a comma-separated list of URIs to the play queue. You must have the appropriate Mopidy backend enabled for each URI schema (eg spotify:, yt:).</h2>
render(){
return (
<Modal className="modal--add-to-queue">
<h1>Add to queue</h1>
<h2 className="mid_grey-text">Add a comma-separated list of URIs to the play queue. You must have the appropriate Mopidy backend enabled for each URI schema (eg spotify:, yt:).</h2>
<form onSubmit={(e) => this.handleSubmit(e)}>
<div className="field text">
<div className="name">URI(s)</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ uris: e.target.value })}
value={this.state.uris}
/>
</div>
</div>
<form onSubmit={e => this.handleSubmit(e)}>
<div className="field text">
<div className="name">URI(s)</div>
<div className="input">
<input
type="text"
onChange={e => this.setState({uris: e.target.value})}
value={this.state.uris} />
</div>
</div>
<div className="field radio white">
<div className="name">
<div className="field radio white">
<div className="name">
Position
</div>
<div className="input">
<label>
<input
type="radio"
name="next"
checked={!this.state.next}
onChange={e => this.setState({next: false})} />
<span className="label">End</span>
</label>
<label>
<input
type="radio"
name="next"
checked={this.state.next}
onChange={e => this.setState({next: true})} />
<span className="label">After current track</span>
</label>
</div>
</div>
</div>
<div className="input">
<label>
<input
type="radio"
name="next"
checked={!this.state.next}
onChange={(e) => this.setState({ next: false })}
/>
<span className="label">End</span>
</label>
<label>
<input
type="radio"
name="next"
checked={this.state.next}
onChange={(e) => this.setState({ next: true })}
/>
<span className="label">After current track</span>
</label>
</div>
</div>
<div className="actions centered-text">
<button type="submit" className="button button--primary button--large">Add</button>
</div>
</form>
</Modal>
)
}
<div className="actions centered-text">
<button type="submit" className="button button--primary button--large">Add</button>
</div>
</form>
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
mopidy_connected: state.mopidy.connected,
playlist: (state.core.playlists[ownProps.match.params.uri] !== undefined ? state.core.playlists[ownProps.match.params.uri] : null),
playlists: state.core.playlists
}
}
const mapStateToProps = (state, ownProps) => ({
mopidy_connected: state.mopidy.connected,
playlist: (state.core.playlists[ownProps.match.params.uri] !== undefined ? state.core.playlists[ownProps.match.params.uri] : null),
playlists: state.core.playlists,
});
const mapDispatchToProps = (dispatch) => {
return {
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(AddToQueue)
export default connect(mapStateToProps, mapDispatchToProps)(AddToQueue);

View File

@ -1,176 +1,177 @@
import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Link from '../../components/Link'
import ReactGA from 'react-ga'
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
import * as coreActions from '../../services/core/actions'
import * as uiActions from '../../services/ui/actions'
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as helpers from '../../helpers';
class CreatePlaylist extends React.Component{
class CreatePlaylist extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
description: '',
scheme: 'spotify',
is_public: true,
is_collaborative: false,
};
}
constructor(props){
super(props)
this.state = {
name: '',
description: '',
scheme: 'spotify',
is_public: true,
is_collaborative: false
}
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Create playlist');
}
componentDidMount(){
this.props.uiActions.setWindowTitle("Create playlist");
}
createPlaylist(e) {
e.preventDefault();
createPlaylist(e){
e.preventDefault();
if (!this.state.name || this.state.name == '') {
this.setState({ error: 'Name is required' });
return false;
}
this.props.coreActions.createPlaylist(
this.state.scheme,
this.state.name,
this.state.description,
this.state.is_public,
this.state.is_collaborative,
);
window.history.back();
if (!this.state.name || this.state.name == ''){
this.setState({error: 'Name is required'})
return false
} else {
this.props.coreActions.createPlaylist(
this.state.scheme,
this.state.name,
this.state.description,
this.state.is_public,
this.state.is_collaborative
);
window.history.back();
}
return false
}
return false;
}
renderFields(){
switch (this.state.scheme){
renderFields() {
switch (this.state.scheme) {
case 'spotify':
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
/>
</div>
</div>
case 'spotify':
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({ name: e.target.value })}
value={ this.state.name } />
</div>
</div>
<div className="field text">
<div className="name">Description</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ description: e.target.value })}
<div className="field text">
<div className="name">Description</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({ description: e.target.value })}
value={ this.state.description } />
</div>
</div>
value={this.state.description}
/>
</div>
</div>
<div className="field checkbox white">
<div className="name">
<div className="field checkbox white">
<div className="name">
Options
</div>
<div className="input">
<label>
<input
type="checkbox"
name="is_public"
checked={ this.state.is_public }
onChange={ e => this.setState({ is_public: !this.state.is_public })} />
<span className="label">Public</span>
</label>
<label>
<input
type="checkbox"
name="is_collaborative"
checked={ this.state.is_collaborative }
onChange={ e => this.setState({ is_collaborative: !this.state.is_collaborative })} />
<span className="label">Collaborative</span>
</label>
</div>
</div>
</div>
)
</div>
<div className="input">
<label>
<input
type="checkbox"
name="is_public"
checked={this.state.is_public}
onChange={(e) => this.setState({ is_public: !this.state.is_public })}
/>
<span className="label">Public</span>
</label>
<label>
<input
type="checkbox"
name="is_collaborative"
checked={this.state.is_collaborative}
onChange={(e) => this.setState({ is_collaborative: !this.state.is_collaborative })}
/>
<span className="label">Collaborative</span>
</label>
</div>
</div>
</div>
);
default:
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({ name: e.target.value })}
value={ this.state.name } />
</div>
</div>
</div>
)
}
}
default:
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
/>
</div>
</div>
</div>
);
}
}
render(){
return (
<Modal className="modal--create-playlist">
<h1>Create playlist</h1>
<form onSubmit={(e) => this.createPlaylist(e)}>
render() {
return (
<Modal className="modal--create-playlist">
<h1>Create playlist</h1>
<form onSubmit={(e) => this.createPlaylist(e)}>
<div className="field radio white">
<div className="name">
<div className="field radio white">
<div className="name">
Provider
</div>
<div className="input">
<label>
<input
type="radio"
name="scheme"
value="spotify"
checked={ this.state.scheme == 'spotify' }
onChange={ e => this.setState({ scheme: e.target.value })} />
<span className="label">Spotify</span>
</label>
<label>
<input
type="radio"
name="scheme"
value="m3u"
checked={ this.state.scheme == 'm3u' }
onChange={ e => this.setState({ scheme: e.target.value })} />
<span className="label">Mopidy</span>
</label>
</div>
</div>
{this.renderFields()}
</div>
<div className="input">
<label>
<input
type="radio"
name="scheme"
value="spotify"
checked={this.state.scheme == 'spotify'}
onChange={(e) => this.setState({ scheme: e.target.value })}
/>
<span className="label">Spotify</span>
</label>
<label>
<input
type="radio"
name="scheme"
value="m3u"
checked={this.state.scheme == 'm3u'}
onChange={(e) => this.setState({ scheme: e.target.value })}
/>
<span className="label">Mopidy</span>
</label>
</div>
</div>
<div className="actions centered-text">
<button type="submit" className="button button--primary button--large">Create playlist</button>
</div>
{this.renderFields()}
</form>
</Modal>
)
}
<div className="actions centered-text">
<button type="submit" className="button button--primary button--large">Create playlist</button>
</div>
</form>
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {}
}
const mapStateToProps = (state, ownProps) => ({});
const mapDispatchToProps = (dispatch) => {
return {
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(CreatePlaylist)
export default connect(mapStateToProps, mapDispatchToProps)(CreatePlaylist);

View File

@ -15,240 +15,242 @@ import * as pusherActions from '../../services/pusher/actions';
import * as uiActions from '../../services/ui/actions';
import * as helpers from '../../helpers';
class EditCommand extends React.Component{
class EditCommand extends React.Component {
constructor(props) {
super(props);
this.state = {
id: helpers.generateGuid(),
icon: 'power_settings_new',
name: '',
colour: '',
url: `https://${window.location.hostname}/broadlink/sendCommand/power/`,
method: 'GET',
post_data: '',
additional_headers: '',
};
}
constructor(props){
super(props)
this.state = {
id: helpers.generateGuid(),
icon: 'power_settings_new',
name: '',
colour: '',
url: "https://"+window.location.hostname+"/broadlink/sendCommand/power/",
method: 'GET',
post_data: "",
additional_headers: ""
}
}
componentDidMount() {
if (this.props.command) {
this.props.uiActions.setWindowTitle('Edit command');
this.setState(this.props.command);
} else {
this.props.uiActions.setWindowTitle('Create command');
}
}
componentDidMount(){
if (this.props.command){
this.props.uiActions.setWindowTitle("Edit command");
this.setState(this.props.command);
} else {
this.props.uiActions.setWindowTitle("Create command");
}
}
handleSubmit(e) {
e.preventDefault();
handleSubmit(e){
e.preventDefault();
this.props.pusherActions.setCommand(this.state);
this.props.pusherActions.setCommand(this.state);
window.history.back();
window.history.back();
// A bit hacky, but wait for a moment to allow the back navigation
// and then scroll down to our commands list
setTimeout(() => {
helpers.scrollTo('#commands-setup');
},
10);
// A bit hacky, but wait for a moment to allow the back navigation
// and then scroll down to our commands list
setTimeout(() => {
helpers.scrollTo("#commands-setup");
},
10
);
return false;
}
return false;
}
handleDelete(e) {
this.props.pusherActions.removeCommand(this.state.id);
window.history.back();
handleDelete(e){
this.props.pusherActions.removeCommand(this.state.id);
window.history.back();
// A bit hacky, but wait for a moment to allow the back navigation
// and then scroll down to our commands list
setTimeout(() => {
helpers.scrollTo('#commands-setup');
},
10);
}
// A bit hacky, but wait for a moment to allow the back navigation
// and then scroll down to our commands list
setTimeout(() => {
helpers.scrollTo("#commands-setup");
},
10
);
}
render() {
const icons = [
'power_settings_new',
'eject',
'grade',
'query_builder',
'settings_input_component',
'settings_input_hdmi',
'settings_input_svideo',
'forward_5',
'forward_10',
'forward_30',
'replay',
'replay_5',
'replay_10',
'replay_30',
'skip_next',
'skip_previous',
'play_arrow',
'pause',
'stop',
'shuffle',
'snooze',
'volume_off',
'volume_down',
'volume_up',
'arrow_left',
'arrow_drop_up',
'arrow_right',
'arrow_drop_down',
'done',
'done_all',
'add',
'remove',
'clear',
'cast',
'speaker',
'speaker_group',
'audiotrack',
'videogame_asset',
'computer',
'tv',
];
render(){
var icons = [
"power_settings_new",
"eject",
"grade",
"query_builder",
"settings_input_component",
"settings_input_hdmi",
"settings_input_svideo",
"forward_5",
"forward_10",
"forward_30",
"replay",
"replay_5",
"replay_10",
"replay_30",
"skip_next",
"skip_previous",
"play_arrow",
"pause",
"stop",
"shuffle",
"snooze",
"volume_off",
"volume_down",
"volume_up",
"arrow_left",
"arrow_drop_up",
"arrow_right",
"arrow_drop_down",
"done",
"done_all",
"add",
"remove",
"clear",
"cast",
"speaker",
"speaker_group",
"audiotrack",
"videogame_asset",
"computer",
"tv"
];
return (
<Modal className="modal--create-command">
<h1>{this.props.command ? "Edit" : "Create"} command</h1>
<form onSubmit={(e) => this.handleSubmit(e)}>
<div className="field textarea white">
<div className="name">
Name
</div>
<div className="input">
<TextField
name="name"
value={this.state.name}
onChange={value => this.setState({ name: value })}
/>
</div>
</div>
<div className="field radio white">
<div className="name">
Colour
</div>
<div className="input">
<ColourField
colour={this.state.colour}
onChange={colour => this.setState({colour: colour})}
/>
</div>
</div>
<div className="field radio white">
<div className="name">
Icon
</div>
<div className="input">
<IconField
icon={this.state.icon}
icons={icons}
onChange={icon => this.setState({icon: icon})}
/>
</div>
</div>
<div className="field textarea white">
<div className="name">
URL
</div>
<div className="input">
<TextField
name="url"
value={this.state.url}
onChange={value => this.setState({ url: value })}
/>
</div>
</div>
<div className="field radio white">
<div className="name">
Method
</div>
<div className="input">
<label>
<input
type="radio"
name="method"
value="GET"
checked={ this.state.method == 'GET' }
onChange={ e => this.setState({ method: e.target.value })} />
<span className="label">GET</span>
</label>
<label>
<input
type="radio"
name="method"
value="POST"
checked={ this.state.method == 'POST' }
onChange={ e => this.setState({ method: e.target.value })} />
<span className="label">POST</span>
</label>
</div>
</div>
{this.state.method == 'POST' && <div className="field textarea white">
<div className="name">
Data
</div>
<div className="input">
<textarea
name="command"
value={this.state.post_data}
onChange={ e => this.setState({ post_data: e.target.value })}>
</textarea>
</div>
</div>}
return (
<Modal className="modal--create-command">
<h1>
{this.props.command ? 'Edit' : 'Create'}
{' '}
command
</h1>
<form onSubmit={(e) => this.handleSubmit(e)}>
<div className="field textarea white">
<div className="name">
<div className="name">
Name
</div>
<div className="input">
<TextField
name="name"
value={this.state.name}
onChange={(value) => this.setState({ name: value })}
/>
</div>
</div>
<div className="field radio white">
<div className="name">
Colour
</div>
<div className="input">
<ColourField
colour={this.state.colour}
onChange={(colour) => this.setState({ colour })}
/>
</div>
</div>
<div className="field radio white">
<div className="name">
Icon
</div>
<div className="input">
<IconField
icon={this.state.icon}
icons={icons}
onChange={(icon) => this.setState({ icon })}
/>
</div>
</div>
<div className="field textarea white">
<div className="name">
URL
</div>
<div className="input">
<TextField
name="url"
value={this.state.url}
onChange={(value) => this.setState({ url: value })}
/>
</div>
</div>
<div className="field radio white">
<div className="name">
Method
</div>
<div className="input">
<label>
<input
type="radio"
name="method"
value="GET"
checked={this.state.method == 'GET'}
onChange={(e) => this.setState({ method: e.target.value })}
/>
<span className="label">GET</span>
</label>
<label>
<input
type="radio"
name="method"
value="POST"
checked={this.state.method == 'POST'}
onChange={(e) => this.setState({ method: e.target.value })}
/>
<span className="label">POST</span>
</label>
</div>
</div>
{this.state.method == 'POST' && (
<div className="field textarea white">
<div className="name">
Data
</div>
<div className="input">
<textarea
name="command"
value={this.state.post_data}
onChange={(e) => this.setState({ post_data: e.target.value })}
/>
</div>
</div>
)}
<div className="field textarea white">
<div className="name">
Additional Headers
</div>
<div className="input">
<textarea
name="headers"
value={this.state.additional_headers}
onChange={ e => this.setState({ additional_headers: e.target.value })}>
</textarea>
</div>
</div>
</div>
<div className="input">
<textarea
name="headers"
value={this.state.additional_headers}
onChange={(e) => this.setState({ additional_headers: e.target.value })}
/>
</div>
</div>
<div className="actions centered-text">
{this.props.command ? <button type="button" className="button button--destructive button--large" onClick={e => this.handleDelete(e)}>Delete</button> : null}
<button type="submit" className="button button--primary button--large">Save</button>
</div>
<div className="actions centered-text">
{this.props.command ? <button type="button" className="button button--destructive button--large" onClick={(e) => this.handleDelete(e)}>Delete</button> : null}
<button type="submit" className="button button--primary button--large">Save</button>
</div>
</form>
</Modal>
)
}
</form>
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
var id = ownProps.match.params.id;
return {
id: id,
command: (id && state.pusher.commands && state.pusher.commands[id] !== undefined ? state.pusher.commands[id] : null)
}
}
const { id } = ownProps.match.params;
return {
id,
command: (id && state.pusher.commands && state.pusher.commands[id] !== undefined ? state.pusher.commands[id] : null),
};
};
const mapDispatchToProps = (dispatch) => {
return {
pusherActions: bindActionCreators(pusherActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
pusherActions: bindActionCreators(pusherActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(EditCommand)
export default connect(mapStateToProps, mapDispatchToProps)(EditCommand);

View File

@ -1,242 +1,236 @@
import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Link from '../../components/Link'
import ReactGA from 'react-ga'
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
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 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 helpers from '../../helpers';
class EditPlaylist extends React.Component{
class EditPlaylist extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
name: '',
description: '',
image: null,
public: false,
collaborative: false,
};
}
constructor(props){
super(props)
this.state = {
error: null,
name: '',
description: '',
image: null,
public: false,
collaborative: false
}
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Edit playlist');
componentDidMount(){
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;
this.props.uiActions.setWindowTitle("Edit playlist");
default:
if (this.props.mopidy_connected) {
this.props.mopidyActions.getPlaylist(this.props.uri);
}
break;
}
}
}
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)){
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),
});
case 'spotify':
this.props.spotifyActions.getPlaylist(this.props.uri);
this.props.spotifyActions.following(this.props.uri);
break
// 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);
}
}
default:
if (this.props.mopidy_connected){
this.props.mopidyActions.getPlaylist(this.props.uri);
}
break
}
}
}
savePlaylist(e) {
e.preventDefault();
componentWillReceiveProps(nextProps){
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;
}
// 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)
});
setImage(e) {
const self = this;
// 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);
}
}
// Create a file-reader to import the selected image as a base64 string
const file_reader = new FileReader();
savePlaylist(e){
e.preventDefault();
if (!this.state.name || this.state.name == ''){
this.setState({error: 'Name is required'})
return false
} else {
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){
var self = this;
// Create a file-reader to import the selected image as a base64 string
var file_reader = new FileReader();
// Once the image is loaded, convert the result
file_reader.addEventListener("load", function(e){
var 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]);
}
file_reader.addEventListener('load', (e) => {
const image_base64 = e.target.result.replace('data:image/jpeg;base64,', '');
self.setState({ image: image_base64 });
});
renderFields(){
switch (helpers.uriSource(this.props.uri)){
// This calls the filereader to load the file
file_reader.readAsDataURL(e.target.files[0]);
}
case 'spotify':
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({ name: e.target.value })}
value={ this.state.name }
/>
</div>
</div>
<div className="field text">
<div className="name">Description</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({ description: e.target.value })}
value={ this.state.description }
/>
</div>
</div>
<div className="field file">
<div className="name">Cover image</div>
<div className="input">
<input
type="file"
placeholder="Leave empty to keep existing image"
onChange={e => this.setImage(e)}
/>
<div className="description">
renderFields() {
switch (helpers.uriSource(this.props.uri)) {
case 'spotify':
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
/>
</div>
</div>
<div className="field text">
<div className="name">Description</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ description: e.target.value })}
value={this.state.description}
/>
</div>
</div>
<div className="field file">
<div className="name">Cover image</div>
<div className="input">
<input
type="file"
placeholder="Leave empty to keep existing image"
onChange={(e) => this.setImage(e)}
/>
<div className="description">
JPEG only, 256kB max. Leave empty to keep cover image unchanged.
</div>
</div>
</div>
<div className="field checkbox white">
<div className="name">
</div>
</div>
</div>
<div className="field checkbox white">
<div className="name">
Options
</div>
<div className="input">
<label>
<input
type="checkbox"
name="playlist_private"
checked={ this.state.public }
onChange={ e => this.setState({ public: !this.state.public })} />
<span className="label">Public</span>
</label>
<label>
<input
type="checkbox"
name="collaborative"
checked={ this.state.collaborative }
onChange={ e => this.setState({ collaborative: !this.state.collaborative })} />
<span className="label">Collaborative</span>
</label>
</div>
</div>
</div>
)
break
</div>
<div className="input">
<label>
<input
type="checkbox"
name="playlist_private"
checked={this.state.public}
onChange={(e) => this.setState({ public: !this.state.public })}
/>
<span className="label">Public</span>
</label>
<label>
<input
type="checkbox"
name="collaborative"
checked={this.state.collaborative}
onChange={(e) => this.setState({ collaborative: !this.state.collaborative })}
/>
<span className="label">Collaborative</span>
</label>
</div>
</div>
</div>
);
break;
default:
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({ name: e.target.value })}
value={ this.state.name } />
</div>
</div>
</div>
)
}
}
default:
return (
<div>
<div className="field text">
<div className="name">Name</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
/>
</div>
</div>
</div>
);
}
}
render(){
return (
<Modal className="modal--edit-playlist">
<h1>Edit playlist</h1>
{this.state.error ? <h3 className="red-text">{this.state.error}</h3> : null}
<form onSubmit={(e) => this.savePlaylist(e)}>
render() {
return (
<Modal className="modal--edit-playlist">
<h1>Edit playlist</h1>
{this.state.error ? <h3 className="red-text">{this.state.error}</h3> : null}
<form onSubmit={(e) => this.savePlaylist(e)}>
{this.renderFields()}
{this.renderFields()}
<div className="actions centered-text">
<button type="submit" className="button button--primary button--large">Save</button>
</div>
</form>
</Modal>
)
}
<div className="actions centered-text">
<button type="submit" className="button button--primary button--large">Save</button>
</div>
</form>
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
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'); // #
// 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
var 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: uri,
mopidy_connected: state.mopidy.connected,
playlist: (state.core.playlists[uri] !== undefined ? state.core.playlists[uri] : null),
playlists: state.core.playlists
}
}
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) => {
return {
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch)
}
}
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)
export default connect(mapStateToProps, mapDispatchToProps)(EditPlaylist);

View File

@ -1,271 +1,271 @@
import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Link from '../../components/Link'
import ReactGA from 'react-ga'
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
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 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 helpers from '../../helpers';
class EditRadio extends React.Component{
class EditRadio extends React.Component {
constructor(props) {
super(props);
this.state = {
enabled: false,
seeds: [],
uri: '',
error_message: null,
};
}
constructor(props){
super(props)
this.state = {
enabled: false,
seeds: [],
uri: '',
error_message: null
}
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Edit radio');
componentDidMount(){
this.props.uiActions.setWindowTitle("Edit radio");
if (this.props.radio && this.props.radio.enabled) {
this.loadRadio(this.props.radio);
}
}
if (this.props.radio && this.props.radio.enabled){
this.loadRadio(this.props.radio);
}
}
componentWillReceiveProps(nextProps) {
if (!this.props.radio && nextProps.radio) {
this.loadRadio(nextProps.radio);
}
}
componentWillReceiveProps(nextProps){
if (!this.props.radio && nextProps.radio){
this.loadRadio(nextProps.radio);
}
}
loadRadio(radio) {
const seeds = [...radio.seed_tracks, ...radio.seed_artists, ...radio.seed_genres];
this.setState({ seeds, enabled: radio.enabled });
this.props.spotifyActions.resolveRadioSeeds(radio);
}
loadRadio(radio){
var seeds = [...radio.seed_tracks, ...radio.seed_artists, ...radio.seed_genres];
this.setState({seeds: seeds, enabled: radio.enabled});
this.props.spotifyActions.resolveRadioSeeds(radio);
}
handleStart(e) {
e.preventDefault();
handleStart(e){
e.preventDefault();
let valid_seeds = true;
const seeds = this.mapSeeds();
for (let i = 0; i < seeds.length; i++) {
if (seeds[i].unresolved !== undefined) {
valid_seeds = false;
continue;
}
}
let valid_seeds = true;
let seeds = this.mapSeeds();
for (let i = 0; i < seeds.length; i++){
if (seeds[i].unresolved !== undefined){
valid_seeds = false;
continue;
}
}
if (valid_seeds) {
this.props.pusherActions.startRadio(this.state.seeds);
window.history.back();
} else {
this.setState({ error_message: 'Invalid seed URI(s)' });
}
}
if (valid_seeds){
this.props.pusherActions.startRadio(this.state.seeds);
window.history.back();
} else {
this.setState({error_message: "Invalid seed URI(s)"});
}
}
handleUpdate(e) {
e.preventDefault();
handleUpdate(e){
e.preventDefault();
let valid_seeds = true;
const seeds = this.mapSeeds();
for (let i = 0; i < seeds.length; i++) {
if (seeds[i].unresolved !== undefined) {
valid_seeds = false;
continue;
}
}
var valid_seeds = true;
var seeds = this.mapSeeds();
for (var i = 0; i < seeds.length; i++){
if (seeds[i].unresolved !== undefined){
valid_seeds = false;
continue;
}
}
if (valid_seeds) {
this.props.pusherActions.updateRadio(this.state.seeds);
this.props.uiActions.closeModal();
} else {
this.setState({ error_message: 'Invalid seed URI(s)' });
}
}
if (valid_seeds){
this.props.pusherActions.updateRadio(this.state.seeds);
this.props.uiActions.closeModal();
} else {
this.setState({error_message: "Invalid seed URI(s)"});
}
}
handleStop(e) {
e.preventDefault();
this.props.pusherActions.stopRadio();
this.props.uiActions.closeModal();
}
handleStop(e){
e.preventDefault()
this.props.pusherActions.stopRadio()
this.props.uiActions.closeModal()
}
addSeed(e) {
e.preventDefault();
addSeed(e){
e.preventDefault();
if (this.state.uri == '') {
this.setState({ error_message: 'Cannot be empty' });
return;
}
if (this.state.uri == ''){
this.setState({error_message: 'Cannot be empty'});
return;
}
this.setState({ error_message: null });
this.setState({error_message: null});
const seeds = Object.assign([], this.state.seeds);
let uris = this.state.uri.split(',');
var seeds = Object.assign([],this.state.seeds);
var uris = this.state.uri.split(',');
if (uris.length >= 5) {
uris = uris.slice(0, 5);
this.setState({ error_message: 'More than 5 seeds provided, ignoring rest' });
}
if (uris.length >= 5) {
uris = uris.slice(0, 5);
this.setState({error_message: 'More than 5 seeds provided, ignoring rest'});
}
for (let i = 0; i < uris.length; i++) {
if (helpers.uriSource(uris[i]) !== 'spotify') {
this.setState({ error_message: 'Non-Spotify URIs not supported' });
return;
} if (seeds.indexOf(uris[i]) > -1) {
this.setState({ error_message: 'URI already added' });
} else {
seeds.push(uris[i]);
}
for (var i = 0; i < uris.length; i++){
if (helpers.uriSource(uris[i]) !== 'spotify'){
this.setState({error_message: 'Non-Spotify URIs not supported'});
return;
} else if (seeds.indexOf(uris[i]) > -1){
this.setState({error_message: 'URI already added'});
} else {
seeds.push(uris[i]);
}
// Resolve
switch (helpers.uriType(uris[i])) {
case 'track':
this.props.spotifyActions.getTrack(uris[i]);
break;
// Resolve
switch (helpers.uriType(uris[i])){
case 'track':
this.props.spotifyActions.getTrack(uris[i]);
break;
case 'artist':
this.props.spotifyActions.getArtist(uris[i]);
break;
}
}
case 'artist':
this.props.spotifyActions.getArtist(uris[i]);
break;
}
}
// commit to state
this.setState({
seeds,
uri: '',
});
}
// commit to state
this.setState({
seeds: seeds,
uri: ''
})
}
removeSeed(uri) {
const seeds = [];
for (let i = 0; i < this.state.seeds.length; i++) {
if (this.state.seeds[i] != uri) {
seeds.push(this.state.seeds[i]);
}
}
this.setState({ seeds });
}
removeSeed(uri){
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});
}
mapSeeds() {
const seeds = [];
mapSeeds(){
var seeds = []
if (this.state.seeds) {
for (let i = 0; i < this.state.seeds.length && i < 5; i++) {
const uri = this.state.seeds[i];
if (uri) {
if (helpers.uriType(uri) == 'artist') {
if (this.props.artists && this.props.artists.hasOwnProperty(uri)) {
seeds.push(this.props.artists[uri]);
} else {
seeds.push({
unresolved: true,
uri,
});
}
} else if (helpers.uriType(uri) == 'track') {
if (this.props.tracks && this.props.tracks.hasOwnProperty(uri)) {
seeds.push(this.props.tracks[uri]);
} else {
seeds.push({
unresolved: true,
uri,
});
}
}
}
}
}
if (this.state.seeds){
for (var i = 0; i < this.state.seeds.length && i < 5; i++){
var uri = this.state.seeds[i]
if (uri){
if (helpers.uriType(uri) == 'artist'){
if (this.props.artists && this.props.artists.hasOwnProperty(uri)){
seeds.push(this.props.artists[uri]);
} else {
seeds.push({
unresolved: true,
uri: uri
})
return seeds;
}
renderSeeds() {
const seeds = this.mapSeeds();
if (seeds.length > 0) {
return (
<div>
<div className="list">
{
seeds.map((seed, index) => (
<div className="list__item" key={seed.uri}>
{seed.unresolved ? <span className="mid_grey-text">{seed.uri}</span> : <span>{seed.name}</span> }
{!seed.unresolved ? (
<span className="mid_grey-text">
&nbsp;(
{helpers.uriType(seed.uri)}
)
</span>
) : null}
<span className="button discrete remove-uri no-hover" onClick={(e) => this.removeSeed(seed.uri)}>
<Icon name="delete" />
Remove
</span>
</div>
))
}
} else if (helpers.uriType(uri) == 'track'){
if (this.props.tracks && this.props.tracks.hasOwnProperty(uri)){
seeds.push(this.props.tracks[uri]);
} else {
seeds.push({
unresolved: true,
uri: uri
})
}
}
}
}
}
</div>
</div>
);
}
return (
<div className="no-results">No seeds</div>
);
}
return seeds;
}
render() {
return (
<Modal className="modal--edit-radio">
<h1>Radio</h1>
<h2 className="mid_grey-text">Add and remove seeds to shape the sound of your radio. Radio uses Spotify's recommendations engine to suggest tracks similar to your seeds.</h2>
renderSeeds(){
var seeds = this.mapSeeds();
<form onSubmit={(e) => { (this.state.enabled ? this.handleUpdate(e) : this.handleStart(e)); }}>
if (seeds.length > 0){
return (
<div>
<div className="list">
{
seeds.map((seed,index) => {
return (
<div className="list__item" key={seed.uri}>
{seed.unresolved ? <span className="mid_grey-text">{seed.uri}</span> : <span>{seed.name}</span> }
{!seed.unresolved ? <span className="mid_grey-text">&nbsp;({helpers.uriType(seed.uri)})</span> : null}
<span className="button discrete remove-uri no-hover" onClick={e => this.removeSeed(seed.uri)}>
<Icon name="delete" />Remove
</span>
</div>
)
})
}
</div>
</div>
)
} else {
return (
<div className="no-results">No seeds</div>
)
}
}
{this.renderSeeds()}
render(){
return (
<Modal className="modal--edit-radio">
<h1>Radio</h1>
<h2 className="mid_grey-text">Add and remove seeds to shape the sound of your radio. Radio uses Spotify's recommendations engine to suggest tracks similar to your seeds.</h2>
<div className="field text">
<div className="name">URI(s)</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ uri: e.target.value, error_message: null })}
value={this.state.uri}
/>
<span className="button discrete add-uri no-hover" onClick={(e) => this.addSeed(e)}>
<Icon name="add" />
Add
</span>
{this.state.error_message ? <span className="description error">{this.state.error_message}</span> : null}
</div>
</div>
<form onSubmit={e => {(this.state.enabled ? this.handleUpdate(e) : this.handleStart(e))}}>
<div className="actions centered-text">
{this.state.enabled ? <span className="button button--destructive button--large" onClick={(e) => this.handleStop(e)}>Stop</span> : null}
{this.renderSeeds()}
<div className="field text">
<div className="name">URI(s)</div>
<div className="input">
<input
type="text"
onChange={e => this.setState({uri: e.target.value, error_message: null})}
value={this.state.uri}
/>
<span className="button discrete add-uri no-hover" onClick={e => this.addSeed(e)}>
<Icon name="add" />Add
</span>
{this.state.error_message ? <span className="description error">{this.state.error_message}</span> : null}
</div>
</div>
<div className="actions centered-text">
{this.state.enabled ? <span className="button button--destructive button--large" onClick={e => this.handleStop(e)}>Stop</span> : null}
{this.state.enabled ? <button className="button button--primary button--large" onClick={e => this.handleUpdate(e)}>Save</button> : <button className="button button--primary button--large" onClick={e => this.handleStart(e)}>Start</button>}
</div>
</form>
</Modal>
)
}
{this.state.enabled ? <button className="button button--primary button--large" onClick={(e) => this.handleUpdate(e)}>Save</button> : <button className="button button--primary button--large" onClick={(e) => this.handleStart(e)}>Start</button>}
</div>
</form>
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
mopidy_connected: state.mopidy.connected,
radio: state.core.radio,
artists: state.core.artists,
tracks: state.core.tracks
}
}
const mapStateToProps = (state, ownProps) => ({
mopidy_connected: state.mopidy.connected,
radio: state.core.radio,
artists: state.core.artists,
tracks: state.core.tracks,
});
const mapDispatchToProps = (dispatch) => {
return {
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
pusherActions: bindActionCreators(pusherActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
pusherActions: bindActionCreators(pusherActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(EditRadio)
export default connect(mapStateToProps, mapDispatchToProps)(EditRadio);

View File

@ -9,33 +9,28 @@ import Thumbnail from '../../components/Thumbnail';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
class ImageZoom extends React.Component{
class ImageZoom extends React.Component {
constructor(props) {
super(props);
}
constructor(props){
super(props)
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Zoomed image');
}
componentDidMount(){
this.props.uiActions.setWindowTitle("Zoomed image");
}
render(){
return (
<Modal className="modal--image-zoom">
<img src={this.props.location.search.replace("?url=","")} />
</Modal>
)
}
render() {
return (
<Modal className="modal--image-zoom">
<img src={this.props.location.search.replace('?url=', '')} />
</Modal>
);
}
}
const mapStateToProps = (state) => {
return {}
}
const mapStateToProps = (state) => ({});
const mapDispatchToProps = (dispatch) => {
return {
uiActions: bindActionCreators(uiActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
uiActions: bindActionCreators(uiActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(ImageZoom)
export default connect(mapStateToProps, mapDispatchToProps)(ImageZoom);

View File

@ -11,145 +11,151 @@ import * as pusherActions from '../../services/pusher/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as helpers from '../../helpers';
class InitialSetup extends React.Component{
constructor(props){
super(props);
class InitialSetup extends React.Component {
constructor(props) {
super(props);
this.state = {
username: this.props.username,
allow_reporting: this.props.allow_reporting,
host: this.props.host,
port: this.props.port
}
}
this.state = {
username: this.props.username,
allow_reporting: this.props.allow_reporting,
host: this.props.host,
port: this.props.port,
};
}
componentDidMount(){
this.props.uiActions.setWindowTitle("Welcome to Iris");
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Welcome to Iris');
}
handleSubmit(e){
e.preventDefault();
var self = this;
handleSubmit(e) {
e.preventDefault();
const self = this;
// Only if we've changed the username do we set it
if (this.props.username !== this.state.username){
this.props.pusherActions.setUsername(this.state.username);
}
// Only if we've changed the username do we set it
if (this.props.username !== this.state.username) {
this.props.pusherActions.setUsername(this.state.username);
}
this.props.uiActions.set({
initial_setup_complete: true,
allow_reporting: this.state.allow_reporting
});
this.props.uiActions.set({
initial_setup_complete: true,
allow_reporting: this.state.allow_reporting,
});
this.props.mopidyActions.set({
host: this.state.host,
port: this.state.port
});
this.props.mopidyActions.set({
host: this.state.host,
port: this.state.port,
});
this.setState({saving: true});
this.setState({ saving: true });
// Wait a jiffy to allow changes to apply to store
setTimeout(() => {
// Wait a jiffy to allow changes to apply to store
setTimeout(() => {
// We've changed a connection setting, so need to reload
if (self.state.host !== self.props.host || self.state.port !== self.props.port) {
window.location = '/';
// We've changed a connection setting, so need to reload
if (self.state.host !== self.props.host || self.state.port !== self.props.port){
window.location = '/';
// Safe to just close modal
} else {
self.props.history.push('/');
}
},
200);
// Safe to just close modal
} else {
self.props.history.push('/');
}
},
200
);
return false;
}
return false;
}
render() {
return (
<Modal className="modal--initial-setup" noclose>
<h1>Get started</h1>
<form onSubmit={(e) => this.handleSubmit(e)}>
render(){
return (
<Modal className="modal--initial-setup" noclose>
<h1>Get started</h1>
<form onSubmit={(e) => this.handleSubmit(e)}>
<div className="field text">
<div className="name">
<div className="field text">
<div className="name">
Username
</div>
<div className="input">
<input
type="text"
onChange={e => this.setState({username: e.target.value.replace(/\W/g, '')})}
value={this.state.username } />
<div className="description">
</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ username: e.target.value.replace(/\W/g, '') })}
value={this.state.username}
/>
<div className="description">
A non-unique string used to identify this client (no special characters)
</div>
</div>
</div>
</div>
</div>
</div>
<div className="field">
<div className="name">Host</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({host: e.target.value})}
value={ this.state.host } />
</div>
</div>
<div className="field">
<div className="name">Port</div>
<div className="input">
<input
type="text"
onChange={ e => this.setState({port: e.target.value})}
value={ this.state.port } />
</div>
</div>
{helpers.isHosted() ? null : <div className="field checkbox">
<div className="input">
<label>
<input
type="checkbox"
name="allow_reporting"
checked={ this.state.allow_reporting }
onChange={ e => this.setState({ allow_reporting: !this.state.allow_reporting })} />
<span className="label">
<div className="field">
<div className="name">Host</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ host: e.target.value })}
value={this.state.host}
/>
</div>
</div>
<div className="field">
<div className="name">Port</div>
<div className="input">
<input
type="text"
onChange={(e) => this.setState({ port: e.target.value })}
value={this.state.port}
/>
</div>
</div>
{helpers.isHosted() ? null : (
<div className="field checkbox">
<div className="input">
<label>
<input
type="checkbox"
name="allow_reporting"
checked={this.state.allow_reporting}
onChange={(e) => this.setState({ allow_reporting: !this.state.allow_reporting })}
/>
<span className="label">
Allow reporting of anonymous usage statistics
</span>
</label>
<p className="description">This anonymous usage data is important in identifying errors and potential features that make Iris better for everyone. Want to know more? Read the <a href="https://github.com/jaedb/Iris/wiki/Terms-of-use#privacy-policy" target="_blank">privacy policy</a>{!this.state.allow_reporting ? <span className="red-text"> Are you sure you don't want to support this?</span> : null}. </p>
</div>
</div>}
</span>
</label>
<p className="description">
This anonymous usage data is important in identifying errors and potential features that make Iris better for everyone. Want to know more? Read the
<a href="https://github.com/jaedb/Iris/wiki/Terms-of-use#privacy-policy" target="_blank">privacy policy</a>
{!this.state.allow_reporting ? <span className="red-text"> Are you sure you don't want to support this?</span> : null}
.
{' '}
</p>
</div>
</div>
)}
<div className="actions centered-text">
<button className={"button button--primary button--large"+(this.state.saving ? " button--working" : "")} onClick={e => this.handleSubmit(e)}>
{this.state.saving ? "Saving" : "Save"}
</button>
</div>
<div className="actions centered-text">
<button className={`button button--primary button--large${this.state.saving ? ' button--working' : ''}`} onClick={(e) => this.handleSubmit(e)}>
{this.state.saving ? 'Saving' : 'Save'}
</button>
</div>
</form>
</Modal>
)
}
</form>
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
allow_reporting: state.ui.allow_reporting,
username: (state.pusher && state.pusher.username ? state.pusher.username : null),
host: state.mopidy.host,
port: state.mopidy.port
}
}
const mapStateToProps = (state, ownProps) => ({
allow_reporting: state.ui.allow_reporting,
username: (state.pusher && state.pusher.username ? state.pusher.username : null),
host: state.mopidy.host,
port: state.mopidy.port,
});
const mapDispatchToProps = (dispatch) => {
return {
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
pusherActions: bindActionCreators(pusherActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
coreActions: bindActionCreators(coreActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
pusherActions: bindActionCreators(pusherActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(InitialSetup)
export default connect(mapStateToProps, mapDispatchToProps)(InitialSetup);

View File

@ -1,8 +1,8 @@
import React from 'react';
import { connect } from 'react-redux';
import Link from '../../components/Link'
import { createStore, bindActionCreators } from 'redux';
import Link from '../../components/Link';
import Modal from './Modal';
import Thumbnail from '../../components/Thumbnail';
@ -15,89 +15,84 @@ import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
class KioskMode extends React.Component{
class KioskMode extends React.Component {
constructor(props) {
super(props);
}
constructor(props){
super(props)
}
componentDidMount() {
this.setWindowTitle();
}
componentDidMount(){
this.setWindowTitle();
}
componentWillReceiveProps(nextProps) {
if (!this.props.current_track && nextProps.current_track) {
this.setWindowTitle(nextProps.current_track);
}
}
componentWillReceiveProps(nextProps){
if (!this.props.current_track && nextProps.current_track){
this.setWindowTitle(nextProps.current_track);
}
}
setWindowTitle(current_track = this.props.current_track) {
if (current_track) {
let artists = '';
for (let i = 0; i < current_track.artists.length; i++) {
if (artists != '') {
artists += ', ';
}
artists += current_track.artists[i].name;
}
this.props.uiActions.setWindowTitle(`${current_track.name} by ${artists} (now playing)`);
} else {
this.props.uiActions.setWindowTitle('Now playing');
}
}
setWindowTitle(current_track = this.props.current_track){
if (current_track){
var artists = "";
for (var i = 0; i < current_track.artists.length; i++){
if (artists != ""){
artists += ", ";
}
artists += current_track.artists[i].name;
}
this.props.uiActions.setWindowTitle(current_track.name+" by "+artists+" (now playing)");
} else{
this.props.uiActions.setWindowTitle("Now playing");
}
}
togglePlay(e) {
if (this.props.play_state == 'playing') {
this.props.mopidyActions.pause();
} else {
this.props.mopidyActions.play();
}
}
togglePlay(e){
if (this.props.play_state == 'playing'){
this.props.mopidyActions.pause();
} else {
this.props.mopidyActions.play();
}
}
render() {
if (this.props.current_track && this.props.current_track.images) {
var { images } = this.props.current_track;
} else {
var images = [];
}
render(){
if (this.props.current_track && this.props.current_track.images){
var images = this.props.current_track.images
} else {
var images = []
}
return (
<Modal className="modal--kiosk-mode">
return (
<Modal className="modal--kiosk-mode">
<Thumbnail className="background" images={images} />
<Thumbnail className="background" images={images} />
<div className="artwork" onClick={e => this.togglePlay(e)}>
<Thumbnail images={images} />
{this.props.play_state == 'playing' ? <Icon name="pause_circle_filled" /> : <Icon name="play_circle_filled" />}
</div>
<div className="artwork" onClick={(e) => this.togglePlay(e)}>
<Thumbnail images={images} />
{this.props.play_state == 'playing' ? <Icon name="pause_circle_filled" /> : <Icon name="play_circle_filled" />}
</div>
<div className="player">
<div className="current-track">
<div className="title">{ this.props.current_track ? this.props.current_track.name : <span>-</span> }</div>
{ this.props.current_track ? <ArtistSentence nolinks artists={ this.props.current_track.artists } /> : <ArtistSentence /> }
</div>
<div className="player">
<div className="current-track">
<div className="title">{ this.props.current_track ? this.props.current_track.name : <span>-</span> }</div>
{ this.props.current_track ? <ArtistSentence nolinks artists={this.props.current_track.artists} /> : <ArtistSentence /> }
</div>
<div className="progress-wrapper">
<ProgressSlider />
</div>
</div>
</Modal>
)
}
<div className="progress-wrapper">
<ProgressSlider />
</div>
</div>
</Modal>
);
}
}
const mapStateToProps = (state) => {
return {
play_state: state.mopidy.play_state,
current_track: (state.core.current_track && state.core.tracks[state.core.current_track.uri] !== undefined ? state.core.tracks[state.core.current_track.uri] : null),
}
}
const mapStateToProps = (state) => ({
play_state: state.mopidy.play_state,
current_track: (state.core.current_track && state.core.tracks[state.core.current_track.uri] !== undefined ? state.core.tracks[state.core.current_track.uri] : null),
});
const mapDispatchToProps = (dispatch) => {
return {
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
uiActions: bindActionCreators(uiActions, dispatch),
mopidyActions: bindActionCreators(mopidyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(KioskMode)
export default connect(mapStateToProps, mapDispatchToProps)(KioskMode);

View File

@ -3,55 +3,51 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as helpers from '../../helpers'
import Icon from '../../components/Icon'
import * as helpers from '../../helpers';
import Icon from '../../components/Icon';
class Modal extends React.Component{
class Modal extends React.Component {
constructor(props) {
super(props);
}
constructor(props){
super(props);
}
componentWillMount() {
$('body').addClass('modal-open');
}
componentWillMount(){
$('body').addClass('modal-open');
}
componentWillUnmount() {
$('body').removeClass('modal-open');
}
componentWillUnmount(){
$('body').removeClass('modal-open');
}
render() {
let className = 'modal';
if (this.props.className) {
className += ` ${this.props.className}`;
}
render(){
return (
<div className={className}>
var className = "modal";
if (this.props.className){
className += " "+this.props.className;
}
<div className="controls">
{this.props.noclose ? null : (
<div className="control close" onClick={(e) => window.history.back()}>
<Icon name="close" className="white" />
</div>
) }
</div>
return (
<div className={className}>
<div className="controls">
{this.props.noclose ? null : <div className="control close" onClick={e => window.history.back()}>
<Icon name="close" className="white" />
</div> }
</div>
<div className="content">
{this.props.children}
</div>
</div>
);
}
<div className="content">
{this.props.children}
</div>
</div>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
shortkeys_enabled: state.ui.shortkeys_enabled
}
}
const mapStateToProps = (state, ownProps) => ({
shortkeys_enabled: state.ui.shortkeys_enabled,
});
const mapDispatchToProps = (dispatch) => {
return {}
}
const mapDispatchToProps = (dispatch) => ({});
export default connect(mapStateToProps, mapDispatchToProps)(Modal)
export default connect(mapStateToProps, mapDispatchToProps)(Modal);

View File

@ -1,8 +1,8 @@
import React from 'react'
import { connect } from 'react-redux'
import Link from '../../components/Link'
import { createStore, bindActionCreators } from 'redux'
import React from 'react';
import { connect } from 'react-redux';
import { createStore, bindActionCreators } from 'redux';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
@ -11,208 +11,221 @@ import * as uiActions from '../../services/ui/actions';
import * as pusherActions from '../../services/pusher/actions';
import * as helpers from '../../helpers';
class ShareConfiguration extends React.Component {
class ShareConfiguration extends React.Component {
constructor(props) {
super(props);
constructor(props){
super(props);
this.state = {
recipients: [],
spotify: false,
lastfm: false,
genius: false,
ui: false,
};
}
this.state = {
recipients: [],
spotify: false,
lastfm: false,
genius: false,
ui: false
};
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Share configuration');
}
componentDidMount(){
this.props.uiActions.setWindowTitle("Share configuration");
}
toggleRecipient(id) {
const { recipients } = this.state;
if (recipients.includes(id)) {
const index = recipients.indexOf(id);
recipients.splice(index, 1);
} else {
recipients.push(id);
}
this.setState({ recipients });
}
toggleRecipient(id){
var recipients = this.state.recipients;
if (recipients.includes(id)){
var index = recipients.indexOf(id);
recipients.splice(index,1);
} else {
recipients.push(id);
}
this.setState({recipients: recipients});
}
handleSubmit(e) {
e.preventDefault();
handleSubmit(e){
e.preventDefault();
const configuration = {};
if (this.state.spotify) {
configuration.spotify = {
authorization: this.props.spotify_authorization,
me: this.props.spotify_me,
};
}
if (this.state.genius) {
configuration.genius = {
authorization: this.props.genius_authorization,
me: this.props.genius_me,
};
}
if (this.state.lastfm) {
configuration.lastfm = {
authorization: this.props.lastfm_authorization,
me: this.props.lastfm_me,
};
}
if (this.state.ui) {
configuration.ui = this.props.ui;
}
var configuration = {};
if (this.state.spotify){
configuration.spotify = {
authorization: this.props.spotify_authorization,
me: this.props.spotify_me
}
}
if (this.state.genius){
configuration.genius = {
authorization: this.props.genius_authorization,
me: this.props.genius_me
}
}
if (this.state.lastfm){
configuration.lastfm = {
authorization: this.props.lastfm_authorization,
me: this.props.lastfm_me
}
}
if (this.state.ui){
configuration.ui = this.props.ui;
}
for (const recipient of this.state.recipients) {
this.props.pusherActions.deliverMessage(
recipient,
'share_configuration_received',
configuration,
);
}
for (var recipient of this.state.recipients){
this.props.pusherActions.deliverMessage(
recipient,
'share_configuration_received',
configuration
);
}
window.history.back();
}
window.history.back();
return;
}
render() {
const connections = [];
for (const connection_id in this.props.connections) {
if (this.props.connections.hasOwnProperty(connection_id) && connection_id != this.props.connection_id) {
connections.push(this.props.connections[connection_id]);
}
}
render(){
var connections = []
for (var connection_id in this.props.connections){
if (this.props.connections.hasOwnProperty(connection_id) && connection_id != this.props.connection_id){
connections.push(this.props.connections[connection_id])
}
}
if (connections.length > 0){
var recipients = (
<div className="input">
{
connections.map((connection, index) => {
return (
<label key={connection.connection_id}>
<input
type="checkbox"
name={"connection_"+connection.connection_id}
checked={this.state.recipients.includes(connection.connection_id)}
onChange={e => this.toggleRecipient(connection.connection_id)}
/>
<span className="label">
<div className="title">{ connection.username }</div>
<div className="description mid_grey-text">
({ connection.ip })
</div>
</span>
</label>
);
})
if (connections.length > 0) {
var recipients = (
<div className="input">
{
connections.map((connection, index) => (
<label key={connection.connection_id}>
<input
type="checkbox"
name={`connection_${connection.connection_id}`}
checked={this.state.recipients.includes(connection.connection_id)}
onChange={(e) => this.toggleRecipient(connection.connection_id)}
/>
<span className="label">
<div className="title">{ connection.username }</div>
<div className="description mid_grey-text">
(
{ connection.ip }
)
</div>
</span>
</label>
))
}
</div>
);
} else {
var recipients = (
<div className="input text">
<span className="mid_grey-text">
</div>
);
} else {
var recipients = (
<div className="input text">
<span className="mid_grey-text">
No peer connections
</span>
</div>
);
}
</span>
</div>
);
}
return (
<Modal className="modal--share-configuration">
<h1>Share configuration</h1>
<h2>Push your authorizations and interface settings to another, connected user</h2>
return (
<Modal className="modal--share-configuration">
<form onSubmit={e => this.handleSubmit(e)}>
<div className="field checkbox white">
<div className="name">Recipients</div>
{recipients}
</div>
<h1>Share configuration</h1>
<h2>Push your authorizations and interface settings to another, connected user</h2>
<div className="field checkbox checkbox--block">
<div className="name">Configurations</div>
<div className="input">
<label>
<input
type="checkbox"
name="interface"
checked={ this.state.ui }
onChange={ e => this.setState({ ui: !this.state.ui })} />
<span className="label">
<span className="title">UI customisation (theme, sorting, filters)</span>
</span>
</label>
<form onSubmit={(e) => this.handleSubmit(e)}>
<div className="field checkbox white">
<div className="name">Recipients</div>
{recipients}
</div>
{this.props.spotify_me && this.props.spotify_authorization ? <label>
<input
type="checkbox"
name="spotify"
checked={this.state.spotify}
onChange={ e => this.setState({ spotify: !this.state.spotify })} />
<span className="label">
<div className="title">Spotify authorization</div>
<div className="description mid_grey-text">Logged in as {this.props.spotify_me.name}</div>
</span>
</label> : null}
<div className="field checkbox checkbox--block">
<div className="name">Configurations</div>
<div className="input">
<label>
<input
type="checkbox"
name="interface"
checked={this.state.ui}
onChange={(e) => this.setState({ ui: !this.state.ui })}
/>
<span className="label">
<span className="title">UI customisation (theme, sorting, filters)</span>
</span>
</label>
{this.props.lastfm_me && this.props.lastfm_authorization ? <label>
<input
type="checkbox"
name="lastfm_authorization"
checked={this.state.lastfm}
onChange={ e => this.setState({ lastfm: !this.state.lastfm })} />
<span className="label">
<div className="title">LastFM authorization</div>
<div className="description mid_grey-text">Logged in as {this.props.lastfm_me.name}</div>
</span>
</label> : null}
{this.props.spotify_me && this.props.spotify_authorization ? (
<label>
<input
type="checkbox"
name="spotify"
checked={this.state.spotify}
onChange={(e) => this.setState({ spotify: !this.state.spotify })}
/>
<span className="label">
<div className="title">Spotify authorization</div>
<div className="description mid_grey-text">
Logged in as
{this.props.spotify_me.name}
</div>
</span>
</label>
) : null}
{this.props.genius_me && this.props.genius_authorization ? <label>
<input
type="checkbox"
name="genius_authorization"
checked={this.state.genius}
onChange={ e => this.setState({ genius: !this.state.genius })} />
<span className="label">
<div className="title">Genius authorization</div>
<div className="description mid_grey-text">Logged in as {this.props.genius_me.name}</div>
</span>
</label> : null}
</div>
</div>
{this.props.lastfm_me && this.props.lastfm_authorization ? (
<label>
<input
type="checkbox"
name="lastfm_authorization"
checked={this.state.lastfm}
onChange={(e) => this.setState({ lastfm: !this.state.lastfm })}
/>
<span className="label">
<div className="title">LastFM authorization</div>
<div className="description mid_grey-text">
Logged in as
{this.props.lastfm_me.name}
</div>
</span>
</label>
) : null}
<div className="actions centered-text">
{this.state.recipients.length > 0 ? <button className="button button--primary button--large" onClick={e => this.handleSubmit(e)}>Send</button> : <button className="button button--primary button--large" disabled="disabled" onClick={e => this.handleSubmit(e)}>Send</button>}
</div>
</form>
</Modal>
)
}
{this.props.genius_me && this.props.genius_authorization ? (
<label>
<input
type="checkbox"
name="genius_authorization"
checked={this.state.genius}
onChange={(e) => this.setState({ genius: !this.state.genius })}
/>
<span className="label">
<div className="title">Genius authorization</div>
<div className="description mid_grey-text">
Logged in as
{this.props.genius_me.name}
</div>
</span>
</label>
) : null}
</div>
</div>
<div className="actions centered-text">
{this.state.recipients.length > 0 ? <button className="button button--primary button--large" onClick={(e) => this.handleSubmit(e)}>Send</button> : <button className="button button--primary button--large" disabled="disabled" onClick={(e) => this.handleSubmit(e)}>Send</button>}
</div>
</form>
</Modal>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
spotify_authorization: state.spotify.authorization,
spotify_me: state.spotify.me,
genius_authorization: state.genius.authorization,
genius_me: state.genius.me,
lastfm_authorization: state.lastfm.authorization,
lastfm_me: state.lastfm.me,
ui: state.ui,
connection_id: state.pusher.connection_id,
connections: state.pusher.connections
}
}
const mapStateToProps = (state, ownProps) => ({
spotify_authorization: state.spotify.authorization,
spotify_me: state.spotify.me,
genius_authorization: state.genius.authorization,
genius_me: state.genius.me,
lastfm_authorization: state.lastfm.authorization,
lastfm_me: state.lastfm.me,
ui: state.ui,
connection_id: state.pusher.connection_id,
connections: state.pusher.connections,
});
const mapDispatchToProps = (dispatch) => {
return {
pusherActions: bindActionCreators(pusherActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch)
}
}
const mapDispatchToProps = (dispatch) => ({
pusherActions: bindActionCreators(pusherActions, dispatch),
uiActions: bindActionCreators(uiActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(ShareConfiguration)
export default connect(mapStateToProps, mapDispatchToProps)(ShareConfiguration);