Support using Element Call for voice calls in DMs (#30817)
* Add voiceOnly options. * tweaks * Nearly working demo * Lots of minor fixes * Better working version * remove unused payload * bits and pieces * Cleanup based on new hints * Simple refactor for skipLobby (and remove returnToLobby) * Tidyup * Remove unused tests * Update tests for voice calls * Add video room support. * Add a test for video rooms * tidy * remove console log line * lint and tests * Bunch of fixes * Fixes * Use correct title * make linter happier * Update tests * cleanup * Drop only * update snaps * Document * lint * Update snapshots * Remove duplicate test * add brackets * fix jest
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
import React from "react";
|
||||
import { render, screen } from "jest-matrix-react";
|
||||
import { CallType } from "matrix-js-sdk/src/webrtc/call";
|
||||
|
||||
import { RoomNotificationState } from "../../../../../src/stores/notifications/RoomNotificationState";
|
||||
import { NotificationDecoration } from "../../../../../src/components/views/rooms/NotificationDecoration";
|
||||
@@ -22,7 +23,7 @@ describe("<NotificationDecoration />", () => {
|
||||
|
||||
it("should not render if RoomNotificationState.hasAnyNotificationOrActivity=true", () => {
|
||||
jest.spyOn(roomNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(false);
|
||||
render(<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />);
|
||||
render(<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />);
|
||||
expect(screen.queryByTestId("notification-decoration")).toBeNull();
|
||||
});
|
||||
|
||||
@@ -30,7 +31,7 @@ describe("<NotificationDecoration />", () => {
|
||||
jest.spyOn(roomNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(true);
|
||||
jest.spyOn(roomNotificationState, "isUnsentMessage", "get").mockReturnValue(true);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
@@ -39,7 +40,7 @@ describe("<NotificationDecoration />", () => {
|
||||
jest.spyOn(roomNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(true);
|
||||
jest.spyOn(roomNotificationState, "invited", "get").mockReturnValue(true);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
@@ -49,7 +50,7 @@ describe("<NotificationDecoration />", () => {
|
||||
jest.spyOn(roomNotificationState, "isMention", "get").mockReturnValue(true);
|
||||
jest.spyOn(roomNotificationState, "count", "get").mockReturnValue(1);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
@@ -59,7 +60,7 @@ describe("<NotificationDecoration />", () => {
|
||||
jest.spyOn(roomNotificationState, "isNotification", "get").mockReturnValue(true);
|
||||
jest.spyOn(roomNotificationState, "count", "get").mockReturnValue(1);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
@@ -69,7 +70,7 @@ describe("<NotificationDecoration />", () => {
|
||||
jest.spyOn(roomNotificationState, "isNotification", "get").mockReturnValue(true);
|
||||
jest.spyOn(roomNotificationState, "count", "get").mockReturnValue(0);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
@@ -78,7 +79,7 @@ describe("<NotificationDecoration />", () => {
|
||||
jest.spyOn(roomNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(true);
|
||||
jest.spyOn(roomNotificationState, "isActivityNotification", "get").mockReturnValue(true);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
@@ -87,14 +88,21 @@ describe("<NotificationDecoration />", () => {
|
||||
jest.spyOn(roomNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(true);
|
||||
jest.spyOn(roomNotificationState, "muted", "get").mockReturnValue(true);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={false} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
it("should render the video decoration", () => {
|
||||
it("should render the video call decoration", () => {
|
||||
jest.spyOn(roomNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(false);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} hasVideoCall={true} />,
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={CallType.Video} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
it("should render the audio call decoration", () => {
|
||||
jest.spyOn(roomNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(false);
|
||||
const { asFragment } = render(
|
||||
<NotificationDecoration notificationState={roomNotificationState} callType={CallType.Voice} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@ import { type MatrixClient, type Room } from "matrix-js-sdk/src/matrix";
|
||||
import { render, screen, waitFor } from "jest-matrix-react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { mocked } from "jest-mock";
|
||||
import { CallType } from "matrix-js-sdk/src/webrtc/call";
|
||||
|
||||
import { mkRoom, stubClient, withClientContextRenderOptions } from "../../../../../test-utils";
|
||||
import { RoomListItemView } from "../../../../../../src/components/views/rooms/RoomListPanel/RoomListItemView";
|
||||
@@ -64,6 +65,7 @@ describe("<RoomListItemView />", () => {
|
||||
isBold: false,
|
||||
isVideoRoom: false,
|
||||
callConnectionState: null,
|
||||
callType: CallType.Video,
|
||||
hasParticipantInCall: false,
|
||||
name: room.name,
|
||||
showNotificationDecoration: false,
|
||||
|
||||
@@ -103,6 +103,17 @@ exports[`<RoomListItemView /> should display notification decoration 1`] = `
|
||||
data-testid="notification-decoration"
|
||||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: center; --mx-flex-gap: var(--cpd-space-1x); --mx-flex-wrap: nowrap;"
|
||||
>
|
||||
<svg
|
||||
fill="var(--cpd-color-icon-accent-primary)"
|
||||
height="20px"
|
||||
viewBox="0 0 24 24"
|
||||
width="20px"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6 4h10a2 2 0 0 1 2 2v4.286l3.35-2.871a1 1 0 0 1 1.65.76v7.65a1 1 0 0 1-1.65.76L18 13.715V18a2 2 0 0 1-2 2H6a4 4 0 0 1-4-4V8a4 4 0 0 1 4-4"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="_unread-counter_9mg0k_8"
|
||||
>
|
||||
|
||||
@@ -16,6 +16,28 @@ exports[`<NotificationDecoration /> should render the activity decoration 1`] =
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<NotificationDecoration /> should render the audio call decoration 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="_flex_4dswl_9"
|
||||
data-testid="notification-decoration"
|
||||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: center; --mx-flex-gap: var(--cpd-space-1x); --mx-flex-wrap: nowrap;"
|
||||
>
|
||||
<svg
|
||||
fill="var(--cpd-color-icon-accent-primary)"
|
||||
height="20px"
|
||||
viewBox="0 0 24 24"
|
||||
width="20px"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="m20.958 16.374.039 3.527q0 .427-.33.756-.33.33-.756.33a16 16 0 0 1-6.57-1.105 16.2 16.2 0 0 1-5.563-3.663 16.1 16.1 0 0 1-3.653-5.573 16.3 16.3 0 0 1-1.115-6.56q0-.427.33-.757T4.095 3l3.528.039a1.07 1.07 0 0 1 1.085.93l.543 3.954q.039.271-.039.504a1.1 1.1 0 0 1-.271.426l-1.64 1.64q.505 1.008 1.154 1.909c.433.6 1.444 1.696 1.444 1.696s1.095 1.01 1.696 1.444q.9.65 1.909 1.153l1.64-1.64q.193-.193.426-.27t.504-.04l3.954.543q.406.059.668.359t.262.727"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<NotificationDecoration /> should render the invitation decoration 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
@@ -142,7 +164,7 @@ exports[`<NotificationDecoration /> should render the unset message decoration 1
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<NotificationDecoration /> should render the video decoration 1`] = `
|
||||
exports[`<NotificationDecoration /> should render the video call decoration 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="_flex_4dswl_9"
|
||||
|
||||
@@ -32,6 +32,7 @@ import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
|
||||
import { CallView as _CallView } from "../../../../../src/components/views/voip/CallView";
|
||||
import { WidgetMessagingStore } from "../../../../../src/stores/widgets/WidgetMessagingStore";
|
||||
import { CallStore } from "../../../../../src/stores/CallStore";
|
||||
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
|
||||
|
||||
const CallView = wrapInMatrixClientContext(_CallView);
|
||||
|
||||
@@ -50,6 +51,7 @@ describe("CallView", () => {
|
||||
|
||||
stubClient();
|
||||
client = mocked(MatrixClientPeg.safeGet());
|
||||
DMRoomMap.makeShared(client);
|
||||
|
||||
room = new Room("!1:example.org", client, "@alice:example.org", {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
|
||||
Reference in New Issue
Block a user