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>
This commit is contained in:
parent
04e1d7f6c0
commit
76844f5973
3 changed files with 53 additions and 30 deletions
|
@ -82,6 +82,7 @@ export default function RoomHeader({
|
||||||
isConnectedToCall,
|
isConnectedToCall,
|
||||||
hasActiveCallSession,
|
hasActiveCallSession,
|
||||||
callOptions,
|
callOptions,
|
||||||
|
showVoiceCallButton,
|
||||||
} = useRoomCall(room);
|
} = useRoomCall(room);
|
||||||
|
|
||||||
const groupCallsEnabled = useFeatureEnabled("feature_group_calls");
|
const groupCallsEnabled = useFeatureEnabled("feature_group_calls");
|
||||||
|
@ -199,20 +200,25 @@ export default function RoomHeader({
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
const voiceCallButton = (
|
|
||||||
<Tooltip label={voiceCallDisabledReason ?? _t("voip|voice_call")}>
|
let voiceCallButton: JSX.Element | undefined;
|
||||||
<IconButton
|
if (showVoiceCallButton) {
|
||||||
// We need both: isViewingCall and isConnectedToCall
|
voiceCallButton = (
|
||||||
// - in the Lobby we are viewing a call but are not connected to it.
|
<Tooltip label={voiceCallDisabledReason ?? _t("voip|voice_call")}>
|
||||||
// - in pip view we are connected to the call but not viewing it.
|
<IconButton
|
||||||
disabled={!!voiceCallDisabledReason || isViewingCall || isConnectedToCall}
|
// We need both: isViewingCall and isConnectedToCall
|
||||||
aria-label={voiceCallDisabledReason ?? _t("voip|voice_call")}
|
// - in the Lobby we are viewing a call but are not connected to it.
|
||||||
onClick={(ev) => voiceCallClick(ev, callOptions[0])}
|
// - in pip view we are connected to the call but not viewing it.
|
||||||
>
|
disabled={!!voiceCallDisabledReason || isViewingCall || isConnectedToCall}
|
||||||
<VoiceCallIcon />
|
aria-label={voiceCallDisabledReason ?? _t("voip|voice_call")}
|
||||||
</IconButton>
|
onClick={(ev) => voiceCallClick(ev, callOptions[0])}
|
||||||
</Tooltip>
|
>
|
||||||
);
|
<VoiceCallIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const closeLobbyButton = (
|
const closeLobbyButton = (
|
||||||
<Tooltip label={_t("voip|close_lobby")}>
|
<Tooltip label={_t("voip|close_lobby")}>
|
||||||
<IconButton onClick={toggleCall} aria-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 { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
|
||||||
import { useRoomState } from "../useRoomState";
|
import { useRoomState } from "../useRoomState";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import { isManagedHybridWidget } from "../../widgets/ManagedHybrid";
|
import { isManagedHybridWidget, isManagedHybridWidgetEnabled } from "../../widgets/ManagedHybrid";
|
||||||
import { IApp } from "../../stores/WidgetStore";
|
import { IApp } from "../../stores/WidgetStore";
|
||||||
import { SdkContextClass } from "../../contexts/SDKContext";
|
import { SdkContextClass } from "../../contexts/SDKContext";
|
||||||
import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
||||||
|
@ -83,6 +83,7 @@ export const useRoomCall = (
|
||||||
isConnectedToCall: boolean;
|
isConnectedToCall: boolean;
|
||||||
hasActiveCallSession: boolean;
|
hasActiveCallSession: boolean;
|
||||||
callOptions: PlatformCallType[];
|
callOptions: PlatformCallType[];
|
||||||
|
showVoiceCallButton: boolean;
|
||||||
} => {
|
} => {
|
||||||
// settings
|
// settings
|
||||||
const groupCallsEnabled = useFeatureEnabled("feature_group_calls");
|
const groupCallsEnabled = useFeatureEnabled("feature_group_calls");
|
||||||
|
@ -124,7 +125,7 @@ export const useRoomCall = (
|
||||||
// The options provided to the RoomHeader.
|
// The options provided to the RoomHeader.
|
||||||
// If there are multiple options, the user will be prompted to choose.
|
// If there are multiple options, the user will be prompted to choose.
|
||||||
const callOptions = useMemo((): PlatformCallType[] => {
|
const callOptions = useMemo((): PlatformCallType[] => {
|
||||||
const options = [];
|
const options: PlatformCallType[] = [];
|
||||||
if (memberCount <= 2) {
|
if (memberCount <= 2) {
|
||||||
options.push(PlatformCallType.LegacyCall);
|
options.push(PlatformCallType.LegacyCall);
|
||||||
} else if (mayEditWidgets || hasJitsiWidget) {
|
} else if (mayEditWidgets || hasJitsiWidget) {
|
||||||
|
@ -266,6 +267,10 @@ export const useRoomCall = (
|
||||||
});
|
});
|
||||||
}, [isViewingCall, room.roomId]);
|
}, [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
|
* We've gone through all the steps
|
||||||
*/
|
*/
|
||||||
|
@ -279,5 +284,6 @@ export const useRoomCall = (
|
||||||
isConnectedToCall: isConnectedToCall,
|
isConnectedToCall: isConnectedToCall,
|
||||||
hasActiveCallSession: hasActiveCallSession,
|
hasActiveCallSession: hasActiveCallSession,
|
||||||
callOptions,
|
callOptions,
|
||||||
|
showVoiceCallButton: !hideVoiceCallButton,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,7 @@ import {
|
||||||
getByRole,
|
getByRole,
|
||||||
getByText,
|
getByText,
|
||||||
queryAllByLabelText,
|
queryAllByLabelText,
|
||||||
|
queryByLabelText,
|
||||||
render,
|
render,
|
||||||
RenderOptions,
|
RenderOptions,
|
||||||
screen,
|
screen,
|
||||||
|
@ -232,6 +233,28 @@ describe("RoomHeader", () => {
|
||||||
expect(setCardSpy).toHaveBeenCalledWith({ phase: RightPanelPhases.NotificationPanel });
|
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", () => {
|
describe("groups call disabled", () => {
|
||||||
it("you can't call if you're alone", () => {
|
it("you can't call if you're alone", () => {
|
||||||
mockRoomMembers(room, 1);
|
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);
|
mockRoomMembers(room, 10);
|
||||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
|
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
|
||||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
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");
|
expect(getByLabelText(container, "Video call")).not.toHaveAttribute("aria-disabled", "true");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -283,9 +305,6 @@ describe("RoomHeader", () => {
|
||||||
mockRoomMembers(room, 10);
|
mockRoomMembers(room, 10);
|
||||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(false);
|
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(false);
|
||||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
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(
|
expect(
|
||||||
getByLabelText(container, "You do not have permission to start video calls", { selector: "button" }),
|
getByLabelText(container, "You do not have permission to start video calls", { selector: "button" }),
|
||||||
).toHaveAttribute("aria-disabled", "true");
|
).toHaveAttribute("aria-disabled", "true");
|
||||||
|
@ -456,15 +475,10 @@ describe("RoomHeader", () => {
|
||||||
|
|
||||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||||
|
|
||||||
const voiceButton = getByLabelText(container, "Voice call");
|
|
||||||
const videoButton = getByLabelText(container, "Video call");
|
const videoButton = getByLabelText(container, "Video call");
|
||||||
expect(voiceButton).not.toHaveAttribute("aria-disabled", "true");
|
|
||||||
expect(videoButton).not.toHaveAttribute("aria-disabled", "true");
|
expect(videoButton).not.toHaveAttribute("aria-disabled", "true");
|
||||||
|
|
||||||
const placeCallSpy = jest.spyOn(LegacyCallHandler.instance, "placeCall");
|
const placeCallSpy = jest.spyOn(LegacyCallHandler.instance, "placeCall");
|
||||||
fireEvent.click(voiceButton);
|
|
||||||
expect(placeCallSpy).toHaveBeenLastCalledWith(room.roomId, CallType.Voice);
|
|
||||||
|
|
||||||
fireEvent.click(videoButton);
|
fireEvent.click(videoButton);
|
||||||
expect(placeCallSpy).toHaveBeenLastCalledWith(room.roomId, CallType.Video);
|
expect(placeCallSpy).toHaveBeenLastCalledWith(room.roomId, CallType.Video);
|
||||||
});
|
});
|
||||||
|
@ -479,9 +493,7 @@ describe("RoomHeader", () => {
|
||||||
|
|
||||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||||
|
|
||||||
const voiceButton = getByLabelText(container, "Voice call");
|
|
||||||
const videoButton = getByLabelText(container, "Video call");
|
const videoButton = getByLabelText(container, "Video call");
|
||||||
expect(voiceButton).not.toHaveAttribute("aria-disabled", "true");
|
|
||||||
expect(videoButton).not.toHaveAttribute("aria-disabled", "true");
|
expect(videoButton).not.toHaveAttribute("aria-disabled", "true");
|
||||||
|
|
||||||
const dispatcherSpy = jest.spyOn(dispatcher, "dispatch");
|
const dispatcherSpy = jest.spyOn(dispatcher, "dispatch");
|
||||||
|
@ -497,9 +509,8 @@ describe("RoomHeader", () => {
|
||||||
);
|
);
|
||||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
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");
|
expect(videoButton).toHaveAttribute("aria-disabled", "true");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue