mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-31 07:00:26 +00:00
Merge remote-tracking branch 'origin/livekit' into hs/emoji-reactions
This commit is contained in:
22
src/utils/iter.test.ts
Normal file
22
src/utils/iter.test.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { test, expect } from "vitest";
|
||||
|
||||
import { fillGaps } from "./iter";
|
||||
|
||||
test("fillGaps filters out gaps", () => {
|
||||
expect([
|
||||
...fillGaps([1, undefined, undefined, undefined, 3], [2]),
|
||||
]).toStrictEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
test("fillGaps adds extra filler elements to the end", () => {
|
||||
expect([
|
||||
...fillGaps([1, undefined, 3, undefined], [2, 4, 5, 6]),
|
||||
]).toStrictEqual([1, 2, 3, 4, 5, 6]);
|
||||
});
|
||||
36
src/utils/iter.ts
Normal file
36
src/utils/iter.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fills in the 'undefined' gaps in a collection by drawing items from a second
|
||||
* collection, or simply filtering out the gap if no items are left. If filler
|
||||
* items remain at the end, they will be appended to the resulting collection.
|
||||
*/
|
||||
export function fillGaps<A>(
|
||||
gappy: Iterable<A | undefined>,
|
||||
filler: Iterable<A>,
|
||||
): Iterable<A> {
|
||||
return {
|
||||
[Symbol.iterator](): Iterator<A> {
|
||||
const gappyIter = gappy[Symbol.iterator]();
|
||||
const fillerIter = filler[Symbol.iterator]();
|
||||
return {
|
||||
next(): IteratorResult<A> {
|
||||
let gappyItem: IteratorResult<A | undefined>;
|
||||
do {
|
||||
gappyItem = gappyIter.next();
|
||||
if (!gappyItem.done && gappyItem.value !== undefined)
|
||||
return gappyItem as IteratorYieldResult<A>;
|
||||
const fillerItem = fillerIter.next();
|
||||
if (!fillerItem.done) return fillerItem;
|
||||
} while (!gappyItem.done);
|
||||
return gappyItem;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -4,7 +4,7 @@ Copyright 2023, 2024 New Vector Ltd.
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
import { map } from "rxjs";
|
||||
import { map, Observable, of } from "rxjs";
|
||||
import { RunHelpers, TestScheduler } from "rxjs/testing";
|
||||
import { expect, vi } from "vitest";
|
||||
import { RoomMember, Room as MatrixRoom } from "matrix-js-sdk/src/matrix";
|
||||
@@ -99,8 +99,27 @@ export function mockMatrixRoom(room: Partial<MatrixRoom>): MatrixRoom {
|
||||
return { ...mockEmitter(), ...room } as Partial<MatrixRoom> as MatrixRoom;
|
||||
}
|
||||
|
||||
export function mockLivekitRoom(room: Partial<LivekitRoom>): LivekitRoom {
|
||||
return { ...mockEmitter(), ...room } as Partial<LivekitRoom> as LivekitRoom;
|
||||
export function mockLivekitRoom(
|
||||
room: Partial<LivekitRoom>,
|
||||
{
|
||||
remoteParticipants,
|
||||
}: { remoteParticipants?: Observable<RemoteParticipant[]> } = {},
|
||||
): LivekitRoom {
|
||||
const livekitRoom = {
|
||||
...mockEmitter(),
|
||||
...room,
|
||||
} as Partial<LivekitRoom> as LivekitRoom;
|
||||
if (remoteParticipants) {
|
||||
livekitRoom.remoteParticipants = new Map();
|
||||
remoteParticipants.subscribe((newRemoteParticipants) => {
|
||||
livekitRoom.remoteParticipants.clear();
|
||||
newRemoteParticipants.forEach((p) => {
|
||||
livekitRoom.remoteParticipants.set(p.identity, p);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return livekitRoom;
|
||||
}
|
||||
|
||||
export function mockLocalParticipant(
|
||||
@@ -119,13 +138,15 @@ export async function withLocalMedia(
|
||||
member: Partial<RoomMember>,
|
||||
continuation: (vm: LocalUserMediaViewModel) => void | Promise<void>,
|
||||
): Promise<void> {
|
||||
const localParticipant = mockLocalParticipant({});
|
||||
const vm = new LocalUserMediaViewModel(
|
||||
"local",
|
||||
mockMember(member),
|
||||
mockLocalParticipant({}),
|
||||
localParticipant,
|
||||
{
|
||||
kind: E2eeType.PER_PARTICIPANT,
|
||||
},
|
||||
mockLivekitRoom({ localParticipant }),
|
||||
);
|
||||
try {
|
||||
await continuation(vm);
|
||||
@@ -152,13 +173,15 @@ export async function withRemoteMedia(
|
||||
participant: Partial<RemoteParticipant>,
|
||||
continuation: (vm: RemoteUserMediaViewModel) => void | Promise<void>,
|
||||
): Promise<void> {
|
||||
const remoteParticipant = mockRemoteParticipant(participant);
|
||||
const vm = new RemoteUserMediaViewModel(
|
||||
"remote",
|
||||
mockMember(member),
|
||||
mockRemoteParticipant(participant),
|
||||
remoteParticipant,
|
||||
{
|
||||
kind: E2eeType.PER_PARTICIPANT,
|
||||
},
|
||||
mockLivekitRoom({}, { remoteParticipants: of([remoteParticipant]) }),
|
||||
);
|
||||
try {
|
||||
await continuation(vm);
|
||||
|
||||
Reference in New Issue
Block a user