From 234061c847e8c9bdabdd99e1b91edc88467748f7 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Fri, 20 Jan 2023 13:33:00 +0100 Subject: [PATCH] Use useTypedEventEmitterState for broadcasts (#9947) --- src/hooks/useEventEmitter.ts | 13 +++++++ .../hooks/useCurrentVoiceBroadcastPlayback.ts | 14 ++----- .../useCurrentVoiceBroadcastPreRecording.ts | 14 +++---- .../useCurrentVoiceBroadcastRecording.ts | 14 +++---- .../hooks/useVoiceBroadcastPlayback.ts | 39 ++++++++++++------- .../hooks/useVoiceBroadcastRecording.tsx | 20 ++++++---- .../models/VoiceBroadcastPlayback.ts | 2 +- 7 files changed, 67 insertions(+), 49 deletions(-) diff --git a/src/hooks/useEventEmitter.ts b/src/hooks/useEventEmitter.ts index d975be78f9..ab25a0db72 100644 --- a/src/hooks/useEventEmitter.ts +++ b/src/hooks/useEventEmitter.ts @@ -63,6 +63,9 @@ export function useEventEmitter(emitter: EventEmitter | undefined, eventName: st type Mapper = (...args: any[]) => T; +/** + * {@link useEventEmitterState} + */ export function useTypedEventEmitterState>( emitter: TypedEventEmitter, eventName: Events, @@ -71,6 +74,16 @@ export function useTypedEventEmitterState(emitter, eventName, fn); } +/** + * Creates a state, that can be updated by events. + * + * @param emitter The emitter sending the event + * @param eventName Event name to listen for + * @param fn The callback function, that should return the state value. + * It should have the signature of the event callback, except that all parameters are optional. + * If the params are not set, a default value for the state should be returned. + * @returns State + */ export function useEventEmitterState( emitter: EventEmitter | undefined, eventName: string | symbol, diff --git a/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPlayback.ts b/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPlayback.ts index a43afafdeb..c0b02d09ce 100644 --- a/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPlayback.ts +++ b/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPlayback.ts @@ -14,9 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { useState } from "react"; - -import { useTypedEventEmitter } from "../../hooks/useEventEmitter"; +import { useTypedEventEmitterState } from "../../hooks/useEventEmitter"; import { VoiceBroadcastPlayback } from "../models/VoiceBroadcastPlayback"; import { VoiceBroadcastPlaybacksStore, @@ -28,15 +26,11 @@ export const useCurrentVoiceBroadcastPlayback = ( ): { currentVoiceBroadcastPlayback: VoiceBroadcastPlayback | null; } => { - const [currentVoiceBroadcastPlayback, setVoiceBroadcastPlayback] = useState( - voiceBroadcastPlaybackStore.getCurrent(), - ); - - useTypedEventEmitter( + const currentVoiceBroadcastPlayback = useTypedEventEmitterState( voiceBroadcastPlaybackStore, VoiceBroadcastPlaybacksStoreEvent.CurrentChanged, - (playback: VoiceBroadcastPlayback) => { - setVoiceBroadcastPlayback(playback); + (playback?: VoiceBroadcastPlayback) => { + return playback ?? voiceBroadcastPlaybackStore.getCurrent(); }, ); diff --git a/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPreRecording.ts b/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPreRecording.ts index 76f682f636..5027daad53 100644 --- a/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPreRecording.ts +++ b/src/voice-broadcast/hooks/useCurrentVoiceBroadcastPreRecording.ts @@ -14,9 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { useState } from "react"; - -import { useTypedEventEmitter } from "../../hooks/useEventEmitter"; +import { useTypedEventEmitterState } from "../../hooks/useEventEmitter"; import { VoiceBroadcastPreRecordingStore } from "../stores/VoiceBroadcastPreRecordingStore"; import { VoiceBroadcastPreRecording } from "../models/VoiceBroadcastPreRecording"; @@ -25,12 +23,14 @@ export const useCurrentVoiceBroadcastPreRecording = ( ): { currentVoiceBroadcastPreRecording: VoiceBroadcastPreRecording | null; } => { - const [currentVoiceBroadcastPreRecording, setCurrentVoiceBroadcastPreRecording] = useState( - voiceBroadcastPreRecordingStore.getCurrent(), + const currentVoiceBroadcastPreRecording = useTypedEventEmitterState( + voiceBroadcastPreRecordingStore, + "changed", + (preRecording?: VoiceBroadcastPreRecording) => { + return preRecording ?? voiceBroadcastPreRecordingStore.getCurrent(); + }, ); - useTypedEventEmitter(voiceBroadcastPreRecordingStore, "changed", setCurrentVoiceBroadcastPreRecording); - return { currentVoiceBroadcastPreRecording, }; diff --git a/src/voice-broadcast/hooks/useCurrentVoiceBroadcastRecording.ts b/src/voice-broadcast/hooks/useCurrentVoiceBroadcastRecording.ts index c406697606..a9b9635ba7 100644 --- a/src/voice-broadcast/hooks/useCurrentVoiceBroadcastRecording.ts +++ b/src/voice-broadcast/hooks/useCurrentVoiceBroadcastRecording.ts @@ -14,24 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { useState } from "react"; - import { VoiceBroadcastRecording, VoiceBroadcastRecordingsStore, VoiceBroadcastRecordingsStoreEvent } from ".."; -import { useTypedEventEmitter } from "../../hooks/useEventEmitter"; +import { useTypedEventEmitterState } from "../../hooks/useEventEmitter"; export const useCurrentVoiceBroadcastRecording = ( voiceBroadcastRecordingsStore: VoiceBroadcastRecordingsStore, ): { currentVoiceBroadcastRecording: VoiceBroadcastRecording; } => { - const [currentVoiceBroadcastRecording, setCurrentVoiceBroadcastRecording] = useState( - voiceBroadcastRecordingsStore.getCurrent(), - ); - - useTypedEventEmitter( + const currentVoiceBroadcastRecording = useTypedEventEmitterState( voiceBroadcastRecordingsStore, VoiceBroadcastRecordingsStoreEvent.CurrentChanged, - setCurrentVoiceBroadcastRecording, + (recording?: VoiceBroadcastRecording) => { + return recording ?? voiceBroadcastRecordingsStore.getCurrent(); + }, ); return { diff --git a/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts b/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts index 51d9c07c00..8f36d77bf4 100644 --- a/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts +++ b/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts @@ -14,17 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { useState } from "react"; import { Room } from "matrix-js-sdk/src/models/room"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; -import { useTypedEventEmitter } from "../../hooks/useEventEmitter"; +import { useTypedEventEmitterState } from "../../hooks/useEventEmitter"; import { MatrixClientPeg } from "../../MatrixClientPeg"; import { VoiceBroadcastLiveness, VoiceBroadcastPlayback, VoiceBroadcastPlaybackEvent, VoiceBroadcastPlaybackState, + VoiceBroadcastPlaybackTimes, } from ".."; export const useVoiceBroadcastPlayback = ( @@ -52,24 +52,35 @@ export const useVoiceBroadcastPlayback = ( playback.toggle(); }; - const [playbackState, setPlaybackState] = useState(playback.getState()); - useTypedEventEmitter( + const playbackState = useTypedEventEmitterState( playback, VoiceBroadcastPlaybackEvent.StateChanged, - (state: VoiceBroadcastPlaybackState, _playback: VoiceBroadcastPlayback) => { - setPlaybackState(state); + (state?: VoiceBroadcastPlaybackState) => { + return state ?? playback.getState(); }, ); - const [times, setTimes] = useState({ - duration: playback.durationSeconds, - position: playback.timeSeconds, - timeLeft: playback.timeLeftSeconds, - }); - useTypedEventEmitter(playback, VoiceBroadcastPlaybackEvent.TimesChanged, (t) => setTimes(t)); + const times = useTypedEventEmitterState( + playback, + VoiceBroadcastPlaybackEvent.TimesChanged, + (t?: VoiceBroadcastPlaybackTimes) => { + return ( + t ?? { + duration: playback.durationSeconds, + position: playback.timeSeconds, + timeLeft: playback.timeLeftSeconds, + } + ); + }, + ); - const [liveness, setLiveness] = useState(playback.getLiveness()); - useTypedEventEmitter(playback, VoiceBroadcastPlaybackEvent.LivenessChanged, (l) => setLiveness(l)); + const liveness = useTypedEventEmitterState( + playback, + VoiceBroadcastPlaybackEvent.LivenessChanged, + (l?: VoiceBroadcastLiveness) => { + return l ?? playback.getLiveness(); + }, + ); return { times, diff --git a/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx b/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx index b8e6028b4c..1b2bde2b40 100644 --- a/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx +++ b/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx @@ -16,7 +16,7 @@ limitations under the License. import { Room } from "matrix-js-sdk/src/models/room"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; -import React, { useState } from "react"; +import React from "react"; import { VoiceBroadcastInfoState, @@ -25,7 +25,7 @@ import { VoiceBroadcastRecordingState, } from ".."; import QuestionDialog from "../../components/views/dialogs/QuestionDialog"; -import { useTypedEventEmitter } from "../../hooks/useEventEmitter"; +import { useTypedEventEmitterState } from "../../hooks/useEventEmitter"; import { _t } from "../../languageHandler"; import { MatrixClientPeg } from "../../MatrixClientPeg"; import Modal from "../../Modal"; @@ -74,17 +74,21 @@ export const useVoiceBroadcastRecording = ( } }; - const [recordingState, setRecordingState] = useState(recording.getState()); - useTypedEventEmitter( + const recordingState = useTypedEventEmitterState( recording, VoiceBroadcastRecordingEvent.StateChanged, - (state: VoiceBroadcastInfoState, _recording: VoiceBroadcastRecording) => { - setRecordingState(state); + (state?: VoiceBroadcastRecordingState) => { + return state ?? recording.getState(); }, ); - const [timeLeft, setTimeLeft] = useState(recording.getTimeLeft()); - useTypedEventEmitter(recording, VoiceBroadcastRecordingEvent.TimeLeftChanged, setTimeLeft); + const timeLeft = useTypedEventEmitterState( + recording, + VoiceBroadcastRecordingEvent.TimeLeftChanged, + (t?: number) => { + return t ?? recording.getTimeLeft(); + }, + ); const live = ( [VoiceBroadcastInfoState.Started, VoiceBroadcastInfoState.Resumed] as VoiceBroadcastRecordingState[] diff --git a/src/voice-broadcast/models/VoiceBroadcastPlayback.ts b/src/voice-broadcast/models/VoiceBroadcastPlayback.ts index 33f2ceb573..86463f5dc9 100644 --- a/src/voice-broadcast/models/VoiceBroadcastPlayback.ts +++ b/src/voice-broadcast/models/VoiceBroadcastPlayback.ts @@ -57,7 +57,7 @@ export enum VoiceBroadcastPlaybackEvent { InfoStateChanged = "info_state_changed", } -type VoiceBroadcastPlaybackTimes = { +export type VoiceBroadcastPlaybackTimes = { duration: number; position: number; timeLeft: number;