+ {
+ sortItems(groups, 'name').map((simpleGroup) => {
+ const group = collate(simpleGroup, { clients });
+ let { clients: groupClients = [] } = group;
+ if (!showAllClients) {
+ groupClients = applyFilter('connected', true, groupClients);
+ }
- setExpanded(expanded = !this.state.expanded, props = this.props) {
- if (expanded) {
- this.setState({ expanded });
- window.addEventListener('click', this.handleClick, false);
+ if (!groupClients.length) return null;
- // Re-check our snapcast clients
- // TODO: Once we have push events, remove this as it'll (marginally)
- // slow down the reveal/render
- if (props.pusher_connected && props.snapcast_enabled) {
- this.props.snapcastActions.getServer();
- }
- } else {
- this.setState({ expanded });
- window.removeEventListener('click', this.handleClick, false);
- }
- }
+ const volume = groupClients.reduce(
+ (acc, client) => acc + (client.volume || 0),
+ 0,
+ ) / groupClients.length;
- handleClick(e) {
- if (!this.props.force_expanded && $(e.target).closest('.output-control').length <= 0) {
- this.setExpanded(false);
- }
- }
-
- snapcastGroups() {
- const {
- snapcast_streams,
- snapcastActions,
- snapcast_groups,
- snapcast_clients: clients,
- show_disconnected_clients,
- } = this.props;
-
- const groups = indexToArray(snapcast_groups);
- if (groups.length <= 0) return null;
-
- const streams = Object.keys(snapcast_streams).map(
- (id) => ({ value: id, label: id }),
- );
-
- return (
-
- {
- sortItems(groups, 'name').map((simpleGroup) => {
- const group = collate(simpleGroup, { clients });
- let { clients: groupClients = [] } = group;
- if (!show_disconnected_clients) {
- groupClients = applyFilter('connected', true, groupClients);
- }
-
- if (!groupClients.length) return null;
-
- const volume = groupClients.reduce(
- (acc, client) => acc + (client.volume || 0),
- 0,
- ) / groupClients.length;
-
- return (
-
-
- {group.name}
-
-
- snapcastActions.setGroupStream(group.id, value)}
- />
- snapcastActions.setGroupMute(group.id, mute)}
- />
- snapcastActions.setGroupVolume(group.id, percent, previousPercent)}
- />
-
+ return (
+
+
+ {group.name}
+
+
+ dispatch(snapcastActions.setGroupStream(group.id, value))}
+ />
+ dispatch(snapcastActions.setGroupMute(group.id, mute))}
+ />
+ dispatch(
+ snapcastActions.setGroupVolume(group.id, percent, previousPercent)
+ )
+ }
+ />
- );
- })
- }
-
- );
- }
-
- commands() {
- const {
- pusher_commands,
- pusherActions,
- } = this.props;
-
- if (!pusher_commands) return null;
-
- let items = indexToArray(pusher_commands);
- if (items.length <= 0) return null;
-
- items = sortItems(items, 'sort_order');
-
- return (
-
- {
- items.map((command) => (
-
pusherActions.runCommand(command.id)}
- >
-
-
- ))
- }
-
- );
- }
+ );
+ })
+ }
+
+ );
+}
- renderOutputs() {
- const snapcastGroups = this.snapcastGroups();
- const commands = this.commands();
+const Commands = () => {
+ const dispatch = useDispatch();
+ const commandsObj = useSelector((state) => state.pusher.commands || {});
+ if (!commandsObj) return null;
- if (!snapcastGroups && !commands) {
- return (
-
- );
- }
+ let items = indexToArray(commandsObj);
+ if (items.length <= 0) return null;
+
+ items = sortItems(items, 'sort_order');
+
+ return (
+
+ {
+ items.map((command) => (
+
dispatch(pusherActions.runCommand(command.id))}
+ >
+
+
+
+ ))
+ }
+
+ );
+}
+
+const Outputs = () => {
+ const snapcastGroups =
;
+ const commands =
;
+
+ if (!snapcastGroups && !commands) {
return (
-
- {commands}
- {snapcastGroups}
+
);
}
+ return (
+
+ {commands}
+ {snapcastGroups}
+
+ );
+}
- render() {
- if (this.state.expanded) {
- return (
-
-
- {this.renderOutputs()}
-
- );
+const OutputControl = ({
+ force_expanded,
+ pusher_commands,
+ snapcast_enabled,
+}) => {
+ const [expanded, setExpanded] = useState(false);
+ const handleClick = (e) => {
+ if (!force_expanded && $(e.target).closest('.output-control').length <= 0) {
+ setExpanded(false);
}
+ };
- // No customisable outputs
- if (!this.props.snapcast_enabled && !this.props.pusher_commands) {
- return (
-
-
-
- );
+ useEffect(() => {
+ if (force_expanded && !expanded) {
+ setExpanded(true);
}
+ }, [force_expanded]);
+
+ useEffect(() => {
+ if (expanded) {
+ window.addEventListener('click', handleClick, false);
+ } else {
+ window.removeEventListener('click', handleClick, false);
+ }
+ }, [expanded]);
+
+ if (expanded) {
return (
-
+
+
);
}
+
+ // No customisable outputs
+ if (!snapcast_enabled && !pusher_commands) {
+ return (
+
+
+
+ );
+ }
+ return (
+
+
+
+ );
}
const mapStateToProps = (state) => ({
pusher_connected: state.pusher.connected,
snapcast_enabled: (state.pusher.config ? state.pusher.config.snapcast_enabled : null),
- show_disconnected_clients: state.ui.snapcast_show_disconnected_clients || false,
- snapcast_clients: state.snapcast.clients,
- snapcast_groups: state.snapcast.groups,
- snapcast_streams: state.snapcast.streams,
- pusher_commands: (state.pusher.commands ? state.pusher.commands : {}),
});
const mapDispatchToProps = (dispatch) => ({