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

Commit

Permalink
Link voice broadcast avatar and room name to room (#9722)
Browse files Browse the repository at this point in the history
  • Loading branch information
weeman1337 authored Dec 13, 2022
1 parent 9c5b1f3 commit a701296
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 35 deletions.
32 changes: 27 additions & 5 deletions src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<void>) | null;
room: Room;
microphoneLabel?: string;
showBroadcast?: boolean;
Expand All @@ -41,9 +45,10 @@ interface VoiceBroadcastHeaderProps {
}

export const VoiceBroadcastHeader: React.FC<VoiceBroadcastHeaderProps> = ({
linkToRoom = false,
live = "not-live",
onCloseClick = () => {},
onMicrophoneLineClick,
onMicrophoneLineClick = null,
room,
microphoneLabel,
showBroadcast = false,
Expand Down Expand Up @@ -96,11 +101,28 @@ export const VoiceBroadcastHeader: React.FC<VoiceBroadcastHeaderProps> = ({
</AccessibleTooltipButton>
);

const onRoomAvatarOrNameClick = (): void => {
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
metricsTrigger: undefined, // other
});
};

let roomAvatar = <RoomAvatar room={room} width={32} height={32} />;
let roomName = <div className="mx_VoiceBroadcastHeader_room">{room.name}</div>;

if (linkToRoom) {
roomAvatar = <AccessibleButton onClick={onRoomAvatarOrNameClick}>{roomAvatar}</AccessibleButton>;

roomName = <AccessibleButton onClick={onRoomAvatarOrNameClick}>{roomName}</AccessibleButton>;
}

return (
<div className="mx_VoiceBroadcastHeader">
<RoomAvatar room={room} width={32} height={32} />
{roomAvatar}
<div className="mx_VoiceBroadcastHeader_content">
<div className="mx_VoiceBroadcastHeader_room">{room.name}</div>
{roomName}
{microphoneLine}
{timeLeftLine}
{broadcast}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export const VoiceBroadcastPlaybackBody: React.FC<VoiceBroadcastPlaybackBodyProp
return (
<div className={classes}>
<VoiceBroadcastHeader
linkToRoom={pip}
live={liveness}
microphoneLabel={sender?.name}
room={room}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const VoiceBroadcastPreRecordingPip: React.FC<Props> = ({ voiceBroadcastP
return (
<div className="mx_VoiceBroadcastBody mx_VoiceBroadcastBody--pip" ref={pipRef}>
<VoiceBroadcastHeader
linkToRoom={true}
onCloseClick={voiceBroadcastPreRecording.cancel}
onMicrophoneLineClick={() => setShowDeviceSelect(true)}
room={voiceBroadcastPreRecording.room}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const VoiceBroadcastRecordingPip: React.FC<VoiceBroadcastRecordingPipProp

return (
<div className="mx_VoiceBroadcastBody mx_VoiceBroadcastBody--pip" ref={pipRef}>
<VoiceBroadcastHeader live={live ? "live" : "grey"} room={room} timeLeft={timeLeft} />
<VoiceBroadcastHeader linkToRoom={true} live={live ? "live" : "grey"} room={room} timeLeft={timeLeft} />
<hr className="mx_VoiceBroadcastBody_divider" />
<div className="mx_VoiceBroadcastBody_controls">
{toggleControl}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => ({
Expand Down Expand Up @@ -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(<VoiceBroadcastPlaybackBody pip={true} playback={playback} />);
});

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`, () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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("[email protected]", client, client.getUserId() || "");
sender = new RoomMember(room.roomId, client.getUserId() || "");
playbacksStore = new VoiceBroadcastPlaybacksStore();
recordingsStore = new VoiceBroadcastRecordingsStore();
mocked(requestMediaPermissions).mockReturnValue(
new Promise<MediaStream>((r) => {
r({
getTracks: () => [],
} as unknown as MediaStream);
}),
);
mocked(requestMediaPermissions).mockResolvedValue({
getTracks: (): Array<MediaStreamTrack> => [],
} as unknown as MediaStream);
jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({
[MediaDeviceKindEnum.AudioInput]: [
{
Expand Down Expand Up @@ -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 () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<MediaStream>((r) => {
r({
getTracks: () => [],
} as unknown as MediaStream);
}),
);
mocked(requestMediaPermissions).mockResolvedValue({
getTracks: (): Array<MediaStreamTrack> => [],
} as unknown as MediaStream);
jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({
[MediaDeviceKindEnum.AudioInput]: [
{
Expand Down Expand Up @@ -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"));
Expand Down
Loading

0 comments on commit a701296

Please sign in to comment.