Compare commits
2 Commits
actions/pl
...
staging
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55c4b2fac0 | ||
|
|
84479a86f3 |
2
.github/workflows/docker.yaml
vendored
2
.github/workflows/docker.yaml
vendored
@@ -132,7 +132,7 @@ jobs:
|
||||
cosign sign --yes ${images}
|
||||
|
||||
- name: Update repo description
|
||||
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4
|
||||
uses: peter-evans/dockerhub-description@0505d8b04853a30189aee66f5bb7fd1511bbac71 # v4
|
||||
if: github.event_name != 'pull_request'
|
||||
continue-on-error: true
|
||||
with:
|
||||
|
||||
6
.github/workflows/release_prepare.yml
vendored
6
.github/workflows/release_prepare.yml
vendored
@@ -100,7 +100,7 @@ jobs:
|
||||
repo: matrix-org/matrix-js-sdk
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "draft / draft"
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-web draft
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
repo: element-hq/element-web
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "draft / draft"
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-desktop draft
|
||||
@@ -122,5 +122,5 @@ jobs:
|
||||
repo: element-hq/element-desktop
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "draft / draft"
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -104,7 +104,7 @@ jobs:
|
||||
|
||||
- name: Skip SonarCloud in merge queue
|
||||
if: github.event_name == 'merge_group' || inputs.disable_coverage == 'true'
|
||||
uses: guibranco/github-status-action-v2@5f2b01ce1394109f70954ae6b69ef41cf7928e63
|
||||
uses: guibranco/github-status-action-v2@9b1d102b3c32583174557f58c53e3b09d43d1b1d
|
||||
with:
|
||||
authToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
state: success
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# syntax=docker.io/docker/dockerfile:1.15-labs
|
||||
# syntax=docker.io/docker/dockerfile:1.14-labs
|
||||
|
||||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye AS builder
|
||||
|
||||
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "element-web",
|
||||
"version": "1.11.97",
|
||||
"version": "1.11.98-rc.0",
|
||||
"description": "Element: the future of secure communication",
|
||||
"author": "New Vector Ltd.",
|
||||
"repository": {
|
||||
@@ -75,7 +75,7 @@
|
||||
"oidc-client-ts": "3.2.0",
|
||||
"jwt-decode": "4.0.0",
|
||||
"caniuse-lite": "1.0.30001707",
|
||||
"testcontainers": "10.24.2",
|
||||
"testcontainers": "10.23.0",
|
||||
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
|
||||
"wrap-ansi": "npm:wrap-ansi@^7.0.0"
|
||||
},
|
||||
@@ -130,7 +130,7 @@
|
||||
"maplibre-gl": "^5.0.0",
|
||||
"matrix-encrypt-attachment": "^1.0.3",
|
||||
"matrix-events-sdk": "0.0.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-js-sdk": "37.4.0-rc.0",
|
||||
"matrix-widget-api": "^1.10.0",
|
||||
"memoize-one": "^6.0.0",
|
||||
"mime": "^4.0.4",
|
||||
@@ -186,7 +186,7 @@
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
|
||||
"@sentry/webpack-plugin": "^3.0.0",
|
||||
"@stylistic/eslint-plugin": "^4.0.0",
|
||||
"@stylistic/eslint-plugin": "^3.0.0",
|
||||
"@svgr/webpack": "^8.0.0",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.4.8",
|
||||
@@ -246,7 +246,7 @@
|
||||
"eslint-plugin-react-compiler": "^19.0.0-beta-df7b47d-20241124",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
"eslint-plugin-unicorn": "^56.0.0",
|
||||
"express": "^5.0.0",
|
||||
"express": "^4.18.2",
|
||||
"fake-indexeddb": "^6.0.0",
|
||||
"fetch-mock": "9.11.0",
|
||||
"fetch-mock-jest": "^1.5.1",
|
||||
@@ -292,7 +292,7 @@
|
||||
"terser-webpack-plugin": "^5.3.9",
|
||||
"testcontainers": "^10.20.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "5.8.3",
|
||||
"typescript": "5.8.2",
|
||||
"util": "^0.12.5",
|
||||
"web-streams-polyfill": "^4.0.0",
|
||||
"webpack": "^5.89.0",
|
||||
|
||||
@@ -19,14 +19,7 @@ test.describe("Invites", () => {
|
||||
const roomId = await bot.createRoom({ is_direct: true });
|
||||
await bot.inviteUser(roomId, user.userId);
|
||||
await app.viewRoomByName("Bob");
|
||||
await expect(page.locator(".mx_RoomView")).toMatchScreenshot("Invites_room_view.png", {
|
||||
// Hide the mxid, which is not stable.
|
||||
css: `
|
||||
.mx_RoomPreviewBar_inviter_mxid {
|
||||
display: none !important;
|
||||
}
|
||||
`,
|
||||
});
|
||||
await expect(page.locator(".mx_RoomView")).toMatchScreenshot("Invites_room_view.png");
|
||||
});
|
||||
|
||||
test("should be able to decline an invite", async ({ page, homeserver, user, bot, app }) => {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 18 KiB |
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { SynapseContainer as BaseSynapseContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers";
|
||||
|
||||
const TAG = "develop@sha256:be7883f4021e24d71bdb8fe744ae6758a5fd15b5491dad97236b29283e3e6705";
|
||||
const TAG = "develop@sha256:66955f34a593cfc3b6e77b8d5510c60c6094f5bade8a17d2feaefbb8662ccf09";
|
||||
|
||||
/**
|
||||
* SynapseContainer which freezes the docker digest to stabilise tests,
|
||||
|
||||
@@ -5,11 +5,32 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { EventType, JoinRule, type MatrixEvent, type Room, RoomEvent } from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
EventType,
|
||||
JoinRule,
|
||||
type MatrixEvent,
|
||||
type Room,
|
||||
RoomEvent,
|
||||
type User,
|
||||
UserEvent,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { useTypedEventEmitter } from "../../../hooks/useEventEmitter";
|
||||
import { useDmMember, usePresence, type Presence } from "../../views/avatars/WithPresenceIndicator";
|
||||
import DMRoomMap from "../../../utils/DMRoomMap";
|
||||
import { getJoinedNonFunctionalMembers } from "../../../utils/room/getJoinedNonFunctionalMembers";
|
||||
import { BUSY_PRESENCE_NAME } from "../../views/rooms/PresenceLabel";
|
||||
import { isPresenceEnabled } from "../../../utils/presence";
|
||||
|
||||
/**
|
||||
* The presence of a user in a DM room.
|
||||
* - "online": The user is online.
|
||||
* - "offline": The user is offline.
|
||||
* - "busy": The user is busy.
|
||||
* - "unavailable": the presence is unavailable.
|
||||
* - null: the user is not in a DM room or presence is not enabled.
|
||||
*/
|
||||
export type Presence = "online" | "offline" | "busy" | "unavailable" | null;
|
||||
|
||||
export interface RoomAvatarViewState {
|
||||
/**
|
||||
@@ -29,7 +50,7 @@ export interface RoomAvatarViewState {
|
||||
* The presence of the user in the DM room.
|
||||
* If null, the user is not in a DM room or presence is not enabled.
|
||||
*/
|
||||
presence: Presence | null;
|
||||
presence: Presence;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,8 +59,7 @@ export interface RoomAvatarViewState {
|
||||
*/
|
||||
export function useRoomAvatarViewModel(room: Room): RoomAvatarViewState {
|
||||
const isVideoRoom = room.isElementVideoRoom() || room.isCallRoom();
|
||||
const roomMember = useDmMember(room);
|
||||
const presence = usePresence(room, roomMember);
|
||||
const presence = useDMPresence(room);
|
||||
const isPublic = useIsPublic(room);
|
||||
|
||||
const hasDecoration = isPublic || isVideoRoom || presence !== null;
|
||||
@@ -77,3 +97,48 @@ function useIsPublic(room: Room): boolean {
|
||||
function isRoomPublic(room: Room): boolean {
|
||||
return room.getJoinRule() === JoinRule.Public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook listening to the presence of the DM user.
|
||||
* @param room
|
||||
*/
|
||||
function useDMPresence(room: Room): Presence {
|
||||
const dmUser = getDMUser(room);
|
||||
const [presence, setPresence] = useState<Presence>(getPresence(dmUser));
|
||||
useTypedEventEmitter(dmUser, UserEvent.Presence, () => setPresence(getPresence(dmUser)));
|
||||
useTypedEventEmitter(dmUser, UserEvent.CurrentlyActive, () => setPresence(getPresence(dmUser)));
|
||||
|
||||
return presence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DM user of the room.
|
||||
* Return undefined if the room is not a DM room, if we can't find the user or if the presence is not enabled.
|
||||
* @param room
|
||||
* @returns found user
|
||||
*/
|
||||
function getDMUser(room: Room): User | undefined {
|
||||
const otherUserId = DMRoomMap.shared().getUserIdForRoomId(room.roomId);
|
||||
if (!otherUserId) return;
|
||||
if (getJoinedNonFunctionalMembers(room).length !== 2) return;
|
||||
if (!isPresenceEnabled(room.client)) return;
|
||||
|
||||
return room.client.getUser(otherUserId) || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the presence of the DM user.
|
||||
* @param dmUser
|
||||
*/
|
||||
function getPresence(dmUser: User | undefined): Presence {
|
||||
if (!dmUser) return null;
|
||||
if (BUSY_PRESENCE_NAME.matches(dmUser.presence)) return "busy";
|
||||
|
||||
const isOnline = dmUser.currentlyActive || dmUser.presence === "online";
|
||||
if (isOnline) return "online";
|
||||
|
||||
if (dmUser.presence === "offline") return "offline";
|
||||
if (dmUser.presence === "unavailable") return "unavailable";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@ import BusyIcon from "@vector-im/compound-design-tokens/assets/web/icons/presenc
|
||||
import classNames from "classnames";
|
||||
|
||||
import RoomAvatar from "./RoomAvatar";
|
||||
import { useRoomAvatarViewModel } from "../../viewmodels/avatars/RoomAvatarViewModel";
|
||||
import { useRoomAvatarViewModel, type Presence } from "../../viewmodels/avatars/RoomAvatarViewModel";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { Presence } from "./WithPresenceIndicator";
|
||||
|
||||
interface RoomAvatarViewProps {
|
||||
/**
|
||||
@@ -84,7 +83,7 @@ type PresenceDecorationProps = {
|
||||
*/
|
||||
function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element {
|
||||
switch (presence) {
|
||||
case Presence.Online:
|
||||
case "online":
|
||||
return (
|
||||
<OnlineOrUnavailableIcon
|
||||
width="8px"
|
||||
@@ -94,7 +93,7 @@ function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element
|
||||
aria-label={_t("presence|online")}
|
||||
/>
|
||||
);
|
||||
case Presence.Away:
|
||||
case "unavailable":
|
||||
return (
|
||||
<OnlineOrUnavailableIcon
|
||||
width="8px"
|
||||
@@ -104,7 +103,7 @@ function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element
|
||||
aria-label={_t("presence|away")}
|
||||
/>
|
||||
);
|
||||
case Presence.Offline:
|
||||
case "offline":
|
||||
return (
|
||||
<OfflineIcon
|
||||
width="8px"
|
||||
@@ -114,7 +113,7 @@ function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element
|
||||
aria-label={_t("presence|offline")}
|
||||
/>
|
||||
);
|
||||
case Presence.Busy:
|
||||
case "busy":
|
||||
return (
|
||||
<BusyIcon
|
||||
width="8px"
|
||||
|
||||
@@ -26,7 +26,7 @@ interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export enum Presence {
|
||||
enum Presence {
|
||||
// Note: the names here are used in CSS class names
|
||||
Online = "ONLINE",
|
||||
Away = "AWAY",
|
||||
@@ -86,7 +86,7 @@ function getPresence(member: RoomMember | null): Presence | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export const usePresence = (room: Room, member: RoomMember | null): Presence | null => {
|
||||
const usePresence = (room: Room, member: RoomMember | null): Presence | null => {
|
||||
const [presence, setPresence] = useState<Presence | null>(getPresence(member));
|
||||
const updatePresence = (): void => {
|
||||
setPresence(getPresence(member));
|
||||
|
||||
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { useState, useCallback, useMemo, useEffect } from "react";
|
||||
import { useState, useCallback, useMemo } from "react";
|
||||
|
||||
import type { RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
import { type Call, ConnectionState, CallEvent } from "../models/Call";
|
||||
@@ -20,12 +20,6 @@ export const useCall = (roomId: string): Call | null => {
|
||||
useEventEmitter(CallStore.instance, CallStoreEvent.Call, (call: Call | null, forRoomId: string) => {
|
||||
if (forRoomId === roomId) setCall(call);
|
||||
});
|
||||
|
||||
// Reset the value when the roomId changes
|
||||
useEffect(() => {
|
||||
setCall(CallStore.instance.getCall(roomId));
|
||||
}, [roomId]);
|
||||
|
||||
return call;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,18 +5,32 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { renderHook, waitFor } from "jest-matrix-react";
|
||||
import { JoinRule, type MatrixClient, type Room, RoomMember, User } from "matrix-js-sdk/src/matrix";
|
||||
import { renderHook, waitFor, act } from "jest-matrix-react";
|
||||
import {
|
||||
JoinRule,
|
||||
type MatrixClient,
|
||||
MatrixEvent,
|
||||
type Room,
|
||||
type RoomMember,
|
||||
User,
|
||||
UserEvent,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
import { useRoomAvatarViewModel } from "../../../../../src/components/viewmodels/avatars/RoomAvatarViewModel";
|
||||
import { createTestClient, mkStubRoom } from "../../../../test-utils";
|
||||
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
|
||||
import * as PresenceIndicatorModule from "../../../../../src/components/views/avatars/WithPresenceIndicator";
|
||||
import { getJoinedNonFunctionalMembers } from "../../../../../src/utils/room/getJoinedNonFunctionalMembers";
|
||||
import { isPresenceEnabled } from "../../../../../src/utils/presence";
|
||||
|
||||
jest.mock("../../../../../src/utils/room/getJoinedNonFunctionalMembers", () => ({
|
||||
getJoinedNonFunctionalMembers: jest.fn().mockReturnValue([]),
|
||||
}));
|
||||
|
||||
jest.mock("../../../../../src/utils/presence", () => ({
|
||||
isPresenceEnabled: jest.fn().mockReturnValue(false),
|
||||
}));
|
||||
|
||||
describe("RoomAvatarViewModel", () => {
|
||||
let matrixClient: MatrixClient;
|
||||
let room: Room;
|
||||
@@ -27,9 +41,6 @@ describe("RoomAvatarViewModel", () => {
|
||||
|
||||
DMRoomMap.makeShared(matrixClient);
|
||||
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
|
||||
|
||||
jest.spyOn(PresenceIndicatorModule, "useDmMember").mockReturnValue(null);
|
||||
jest.spyOn(PresenceIndicatorModule, "usePresence").mockReturnValue(null);
|
||||
});
|
||||
|
||||
it("should has hasDecoration to false", async () => {
|
||||
@@ -63,14 +74,62 @@ describe("RoomAvatarViewModel", () => {
|
||||
await waitFor(() => expect(vm.current.isPublic).toBe(true));
|
||||
});
|
||||
|
||||
it("should return presence", async () => {
|
||||
const user = User.createUser("userId", matrixClient);
|
||||
const roomMember = new RoomMember(room.roomId, "userId");
|
||||
roomMember.user = user;
|
||||
jest.spyOn(PresenceIndicatorModule, "useDmMember").mockReturnValue(roomMember);
|
||||
jest.spyOn(PresenceIndicatorModule, "usePresence").mockReturnValue(PresenceIndicatorModule.Presence.Online);
|
||||
describe("presence", () => {
|
||||
let user: User;
|
||||
|
||||
const { result: vm } = renderHook(() => useRoomAvatarViewModel(room));
|
||||
expect(vm.current.presence).toBe(PresenceIndicatorModule.Presence.Online);
|
||||
beforeEach(() => {
|
||||
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue("userId");
|
||||
mocked(getJoinedNonFunctionalMembers).mockReturnValue([{}, {}] as RoomMember[]);
|
||||
mocked(isPresenceEnabled).mockReturnValue(true);
|
||||
|
||||
user = User.createUser("userId", matrixClient);
|
||||
jest.spyOn(matrixClient, "getUser").mockReturnValue(user);
|
||||
});
|
||||
|
||||
it("should has presence set to null", () => {
|
||||
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
|
||||
|
||||
const { result: vm } = renderHook(() => useRoomAvatarViewModel(room));
|
||||
expect(vm.current.presence).toBe(null);
|
||||
});
|
||||
|
||||
it("should has online presence", async () => {
|
||||
const { result: vm } = renderHook(() => useRoomAvatarViewModel(room));
|
||||
expect(vm.current.presence).toBe("offline");
|
||||
|
||||
user.presence = "online";
|
||||
|
||||
await act(() => user.emit(UserEvent.Presence, new MatrixEvent(), user));
|
||||
await waitFor(() => expect(vm.current.presence).toBe("online"));
|
||||
|
||||
user.currentlyActive = true;
|
||||
user.presence = "offline";
|
||||
|
||||
await act(() => user.emit(UserEvent.CurrentlyActive, new MatrixEvent(), user));
|
||||
await waitFor(() => expect(vm.current.presence).toBe("online"));
|
||||
});
|
||||
|
||||
it("should has busy presence", async () => {
|
||||
user.presence = "busy";
|
||||
const { result: vm } = renderHook(() => useRoomAvatarViewModel(room));
|
||||
expect(vm.current.presence).toBe("busy");
|
||||
});
|
||||
|
||||
it("should has offline presence", async () => {
|
||||
user.presence = "offline";
|
||||
const { result: vm } = renderHook(() => useRoomAvatarViewModel(room));
|
||||
expect(vm.current.presence).toBe("offline");
|
||||
});
|
||||
|
||||
it("should has unavailable presence", async () => {
|
||||
user.presence = "unavailable";
|
||||
const { result: vm } = renderHook(() => useRoomAvatarViewModel(room));
|
||||
expect(vm.current.presence).toBe("unavailable");
|
||||
});
|
||||
|
||||
it("should has hasDecoration to true", async () => {
|
||||
const { result: vm } = renderHook(() => useRoomAvatarViewModel(room));
|
||||
expect(vm.current.hasDecoration).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,11 +12,11 @@ import { mocked } from "jest-mock";
|
||||
import { RoomAvatarView } from "../../../../../src/components/views/avatars/RoomAvatarView";
|
||||
import { mkStubRoom, stubClient } from "../../../../test-utils";
|
||||
import {
|
||||
type Presence,
|
||||
type RoomAvatarViewState,
|
||||
useRoomAvatarViewModel,
|
||||
} from "../../../../../src/components/viewmodels/avatars/RoomAvatarViewModel";
|
||||
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
|
||||
import { Presence } from "../../../../../src/components/views/avatars/WithPresenceIndicator";
|
||||
|
||||
jest.mock("../../../../../src/components/viewmodels/avatars/RoomAvatarViewModel", () => ({
|
||||
useRoomAvatarViewModel: jest.fn(),
|
||||
@@ -83,10 +83,10 @@ describe("<RoomAvatarView />", () => {
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ presence: Presence.Online, label: "Online" },
|
||||
{ presence: Presence.Offline, label: "Offline" },
|
||||
{ presence: Presence.Busy, label: "Busy" },
|
||||
{ presence: Presence.Away, label: "Away" },
|
||||
{ presence: "online" as Presence, label: "Online" },
|
||||
{ presence: "offline" as Presence, label: "Offline" },
|
||||
{ presence: "busy" as Presence, label: "Busy" },
|
||||
{ presence: "unavailable" as Presence, label: "Away" },
|
||||
])("should render the $presence presence", ({ presence, label }) => {
|
||||
mocked(useRoomAvatarViewModel).mockReturnValue({
|
||||
...defaultValue,
|
||||
|
||||
@@ -108,76 +108,7 @@ exports[`<RoomAvatarView /> should render a video room decoration 1`] = `
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<RoomAvatarView /> should render the AWAY presence 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_RoomAvatarView"
|
||||
>
|
||||
<span
|
||||
aria-label="Avatar"
|
||||
class="_avatar_1qbcf_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon mx_RoomAvatarView_RoomAvatar_presence"
|
||||
data-color="1"
|
||||
data-testid="avatar-img"
|
||||
data-type="round"
|
||||
style="--cpd-avatar-size: 32px;"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="_image_1qbcf_41"
|
||||
data-type="round"
|
||||
height="32px"
|
||||
loading="lazy"
|
||||
referrerpolicy="no-referrer"
|
||||
src="http://this.is.a.url/avatar.url/room.png"
|
||||
width="32px"
|
||||
/>
|
||||
</span>
|
||||
<svg
|
||||
aria-label="This room is a video room"
|
||||
class="mx_RoomAvatarView_icon"
|
||||
color="var(--cpd-color-icon-tertiary)"
|
||||
fill="currentColor"
|
||||
height="16px"
|
||||
viewBox="0 0 24 24"
|
||||
width="16px"
|
||||
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>
|
||||
<svg
|
||||
aria-label="Away"
|
||||
class="mx_RoomAvatarView_PresenceDecoration"
|
||||
color="var(--cpd-color-icon-quaternary)"
|
||||
fill="currentColor"
|
||||
height="8px"
|
||||
viewBox="0 0 8 8"
|
||||
width="8px"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
clip-path="url(#a)"
|
||||
>
|
||||
<path
|
||||
d="M8 4a4 4 0 1 1-8 0 4 4 0 0 1 8 0"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clippath
|
||||
id="a"
|
||||
>
|
||||
<path
|
||||
d="M0 0h8v8H0z"
|
||||
/>
|
||||
</clippath>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<RoomAvatarView /> should render the BUSY presence 1`] = `
|
||||
exports[`<RoomAvatarView /> should render the busy presence 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_RoomAvatarView"
|
||||
@@ -248,7 +179,7 @@ exports[`<RoomAvatarView /> should render the BUSY presence 1`] = `
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<RoomAvatarView /> should render the OFFLINE presence 1`] = `
|
||||
exports[`<RoomAvatarView /> should render the offline presence 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_RoomAvatarView"
|
||||
@@ -319,7 +250,7 @@ exports[`<RoomAvatarView /> should render the OFFLINE presence 1`] = `
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<RoomAvatarView /> should render the ONLINE presence 1`] = `
|
||||
exports[`<RoomAvatarView /> should render the online presence 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_RoomAvatarView"
|
||||
@@ -387,3 +318,72 @@ exports[`<RoomAvatarView /> should render the ONLINE presence 1`] = `
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<RoomAvatarView /> should render the unavailable presence 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_RoomAvatarView"
|
||||
>
|
||||
<span
|
||||
aria-label="Avatar"
|
||||
class="_avatar_1qbcf_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon mx_RoomAvatarView_RoomAvatar_presence"
|
||||
data-color="1"
|
||||
data-testid="avatar-img"
|
||||
data-type="round"
|
||||
style="--cpd-avatar-size: 32px;"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="_image_1qbcf_41"
|
||||
data-type="round"
|
||||
height="32px"
|
||||
loading="lazy"
|
||||
referrerpolicy="no-referrer"
|
||||
src="http://this.is.a.url/avatar.url/room.png"
|
||||
width="32px"
|
||||
/>
|
||||
</span>
|
||||
<svg
|
||||
aria-label="This room is a video room"
|
||||
class="mx_RoomAvatarView_icon"
|
||||
color="var(--cpd-color-icon-tertiary)"
|
||||
fill="currentColor"
|
||||
height="16px"
|
||||
viewBox="0 0 24 24"
|
||||
width="16px"
|
||||
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>
|
||||
<svg
|
||||
aria-label="Away"
|
||||
class="mx_RoomAvatarView_PresenceDecoration"
|
||||
color="var(--cpd-color-icon-quaternary)"
|
||||
fill="currentColor"
|
||||
height="8px"
|
||||
viewBox="0 0 8 8"
|
||||
width="8px"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
clip-path="url(#a)"
|
||||
>
|
||||
<path
|
||||
d="M8 4a4 4 0 1 1-8 0 4 4 0 0 1 8 0"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clippath
|
||||
id="a"
|
||||
>
|
||||
<path
|
||||
d="M0 0h8v8H0z"
|
||||
/>
|
||||
</clippath>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user