mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-28 06:50:26 +00:00
Use call view model for hand raised reactions
This commit is contained in:
@@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { ReactNode, useDeferredValue, useEffect, useMemo } from "react";
|
||||
import { filter, interval, throttle } from "rxjs";
|
||||
import { filter, interval, map, scan, throttle } from "rxjs";
|
||||
|
||||
import { CallViewModel } from "../state/CallViewModel";
|
||||
import joinCallSoundMp3 from "../sound/join_call.mp3";
|
||||
@@ -51,19 +51,6 @@ export function CallEventAudioRenderer({
|
||||
});
|
||||
const audioEngineRef = useLatest(audioEngineCtx);
|
||||
|
||||
const { raisedHands } = useReactions();
|
||||
const raisedHandCount = useMemo(
|
||||
() => Object.keys(raisedHands).length,
|
||||
[raisedHands],
|
||||
);
|
||||
const previousRaisedHandCount = useDeferredValue(raisedHandCount);
|
||||
|
||||
useEffect(() => {
|
||||
if (audioEngineRef.current && previousRaisedHandCount < raisedHandCount) {
|
||||
audioEngineRef.current.playSound("raiseHand");
|
||||
}
|
||||
}, [audioEngineRef, previousRaisedHandCount, raisedHandCount]);
|
||||
|
||||
useEffect(() => {
|
||||
const joinSub = vm.memberChanges
|
||||
.pipe(
|
||||
@@ -89,9 +76,14 @@ export function CallEventAudioRenderer({
|
||||
audioEngineRef.current?.playSound("left");
|
||||
});
|
||||
|
||||
const handRaisedSub = vm.handRaised.subscribe(() => {
|
||||
audioEngineRef.current?.playSound("raiseHand");
|
||||
});
|
||||
|
||||
return (): void => {
|
||||
joinSub.unsubscribe();
|
||||
leftSub.unsubscribe();
|
||||
handRaisedSub.unsubscribe();
|
||||
};
|
||||
}, [audioEngineRef, vm]);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
Subject,
|
||||
combineLatest,
|
||||
concat,
|
||||
distinct,
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
forkJoin,
|
||||
@@ -1099,13 +1098,16 @@ export class CallViewModel extends ViewModel {
|
||||
);
|
||||
|
||||
public readonly handsRaised = new Subject<Record<string, Date>>();
|
||||
public readonly reactions = new Subject<Record<string, ReactionOption>>();
|
||||
private readonly reactions = new Subject<Record<string, ReactionOption>>();
|
||||
|
||||
public updateReactions(data: ReturnType<typeof useReactions>) {
|
||||
this.handsRaised.next(data.raisedHands);
|
||||
this.reactions.next(data.reactions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an array of reactions that should be visible on the screen.
|
||||
*/
|
||||
public readonly visibleReactions = showReactions.value
|
||||
.pipe(switchMap((show) => (show ? this.reactions : of({}))))
|
||||
.pipe(
|
||||
@@ -1125,6 +1127,9 @@ export class CallViewModel extends ViewModel {
|
||||
)
|
||||
.pipe(this.scope.state());
|
||||
|
||||
/**
|
||||
* Emits an array of reactions that should be played.
|
||||
*/
|
||||
public readonly audibleReactions = playReactionsSound.value
|
||||
.pipe(
|
||||
switchMap((show) =>
|
||||
@@ -1147,10 +1152,25 @@ export class CallViewModel extends ViewModel {
|
||||
{ playing: [], newSounds: [] },
|
||||
),
|
||||
map((v) => v.newSounds),
|
||||
distinct(),
|
||||
)
|
||||
.pipe(this.scope.state());
|
||||
|
||||
/**
|
||||
* Emits an event every time a new hand is raised in
|
||||
* the call.
|
||||
*/
|
||||
public readonly handRaised = this.handsRaised.pipe(
|
||||
map((v) => Object.keys(v).length),
|
||||
scan(
|
||||
(acc, newValue) => ({
|
||||
value: newValue,
|
||||
playSounds: newValue > acc.value,
|
||||
}),
|
||||
{ value: 0, playSounds: false },
|
||||
),
|
||||
filter((v) => v.playSounds),
|
||||
);
|
||||
|
||||
public constructor(
|
||||
// A call is permanently tied to a single Matrix room and LiveKit room
|
||||
private readonly matrixRTCSession: MatrixRTCSession,
|
||||
|
||||
Reference in New Issue
Block a user