Use useTypedEventEmitterState for broadcasts (#9947)

This commit is contained in:
Michael Weimann 2023-01-20 13:33:00 +01:00 committed by GitHub
parent 9dbc5f3773
commit 234061c847
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 67 additions and 49 deletions

View File

@ -63,6 +63,9 @@ export function useEventEmitter(emitter: EventEmitter | undefined, eventName: st
type Mapper<T> = (...args: any[]) => T;
/**
* {@link useEventEmitterState}
*/
export function useTypedEventEmitterState<T, Events extends string, Arguments extends ListenerMap<Events>>(
emitter: TypedEventEmitter<Events, Arguments>,
eventName: Events,
@ -71,6 +74,16 @@ export function useTypedEventEmitterState<T, Events extends string, Arguments ex
return useEventEmitterState<T>(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<T>(
emitter: EventEmitter | undefined,
eventName: string | symbol,

View File

@ -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();
},
);

View File

@ -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,
};

View File

@ -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 {

View File

@ -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,

View File

@ -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[]

View File

@ -57,7 +57,7 @@ export enum VoiceBroadcastPlaybackEvent {
InfoStateChanged = "info_state_changed",
}
type VoiceBroadcastPlaybackTimes = {
export type VoiceBroadcastPlaybackTimes = {
duration: number;
position: number;
timeLeft: number;