From 0f7a2ce6df2243d3ee38b81771a0f13e05e4f9ba Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Mon, 2 Jan 2023 13:21:33 +0100 Subject: [PATCH] Confirm listen to a broadcast while recording (#9831) --- src/contexts/SDKContext.ts | 2 +- src/i18n/strings/en_EN.json | 5 +- .../ConfirmListeBroadcastStopCurrent.tsx | 56 ++++++++++++ src/voice-broadcast/index.ts | 1 + .../models/VoiceBroadcastPlayback.ts | 25 +++++- .../stores/VoiceBroadcastPlaybacksStore.ts | 11 ++- test/LegacyCallHandler-test.ts | 1 + test/components/views/voip/PipView-test.tsx | 2 +- test/stores/RoomViewStore-test.ts | 3 +- .../components/VoiceBroadcastBody-test.tsx | 3 +- .../VoiceBroadcastPlaybackBody-test.tsx | 7 +- .../VoiceBroadcastPreRecordingPip-test.tsx | 2 +- .../VoiceBroadcastSmallPlaybackBody-test.tsx | 7 +- ...est.ts => VoiceBroadcastPlayback-test.tsx} | 86 ++++++++++++++++++- .../models/VoiceBroadcastPreRecording-test.ts | 2 +- .../VoiceBroadcastPlaybacksStore-test.ts | 8 +- .../VoiceBroadcastPreRecordingStore-test.ts | 4 +- ...pauseNonLiveBroadcastFromOtherRoom-test.ts | 7 +- .../setUpVoiceBroadcastPreRecording-test.ts | 6 +- .../startNewVoiceBroadcastRecording-test.ts | 4 +- 20 files changed, 213 insertions(+), 29 deletions(-) create mode 100644 src/voice-broadcast/components/molecules/ConfirmListeBroadcastStopCurrent.tsx rename test/voice-broadcast/models/{VoiceBroadcastPlayback-test.ts => VoiceBroadcastPlayback-test.tsx} (85%) diff --git a/src/contexts/SDKContext.ts b/src/contexts/SDKContext.ts index 2f2317c24a..c3d4f64899 100644 --- a/src/contexts/SDKContext.ts +++ b/src/contexts/SDKContext.ts @@ -172,7 +172,7 @@ export class SdkContextClass { public get voiceBroadcastPlaybacksStore(): VoiceBroadcastPlaybacksStore { if (!this._VoiceBroadcastPlaybacksStore) { - this._VoiceBroadcastPlaybacksStore = new VoiceBroadcastPlaybacksStore(); + this._VoiceBroadcastPlaybacksStore = new VoiceBroadcastPlaybacksStore(this.voiceBroadcastRecordingsStore); } return this._VoiceBroadcastPlaybacksStore; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 87a7c5c721..e9f5aabb76 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -659,6 +659,10 @@ "Stop live broadcasting?": "Stop live broadcasting?", "Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.": "Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.", "Yes, stop broadcast": "Yes, stop broadcast", + "Listen to live broadcast?": "Listen to live broadcast?", + "If you start listening to this live broadcast, your current live broadcast recording will be ended.": "If you start listening to this live broadcast, your current live broadcast recording will be ended.", + "Yes, end my recording": "Yes, end my recording", + "No": "No", "30s backward": "30s backward", "30s forward": "30s forward", "Go live": "Go live", @@ -815,7 +819,6 @@ "Learn more": "Learn more", "Share anonymous data to help us identify issues. Nothing personal. No third parties. Learn More": "Share anonymous data to help us identify issues. Nothing personal. No third parties. Learn More", "Yes": "Yes", - "No": "No", "Help improve %(analyticsOwner)s": "Help improve %(analyticsOwner)s", "You have unverified sessions": "You have unverified sessions", "Review to ensure your account is safe": "Review to ensure your account is safe", diff --git a/src/voice-broadcast/components/molecules/ConfirmListeBroadcastStopCurrent.tsx b/src/voice-broadcast/components/molecules/ConfirmListeBroadcastStopCurrent.tsx new file mode 100644 index 0000000000..babef3564f --- /dev/null +++ b/src/voice-broadcast/components/molecules/ConfirmListeBroadcastStopCurrent.tsx @@ -0,0 +1,56 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { defer } from "matrix-js-sdk/src/utils"; +import React from "react"; + +import BaseDialog from "../../../components/views/dialogs/BaseDialog"; +import DialogButtons from "../../../components/views/elements/DialogButtons"; +import { _t } from "../../../languageHandler"; +import Modal from "../../../Modal"; + +interface Props { + onFinished: (confirmed: boolean) => void; +} + +export const ConfirmListenBroadcastStopCurrentDialog: React.FC = ({ onFinished }) => { + return ( + +

+ {_t( + "If you start listening to this live broadcast, " + + "your current live broadcast recording will be ended.", + )} +

+ onFinished(true)} + primaryButton={_t("Yes, end my recording")} + cancelButton={_t("No")} + onCancel={() => onFinished(false)} + /> +
+ ); +}; + +export const showConfirmListenBroadcastStopCurrentDialog = async (): Promise => { + const { promise, resolve } = defer(); + + Modal.createDialog(ConfirmListenBroadcastStopCurrentDialog, { + onFinished: resolve, + }); + + return promise; +}; diff --git a/src/voice-broadcast/index.ts b/src/voice-broadcast/index.ts index e0be5f821b..b6d859a925 100644 --- a/src/voice-broadcast/index.ts +++ b/src/voice-broadcast/index.ts @@ -30,6 +30,7 @@ export * from "./components/atoms/VoiceBroadcastControl"; export * from "./components/atoms/VoiceBroadcastHeader"; export * from "./components/atoms/VoiceBroadcastPlaybackControl"; export * from "./components/atoms/VoiceBroadcastRoomSubtitle"; +export * from "./components/molecules/ConfirmListeBroadcastStopCurrent"; export * from "./components/molecules/VoiceBroadcastPlaybackBody"; export * from "./components/molecules/VoiceBroadcastSmallPlaybackBody"; export * from "./components/molecules/VoiceBroadcastPreRecordingPip"; diff --git a/src/voice-broadcast/models/VoiceBroadcastPlayback.ts b/src/voice-broadcast/models/VoiceBroadcastPlayback.ts index 047c36b3b3..a1fc48aca2 100644 --- a/src/voice-broadcast/models/VoiceBroadcastPlayback.ts +++ b/src/voice-broadcast/models/VoiceBroadcastPlayback.ts @@ -36,6 +36,8 @@ import { VoiceBroadcastInfoEventType, VoiceBroadcastInfoState, VoiceBroadcastInfoEventContent, + VoiceBroadcastRecordingsStore, + showConfirmListenBroadcastStopCurrentDialog, } from ".."; import { RelationsHelper, RelationsHelperEvent } from "../../events/RelationsHelper"; import { VoiceBroadcastChunkEvents } from "../utils/VoiceBroadcastChunkEvents"; @@ -86,7 +88,7 @@ export class VoiceBroadcastPlayback public readonly liveData = new SimpleObservable(); private liveness: VoiceBroadcastLiveness = "not-live"; - // set vial addInfoEvent() in constructor + // set via addInfoEvent() in constructor private infoState!: VoiceBroadcastInfoState; private lastInfoEvent!: MatrixEvent; @@ -94,7 +96,11 @@ export class VoiceBroadcastPlayback private chunkRelationHelper!: RelationsHelper; private infoRelationHelper!: RelationsHelper; - public constructor(public readonly infoEvent: MatrixEvent, private client: MatrixClient) { + public constructor( + public readonly infoEvent: MatrixEvent, + private client: MatrixClient, + private recordings: VoiceBroadcastRecordingsStore, + ) { super(); this.addInfoEvent(this.infoEvent); this.infoEvent.on(MatrixEventEvent.BeforeRedaction, this.onBeforeRedaction); @@ -399,6 +405,21 @@ export class VoiceBroadcastPlayback } public async start(): Promise { + if (this.state === VoiceBroadcastPlaybackState.Playing) return; + + const currentRecording = this.recordings.getCurrent(); + + if (currentRecording && currentRecording.getState() !== VoiceBroadcastInfoState.Stopped) { + const shouldStopRecording = await showConfirmListenBroadcastStopCurrentDialog(); + + if (!shouldStopRecording) { + // keep recording + return; + } + + await this.recordings.getCurrent()?.stop(); + } + const chunkEvents = this.chunkEvents.getEvents(); const toPlay = diff --git a/src/voice-broadcast/stores/VoiceBroadcastPlaybacksStore.ts b/src/voice-broadcast/stores/VoiceBroadcastPlaybacksStore.ts index 4e92524025..e0afea2bc1 100644 --- a/src/voice-broadcast/stores/VoiceBroadcastPlaybacksStore.ts +++ b/src/voice-broadcast/stores/VoiceBroadcastPlaybacksStore.ts @@ -17,7 +17,12 @@ limitations under the License. import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix"; import { TypedEventEmitter } from "matrix-js-sdk/src/models/typed-event-emitter"; -import { VoiceBroadcastPlayback, VoiceBroadcastPlaybackEvent, VoiceBroadcastPlaybackState } from ".."; +import { + VoiceBroadcastPlayback, + VoiceBroadcastPlaybackEvent, + VoiceBroadcastPlaybackState, + VoiceBroadcastRecordingsStore, +} from ".."; import { IDestroyable } from "../../utils/IDestroyable"; export enum VoiceBroadcastPlaybacksStoreEvent { @@ -42,7 +47,7 @@ export class VoiceBroadcastPlaybacksStore /** Playbacks indexed by their info event id. */ private playbacks = new Map(); - public constructor() { + public constructor(private recordings: VoiceBroadcastRecordingsStore) { super(); } @@ -69,7 +74,7 @@ export class VoiceBroadcastPlaybacksStore const infoEventId = infoEvent.getId(); if (!this.playbacks.has(infoEventId)) { - this.addPlayback(new VoiceBroadcastPlayback(infoEvent, client)); + this.addPlayback(new VoiceBroadcastPlayback(infoEvent, client, this.recordings)); } return this.playbacks.get(infoEventId); diff --git a/test/LegacyCallHandler-test.ts b/test/LegacyCallHandler-test.ts index 91d8a602a8..3e21780dab 100644 --- a/test/LegacyCallHandler-test.ts +++ b/test/LegacyCallHandler-test.ts @@ -406,6 +406,7 @@ describe("LegacyCallHandler", () => { "d42", ), MatrixClientPeg.get(), + SdkContextClass.instance.voiceBroadcastRecordingsStore, ); SdkContextClass.instance.voiceBroadcastPlaybacksStore.setCurrent(voiceBroadcastPlayback); jest.spyOn(voiceBroadcastPlayback, "pause").mockImplementation(); diff --git a/test/components/views/voip/PipView-test.tsx b/test/components/views/voip/PipView-test.tsx index 4d15116f96..6da5f1d6f8 100644 --- a/test/components/views/voip/PipView-test.tsx +++ b/test/components/views/voip/PipView-test.tsx @@ -112,7 +112,7 @@ describe("PipView", () => { sdkContext = new TestSdkContext(); voiceBroadcastRecordingsStore = new VoiceBroadcastRecordingsStore(); voiceBroadcastPreRecordingStore = new VoiceBroadcastPreRecordingStore(); - voiceBroadcastPlaybacksStore = new VoiceBroadcastPlaybacksStore(); + voiceBroadcastPlaybacksStore = new VoiceBroadcastPlaybacksStore(voiceBroadcastRecordingsStore); sdkContext.client = client; sdkContext._VoiceBroadcastRecordingsStore = voiceBroadcastRecordingsStore; sdkContext._VoiceBroadcastPreRecordingStore = voiceBroadcastPreRecordingStore; diff --git a/test/stores/RoomViewStore-test.ts b/test/stores/RoomViewStore-test.ts index c5075beb77..30a8cff02c 100644 --- a/test/stores/RoomViewStore-test.ts +++ b/test/stores/RoomViewStore-test.ts @@ -132,7 +132,7 @@ describe("RoomViewStore", function () { stores._SlidingSyncManager = slidingSyncManager; stores._PosthogAnalytics = new MockPosthogAnalytics(); stores._SpaceStore = new MockSpaceStore(); - stores._VoiceBroadcastPlaybacksStore = new VoiceBroadcastPlaybacksStore(); + stores._VoiceBroadcastPlaybacksStore = new VoiceBroadcastPlaybacksStore(stores.voiceBroadcastRecordingsStore); roomViewStore = new RoomViewStore(dis, stores); stores._RoomViewStore = roomViewStore; }); @@ -271,6 +271,7 @@ describe("RoomViewStore", function () { "d42", ), mockClient, + stores.voiceBroadcastRecordingsStore, ); stores.voiceBroadcastPlaybacksStore.setCurrent(voiceBroadcastPlayback); jest.spyOn(voiceBroadcastPlayback, "pause").mockImplementation(); diff --git a/test/voice-broadcast/components/VoiceBroadcastBody-test.tsx b/test/voice-broadcast/components/VoiceBroadcastBody-test.tsx index 77ea0953a9..571d8a661e 100644 --- a/test/voice-broadcast/components/VoiceBroadcastBody-test.tsx +++ b/test/voice-broadcast/components/VoiceBroadcastBody-test.tsx @@ -26,6 +26,7 @@ import { VoiceBroadcastRecording, VoiceBroadcastPlaybackBody, VoiceBroadcastPlayback, + VoiceBroadcastRecordingsStore, } from "../../../src/voice-broadcast"; import { stubClient, wrapInSdkContext } from "../../test-utils"; import { mkVoiceBroadcastInfoStateEvent } from "../utils/test-utils"; @@ -91,7 +92,7 @@ describe("VoiceBroadcastBody", () => { ); room.addEventsToTimeline([infoEvent], true, room.getLiveTimeline()); testRecording = new VoiceBroadcastRecording(infoEvent, client); - testPlayback = new VoiceBroadcastPlayback(infoEvent, client); + testPlayback = new VoiceBroadcastPlayback(infoEvent, client, new VoiceBroadcastRecordingsStore()); mocked(VoiceBroadcastRecordingBody).mockImplementation(({ recording }): ReactElement | null => { if (testRecording === recording) { return
; diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx index 1021066c2d..540653b1c2 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx @@ -32,6 +32,7 @@ import { stubClient } from "../../../test-utils"; import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils"; import dis from "../../../../src/dispatcher/dispatcher"; import { Action } from "../../../../src/dispatcher/actions"; +import { SdkContextClass } from "../../../../src/contexts/SDKContext"; jest.mock("../../../../src/dispatcher/dispatcher"); @@ -66,7 +67,11 @@ describe("VoiceBroadcastPlaybackBody", () => { }); beforeEach(() => { - playback = new VoiceBroadcastPlayback(infoEvent, client); + playback = new VoiceBroadcastPlayback( + infoEvent, + client, + SdkContextClass.instance.voiceBroadcastRecordingsStore, + ); jest.spyOn(playback, "toggle").mockImplementation(() => Promise.resolve()); jest.spyOn(playback, "getLiveness"); jest.spyOn(playback, "getState"); diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx index 96b3c8c774..a15efc86bc 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx @@ -66,8 +66,8 @@ describe("VoiceBroadcastPreRecordingPip", () => { client = stubClient(); room = new Room("!room@example.com", client, client.getUserId() || ""); sender = new RoomMember(room.roomId, client.getUserId() || ""); - playbacksStore = new VoiceBroadcastPlaybacksStore(); recordingsStore = new VoiceBroadcastRecordingsStore(); + playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore); mocked(requestMediaPermissions).mockResolvedValue({ getTracks: (): Array => [], } as unknown as MediaStream); diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastSmallPlaybackBody-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastSmallPlaybackBody-test.tsx index 31d8ee9311..bb374ea73a 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastSmallPlaybackBody-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastSmallPlaybackBody-test.tsx @@ -29,6 +29,7 @@ import { } from "../../../../src/voice-broadcast"; import { stubClient } from "../../../test-utils"; import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils"; +import { SdkContextClass } from "../../../../src/contexts/SDKContext"; // mock RoomAvatar, because it is doing too much fancy stuff jest.mock("../../../../src/components/views/avatars/RoomAvatar", () => ({ @@ -60,7 +61,11 @@ describe("", () => { }); beforeEach(() => { - playback = new VoiceBroadcastPlayback(infoEvent, client); + playback = new VoiceBroadcastPlayback( + infoEvent, + client, + SdkContextClass.instance.voiceBroadcastRecordingsStore, + ); jest.spyOn(playback, "toggle").mockImplementation(() => Promise.resolve()); jest.spyOn(playback, "getLiveness"); jest.spyOn(playback, "getState"); diff --git a/test/voice-broadcast/models/VoiceBroadcastPlayback-test.ts b/test/voice-broadcast/models/VoiceBroadcastPlayback-test.tsx similarity index 85% rename from test/voice-broadcast/models/VoiceBroadcastPlayback-test.ts rename to test/voice-broadcast/models/VoiceBroadcastPlayback-test.tsx index ad8d6f4587..e99605c7d3 100644 --- a/test/voice-broadcast/models/VoiceBroadcastPlayback-test.ts +++ b/test/voice-broadcast/models/VoiceBroadcastPlayback-test.tsx @@ -15,10 +15,13 @@ limitations under the License. */ import { mocked } from "jest-mock"; +import { screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; import { Playback, PlaybackState } from "../../../src/audio/Playback"; import { PlaybackManager } from "../../../src/audio/PlaybackManager"; +import { SdkContextClass } from "../../../src/contexts/SDKContext"; import { MediaEventHelper } from "../../../src/utils/MediaEventHelper"; import { VoiceBroadcastInfoState, @@ -26,6 +29,7 @@ import { VoiceBroadcastPlayback, VoiceBroadcastPlaybackEvent, VoiceBroadcastPlaybackState, + VoiceBroadcastRecording, } from "../../../src/voice-broadcast"; import { flushPromises, stubClient } from "../../test-utils"; import { createTestPlayback } from "../../test-utils/audio"; @@ -65,6 +69,17 @@ describe("VoiceBroadcastPlayback", () => { let chunk2Playback: Playback; let chunk3Playback: Playback; + const queryConfirmListeningDialog = () => { + return screen.queryByText( + "If you start listening to this live broadcast, your current live broadcast recording will be ended.", + ); + }; + + const waitForDialog = async () => { + await flushPromises(); + await flushPromises(); + }; + const itShouldSetTheStateTo = (state: VoiceBroadcastPlaybackState) => { it(`should set the state to ${state}`, () => { expect(playback.getState()).toBe(state); @@ -119,7 +134,11 @@ describe("VoiceBroadcastPlayback", () => { }; const mkPlayback = async () => { - const playback = new VoiceBroadcastPlayback(infoEvent, client); + const playback = new VoiceBroadcastPlayback( + infoEvent, + client, + SdkContextClass.instance.voiceBroadcastRecordingsStore, + ); jest.spyOn(playback, "removeAllListeners"); jest.spyOn(playback, "destroy"); playback.on(VoiceBroadcastPlaybackEvent.StateChanged, onStateChanged); @@ -178,7 +197,11 @@ describe("VoiceBroadcastPlayback", () => { onStateChanged = jest.fn(); }); - afterEach(() => { + afterEach(async () => { + SdkContextClass.instance.voiceBroadcastPlaybacksStore.getCurrent()?.stop(); + SdkContextClass.instance.voiceBroadcastPlaybacksStore.clearCurrent(); + await SdkContextClass.instance.voiceBroadcastRecordingsStore.getCurrent()?.stop(); + SdkContextClass.instance.voiceBroadcastRecordingsStore.clearCurrent(); playback.destroy(); }); @@ -347,6 +370,59 @@ describe("VoiceBroadcastPlayback", () => { }); }); }); + + describe("and currently recording a broadcast", () => { + let recording: VoiceBroadcastRecording; + + beforeEach(async () => { + recording = new VoiceBroadcastRecording( + mkVoiceBroadcastInfoStateEvent( + roomId, + VoiceBroadcastInfoState.Started, + client.getSafeUserId(), + client.deviceId, + ), + client, + ); + jest.spyOn(recording, "stop"); + SdkContextClass.instance.voiceBroadcastRecordingsStore.setCurrent(recording); + playback.start(); + await waitForDialog(); + }); + + it("should display a confirm modal", () => { + expect(queryConfirmListeningDialog()).toBeInTheDocument(); + }); + + describe("when confirming the dialog", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText("Yes, end my recording")); + }); + + it("should stop the recording", () => { + expect(recording.stop).toHaveBeenCalled(); + expect(SdkContextClass.instance.voiceBroadcastRecordingsStore.getCurrent()).toBeNull(); + }); + + it("should not start the playback", () => { + expect(playback.getState()).toBe(VoiceBroadcastPlaybackState.Playing); + }); + }); + + describe("when not confirming the dialog", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText("No")); + }); + + it("should not stop the recording", () => { + expect(recording.stop).not.toHaveBeenCalled(); + }); + + it("should start the playback", () => { + expect(playback.getState()).toBe(VoiceBroadcastPlaybackState.Stopped); + }); + }); + }); }); describe("when there is a stopped voice broadcast", () => { @@ -375,6 +451,12 @@ describe("VoiceBroadcastPlayback", () => { expect(chunk2Playback.play).not.toHaveBeenCalled(); }); + describe("and calling start again", () => { + it("should not play the first chunk a second time", () => { + expect(chunk1Playback.play).toHaveBeenCalledTimes(1); + }); + }); + describe("and the chunk playback progresses", () => { beforeEach(() => { chunk1Playback.clockInfo.liveData.update([11]); diff --git a/test/voice-broadcast/models/VoiceBroadcastPreRecording-test.ts b/test/voice-broadcast/models/VoiceBroadcastPreRecording-test.ts index 985a8156a2..a709f865ba 100644 --- a/test/voice-broadcast/models/VoiceBroadcastPreRecording-test.ts +++ b/test/voice-broadcast/models/VoiceBroadcastPreRecording-test.ts @@ -40,8 +40,8 @@ describe("VoiceBroadcastPreRecording", () => { client = stubClient(); room = new Room(roomId, client, client.getUserId() || ""); sender = new RoomMember(roomId, client.getUserId() || ""); - playbacksStore = new VoiceBroadcastPlaybacksStore(); recordingsStore = new VoiceBroadcastRecordingsStore(); + playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore); }); beforeEach(() => { diff --git a/test/voice-broadcast/stores/VoiceBroadcastPlaybacksStore-test.ts b/test/voice-broadcast/stores/VoiceBroadcastPlaybacksStore-test.ts index 612ed97653..889e94a093 100644 --- a/test/voice-broadcast/stores/VoiceBroadcastPlaybacksStore-test.ts +++ b/test/voice-broadcast/stores/VoiceBroadcastPlaybacksStore-test.ts @@ -24,6 +24,7 @@ import { VoiceBroadcastPlaybacksStore, VoiceBroadcastPlaybacksStoreEvent, VoiceBroadcastPlaybackState, + VoiceBroadcastRecordingsStore, } from "../../../src/voice-broadcast"; import { mkStubRoom, stubClient } from "../../test-utils"; import { mkVoiceBroadcastInfoStateEvent } from "../utils/test-utils"; @@ -59,12 +60,13 @@ describe("VoiceBroadcastPlaybacksStore", () => { infoEvent1 = mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Started, userId, deviceId); infoEvent2 = mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Started, userId, deviceId); - playback1 = new VoiceBroadcastPlayback(infoEvent1, client); + const recordings = new VoiceBroadcastRecordingsStore(); + playback1 = new VoiceBroadcastPlayback(infoEvent1, client, recordings); jest.spyOn(playback1, "off"); - playback2 = new VoiceBroadcastPlayback(infoEvent2, client); + playback2 = new VoiceBroadcastPlayback(infoEvent2, client, recordings); jest.spyOn(playback2, "off"); - playbacks = new VoiceBroadcastPlaybacksStore(); + playbacks = new VoiceBroadcastPlaybacksStore(recordings); jest.spyOn(playbacks, "removeAllListeners"); onCurrentChanged = jest.fn(); playbacks.on(VoiceBroadcastPlaybacksStoreEvent.CurrentChanged, onCurrentChanged); diff --git a/test/voice-broadcast/stores/VoiceBroadcastPreRecordingStore-test.ts b/test/voice-broadcast/stores/VoiceBroadcastPreRecordingStore-test.ts index 97e944b564..dfffb6e872 100644 --- a/test/voice-broadcast/stores/VoiceBroadcastPreRecordingStore-test.ts +++ b/test/voice-broadcast/stores/VoiceBroadcastPreRecordingStore-test.ts @@ -25,8 +25,6 @@ import { } from "../../../src/voice-broadcast"; import { stubClient } from "../../test-utils"; -jest.mock("../../../src/voice-broadcast/stores/VoiceBroadcastRecordingsStore"); - describe("VoiceBroadcastPreRecordingStore", () => { const roomId = "!room:example.com"; let client: MatrixClient; @@ -41,8 +39,8 @@ describe("VoiceBroadcastPreRecordingStore", () => { client = stubClient(); room = new Room(roomId, client, client.getUserId() || ""); sender = new RoomMember(roomId, client.getUserId() || ""); - playbacksStore = new VoiceBroadcastPlaybacksStore(); recordingsStore = new VoiceBroadcastRecordingsStore(); + playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore); }); beforeEach(() => { diff --git a/test/voice-broadcast/utils/pauseNonLiveBroadcastFromOtherRoom-test.ts b/test/voice-broadcast/utils/pauseNonLiveBroadcastFromOtherRoom-test.ts index 1aba3a6b11..db2bc80982 100644 --- a/test/voice-broadcast/utils/pauseNonLiveBroadcastFromOtherRoom-test.ts +++ b/test/voice-broadcast/utils/pauseNonLiveBroadcastFromOtherRoom-test.ts @@ -20,6 +20,7 @@ import { VoiceBroadcastInfoState, VoiceBroadcastPlayback, VoiceBroadcastPlaybacksStore, + VoiceBroadcastRecordingsStore, } from "../../../src/voice-broadcast"; import { pauseNonLiveBroadcastFromOtherRoom } from "../../../src/voice-broadcast/utils/pauseNonLiveBroadcastFromOtherRoom"; import { stubClient } from "../../test-utils"; @@ -32,6 +33,7 @@ describe("pauseNonLiveBroadcastFromOtherRoom", () => { let client: MatrixClient; let playback: VoiceBroadcastPlayback; let playbacks: VoiceBroadcastPlaybacksStore; + let recordings: VoiceBroadcastRecordingsStore; const mkPlayback = (infoState: VoiceBroadcastInfoState, roomId: string): VoiceBroadcastPlayback => { const infoEvent = mkVoiceBroadcastInfoStateEvent( @@ -40,7 +42,7 @@ describe("pauseNonLiveBroadcastFromOtherRoom", () => { client.getSafeUserId(), client.getDeviceId()!, ); - const playback = new VoiceBroadcastPlayback(infoEvent, client); + const playback = new VoiceBroadcastPlayback(infoEvent, client, recordings); jest.spyOn(playback, "pause"); playbacks.setCurrent(playback); return playback; @@ -49,7 +51,8 @@ describe("pauseNonLiveBroadcastFromOtherRoom", () => { beforeEach(() => { client = stubClient(); room = new Room(roomId, client, client.getSafeUserId()); - playbacks = new VoiceBroadcastPlaybacksStore(); + recordings = new VoiceBroadcastRecordingsStore(); + playbacks = new VoiceBroadcastPlaybacksStore(recordings); jest.spyOn(playbacks, "clearCurrent"); }); diff --git a/test/voice-broadcast/utils/setUpVoiceBroadcastPreRecording-test.ts b/test/voice-broadcast/utils/setUpVoiceBroadcastPreRecording-test.ts index a9d2cea13d..224207f95c 100644 --- a/test/voice-broadcast/utils/setUpVoiceBroadcastPreRecording-test.ts +++ b/test/voice-broadcast/utils/setUpVoiceBroadcastPreRecording-test.ts @@ -80,10 +80,10 @@ describe("setUpVoiceBroadcastPreRecording", () => { ); preRecording = null; preRecordingStore = new VoiceBroadcastPreRecordingStore(); - playback = new VoiceBroadcastPlayback(infoEvent, client); - jest.spyOn(playback, "pause"); - playbacksStore = new VoiceBroadcastPlaybacksStore(); recordingsStore = new VoiceBroadcastRecordingsStore(); + playback = new VoiceBroadcastPlayback(infoEvent, client, recordingsStore); + jest.spyOn(playback, "pause"); + playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore); }); describe("when the preconditions fail", () => { diff --git a/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts b/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts index 091a452d22..afab8278df 100644 --- a/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts +++ b/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts @@ -84,7 +84,7 @@ describe("startNewVoiceBroadcastRecording", () => { skey: "", }); - playbacksStore = new VoiceBroadcastPlaybacksStore(); + playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore); recordingsStore = { setCurrent: jest.fn(), getCurrent: jest.fn(), @@ -112,7 +112,7 @@ describe("startNewVoiceBroadcastRecording", () => { let playback: VoiceBroadcastPlayback; beforeEach(() => { - playback = new VoiceBroadcastPlayback(infoEvent, client); + playback = new VoiceBroadcastPlayback(infoEvent, client, recordingsStore); jest.spyOn(playback, "pause"); playbacksStore.setCurrent(playback); });