Merge branch 'develop' into dbkr/module_api_additions_2

This commit is contained in:
David Baker 2025-10-15 11:49:40 +01:00 committed by GitHub
commit 97f345651d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 1372 additions and 884 deletions

View File

@ -44,7 +44,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
# Disable cache on Windows as it is slower than not caching
# https://github.com/actions/setup-node/issues/975

View File

@ -28,7 +28,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"

View File

@ -132,7 +132,7 @@ jobs:
cosign sign --yes ${images}
- name: Update repo description
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5
if: github.event_name != 'pull_request'
continue-on-error: true
with:
@ -141,7 +141,7 @@ jobs:
repository: vectorim/element-web
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3
uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4
if: github.event_name != 'pull_request'
with:
repository: element-hq/element-web-pro

View File

@ -33,7 +33,7 @@ jobs:
repository: matrix-org/matrix-js-sdk
path: matrix-js-sdk
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
cache-dependency-path: element-web/yarn.lock

View File

@ -54,7 +54,7 @@ jobs:
with:
repository: element-hq/element-web
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"
@ -133,7 +133,7 @@ jobs:
name: webapp
path: webapp
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
cache-dependency-path: yarn.lock
@ -200,7 +200,7 @@ jobs:
persist-credentials: false
repository: element-hq/element-web
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
if: inputs.skip != true
with:
cache: "yarn"

View File

@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: 🔧 Set up node environment
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version-file: ".node-version"

View File

@ -26,7 +26,7 @@ jobs:
persist-credentials: false
repository: element-hq/element-web
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"

View File

@ -24,7 +24,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"
@ -79,7 +79,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"
@ -107,7 +107,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"
@ -125,7 +125,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"
@ -143,7 +143,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"

View File

@ -44,7 +44,7 @@ jobs:
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
- name: Yarn cache
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
node-version: "lts/*"
cache: "yarn"

View File

@ -12,7 +12,7 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10
with:
operations-per-run: 100

View File

@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
cache: "yarn"
node-version: "lts/*"

View File

@ -1,7 +1,7 @@
# syntax=docker.io/docker/dockerfile:1.18-labs@sha256:79cdc14e1c220efb546ad14a8ebc816e3277cd72d27195ced5bebdd226dd1025
# syntax=docker.io/docker/dockerfile:1.19-labs@sha256:dce1c693ef318bca08c964ba3122ae6248e45a1b96d65c4563c8dc6fe80349a2
# Builder
FROM --platform=$BUILDPLATFORM node:22-bullseye@sha256:5e638ea282ab9f0224949e8cfc7bb4621710e5d21b19fc3cf6e8884fcb5839f0 AS builder
FROM --platform=$BUILDPLATFORM node:22-bullseye@sha256:cd951bb228ddf85882951d4bf4acefc5314eb2eb66eee002256f4bb17c2293e3 AS builder
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
ARG USE_CUSTOM_SDKS=false
@ -19,7 +19,7 @@ RUN /src/scripts/docker-package.sh
RUN cp /src/config.sample.json /src/webapp/config.json
# App
FROM nginxinc/nginx-unprivileged:alpine-slim@sha256:13d1e0acc26b7ce8a40d155473759387e04d1433e73726d4bb49c67bdb197fe5
FROM nginxinc/nginx-unprivileged:alpine-slim@sha256:304079937327a6490d5c89df47c8951d76f05b346d4c6e3b10cba2e266cd4904
# Need root user to install packages & manipulate the usr directory
USER root

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"],

View File

