diff --git a/src/lib/shared/hooks/interfaces/useILevelControls.ts b/src/lib/shared/hooks/interfaces/useILevelControls.ts index 9b9ac49..b8e829e 100644 --- a/src/lib/shared/hooks/interfaces/useILevelControls.ts +++ b/src/lib/shared/hooks/interfaces/useILevelControls.ts @@ -1,4 +1,4 @@ -import { useGetDevice } from 'src/lib/store'; +import { useGetDevice, useRoomLevelControls } from 'src/lib/store'; import { LevelControlsState } from 'src/lib/types/state/state/LevelControlsState'; import { useWebsocketContext } from 'src/lib/utils/useWebsocketContext'; @@ -6,8 +6,11 @@ import { useWebsocketContext } from 'src/lib/utils/useWebsocketContext'; export function useILevelControls(key: string): ILevelControlsReturn | undefined { const { sendMessage, sendSimpleMessage } = useWebsocketContext(); const device = useGetDevice(key); + const room = useRoomLevelControls(key); - if (!device) return undefined; + const state: LevelControlsState | undefined = device || room; + + if (!state) return undefined; const setLevel = (levelKey: string, value: number) => sendSimpleMessage(`${levelKey}/level`, value); @@ -19,7 +22,7 @@ export function useILevelControls(key: string): ILevelControlsReturn | undefined const muteOff = (levelKey: string) => sendMessage(`${levelKey}/muteOff`, null); return { - levelState: device, + levelState: state, setLevel, muteToggle, muteOn, diff --git a/src/lib/shared/hooks/useGetDeviceStateFromRoomConfiguration.ts b/src/lib/shared/hooks/useGetDeviceStateFromRoomConfiguration.ts index 94843a5..82d9a5c 100644 --- a/src/lib/shared/hooks/useGetDeviceStateFromRoomConfiguration.ts +++ b/src/lib/shared/hooks/useGetDeviceStateFromRoomConfiguration.ts @@ -27,6 +27,12 @@ export const useGetAllDeviceStateFromRoomConfiguration = ({config}: {config: Roo deviceKeys.push(dli.sinkKey); }); + if(config.levelControlList) { + Object.values(config.levelControlList).forEach((lcl) => { + deviceKeys.push(lcl.deviceKey); + }); + } + config.touchpanelKeys?.forEach((d) => { deviceKeys.push(d); }); diff --git a/src/lib/store/devices/devices.slice.ts b/src/lib/store/devices/devices.slice.ts index 16bf126..74e7182 100644 --- a/src/lib/store/devices/devices.slice.ts +++ b/src/lib/store/devices/devices.slice.ts @@ -31,7 +31,10 @@ const devicesSlice = createSlice({ state[key] = newState; return state; - } + }, + clearDevices() { + return initialState; + }, }, }) diff --git a/src/lib/store/rooms/rooms.slice.ts b/src/lib/store/rooms/rooms.slice.ts index 645079a..46cd2eb 100644 --- a/src/lib/store/rooms/rooms.slice.ts +++ b/src/lib/store/rooms/rooms.slice.ts @@ -38,7 +38,10 @@ const roomsSlice = createSlice({ console.log(state); return state; - } + }, + clearRooms() { + return initialState; + }, }, }) diff --git a/src/lib/store/rooms/roomsSelectors.ts b/src/lib/store/rooms/roomsSelectors.ts index 554624d..cff86ee 100644 --- a/src/lib/store/rooms/roomsSelectors.ts +++ b/src/lib/store/rooms/roomsSelectors.ts @@ -1,6 +1,6 @@ import { createSelector } from '@reduxjs/toolkit'; import { RoomVolumeType, Volume } from 'src/lib/types'; -import { DisplayState, RoomConfiguration } from "src/lib/types/state/state"; +import { DisplayState, LevelControlsState, RoomConfiguration } from "src/lib/types/state/state"; import { useGetAllDevices } from '../devices/devicesSelectors'; import { useAppSelector } from "../hooks"; import store, { RootState } from '../rootReducer'; @@ -26,6 +26,11 @@ export const useRoomVolume = (roomKey: string, volumeKey: RoomVolumeType) => state.rooms[roomKey] ? state.rooms[roomKey]?.volumes[volumeKey] as Volume : undefined ); +export const useRoomLevelControls = (roomKey: string) => + useAppSelector((state) => + state.rooms[roomKey] ? state.rooms[roomKey] as unknown as LevelControlsState : undefined + ); + export const useRoomSourceList = (roomKey: string) => useAppSelector((state) => state.rooms[roomKey] @@ -33,6 +38,13 @@ export const useRoomSourceList = (roomKey: string) => : undefined ); +export const useRoomLevelControlList = (roomKey: string) => + useAppSelector((state) => + state.rooms[roomKey] + ? state.rooms[roomKey]?.configuration?.levelControlList + : undefined + ); + export const useRoomDestinations = (roomKey: string) => useAppSelector((state) => state.rooms[roomKey] diff --git a/src/lib/store/runtimeConfig/runtimeConfig.slice.ts b/src/lib/store/runtimeConfig/runtimeConfig.slice.ts index 6ba404b..eea943a 100644 --- a/src/lib/store/runtimeConfig/runtimeConfig.slice.ts +++ b/src/lib/store/runtimeConfig/runtimeConfig.slice.ts @@ -1,5 +1,8 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { RoomData } from '../../types/index'; +import { devicesActions } from '../devices/devices.slice'; +import { roomsActions } from '../rooms/rooms.slice'; +import store from '../rootReducer'; const initialState: RuntimeConfigState = { apiVersion: '', @@ -12,7 +15,8 @@ const initialState: RuntimeConfigState = { token: '', roomData: { clientId: '', - roomKey: '', + defaultRoomKey: '', + currentRoomKey: '', systemUuid: '', roomUuid: '', userAppUrl: '', @@ -45,7 +49,10 @@ const runtimeConfigSlice = createSlice({ state.roomData = action.payload; }, setCurrentRoomKey(state, action: PayloadAction) { - state.roomData.roomKey = action.payload; + // clear out any existing room/device data + store.dispatch(roomsActions.clearRooms()); + store.dispatch(devicesActions.clearDevices()); + state.roomData.currentRoomKey = action.payload; }, setUserCode(state, action: PayloadAction) { state.roomData.userCode = action.payload.userCode; diff --git a/src/lib/store/runtimeConfig/runtimeSelectors.ts b/src/lib/store/runtimeConfig/runtimeSelectors.ts index 1d83ad0..57ede34 100644 --- a/src/lib/store/runtimeConfig/runtimeSelectors.ts +++ b/src/lib/store/runtimeConfig/runtimeSelectors.ts @@ -2,6 +2,6 @@ import { useAppSelector } from '../hooks'; export const useWsIsConnected = () => useAppSelector((state) => state.runtimeConfig.websocket.isConnected); -export const useRoomKey = () => useAppSelector((state) => state.runtimeConfig.roomData.roomKey); +export const useRoomKey = () => useAppSelector((state) => state.runtimeConfig.roomData.currentRoomKey); export const useClientId = () => useAppSelector((state) => state.runtimeConfig.roomData.clientId); \ No newline at end of file diff --git a/src/lib/types/classes/room-data.ts b/src/lib/types/classes/room-data.ts index 1c88fda..f3c5ca3 100644 --- a/src/lib/types/classes/room-data.ts +++ b/src/lib/types/classes/room-data.ts @@ -1,6 +1,7 @@ export interface RoomData { clientId: string | number; - roomKey: string; + defaultRoomKey: string; + currentRoomKey: string; systemUuid: string; roomUuid: string; userAppUrl: string; diff --git a/src/lib/types/interfaces/ISelectableItem.ts b/src/lib/types/interfaces/ISelectableItem.ts index 477c61a..aff3629 100644 --- a/src/lib/types/interfaces/ISelectableItem.ts +++ b/src/lib/types/interfaces/ISelectableItem.ts @@ -1,7 +1,5 @@ -import { IKeyName } from 'src/lib'; +import { IKeyName } from '.'; export interface ISelectableItem extends IKeyName { isSelected: boolean; - Name: string; - Key: string; } \ No newline at end of file diff --git a/src/lib/types/state/LevelControlListItem.ts b/src/lib/types/state/LevelControlListItem.ts new file mode 100644 index 0000000..fc4713c --- /dev/null +++ b/src/lib/types/state/LevelControlListItem.ts @@ -0,0 +1,10 @@ +export interface LevelControlListItem { + deviceKey: string; + preferredName: string; + name: string; + includeInUserList: boolean; + order: number; + type: LevelControlType; +} + +export type LevelControlType = 'Level' | 'Mute' | 'LevelAndMute'; \ No newline at end of file diff --git a/src/lib/types/state/index.ts b/src/lib/types/state/index.ts index 897707b..5d86b3c 100644 --- a/src/lib/types/state/index.ts +++ b/src/lib/types/state/index.ts @@ -1,3 +1,4 @@ +export * from './LevelControlListItem'; export * from './collections'; export * from './common-functions-util'; export * from './config'; diff --git a/src/lib/types/state/state/IEssentialsRoomCombinerState.ts b/src/lib/types/state/state/IEssentialsRoomCombinerState.ts index 574a79b..fd2632a 100644 --- a/src/lib/types/state/state/IEssentialsRoomCombinerState.ts +++ b/src/lib/types/state/state/IEssentialsRoomCombinerState.ts @@ -17,11 +17,9 @@ export interface RoomCombinationScenario extends IKeyName { isActive: boolean; } -export interface Partition { +export interface Partition extends IKeyName { partitionPresent: boolean; adjacentRoomKeys: string[]; - Name: string; - Key: string; } export interface PartitionState { diff --git a/src/lib/types/state/state/RoomState.ts b/src/lib/types/state/state/RoomState.ts index 1509cd0..9d07e89 100644 --- a/src/lib/types/state/state/RoomState.ts +++ b/src/lib/types/state/state/RoomState.ts @@ -1,6 +1,7 @@ /* eslint-disable max-classes-per-file */ import { DestinationListItem } from '../DestinationListItem'; +import { LevelControlListItem } from '../LevelControlListItem'; import { SourceListItem } from '../sourceListItem'; import { Volume } from '../volume/volume'; import { DeviceState } from './DeviceState'; @@ -23,30 +24,31 @@ export interface RoomState extends DeviceState{ } export interface RoomConfiguration { + accessoryDeviceKeys?: string[]; audioCodecKey?: string; + ciscoNavigatorKey?: string; defaultDisplayKey?: string; defaultPresentationSourceKey: string; - destinations: Record; destinationList: Record; + destinations: Record; + endpointKeys?: string[]; environmentalDevices: EnvironmentalDeviceConfiguration[]; hasAudioConferencing?: boolean; hasEnvironmentalControls?: boolean; hasVideoConferencing?: boolean; helpMessage?: string; - techPassword?: string; + levelControlList: Record; + matrixRoutingKey?: string; + roomCombinerKey?: string; sourceList: Record; supportsAdvancedSharing?: boolean; + techPassword?: string; + touchpanelKeys?: string[]; uiBehavior?: EssentialsRoomUiBehaviorConfiguration; userCanChangeShareMode?: boolean; videoCodecIsZoomRoom?: boolean; videoCodecKey?: string; - touchpanelKeys?: string[]; zoomRoomControllerKey?: string; - ciscoNavigatorKey?: string; - matrixRoutingKey?: string; - endpointKeys?: string[]; - accessoryDeviceKeys?: string[]; - roomCombinerKey?: string; } export interface EssentialsRoomUiBehaviorConfiguration { diff --git a/src/lib/utils/WebsocketProvider.tsx b/src/lib/utils/WebsocketProvider.tsx index e6cc575..e2a4c0d 100644 --- a/src/lib/utils/WebsocketProvider.tsx +++ b/src/lib/utils/WebsocketProvider.tsx @@ -209,6 +209,12 @@ const WebsocketProvider = ({ children }: { children: ReactNode }) => { runtimeConfigActions.setUserCode(message.content as UserCode) ); break; + case "/system/roomCombinationChanged": + window.location.reload(); + break; + default: + console.log("unhandled system message", message); + break; } } else if (message.type.startsWith("/event/")) { console.log('event message received', message); @@ -255,6 +261,7 @@ const WebsocketProvider = ({ children }: { children: ReactNode }) => { * */ useEffect(() => { if (roomKey) { + console.log("requesting status from room: ", roomKey); sendMessage(`/room/${roomKey}/status`, null); } }, [roomKey, sendMessage]);