This commit is contained in:
Half-Shot
2024-12-19 11:02:57 +00:00
parent 3aff86c2c4
commit acef18b26d
3 changed files with 51 additions and 61 deletions

View File

@@ -16,7 +16,6 @@ import {
import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession"; import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { useObservableEagerState } from "observable-hooks"; import { useObservableEagerState } from "observable-hooks";
import { map } from "rxjs";
import { useMatrixRTCSessionMemberships } from "../useMatrixRTCSessionMemberships"; import { useMatrixRTCSessionMemberships } from "../useMatrixRTCSessionMemberships";
import { useClientState } from "../ClientContext"; import { useClientState } from "../ClientContext";
@@ -75,24 +74,22 @@ export const ReactionsSenderProvider = ({
: undefined; : undefined;
}, [memberships, myUserId]); }, [memberships, myUserId]);
const myReaction = useObservableEagerState( const reactions = useObservableEagerState(vm.reactions$);
vm.reactions$.pipe( const myReaction = useMemo(
map((v) => () =>
myMembershipIdentifier !== undefined myMembershipIdentifier !== undefined
? v[myMembershipIdentifier] ? reactions[myMembershipIdentifier]
: undefined, : undefined,
), [myMembershipIdentifier, reactions],
),
); );
const myRaisedHand = useObservableEagerState( const handsRaised = useObservableEagerState(vm.handsRaised$);
vm.handsRaised$.pipe( const myRaisedHand = useMemo(
map((v) => () =>
myMembershipIdentifier !== undefined myMembershipIdentifier !== undefined
? v[myMembershipIdentifier] ? handsRaised[myMembershipIdentifier]
: undefined, : undefined,
), [myMembershipIdentifier, handsRaised],
),
); );
const toggleRaisedHand = useCallback(async () => { const toggleRaisedHand = useCallback(async () => {

View File

@@ -805,8 +805,7 @@ it("should rank raised hands above video feeds and below speakers and presenters
(vm, { raisedHands$ }) => { (vm, { raisedHands$ }) => {
schedule("ab", { schedule("ab", {
a: () => { a: () => {
// We imagine that only three tiles (the first three) will be visible // We imagine that only two tiles (the first two) will be visible on screen at a time
// on screen at a time
vm.layout$.subscribe((layout) => { vm.layout$.subscribe((layout) => {
if (layout.type === "grid") { if (layout.type === "grid") {
layout.setVisibleTiles(2); layout.setVisibleTiles(2);

View File

@@ -1216,52 +1216,46 @@ export class CallViewModel extends ViewModel {
/** /**
* Emits an array of reactions that should be visible on the screen. * Emits an array of reactions that should be visible on the screen.
*/ */
public readonly visibleReactions$ = showReactions.value$ public readonly visibleReactions$ = showReactions.value$.pipe(
.pipe(switchMap((show) => (show ? this.reactions$ : of({})))) switchMap((show) => (show ? this.reactions$ : of({}))),
.pipe( scan<
scan< Record<string, ReactionOption>,
Record<string, ReactionOption>, { sender: string; emoji: string; startX: number }[]
{ sender: string; emoji: string; startX: number }[] >((acc, latest) => {
>((acc, latest) => { const newSet: { sender: string; emoji: string; startX: number }[] = [];
const newSet: { sender: string; emoji: string; startX: number }[] = []; for (const [sender, reaction] of Object.entries(latest)) {
for (const [sender, reaction] of Object.entries(latest)) { const startX =
const startX = acc.find((v) => v.sender === sender && v.emoji)?.startX ??
acc.find((v) => v.sender === sender && v.emoji)?.startX ?? Math.ceil(Math.random() * 80) + 10;
Math.ceil(Math.random() * 80) + 10; newSet.push({ sender, emoji: reaction.emoji, startX });
newSet.push({ sender, emoji: reaction.emoji, startX }); }
} return newSet;
return newSet; }, []),
}, []), );
)
.pipe(this.scope.state());
/** /**
* Emits an array of reactions that should be played. * Emits an array of reactions that should be played.
*/ */
public readonly audibleReactions$ = playReactionsSound.value$ public readonly audibleReactions$ = playReactionsSound.value$.pipe(
.pipe( switchMap((show) =>
switchMap((show) => show ? this.reactions$ : of<Record<string, ReactionOption>>({}),
show ? this.reactions$ : of<Record<string, ReactionOption>>({}), ),
), map((reactions) => Object.values(reactions).map((v) => v.name)),
) scan<string[], { playing: string[]; newSounds: string[] }>(
.pipe( (acc, latest) => {
map((reactions) => Object.values(reactions).map((v) => v.name)), return {
scan<string[], { playing: string[]; newSounds: string[] }>( playing: latest.filter(
(acc, latest) => { (v) => acc.playing.includes(v) || acc.newSounds.includes(v),
return { ),
playing: latest.filter( newSounds: latest.filter(
(v) => acc.playing.includes(v) || acc.newSounds.includes(v), (v) => !acc.playing.includes(v) && !acc.newSounds.includes(v),
), ),
newSounds: latest.filter( };
(v) => !acc.playing.includes(v) && !acc.newSounds.includes(v), },
), { playing: [], newSounds: [] },
}; ),
}, map((v) => v.newSounds),
{ playing: [], newSounds: [] }, );
),
map((v) => v.newSounds),
)
.pipe(this.scope.state());
/** /**
* Emits an event every time a new hand is raised in * Emits an event every time a new hand is raised in