Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit a701296

Browse files
authored
Link voice broadcast avatar and room name to room (#9722)
1 parent 9c5b1f3 commit a701296

10 files changed

+304
-35
lines changed

src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,21 @@ import { Icon as MicrophoneIcon } from "../../../../res/img/voip/call-view/mic-o
2121
import { Icon as TimerIcon } from "../../../../res/img/element-icons/Timer.svg";
2222
import { _t } from "../../../languageHandler";
2323
import RoomAvatar from "../../../components/views/avatars/RoomAvatar";
24-
import AccessibleButton from "../../../components/views/elements/AccessibleButton";
24+
import AccessibleButton, { ButtonEvent } from "../../../components/views/elements/AccessibleButton";
2525
import { Icon as XIcon } from "../../../../res/img/element-icons/cancel-rounded.svg";
2626
import Clock from "../../../components/views/audio_messages/Clock";
2727
import { formatTimeLeft } from "../../../DateUtils";
2828
import Spinner from "../../../components/views/elements/Spinner";
29+
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
30+
import { Action } from "../../../dispatcher/actions";
31+
import dis from "../../../dispatcher/dispatcher";
2932
import AccessibleTooltipButton from "../../../components/views/elements/AccessibleTooltipButton";
3033

3134
interface VoiceBroadcastHeaderProps {
35+
linkToRoom?: boolean;
3236
live?: VoiceBroadcastLiveness;
3337
onCloseClick?: () => void;
34-
onMicrophoneLineClick?: () => void;
38+
onMicrophoneLineClick?: ((e: ButtonEvent) => void | Promise<void>) | null;
3539
room: Room;
3640
microphoneLabel?: string;
3741
showBroadcast?: boolean;
@@ -41,9 +45,10 @@ interface VoiceBroadcastHeaderProps {
4145
}
4246

4347
export const VoiceBroadcastHeader: React.FC<VoiceBroadcastHeaderProps> = ({
48+
linkToRoom = false,
4449
live = "not-live",
4550
onCloseClick = () => {},
46-
onMicrophoneLineClick,
51+
onMicrophoneLineClick = null,
4752
room,
4853
microphoneLabel,
4954
showBroadcast = false,
@@ -96,11 +101,28 @@ export const VoiceBroadcastHeader: React.FC<VoiceBroadcastHeaderProps> = ({
96101
</AccessibleTooltipButton>
97102
);
98103

104+
const onRoomAvatarOrNameClick = (): void => {
105+
dis.dispatch<ViewRoomPayload>({
106+
action: Action.ViewRoom,
107+
room_id: room.roomId,
108+
metricsTrigger: undefined, // other
109+
});
110+
};
111+
112+
let roomAvatar = <RoomAvatar room={room} width={32} height={32} />;
113+
let roomName = <div className="mx_VoiceBroadcastHeader_room">{room.name}</div>;
114+
115+
if (linkToRoom) {
116+
roomAvatar = <AccessibleButton onClick={onRoomAvatarOrNameClick}>{roomAvatar}</AccessibleButton>;
117+
118+
roomName = <AccessibleButton onClick={onRoomAvatarOrNameClick}>{roomName}</AccessibleButton>;
119+
}
120+
99121
return (
100122
<div className="mx_VoiceBroadcastHeader">
101-
<RoomAvatar room={room} width={32} height={32} />
123+
{roomAvatar}
102124
<div className="mx_VoiceBroadcastHeader_content">
103-
<div className="mx_VoiceBroadcastHeader_room">{room.name}</div>
125+
{roomName}
104126
{microphoneLine}
105127
{timeLeftLine}
106128
{broadcast}

src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export const VoiceBroadcastPlaybackBody: React.FC<VoiceBroadcastPlaybackBodyProp
9898
return (
9999
<div className={classes}>
100100
<VoiceBroadcastHeader
101+
linkToRoom={pip}
101102
live={liveness}
102103
microphoneLabel={sender?.name}
103104
room={room}

src/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const VoiceBroadcastPreRecordingPip: React.FC<Props> = ({ voiceBroadcastP
4141
return (
4242
<div className="mx_VoiceBroadcastBody mx_VoiceBroadcastBody--pip" ref={pipRef}>
4343
<VoiceBroadcastHeader
44+
linkToRoom={true}
4445
onCloseClick={voiceBroadcastPreRecording.cancel}
4546
onMicrophoneLineClick={() => setShowDeviceSelect(true)}
4647
room={voiceBroadcastPreRecording.room}

src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export const VoiceBroadcastRecordingPip: React.FC<VoiceBroadcastRecordingPipProp
7474

7575
return (
7676
<div className="mx_VoiceBroadcastBody mx_VoiceBroadcastBody--pip" ref={pipRef}>
77-
<VoiceBroadcastHeader live={live ? "live" : "grey"} room={room} timeLeft={timeLeft} />
77+
<VoiceBroadcastHeader linkToRoom={true} live={live ? "live" : "grey"} room={room} timeLeft={timeLeft} />
7878
<hr className="mx_VoiceBroadcastBody_divider" />
7979
<div className="mx_VoiceBroadcastBody_controls">
8080
{toggleControl}

test/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody-test.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ import {
3030
} from "../../../../src/voice-broadcast";
3131
import { stubClient } from "../../../test-utils";
3232
import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils";
33+
import dis from "../../../../src/dispatcher/dispatcher";
34+
import { Action } from "../../../../src/dispatcher/actions";
35+
36+
jest.mock("../../../../src/dispatcher/dispatcher");
3337

3438
// mock RoomAvatar, because it is doing too much fancy stuff
3539
jest.mock("../../../../src/components/views/avatars/RoomAvatar", () => ({
@@ -128,6 +132,42 @@ describe("VoiceBroadcastPlaybackBody", () => {
128132
});
129133
});
130134
});
135+
136+
describe("and clicking the room name", () => {
137+
beforeEach(async () => {
138+
await userEvent.click(screen.getByText("My room"));
139+
});
140+
141+
it("should not view the room", () => {
142+
expect(dis.dispatch).not.toHaveBeenCalled();
143+
});
144+
});
145+
});
146+
147+
describe("when rendering a playing broadcast in pip mode", () => {
148+
beforeEach(() => {
149+
mocked(playback.getState).mockReturnValue(VoiceBroadcastPlaybackState.Playing);
150+
mocked(playback.getLiveness).mockReturnValue("not-live");
151+
renderResult = render(<VoiceBroadcastPlaybackBody pip={true} playback={playback} />);
152+
});
153+
154+
it("should render as expected", () => {
155+
expect(renderResult.container).toMatchSnapshot();
156+
});
157+
158+
describe("and clicking the room name", () => {
159+
beforeEach(async () => {
160+
await userEvent.click(screen.getByText("My room"));
161+
});
162+
163+
it("should view the room", () => {
164+
expect(dis.dispatch).toHaveBeenCalledWith({
165+
action: Action.ViewRoom,
166+
room_id: roomId,
167+
metricsTrigger: undefined,
168+
});
169+
});
170+
});
131171
});
132172

133173
describe(`when rendering a stopped broadcast`, () => {

test/voice-broadcast/components/molecules/VoiceBroadcastPreRecordingPip-test.tsx

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ import {
2929
import { flushPromises, stubClient } from "../../../test-utils";
3030
import { requestMediaPermissions } from "../../../../src/utils/media/requestMediaPermissions";
3131
import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../../src/MediaDeviceHandler";
32+
import dis from "../../../../src/dispatcher/dispatcher";
33+
import { Action } from "../../../../src/dispatcher/actions";
3234

35+
jest.mock("../../../../src/dispatcher/dispatcher");
3336
jest.mock("../../../../src/utils/media/requestMediaPermissions");
3437

3538
// mock RoomAvatar, because it is doing too much fancy stuff
@@ -49,19 +52,25 @@ describe("VoiceBroadcastPreRecordingPip", () => {
4952
let room: Room;
5053
let sender: RoomMember;
5154

55+
const itShouldShowTheBroadcastRoom = () => {
56+
it("should show the broadcast room", () => {
57+
expect(dis.dispatch).toHaveBeenCalledWith({
58+
action: Action.ViewRoom,
59+
room_id: room.roomId,
60+
metricsTrigger: undefined,
61+
});
62+
});
63+
};
64+
5265
beforeEach(() => {
5366
client = stubClient();
5467
room = new Room("[email protected]", client, client.getUserId() || "");
5568
sender = new RoomMember(room.roomId, client.getUserId() || "");
5669
playbacksStore = new VoiceBroadcastPlaybacksStore();
5770
recordingsStore = new VoiceBroadcastRecordingsStore();
58-
mocked(requestMediaPermissions).mockReturnValue(
59-
new Promise<MediaStream>((r) => {
60-
r({
61-
getTracks: () => [],
62-
} as unknown as MediaStream);
63-
}),
64-
);
71+
mocked(requestMediaPermissions).mockResolvedValue({
72+
getTracks: (): Array<MediaStreamTrack> => [],
73+
} as unknown as MediaStream);
6574
jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({
6675
[MediaDeviceKindEnum.AudioInput]: [
6776
{
@@ -97,6 +106,22 @@ describe("VoiceBroadcastPreRecordingPip", () => {
97106
expect(renderResult.container).toMatchSnapshot();
98107
});
99108

109+
describe("and clicking the room name", () => {
110+
beforeEach(async () => {
111+
await userEvent.click(screen.getByText(room.name));
112+
});
113+
114+
itShouldShowTheBroadcastRoom();
115+
});
116+
117+
describe("and clicking the room avatar", () => {
118+
beforeEach(async () => {
119+
await userEvent.click(screen.getByText(`room avatar: ${room.name}`));
120+
});
121+
122+
itShouldShowTheBroadcastRoom();
123+
});
124+
100125
describe("and clicking the device label", () => {
101126
beforeEach(async () => {
102127
await act(async () => {

test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ import { filterConsole, flushPromises, stubClient } from "../../../test-utils";
3131
import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils";
3232
import { requestMediaPermissions } from "../../../../src/utils/media/requestMediaPermissions";
3333
import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../../src/MediaDeviceHandler";
34+
import dis from "../../../../src/dispatcher/dispatcher";
35+
import { Action } from "../../../../src/dispatcher/actions";
3436

37+
jest.mock("../../../../src/dispatcher/dispatcher");
3538
jest.mock("../../../../src/utils/media/requestMediaPermissions");
3639

3740
// mock RoomAvatar, because it is doing too much fancy stuff
@@ -72,15 +75,21 @@ describe("VoiceBroadcastRecordingPip", () => {
7275
});
7376
};
7477

78+
const itShouldShowTheBroadcastRoom = () => {
79+
it("should show the broadcast room", () => {
80+
expect(dis.dispatch).toHaveBeenCalledWith({
81+
action: Action.ViewRoom,
82+
room_id: roomId,
83+
metricsTrigger: undefined,
84+
});
85+
});
86+
};
87+
7588
beforeAll(() => {
7689
client = stubClient();
77-
mocked(requestMediaPermissions).mockReturnValue(
78-
new Promise<MediaStream>((r) => {
79-
r({
80-
getTracks: () => [],
81-
} as unknown as MediaStream);
82-
}),
83-
);
90+
mocked(requestMediaPermissions).mockResolvedValue({
91+
getTracks: (): Array<MediaStreamTrack> => [],
92+
} as unknown as MediaStream);
8493
jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({
8594
[MediaDeviceKindEnum.AudioInput]: [
8695
{
@@ -130,6 +139,22 @@ describe("VoiceBroadcastRecordingPip", () => {
130139
});
131140
});
132141

142+
describe("and clicking the room name", () => {
143+
beforeEach(async () => {
144+
await userEvent.click(screen.getByText("My room"));
145+
});
146+
147+
itShouldShowTheBroadcastRoom();
148+
});
149+
150+
describe("and clicking the room avatar", () => {
151+
beforeEach(async () => {
152+
await userEvent.click(screen.getByText("room avatar: My room"));
153+
});
154+
155+
itShouldShowTheBroadcastRoom();
156+
});
157+
133158
describe("and clicking the pause button", () => {
134159
beforeEach(async () => {
135160
await userEvent.click(screen.getByLabelText("pause voice broadcast"));

0 commit comments

Comments
 (0)