diff --git a/src/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl.tsx b/src/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl.tsx index 238b50de14..9f16f9637c 100644 --- a/src/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl.tsx +++ b/src/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl.tsx @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2022-2023 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. @@ -27,8 +27,8 @@ interface Props { } export const VoiceBroadcastPlaybackControl: React.FC = ({ onClick, state }) => { - let controlIcon: ReactElement; - let controlLabel: string; + let controlIcon: ReactElement | null = null; + let controlLabel: string | null = null; let className = ""; switch (state) { @@ -49,5 +49,11 @@ export const VoiceBroadcastPlaybackControl: React.FC = ({ onClick, state break; } - return ; + if (controlIcon && controlLabel) { + return ( + + ); + } + + return null; }; diff --git a/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts b/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts index 8f36d77bf4..660bf31865 100644 --- a/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts +++ b/src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2022-2023 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. @@ -48,6 +48,12 @@ export const useVoiceBroadcastPlayback = ( throw new Error(`Voice Broadcast room not found (event ${playback.infoEvent.getId()})`); } + const sender = playback.infoEvent.sender; + + if (!sender) { + throw new Error(`Voice Broadcast sender not found (event ${playback.infoEvent.getId()})`); + } + const playbackToggle = (): void => { playback.toggle(); }; @@ -87,7 +93,7 @@ export const useVoiceBroadcastPlayback = ( liveness: liveness, playbackState, room: room, - sender: playback.infoEvent.sender, + sender, toggle: playbackToggle, }; }; diff --git a/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx b/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx index 71f4ccf1f1..e4e0f9955c 100644 --- a/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx +++ b/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2022-2023 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. @@ -66,6 +66,12 @@ export const useVoiceBroadcastRecording = ( throw new Error("Unable to find voice broadcast room with Id: " + roomId); } + const sender = recording.infoEvent.sender; + + if (!sender) { + throw new Error(`Voice Broadcast sender not found (event ${recording.infoEvent.getId()})`); + } + const stopRecording = async (): Promise => { const confirmed = await showStopBroadcastingDialog(); @@ -99,7 +105,7 @@ export const useVoiceBroadcastRecording = ( timeLeft, recordingState, room, - sender: recording.infoEvent.sender, + sender, stopRecording, toggleRecording: recording.toggle, }; diff --git a/src/voice-broadcast/stores/VoiceBroadcastRecordingsStore.ts b/src/voice-broadcast/stores/VoiceBroadcastRecordingsStore.ts index 3776ea8244..b484e6ef3a 100644 --- a/src/voice-broadcast/stores/VoiceBroadcastRecordingsStore.ts +++ b/src/voice-broadcast/stores/VoiceBroadcastRecordingsStore.ts @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2022-2023 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. @@ -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 { VoiceBroadcastInfoState, VoiceBroadcastRecording, VoiceBroadcastRecordingEvent } from ".."; +import { + VoiceBroadcastInfoState, + VoiceBroadcastRecording, + VoiceBroadcastRecordingEvent, + VoiceBroadcastRecordingState, +} from ".."; export enum VoiceBroadcastRecordingsStoreEvent { CurrentChanged = "current_changed", @@ -85,7 +90,7 @@ export class VoiceBroadcastRecordingsStore extends TypedEventEmitter { + private onCurrentStateChanged = (state: VoiceBroadcastRecordingState): void => { if (state === VoiceBroadcastInfoState.Stopped) { this.clearCurrent(); } diff --git a/test/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl-test.tsx b/test/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl-test.tsx index a70530a476..d86e1e1386 100644 --- a/test/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl-test.tsx +++ b/test/voice-broadcast/components/atoms/VoiceBroadcastPlaybackControl-test.tsx @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2022-2023 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. @@ -38,6 +38,12 @@ describe("", () => { expect(renderControl(state).result.container).toMatchSnapshot(); }); + it("should not render for error state", () => { + expect(renderControl(VoiceBroadcastPlaybackState.Error).result.asFragment()).toMatchInlineSnapshot( + ``, + ); + }); + describe("when clicking the control", () => { let onClick: () => void; diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx index 15cf39f443..adc3a55824 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2022-2023 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. @@ -233,15 +233,25 @@ describe("VoiceBroadcastPlaybackBody", () => { describe.each([ [VoiceBroadcastPlaybackState.Paused, "not-live"], [VoiceBroadcastPlaybackState.Playing, "live"], - ])("when rendering a %s/%s broadcast", (state: VoiceBroadcastPlaybackState, liveness: VoiceBroadcastLiveness) => { - beforeEach(() => { - mocked(playback.getState).mockReturnValue(state); - mocked(playback.getLiveness).mockReturnValue(liveness); - renderResult = render(); - }); + ] satisfies [VoiceBroadcastPlaybackState, VoiceBroadcastLiveness][])( + "when rendering a %s/%s broadcast", + (state: VoiceBroadcastPlaybackState, liveness: VoiceBroadcastLiveness) => { + beforeEach(() => { + mocked(playback.getState).mockReturnValue(state); + mocked(playback.getLiveness).mockReturnValue(liveness); + renderResult = render(); + }); - it("should render as expected", () => { - expect(renderResult.container).toMatchSnapshot(); - }); + it("should render as expected", () => { + expect(renderResult.container).toMatchSnapshot(); + }); + }, + ); + + it("when there is a broadcast without sender, it should raise an error", () => { + infoEvent.sender = null; + expect(() => { + render(); + }).toThrow(`Voice Broadcast sender not found (event ${playback.infoEvent.getId()})`); }); }); diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingBody-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingBody-test.tsx index 2edf6b002d..7d3fd700f5 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingBody-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingBody-test.tsx @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2022-2023 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. @@ -77,4 +77,11 @@ describe("VoiceBroadcastRecordingBody", () => { expect(renderResult.container).toMatchSnapshot(); }); }); + + it("when there is a broadcast without sender, it should raise an error", () => { + infoEvent.sender = null; + expect(() => { + render(); + }).toThrow(`Voice Broadcast sender not found (event ${recording.infoEvent.getId()})`); + }); });