@ -69,12 +69,12 @@
},
"resolutions": {
"**/pretty-format/react-is": "19.1.1",
"@playwright/test": "1.54.2",
"@playwright/test": "1.56.0",
"@types/react": "19.1.14",
"@types/react-dom": "19.1.9",
"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"
@ -137,7 +137,7 @@
"opus-recorder": "^8.0.3",
"pako": "^2.0.3",
"png-chunks-extract": "^1.0.0",
"posthog-js": "1.268.6",
"posthog-js": "1.275.1",
"qrcode": "1.5.4",
"re-resizable": "6.11.2",
"react": "^19.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",
@ -239,11 +240,11 @@
"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-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",
@ -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",

View File

@ -10,7 +10,7 @@ import {
type StartedPostgreSqlContainer,
} from "@element-hq/element-web-playwright-common/lib/testcontainers";
const TAG = "main@sha256:8d74c051ec783bb7d14a61f1d3633236bd59c4317d4ca05a5c1fe4bba10495f1";
const TAG = "main@sha256:0a72a3ecb38e961e45062de91a9afa6d8f7319ddba460b8141b4e6a1bab45ea1";
/**
* MatrixAuthenticationServiceContainer which freezes the docker digest to

View File

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
import { SynapseContainer as BaseSynapseContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers";
const TAG = "develop@sha256:fd9056211bca90e96d50141997779e13194825dbdee750166078ed811d7c0228";
const TAG = "develop@sha256:51e3ca5c351669569a945ad3cbfd11c803d19f7c32bdf6727ccffb3808a61a97";
/**
* SynapseContainer which freezes the docker digest to stabilise tests,

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.sources=src,res,packages/shared-components/src
sonar.tests=test,playwright,src
sonar.test.inclusions=test/*,playwright/*,src/**/*.test.*
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

@ -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

@ -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

@ -2663,6 +2663,7 @@
"allow_spellcheck": "Autoriser la vérification orthographique",
"application_language": "Langue de l'application",
"application_language_reload_hint": "Lapplication se rechargera après avoir sélectionné une autre langue",
"avatar_open_menu": "Ouvrir le menu de l'avatar",
"avatar_remove_progress": "Suppression de l'image...",
"avatar_save_progress": "Chargement de l'image...",
"avatar_upload_error_text": "Le format de fichier n'est pas pris en charge ou l'image est plus grande que%(size)s.",
@ -2889,6 +2890,7 @@
"room_list_heading": "Liste de salons",
"show_avatars_pills": "Afficher les avatars dans les mentions d'utilisateur, de salon et dévènements",
"show_polls_button": "Afficher le bouton des sondages",
"startup_window_behaviour_label": "Comportement au démarrage et de la fenêtre",
"surround_text": "Entourer le texte sélectionné lors de la saisie de certains caractères",
"time_heading": "Affichage de lheure",
"user_timezone": "Définir le fuseau horaire"
@ -3062,6 +3064,12 @@
"spaces_explainer": "Les espaces sont un nouveau moyen de regrouper les salons et les gens. En plus des espaces auxquels vous participez, vous pouvez également utiliser ceux qui sont prédéfinis.",
"title": "Barre latérale"
},
"start_automatically": {
"disabled": "Non",
"enabled": "Oui",
"label": "Ouvrir %(brand)s au démarrage de votre ordinateur",
"minimised": "Minimisé"
},
"tac_only_notifications": "Afficher uniquement les notifications dans le centre d'activité des fils de discussions",
"use_12_hour_format": "Afficher lheure au format am/pm (par ex. 2:30pm)",
"use_command_enter_send_message": "Utilisez Ctrl + Entrée pour envoyer un message",

View File

@ -40,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));
@ -79,8 +89,3 @@ class ModuleApi implements Api {
}
export type ModuleApiType = ModuleApi;
if (!window.mxModuleApi) {
window.mxModuleApi = new ModuleApi();
}
export default window.mxModuleApi;

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;
}

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

@ -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

@ -13,10 +13,13 @@ import {
JSONEventFactory,
MessageEventFactory,
pickFactory,
renderTile,
RoomCreateEventFactory,
} from "../../../src/events/EventTileFactory";
import SettingsStore from "../../../src/settings/SettingsStore";
import { createTestClient, mkEvent } from "../../test-utils";
import { TimelineRenderingType } from "../../../src/contexts/RoomContext";
import { ModuleApi } from "../../../src/modules/Api";
const roomId = "!room:example.com";
@ -205,3 +208,54 @@ describe("pickFactory", () => {
});
});
});
describe("renderTile", () => {
let client: MatrixClient;
beforeEach(() => {
client = createTestClient();
});
it("rendering a tile defers to the module API", () => {
ModuleApi.instance.customComponents.renderMessage = jest.fn();
const messageEvent = mkEvent({
event: true,
type: EventType.RoomMessage,
user: client.getUserId()!,
room: roomId,
content: {
msgtype: MsgType.Text,
},
});
renderTile(TimelineRenderingType.Room, { mxEvent: messageEvent, showHiddenEvents: false }, client);
expect(ModuleApi.instance.customComponents.renderMessage).toHaveBeenCalledWith(
{
mxEvent: messageEvent,
},
expect.any(Function),
);
});
it("rendering a tile for a message of unknown type defers to the module API", () => {
ModuleApi.instance.customComponents.renderMessage = jest.fn();
const messageEvent = mkEvent({
event: true,
type: "weird.type",
user: client.getUserId()!,
room: roomId,
content: {
msgtype: MsgType.Text,
},
});
renderTile(TimelineRenderingType.Room, { mxEvent: messageEvent, showHiddenEvents: false }, client);
expect(ModuleApi.instance.customComponents.renderMessage).toHaveBeenCalledWith({
mxEvent: messageEvent,
});
});
});

2078
yarn.lock

File diff suppressed because it is too large Load Diff