Compare commits

...

20 Commits

Author SHA1 Message Date
David Baker
63ecbab533 Merge remote-tracking branch 'origin/develop' into dbkr/module_api_additions_2 2025-10-16 10:46:06 +01:00
David Baker
0468876aa0 Move some message utils out to their own file (#31035)
* Move some message utils out to their own file

In another attempt at import cycle breaking

* Also add the file

* Move tests
2025-10-16 08:17:46 +00:00
R Midhun Suresh
c8f1c19517 Add missing dependency (#31034) 2025-10-15 16:45:49 +00:00
R Midhun Suresh
2598e4ea22 Move view model code to shared components package (#31024)
* Remove vm related code from element-web/src

* Add and export view model code from package

* Update imports

* Rewrite vm tests using vitest

* Add github action to run vm tests

* Fix lint errors

* Mvoe tests over to jest

* Try fixing code coverage

* Second attempt at fixing code coverage
2025-10-15 13:49:12 +00:00
renovate[bot]
ac96ab0d46 Update react monorepo (#31014)
* Update react monorepo

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update shared-components snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-15 11:20:34 +00:00
David Baker
b07362717b Add soacetreelevel change 2025-10-15 12:01:51 +01:00
David Baker
97f345651d Merge branch 'develop' into dbkr/module_api_additions_2 2025-10-15 11:49:40 +01:00
renovate[bot]
949d0dc8a9 Update eslint-plugins (#31033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-15 10:44:06 +00:00
renovate[bot]
0e0e928040 Update eslint-plugins (#31032)
* Update eslint-plugins

* Bump matrix-org

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-15 10:08:35 +00:00
David Baker
c519438dad Add prepare script (#31030)
Removed it when we switched to publishing, but that doesn't really
make sense
2025-10-15 09:22:42 +00:00
David Baker
146e4772ac Change module API to be an instance getter (#31025)
* Change module API to be an instance getter

Helps with circular dependencies by not instantating the module API
on the initial evaluation of the files.

* Add basic test

* add another test
2025-10-15 09:20:48 +00:00
Florian Duros
6cfe197a38 Update sonar and jest config with new shared components path (#31029)
* fix: update jest config with new shared components path

* fix: update sonar config

* chore: add `storybook` & `@storybook/react-vite` to run the shared components tests
2025-10-15 09:08:49 +00:00
renovate[bot]
a4a44a0c1c Update browserslist (#31021)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-15 08:37:57 +00:00
renovate[bot]
2ce2218549 Update typescript-eslint monorepo to v8.46.0 (#30921)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-15 08:21:23 +00:00
David Baker
898475ab5a CSS 2025-10-14 16:04:38 +01:00
David Baker
a79febf6d8 Add items from the module api 2025-10-14 15:48:54 +01:00
David Baker
494ba59aa1 and new files 2025-10-14 15:34:37 +01:00
David Baker
31410fe4ef Add actual module api bits 2025-10-14 15:31:42 +01:00
David Baker
d23223c836 right kind of bracket 2025-10-14 15:24:42 +01:00
David Baker
c02163bf55 Additions to module API 2025-10-14 15:16:06 +01:00
121 changed files with 1821 additions and 1217 deletions

View File

@@ -17,7 +17,7 @@ const config: Config = {
// This is needed to be able to load dual CJS/ESM WASM packages e.g. rust crypto & matrix-wywiwyg
customExportConditions: ["browser", "node"],
},
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)", "<rootDir>/src/shared-components/**/*.test.[t]s?(x)"],
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)", "<rootDir>/packages/*/src/**/*.test.[t]s?(x)"],
globalSetup: "<rootDir>/test/globalSetup.ts",
setupFiles: ["jest-canvas-mock", "web-streams-polyfill/polyfill"],
setupFilesAfterEnv: ["<rootDir>/test/setupTests.ts"],
@@ -46,6 +46,7 @@ const config: Config = {
],
collectCoverageFrom: [
"<rootDir>/src/**/*.{js,ts,tsx}",
"<rootDir>/packages/**/*.{js,ts,tsx}",
// getSessionLock is piped into a different JS context via stringification, and the coverage functionality is
// not available in that contest. So, turn off coverage instrumentation for it.
"!<rootDir>/src/utils/SessionLock.ts",

View File

@@ -68,13 +68,13 @@
"postinstall": "patch-package"
},
"resolutions": {
"**/pretty-format/react-is": "19.1.1",
"**/pretty-format/react-is": "19.2.0",
"@playwright/test": "1.56.0",
"@types/react": "19.1.14",
"@types/react-dom": "19.1.9",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.1",
"oidc-client-ts": "3.3.0",
"jwt-decode": "4.0.0",
"caniuse-lite": "1.0.30001745",
"caniuse-lite": "1.0.30001750",
"testcontainers": "^11.0.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
"wrap-ansi": "npm:wrap-ansi@^7.0.0"
@@ -187,6 +187,7 @@
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
"@rrweb/types": "^2.0.0-alpha.18",
"@sentry/webpack-plugin": "^4.0.0",
"@storybook/react-vite": "^9.1.10",
"@stylistic/eslint-plugin": "^5.0.0",
"@svgr/webpack": "^8.0.0",
"@testing-library/dom": "^10.4.0",
@@ -213,9 +214,9 @@
"@types/node-fetch": "^2.6.2",
"@types/pako": "^2.0.0",
"@types/qrcode": "^1.3.5",
"@types/react": "19.1.14",
"@types/react": "19.2.2",
"@types/react-beautiful-dnd": "^13.0.0",
"@types/react-dom": "19.1.9",
"@types/react-dom": "19.2.1",
"@types/react-transition-group": "^4.4.0",
"@types/sanitize-html": "2.16.0",
"@types/sdp-transform": "^2.4.10",
@@ -239,14 +240,14 @@
"eslint": "8.57.1",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-deprecate": "0.8.5",
"eslint-plugin-deprecate": "0.8.7",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^28.0.0",
"eslint-plugin-jest": "^29.0.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-matrix-org": "^2.0.2",
"eslint-plugin-matrix-org": "^3.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-compiler": "^19.0.0-beta-df7b47d-20241124",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-hooks": "^7.0.0",
"eslint-plugin-unicorn": "^56.0.0",
"express": "^5.0.0",
"fake-indexeddb": "^6.0.0",
@@ -287,6 +288,7 @@
"rimraf": "^6.0.0",
"semver": "^7.5.2",
"source-map-loader": "^5.0.0",
"storybook": "^9.1.10",
"stylelint": "^16.23.0",
"stylelint-config-standard": "^39.0.0",
"stylelint-scss": "^6.0.0",

View File

@@ -31,6 +31,7 @@
],
"scripts": {
"postinstall": "patch-package",
"prepare": "vite build",
"storybook": "storybook dev -p 6007",
"build-storybook": "storybook build",
"lint": "yarn lint:types && yarn lint:js",
@@ -42,7 +43,8 @@
},
"dependencies": {
"matrix-web-i18n": "^3.4.0",
"patch-package": "^8.0.1"
"patch-package": "^8.0.1",
"counterpart": "^0.18.6"
},
"devDependencies": {
"@storybook/addon-a11y": "^9.1.10",
@@ -53,7 +55,6 @@
"@storybook/test-runner": "^0.23.0",
"concurrently": "^9.2.1",
"eslint": "8",
"jest-image-snapshot": "^6.5.1",
"eslint-plugin-storybook": "^9.1.10",
"jest-image-snapshot": "^6.5.1",
"patch-package": "^8.0.1",

View File

@@ -8,8 +8,8 @@
import React, { type JSX, useMemo, type ComponentType } from "react";
import { omitBy, pickBy } from "lodash";
import { MockViewModel } from "./MockViewModel";
import { type ViewModel } from "./ViewModel";
import { MockViewModel } from "./viewmodel/MockViewModel";
import { type ViewModel } from "./viewmodel/ViewModel";
interface ViewWrapperProps<V> {
/**

View File

@@ -13,7 +13,7 @@ import { fireEvent } from "@testing-library/dom";
import * as stories from "./AudioPlayerView.stories.tsx";
import { AudioPlayerView, type AudioPlayerViewActions, type AudioPlayerViewSnapshot } from "./AudioPlayerView";
import { MockViewModel } from "../../MockViewModel";
import { MockViewModel } from "../../viewmodel/MockViewModel.ts";
const { Default, NoMediaName, NoSize, HasError } = composeStories(stories);

View File

@@ -7,7 +7,7 @@
import React, { type ChangeEventHandler, type JSX, type KeyboardEventHandler, type MouseEventHandler } from "react";
import { type ViewModel } from "../../ViewModel";
import { type ViewModel } from "../../viewmodel/ViewModel";
import { useViewModel } from "../../useViewModel";
import { MediaBody } from "../../message-body/MediaBody";
import { Flex } from "../../utils/Flex";

View File

@@ -15,7 +15,7 @@ exports[`AudioPlayerView renders the audio player in default state 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -106,7 +106,7 @@ exports[`AudioPlayerView renders the audio player in error state 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«ri»"
aria-labelledby="_r_i_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -202,7 +202,7 @@ exports[`AudioPlayerView renders the audio player without media name 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -293,7 +293,7 @@ exports[`AudioPlayerView renders the audio player without size 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«rc»"
aria-labelledby="_r_c_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"

View File

@@ -5,7 +5,7 @@ exports[`PlayPauseButton renders the button in default state 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -37,7 +37,7 @@ exports[`PlayPauseButton renders the button in playing state 1`] = `
<button
aria-disabled="false"
aria-label="Pause"
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"

View File

@@ -9,7 +9,7 @@ import React from "react";
import { type Meta, type StoryFn } from "@storybook/react-vite";
import { TextualEventView as TextualEventComponent } from "./TextualEventView";
import { MockViewModel } from "../../MockViewModel";
import { MockViewModel } from "../../viewmodel/MockViewModel";
export default {
title: "Event/TextualEvent",

View File

@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
import React, { type ReactNode, type JSX } from "react";
import { type ViewModel } from "../../ViewModel";
import { type ViewModel } from "../../viewmodel/ViewModel";
import { useViewModel } from "../../useViewModel";
export type TextualEventViewSnapshot = {

View File

@@ -27,7 +27,6 @@ export * from "./utils/DateUtils";
export * from "./utils/numbers";
// MVVM
export * from "./viewmodel";
export * from "./ViewWrapper";
export type * from "./ViewModel";
export * from "./useViewModel";
export * from "./MockViewModel";

View File

@@ -11,12 +11,12 @@ exports[`Pill renders the pill 1`] = `
/>
<span
class="label"
id="«r0»"
id="_r_0_"
>
Pill
</span>
<button
aria-describedby="«r0»"
aria-describedby="_r_0_"
aria-label="Delete"
class="_icon-button_1pz9o_8"
data-kind="primary"
@@ -57,7 +57,7 @@ exports[`Pill renders the pill without close button 1`] = `
/>
<span
class="label"
id="«r1»"
id="_r_1_"
>
Pill
</span>

View File

@@ -11,12 +11,12 @@ exports[`RichItem renders the list 1`] = `
>
<span
class="title"
id="«r0»"
id="_r_0_"
>
Rich List Title
</span>
<ul
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="content"
role="listbox"
tabindex="0"
@@ -174,7 +174,7 @@ exports[`RichItem renders the list with isEmpty=true 1`] = `
>
<span
class="title"
id="«r1»"
id="_r_1_"
>
Rich List Title
</span>

View File

@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
import { useSyncExternalStore } from "react";
import { type ViewModel } from "./ViewModel";
import { type ViewModel } from "./viewmodel/ViewModel";
/**
* A small wrapper around useSyncExternalStore to use a view model in a shared component view

View File

@@ -5,7 +5,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 { type ViewModel } from "../../../packages/shared-components/src/ViewModel";
import { type ViewModel } from "./ViewModel";
import { Disposables } from "./Disposables";
import { Snapshot } from "./Snapshot";
import { ViewModelSubscriptions } from "./ViewModelSubscriptions";

View File

@@ -0,0 +1,13 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
export * from "./BaseViewModel";
export * from "./Disposables";
export * from "./Snapshot";
export * from "./ViewModelSubscriptions";
export type * from "./ViewModel";
export * from "./MockViewModel";

View File

@@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details.
import { EventEmitter } from "events";
import { Disposables } from "../../../src/viewmodels/base/Disposables";
import { Disposables } from "..";
describe("Disposable", () => {
it("isDisposed is true after dispose() is called", () => {

View File

@@ -5,7 +5,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 { Snapshot } from "../../../src/viewmodels/base/Snapshot";
import { Snapshot } from "..";
interface TestSnapshot {
key1: string;

View File

@@ -2333,6 +2333,17 @@ core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
counterpart@^0.18.6:
version "0.18.6"
resolved "https://registry.yarnpkg.com/counterpart/-/counterpart-0.18.6.tgz#cf6b60d8ef99a4b44b8bf6445fa99b4bd1b2f9dd"
integrity sha512-cAIDAYbC3x8S2DDbvFEJ4TzPtPYXma25/kfAkfmprNLlkPWeX4SdUp1c2xklfphqCU3HnDaivR4R3BrAYf5OMA==
dependencies:
date-names "^0.1.11"
except "^0.1.3"
extend "^3.0.0"
pluralizers "^0.1.7"
sprintf-js "^1.0.3"
create-ecdh@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
@@ -2422,6 +2433,11 @@ cwd@^0.10.0:
find-pkg "^0.1.2"
fs-exists-sync "^0.1.0"
date-names@^0.1.11:
version "0.1.13"
resolved "https://registry.yarnpkg.com/date-names/-/date-names-0.1.13.tgz#c4358f6f77c8056e2f5ea68fdbb05f0bf1e53bd0"
integrity sha512-IxxoeD9tdx8pXVcmqaRlPvrXIsSrSrIZzfzlOkm9u+hyzKp5Wk/odt9O/gd7Ockzy8n/WHeEpTVJ2bF3mMV4LA==
de-indent@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
@@ -2870,6 +2886,13 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
except@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/except/-/except-0.1.3.tgz#98261c91958551536b44482238e9783fb73d292a"
integrity sha512-ouwgJavvMOTOfy0RE8NGQFAIoWh8ehJhkuxDyXxngMVTxTq7HGE7gZopZhqKFnu5lZLI+qQdtvJ8n03ehp7RJg==
dependencies:
indexof "0.0.1"
execa@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
@@ -2918,6 +2941,11 @@ exsolve@^1.0.7:
resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.7.tgz#3b74e4c7ca5c5f9a19c3626ca857309fa99f9e9e"
integrity sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==
extend@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -3449,6 +3477,11 @@ indent-string@^4.0.0:
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
indexof@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
integrity sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -4994,6 +5027,11 @@ playwright@^1.14.0:
optionalDependencies:
fsevents "2.3.2"
pluralizers@^0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/pluralizers/-/pluralizers-0.1.7.tgz#8d38dd0a1b660e739b10ab2eab10b684c9d50142"
integrity sha512-mw6AejUiCaMQ6uPN9ObjJDTnR5AnBSmnHHy3uVTbxrSFSxO5scfwpTs8Dxyb6T2v7GSulhvOq+pm9y+hXUvtOA==
pngjs@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
@@ -5535,6 +5573,11 @@ spawnd@^5.0.0:
tree-kill "^1.2.2"
wait-port "^0.2.9"
sprintf-js@^1.0.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"

View File

@@ -211,6 +211,10 @@ Please see LICENSE files in the repository root for full details.
}
}
&.mx_SpaceButton_withIcon .mx_SpaceButton_icon {
background-color: $panel-actions;
}
&.mx_SpaceButton_home .mx_SpaceButton_icon::before {
mask-image: url("@vector-im/compound-design-tokens/icons/home-solid.svg");
}

View File

@@ -4,9 +4,9 @@ sonar.organization=element-hq
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8
sonar.sources=src,res
sonar.tests=test,playwright,src
sonar.test.inclusions=test/*,playwright/*,src/**/*.test.*
sonar.sources=src,res,packages/shared-components/src
sonar.tests=test,playwright,src,packages
sonar.test.inclusions=test/*,playwright/*,src/**/*.test.*,packages/*/src/**/*.test.*
sonar.exclusions=__mocks__,docs,element.io,nginx
sonar.cpd.exclusions=src/i18n/strings/*.json

View File

@@ -53,7 +53,7 @@ import ErrorDialog from "./components/views/dialogs/ErrorDialog";
import UploadFailureDialog from "./components/views/dialogs/UploadFailureDialog";
import UploadConfirmDialog from "./components/views/dialogs/UploadConfirmDialog";
import { createThumbnail } from "./utils/image-media";
import { attachMentions, attachRelation } from "./components/views/rooms/SendMessageComposer";
import { attachMentions, attachRelation } from "./utils/messages.ts";
import { doMaybeLocalRoomAction } from "./utils/local-room";
import { SdkContextClass } from "./contexts/SDKContext";
import { blobIsAnimated } from "./utils/Image.ts";

View File

@@ -31,7 +31,7 @@ const notLoggedInMap: Record<Exclude<Views, Views.LOGGED_IN>, ScreenName> = {
[Views.LOCK_STOLEN]: "SessionLockStolen",
};
const loggedInPageTypeMap: Record<PageType, ScreenName> = {
const loggedInPageTypeMap: Record<PageType | string, ScreenName> = {
[PageType.HomePage]: "Home",
[PageType.RoomView]: "Room",
[PageType.UserView]: "User",
@@ -48,10 +48,10 @@ export default class PosthogTrackers {
}
private view: Views = Views.LOADING;
private pageType?: PageType;
private pageType?: PageType | string;
private override?: ScreenName;
public trackPageChange(view: Views, pageType: PageType | undefined, durationMs: number): void {
public trackPageChange(view: Views, pageType: PageType | string | undefined, durationMs: number): void {
this.view = view;
this.pageType = pageType;
if (this.override) return;

View File

@@ -69,6 +69,7 @@ import { type ConfigOptions } from "../../SdkConfig";
import { MatrixClientContextProvider } from "./MatrixClientContextProvider";
import { Landmark, LandmarkNavigation } from "../../accessibility/LandmarkNavigation";
import { SDKContext } from "../../contexts/SDKContext.ts";
import ModuleApi from "../../modules/Api.ts";
// We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity.
@@ -679,6 +680,10 @@ class LoggedInView extends React.Component<IProps, IState> {
public render(): React.ReactNode {
let pageElement;
const moduleRenderer = this.props.page_type
? ModuleApi.navigation.locationRenderers.get(this.props.page_type)
: undefined;
switch (this.props.page_type) {
case PageTypes.RoomView:
pageElement = (
@@ -705,6 +710,13 @@ class LoggedInView extends React.Component<IProps, IState> {
);
}
break;
default: {
if (moduleRenderer) {
pageElement = moduleRenderer();
} else {
console.warn(`Couldn't render page type "${this.props.page_type}"`);
}
}
}
const wrapperClasses = classNames({
@@ -746,20 +758,22 @@ class LoggedInView extends React.Component<IProps, IState> {
)}
<SpacePanel />
{!useNewRoomList && <BackdropPanel backgroundImage={this.state.backgroundImage} />}
<div
className="mx_LeftPanel_wrapper--user"
ref={this._resizeContainer}
data-collapsed={shouldUseMinimizedUI ? true : undefined}
>
<LeftPanel
pageType={this.props.page_type as PageTypes}
isMinimized={shouldUseMinimizedUI || false}
resizeNotifier={this.context.resizeNotifier}
/>
</div>
{!moduleRenderer && (
<div
className="mx_LeftPanel_wrapper--user"
ref={this._resizeContainer}
data-collapsed={shouldUseMinimizedUI ? true : undefined}
>
<LeftPanel
pageType={this.props.page_type as PageTypes}
isMinimized={shouldUseMinimizedUI || false}
resizeNotifier={this.context.resizeNotifier}
/>
</div>
)}
</div>
</div>
<ResizeHandle passRef={this.resizeHandler} id="lp-resizer" />
{!moduleRenderer && <ResizeHandle passRef={this.resizeHandler} id="lp-resizer" />}
<div className="mx_RoomView_wrapper">{pageElement}</div>
</div>
</div>

View File

@@ -140,6 +140,7 @@ import { ShareFormat, type SharePayload } from "../../dispatcher/payloads/ShareP
import Markdown from "../../Markdown";
import { sanitizeHtmlParams } from "../../Linkify";
import { isOnlyAdmin } from "../../utils/membership";
import ModuleApi from "../../modules/Api.ts";
// legacy export
export { default as Views } from "../../Views";
@@ -175,9 +176,11 @@ interface IProps {
interface IState {
// the master view we are showing.
view: Views;
// What the LoggedInView would be showing if visible
// What the LoggedInView would be showing if visible.
// A member of the enum for standard pages or a string for those provided by
// a module.
// eslint-disable-next-line camelcase
page_type?: PageType;
page_type?: PageType | string;
// The ID of the room we're viewing. This is either populated directly
// in the case where we view a room by ID or by RoomView when it resolves
// what ID an alias points at.
@@ -1922,7 +1925,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
subAction: params?.action,
});
} else {
logger.info(`Ignoring showScreen for '${screen}'`);
if (ModuleApi.navigation.locationRenderers.get(screen)) {
this.setState({ page_type: screen });
}
}
}

View File

@@ -44,6 +44,7 @@ import { type CallState, type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import { debounce, throttle } from "lodash";
import { CryptoEvent } from "matrix-js-sdk/src/crypto-api";
import { type ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle";
import { type RoomViewProps } from "@element-hq/element-web-module-api";
import shouldHideEvent from "../../shouldHideEvent";
import { _t } from "../../languageHandler";
@@ -147,7 +148,7 @@ if (DEBUG) {
debuglog = logger.log.bind(console);
}
interface IRoomProps {
interface IRoomProps extends RoomViewProps {
threepidInvite?: IThreepidInvite;
oobData?: IOOBData;

View File

@@ -43,7 +43,7 @@ import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { PosthogAnalytics } from "../../../PosthogAnalytics";
import { editorRoomKey, editorStateKey } from "../../../Editing";
import type DocumentOffset from "../../../editor/offset";
import { attachMentions, attachRelation } from "./SendMessageComposer";
import { attachMentions, attachRelation } from "../../../utils/messages";
import { filterBoolean } from "../../../utils/arrays";
import { MatrixClientPeg } from "../../../MatrixClientPeg";

View File

@@ -31,7 +31,7 @@ import { UIFeature } from "../../../settings/UIFeature";
import { ModuleRunner } from "../../../modules/ModuleRunner";
import { Icon as AskToJoinIcon } from "../../../../res/img/element-icons/ask-to-join.svg";
import Field from "../elements/Field";
import ModuleApi from "../../../modules/Api.ts";
import { ModuleApi } from "../../../modules/Api.ts";
const MemberEventHtmlReasonField = "io.element.html_reason";
@@ -750,7 +750,7 @@ class RoomPreviewBar extends React.Component<IProps, IState> {
}
const WrappedRoomPreviewBar = (props: IProps): JSX.Element => {
const moduleRenderer = ModuleApi.customComponents.roomPreviewBarRenderer;
const moduleRenderer = ModuleApi.instance.customComponents.roomPreviewBarRenderer;
if (moduleRenderer) {
return moduleRenderer(
{

View File

@@ -8,10 +8,8 @@ Please see LICENSE files in the repository root for full details.
import React, { createRef, type KeyboardEvent, type SyntheticEvent } from "react";
import {
type IContent,
type MatrixEvent,
type IEventRelation,
type IMentions,
type Room,
EventType,
MsgType,
@@ -35,7 +33,7 @@ import {
unescapeMessage,
} from "../../../editor/serialize";
import BasicMessageComposer, { REGEX_EMOTICON } from "./BasicMessageComposer";
import { CommandPartCreator, type Part, type PartCreator, type SerializedPart, Type } from "../../../editor/parts";
import { CommandPartCreator, type Part, type PartCreator, type SerializedPart } from "../../../editor/parts";
import { findEditableEvent } from "../../../utils/EventUtils";
import SendHistoryManager from "../../../SendHistoryManager";
import { CommandCategories } from "../../../SlashCommands";
@@ -61,108 +59,11 @@ import { type Caret } from "../../../editor/caret";
import { type IDiff } from "../../../editor/diff";
import { getBlobSafeMimeType } from "../../../utils/blobs";
import { EMOJI_REGEX } from "../../../HtmlUtils";
import { attachMentions, attachRelation } from "../../../utils/messages";
// The prefix used when persisting editor drafts to localstorage.
export const EDITOR_STATE_STORAGE_PREFIX = "mx_cider_state_";
/**
* Build the mentions information based on the editor model (and any related events):
*
* 1. Search the model parts for room or user pills and fill in the mentions object.
* 2. If this is a reply to another event, include any user mentions from that
* (but do not include a room mention).
*
* @param sender - The Matrix ID of the user sending the event.
* @param content - The event content.
* @param model - The editor model to search for mentions, null if there is no editor.
* @param replyToEvent - The event being replied to or undefined if it is not a reply.
* @param editedContent - The content of the parent event being edited.
*/
export function attachMentions(
sender: string,
content: IContent,
model: EditorModel | null,
replyToEvent: MatrixEvent | undefined,
editedContent: IContent | null = null,
): void {
// We always attach the mentions even if the home server doesn't yet support
// intentional mentions. This is safe because m.mentions is an additive change
// that should simply be ignored by incapable home servers.
// The mentions property *always* gets included to disable legacy push rules.
const mentions: IMentions = (content["m.mentions"] = {});
const userMentions = new Set<string>();
let roomMention = false;
// If there's a reply, initialize the mentioned users as the sender of that event.
if (replyToEvent) {
userMentions.add(replyToEvent.sender!.userId);
}
// If user provided content is available, check to see if any users are mentioned.
if (model) {
// Add any mentioned users in the current content.
for (const part of model.parts) {
if (part.type === Type.UserPill) {
userMentions.add(part.resourceId);
} else if (part.type === Type.AtRoomPill) {
roomMention = true;
}
}
}
// Ensure the *current* user isn't listed in the mentioned users.
userMentions.delete(sender);
// Finally, if this event is editing a previous event, only include users who
// were not previously mentioned and a room mention if the previous event was
// not a room mention.
if (editedContent) {
// First, the new event content gets the *full* set of users.
const newContent = content["m.new_content"];
const newMentions: IMentions = (newContent["m.mentions"] = {});
// Only include the users/room if there is any content.
if (userMentions.size) {
newMentions.user_ids = [...userMentions];
}
if (roomMention) {
newMentions.room = true;
}
// Fetch the mentions from the original event and remove any previously
// mentioned users.
const prevMentions = editedContent["m.mentions"];
if (Array.isArray(prevMentions?.user_ids)) {
prevMentions!.user_ids.forEach((userId) => userMentions.delete(userId));
}
// If the original event mentioned the room, nothing to do here.
if (prevMentions?.room) {
roomMention = false;
}
}
// Only include the users/room if there is any content.
if (userMentions.size) {
mentions.user_ids = [...userMentions];
}
if (roomMention) {
mentions.room = true;
}
}
// Merges favouring the given relation
export function attachRelation(content: IContent, relation?: IEventRelation): void {
if (relation) {
content["m.relates_to"] = {
...(content["m.relates_to"] || {}),
...relation,
};
}
}
// exported for tests
export function createMessageContent(
sender: string,

View File

@@ -29,7 +29,7 @@ import InlineSpinner from "../elements/InlineSpinner";
import { PlaybackManager } from "../../../audio/PlaybackManager";
import { doMaybeLocalRoomAction } from "../../../utils/local-room";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import { attachMentions, attachRelation } from "./SendMessageComposer";
import { attachMentions, attachRelation } from "../../../utils/messages";
import { addReplyToMessageContent } from "../../../utils/Reply";
import RoomContext from "../../../contexts/RoomContext";
import { type IUpload, type VoiceMessageRecording } from "../../../audio/VoiceMessageRecording";

View File

@@ -33,7 +33,7 @@ import { CommandCategories, getCommand } from "../../../../../SlashCommands";
import { runSlashCommand, shouldSendAnyway } from "../../../../../editor/commands";
import { Action } from "../../../../../dispatcher/actions";
import { addReplyToMessageContent } from "../../../../../utils/Reply";
import { attachRelation } from "../../SendMessageComposer";
import { attachRelation } from "../../../../../utils/messages";
export interface SendMessageParams {
mxClient: MatrixClient;

View File

@@ -69,6 +69,7 @@ import AccessibleButton from "../elements/AccessibleButton";
import { Landmark, LandmarkNavigation } from "../../../accessibility/LandmarkNavigation";
import { KeyboardShortcut } from "../settings/KeyboardShortcut";
import { ReleaseAnnouncement } from "../../structures/ReleaseAnnouncement";
import ModuleApi from "../../../modules/Api.ts";
const useSpaces = (): [Room[], MetaSpace[], Room[], SpaceKey] => {
const invites = useEventEmitterState<Room[]>(SpaceStore.instance, UPDATE_INVITED_SPACES, () => {
@@ -341,6 +342,7 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(
</Draggable>
))}
{children}
{ModuleApi.extras.spacePanelItems.map((renderer) => renderer({ isPanelCollapsed }))}
{shouldShowComponent(UIComponent.CreateSpaces) && (
<CreateSpaceButton isPanelCollapsed={isPanelCollapsed} setPanelCollapsed={setPanelCollapsed} />
)}

View File

@@ -52,6 +52,7 @@ type ButtonProps<T extends keyof HTMLElementTagNameMap> = Omit<
className?: string;
selected?: boolean;
label: string;
icon?: JSX.Element;
contextMenuTooltip?: string;
notificationState?: NotificationState;
isNarrow?: boolean;
@@ -65,6 +66,7 @@ export const SpaceButton = <T extends keyof HTMLElementTagNameMap>({
space,
spaceKey: _spaceKey,
className,
icon,
selected,
label,
contextMenuTooltip,
@@ -84,7 +86,7 @@ export const SpaceButton = <T extends keyof HTMLElementTagNameMap>({
let avatar = (
<div className="mx_SpaceButton_avatarPlaceholder">
<div className="mx_SpaceButton_icon" />
<div className="mx_SpaceButton_icon">{icon}</div>
</div>
);
if (space) {
@@ -143,6 +145,7 @@ export const SpaceButton = <T extends keyof HTMLElementTagNameMap>({
mx_SpaceButton_active: selected,
mx_SpaceButton_hasMenuOpen: menuDisplayed,
mx_SpaceButton_narrow: isNarrow,
mx_SpaceButton_withIcon: Boolean(icon),
})}
aria-label={label}
title={!isNarrow || menuDisplayed ? undefined : label}

View File

@@ -41,7 +41,7 @@ import HiddenBody from "../components/views/messages/HiddenBody";
import ViewSourceEvent from "../components/views/messages/ViewSourceEvent";
import { shouldDisplayAsBeaconTile } from "../utils/beacon/timeline";
import { type IBodyProps } from "../components/views/messages/IBodyProps";
import ModuleApi from "../modules/Api";
import { ModuleApi } from "../modules/Api";
import { TextualEventViewModel } from "../viewmodels/event-tiles/TextualEventViewModel";
import { TextualEventView } from "../../packages/shared-components/src/event-tiles/TextualEventView";
import { ElementCallEventType } from "../call-types";
@@ -266,7 +266,7 @@ export function renderTile(
// If we don't have a factory for this event, attempt
// to find a custom component that can render it.
// Will return null if no custom component can render it.
return ModuleApi.customComponents.renderMessage({
return ModuleApi.instance.customComponents.renderMessage({
mxEvent: props.mxEvent,
});
}
@@ -297,7 +297,7 @@ export function renderTile(
case TimelineRenderingType.File:
case TimelineRenderingType.Notification:
case TimelineRenderingType.Thread:
return ModuleApi.customComponents.renderMessage(
return ModuleApi.instance.customComponents.renderMessage(
{
mxEvent: props.mxEvent,
},
@@ -318,7 +318,7 @@ export function renderTile(
}),
);
default:
return ModuleApi.customComponents.renderMessage(
return ModuleApi.instance.customComponents.renderMessage(
{
mxEvent: props.mxEvent,
},
@@ -363,7 +363,7 @@ export function renderReplyTile(
// If we don't have a factory for this event, attempt
// to find a custom component that can render it.
// Will return null if no custom component can render it.
return ModuleApi.customComponents.renderMessage({
return ModuleApi.instance.customComponents.renderMessage({
mxEvent: props.mxEvent,
});
}
@@ -384,7 +384,7 @@ export function renderReplyTile(
permalinkCreator,
} = props;
return ModuleApi.customComponents.renderMessage(
return ModuleApi.instance.customComponents.renderMessage(
{
mxEvent: props.mxEvent,
},
@@ -429,7 +429,7 @@ export function haveRendererForEvent(
// Check to see if we have any hints for this message, which indicates
// there is a custom renderer for the event.
if (ModuleApi.customComponents.getHintsForMessage(mxEvent)) {
if (ModuleApi.instance.customComponents.getHintsForMessage(mxEvent)) {
return true;
}

View File

@@ -15,7 +15,7 @@ import { _t } from "../languageHandler";
import Modal from "../Modal";
import { FileDownloader } from "../utils/FileDownloader";
import { MediaEventHelper } from "../utils/MediaEventHelper";
import ModuleApi from "../modules/Api";
import { ModuleApi } from "../modules/Api";
export interface UseDownloadMediaReturn {
download: () => Promise<void>;
@@ -34,7 +34,7 @@ export function useDownloadMedia(url: string, fileName?: string, mxEvent?: Matri
useEffect(() => {
if (!mxEvent) return;
const hints = ModuleApi.customComponents.getHintsForMessage(mxEvent);
const hints = ModuleApi.instance.customComponents.getHintsForMessage(mxEvent);
if (hints?.allowDownloadingMedia) {
setCanDownload(false);
hints

View File

@@ -26,6 +26,7 @@ import { WatchableProfile } from "./Profile.ts";
import { NavigationApi } from "./Navigation.ts";
import { openDialog } from "./Dialog.tsx";
import { overwriteAccountAuth } from "./Auth.ts";
import { ElementWebExtrasApi } from "./ExtrasApi.ts";
const legacyCustomisationsFactory = <T extends object>(baseCustomisations: T) => {
let used = false;
@@ -39,7 +40,17 @@ const legacyCustomisationsFactory = <T extends object>(baseCustomisations: T) =>
/**
* Implementation of the @element-hq/element-web-module-api runtime module API.
*/
class ModuleApi implements Api {
export class ModuleApi implements Api {
private static _instance: ModuleApi;
public static get instance(): ModuleApi {
if (!ModuleApi._instance) {
ModuleApi._instance = new ModuleApi();
window.mxModuleApi = ModuleApi._instance;
}
return ModuleApi._instance;
}
/* eslint-disable @typescript-eslint/naming-convention */
public async _registerLegacyModule(LegacyModule: RuntimeModuleConstructor): Promise<void> {
ModuleRunner.instance.registerModule((api) => new LegacyModule(api));
@@ -69,6 +80,7 @@ class ModuleApi implements Api {
public readonly config = new ConfigApi();
public readonly i18n = new I18nApi();
public readonly customComponents = new CustomComponentsApi();
public readonly extras = new ElementWebExtrasApi();
public readonly rootNode = document.getElementById("matrixchat")!;
public createRoot(element: Element): Root {
@@ -77,8 +89,3 @@ class ModuleApi implements Api {
}
export type ModuleApiType = ModuleApi;
if (!window.mxModuleApi) {
window.mxModuleApi = new ModuleApi();
}
export default window.mxModuleApi;

View File

@@ -0,0 +1,16 @@
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { type RoomViewProps, type BuiltinsApi } from "@element-hq/element-web-module-api";
import { RoomView } from "../components/structures/RoomView";
export class ElementWebBuiltinsApi implements BuiltinsApi {
public getRoomViewComponent(): React.ComponentType<RoomViewProps> {
return RoomView;
}
}

16
src/modules/ExtrasApi.ts Normal file
View File

@@ -0,0 +1,16 @@
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { type SpacePanelItemRenderFunction, type ExtrasApi } from "@element-hq/element-web-module-api";
export class ElementWebExtrasApi implements ExtrasApi {
public spacePanelItems: SpacePanelItemRenderFunction[] = [];
public addSpacePanelItem(renderer: SpacePanelItemRenderFunction): void {
this.spacePanelItems.push(renderer);
}
}

View File

@@ -5,7 +5,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 { type NavigationApi as INavigationApi } from "@element-hq/element-web-module-api";
import { type LocationRenderFunction, type NavigationApi as INavigationApi } from "@element-hq/element-web-module-api";
import { navigateToPermalink } from "../utils/permalinks/navigator.ts";
import { parsePermalink } from "../utils/permalinks/Permalinks.ts";
@@ -14,6 +14,8 @@ import { Action } from "../dispatcher/actions.ts";
import type { ViewRoomPayload } from "../dispatcher/payloads/ViewRoomPayload.ts";
export class NavigationApi implements INavigationApi {
public locationRenderers = new Map<string, LocationRenderFunction>();
public async toMatrixToLink(link: string, join = false): Promise<void> {
navigateToPermalink(link);
@@ -38,4 +40,8 @@ export class NavigationApi implements INavigationApi {
}
}
}
public registerLocationRenderer(path: string, renderer: LocationRenderFunction): void {
this.locationRenderers.set(path, renderer);
}
}

View File

@@ -30,7 +30,7 @@ import { type TimelineRenderingType } from "../contexts/RoomContext";
import { launchPollEditor } from "../components/views/messages/MPollBody";
import { Action } from "../dispatcher/actions";
import { type ViewRoomPayload } from "../dispatcher/payloads/ViewRoomPayload";
import ModuleApi from "../modules/Api";
import { ModuleApi } from "../modules/Api";
/**
* Returns whether an event should allow actions like reply, reactions, edit, etc.
@@ -78,7 +78,7 @@ export function canEditContent(matrixClient: MatrixClient, mxEvent: MatrixEvent)
return false;
}
if (ModuleApi.customComponents.getHintsForMessage(mxEvent)?.allowEditingEvent === false) {
if (ModuleApi.instance.customComponents.getHintsForMessage(mxEvent)?.allowEditingEvent === false) {
return false;
}

109
src/utils/messages.ts Normal file
View File

@@ -0,0 +1,109 @@
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { type MatrixEvent, type IContent, type IMentions, type IEventRelation } from "matrix-js-sdk/src/matrix";
import type EditorModel from "../editor/model";
import { Type } from "../editor/parts";
/**
* Build the mentions information based on the editor model (and any related events):
*
* 1. Search the model parts for room or user pills and fill in the mentions object.
* 2. If this is a reply to another event, include any user mentions from that
* (but do not include a room mention).
*
* @param sender - The Matrix ID of the user sending the event.
* @param content - The event content.
* @param model - The editor model to search for mentions, null if there is no editor.
* @param replyToEvent - The event being replied to or undefined if it is not a reply.
* @param editedContent - The content of the parent event being edited.
*/
export function attachMentions(
sender: string,
content: IContent,
model: EditorModel | null,
replyToEvent: MatrixEvent | undefined,
editedContent: IContent | null = null,
): void {
// We always attach the mentions even if the home server doesn't yet support
// intentional mentions. This is safe because m.mentions is an additive change
// that should simply be ignored by incapable home servers.
// The mentions property *always* gets included to disable legacy push rules.
const mentions: IMentions = (content["m.mentions"] = {});
const userMentions = new Set<string>();
let roomMention = false;
// If there's a reply, initialize the mentioned users as the sender of that event.
if (replyToEvent) {
userMentions.add(replyToEvent.sender!.userId);
}
// If user provided content is available, check to see if any users are mentioned.
if (model) {
// Add any mentioned users in the current content.
for (const part of model.parts) {
if (part.type === Type.UserPill) {
userMentions.add(part.resourceId);
} else if (part.type === Type.AtRoomPill) {
roomMention = true;
}
}
}
// Ensure the *current* user isn't listed in the mentioned users.
userMentions.delete(sender);
// Finally, if this event is editing a previous event, only include users who
// were not previously mentioned and a room mention if the previous event was
// not a room mention.
if (editedContent) {
// First, the new event content gets the *full* set of users.
const newContent = content["m.new_content"];
const newMentions: IMentions = (newContent["m.mentions"] = {});
// Only include the users/room if there is any content.
if (userMentions.size) {
newMentions.user_ids = [...userMentions];
}
if (roomMention) {
newMentions.room = true;
}
// Fetch the mentions from the original event and remove any previously
// mentioned users.
const prevMentions = editedContent["m.mentions"];
if (Array.isArray(prevMentions?.user_ids)) {
prevMentions!.user_ids.forEach((userId) => userMentions.delete(userId));
}
// If the original event mentioned the room, nothing to do here.
if (prevMentions?.room) {
roomMention = false;
}
}
// Only include the users/room if there is any content.
if (userMentions.size) {
mentions.user_ids = [...userMentions];
}
if (roomMention) {
mentions.room = true;
}
}
// Merges favouring the given relation
export function attachRelation(content: IContent, relation?: IEventRelation): void {
if (relation) {
content["m.relates_to"] = {
...(content["m.relates_to"] || {}),
...relation,
};
}
}

View File

@@ -25,7 +25,7 @@ import ElectronPlatform from "./platform/ElectronPlatform";
import PWAPlatform from "./platform/PWAPlatform";
import WebPlatform from "./platform/WebPlatform";
import { initRageshake, initRageshakeStore } from "./rageshakesetup";
import ModuleApi from "../modules/Api.ts";
import { ModuleApi } from "../modules/Api.ts";
export const rageshakePromise = initRageshake();
@@ -145,7 +145,7 @@ export async function loadPlugins(): Promise<void> {
const modules = SdkConfig.get("modules");
if (!modules?.length) return;
const moduleLoader = new ModuleLoader(ModuleApi);
const moduleLoader = new ModuleLoader(ModuleApi.instance);
window.mxModuleLoader = moduleLoader;
for (const src of modules) {
// We need to instruct webpack to not mangle this import as it is not available at compile time

View File

@@ -17,7 +17,7 @@ import { UPDATE_EVENT } from "../../stores/AsyncStore";
import { percentageOf } from "../../../packages/shared-components/src/utils/numbers";
import { getKeyBindingsManager } from "../../KeyBindingsManager";
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
import { BaseViewModel } from "../base/BaseViewModel";
import { BaseViewModel } from "../../../packages/shared-components/src/viewmodel";
/**
* The number of seconds to skip when the user presses the left or right arrow keys.

View File

@@ -11,7 +11,7 @@ import { type EventTileTypeProps } from "../../events/EventTileFactory";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import { textForEvent } from "../../TextForEvent";
import { type TextualEventViewSnapshot } from "../../../packages/shared-components/src/event-tiles/TextualEventView/TextualEventView";
import { BaseViewModel } from "../base/BaseViewModel";
import { BaseViewModel } from "../../../packages/shared-components/src/viewmodel";
export class TextualEventViewModel extends BaseViewModel<TextualEventViewSnapshot, EventTileTypeProps> {
public constructor(props: EventTileTypeProps) {

View File

@@ -19,7 +19,7 @@ exports[`FilePanel renders empty state 1`] = `
</p>
</div>
<button
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"

View File

@@ -47,7 +47,7 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1
</button>
<button
aria-label="Threads"
aria-labelledby="«rg1»"
aria-labelledby="_r_g1_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -74,7 +74,7 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1
</button>
<button
aria-label="Room info"
aria-labelledby="«rg6»"
aria-labelledby="_r_g6_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -104,7 +104,7 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1
>
<div
aria-label="2 members"
aria-labelledby="«rgb»"
aria-labelledby="_r_gb_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -212,7 +212,7 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
</button>
<button
aria-label="Threads"
aria-labelledby="«rgj»"
aria-labelledby="_r_gj_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -239,7 +239,7 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
</button>
<button
aria-label="Room info"
aria-labelledby="«rgo»"
aria-labelledby="_r_go_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -269,7 +269,7 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
>
<div
aria-label="2 members"
aria-labelledby="«rgt»"
aria-labelledby="_r_gt_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -463,7 +463,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
</button>
<button
aria-label="Threads"
aria-labelledby="«rc1»"
aria-labelledby="_r_c1_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -490,7 +490,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
</button>
<button
aria-label="Room info"
aria-labelledby="«rc6»"
aria-labelledby="_r_c6_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -520,7 +520,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
>
<div
aria-label="2 members"
aria-labelledby="«rcb»"
aria-labelledby="_r_cb_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -639,7 +639,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
>
<svg
aria-label="Messages in this room are not end-to-end encrypted"
aria-labelledby="«rck»"
aria-labelledby="_r_ck_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
@@ -810,7 +810,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
</button>
<button
aria-label="Threads"
aria-labelledby="«re1»"
aria-labelledby="_r_e1_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -837,7 +837,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
</button>
<button
aria-label="Room info"
aria-labelledby="«re6»"
aria-labelledby="_r_e6_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -867,7 +867,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
>
<div
aria-label="2 members"
aria-labelledby="«reb»"
aria-labelledby="_r_eb_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -1231,7 +1231,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="«r2j»"
aria-labelledby="_r_2j_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -1247,7 +1247,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
<button
aria-disabled="false"
aria-label="Voice call"
aria-labelledby="«r2o»"
aria-labelledby="_r_2o_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1273,7 +1273,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Threads"
aria-labelledby="«r2t»"
aria-labelledby="_r_2t_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1300,7 +1300,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Room info"
aria-labelledby="«r32»"
aria-labelledby="_r_32_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1330,7 +1330,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
aria-label="0 members"
aria-labelledby="«r37»"
aria-labelledby="_r_37_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -1443,7 +1443,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="«r2j»"
aria-labelledby="_r_2j_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -1459,7 +1459,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
<button
aria-disabled="false"
aria-label="Voice call"
aria-labelledby="«r2o»"
aria-labelledby="_r_2o_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1485,7 +1485,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Threads"
aria-labelledby="«r2t»"
aria-labelledby="_r_2t_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1512,7 +1512,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Room info"
aria-labelledby="«r32»"
aria-labelledby="_r_32_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1542,7 +1542,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
aria-label="0 members"
aria-labelledby="«r37»"
aria-labelledby="_r_37_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -1610,7 +1610,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
tabindex="0"
>
<div
aria-labelledby="«r3m»"
aria-labelledby="_r_3m_"
class="mx_E2EIcon mx_E2EIcon_verified mx_MessageComposer_e2eIcon"
data-testid="e2e-icon"
>
@@ -1821,7 +1821,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</button>
<button
aria-label="Chat"
aria-labelledby="«r7l»"
aria-labelledby="_r_7l_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1848,7 +1848,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</button>
<button
aria-label="Threads"
aria-labelledby="«r7q»"
aria-labelledby="_r_7q_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1875,7 +1875,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</button>
<button
aria-label="Room info"
aria-labelledby="«r7v»"
aria-labelledby="_r_7v_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1905,7 +1905,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
>
<div
aria-label="0 members"
aria-labelledby="«r84»"
aria-labelledby="_r_84_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -1981,7 +1981,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</p>
</div>
<button
aria-labelledby="«r8d»"
aria-labelledby="_r_8d_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -2041,7 +2041,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
>
<svg
aria-label="Messages in this room are not end-to-end encrypted"
aria-labelledby="«r8m»"
aria-labelledby="_r_8m_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
<DocumentFragment>
@@ -58,7 +58,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
role="tree"
>
<li
aria-labelledby="«r8»"
aria-labelledby="_r_8_"
class="mx_SpaceHierarchy_roomTileWrapper"
role="treeitem"
>
@@ -88,7 +88,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_name"
>
<span
id="«r8»"
id="_r_8_"
>
Unnamed Room
</span>
@@ -122,7 +122,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="_container_1hel1_10"
>
<input
aria-labelledby="«r8»"
aria-labelledby="_r_8_"
class="_input_1hel1_18"
id="checkbox_MwbPDmfGtm"
role="presentation"
@@ -156,7 +156,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
</div>
</li>
<li
aria-labelledby="«rc»"
aria-labelledby="_r_c_"
class="mx_SpaceHierarchy_roomTileWrapper"
role="treeitem"
>
@@ -186,7 +186,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_name"
>
<span
id="«rc»"
id="_r_c_"
>
Unnamed Room
</span>
@@ -220,7 +220,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="_container_1hel1_10"
>
<input
aria-labelledby="«rc»"
aria-labelledby="_r_c_"
class="_input_1hel1_18"
id="checkbox_GQvdMWe954"
role="presentation"
@@ -254,7 +254,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
</div>
</li>
<li
aria-labelledby="«rg»"
aria-labelledby="_r_g_"
class="mx_SpaceHierarchy_roomTileWrapper"
role="treeitem"
>
@@ -284,7 +284,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_name"
>
<span
id="«rg»"
id="_r_g_"
>
Knock room
</span>
@@ -318,7 +318,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="_container_1hel1_10"
>
<input
aria-labelledby="«rg»"
aria-labelledby="_r_g_"
class="_input_1hel1_18"
id="checkbox_DVIAu5CsiH"
role="presentation"
@@ -353,7 +353,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
</li>
<li
aria-expanded="true"
aria-labelledby="«rk»"
aria-labelledby="_r_k_"
class="mx_SpaceHierarchy_roomTileWrapper"
role="treeitem"
>
@@ -383,7 +383,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_name"
>
<span
id="«rk»"
id="_r_k_"
>
Nested space
</span>
@@ -417,7 +417,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="_container_1hel1_10"
>
<input
aria-labelledby="«rk»"
aria-labelledby="_r_k_"
class="_input_1hel1_18"
id="checkbox_RD7nyrA2oh"
role="presentation"
@@ -458,7 +458,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
/>
</li>
<li
aria-labelledby="«ro»"
aria-labelledby="_r_o_"
class="mx_SpaceHierarchy_roomTileWrapper"
role="treeitem"
>
@@ -488,7 +488,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_name"
>
<span
id="«ro»"
id="_r_o_"
>
Nested room
</span>
@@ -510,7 +510,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
Join
</div>
<span
aria-labelledby="«rp»"
aria-labelledby="_r_p_"
tabindex="0"
>
<form
@@ -526,7 +526,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="_container_1hel1_10"
>
<input
aria-labelledby="«ro»"
aria-labelledby="_r_o_"
class="_input_1hel1_18"
disabled=""
id="checkbox_jWVJIPauy1"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ThreadPanel Header expect that All filter for ThreadPanelHeader properly renders Show: All threads 1`] = `
<DocumentFragment>
@@ -6,7 +6,7 @@ exports[`ThreadPanel Header expect that All filter for ThreadPanelHeader properl
class="mx_ThreadPanelHeader"
>
<button
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -45,7 +45,7 @@ exports[`ThreadPanel Header expect that My filter for ThreadPanelHeader properly
class="mx_ThreadPanelHeader"
>
<button
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"

View File

@@ -16,7 +16,7 @@ exports[`DecoratedRoomAvatar shows an avatar with globe icon and tooltip for pub
r
</span>
<div
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="mx_DecoratedRoomAvatar_icon mx_DecoratedRoomAvatar_icon_globe"
tabindex="0"
/>
@@ -40,7 +40,7 @@ exports[`DecoratedRoomAvatar shows the presence indicator in a DM room that also
r
</span>
<div
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="mx_DecoratedRoomAvatar_icon mx_DecoratedRoomAvatar_icon_online"
tabindex="0"
/>

View File

@@ -50,7 +50,7 @@ exports[`<RoomAvatarView /> should render a low priority room decoration 1`] = `
</span>
<svg
aria-label="This is a low priority room"
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="mx_RoomAvatarView_icon"
color="var(--cpd-color-icon-tertiary)"
fill="currentColor"
@@ -93,7 +93,7 @@ exports[`<RoomAvatarView /> should render a public room decoration 1`] = `
</span>
<svg
aria-label="This room is public"
aria-labelledby="«rc»"
aria-labelledby="_r_c_"
class="mx_RoomAvatarView_icon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
@@ -136,7 +136,7 @@ exports[`<RoomAvatarView /> should render a video room decoration 1`] = `
</span>
<svg
aria-label="This room is a video room"
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="mx_RoomAvatarView_icon"
color="var(--cpd-color-icon-tertiary)"
fill="currentColor"
@@ -179,7 +179,7 @@ exports[`<RoomAvatarView /> should render the AWAY presence 1`] = `
</span>
<svg
aria-label="Away"
aria-labelledby="«r14»"
aria-labelledby="_r_14_"
class="mx_RoomAvatarView_PresenceDecoration"
color="var(--cpd-color-icon-quaternary)"
fill="currentColor"
@@ -235,7 +235,7 @@ exports[`<RoomAvatarView /> should render the BUSY presence 1`] = `
</span>
<svg
aria-label="Busy"
aria-labelledby="«ru»"
aria-labelledby="_r_u_"
class="mx_RoomAvatarView_PresenceDecoration"
color="var(--cpd-color-icon-tertiary)"
fill="currentColor"
@@ -293,7 +293,7 @@ exports[`<RoomAvatarView /> should render the OFFLINE presence 1`] = `
</span>
<svg
aria-label="Offline"
aria-labelledby="«ro»"
aria-labelledby="_r_o_"
class="mx_RoomAvatarView_PresenceDecoration"
color="var(--cpd-color-icon-tertiary)"
fill="currentColor"
@@ -351,7 +351,7 @@ exports[`<RoomAvatarView /> should render the ONLINE presence 1`] = `
</span>
<svg
aria-label="Online"
aria-labelledby="«ri»"
aria-labelledby="_r_i_"
class="mx_RoomAvatarView_PresenceDecoration"
color="var(--cpd-color-icon-accent-primary)"
fill="currentColor"

View File

@@ -7,7 +7,7 @@ exports[`WithPresenceIndicator renders presence indicator with tooltip for DM ro
>
<span />
<div
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="mx_WithPresenceIndicator_icon mx_WithPresenceIndicator_icon_online"
style="width: 32px; height: 32px;"
tabindex="0"
@@ -23,7 +23,7 @@ exports[`WithPresenceIndicator renders presence indicator with tooltip for DM ro
>
<span />
<div
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="mx_WithPresenceIndicator_icon mx_WithPresenceIndicator_icon_offline"
style="width: 32px; height: 32px;"
tabindex="0"
@@ -39,7 +39,7 @@ exports[`WithPresenceIndicator renders presence indicator with tooltip for DM ro
>
<span />
<div
aria-labelledby="«rc»"
aria-labelledby="_r_c_"
class="mx_WithPresenceIndicator_icon mx_WithPresenceIndicator_icon_away"
style="width: 32px; height: 32px;"
tabindex="0"

View File

@@ -32,7 +32,7 @@ exports[`<BeaconListItem /> when a beacon is live and has locations renders beac
class="mx_BeaconListItem_interactions"
>
<a
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
data-testid="open-location-in-osm"
href="https://www.openstreetmap.org/?mlat=51&mlon=41#map=16/51/41"
rel="noreferrer noopener"

View File

@@ -72,7 +72,7 @@ exports[`<DialogSidebar /> renders sidebar correctly with beacons 1`] = `
class="mx_BeaconListItem_interactions"
>
<a
aria-labelledby="«r8»"
aria-labelledby="_r_8_"
data-testid="open-location-in-osm"
href="https://www.openstreetmap.org/?mlat=51&mlon=41#map=16/51/41"
rel="noreferrer noopener"

View File

@@ -3,7 +3,7 @@
exports[`<ShareLatestLocation /> renders share buttons when there is a location 1`] = `
<DocumentFragment>
<a
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
data-testid="open-location-in-osm"
href="https://www.openstreetmap.org/?mlat=51&mlon=42#map=16/51/42"
rel="noreferrer noopener"

View File

@@ -38,22 +38,22 @@ exports[`ConfirmRejectInviteDialog can reject with options selected 1`] = `
class="mx_SettingsFlag_label"
>
<div
id="mx_LabelledToggleSwitch_«r7»"
id="mx_LabelledToggleSwitch__r_7_"
>
Ignore user
</div>
<span
class="mx_Caption"
id="mx_LabelledToggleSwitch_«r7»_caption"
id="mx_LabelledToggleSwitch__r_7__caption"
>
You will not see any messages or room invites from this user.
</span>
</span>
<div
aria-checked="true"
aria-describedby="mx_LabelledToggleSwitch_«r7»_caption"
aria-describedby="mx_LabelledToggleSwitch__r_7__caption"
aria-disabled="false"
aria-labelledby="mx_LabelledToggleSwitch_«r7»"
aria-labelledby="mx_LabelledToggleSwitch__r_7_"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
role="switch"
tabindex="0"
@@ -70,22 +70,22 @@ exports[`ConfirmRejectInviteDialog can reject with options selected 1`] = `
class="mx_SettingsFlag_label"
>
<div
id="mx_LabelledToggleSwitch_«r8»"
id="mx_LabelledToggleSwitch__r_8_"
>
Report room
</div>
<span
class="mx_Caption"
id="mx_LabelledToggleSwitch_«r8»_caption"
id="mx_LabelledToggleSwitch__r_8__caption"
>
Report this room to your account provider.
</span>
</span>
<div
aria-checked="true"
aria-describedby="mx_LabelledToggleSwitch_«r8»_caption"
aria-describedby="mx_LabelledToggleSwitch__r_8__caption"
aria-disabled="false"
aria-labelledby="mx_LabelledToggleSwitch_«r8»"
aria-labelledby="mx_LabelledToggleSwitch__r_8_"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
role="switch"
tabindex="0"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<CreateRoomDialog /> for a private room should create a private room 1`] = `
<DocumentFragment>
@@ -98,7 +98,7 @@ exports[`<CreateRoomDialog /> for a private room should create a private room 1`
class="mx_SettingsFlag_label"
>
<div
id="mx_LabelledToggleSwitch_«r4m»"
id="mx_LabelledToggleSwitch__r_4m_"
>
Enable end-to-end encryption
</div>
@@ -106,7 +106,7 @@ exports[`<CreateRoomDialog /> for a private room should create a private room 1`
<div
aria-checked="true"
aria-disabled="false"
aria-labelledby="mx_LabelledToggleSwitch_«r4m»"
aria-labelledby="mx_LabelledToggleSwitch__r_4m_"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
role="switch"
tabindex="0"
@@ -134,7 +134,7 @@ exports[`<CreateRoomDialog /> for a private room should create a private room 1`
class="mx_SettingsFlag_label"
>
<div
id="mx_LabelledToggleSwitch_«r4n»"
id="mx_LabelledToggleSwitch__r_4n_"
>
Block anyone not part of server.org from ever joining this room.
</div>
@@ -142,7 +142,7 @@ exports[`<CreateRoomDialog /> for a private room should create a private room 1`
<div
aria-checked="false"
aria-disabled="false"
aria-labelledby="mx_LabelledToggleSwitch_«r4n»"
aria-labelledby="mx_LabelledToggleSwitch__r_4n_"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
role="switch"
tabindex="0"
@@ -292,7 +292,7 @@ exports[`<CreateRoomDialog /> for a private room should render not the advanced
class="mx_SettingsFlag_label"
>
<div
id="mx_LabelledToggleSwitch_«r54»"
id="mx_LabelledToggleSwitch__r_54_"
>
Enable end-to-end encryption
</div>
@@ -300,7 +300,7 @@ exports[`<CreateRoomDialog /> for a private room should render not the advanced
<div
aria-checked="true"
aria-disabled="false"
aria-labelledby="mx_LabelledToggleSwitch_«r54»"
aria-labelledby="mx_LabelledToggleSwitch__r_54_"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
role="switch"
tabindex="0"

View File

@@ -34,7 +34,7 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
>
Room ID: !id
<div
aria-describedby="«r2»"
aria-describedby="_r_2_"
aria-label="Copy"
class="mx_AccessibleButton mx_CopyableText_copyButton"
role="button"
@@ -206,7 +206,7 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
>
<label
class="_label_19upo_59"
for="radix-«r4»"
for="radix-_r_4_"
>
Element Call URL
</label>
@@ -215,7 +215,7 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
>
<input
class="_control_sqdq4_10"
id="radix-«r4»"
id="radix-_r_4_"
name="input"
title=""
value=""

View File

@@ -74,7 +74,7 @@ exports[`LogoutDialog Prompts user to go to settings if there is a backup on the
</details>
</div>
<div
aria-describedby="«rq»"
aria-describedby="_r_q_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"
@@ -163,7 +163,7 @@ exports[`LogoutDialog Prompts user to go to settings if there is no backup on th
</details>
</div>
<div
aria-describedby="«r10»"
aria-describedby="_r_10_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"

View File

@@ -76,7 +76,7 @@ exports[`<ManageRestrictedJoinRuleDialog /> should list spaces which are not par
class="_container_1hel1_10"
>
<input
aria-describedby="«r5»"
aria-describedby="_r_5_"
class="_input_1hel1_18"
id="checkbox_vY7Q4uEh9K"
type="checkbox"
@@ -126,7 +126,7 @@ exports[`<ManageRestrictedJoinRuleDialog /> should list spaces which are not par
</label>
<span
class="_message_19upo_85 _help-message_19upo_91"
id="«r5»"
id="_r_5_"
>
0 members
</span>

View File

@@ -103,7 +103,7 @@ exports[`<MessageEditHistory /> should match the snapshot 1`] = `
</div>
</div>
<div
aria-describedby="«r2»"
aria-describedby="_r_2_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"
@@ -318,7 +318,7 @@ exports[`<MessageEditHistory /> should support events with 1`] = `
</div>
</div>
<div
aria-describedby="«r8»"
aria-describedby="_r_8_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"

View File

@@ -44,7 +44,7 @@ exports[`ReportRoomDialog displays admin message 1`] = `
/>
<span
class="_message_19upo_85 _help-message_19upo_91"
id="radix-«r8»"
id="radix-_r_8_"
>
Report this room to your account provider. If the messages are encrypted, your admin will not be able to read them.
</span>
@@ -72,7 +72,7 @@ exports[`ReportRoomDialog displays admin message 1`] = `
class="mx_SettingsFlag_label"
>
<div
id="mx_LabelledToggleSwitch_«r9»"
id="mx_LabelledToggleSwitch__r_9_"
>
Leave room
</div>
@@ -80,7 +80,7 @@ exports[`ReportRoomDialog displays admin message 1`] = `
<div
aria-checked="false"
aria-disabled="false"
aria-labelledby="mx_LabelledToggleSwitch_«r9»"
aria-labelledby="mx_LabelledToggleSwitch__r_9_"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
role="switch"
tabindex="0"

View File

@@ -51,7 +51,7 @@ exports[`<ServerPickerDialog /> should render dialog 1`] = `
class="mx_StyledRadioButton_content"
>
<span
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="mx_Login_underlinedServerName"
tabindex="0"
>

View File

@@ -103,7 +103,7 @@ exports[`VerificationRequestDialog After we started verification here, says we a
Once accepted you'll be able to continue with the verification.
</div>
<div
aria-describedby="«r6»"
aria-describedby="_r_6_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"

View File

@@ -286,7 +286,7 @@ exports[`<RestoreKeyBackupDialog /> should render 1`] = `
</div>
</div>
<div
aria-describedby="«r2»"
aria-describedby="_r_2_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"
@@ -485,7 +485,7 @@ exports[`<RestoreKeyBackupDialog /> should restore key backup when the key is ca
</div>
</div>
<div
aria-describedby="«rk»"
aria-describedby="_r_k_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"
@@ -552,7 +552,7 @@ exports[`<RestoreKeyBackupDialog /> should restore key backup when the key is in
</div>
</div>
<div
aria-describedby="«rq»"
aria-describedby="_r_q_"
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AppTile destroys non-persisted right panel widget on room change 1`] = `
<DocumentFragment>
@@ -33,7 +33,7 @@ exports[`AppTile destroys non-persisted right panel widget on room change 1`] =
/>
</div>
<button
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -342,8 +342,8 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
<span>
Using this widget may share data
<div
aria-describedby="«r2n»"
aria-labelledby="«r2m»"
aria-describedby="_r_2n_"
aria-labelledby="_r_2m_"
class="mx_TextWithTooltip_target mx_TextWithTooltip_target--helpIcon"
>
<svg

View File

@@ -3,7 +3,7 @@
exports[`<FacePile /> renders with a tooltip 1`] = `
<DocumentFragment>
<div
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"

View File

@@ -21,7 +21,7 @@ exports[`<ImageView /> renders correctly 1`] = `
class="mx_ImageView_toolbar"
>
<div
aria-describedby="«r2»"
aria-describedby="_r_2_"
aria-label="Zoom out"
class="mx_AccessibleButton mx_ImageView_button mx_ImageView_button_zoomOut"
role="button"

View File

@@ -3,7 +3,7 @@
exports[`InfoTooltip should show tooltip on hover 1`] = `
<DocumentFragment>
<div
aria-describedby="«r2»"
aria-describedby="_r_2_"
class="mx_InfoTooltip"
tabindex="0"
>

View File

@@ -18,7 +18,7 @@ exports[`<LabelledCheckbox /> should render with byline of "this is a byline" 1`
class="_container_1hel1_10"
>
<input
aria-describedby="«r4»"
aria-describedby="_r_4_"
checked=""
class="_input_1hel1_18"
id="checkbox_vY7Q4uEh9K"
@@ -57,7 +57,7 @@ exports[`<LabelledCheckbox /> should render with byline of "this is a byline" 1`
</label>
<span
class="_message_19upo_85 _help-message_19upo_91"
id="«r4»"
id="_r_4_"
>
this is a byline
</span>

View File

@@ -3,8 +3,8 @@
exports[`<RoomFacePile /> renders 1`] = `
<DocumentFragment>
<div
aria-describedby="«r1»"
aria-labelledby="«r0»"
aria-describedby="_r_1_"
aria-labelledby="_r_0_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"

View File

@@ -7,7 +7,7 @@ exports[`<SettingsDropdown /> should render a disabled setting 1`] = `
>
<label
class="mx_SettingsDropdown_label"
for="«r0»"
for="_r_0_"
>
<span
class="mx_SettingsDropdown_labelText"
@@ -19,12 +19,12 @@ exports[`<SettingsDropdown /> should render a disabled setting 1`] = `
class="mx_Dropdown mx_Dropdown_disabled"
>
<div
aria-describedby="«r0»_value"
aria-describedby="_r_0__value"
aria-disabled="true"
aria-expanded="false"
aria-haspopup="listbox"
aria-label="Open %(brand)s when you log in to your computer"
aria-owns="«r0»_input"
aria-owns="_r_0__input"
class="mx_AccessibleButton mx_Dropdown_input mx_no_textinput mx_AccessibleButton_disabled"
disabled=""
role="button"
@@ -32,7 +32,7 @@ exports[`<SettingsDropdown /> should render a disabled setting 1`] = `
>
<div
class="mx_Dropdown_option"
id="«r0»_value"
id="_r_0__value"
>
<div>
No

View File

@@ -10,7 +10,7 @@ exports[`<SettingsField /> should render with the default label 1`] = `
>
<label
class="_label_19upo_59"
for="radix-«r0»"
for="radix-_r_0_"
>
Element Call URL
</label>
@@ -19,7 +19,7 @@ exports[`<SettingsField /> should render with the default label 1`] = `
>
<input
class="_control_sqdq4_10"
id="radix-«r0»"
id="radix-_r_0_"
name="input"
title=""
value=""

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<LocationShareMenu /> with live location disabled goes to labs flag screen after live options is clicked 1`] = `
<div
@@ -26,7 +26,7 @@ exports[`<LocationShareMenu /> with live location disabled goes to labs flag scr
class="mx_SettingsFlag_label"
>
<div
id="mx_LabelledToggleSwitch_«r0»"
id="mx_LabelledToggleSwitch__r_0_"
>
Enable live location sharing
</div>
@@ -34,7 +34,7 @@ exports[`<LocationShareMenu /> with live location disabled goes to labs flag scr
<div
aria-checked="false"
aria-disabled="false"
aria-labelledby="mx_LabelledToggleSwitch_«r0»"
aria-labelledby="mx_LabelledToggleSwitch__r_0_"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
role="switch"
tabindex="0"

View File

@@ -32,7 +32,7 @@ exports[`<LocationViewDialog /> renders map correctly 1`] = `
class="mx_ZoomButtons"
>
<div
aria-describedby="«r6»"
aria-describedby="_r_6_"
aria-label="Zoom in"
class="mx_AccessibleButton mx_ZoomButtons_button"
data-testid="map-zoom-in-button"

View File

@@ -34,7 +34,7 @@ exports[`MLocationBody <MLocationBody> without error renders map correctly 1`] =
class="mx_MLocationBody"
>
<div
aria-labelledby="«ri»"
aria-labelledby="_r_i_"
class="mx_MLocationBody_map"
>
<div
@@ -76,7 +76,7 @@ exports[`MLocationBody <MLocationBody> without error renders marker correctly fo
class="mx_MLocationBody"
>
<div
aria-labelledby="«ru»"
aria-labelledby="_r_u_"
class="mx_MLocationBody_map"
>
<div

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<PollHistory /> Poll detail displays poll detail on active poll list item click 1`] = `
<h2
@@ -91,7 +91,7 @@ exports[`<PollHistory /> renders a list of active polls when there are polls in
tabindex="0"
>
<div
aria-labelledby="«ra»"
aria-labelledby="_r_a_"
class="mx_PollListItem_content"
>
<span>
@@ -116,7 +116,7 @@ exports[`<PollHistory /> renders a list of active polls when there are polls in
tabindex="0"
>
<div
aria-labelledby="«rf»"
aria-labelledby="_r_f_"
class="mx_PollListItem_content"
>
<span>

View File

@@ -10,7 +10,7 @@ exports[`<PollListItem /> renders a poll 1`] = `
tabindex="0"
>
<div
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="mx_PollListItem_content"
>
<span>

View File

@@ -10,7 +10,7 @@ exports[`<PollListItemEnded /> renders a poll with no responses 1`] = `
tabindex="0"
>
<div
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="mx_PollListItemEnded_content"
>
<div

View File

@@ -19,7 +19,7 @@ exports[`<BaseCard /> should close when clicking X button 1`] = `
</p>
</div>
<button
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"

View File

@@ -19,7 +19,7 @@ exports[`<ExtensionsCard /> should render empty state 1`] = `
</p>
</div>
<button
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -120,7 +120,7 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
</p>
</div>
<button
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<PinnedMessagesCard /> should show the empty state when there are no pins 1`] = `
<DocumentFragment>
@@ -19,7 +19,7 @@ exports[`<PinnedMessagesCard /> should show the empty state when there are no pi
</p>
</div>
<button
aria-labelledby="«rf»"
aria-labelledby="_r_f_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -101,7 +101,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
</p>
</div>
<button
aria-labelledby="«rl»"
aria-labelledby="_r_l_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -159,13 +159,13 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
class="mx_PinnedEventTile_top"
>
<span
aria-labelledby="«rs»"
aria-labelledby="_r_s_"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
<button
aria-describedby="«rr»"
aria-describedby="_r_r_"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
@@ -173,7 +173,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r11»"
id="radix-_r_11_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -199,7 +199,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
</div>
<div
class="mx_MTextBody mx_EventTile_content"
id="«rr»"
id="_r_r_"
>
<div
class="mx_EventTile_body translate"
@@ -240,13 +240,13 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
class="mx_PinnedEventTile_top"
>
<span
aria-labelledby="«r14»"
aria-labelledby="_r_14_"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
<button
aria-describedby="«r13»"
aria-describedby="_r_13_"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
@@ -254,7 +254,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r19»"
id="radix-_r_19_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -280,7 +280,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
</div>
<div
class="mx_MTextBody mx_EventTile_content"
id="«r13»"
id="_r_13_"
>
<div
class="mx_EventTile_body translate"
@@ -329,7 +329,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
</p>
</div>
<button
aria-labelledby="«r10f»"
aria-labelledby="_r_10f_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -387,13 +387,13 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
class="mx_PinnedEventTile_top"
>
<span
aria-labelledby="«r10m»"
aria-labelledby="_r_10m_"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
<button
aria-describedby="«r10l»"
aria-describedby="_r_10l_"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
@@ -401,7 +401,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r10r»"
id="radix-_r_10r_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -427,7 +427,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
</div>
<div
class="mx_MTextBody mx_EventTile_content"
id="«r10l»"
id="_r_10l_"
>
<div
class="mx_EventTile_body translate"
@@ -468,13 +468,13 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
class="mx_PinnedEventTile_top"
>
<span
aria-labelledby="«r10u»"
aria-labelledby="_r_10u_"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
<button
aria-describedby="«r10t»"
aria-describedby="_r_10t_"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
@@ -482,7 +482,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r113»"
id="radix-_r_113_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -508,7 +508,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
</div>
<div
class="mx_MTextBody mx_EventTile_content"
id="«r10t»"
id="_r_10t_"
>
<div
class="mx_EventTile_body translate"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<RoomSummaryCard /> has button to edit topic 1`] = `
<div>
@@ -15,7 +15,7 @@ exports[`<RoomSummaryCard /> has button to edit topic 1`] = `
class="mx_BaseCard_header_spacer"
/>
<button
aria-labelledby="«re»"
aria-labelledby="_r_e_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -210,7 +210,7 @@ exports[`<RoomSummaryCard /> has button to edit topic 1`] = `
<input
aria-hidden="true"
class="_input_19o42_24"
id="«rj»"
id="_r_j_"
role="switch"
type="checkbox"
/>
@@ -728,7 +728,7 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
class="mx_BaseCard_header_spacer"
/>
<button
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -885,7 +885,7 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
<input
aria-hidden="true"
class="_input_19o42_24"
id="«r5»"
id="_r_5_"
role="switch"
type="checkbox"
/>
@@ -1403,7 +1403,7 @@ exports[`<RoomSummaryCard /> renders the room topic in the summary 1`] = `
class="mx_BaseCard_header_spacer"
/>
<button
aria-labelledby="«r7»"
aria-labelledby="_r_7_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -1598,7 +1598,7 @@ exports[`<RoomSummaryCard /> renders the room topic in the summary 1`] = `
<input
aria-hidden="true"
class="_input_19o42_24"
id="«rc»"
id="_r_c_"
role="switch"
type="checkbox"
/>

View File

@@ -19,7 +19,7 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
</p>
</div>
<button
aria-labelledby="«r7c»"
aria-labelledby="_r_7c_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -306,7 +306,7 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
</p>
</div>
<button
aria-labelledby="«r7m»"
aria-labelledby="_r_7m_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
<DocumentFragment>
@@ -56,7 +56,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="«r14k»"
aria-labelledby="_r_14k_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -72,7 +72,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
<button
aria-disabled="false"
aria-label="Voice call"
aria-labelledby="«r14p»"
aria-labelledby="_r_14p_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -98,7 +98,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</button>
<button
aria-label="Threads"
aria-labelledby="«r14u»"
aria-labelledby="_r_14u_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -125,7 +125,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</button>
<button
aria-label="Room info"
aria-labelledby="«r153»"
aria-labelledby="_r_153_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"

View File

@@ -3,7 +3,7 @@
exports[`<VideoRoomChatButton /> renders button with an unread marker when room is unread 1`] = `
<button
aria-label="Chat"
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8"
data-indicator="default"
data-kind="primary"

View File

@@ -25,7 +25,7 @@ exports[`<RoomListHeaderView /> compose menu should display the compose menu 1`]
class="_icon-button_1pz9o_8 mx_SpaceMenu_button"
data-kind="primary"
data-state="closed"
id="radix-«rk»"
id="radix-_r_k_"
role="button"
style="--cpd-icon-button-size: 20px;"
tabindex="0"
@@ -63,11 +63,11 @@ exports[`<RoomListHeaderView /> compose menu should display the compose menu 1`]
aria-expanded="false"
aria-haspopup="menu"
aria-label="Room Options"
aria-labelledby="«rs»"
aria-labelledby="_r_s_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«rq»"
id="radix-_r_q_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -104,7 +104,7 @@ exports[`<RoomListHeaderView /> compose menu should display the compose menu 1`]
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r15»"
id="radix-_r_15_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -164,7 +164,7 @@ exports[`<RoomListHeaderView /> compose menu should not display the compose menu
class="_icon-button_1pz9o_8 mx_SpaceMenu_button"
data-kind="primary"
data-state="closed"
id="radix-«r18»"
id="radix-_r_18_"
role="button"
style="--cpd-icon-button-size: 20px;"
tabindex="0"
@@ -202,11 +202,11 @@ exports[`<RoomListHeaderView /> compose menu should not display the compose menu
aria-expanded="false"
aria-haspopup="menu"
aria-label="Room Options"
aria-labelledby="«r1g»"
aria-labelledby="_r_1g_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r1e»"
id="radix-_r_1e_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -297,7 +297,7 @@ exports[`<RoomListHeaderView /> should render 'room options' button 1`] = `
class="_icon-button_1pz9o_8 mx_SpaceMenu_button"
data-kind="primary"
data-state="closed"
id="radix-«r0»"
id="radix-_r_0_"
role="button"
style="--cpd-icon-button-size: 20px;"
tabindex="0"
@@ -335,11 +335,11 @@ exports[`<RoomListHeaderView /> should render 'room options' button 1`] = `
aria-expanded="false"
aria-haspopup="menu"
aria-label="Room Options"
aria-labelledby="«r8»"
aria-labelledby="_r_8_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r6»"
id="radix-_r_6_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -376,7 +376,7 @@ exports[`<RoomListHeaderView /> should render 'room options' button 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«rh»"
id="radix-_r_h_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -436,7 +436,7 @@ exports[`<RoomListHeaderView /> space menu should display the space menu 1`] = `
class="_icon-button_1pz9o_8 mx_SpaceMenu_button"
data-kind="primary"
data-state="closed"
id="radix-«r3g»"
id="radix-_r_3g_"
role="button"
style="--cpd-icon-button-size: 20px;"
tabindex="0"
@@ -474,11 +474,11 @@ exports[`<RoomListHeaderView /> space menu should display the space menu 1`] = `
aria-expanded="false"
aria-haspopup="menu"
aria-label="Room Options"
aria-labelledby="«r3o»"
aria-labelledby="_r_3o_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r3m»"
id="radix-_r_3m_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -515,7 +515,7 @@ exports[`<RoomListHeaderView /> space menu should display the space menu 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r41»"
id="radix-_r_41_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -581,11 +581,11 @@ exports[`<RoomListHeaderView /> space menu should not display the space menu 1`]
aria-expanded="false"
aria-haspopup="menu"
aria-label="Room Options"
aria-labelledby="«r4a»"
aria-labelledby="_r_4a_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r48»"
id="radix-_r_48_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@@ -622,7 +622,7 @@ exports[`<RoomListHeaderView /> space menu should not display the space menu 1`]
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r4j»"
id="radix-_r_4j_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"

View File

@@ -11,11 +11,11 @@ exports[`<RoomListItemMenuView /> should render the more options menu 1`] = `
aria-expanded="false"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="«r2»"
aria-labelledby="_r_2_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r0»"
id="radix-_r_0_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -44,11 +44,11 @@ exports[`<RoomListItemMenuView /> should render the more options menu 1`] = `
aria-expanded="false"
aria-haspopup="menu"
aria-label="Notification options"
aria-labelledby="«r9»"
aria-labelledby="_r_9_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r7»"
id="radix-_r_7_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -90,11 +90,11 @@ exports[`<RoomListItemMenuView /> should render the notification options menu 1`
aria-expanded="false"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="«ri»"
aria-labelledby="_r_i_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«rg»"
id="radix-_r_g_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -123,11 +123,11 @@ exports[`<RoomListItemMenuView /> should render the notification options menu 1`
aria-expanded="false"
aria-haspopup="menu"
aria-label="Notification options"
aria-labelledby="«rp»"
aria-labelledby="_r_p_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«rn»"
id="radix-_r_n_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"

View File

@@ -7,11 +7,11 @@ exports[`<RoomListOptionsMenu /> should match snapshot 1`] = `
aria-expanded="false"
aria-haspopup="menu"
aria-label="Room Options"
aria-labelledby="«r2»"
aria-labelledby="_r_2_"
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r0»"
id="radix-_r_0_"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"

View File

@@ -10,7 +10,7 @@ exports[`<RoomListPrimaryFilters /> should renders all filters correctly 1`] = `
<div
aria-label="Room list filters"
class="flex mx_RoomListPrimaryFilters_list"
id="«r0»"
id="_r_0_"
role="listbox"
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-2x); --mx-flex-wrap: wrap;"
>

View File

@@ -16,7 +16,7 @@ import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
import RoomPreviewBar from "../../../../../src/components/views/rooms/RoomPreviewBar";
import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
import ModuleApi from "../../../../../src/modules/Api.ts";
import { ModuleApi } from "../../../../../src/modules/Api.ts";
jest.mock("../../../../../src/IdentityAuthClient", () => {
return jest.fn().mockImplementation(() => {
@@ -500,7 +500,7 @@ describe("<RoomPreviewBar />", () => {
});
it("should render Module roomPreviewBarRenderer if specified", () => {
jest.spyOn(ModuleApi.customComponents, "roomPreviewBarRenderer", "get").mockReturnValue(() => (
jest.spyOn(ModuleApi.instance.customComponents, "roomPreviewBarRenderer", "get").mockReturnValue(() => (
<>Test component</>
));
const { getByText } = render(<RoomPreviewBar />);

View File

@@ -8,12 +8,11 @@ Please see LICENSE files in the repository root for full details.
import React from "react";
import { fireEvent, render, waitFor } from "jest-matrix-react";
import { type IContent, type MatrixClient, MsgType } from "matrix-js-sdk/src/matrix";
import { type MatrixClient, MsgType } from "matrix-js-sdk/src/matrix";
import { mocked } from "jest-mock";
import userEvent from "@testing-library/user-event";
import SendMessageComposer, {
attachMentions,
createMessageContent,
isQuickReaction,
} from "../../../../../src/components/views/rooms/SendMessageComposer";
@@ -157,186 +156,6 @@ describe("<SendMessageComposer/>", () => {
});
});
describe("attachMentions", () => {
const partsCreator = createPartCreator();
it("no mentions", () => {
const model = new EditorModel([], partsCreator);
const content: IContent = {};
attachMentions("@alice:test", content, model, undefined);
expect(content).toEqual({
"m.mentions": {},
});
});
it("test user mentions", () => {
const model = new EditorModel([partsCreator.userPill("Bob", "@bob:test")], partsCreator);
const content: IContent = {};
attachMentions("@alice:test", content, model, undefined);
expect(content).toEqual({
"m.mentions": { user_ids: ["@bob:test"] },
});
});
it("test reply", () => {
// Replying to an event adds the sender to the list of mentioned users.
const model = new EditorModel([], partsCreator);
let replyToEvent = mkEvent({
type: "m.room.message",
user: "@bob:test",
room: "!abc:test",
content: { "m.mentions": {} },
event: true,
});
let content: IContent = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"m.mentions": { user_ids: ["@bob:test"] },
});
// It no longer adds any other mentioned users
replyToEvent = mkEvent({
type: "m.room.message",
user: "@bob:test",
room: "!abc:test",
content: { "m.mentions": { user_ids: ["@alice:test", "@charlie:test"] } },
event: true,
});
content = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"m.mentions": { user_ids: ["@bob:test"] },
});
});
it("test room mention", () => {
const model = new EditorModel([partsCreator.atRoomPill("@room")], partsCreator);
const content: IContent = {};
attachMentions("@alice:test", content, model, undefined);
expect(content).toEqual({
"m.mentions": { room: true },
});
});
it("test reply to room mention", () => {
// Replying to a room mention shouldn't automatically be a room mention.
const model = new EditorModel([], partsCreator);
const replyToEvent = mkEvent({
type: "m.room.message",
user: "@alice:test",
room: "!abc:test",
content: { "m.mentions": { room: true } },
event: true,
});
const content: IContent = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"m.mentions": {},
});
});
it("test broken mentions", () => {
// Replying to a room mention shouldn't automatically be a room mention.
const model = new EditorModel([], partsCreator);
const replyToEvent = mkEvent({
type: "m.room.message",
user: "@alice:test",
room: "!abc:test",
// @ts-ignore - Purposefully testing invalid data.
content: { "m.mentions": { user_ids: "@bob:test" } },
event: true,
});
const content: IContent = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"m.mentions": {},
});
});
describe("attachMentions with edit", () => {
it("no mentions", () => {
const model = new EditorModel([], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = {};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"m.mentions": {},
"m.new_content": { "m.mentions": {} },
});
});
it("mentions do not propagate", () => {
const model = new EditorModel([], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = {
"m.mentions": { user_ids: ["@bob:test"], room: true },
};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"m.mentions": {},
"m.new_content": { "m.mentions": {} },
});
});
it("test user mentions", () => {
const model = new EditorModel([partsCreator.userPill("Bob", "@bob:test")], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = {};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"m.mentions": { user_ids: ["@bob:test"] },
"m.new_content": { "m.mentions": { user_ids: ["@bob:test"] } },
});
});
it("test prev user mentions", () => {
const model = new EditorModel([partsCreator.userPill("Bob", "@bob:test")], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = { "m.mentions": { user_ids: ["@bob:test"] } };
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"m.mentions": {},
"m.new_content": { "m.mentions": { user_ids: ["@bob:test"] } },
});
});
it("test room mention", () => {
const model = new EditorModel([partsCreator.atRoomPill("@room")], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = {};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"m.mentions": { room: true },
"m.new_content": { "m.mentions": { room: true } },
});
});
it("test prev room mention", () => {
const model = new EditorModel([partsCreator.atRoomPill("@room")], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = { "m.mentions": { room: true } };
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"m.mentions": {},
"m.new_content": { "m.mentions": { room: true } },
});
});
it("test broken mentions", () => {
// Replying to a room mention shouldn't automatically be a room mention.
const model = new EditorModel([], partsCreator);
const content: IContent = { "m.new_content": {} };
// @ts-ignore - Purposefully testing invalid data.
const prevContent: IContent = { "m.mentions": { user_ids: "@bob:test" } };
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"m.mentions": {},
"m.new_content": { "m.mentions": {} },
});
});
});
});
describe("functions correctly mounted", () => {
const mockClient = createTestClient();
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mockClient);

View File

@@ -25,13 +25,13 @@ exports[`<PinnedEventTile /> should render pinned event 1`] = `
class="mx_PinnedEventTile_top"
>
<span
aria-labelledby="«r1»"
aria-labelledby="_r_1_"
class="mx_PinnedEventTile_sender mx_Username_color2"
>
@alice:server.org
</span>
<button
aria-describedby="«r0»"
aria-describedby="_r_0_"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
@@ -39,7 +39,7 @@ exports[`<PinnedEventTile /> should render pinned event 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«r6»"
id="radix-_r_6_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -65,7 +65,7 @@ exports[`<PinnedEventTile /> should render pinned event 1`] = `
</div>
<div
class="mx_MTextBody mx_EventTile_content"
id="«r0»"
id="_r_0_"
>
<div
class="mx_EventTile_body translate"
@@ -104,13 +104,13 @@ exports[`<PinnedEventTile /> should render pinned event with thread info 1`] = `
class="mx_PinnedEventTile_top"
>
<span
aria-labelledby="«ra»"
aria-labelledby="_r_a_"
class="mx_PinnedEventTile_sender mx_Username_color2"
>
@alice:server.org
</span>
<button
aria-describedby="«r9»"
aria-describedby="_r_9_"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
@@ -118,7 +118,7 @@ exports[`<PinnedEventTile /> should render pinned event with thread info 1`] = `
class="_icon-button_1pz9o_8"
data-kind="primary"
data-state="closed"
id="radix-«rf»"
id="radix-_r_f_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
@@ -144,7 +144,7 @@ exports[`<PinnedEventTile /> should render pinned event with thread info 1`] = `
</div>
<div
class="mx_MTextBody mx_EventTile_content"
id="«r9»"
id="_r_9_"
>
<div
class="mx_EventTile_body translate"
@@ -187,7 +187,7 @@ exports[`<PinnedEventTile /> should render pinned event with thread info 1`] = `
exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
<div
aria-label="Open menu"
aria-labelledby="radix-«r14»"
aria-labelledby="radix-_r_14_"
aria-orientation="vertical"
class="_menu_1glhz_8"
data-align="start"
@@ -196,7 +196,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
data-side="right"
data-state="open"
dir="ltr"
id="radix-«r15»"
id="radix-_r_15_"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1"
@@ -378,7 +378,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`] = `
<div
aria-label="Open menu"
aria-labelledby="radix-«ro»"
aria-labelledby="radix-_r_o_"
aria-orientation="vertical"
class="_menu_1glhz_8"
data-align="start"
@@ -387,7 +387,7 @@ exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`]
data-side="right"
data-state="open"
dir="ltr"
id="radix-«rp»"
id="radix-_r_p_"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1"

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<PinnedMessageBanner /> should display display a poll event 1`] = `
<DocumentFragment>
@@ -10,14 +10,14 @@ exports[`<PinnedMessageBanner /> should display display a poll event 1`] = `
role="region"
>
<button
aria-describedby="«ra»"
aria-describedby="_r_a_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«ra»"
id="_r_a_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -68,14 +68,14 @@ exports[`<PinnedMessageBanner /> should display the last message when the pinned
role="region"
>
<button
aria-describedby="«r4»"
aria-describedby="_r_4_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r4»"
id="_r_4_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -150,14 +150,14 @@ exports[`<PinnedMessageBanner /> should display the m.audio event type 1`] = `
role="region"
>
<button
aria-describedby="«r7»"
aria-describedby="_r_7_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r7»"
id="_r_7_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -208,14 +208,14 @@ exports[`<PinnedMessageBanner /> should display the m.file event type 1`] = `
role="region"
>
<button
aria-describedby="«r6»"
aria-describedby="_r_6_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r6»"
id="_r_6_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -266,14 +266,14 @@ exports[`<PinnedMessageBanner /> should display the m.image event type 1`] = `
role="region"
>
<button
aria-describedby="«r9»"
aria-describedby="_r_9_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r9»"
id="_r_9_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -324,14 +324,14 @@ exports[`<PinnedMessageBanner /> should display the m.video event type 1`] = `
role="region"
>
<button
aria-describedby="«r8»"
aria-describedby="_r_8_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r8»"
id="_r_8_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -382,14 +382,14 @@ exports[`<PinnedMessageBanner /> should render 2 pinned event 1`] = `
role="region"
>
<button
aria-describedby="«r2»"
aria-describedby="_r_2_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r2»"
id="_r_2_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -460,14 +460,14 @@ exports[`<PinnedMessageBanner /> should render 4 pinned event 1`] = `
role="region"
>
<button
aria-describedby="«r3»"
aria-describedby="_r_3_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r3»"
id="_r_3_"
>
<div
class="mx_PinnedMessageBanner_Indicators"
@@ -542,14 +542,14 @@ exports[`<PinnedMessageBanner /> should render a single pinned event 1`] = `
role="region"
>
<button
aria-describedby="«r1»"
aria-describedby="_r_1_"
aria-label="View the pinned message in the timeline and the newest pinned message here"
class="mx_PinnedMessageBanner_main"
type="button"
>
<div
class="mx_PinnedMessageBanner_content"
id="«r1»"
id="_r_1_"
>
<div
class="mx_PinnedMessageBanner_Indicators"

View File

@@ -4,7 +4,7 @@ exports[`ReadReceiptGroup <ReadReceiptPerson /> should display a tooltip 1`] = `
<div
class="_tooltip_6ode6_8"
data-floating-ui-focusable=""
id="«r6»"
id="_r_6_"
role="tooltip"
style="position: absolute; left: 0px; top: 0px; transform: translate(0px, 0px);"
tabindex="-1"
@@ -22,7 +22,7 @@ exports[`ReadReceiptGroup <ReadReceiptPerson /> should display a tooltip 1`] = `
stroke="none"
/>
<clippath
id="«r9»"
id="_r_9_"
>
<rect
height="10"
@@ -33,13 +33,13 @@ exports[`ReadReceiptGroup <ReadReceiptPerson /> should display a tooltip 1`] = `
</clippath>
</svg>
<span
id="«r4»"
id="_r_4_"
>
Alice
</span>
<span
class="_caption_6ode6_28 cpd-theme-dark"
id="«r5»"
id="_r_5_"
>
@alice:example.org
</span>

View File

@@ -19,7 +19,7 @@ exports[`<ThirdPartyMemberInfo /> should render invite 1`] = `
</p>
</div>
<button
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -94,7 +94,7 @@ exports[`<ThirdPartyMemberInfo /> should render invite when room in not availabl
</p>
</div>
<button
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"

Some files were not shown because too many files have changed in this diff Show More