diff --git a/linked-dependencies/matrix-react-sdk/src/components/views/voip/LegacyCallView.tsx b/linked-dependencies/matrix-react-sdk/src/components/views/voip/LegacyCallView.tsx index 06beb329ef..e9ce19e746 100644 --- a/linked-dependencies/matrix-react-sdk/src/components/views/voip/LegacyCallView.tsx +++ b/linked-dependencies/matrix-react-sdk/src/components/views/voip/LegacyCallView.tsx @@ -36,6 +36,7 @@ import LegacyCallViewButtons from "./LegacyCallView/LegacyCallViewButtons"; import { ActionPayload } from "../../../dispatcher/payloads"; import { getKeyBindingsManager } from "../../../KeyBindingsManager"; import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts"; +import TchapUIFeature from "../../../../../../src/tchap/util/TchapUIFeature"; /** :TCHAP: hide-video-button-on-call-screen */ interface IProps { // The call for us to display @@ -348,7 +349,13 @@ export default class LegacyCallView extends React.Component { const { callState, micMuted, vidMuted, screensharing, sidebarShown, secondaryFeed, sidebarFeeds } = this.state; // If SDPStreamMetadata isn't supported don't show video mute button in voice calls - const vidMuteButtonShown = call.opponentSupportsSDPStreamMetadata() || call.hasLocalUserMediaVideoTrack; + /** :TCHAP: hide-video-button-on-call-screen */ + // const vidMuteButtonShown = call.opponentSupportsSDPStreamMetadata() || call.hasLocalUserMediaVideoTrack; + let vidMuteButtonShown = false // hide by default + if (TchapUIFeature.isFeatureActiveForHomeserver("feature_video_call")) { + vidMuteButtonShown = call.opponentSupportsSDPStreamMetadata() || call.hasLocalUserMediaVideoTrack; + }; + /** end :TCHAP: */ // Screensharing is possible, if we can send a second stream and // identify it using SDPStreamMetadata or if we can replace the already // existing usermedia track by a screensharing track. We also need to be diff --git a/patches/subtree-modifications.json b/patches/subtree-modifications.json index ace678f869..69d052fee4 100644 --- a/patches/subtree-modifications.json +++ b/patches/subtree-modifications.json @@ -5,5 +5,11 @@ "src/hooks/useUserOnboardingContext.ts", "src/hooks/useUserOnboardingTasks.ts" ] + }, + "hide-video-button-on-call-screen": { + "issue": "https://github.com/tchapgouv/tchap-web-v4/issues/952", + "files": [ + "src/components/views/voip/LegacyCallView.tsx" + ] } } \ No newline at end of file diff --git a/test/unit-tests/tchap/components/views/voip/LegacyCallView-test.tsx b/test/unit-tests/tchap/components/views/voip/LegacyCallView-test.tsx new file mode 100644 index 0000000000..65135cfce1 --- /dev/null +++ b/test/unit-tests/tchap/components/views/voip/LegacyCallView-test.tsx @@ -0,0 +1,142 @@ +import { stubClient } from "matrix-react-sdk/test/test-utils"; +import SdkConfig, { ConfigOptions } from "matrix-react-sdk/src/SdkConfig"; +import { MatrixClientPeg } from "matrix-react-sdk/src/MatrixClientPeg"; +import React from "react"; +import { MatrixCall } from "matrix-js-sdk/src/webrtc/call"; +import { CallState } from "matrix-js-sdk/src/webrtc/call"; +import { fireEvent, render, waitFor } from "@testing-library/react"; +import { MatrixClient } from "matrix-js-sdk/src/matrix"; + +import LegacyCallView from "~matrix-react-sdk/src/components/views/voip/LegacyCallView"; +import DMRoomMap from "~matrix-react-sdk/src/utils/DMRoomMap"; + +describe("LegacyCallView", () => { + const featureName: string = "feature_video_call"; + const homeserverName: string = "my.home.server"; + const roomId: string = "roomId"; + // const fakeCall: MatrixCall = new FakeCall(roomId) as unknown as MatrixCall; + let fakeCall: MatrixCall; + + beforeAll(() => { + SdkConfig.reset(); // in case other tests didn't clean up + }); + + beforeEach(() => { + stubClient(); + MatrixClientPeg.getHomeserverName = () => homeserverName; + + const mockClient: MatrixClient = MatrixClientPeg.safeGet(); + mockClient.isFallbackICEServerAllowed = jest.fn(); + + const dmRoomMap = new DMRoomMap(mockClient); + + jest.spyOn(dmRoomMap, "getUserIdForRoomId"); + jest.spyOn(DMRoomMap, "shared").mockReturnValue(dmRoomMap); + + fakeCall = new MatrixCall({ + client: mockClient, + roomId, + }); + + jest.spyOn(fakeCall, "state", "get").mockReturnValue(CallState.Connected); + jest.spyOn(fakeCall, "isLocalOnHold").mockReturnValue(false); + jest.spyOn(fakeCall, "isRemoteOnHold").mockReturnValue(false); + jest.spyOn(fakeCall, "isMicrophoneMuted").mockReturnValue(false); + jest.spyOn(fakeCall, "isLocalVideoMuted").mockReturnValue(true); + jest.spyOn(fakeCall, "isScreensharing").mockReturnValue(false); + jest.spyOn(fakeCall, "isScreensharing").mockReturnValue(false); + }); + + afterEach(function () { + SdkConfig.reset(); // we touch the config, so clean up + jest.clearAllMocks(); + }); + + const mockFeatureConfig = (homeservers: string[]) => { + // mock SdkConfig.get("tchap_features") + const config: ConfigOptions = { tchap_features: {} }; + config.tchap_features[featureName] = homeservers; + SdkConfig.put(config); + }; + + const renderCallView = () => { + return render( + null} + call={fakeCall} + secondaryCall={fakeCall} + pipMode={false} + onResize={() => null} + />, + ); + }; + + it("returns true when the the homeserver include video_call feature", () => { + jest.spyOn(fakeCall, "opponentSupportsSDPStreamMetadata").mockReturnValue(true); + + mockFeatureConfig([homeserverName]); + const { container } = renderCallView(); + + // needs to hover on the component to make the control button appears + fireEvent.mouseEnter(container); + waitFor(() => container.getElementsByClassName("mx_LegacyCallViewButtons").length); + + expect(container.getElementsByClassName("mx_LegacyCallViewButtons_button_vid").length).toBe(1); + }); + + it("returns false when the the homeserver doesnt include video_call feature", async () => { + jest.spyOn(fakeCall, "opponentSupportsSDPStreamMetadata").mockReturnValue(true); + + mockFeatureConfig(["other.homeserver"]); + const { container } = renderCallView(); + + // needs to hover on the component to make the control button appears + fireEvent.mouseEnter(container); + waitFor(() => container.getElementsByClassName("mx_LegacyCallViewButtons").length); + + expect(container.getElementsByClassName("mx_LegacyCallViewButtons_button_vid").length).toBe(0); + }); + + it("returns false when the call doesnt support opponentSupportsSDPStreamMetadata or hasLocalUserMediaVideoTrack", async () => { + jest.spyOn(fakeCall, "opponentSupportsSDPStreamMetadata").mockReturnValue(false); + jest.spyOn(fakeCall, "hasLocalUserMediaVideoTrack", "get").mockReturnValue(false); + + mockFeatureConfig([homeserverName]); + const { container } = renderCallView(); + + // needs to hover on the component to make the control button appears + fireEvent.mouseEnter(container); + waitFor(() => container.getElementsByClassName("mx_LegacyCallViewButtons").length); + + expect(container.getElementsByClassName("mx_LegacyCallViewButtons_button_vid").length).toBe(0); + }); + + it("returns true when the call support opponentSupportsSDPStreamMetadata", async () => { + jest.spyOn(fakeCall, "opponentSupportsSDPStreamMetadata").mockReturnValue(true); + jest.spyOn(fakeCall, "hasLocalUserMediaVideoTrack", "get").mockReturnValue(false); + + mockFeatureConfig([homeserverName]); + const { container } = renderCallView(); + + // needs to hover on the component to make the control button appears + fireEvent.mouseEnter(container); + waitFor(() => container.getElementsByClassName("mx_LegacyCallViewButtons").length); + + expect(container.getElementsByClassName("mx_LegacyCallViewButtons_button_vid").length).toBe(1); + }); + + it("returns true when the call support hasLocalUserMediaVideoTrack", async () => { + jest.spyOn(fakeCall, "opponentSupportsSDPStreamMetadata").mockReturnValue(false); + jest.spyOn(fakeCall, "hasLocalUserMediaVideoTrack", "get").mockReturnValue(true); + + mockFeatureConfig([homeserverName]); + const { container } = renderCallView(); + + // needs to hover on the component to make the control button appears + fireEvent.mouseEnter(container); + waitFor(() => container.getElementsByClassName("mx_LegacyCallViewButtons").length); + + expect(container.getElementsByClassName("mx_LegacyCallViewButtons_button_vid").length).toBe(1); + }); +});