From a701296f33a8293a8a829157efd71d4acf7365b8 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Tue, 13 Dec 2022 13:32:19 +0100 Subject: [PATCH] Link voice broadcast avatar and room name to room (#9722) --- .../components/atoms/VoiceBroadcastHeader.tsx | 32 ++++- .../molecules/VoiceBroadcastPlaybackBody.tsx | 1 + .../VoiceBroadcastPreRecordingPip.tsx | 1 + .../molecules/VoiceBroadcastRecordingPip.tsx | 2 +- .../VoiceBroadcastPlaybackBody-test.tsx | 40 ++++++ .../VoiceBroadcastPreRecordingPip-test.tsx | 39 ++++-- .../VoiceBroadcastRecordingPip-test.tsx | 39 ++++-- .../VoiceBroadcastPlaybackBody-test.tsx.snap | 119 ++++++++++++++++++ ...oiceBroadcastPreRecordingPip-test.tsx.snap | 22 +++- .../VoiceBroadcastRecordingPip-test.tsx.snap | 44 +++++-- 10 files changed, 304 insertions(+), 35 deletions(-) diff --git a/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx b/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx index e1ee393f81..3814399b93 100644 --- a/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx +++ b/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx @@ -21,17 +21,21 @@ import { Icon as MicrophoneIcon } from "../../../../res/img/voip/call-view/mic-o import { Icon as TimerIcon } from "../../../../res/img/element-icons/Timer.svg"; import { _t } from "../../../languageHandler"; import RoomAvatar from "../../../components/views/avatars/RoomAvatar"; -import AccessibleButton from "../../../components/views/elements/AccessibleButton"; +import AccessibleButton, { ButtonEvent } from "../../../components/views/elements/AccessibleButton"; import { Icon as XIcon } from "../../../../res/img/element-icons/cancel-rounded.svg"; import Clock from "../../../components/views/audio_messages/Clock"; import { formatTimeLeft } from "../../../DateUtils"; import Spinner from "../../../components/views/elements/Spinner"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; +import { Action } from "../../../dispatcher/actions"; +import dis from "../../../dispatcher/dispatcher"; import AccessibleTooltipButton from "../../../components/views/elements/AccessibleTooltipButton"; interface VoiceBroadcastHeaderProps { + linkToRoom?: boolean; live?: VoiceBroadcastLiveness; onCloseClick?: () => void; - onMicrophoneLineClick?: () => void; + onMicrophoneLineClick?: ((e: ButtonEvent) => void | Promise) | null; room: Room; microphoneLabel?: string; showBroadcast?: boolean; @@ -41,9 +45,10 @@ interface VoiceBroadcastHeaderProps { } export const VoiceBroadcastHeader: React.FC = ({ + linkToRoom = false, live = "not-live", onCloseClick = () => {}, - onMicrophoneLineClick, + onMicrophoneLineClick = null, room, microphoneLabel, showBroadcast = false, @@ -96,11 +101,28 @@ export const VoiceBroadcastHeader: React.FC = ({ ); + const onRoomAvatarOrNameClick = (): void => { + dis.dispatch({ + action: Action.ViewRoom, + room_id: room.roomId, + metricsTrigger: undefined, // other + }); + }; + + let roomAvatar = ; + let roomName =
{room.name}
; + + if (linkToRoom) { + roomAvatar = {roomAvatar}; + + roomName = {roomName}; + } + return (
- + {roomAvatar}
-
{room.name}
+ {roomName} {microphoneLine} {timeLeftLine} {broadcast} diff --git a/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx b/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx index 8c93975b01..54c4e90412 100644 --- a/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx +++ b/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx @@ -98,6 +98,7 @@ export const VoiceBroadcastPlaybackBody: React.FC = ({ voiceBroadcastP return (
setShowDeviceSelect(true)} room={voiceBroadcastPreRecording.room} diff --git a/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx b/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx index 1ae05b086e..1f97c5ba34 100644 --- a/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx +++ b/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx @@ -74,7 +74,7 @@ export const VoiceBroadcastRecordingPip: React.FC - +
{toggleControl} diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx index 02cfff0042..1021066c2d 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx @@ -30,6 +30,10 @@ import { } from "../../../../src/voice-broadcast"; import { stubClient } from "../../../test-utils"; import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils"; +import dis from "../../../../src/dispatcher/dispatcher"; +import { Action } from "../../../../src/dispatcher/actions"; + +jest.mock("../../../../src/dispatcher/dispatcher"); // mock RoomAvatar, because it is doing too much fancy stuff jest.mock("../../../../src/components/views/avatars/RoomAvatar", () => ({ @@ -128,6 +132,42 @@ describe("VoiceBroadcastPlaybackBody", () => { }); }); }); + + describe("and clicking the room name", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText("My room")); + }); + + it("should not view the room", () => { + expect(dis.dispatch).not.toHaveBeenCalled(); + }); + }); + }); + + describe("when rendering a playing broadcast in pip mode", () => { + beforeEach(() => { + mocked(playback.getState).mockReturnValue(VoiceBroadcastPlaybackState.Playing); + mocked(playback.getLiveness).mockReturnValue("not-live"); + renderResult = render(); + }); + + it("should render as expected", () => { + expect(renderResult.container).toMatchSnapshot(); + }); + + describe("and clicking the room name", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText("My room")); + }); + + it("should view the room", () => { + expect(dis.dispatch).toHaveBeenCalledWith({ + action: Action.ViewRoom, + room_id: roomId, + metricsTrigger: undefined, + }); + }); + }); }); describe(`when rendering a stopped broadcast`, () => { diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx index cece0b8679..8a8d57278b 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx @@ -29,7 +29,10 @@ import { import { flushPromises, stubClient } from "../../../test-utils"; import { requestMediaPermissions } from "../../../../src/utils/media/requestMediaPermissions"; import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../../src/MediaDeviceHandler"; +import dis from "../../../../src/dispatcher/dispatcher"; +import { Action } from "../../../../src/dispatcher/actions"; +jest.mock("../../../../src/dispatcher/dispatcher"); jest.mock("../../../../src/utils/media/requestMediaPermissions"); // mock RoomAvatar, because it is doing too much fancy stuff @@ -49,19 +52,25 @@ describe("VoiceBroadcastPreRecordingPip", () => { let room: Room; let sender: RoomMember; + const itShouldShowTheBroadcastRoom = () => { + it("should show the broadcast room", () => { + expect(dis.dispatch).toHaveBeenCalledWith({ + action: Action.ViewRoom, + room_id: room.roomId, + metricsTrigger: undefined, + }); + }); + }; + beforeEach(() => { client = stubClient(); room = new Room("!room@example.com", client, client.getUserId() || ""); sender = new RoomMember(room.roomId, client.getUserId() || ""); playbacksStore = new VoiceBroadcastPlaybacksStore(); recordingsStore = new VoiceBroadcastRecordingsStore(); - mocked(requestMediaPermissions).mockReturnValue( - new Promise((r) => { - r({ - getTracks: () => [], - } as unknown as MediaStream); - }), - ); + mocked(requestMediaPermissions).mockResolvedValue({ + getTracks: (): Array => [], + } as unknown as MediaStream); jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({ [MediaDeviceKindEnum.AudioInput]: [ { @@ -97,6 +106,22 @@ describe("VoiceBroadcastPreRecordingPip", () => { expect(renderResult.container).toMatchSnapshot(); }); + describe("and clicking the room name", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText(room.name)); + }); + + itShouldShowTheBroadcastRoom(); + }); + + describe("and clicking the room avatar", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText(`room avatar: ${room.name}`)); + }); + + itShouldShowTheBroadcastRoom(); + }); + describe("and clicking the device label", () => { beforeEach(async () => { await act(async () => { diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx index b996d3d13b..15b3348465 100644 --- a/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx +++ b/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx @@ -31,7 +31,10 @@ import { filterConsole, flushPromises, stubClient } from "../../../test-utils"; import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils"; import { requestMediaPermissions } from "../../../../src/utils/media/requestMediaPermissions"; import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../../src/MediaDeviceHandler"; +import dis from "../../../../src/dispatcher/dispatcher"; +import { Action } from "../../../../src/dispatcher/actions"; +jest.mock("../../../../src/dispatcher/dispatcher"); jest.mock("../../../../src/utils/media/requestMediaPermissions"); // mock RoomAvatar, because it is doing too much fancy stuff @@ -72,15 +75,21 @@ describe("VoiceBroadcastRecordingPip", () => { }); }; + const itShouldShowTheBroadcastRoom = () => { + it("should show the broadcast room", () => { + expect(dis.dispatch).toHaveBeenCalledWith({ + action: Action.ViewRoom, + room_id: roomId, + metricsTrigger: undefined, + }); + }); + }; + beforeAll(() => { client = stubClient(); - mocked(requestMediaPermissions).mockReturnValue( - new Promise((r) => { - r({ - getTracks: () => [], - } as unknown as MediaStream); - }), - ); + mocked(requestMediaPermissions).mockResolvedValue({ + getTracks: (): Array => [], + } as unknown as MediaStream); jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({ [MediaDeviceKindEnum.AudioInput]: [ { @@ -130,6 +139,22 @@ describe("VoiceBroadcastRecordingPip", () => { }); }); + describe("and clicking the room name", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText("My room")); + }); + + itShouldShowTheBroadcastRoom(); + }); + + describe("and clicking the room avatar", () => { + beforeEach(async () => { + await userEvent.click(screen.getByText("room avatar: My room")); + }); + + itShouldShowTheBroadcastRoom(); + }); + describe("and clicking the pause button", () => { beforeEach(async () => { await userEvent.click(screen.getByLabelText("pause voice broadcast")); diff --git a/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastPlaybackBody-test.tsx.snap b/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastPlaybackBody-test.tsx.snap index 54de19e1b2..da350d259d 100644 --- a/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastPlaybackBody-test.tsx.snap +++ b/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastPlaybackBody-test.tsx.snap @@ -345,6 +345,125 @@ exports[`VoiceBroadcastPlaybackBody when rendering a buffering voice broadcast s
`; +exports[`VoiceBroadcastPlaybackBody when rendering a playing broadcast in pip mode should render as expected 1`] = ` +
+
+
+
+
+ room avatar: + My room +
+
+
+
+
+ My room +
+
+
+
+ + @user:example.com + +
+
+
+ Voice broadcast +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + 00:00 + + + -23:42 + +
+
+
+`; + exports[`VoiceBroadcastPlaybackBody when rendering a playing broadcast should render as expected 1`] = `
- room avatar: - !room@example.com +
+ room avatar: + !room@example.com +
- !room@example.com +
+ !room@example.com +
- room avatar: - My room +
+ room avatar: + My room +
- My room +
+ My room +
- room avatar: - My room +
+ room avatar: + My room +
- My room +
+ My room +