diff --git a/src/room/MuteStates.ts b/src/room/MuteStates.ts index 0f5712f9..8ec58265 100644 --- a/src/room/MuteStates.ts +++ b/src/room/MuteStates.ts @@ -14,7 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Dispatch, SetStateAction, useEffect, useMemo } from "react"; +import { + Dispatch, + SetStateAction, + useCallback, + useEffect, + useMemo, +} from "react"; import { IWidgetApiRequest } from "matrix-widget-api"; import { MediaDevice, useMediaDevices } from "../livekit/MediaDevicesContext"; @@ -83,41 +89,41 @@ export function useMuteStates(): MuteStates { }); }, [audio, video]); + const onMuteStateChangeRequest = useCallback( + (ev: CustomEvent) => { + // First copy the current state into our new state. + const newState = { + audio_enabled: audio.enabled, + video_enabled: video.enabled, + }; + // Update new state if there are any requested changes from the widget action + // in `ev.detail.data`. + if ( + ev.detail.data.audio_enabled != null && + typeof ev.detail.data.audio_enabled === "boolean" + ) { + audio.setEnabled?.(ev.detail.data.audio_enabled); + newState.audio_enabled = ev.detail.data.audio_enabled; + } + if ( + ev.detail.data.video_enabled != null && + typeof ev.detail.data.video_enabled === "boolean" + ) { + video.setEnabled?.(ev.detail.data.video_enabled); + newState.video_enabled = ev.detail.data.video_enabled; + } + // Always reply with the new (now "current") state. + // This allows to also use this action to just get the unaltered current state + // by using a fromWidget request with: `ev.detail.data = {}` + widget!.api.transport.reply(ev.detail, newState); + }, + [audio, video], + ); useEffect(() => { // We setup a event listener for the widget action ElementWidgetActions.DeviceMute. if (widget) { // only setup the listener in widget mode - const onMuteStateChangeRequest = ( - ev: CustomEvent, - ): void => { - // First copy the current state into our new state. - const newState = { - audio_enabled: audio.enabled, - video_enabled: video.enabled, - }; - // Update new state if there are any requested changes from the widget action - // in `ev.detail.data`. - if ( - ev.detail.data.audio_enabled != null && - typeof ev.detail.data.audio_enabled === "boolean" - ) { - audio.setEnabled?.(ev.detail.data.audio_enabled); - newState.audio_enabled = ev.detail.data.audio_enabled; - } - if ( - ev.detail.data.video_enabled != null && - typeof ev.detail.data.video_enabled === "boolean" - ) { - video.setEnabled?.(ev.detail.data.video_enabled); - newState.video_enabled = ev.detail.data.video_enabled; - } - // Always reply with the new (now "current") state. - // This allows to also use this action to just get the unaltered current state - // by using a fromWidget request with: `ev.detail.data = {}` - widget!.api.transport.reply(ev.detail, newState); - }; - // Connect our mute listener. widget.lazyActions.on( ElementWidgetActions.DeviceMute, onMuteStateChangeRequest, @@ -131,7 +137,7 @@ export function useMuteStates(): MuteStates { ); }; } - }, [audio, video]); + }, [onMuteStateChangeRequest]); return useMemo(() => ({ audio, video }), [audio, video]); }