From be181d2c794618773780d7d9d224acf5977eb876 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 19 Dec 2024 22:53:51 +0000 Subject: [PATCH] Use mapped types around account data events (#28752) * Use mapped types around account data events --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- playwright/e2e/crypto/crypto.spec.ts | 2 +- .../get-openid-token.spec.ts | 3 +- .../e2e/integration-manager/kick.spec.ts | 3 +- .../integration-manager/read_events.spec.ts | 3 +- .../integration-manager/send_event.spec.ts | 3 +- playwright/e2e/room/room.spec.ts | 4 +-- playwright/e2e/spotlight/spotlight.spec.ts | 5 ++- playwright/e2e/widgets/stickers.spec.ts | 3 +- playwright/pages/client.ts | 8 +++-- src/@types/matrix-js-sdk.d.ts | 31 ++++++++++++++++++ src/components/structures/LoggedInView.tsx | 3 +- .../views/dialogs/devtools/AccountData.tsx | 4 +-- .../views/settings/devices/useOwnDevices.ts | 2 +- src/hooks/useAccountData.ts | 4 +-- .../handlers/AccountSettingsHandler.ts | 17 +++++----- src/stores/WidgetStore.ts | 10 ++---- src/utils/IdentityServerUtils.ts | 2 +- src/utils/WidgetUtils-types.ts | 32 +++++++++++++++++++ src/utils/WidgetUtils.ts | 14 ++------ src/utils/device/clientInformation.ts | 14 ++++---- src/utils/device/types.ts | 13 ++++++++ src/utils/notifications.ts | 4 ++- test/unit-tests/Notifier-test.ts | 3 +- .../right_panel/RoomSummaryCard-test.tsx | 25 +++++++-------- test/unit-tests/utils/notifications-test.ts | 11 +++++-- 25 files changed, 152 insertions(+), 71 deletions(-) create mode 100644 src/utils/WidgetUtils-types.ts create mode 100644 src/utils/device/types.ts diff --git a/playwright/e2e/crypto/crypto.spec.ts b/playwright/e2e/crypto/crypto.spec.ts index 668c17d931d..d223138781a 100644 --- a/playwright/e2e/crypto/crypto.spec.ts +++ b/playwright/e2e/crypto/crypto.spec.ts @@ -81,7 +81,7 @@ test.describe("Cryptography", function () { * Verify that the `m.cross_signing.${keyType}` key is available on the account data on the server * @param keyType */ - async function verifyKey(app: ElementAppPage, keyType: string) { + async function verifyKey(app: ElementAppPage, keyType: "master" | "self_signing" | "user_signing") { const accountData: { encrypted: Record> } = await app.client.evaluate( (cli, keyType) => cli.getAccountDataFromServer(`m.cross_signing.${keyType}`), keyType, diff --git a/playwright/e2e/integration-manager/get-openid-token.spec.ts b/playwright/e2e/integration-manager/get-openid-token.spec.ts index 48d52d35fa4..2bf00817ed6 100644 --- a/playwright/e2e/integration-manager/get-openid-token.spec.ts +++ b/playwright/e2e/integration-manager/get-openid-token.spec.ts @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import type { Page } from "@playwright/test"; import { test, expect } from "../../element-web-test"; import { openIntegrationManager } from "./utils"; +import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts"; const ROOM_NAME = "Integration Manager Test"; @@ -92,7 +93,7 @@ test.describe("Integration Manager: Get OpenID Token", () => { }, }, id: "integration-manager", - }, + } as unknown as UserWidget, }); // Succeed when checking the token is valid diff --git a/playwright/e2e/integration-manager/kick.spec.ts b/playwright/e2e/integration-manager/kick.spec.ts index 59c2703a18d..9d25d049348 100644 --- a/playwright/e2e/integration-manager/kick.spec.ts +++ b/playwright/e2e/integration-manager/kick.spec.ts @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import type { Page } from "@playwright/test"; import { test, expect } from "../../element-web-test"; import { openIntegrationManager } from "./utils"; +import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts"; const ROOM_NAME = "Integration Manager Test"; const USER_DISPLAY_NAME = "Alice"; @@ -136,7 +137,7 @@ test.describe("Integration Manager: Kick", () => { }, }, id: "integration-manager", - }, + } as unknown as UserWidget, }); // Succeed when checking the token is valid diff --git a/playwright/e2e/integration-manager/read_events.spec.ts b/playwright/e2e/integration-manager/read_events.spec.ts index 791d5bd725b..8fc81d766f5 100644 --- a/playwright/e2e/integration-manager/read_events.spec.ts +++ b/playwright/e2e/integration-manager/read_events.spec.ts @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import type { Page } from "@playwright/test"; import { test, expect } from "../../element-web-test"; import { openIntegrationManager } from "./utils"; +import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts"; const ROOM_NAME = "Integration Manager Test"; @@ -107,7 +108,7 @@ test.describe("Integration Manager: Read Events", () => { }, }, id: "integration-manager", - }, + } as unknown as UserWidget, }); // Succeed when checking the token is valid diff --git a/playwright/e2e/integration-manager/send_event.spec.ts b/playwright/e2e/integration-manager/send_event.spec.ts index 363719d8f14..2f6e9039533 100644 --- a/playwright/e2e/integration-manager/send_event.spec.ts +++ b/playwright/e2e/integration-manager/send_event.spec.ts @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import type { Page } from "@playwright/test"; import { test, expect } from "../../element-web-test"; import { openIntegrationManager } from "./utils"; +import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts"; const ROOM_NAME = "Integration Manager Test"; @@ -113,7 +114,7 @@ test.describe("Integration Manager: Send Event", () => { }, }, id: "integration-manager", - }, + } as unknown as UserWidget, }); // Succeed when checking the token is valid diff --git a/playwright/e2e/room/room.spec.ts b/playwright/e2e/room/room.spec.ts index 76fa64a6488..cd8a3ff793d 100644 --- a/playwright/e2e/room/room.spec.ts +++ b/playwright/e2e/room/room.spec.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ -import type { EventType } from "matrix-js-sdk/src/matrix"; +import type { AccountDataEvents } from "matrix-js-sdk/src/matrix"; import { test, expect } from "../../element-web-test"; import { Bot } from "../../pages/bot"; @@ -28,7 +28,7 @@ test.describe("Room Directory", () => { const charlieRoom = await cli.createRoom({ is_direct: true }); await cli.invite(bobRoom.room_id, bob); await cli.invite(charlieRoom.room_id, charlie); - await cli.setAccountData("m.direct" as EventType, { + await cli.setAccountData("m.direct" as keyof AccountDataEvents, { [bob]: [bobRoom.room_id], [charlie]: [charlieRoom.room_id], }); diff --git a/playwright/e2e/spotlight/spotlight.spec.ts b/playwright/e2e/spotlight/spotlight.spec.ts index 22513ca47a7..a6396dcc42a 100644 --- a/playwright/e2e/spotlight/spotlight.spec.ts +++ b/playwright/e2e/spotlight/spotlight.spec.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ +import type { AccountDataEvents } from "matrix-js-sdk/src/matrix"; import { test, expect } from "../../element-web-test"; import { Filter } from "../../pages/Spotlight"; import { Bot } from "../../pages/bot"; @@ -255,7 +256,9 @@ test.describe("Spotlight", () => { // Invite BotBob into existing DM with ByteBot const dmRooms = await app.client.evaluate((client, userId) => { - const map = client.getAccountData("m.direct")?.getContent>(); + const map = client + .getAccountData("m.direct" as keyof AccountDataEvents) + ?.getContent>(); return map[userId] ?? []; }, bot2UserId); expect(dmRooms).toHaveLength(1); diff --git a/playwright/e2e/widgets/stickers.spec.ts b/playwright/e2e/widgets/stickers.spec.ts index 318f7129616..418e104037b 100644 --- a/playwright/e2e/widgets/stickers.spec.ts +++ b/playwright/e2e/widgets/stickers.spec.ts @@ -12,6 +12,7 @@ import type { Page } from "@playwright/test"; import { test, expect } from "../../element-web-test"; import { ElementAppPage } from "../../pages/ElementAppPage"; import { Credentials } from "../../plugins/homeserver"; +import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts"; const STICKER_PICKER_WIDGET_ID = "fake-sticker-picker"; const STICKER_PICKER_WIDGET_NAME = "Fake Stickers"; @@ -123,7 +124,7 @@ async function setWidgetAccountData( state_key: STICKER_PICKER_WIDGET_ID, type: "m.widget", id: STICKER_PICKER_WIDGET_ID, - }, + } as unknown as UserWidget, }); } diff --git a/playwright/pages/client.ts b/playwright/pages/client.ts index 2dfe7484f5d..23b48602e98 100644 --- a/playwright/pages/client.ts +++ b/playwright/pages/client.ts @@ -25,6 +25,7 @@ import type { Upload, StateEvents, TimelineEvents, + AccountDataEvents, } from "matrix-js-sdk/src/matrix"; import type { RoomMessageEventContent } from "matrix-js-sdk/src/types"; import { Credentials } from "../plugins/homeserver"; @@ -439,11 +440,14 @@ export class Client { * @param type The type of account data to set * @param content The content to set */ - public async setAccountData(type: string, content: IContent): Promise { + public async setAccountData( + type: T, + content: AccountDataEvents[T], + ): Promise { const client = await this.prepareClient(); return client.evaluate( async (client, { type, content }) => { - await client.setAccountData(type, content); + await client.setAccountData(type as T, content as AccountDataEvents[T]); }, { type, content }, ); diff --git a/src/@types/matrix-js-sdk.d.ts b/src/@types/matrix-js-sdk.d.ts index 41ccfcbb3b2..21299cff300 100644 --- a/src/@types/matrix-js-sdk.d.ts +++ b/src/@types/matrix-js-sdk.d.ts @@ -11,6 +11,8 @@ import type { BLURHASH_FIELD } from "../utils/image-media"; import type { JitsiCallMemberEventType, JitsiCallMemberContent } from "../call-types"; import type { ILayoutStateEvent, WIDGET_LAYOUT_EVENT_TYPE } from "../stores/widgets/types"; import type { EncryptedFile } from "matrix-js-sdk/src/types"; +import type { DeviceClientInformation } from "../utils/device/types.ts"; +import type { UserWidget } from "../utils/WidgetUtils-types.ts"; // Extend Matrix JS SDK types via Typescript declaration merging to support unspecced event fields and types declare module "matrix-js-sdk/src/types" { @@ -57,6 +59,35 @@ declare module "matrix-js-sdk/src/types" { }; } + export interface AccountDataEvents { + // Analytics account data event + "im.vector.analytics": { + id: string; + pseudonymousAnalyticsOptIn?: boolean; + }; + // Device client information account data event + [key: `io.element.matrix_client_information.${string}`]: DeviceClientInformation; + // Element settings account data events + "im.vector.setting.breadcrumbs": { recent_rooms: string[] }; + "io.element.recent_emoji": { recent_emoji: string[] }; + "im.vector.setting.integration_provisioning": { enabled: boolean }; + "im.vector.riot.breadcrumb_rooms": { recent_rooms: string[] }; + "im.vector.web.settings": Record; + + // URL preview account data event + "org.matrix.preview_urls": { disable: boolean }; + + // This is not yet in the Matrix spec yet is being used as if it was + "m.widgets": { + [widgetId: string]: UserWidget; + }; + + // This is not in the Matrix spec yet seems to use an `m.` prefix + "m.accepted_terms": { + accepted: string[]; + }; + } + export interface AudioContent { // MSC1767 + Ideals of MSC2516 as MSC3245 // https://github.com/matrix-org/matrix-doc/pull/3245 diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 019f9cd1a84..88e7e937900 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -16,6 +16,7 @@ import { IUsageLimit, SyncStateData, SyncState, + EventType, } from "matrix-js-sdk/src/matrix"; import { MatrixCall } from "matrix-js-sdk/src/webrtc/call"; import classNames from "classnames"; @@ -161,7 +162,7 @@ class LoggedInView extends React.Component { this._matrixClient.on(ClientEvent.AccountData, this.onAccountData); // check push rules on start up as well - monitorSyncedPushRules(this._matrixClient.getAccountData("m.push_rules"), this._matrixClient); + monitorSyncedPushRules(this._matrixClient.getAccountData(EventType.PushRules), this._matrixClient); this._matrixClient.on(ClientEvent.Sync, this.onSync); // Call `onSync` with the current state as well this.onSync(this._matrixClient.getSyncState(), null, this._matrixClient.getSyncStateData() ?? undefined); diff --git a/src/components/views/dialogs/devtools/AccountData.tsx b/src/components/views/dialogs/devtools/AccountData.tsx index f1fc081b009..920cab88603 100644 --- a/src/components/views/dialogs/devtools/AccountData.tsx +++ b/src/components/views/dialogs/devtools/AccountData.tsx @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. */ import React, { useContext, useMemo, useState } from "react"; -import { IContent, MatrixEvent } from "matrix-js-sdk/src/matrix"; +import { AccountDataEvents, IContent, MatrixEvent } from "matrix-js-sdk/src/matrix"; import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool"; import MatrixClientContext from "../../../../contexts/MatrixClientContext"; @@ -21,7 +21,7 @@ export const AccountDataEventEditor: React.FC = ({ mxEvent, onBack const fields = useMemo(() => [eventTypeField(mxEvent?.getType())], [mxEvent]); - const onSend = async ([eventType]: string[], content?: IContent): Promise => { + const onSend = async ([eventType]: Array, content?: IContent): Promise => { await cli.setAccountData(eventType, content || {}); }; diff --git a/src/components/views/settings/devices/useOwnDevices.ts b/src/components/views/settings/devices/useOwnDevices.ts index 51a05f6242d..52b8e0aa631 100644 --- a/src/components/views/settings/devices/useOwnDevices.ts +++ b/src/components/views/settings/devices/useOwnDevices.ts @@ -116,7 +116,7 @@ export const useOwnDevices = (): DevicesState => { const notificationSettings = new Map(); Object.keys(devices).forEach((deviceId) => { - const eventType = `${LOCAL_NOTIFICATION_SETTINGS_PREFIX.name}.${deviceId}`; + const eventType = `${LOCAL_NOTIFICATION_SETTINGS_PREFIX.name}.${deviceId}` as const; const event = matrixClient.getAccountData(eventType); if (event) { notificationSettings.set(deviceId, event.getContent()); diff --git a/src/hooks/useAccountData.ts b/src/hooks/useAccountData.ts index 0f55969e29a..b2fe464e55d 100644 --- a/src/hooks/useAccountData.ts +++ b/src/hooks/useAccountData.ts @@ -7,14 +7,14 @@ Please see LICENSE files in the repository root for full details. */ import { useCallback, useState } from "react"; -import { ClientEvent, MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix"; +import { AccountDataEvents, ClientEvent, MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix"; import { useTypedEventEmitter } from "./useEventEmitter"; const tryGetContent = (ev?: MatrixEvent): T | undefined => ev?.getContent(); // Hook to simplify listening to Matrix account data -export const useAccountData = (cli: MatrixClient, eventType: string): T => { +export const useAccountData = (cli: MatrixClient, eventType: keyof AccountDataEvents): T => { const [value, setValue] = useState(() => tryGetContent(cli.getAccountData(eventType))); const handler = useCallback( diff --git a/src/settings/handlers/AccountSettingsHandler.ts b/src/settings/handlers/AccountSettingsHandler.ts index 051e6fc7a61..9187bd0d492 100644 --- a/src/settings/handlers/AccountSettingsHandler.ts +++ b/src/settings/handlers/AccountSettingsHandler.ts @@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ -import { ClientEvent, MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix"; +import { AccountDataEvents, ClientEvent, MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix"; import { defer } from "matrix-js-sdk/src/utils"; import { isEqual } from "lodash"; @@ -140,11 +140,11 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa } // helper function to set account data then await it being echoed back - private async setAccountData( - eventType: string, - field: string, - value: any, - legacyEventType?: string, + private async setAccountData( + eventType: K, + field: F, + value: AccountDataEvents[K][F], + legacyEventType?: keyof AccountDataEvents, ): Promise { let content = this.getSettings(eventType); if (legacyEventType && !content?.[field]) { @@ -161,7 +161,8 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa // which race between different lines. const deferred = defer(); const handler = (event: MatrixEvent): void => { - if (event.getType() !== eventType || !isEqual(event.getContent()[field], value)) return; + if (event.getType() !== eventType || !isEqual(event.getContent()[field], value)) + return; this.client.off(ClientEvent.AccountData, handler); deferred.resolve(); }; @@ -212,7 +213,7 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa return this.client && !this.client.isGuest(); } - private getSettings(eventType = "im.vector.web.settings"): any { + private getSettings(eventType: keyof AccountDataEvents = "im.vector.web.settings"): any { // TODO: [TS] Types on return if (!this.client) return null; diff --git a/src/stores/WidgetStore.ts b/src/stores/WidgetStore.ts index cfb92360a0d..62aac7a4298 100644 --- a/src/stores/WidgetStore.ts +++ b/src/stores/WidgetStore.ts @@ -17,17 +17,11 @@ import WidgetEchoStore from "../stores/WidgetEchoStore"; import ActiveWidgetStore from "../stores/ActiveWidgetStore"; import WidgetUtils from "../utils/WidgetUtils"; import { UPDATE_EVENT } from "./AsyncStore"; +import { IApp } from "../utils/WidgetUtils-types"; interface IState {} -export interface IApp extends IWidget { - "roomId": string; - "eventId"?: string; // not present on virtual widgets - // eslint-disable-next-line camelcase - "avatar_url"?: string; // MSC2765 https://github.com/matrix-org/matrix-doc/pull/2765 - // Whether the widget was created from `widget_build_url` and thus is a call widget of some kind - "io.element.managed_hybrid"?: boolean; -} +export type { IApp }; export function isAppWidget(widget: IWidget | IApp): widget is IApp { return "roomId" in widget && typeof widget.roomId === "string"; diff --git a/src/utils/IdentityServerUtils.ts b/src/utils/IdentityServerUtils.ts index 6fb2a100e6d..a7bd3d12be8 100644 --- a/src/utils/IdentityServerUtils.ts +++ b/src/utils/IdentityServerUtils.ts @@ -20,7 +20,7 @@ export function setToDefaultIdentityServer(matrixClient: MatrixClient): void { const url = getDefaultIdentityServerUrl(); // Account data change will update localstorage, client, etc through dispatcher matrixClient.setAccountData("m.identity_server", { - base_url: url, + base_url: url ?? null, }); } diff --git a/src/utils/WidgetUtils-types.ts b/src/utils/WidgetUtils-types.ts new file mode 100644 index 00000000000..56515eeddb1 --- /dev/null +++ b/src/utils/WidgetUtils-types.ts @@ -0,0 +1,32 @@ +/* +Copyright 2024 New Vector Ltd. +Copyright 2017-2020 The Matrix.org Foundation C.I.C. +Copyright 2019 Travis Ralston + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +import { IWidget } from "matrix-widget-api"; + +export interface IApp extends IWidget { + "roomId": string; + "eventId"?: string; // not present on virtual widgets + // eslint-disable-next-line camelcase + "avatar_url"?: string; // MSC2765 https://github.com/matrix-org/matrix-doc/pull/2765 + // Whether the widget was created from `widget_build_url` and thus is a call widget of some kind + "io.element.managed_hybrid"?: boolean; +} + +export interface IWidgetEvent { + id: string; + type: string; + sender: string; + // eslint-disable-next-line camelcase + state_key: string; + content: IApp; +} + +export interface UserWidget extends Omit { + content: IWidget & Partial; +} diff --git a/src/utils/WidgetUtils.ts b/src/utils/WidgetUtils.ts index ad2ed63ba16..e82b8b632d8 100644 --- a/src/utils/WidgetUtils.ts +++ b/src/utils/WidgetUtils.ts @@ -29,23 +29,13 @@ import WidgetStore, { IApp, isAppWidget } from "../stores/WidgetStore"; import { parseUrl } from "./UrlUtils"; import { useEventEmitter } from "../hooks/useEventEmitter"; import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore"; +import { IWidgetEvent, UserWidget } from "./WidgetUtils-types"; // How long we wait for the state event echo to come back from the server // before waitFor[Room/User]Widget rejects its promise const WIDGET_WAIT_TIME = 20000; -export interface IWidgetEvent { - id: string; - type: string; - sender: string; - // eslint-disable-next-line camelcase - state_key: string; - content: IApp; -} - -export interface UserWidget extends Omit { - content: IWidget & Partial; -} +export type { IWidgetEvent, UserWidget }; export default class WidgetUtils { /** diff --git a/src/utils/device/clientInformation.ts b/src/utils/device/clientInformation.ts index 500bfdd5508..5e3f23018fd 100644 --- a/src/utils/device/clientInformation.ts +++ b/src/utils/device/clientInformation.ts @@ -6,17 +6,14 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ -import { MatrixClient } from "matrix-js-sdk/src/matrix"; +import { AccountDataEvents, MatrixClient } from "matrix-js-sdk/src/matrix"; import BasePlatform from "../../BasePlatform"; import { IConfigOptions } from "../../IConfigOptions"; import { DeepReadonly } from "../../@types/common"; +import { DeviceClientInformation } from "./types"; -export type DeviceClientInformation = { - name?: string; - version?: string; - url?: string; -}; +export type { DeviceClientInformation }; const formatUrl = (): string | undefined => { // don't record url for electron clients @@ -34,7 +31,8 @@ const formatUrl = (): string | undefined => { }; const clientInformationEventPrefix = "io.element.matrix_client_information."; -export const getClientInformationEventType = (deviceId: string): string => `${clientInformationEventPrefix}${deviceId}`; +export const getClientInformationEventType = (deviceId: string): `${typeof clientInformationEventPrefix}${string}` => + `${clientInformationEventPrefix}${deviceId}`; /** * Record extra client information for the current device @@ -70,7 +68,7 @@ export const pruneClientInformation = (validDeviceIds: string[], matrixClient: M } const [, deviceId] = event.getType().split(clientInformationEventPrefix); if (deviceId && !validDeviceIds.includes(deviceId)) { - matrixClient.deleteAccountData(event.getType()); + matrixClient.deleteAccountData(event.getType() as keyof AccountDataEvents); } }); }; diff --git a/src/utils/device/types.ts b/src/utils/device/types.ts new file mode 100644 index 00000000000..1b652672a83 --- /dev/null +++ b/src/utils/device/types.ts @@ -0,0 +1,13 @@ +/* +Copyright 2024 New Vector Ltd. +Copyright 2022 The Matrix.org Foundation C.I.C. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +export type DeviceClientInformation = { + name?: string; + version?: string; + url?: string; +}; diff --git a/src/utils/notifications.ts b/src/utils/notifications.ts index 30d29483802..164b888d027 100644 --- a/src/utils/notifications.ts +++ b/src/utils/notifications.ts @@ -40,7 +40,9 @@ export const deviceNotificationSettingsKeys = [ "audioNotificationsEnabled", ]; -export function getLocalNotificationAccountDataEventType(deviceId: string | null): string { +export function getLocalNotificationAccountDataEventType( + deviceId: string | null, +): `${typeof LOCAL_NOTIFICATION_SETTINGS_PREFIX.name}.${string}` { return `${LOCAL_NOTIFICATION_SETTINGS_PREFIX.name}.${deviceId}`; } diff --git a/test/unit-tests/Notifier-test.ts b/test/unit-tests/Notifier-test.ts index f94f50724d0..4c4897dbc38 100644 --- a/test/unit-tests/Notifier-test.ts +++ b/test/unit-tests/Notifier-test.ts @@ -16,6 +16,7 @@ import { IContent, MatrixEvent, SyncState, + AccountDataEvents, } from "matrix-js-sdk/src/matrix"; import { waitFor } from "jest-matrix-react"; import { CallMembership, MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc"; @@ -69,7 +70,7 @@ describe("Notifier", () => { let MockPlatform: MockedObject; let mockClient: MockedObject; let testRoom: Room; - let accountDataEventKey: string; + let accountDataEventKey: keyof AccountDataEvents; let accountDataStore: Record = {}; let mockSettings: Record = {}; diff --git a/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx b/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx index 80d2609577e..52e7b5a118c 100644 --- a/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx +++ b/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx @@ -338,19 +338,18 @@ describe("", () => { }); it("does not show public room label for a DM", async () => { - mockClient.getAccountData.mockImplementation( - (eventType) => - ({ - [EventType.Direct]: new MatrixEvent({ - type: EventType.Direct, - content: { - "@bob:sesame.st": ["some-room-id"], - // this room is a DM with ernie - "@ernie:sesame.st": ["some-other-room-id", room.roomId], - }, - }), - })[eventType], - ); + mockClient.getAccountData.mockImplementation((eventType) => { + if (eventType === EventType.Direct) { + return new MatrixEvent({ + type: EventType.Direct, + content: { + "@bob:sesame.st": ["some-room-id"], + // this room is a DM with ernie + "@ernie:sesame.st": ["some-other-room-id", room.roomId], + }, + }); + } + }); getComponent(); await flushPromises(); diff --git a/test/unit-tests/utils/notifications-test.ts b/test/unit-tests/utils/notifications-test.ts index 6cf6e3496b7..2432d477a97 100644 --- a/test/unit-tests/utils/notifications-test.ts +++ b/test/unit-tests/utils/notifications-test.ts @@ -6,7 +6,14 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ -import { MatrixEvent, NotificationCountType, Room, MatrixClient, ReceiptType } from "matrix-js-sdk/src/matrix"; +import { + MatrixEvent, + NotificationCountType, + Room, + MatrixClient, + ReceiptType, + AccountDataEvents, +} from "matrix-js-sdk/src/matrix"; import { Mocked, mocked } from "jest-mock"; import { @@ -32,7 +39,7 @@ jest.mock("../../../src/settings/SettingsStore"); describe("notifications", () => { let accountDataStore: Record = {}; let mockClient: Mocked; - let accountDataEventKey: string; + let accountDataEventKey: keyof AccountDataEvents; beforeEach(() => { jest.clearAllMocks();