import React, { PropTypes } from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' import { Link, hashHistory } from 'react-router' import ArtistSentence from './ArtistSentence' import VolumeControl from './Fields/VolumeControl' import LatencyControl from './Fields/LatencyControl' import TextField from './Fields/TextField' import DropdownField from './Fields/DropdownField' import * as helpers from '../helpers' import * as coreActions from '../services/core/actions' import * as uiActions from '../services/ui/actions' import * as pusherActions from '../services/pusher/actions' class Snapcast extends React.Component{ constructor(props){ super(props); } componentDidMount(){ if (this.props.pusher_connected && this.props.snapcast_enabled){ this.props.pusherActions.getSnapcast(); } } componentWillReceiveProps(newProps){ // Just connected if (newProps.snapcast_enabled && !this.props.pusher_connected && newProps.pusher_connected){ this.props.pusherActions.getSnapcast(); // Just enabled // This is the more probable scenario as we don't know if we're enabled until pusher connects // and then gets the config from the server } else if (!this.props.snapcast_enabled && newProps.snapcast_enabled && newProps.pusher_connected){ this.props.pusherActions.getSnapcast(); } } renderClientsList(group, groups){ if (!group.clients || group.clients.length <= 0){ return (
No clients
); } return (
{ group.clients.map(client => { var name = client.config.name ? client.config.name : client.host.name; var groups_dropdown = []; for (var i = 0; i < groups.length; i++){ // Don't add our existing group if (groups[i].id !== group.id){ groups_dropdown.push({ label: (groups[i].name ? groups[i].name : 'Group '+groups[i].id.substring(0,3)), value: groups[i].id }); } } // And append with 'New group' (which is actually // the existing group and middleware handles the behavior shift) groups_dropdown.push({ label: 'New group', value: group.id, className: 'grey-text' }); return (
{this.props.pusherActions.setSnapcastClientGroup(client.id, value); this.props.uiActions.hideContextMenu()}} /> this.props.pusherActions.setSnapcastClientName(client.id, value)} value={name} />
this.props.pusherActions.setSnapcastClientVolume(client.id, percent)} onMuteChange={mute => this.props.pusherActions.setSnapcastClientMute(client.id, mute)} /> this.props.pusherActions.setSnapcastClientVolume(client.id, parseInt(value))} value={client.config.volume.percent} />
this.props.pusherActions.setSnapcastClientLatency(client.id, parseInt(value))} /> this.props.pusherActions.setSnapcastClientLatency(client.id, parseInt(value))} value={String(client.config.latency)} />
); }) }
); } render(){ if (!this.props.snapcast_enabled){ return (
To enable Snapcast, edit your mopidy.conf file
) } if (!this.props.snapcast_clients || !this.props.snapcast_groups){ return (
) } var streams = []; for (var key in this.props.snapcast_streams){ if (this.props.snapcast_streams.hasOwnProperty(key)){ streams.push(this.props.snapcast_streams[key]); } } // Construct a simple array of our groups index var groups = []; for (var group_id in this.props.snapcast_groups){ if (this.props.snapcast_groups.hasOwnProperty(group_id)){ var group = this.props.snapcast_groups[group_id]; // Merge the group's clients into this group (also as a simple array) var clients = []; for (var i = 0; i < group.clients_ids.length; i++){ if (this.props.snapcast_clients.hasOwnProperty(group.clients_ids[i])){ var client = this.props.snapcast_clients[group.clients_ids[i]]; if (client.connected || this.props.snapcast_show_disconnected_clients){ clients.push(client); } } } groups.push(Object.assign( {}, group, { clients: clients } )); } } return (
Display
{ groups.map(group => { // Average our clients' volume for an overall group volume var group_volume = 0; for (var i = 0; i < group.clients.length; i++){ var client = group.clients[i]; group_volume += client.config.volume.percent; } group_volume = group_volume / group.clients.length; return (
Name
{group.name ? group.name : 'Group '+group.id.substring(0,3)}   ({group.id})
Stream
Volume
this.props.pusherActions.setSnapcastGroupVolume(group.id, percent, old_percent)} onMuteChange={mute => this.props.pusherActions.setSnapcastGroupMute(group.id, mute)} />
Clients
{this.renderClientsList(group, groups)}
); }) }
); } } const mapStateToProps = (state, ownProps) => { return { snapcast_enabled: state.pusher.config.snapcast_enabled, pusher_connected: state.pusher.connected, snapcast_show_disconnected_clients: (state.ui.snapcast_show_disconnected_clients !== undefined ? state.ui.snapcast_show_disconnected_clients : false), snapcast_streams: state.pusher.snapcast_streams, snapcast_groups: state.pusher.snapcast_groups, snapcast_clients: state.pusher.snapcast_clients } } const mapDispatchToProps = (dispatch) => { return { coreActions: bindActionCreators(coreActions, dispatch), uiActions: bindActionCreators(uiActions, dispatch), pusherActions: bindActionCreators(pusherActions, dispatch) } } export default connect(mapStateToProps, mapDispatchToProps)(Snapcast)