Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2024-12-17 13:58:27 +00:00
parent c306774829
commit 40d2c9bf2b
13 changed files with 75 additions and 37 deletions

View File

@@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
import type { Page } from "@playwright/test"; import type { Page } from "@playwright/test";
import { test, expect } from "../../element-web-test"; import { test, expect } from "../../element-web-test";
import { openIntegrationManager } from "./utils"; import { openIntegrationManager } from "./utils";
import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts";
const ROOM_NAME = "Integration Manager Test"; const ROOM_NAME = "Integration Manager Test";
@@ -92,7 +93,7 @@ test.describe("Integration Manager: Get OpenID Token", () => {
}, },
}, },
id: "integration-manager", id: "integration-manager",
}, } as unknown as UserWidget,
}); });
// Succeed when checking the token is valid // Succeed when checking the token is valid

View File

@@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
import type { Page } from "@playwright/test"; import type { Page } from "@playwright/test";
import { test, expect } from "../../element-web-test"; import { test, expect } from "../../element-web-test";
import { openIntegrationManager } from "./utils"; import { openIntegrationManager } from "./utils";
import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts";
const ROOM_NAME = "Integration Manager Test"; const ROOM_NAME = "Integration Manager Test";
const USER_DISPLAY_NAME = "Alice"; const USER_DISPLAY_NAME = "Alice";
@@ -136,7 +137,7 @@ test.describe("Integration Manager: Kick", () => {
}, },
}, },
id: "integration-manager", id: "integration-manager",
}, } as unknown as UserWidget,
}); });
// Succeed when checking the token is valid // Succeed when checking the token is valid

View File

@@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
import type { Page } from "@playwright/test"; import type { Page } from "@playwright/test";
import { test, expect } from "../../element-web-test"; import { test, expect } from "../../element-web-test";
import { openIntegrationManager } from "./utils"; import { openIntegrationManager } from "./utils";
import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts";
const ROOM_NAME = "Integration Manager Test"; const ROOM_NAME = "Integration Manager Test";
@@ -107,7 +108,7 @@ test.describe("Integration Manager: Read Events", () => {
}, },
}, },
id: "integration-manager", id: "integration-manager",
}, } as unknown as UserWidget,
}); });
// Succeed when checking the token is valid // Succeed when checking the token is valid

View File

@@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
import type { Page } from "@playwright/test"; import type { Page } from "@playwright/test";
import { test, expect } from "../../element-web-test"; import { test, expect } from "../../element-web-test";
import { openIntegrationManager } from "./utils"; import { openIntegrationManager } from "./utils";
import type { UserWidget } from "../../../src/utils/WidgetUtils-types.ts";
const ROOM_NAME = "Integration Manager Test"; const ROOM_NAME = "Integration Manager Test";
@@ -113,7 +114,7 @@ test.describe("Integration Manager: Send Event", () => {
}, },
}, },
id: "integration-manager", id: "integration-manager",
}, } as unknown as UserWidget,
}); });
// Succeed when checking the token is valid // Succeed when checking the token is valid

View File

@@ -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. 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 { test, expect } from "../../element-web-test";
import { Bot } from "../../pages/bot"; import { Bot } from "../../pages/bot";
@@ -28,7 +28,7 @@ test.describe("Room Directory", () => {
const charlieRoom = await cli.createRoom({ is_direct: true }); const charlieRoom = await cli.createRoom({ is_direct: true });
await cli.invite(bobRoom.room_id, bob); await cli.invite(bobRoom.room_id, bob);
await cli.invite(charlieRoom.room_id, charlie); 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], [bob]: [bobRoom.room_id],
[charlie]: [charlieRoom.room_id], [charlie]: [charlieRoom.room_id],
}); });

View File

@@ -12,6 +12,7 @@ import type { Page } from "@playwright/test";
import { test, expect } from "../../element-web-test"; import { test, expect } from "../../element-web-test";
import { ElementAppPage } from "../../pages/ElementAppPage"; import { ElementAppPage } from "../../pages/ElementAppPage";
import { Credentials } from "../../plugins/homeserver"; 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_ID = "fake-sticker-picker";
const STICKER_PICKER_WIDGET_NAME = "Fake Stickers"; const STICKER_PICKER_WIDGET_NAME = "Fake Stickers";
@@ -123,7 +124,7 @@ async function setWidgetAccountData(
state_key: STICKER_PICKER_WIDGET_ID, state_key: STICKER_PICKER_WIDGET_ID,
type: "m.widget", type: "m.widget",
id: STICKER_PICKER_WIDGET_ID, id: STICKER_PICKER_WIDGET_ID,
}, } as unknown as UserWidget,
}); });
} }

View File

