import React from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import Link from './Link'; import VolumeControl from './Fields/VolumeControl'; import MuteControl from './Fields/MuteControl'; import LatencyControl from './Fields/LatencyControl'; import TextField from './Fields/TextField'; import DropdownField from './Fields/DropdownField'; import Icon from './Icon'; 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'; import * as snapcastActions from '../services/snapcast/actions'; class Snapcast extends React.Component{ constructor(props){ super(props); this.state = { clients_expanded: [] } } componentDidMount(){ if (this.props.pusher_connected && this.props.snapcast_enabled){ this.props.snapcastActions.getServer(); } } componentWillReceiveProps(newProps){ // Just connected if (newProps.snapcast_enabled && !this.props.pusher_connected && newProps.pusher_connected){ this.props.snapcastActions.getServer(); // 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.snapcastActions.getServer(); } } toggleClientExpanded(client_id){ var clients_expanded = this.state.clients_expanded; var index = clients_expanded.indexOf(client_id); if (index >= 0){ clients_expanded.splice(index, 1); } else { clients_expanded.push(client_id); } this.setState({clients_expanded: clients_expanded}); } renderClientsList(group, groups){ if (!this.props.show_disconnected_clients && group.clients){ var clients = helpers.applyFilter('connected', true, group.clients); } else { var clients = group.clients; } if (!clients || clients.length <= 0){ return (
No clients
); } return (
{ clients.map(client => { var class_name = "list__item list__item--no-interaction snapcast__client"; if (client.connected){ class_name += " snapcast__client--connected"; } else { class_name += " snapcast__client--disconnected"; } if (this.state.clients_expanded.includes(client.id)){ return (
this.toggleClientExpanded(client.id)}> {client.name}
{!client.connected ? : null}
Volume
this.props.snapcastActions.setClientMute(client.id, mute)} /> this.props.snapcastActions.setClientVolume(client.id, percent)} />
Latency
this.props.snapcastActions.setClientLatency(client.id, parseInt(value))} /> this.props.snapcastActions.setClientLatency(client.id, parseInt(value))} value={String(client.latency)} />
); } else { return (
this.toggleClientExpanded(client.id)}> {client.name}
{!client.connected ? : null}
); } }) }
); } render(){ if (!this.props.snapcast_enabled){ return (

To enable Snapcast, edit your mopidy.conf file

) } var streams = []; for (var id in this.props.streams){ if (this.props.streams.hasOwnProperty(id)){ streams.push(this.props.streams[id]); } } var groups = []; for (var id in this.props.groups){ if (this.props.groups.hasOwnProperty(id)){ groups.push(this.props.groups[id]); } } return (
Display
{ groups.map(group => { group = helpers.collate(group, {clients: this.props.clients}); // 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.volume; } group_volume = group_volume / group.clients.length; return (
Name
{group.name}   ({group.id})
Stream
Volume
this.props.snapcastActions.setGroupMute(group.id, mute)} /> this.props.snapcastActions.setGroupVolume(group.id, percent, old_percent)} />
Clients
{this.renderClientsList(group, groups)}
); }) }
); } } const mapStateToProps = (state, ownProps) => { return { snapcast_enabled: state.pusher.config.snapcast_enabled, pusher_connected: state.pusher.connected, show_disconnected_clients: (state.ui.snapcast_show_disconnected_clients !== undefined ? state.ui.snapcast_show_disconnected_clients : false), streams: (state.snapcast.streams ? state.snapcast.streams : null), groups: (state.snapcast.groups ? state.snapcast.groups : null), clients: (state.snapcast.clients ? state.snapcast.clients : null) } } const mapDispatchToProps = (dispatch) => { return { coreActions: bindActionCreators(coreActions, dispatch), uiActions: bindActionCreators(uiActions, dispatch), snapcastActions: bindActionCreators(snapcastActions, dispatch), pusherActions: bindActionCreators(pusherActions, dispatch) } } export default connect(mapStateToProps, mapDispatchToProps)(Snapcast)