1- import { useMemo } from 'react' ;
1+ import { useEffect , useMemo , useRef } from 'react' ;
22import { RoomConfiguration } from '../../types/state/state' ;
33import { useWebsocketContext } from '../../utils/useWebsocketContext' ;
44
55/**
66 * This hook will gather up all the keys for devices in the room
7- * and send messages to the websocket to get the iniital state
8- * for each device
7+ * and send messages to the websocket to get the initial state
8+ * for each device.
9+ *
10+ * @param config - Room configuration containing device keys
11+ * @param requestStatus - Whether to request device status (default: true)
12+ * @returns Set of device keys found in the configuration
913 */
1014export const useGetAllDeviceStateFromRoomConfiguration = (
1115 {
@@ -16,23 +20,25 @@ export const useGetAllDeviceStateFromRoomConfiguration = (
1620 requestStatus : boolean = true
1721) => {
1822 const { sendMessage } = useWebsocketContext ( ) ;
23+ const hasRequestedRef = useRef ( false ) ;
1924
20- return useMemo ( ( ) => {
25+ // Step 1: Memoize the collection of device keys (pure computation)
26+ const deviceKeysSet = useMemo ( ( ) => {
2127 if ( ! config ) {
22- return ;
28+ return undefined ;
2329 }
2430
25- const deviceKeysSet : Set < string > = new Set < string > ( ) ;
31+ const keys : Set < string > = new Set < string > ( ) ;
2632
2733 if ( config . destinations ) {
2834 Object . values ( config . destinations ) . forEach ( ( d ) => {
29- deviceKeysSet . add ( d ) ;
35+ keys . add ( d ) ;
3036 } ) ;
3137 }
3238
3339 if ( config . destinationList ) {
3440 Object . values ( config . destinationList ) . forEach ( ( dli ) => {
35- deviceKeysSet . add ( dli . sinkKey ) ;
41+ keys . add ( dli . sinkKey ) ;
3642 } ) ;
3743 }
3844
@@ -41,64 +47,78 @@ export const useGetAllDeviceStateFromRoomConfiguration = (
4147 ( lcl ) => {
4248 // if the level control has an item key, combine it with the parent device key
4349 if ( lcl . itemKey ) {
44- deviceKeysSet . add ( lcl . parentDeviceKey + '--' + lcl . itemKey ) ;
50+ keys . add ( lcl . parentDeviceKey + '--' + lcl . itemKey ) ;
4551 } else {
46- deviceKeysSet . add ( lcl . parentDeviceKey ) ;
52+ keys . add ( lcl . parentDeviceKey ) ;
4753 }
4854 }
4955 ) ;
5056 }
5157
5258 config . touchpanelKeys ?. forEach ( ( d ) => {
53- deviceKeysSet . add ( d ) ;
59+ keys . add ( d ) ;
5460 } ) ;
5561
5662 config . environmentalDevices ?. forEach ( ( d ) => {
57- if ( d . deviceKey ) deviceKeysSet . add ( d . deviceKey ) ;
63+ if ( d . deviceKey ) keys . add ( d . deviceKey ) ;
5864 } ) ;
5965
6066 config . accessoryDeviceKeys ?. forEach ( ( d ) => {
61- deviceKeysSet . add ( d ) ;
67+ keys . add ( d ) ;
6268 } ) ;
6369
6470 if ( config . audioCodecKey ) {
65- deviceKeysSet . add ( config . audioCodecKey ) ;
71+ keys . add ( config . audioCodecKey ) ;
6672 }
6773
6874 if ( config . videoCodecKey ) {
69- deviceKeysSet . add ( config . videoCodecKey ) ;
75+ keys . add ( config . videoCodecKey ) ;
7076 }
7177
7278 if ( config . matrixRoutingKey ) {
73- deviceKeysSet . add ( config . matrixRoutingKey ) ;
79+ keys . add ( config . matrixRoutingKey ) ;
7480 }
7581
7682 if ( config . roomCombinerKey ) {
77- deviceKeysSet . add ( config . roomCombinerKey ) ;
83+ keys . add ( config . roomCombinerKey ) ;
7884 }
7985
8086 if ( config . endpointKeys ) {
8187 config . endpointKeys . forEach ( ( ek ) => {
82- deviceKeysSet . add ( ek ) ;
88+ keys . add ( ek ) ;
8389 } ) ;
8490 }
8591
8692 if ( config . sourceList ) {
8793 for ( const value of Object . values ( config . sourceList ) ) {
8894 // if the source has a source key, add it to the list of device keys
8995 if ( value . sourceKey && value . sourceKey !== '$off' )
90- deviceKeysSet . add ( value . sourceKey ) ;
96+ keys . add ( value . sourceKey ) ;
9197 }
9298 }
9399
94- console . log ( 'requesting state for deviceKeys:' , deviceKeysSet ) ;
100+ return keys ;
101+ } , [ config ] ) ;
102+
103+ // Step 2: Create a stable callback for requesting device status
104+ useEffect ( ( ) => {
105+ if (
106+ ! requestStatus ||
107+ ! deviceKeysSet ||
108+ deviceKeysSet . size === 0 ||
109+ hasRequestedRef . current
110+ ) {
111+ return ;
112+ }
95113
96- if ( ! requestStatus ) return deviceKeysSet ;
114+ console . log ( 'requesting state for deviceKeys:' , deviceKeysSet ) ;
97115
98116 deviceKeysSet . forEach ( ( dk ) => {
99117 sendMessage ( `/device/${ dk } /fullStatus` , { deviceKey : dk } ) ;
100118 } ) ;
101119
102- return deviceKeysSet ;
103- } , [ config , sendMessage , requestStatus ] ) ;
120+ hasRequestedRef . current = true ;
121+ } , [ deviceKeysSet , requestStatus , sendMessage ] ) ;
122+
123+ return deviceKeysSet ;
104124} ;
0 commit comments