Use useTypedEventEmitterState for broadcasts (#9947)
parent
9dbc5f3773
commit
234061c847
|
@ -63,6 +63,9 @@ export function useEventEmitter(emitter: EventEmitter | undefined, eventName: st
|
||||||
|
|
||||||
type Mapper<T> = (...args: any[]) => T;
|
type Mapper<T> = (...args: any[]) => T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link useEventEmitterState}
|
||||||
|
*/
|
||||||
export function useTypedEventEmitterState<T, Events extends string, Arguments extends ListenerMap<Events>>(
|
export function useTypedEventEmitterState<T, Events extends string, Arguments extends ListenerMap<Events>>(
|
||||||
emitter: TypedEventEmitter<Events, Arguments>,
|
emitter: TypedEventEmitter<Events, Arguments>,
|
||||||
eventName: Events,
|
eventName: Events,
|
||||||
|
@ -71,6 +74,16 @@ export function useTypedEventEmitterState<T, Events extends string, Arguments ex
|
||||||
return useEventEmitterState<T>(emitter, eventName, fn);
|
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>(
|
export function useEventEmitterState<T>(
|
||||||
emitter: EventEmitter | undefined,
|
emitter: EventEmitter | undefined,
|
||||||
eventName: string | symbol,
|
eventName: string | symbol,
|
||||||
|
|
|
@ -14,9 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useTypedEventEmitterState } from "../../hooks/useEventEmitter";
|
||||||
|
|
||||||
import { useTypedEventEmitter } from "../../hooks/useEventEmitter";
|
|
||||||
import { VoiceBroadcastPlayback } from "../models/VoiceBroadcastPlayback";
|
import { VoiceBroadcastPlayback } from "../models/VoiceBroadcastPlayback";
|
||||||
import {
|
import {
|
||||||
VoiceBroadcastPlaybacksStore,
|
VoiceBroadcastPlaybacksStore,
|
||||||
|
@ -28,15 +26,11 @@ export const useCurrentVoiceBroadcastPlayback = (
|
||||||
): {
|
): {
|
||||||
currentVoiceBroadcastPlayback: VoiceBroadcastPlayback | null;
|
currentVoiceBroadcastPlayback: VoiceBroadcastPlayback | null;
|
||||||
} => {
|
} => {
|
||||||
const [currentVoiceBroadcastPlayback, setVoiceBroadcastPlayback] = useState(
|
const currentVoiceBroadcastPlayback = useTypedEventEmitterState(
|
||||||
voiceBroadcastPlaybackStore.getCurrent(),
|
|
||||||
);
|
|
||||||
|
|
||||||
useTypedEventEmitter(
|
|
||||||
voiceBroadcastPlaybackStore,
|
voiceBroadcastPlaybackStore,
|
||||||
VoiceBroadcastPlaybacksStoreEvent.CurrentChanged,
|
VoiceBroadcastPlaybacksStoreEvent.CurrentChanged,
|
||||||
(playback: VoiceBroadcastPlayback) => {
|
(playback?: VoiceBroadcastPlayback) => {
|
||||||
setVoiceBroadcastPlayback(playback);
|
return playback ?? voiceBroadcastPlaybackStore.getCurrent();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useTypedEventEmitterState } from "../../hooks/useEventEmitter";
|
||||||
|
|
||||||
import { useTypedEventEmitter } from "../../hooks/useEventEmitter";
|
|
||||||
import { VoiceBroadcastPreRecordingStore } from "../stores/VoiceBroadcastPreRecordingStore";
|
import { VoiceBroadcastPreRecordingStore } from "../stores/VoiceBroadcastPreRecordingStore";
|
||||||
import { VoiceBroadcastPreRecording } from "../models/VoiceBroadcastPreRecording";
|
import { VoiceBroadcastPreRecording } from "../models/VoiceBroadcastPreRecording";
|
||||||
|
|
||||||
|
@ -25,12 +23,14 @@ export const useCurrentVoiceBroadcastPreRecording = (
|
||||||
): {
|
): {
|
||||||
currentVoiceBroadcastPreRecording: VoiceBroadcastPreRecording | null;
|
currentVoiceBroadcastPreRecording: VoiceBroadcastPreRecording | null;
|
||||||
} => {
|
} => {
|
||||||
const [currentVoiceBroadcastPreRecording, setCurrentVoiceBroadcastPreRecording] = useState(
|
const currentVoiceBroadcastPreRecording = useTypedEventEmitterState(
|
||||||
voiceBroadcastPreRecordingStore.getCurrent(),
|
voiceBroadcastPreRecordingStore,
|
||||||
|
"changed",
|
||||||
|
(preRecording?: VoiceBroadcastPreRecording) => {
|
||||||
|
return preRecording ?? voiceBroadcastPreRecordingStore.getCurrent();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
useTypedEventEmitter(voiceBroadcastPreRecordingStore, "changed", setCurrentVoiceBroadcastPreRecording);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentVoiceBroadcastPreRecording,
|
currentVoiceBroadcastPreRecording,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,24 +14,20 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
import { VoiceBroadcastRecording, VoiceBroadcastRecordingsStore, VoiceBroadcastRecordingsStoreEvent } from "..";
|
import { VoiceBroadcastRecording, VoiceBroadcastRecordingsStore, VoiceBroadcastRecordingsStoreEvent } from "..";
|
||||||
import { useTypedEventEmitter } from "../../hooks/useEventEmitter";
|
import { useTypedEventEmitterState } from "../../hooks/useEventEmitter";
|
||||||
|
|
||||||
export const useCurrentVoiceBroadcastRecording = (
|
export const useCurrentVoiceBroadcastRecording = (
|
||||||
voiceBroadcastRecordingsStore: VoiceBroadcastRecordingsStore,
|
voiceBroadcastRecordingsStore: VoiceBroadcastRecordingsStore,
|
||||||
): {
|
): {
|
||||||
currentVoiceBroadcastRecording: VoiceBroadcastRecording;
|
currentVoiceBroadcastRecording: VoiceBroadcastRecording;
|
||||||
} => {
|
} => {
|
||||||
const [currentVoiceBroadcastRecording, setCurrentVoiceBroadcastRecording] = useState(
|
const currentVoiceBroadcastRecording = useTypedEventEmitterState(
|
||||||
voiceBroadcastRecordingsStore.getCurrent(),
|
|
||||||
);
|
|
||||||
|
|
||||||
useTypedEventEmitter(
|
|
||||||
voiceBroadcastRecordingsStore,
|
voiceBroadcastRecordingsStore,
|
||||||
VoiceBroadcastRecordingsStoreEvent.CurrentChanged,
|
VoiceBroadcastRecordingsStoreEvent.CurrentChanged,
|
||||||
setCurrentVoiceBroadcastRecording,
|
(recording?: VoiceBroadcastRecording) => {
|
||||||
|
return recording ?? voiceBroadcastRecordingsStore.getCurrent();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -14,17 +14,17 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState } from "react";
|
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
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 { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||||
import {
|
import {
|
||||||
VoiceBroadcastLiveness,
|
VoiceBroadcastLiveness,
|
||||||
VoiceBroadcastPlayback,
|
VoiceBroadcastPlayback,
|
||||||
VoiceBroadcastPlaybackEvent,
|
VoiceBroadcastPlaybackEvent,
|
||||||
VoiceBroadcastPlaybackState,
|
VoiceBroadcastPlaybackState,
|
||||||
|
VoiceBroadcastPlaybackTimes,
|
||||||
} from "..";
|
} from "..";
|
||||||
|
|
||||||
export const useVoiceBroadcastPlayback = (
|
export const useVoiceBroadcastPlayback = (
|
||||||
|
@ -52,24 +52,35 @@ export const useVoiceBroadcastPlayback = (
|
||||||
playback.toggle();
|
playback.toggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
const [playbackState, setPlaybackState] = useState(playback.getState());
|
const playbackState = useTypedEventEmitterState(
|
||||||
useTypedEventEmitter(
|
|
||||||
playback,
|
playback,
|
||||||
VoiceBroadcastPlaybackEvent.StateChanged,
|
VoiceBroadcastPlaybackEvent.StateChanged,
|
||||||
(state: VoiceBroadcastPlaybackState, _playback: VoiceBroadcastPlayback) => {
|
(state?: VoiceBroadcastPlaybackState) => {
|
||||||
setPlaybackState(state);
|
return state ?? playback.getState();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const [times, setTimes] = useState({
|
const times = useTypedEventEmitterState(
|
||||||
duration: playback.durationSeconds,
|
playback,
|
||||||
position: playback.timeSeconds,
|
VoiceBroadcastPlaybackEvent.TimesChanged,
|
||||||
timeLeft: playback.timeLeftSeconds,
|
(t?: VoiceBroadcastPlaybackTimes) => {
|
||||||
});
|
return (
|
||||||
useTypedEventEmitter(playback, VoiceBroadcastPlaybackEvent.TimesChanged, (t) => setTimes(t));
|
t ?? {
|
||||||
|
duration: playback.durationSeconds,
|
||||||
|
position: playback.timeSeconds,
|
||||||
|
timeLeft: playback.timeLeftSeconds,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const [liveness, setLiveness] = useState(playback.getLiveness());
|
const liveness = useTypedEventEmitterState(
|
||||||
useTypedEventEmitter(playback, VoiceBroadcastPlaybackEvent.LivenessChanged, (l) => setLiveness(l));
|
playback,
|
||||||
|
VoiceBroadcastPlaybackEvent.LivenessChanged,
|
||||||
|
(l?: VoiceBroadcastLiveness) => {
|
||||||
|
return l ?? playback.getLiveness();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
times,
|
times,
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
import React, { useState } from "react";
|
import React from "react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
VoiceBroadcastInfoState,
|
VoiceBroadcastInfoState,
|
||||||
|
@ -25,7 +25,7 @@ import {
|
||||||
VoiceBroadcastRecordingState,
|
VoiceBroadcastRecordingState,
|
||||||
} from "..";
|
} from "..";
|
||||||
import QuestionDialog from "../../components/views/dialogs/QuestionDialog";
|
import QuestionDialog from "../../components/views/dialogs/QuestionDialog";
|
||||||
import { useTypedEventEmitter } from "../../hooks/useEventEmitter";
|
import { useTypedEventEmitterState } from "../../hooks/useEventEmitter";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||||
import Modal from "../../Modal";
|
import Modal from "../../Modal";
|
||||||
|
@ -74,17 +74,21 @@ export const useVoiceBroadcastRecording = (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [recordingState, setRecordingState] = useState(recording.getState());
|
const recordingState = useTypedEventEmitterState(
|
||||||
useTypedEventEmitter(
|
|
||||||
recording,
|
recording,
|
||||||
VoiceBroadcastRecordingEvent.StateChanged,
|
VoiceBroadcastRecordingEvent.StateChanged,
|
||||||
(state: VoiceBroadcastInfoState, _recording: VoiceBroadcastRecording) => {
|
(state?: VoiceBroadcastRecordingState) => {
|
||||||
setRecordingState(state);
|
return state ?? recording.getState();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const [timeLeft, setTimeLeft] = useState(recording.getTimeLeft());
|
const timeLeft = useTypedEventEmitterState(
|
||||||
useTypedEventEmitter(recording, VoiceBroadcastRecordingEvent.TimeLeftChanged, setTimeLeft);
|
recording,
|
||||||
|
VoiceBroadcastRecordingEvent.TimeLeftChanged,
|
||||||
|
(t?: number) => {
|
||||||
|
return t ?? recording.getTimeLeft();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const live = (
|
const live = (
|
||||||
[VoiceBroadcastInfoState.Started, VoiceBroadcastInfoState.Resumed] as VoiceBroadcastRecordingState[]
|
[VoiceBroadcastInfoState.Started, VoiceBroadcastInfoState.Resumed] as VoiceBroadcastRecordingState[]
|
||||||
|
|
|
@ -57,7 +57,7 @@ export enum VoiceBroadcastPlaybackEvent {
|
||||||
InfoStateChanged = "info_state_changed",
|
InfoStateChanged = "info_state_changed",
|
||||||
}
|
}
|
||||||
|
|
||||||
type VoiceBroadcastPlaybackTimes = {
|
export type VoiceBroadcastPlaybackTimes = {
|
||||||
duration: number;
|
duration: number;
|
||||||
position: number;
|
position: number;
|
||||||
timeLeft: number;
|
timeLeft: number;
|
||||||
|
|
Loading…
Reference in New Issue