Hide voice call button when redundant (#12639)
* Hide voice call button when redundant i.e. when it'd do the same thing as the video call button like in non-dm rooms Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>pull/28217/head
							parent
							
								
									04e1d7f6c0
								
							
						
					
					
						commit
						76844f5973
					
				|  | @ -82,6 +82,7 @@ export default function RoomHeader({ | |||
|         isConnectedToCall, | ||||
|         hasActiveCallSession, | ||||
|         callOptions, | ||||
|         showVoiceCallButton, | ||||
|     } = useRoomCall(room); | ||||
| 
 | ||||
|     const groupCallsEnabled = useFeatureEnabled("feature_group_calls"); | ||||
|  | @ -199,20 +200,25 @@ export default function RoomHeader({ | |||
|             )} | ||||
|         </> | ||||
|     ); | ||||
|     const 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; | ||||
|     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> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     const closeLobbyButton = ( | ||||
|         <Tooltip label={_t("voip|close_lobby")}> | ||||
|             <IconButton onClick={toggleCall} aria-label={_t("voip|close_lobby")}> | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ import { placeCall } from "../../utils/room/placeCall"; | |||
| import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore"; | ||||
| import { useRoomState } from "../useRoomState"; | ||||
| import { _t } from "../../languageHandler"; | ||||
| import { isManagedHybridWidget } from "../../widgets/ManagedHybrid"; | ||||
| import { isManagedHybridWidget, isManagedHybridWidgetEnabled } from "../../widgets/ManagedHybrid"; | ||||
| import { IApp } from "../../stores/WidgetStore"; | ||||
| import { SdkContextClass } from "../../contexts/SDKContext"; | ||||
| import { UPDATE_EVENT } from "../../stores/AsyncStore"; | ||||
|  | @ -83,6 +83,7 @@ export const useRoomCall = ( | |||
|     isConnectedToCall: boolean; | ||||
|     hasActiveCallSession: boolean; | ||||
|     callOptions: PlatformCallType[]; | ||||
|     showVoiceCallButton: boolean; | ||||
| } => { | ||||
|     // settings
 | ||||
|     const groupCallsEnabled = useFeatureEnabled("feature_group_calls"); | ||||
|  | @ -124,7 +125,7 @@ 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) { | ||||
|  | @ -266,6 +267,10 @@ 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 = | ||||
|         isManagedHybridWidgetEnabled(room.roomId) || !callOptions.includes(PlatformCallType.LegacyCall); | ||||
| 
 | ||||
|     /** | ||||
|      * We've gone through all the steps | ||||
|      */ | ||||
|  | @ -279,5 +284,6 @@ export const useRoomCall = ( | |||
|         isConnectedToCall: isConnectedToCall, | ||||
|         hasActiveCallSession: hasActiveCallSession, | ||||
|         callOptions, | ||||
|         showVoiceCallButton: !hideVoiceCallButton, | ||||
|     }; | ||||
| }; | ||||
|  |  | |||
|  | @ -34,6 +34,7 @@ import { | |||
|     getByRole, | ||||
|     getByText, | ||||
|     queryAllByLabelText, | ||||
|     queryByLabelText, | ||||
|     render, | ||||
|     RenderOptions, | ||||
|     screen, | ||||
|  | @ -232,6 +233,28 @@ describe("RoomHeader", () => { | |||
|         expect(setCardSpy).toHaveBeenCalledWith({ phase: RightPanelPhases.NotificationPanel }); | ||||
|     }); | ||||
| 
 | ||||
|     it("should show both call buttons in rooms smaller than 3 members", async () => { | ||||
|         mockRoomMembers(room, 2); | ||||
|         const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
|         expect(getByLabelText(container, "Video call")).toBeInTheDocument(); | ||||
|         expect(getByLabelText(container, "Voice call")).toBeInTheDocument(); | ||||
|     }); | ||||
| 
 | ||||
|     it("should not show voice call button in managed hybrid environments", async () => { | ||||
|         mockRoomMembers(room, 2); | ||||
|         jest.spyOn(SdkConfig, "get").mockReturnValue({ widget_build_url: "https://widget.build.url" }); | ||||
|         const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
|         expect(getByLabelText(container, "Video call")).toBeInTheDocument(); | ||||
|         expect(queryByLabelText(container, "Voice call")).not.toBeInTheDocument(); | ||||
|     }); | ||||
| 
 | ||||
|     it("should not show voice call button in rooms larger than 2 members", async () => { | ||||
|         mockRoomMembers(room, 3); | ||||
|         const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
|         expect(getByLabelText(container, "Video call")).toBeInTheDocument(); | ||||
|         expect(queryByLabelText(container, "Voice call")).not.toBeInTheDocument(); | ||||
|     }); | ||||
| 
 | ||||
|     describe("groups call disabled", () => { | ||||
|         it("you can't call if you're alone", () => { | ||||
|             mockRoomMembers(room, 1); | ||||
|  | @ -270,12 +293,11 @@ describe("RoomHeader", () => { | |||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         it("can calls in large rooms if able to edit widgets", () => { | ||||
|         it("can call in large rooms if able to edit widgets", () => { | ||||
|             mockRoomMembers(room, 10); | ||||
|             jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true); | ||||
|             const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
| 
 | ||||
|             expect(getByLabelText(container, "Voice call")).not.toHaveAttribute("aria-disabled", "true"); | ||||
|             expect(getByLabelText(container, "Video call")).not.toHaveAttribute("aria-disabled", "true"); | ||||
|         }); | ||||
| 
 | ||||
|  | @ -283,9 +305,6 @@ describe("RoomHeader", () => { | |||
|             mockRoomMembers(room, 10); | ||||
|             jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(false); | ||||
|             const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
|             expect( | ||||
|                 getByLabelText(container, "You do not have permission to start voice calls", { selector: "button" }), | ||||
|             ).toHaveAttribute("aria-disabled", "true"); | ||||
|             expect( | ||||
|                 getByLabelText(container, "You do not have permission to start video calls", { selector: "button" }), | ||||
|             ).toHaveAttribute("aria-disabled", "true"); | ||||
|  | @ -456,15 +475,10 @@ describe("RoomHeader", () => { | |||
| 
 | ||||
|             const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
| 
 | ||||
|             const voiceButton = getByLabelText(container, "Voice call"); | ||||
|             const videoButton = getByLabelText(container, "Video call"); | ||||
|             expect(voiceButton).not.toHaveAttribute("aria-disabled", "true"); | ||||
|             expect(videoButton).not.toHaveAttribute("aria-disabled", "true"); | ||||
| 
 | ||||
|             const placeCallSpy = jest.spyOn(LegacyCallHandler.instance, "placeCall"); | ||||
|             fireEvent.click(voiceButton); | ||||
|             expect(placeCallSpy).toHaveBeenLastCalledWith(room.roomId, CallType.Voice); | ||||
| 
 | ||||
|             fireEvent.click(videoButton); | ||||
|             expect(placeCallSpy).toHaveBeenLastCalledWith(room.roomId, CallType.Video); | ||||
|         }); | ||||
|  | @ -479,9 +493,7 @@ describe("RoomHeader", () => { | |||
| 
 | ||||
|             const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
| 
 | ||||
|             const voiceButton = getByLabelText(container, "Voice call"); | ||||
|             const videoButton = getByLabelText(container, "Video call"); | ||||
|             expect(voiceButton).not.toHaveAttribute("aria-disabled", "true"); | ||||
|             expect(videoButton).not.toHaveAttribute("aria-disabled", "true"); | ||||
| 
 | ||||
|             const dispatcherSpy = jest.spyOn(dispatcher, "dispatch"); | ||||
|  | @ -497,9 +509,8 @@ describe("RoomHeader", () => { | |||
|             ); | ||||
|             const { container } = render(<RoomHeader room={room} />, getWrapper()); | ||||
| 
 | ||||
|             const [videoButton, voiceButton] = getAllByLabelText(container, "Ongoing call"); | ||||
|             const [videoButton] = getAllByLabelText(container, "Ongoing call"); | ||||
| 
 | ||||
|             expect(voiceButton).toHaveAttribute("aria-disabled", "true"); | ||||
|             expect(videoButton).toHaveAttribute("aria-disabled", "true"); | ||||
|         }); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Michael Telatynski
						Michael Telatynski