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

Hide voip buttons in group rooms in environments with widgets disabled #12664

Merged
merged 4 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions src/components/views/rooms/RoomHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default function RoomHeader({
hasActiveCallSession,
callOptions,
showVoiceCallButton,
showVideoCallButton,
} = useRoomCall(room);

const groupCallsEnabled = useFeatureEnabled("feature_group_calls");
Expand Down Expand Up @@ -200,39 +201,41 @@ export default function RoomHeader({
)}
</>
);

let voiceCallButton: JSX.Element | undefined;
if (showVoiceCallButton) {
voiceCallButton = (
<Tooltip label={voiceCallDisabledReason ?? _t("voip|voice_call")}>
<IconButton
// We need both: isViewingCall and isConnectedToCall
// - in the Lobby we are viewing a call but are not connected to it.
// - in pip view we are connected to the call but not viewing it.
disabled={!!voiceCallDisabledReason || isViewingCall || isConnectedToCall}
aria-label={voiceCallDisabledReason ?? _t("voip|voice_call")}
onClick={(ev) => voiceCallClick(ev, callOptions[0])}
>
<VoiceCallIcon />
</IconButton>
</Tooltip>
);
}

let voiceCallButton: JSX.Element | undefined = (
<Tooltip label={voiceCallDisabledReason ?? _t("voip|voice_call")}>
<IconButton
// We need both: isViewingCall and isConnectedToCall
// - in the Lobby we are viewing a call but are not connected to it.
// - in pip view we are connected to the call but not viewing it.
disabled={!!voiceCallDisabledReason || isViewingCall || isConnectedToCall}
aria-label={voiceCallDisabledReason ?? _t("voip|voice_call")}
onClick={(ev) => voiceCallClick(ev, callOptions[0])}
>
<VoiceCallIcon />
</IconButton>
</Tooltip>
);
const closeLobbyButton = (
<Tooltip label={_t("voip|close_lobby")}>
<IconButton onClick={toggleCall} aria-label={_t("voip|close_lobby")}>
<CloseCallIcon />
</IconButton>
</Tooltip>
);
let videoCallButton = startVideoCallButton;
let videoCallButton: JSX.Element | undefined = startVideoCallButton;
if (isConnectedToCall) {
videoCallButton = toggleCallButton;
} else if (isViewingCall) {
videoCallButton = closeLobbyButton;
}

if (!showVideoCallButton) {
videoCallButton = undefined;
}
if (!showVoiceCallButton) {
voiceCallButton = undefined;
}

return (
<>
<Flex as="header" align="center" gap="var(--cpd-space-3x)" className="mx_RoomHeader light-panel">
Expand Down
12 changes: 11 additions & 1 deletion src/hooks/room/useRoomCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import { Action } from "../../dispatcher/actions";
import { CallStore, CallStoreEvent } from "../../stores/CallStore";
import { isVideoRoom } from "../../utils/video-rooms";
import { useGuestAccessInformation } from "./useGuestAccessInformation";
import SettingsStore from "../../settings/SettingsStore";
import { UIFeature } from "../../settings/UIFeature";

export enum PlatformCallType {
ElementCall,
Expand Down Expand Up @@ -83,6 +85,7 @@ export const useRoomCall = (
isConnectedToCall: boolean;
hasActiveCallSession: boolean;
callOptions: PlatformCallType[];
showVideoCallButton: boolean;
showVoiceCallButton: boolean;
} => {
// settings
Expand Down Expand Up @@ -268,8 +271,14 @@ export const useRoomCall = (
}, [isViewingCall, room.roomId]);

// We hide the voice call button if it'd have the same effect as the video call button
const hideVoiceCallButton =
let hideVoiceCallButton =
isManagedHybridWidgetEnabled(room.roomId) || !callOptions.includes(PlatformCallType.LegacyCall);
let hideVideoCallButton = false;
// We hide both buttons if they require widgets but widgets are disabled.
if (memberCount > 2 && !SettingsStore.getValue(UIFeature.Widgets)) {
hideVoiceCallButton = true;
hideVideoCallButton = true;
}

/**
* We've gone through all the steps
Expand All @@ -285,5 +294,6 @@ export const useRoomCall = (
hasActiveCallSession: hasActiveCallSession,
callOptions,
showVoiceCallButton: !hideVoiceCallButton,
showVideoCallButton: !hideVideoCallButton,
};
};
47 changes: 45 additions & 2 deletions test/components/views/rooms/RoomHeader-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { _t } from "../../../../src/languageHandler";
import * as UseCall from "../../../../src/hooks/useCall";
import { SdkContextClass } from "../../../../src/contexts/SDKContext";
import WidgetStore, { IApp } from "../../../../src/stores/WidgetStore";
import { UIFeature } from "../../../../src/settings/UIFeature";

jest.mock("../../../../src/utils/ShieldUtils");

Expand Down Expand Up @@ -255,7 +256,47 @@ describe("RoomHeader", () => {
expect(queryByLabelText(container, "Voice call")).not.toBeInTheDocument();
});

describe("UIFeature.Widgets enabled (default)", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature == UIFeature.Widgets);
});

it("should show call buttons in a room with 2 members", () => {
mockRoomMembers(room, 2);
const { container } = render(<RoomHeader room={room} />, getWrapper());
expect(getByLabelText(container, "Video call")).toBeInTheDocument();
});

it("should show call buttons in a room with more than 2 members", () => {
mockRoomMembers(room, 3);
const { container } = render(<RoomHeader room={room} />, getWrapper());
expect(getByLabelText(container, "Video call")).toBeInTheDocument();
});
});

describe("UIFeature.Widgets disabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => false);
});

it("should show call buttons in a room with 2 members", () => {
mockRoomMembers(room, 2);
const { container } = render(<RoomHeader room={room} />, getWrapper());
expect(getByLabelText(container, "Video call")).toBeInTheDocument();
});

it("should not show call buttons in a room with more than 2 members", () => {
mockRoomMembers(room, 3);
const { container } = render(<RoomHeader room={room} />, getWrapper());
expect(queryByLabelText(container, "Video call")).not.toBeInTheDocument();
});
});

describe("groups call disabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature == UIFeature.Widgets);
});

it("you can't call if you're alone", () => {
mockRoomMembers(room, 1);
const { container } = render(<RoomHeader room={room} />, getWrapper());
Expand Down Expand Up @@ -313,7 +354,9 @@ describe("RoomHeader", () => {

describe("group call enabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature === "feature_group_calls");
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(feature) => feature === "feature_group_calls" || feature == UIFeature.Widgets,
);
});

it("renders only the video call element", async () => {
Expand Down Expand Up @@ -353,7 +396,7 @@ describe("RoomHeader", () => {

it("clicking on ongoing (unpinned) call re-pins it", () => {
mockRoomMembers(room, 3);
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature == UIFeature.Widgets);
// allow calls
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
jest.spyOn(WidgetLayoutStore.instance, "isInContainer").mockReturnValue(false);
Expand Down
Loading