2018-05-30 21:39:38 +12:00
|
|
|
|
|
|
|
|
import React, { PropTypes } from 'react'
|
|
|
|
|
import { connect } from 'react-redux'
|
|
|
|
|
import { bindActionCreators } from 'redux'
|
|
|
|
|
|
|
|
|
|
import VolumeControl from './VolumeControl'
|
|
|
|
|
import Icon from '../Icon'
|
|
|
|
|
|
|
|
|
|
import * as helpers from '../../helpers'
|
2018-07-01 21:08:35 +12:00
|
|
|
import * as coreActions from '../../services/core/actions'
|
2018-05-30 21:39:38 +12:00
|
|
|
import * as pusherActions from '../../services/pusher/actions'
|
|
|
|
|
|
2018-07-01 21:08:35 +12:00
|
|
|
class OutputControl extends React.Component{
|
2018-05-30 21:39:38 +12:00
|
|
|
|
|
|
|
|
constructor(props){
|
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
|
expanded: false
|
|
|
|
|
}
|
2018-05-31 21:34:50 +12:00
|
|
|
|
|
|
|
|
this.handleClick = this.handleClick.bind(this);
|
2018-05-30 21:39:38 +12:00
|
|
|
}
|
|
|
|
|
|
2018-05-31 21:34:50 +12:00
|
|
|
handleClick(e){
|
2018-07-01 21:08:35 +12:00
|
|
|
if ($(e.target).closest('.output-control').length <= 0){
|
2018-05-31 21:34:50 +12:00
|
|
|
this.setExpanded(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setExpanded(expanded = !this.state.expanded){
|
|
|
|
|
if (expanded){
|
|
|
|
|
this.setState({expanded: expanded});
|
|
|
|
|
window.addEventListener("click", this.handleClick, false);
|
2018-07-01 21:08:35 +12:00
|
|
|
|
|
|
|
|
// Re-check our snapcast clients
|
|
|
|
|
// TODO: Once we have push events, remove this as it'll (marginally)
|
|
|
|
|
// slow down the reveal/render
|
|
|
|
|
if (this.props.pusher_connected && this.props.snapcast_enabled){
|
|
|
|
|
this.props.pusherActions.getSnapcast();
|
|
|
|
|
}
|
2018-05-31 21:34:50 +12:00
|
|
|
} else {
|
|
|
|
|
this.setState({expanded: expanded});
|
|
|
|
|
window.removeEventListener("click", this.handleClick, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-01 21:08:35 +12:00
|
|
|
renderOutputs(){
|
2018-05-30 21:39:38 +12:00
|
|
|
|
|
|
|
|
var clients = [];
|
|
|
|
|
for (var key in this.props.snapcast_clients){
|
|
|
|
|
if (this.props.snapcast_clients.hasOwnProperty(key)){
|
|
|
|
|
var client = this.props.snapcast_clients[key];
|
2018-06-01 20:44:30 +12:00
|
|
|
if (client.connected){
|
2018-05-30 21:39:38 +12:00
|
|
|
clients.push(client);
|
2018-06-01 20:44:30 +12:00
|
|
|
}
|
2018-05-30 21:39:38 +12:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
2018-07-01 21:08:35 +12:00
|
|
|
<div className="outputs">
|
|
|
|
|
{this.props.http_streaming_enabled ? <div className="output icecast-output">
|
2018-07-04 21:10:51 +12:00
|
|
|
<div className="actions">
|
|
|
|
|
<span className="action" onClick={e => this.props.coreActions.cachebustHttpStream()}>
|
|
|
|
|
<Icon name="refresh" />
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="name">
|
2018-07-01 21:08:35 +12:00
|
|
|
Local browser
|
2018-07-04 21:10:51 +12:00
|
|
|
</div>
|
2018-07-01 21:08:35 +12:00
|
|
|
<VolumeControl
|
|
|
|
|
className="client-volume-control"
|
|
|
|
|
volume={this.props.http_streaming_volume}
|
|
|
|
|
mute={this.props.http_streaming_mute}
|
|
|
|
|
onVolumeChange={percent => this.props.coreActions.set({http_streaming_volume: percent})}
|
|
|
|
|
onMuteChange={mute => this.props.coreActions.set({http_streaming_mute: mute})}
|
|
|
|
|
/>
|
|
|
|
|
</div> : null}
|
2018-05-30 21:39:38 +12:00
|
|
|
{
|
|
|
|
|
clients.map(client => {
|
|
|
|
|
var name = client.config.name ? client.config.name : client.host.name;
|
|
|
|
|
|
|
|
|
|
return (
|
2018-07-01 21:08:35 +12:00
|
|
|
<div className="output snapcast-output" key={client.id}>
|
2018-07-04 21:10:51 +12:00
|
|
|
<div className="name">
|
2018-05-30 21:39:38 +12:00
|
|
|
{name}
|
2018-07-04 21:10:51 +12:00
|
|
|
</div>
|
2018-05-30 21:39:38 +12:00
|
|
|
<VolumeControl
|
|
|
|
|
className="client-volume-control"
|
|
|
|
|
volume={client.config.volume.percent}
|
|
|
|
|
mute={client.config.volume.muted}
|
|
|
|
|
onVolumeChange={percent => this.props.pusherActions.setSnapcastClientVolume(client.id, percent)}
|
|
|
|
|
onMuteChange={mute => this.props.pusherActions.setSnapcastClientMute(client.id, mute)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render(){
|
|
|
|
|
if (this.state.expanded){
|
|
|
|
|
return (
|
2018-07-01 21:08:35 +12:00
|
|
|
<span className="output-control">
|
2018-05-31 21:34:50 +12:00
|
|
|
<a className="control speakers active" onClick={e => this.setExpanded()}><Icon name="speaker" /></a>
|
2018-07-01 21:08:35 +12:00
|
|
|
{this.renderOutputs()}
|
2018-05-30 21:39:38 +12:00
|
|
|
</span>
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return (
|
2018-07-01 21:08:35 +12:00
|
|
|
<span className="output-control">
|
2018-05-31 21:34:50 +12:00
|
|
|
<a className="control speakers" onClick={e => this.setExpanded()}><Icon name="speaker" /></a>
|
2018-05-30 21:39:38 +12:00
|
|
|
</span>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mapStateToProps = (state, ownProps) => {
|
|
|
|
|
return {
|
2018-07-01 21:08:35 +12:00
|
|
|
http_streaming_enabled: state.core.http_streaming_enabled,
|
|
|
|
|
http_streaming_volume: state.core.http_streaming_volume,
|
|
|
|
|
http_streaming_mute: state.core.http_streaming_mute,
|
2018-05-30 21:39:38 +12:00
|
|
|
snapcast_enabled: state.pusher.config.snapcast_enabled,
|
|
|
|
|
pusher_connected: state.pusher.connected,
|
|
|
|
|
snapcast_clients: state.pusher.snapcast_clients
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mapDispatchToProps = (dispatch) => {
|
|
|
|
|
return {
|
2018-07-01 21:08:35 +12:00
|
|
|
coreActions: bindActionCreators(coreActions, dispatch),
|
2018-05-30 21:39:38 +12:00
|
|
|
pusherActions: bindActionCreators(pusherActions, dispatch)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-01 21:08:35 +12:00
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(OutputControl)
|