@@ -25,6 +25,7 @@ import type {
Upload, Upload,
StateEvents, StateEvents,
TimelineEvents, TimelineEvents,
AccountDataEvents,
} from "matrix-js-sdk/src/matrix"; } from "matrix-js-sdk/src/matrix";
import type { RoomMessageEventContent } from "matrix-js-sdk/src/types"; import type { RoomMessageEventContent } from "matrix-js-sdk/src/types";
import { Credentials } from "../plugins/homeserver"; import { Credentials } from "../plugins/homeserver";
@@ -439,7 +440,10 @@ export class Client {
* @param type The type of account data to set * @param type The type of account data to set
* @param content The content to set * @param content The content to set
*/ */
public async setAccountData(type: string, content: IContent): Promise<void> { public async setAccountData<T extends keyof AccountDataEvents>(
type: T,
content: AccountDataEvents[T],
): Promise<void> {
const client = await this.prepareClient(); const client = await this.prepareClient();
return client.evaluate( return client.evaluate(
async (client, { type, content }) => { async (client, { type, content }) => {

View File

@@ -11,9 +11,8 @@ import type { BLURHASH_FIELD } from "../utils/image-media";
import type { JitsiCallMemberEventType, JitsiCallMemberContent } from "../call-types"; import type { JitsiCallMemberEventType, JitsiCallMemberContent } from "../call-types";
import type { ILayoutStateEvent, WIDGET_LAYOUT_EVENT_TYPE } from "../stores/widgets/types"; import type { ILayoutStateEvent, WIDGET_LAYOUT_EVENT_TYPE } from "../stores/widgets/types";
import type { EncryptedFile } from "matrix-js-sdk/src/types"; import type { EncryptedFile } from "matrix-js-sdk/src/types";
import { PosthogAnalytics } from "../PosthogAnalytics.ts"; import type { DeviceClientInformation } from "../utils/device/types.ts";
import { DeviceClientInformation } from "../utils/device/clientInformation.ts"; import type { UserWidget } from "../utils/WidgetUtils-types.ts";
import { UserWidget } from "../utils/WidgetUtils.ts";
// Extend Matrix JS SDK types via Typescript declaration merging to support unspecced event fields and types // Extend Matrix JS SDK types via Typescript declaration merging to support unspecced event fields and types
declare module "matrix-js-sdk/src/types" { declare module "matrix-js-sdk/src/types" {
@@ -61,16 +60,20 @@ declare module "matrix-js-sdk/src/types" {
} }
export interface AccountDataEvents { export interface AccountDataEvents {
[PosthogAnalytics.ANALYTICS_EVENT_TYPE]: { // Analytics account data event
"im.vector.analytics": {
id: string; id: string;
pseudonymousAnalyticsOptIn?: boolean; pseudonymousAnalyticsOptIn?: boolean;
}; };
// Device client information account data event
[key: `io.element.matrix_client_information.${string}`]: DeviceClientInformation; [key: `io.element.matrix_client_information.${string}`]: DeviceClientInformation;
// Element settings account data events
"im.vector.setting.breadcrumbs": { recent_rooms: string[] }; "im.vector.setting.breadcrumbs": { recent_rooms: string[] };
"io.element.recent_emoji": { recent_emoji: string[] }; "io.element.recent_emoji": { recent_emoji: string[] };
"im.vector.setting.integration_provisioning": { enabled: boolean }; "im.vector.setting.integration_provisioning": { enabled: boolean };
"im.vector.web.settings": Record<string, any>; "im.vector.web.settings": Record<string, any>;
// URL preview account data event
"org.matrix.preview_urls": { disable: boolean }; "org.matrix.preview_urls": { disable: boolean };
// This is not yet in the Matrix spec yet is being used as if it was // This is not yet in the Matrix spec yet is being used as if it was

View File

@@ -17,17 +17,11 @@ import WidgetEchoStore from "../stores/WidgetEchoStore";
import ActiveWidgetStore from "../stores/ActiveWidgetStore"; import ActiveWidgetStore from "../stores/ActiveWidgetStore";
import WidgetUtils from "../utils/WidgetUtils"; import WidgetUtils from "../utils/WidgetUtils";
import { UPDATE_EVENT } from "./AsyncStore"; import { UPDATE_EVENT } from "./AsyncStore";
import { IApp } from "../utils/WidgetUtils-types";
interface IState {} interface IState {}
export interface IApp extends IWidget { export type { IApp };
"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 function isAppWidget(widget: IWidget | IApp): widget is IApp { export function isAppWidget(widget: IWidget | IApp): widget is IApp {
return "roomId" in widget && typeof widget.roomId === "string"; return "roomId" in widget && typeof widget.roomId === "string";

View File

@@ -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<IWidgetEvent, "content"> {
content: IWidget & Partial<IApp>;
}

View File

@@ -29,23 +29,13 @@ import WidgetStore, { IApp, isAppWidget } from "../stores/WidgetStore";
import { parseUrl } from "./UrlUtils"; import { parseUrl } from "./UrlUtils";
import { useEventEmitter } from "../hooks/useEventEmitter"; import { useEventEmitter } from "../hooks/useEventEmitter";
import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore"; 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 // How long we wait for the state event echo to come back from the server
// before waitFor[Room/User]Widget rejects its promise // before waitFor[Room/User]Widget rejects its promise
const WIDGET_WAIT_TIME = 20000; const WIDGET_WAIT_TIME = 20000;
export interface IWidgetEvent { export type { IWidgetEvent, UserWidget };
id: string;
type: string;
sender: string;
// eslint-disable-next-line camelcase
state_key: string;
content: IApp;
}
export interface UserWidget extends Omit<IWidgetEvent, "content"> {
content: IWidget & Partial<IApp>;
}
export default class WidgetUtils { export default class WidgetUtils {
/** /**

View File

@@ -11,12 +11,9 @@ import { AccountDataEvents, MatrixClient } from "matrix-js-sdk/src/matrix";
import BasePlatform from "../../BasePlatform"; import BasePlatform from "../../BasePlatform";
import { IConfigOptions } from "../../IConfigOptions"; import { IConfigOptions } from "../../IConfigOptions";
import { DeepReadonly } from "../../@types/common"; import { DeepReadonly } from "../../@types/common";
import { DeviceClientInformation } from "./types";
export type DeviceClientInformation = { export type { DeviceClientInformation };
name?: string;
version?: string;
url?: string;
};
const formatUrl = (): string | undefined => { const formatUrl = (): string | undefined => {
// don't record url for electron clients // don't record url for electron clients

13
src/utils/device/types.ts Normal file
View File

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