From 77ce828d66f0d6379a301a184734e625019a19e0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 Jun 2024 13:41:43 +0100 Subject: [PATCH 1/3] Hide voip buttons in group rooms in environments with widgets disabled Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/hooks/room/useRoomCall.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hooks/room/useRoomCall.ts b/src/hooks/room/useRoomCall.ts index 57145235fac..1d4a8a79346 100644 --- a/src/hooks/room/useRoomCall.ts +++ b/src/hooks/room/useRoomCall.ts @@ -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, @@ -89,6 +91,7 @@ export const useRoomCall = ( const useElementCallExclusively = useMemo(() => { return SdkConfig.get("element_call").use_exclusively; }, []); + const widgetsEnabled = SettingsStore.getValue(UIFeature.Widgets); const hasLegacyCall = useEventEmitterState( LegacyCallHandler.instance, @@ -124,13 +127,13 @@ export const useRoomCall = ( // The options provided to the RoomHeader. // If there are multiple options, the user will be prompted to choose. const callOptions = useMemo((): PlatformCallType[] => { - const options = []; + const options: PlatformCallType[] = []; if (memberCount <= 2) { options.push(PlatformCallType.LegacyCall); - } else if (mayEditWidgets || hasJitsiWidget) { + } else if ((mayEditWidgets || hasJitsiWidget) && widgetsEnabled) { options.push(PlatformCallType.JitsiCall); } - if (groupCallsEnabled) { + if (groupCallsEnabled && widgetsEnabled) { if (hasGroupCall || mayCreateElementCalls) { options.push(PlatformCallType.ElementCall); } @@ -152,6 +155,7 @@ export const useRoomCall = ( mayCreateElementCalls, useElementCallExclusively, groupCall?.widget.type, + widgetsEnabled, ]); let widget: IApp | undefined; From 4f6eced1d4caf48f4a71d5976550f9dae5e0fc14 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 Jun 2024 13:53:22 +0100 Subject: [PATCH 2/3] Fix test stubs Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- test/components/views/rooms/RoomHeader-test.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/components/views/rooms/RoomHeader-test.tsx b/test/components/views/rooms/RoomHeader-test.tsx index a3cb89a7fb8..99668b4fa05 100644 --- a/test/components/views/rooms/RoomHeader-test.tsx +++ b/test/components/views/rooms/RoomHeader-test.tsx @@ -60,6 +60,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"); @@ -294,7 +295,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 () => { From d6f2861901386f0152ced9d39087afde7208efc6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 Jun 2024 14:54:42 +0100 Subject: [PATCH 3/3] Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomHeader.tsx | 43 ++++++++++--------- src/hooks/room/useRoomCall.ts | 16 ++++--- .../views/rooms/RoomHeader-test.tsx | 42 +++++++++++++++++- 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/src/components/views/rooms/RoomHeader.tsx b/src/components/views/rooms/RoomHeader.tsx index 59dfdb219e3..d37ff18a768 100644 --- a/src/components/views/rooms/RoomHeader.tsx +++ b/src/components/views/rooms/RoomHeader.tsx @@ -83,6 +83,7 @@ export default function RoomHeader({ hasActiveCallSession, callOptions, showVoiceCallButton, + showVideoCallButton, } = useRoomCall(room); const groupCallsEnabled = useFeatureEnabled("feature_group_calls"); @@ -200,25 +201,20 @@ export default function RoomHeader({ )} ); - - let voiceCallButton: JSX.Element | undefined; - if (showVoiceCallButton) { - voiceCallButton = ( - - voiceCallClick(ev, callOptions[0])} - > - - - - ); - } - + let voiceCallButton: JSX.Element | undefined = ( + + voiceCallClick(ev, callOptions[0])} + > + + + + ); const closeLobbyButton = ( @@ -226,13 +222,20 @@ export default function RoomHeader({ ); - 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 ( <> diff --git a/src/hooks/room/useRoomCall.ts b/src/hooks/room/useRoomCall.ts index 277c9ee72ca..fd2ed9c7502 100644 --- a/src/hooks/room/useRoomCall.ts +++ b/src/hooks/room/useRoomCall.ts @@ -85,6 +85,7 @@ export const useRoomCall = ( isConnectedToCall: boolean; hasActiveCallSession: boolean; callOptions: PlatformCallType[]; + showVideoCallButton: boolean; showVoiceCallButton: boolean; } => { // settings @@ -92,7 +93,6 @@ export const useRoomCall = ( const useElementCallExclusively = useMemo(() => { return SdkConfig.get("element_call").use_exclusively; }, []); - const widgetsEnabled = SettingsStore.getValue(UIFeature.Widgets); const hasLegacyCall = useEventEmitterState( LegacyCallHandler.instance, @@ -131,10 +131,10 @@ export const useRoomCall = ( const options: PlatformCallType[] = []; if (memberCount <= 2) { options.push(PlatformCallType.LegacyCall); - } else if ((mayEditWidgets || hasJitsiWidget) && widgetsEnabled) { + } else if (mayEditWidgets || hasJitsiWidget) { options.push(PlatformCallType.JitsiCall); } - if (groupCallsEnabled && widgetsEnabled) { + if (groupCallsEnabled) { if (hasGroupCall || mayCreateElementCalls) { options.push(PlatformCallType.ElementCall); } @@ -156,7 +156,6 @@ export const useRoomCall = ( mayCreateElementCalls, useElementCallExclusively, groupCall?.widget.type, - widgetsEnabled, ]); let widget: IApp | undefined; @@ -272,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 @@ -289,5 +294,6 @@ export const useRoomCall = ( hasActiveCallSession: hasActiveCallSession, callOptions, showVoiceCallButton: !hideVoiceCallButton, + showVideoCallButton: !hideVideoCallButton, }; }; diff --git a/test/components/views/rooms/RoomHeader-test.tsx b/test/components/views/rooms/RoomHeader-test.tsx index 30de1a636f5..92ababba28f 100644 --- a/test/components/views/rooms/RoomHeader-test.tsx +++ b/test/components/views/rooms/RoomHeader-test.tsx @@ -256,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(, 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(, 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(, 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(, 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(, getWrapper()); @@ -356,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);