From f9efd44c296f37fe1e60061b9b23262121610e9a Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Tue, 12 Oct 2021 20:25:43 +1300 Subject: [PATCH] Upgrading to functional component --- src/js/components/Fields/OutputControl.js | 325 +++++++++++----------- 1 file changed, 156 insertions(+), 169 deletions(-) diff --git a/src/js/components/Fields/OutputControl.js b/src/js/components/Fields/OutputControl.js index 2d4b2e37..609773e8 100755 --- a/src/js/components/Fields/OutputControl.js +++ b/src/js/components/Fields/OutputControl.js @@ -1,5 +1,5 @@ -import React from 'react'; -import { connect } from 'react-redux'; +import React, { useState, useEffect } from 'react'; +import { connect, useSelector, useDispatch } from 'react-redux'; import { bindActionCreators } from 'redux'; import VolumeControl from './VolumeControl'; import MuteControl from './MuteControl'; @@ -12,201 +12,188 @@ import { sortItems, indexToArray, applyFilter } from '../../util/arrays'; import { collate } from '../../util/format'; import { I18n } from '../../locale'; -class OutputControl extends React.Component { - constructor(props) { - super(props); +const SnapcastGroups = () => { + const dispatch = useDispatch(); + const showAllClients = useSelector((state) => state.ui.snapcast_show_disconnected_clients); + const clients = useSelector((state) => state.snapcast.clients); + const groupsObj = useSelector((state) => state.snapcast.groups); + const streamsObj = useSelector((state) => state.snapcast.streams); - this.state = { - expanded: false, - }; + const groups = indexToArray(groupsObj); + if (groups.length <= 0) return null; - this.handleClick = this.handleClick.bind(this); - } + const streams = Object.keys(streamsObj).map((id) => ({ value: id, label: id })); - componentDidUpdate = ({ - force_expanded: prev_force_expanded, - }) => { - const { force_expanded } = this.props; - if (!prev_force_expanded && force_expanded) this.setExpanded(true); - } + return ( +
+ { + 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) => ({