diff --git a/packages/element-web-module-api/element-web-module-api.api.md b/packages/element-web-module-api/element-web-module-api.api.md index 2d341fd..ac8ce74 100644 --- a/packages/element-web-module-api/element-web-module-api.api.md +++ b/packages/element-web-module-api/element-web-module-api.api.md @@ -24,6 +24,18 @@ export interface AccountAuthInfo { userId: string; } +// @public +export interface AccountDataApi { + delete(eventType: string): Promise; + get(eventType: string): unknown; + set(eventType: string, content: unknown): Promise; +} + +// @public +export interface ActionsApi { + openRoom: (roomId: string) => void; +} + // @alpha @deprecated (undocumented) export interface AliasCustomisations { // (undocumented) @@ -35,8 +47,10 @@ export interface AliasCustomisations { // // @public export interface Api extends LegacyModuleApiExtension, LegacyCustomisationsApiExtension, DialogApiExtension, AccountAuthApiExtension, ProfileApiExtension { + readonly actions: ActionsApi; // @alpha readonly builtins: BuiltinsApi; + readonly client: ClientApi; readonly config: ConfigApi; createRoot(element: Element): Root; // @alpha @@ -46,11 +60,13 @@ export interface Api extends LegacyModuleApiExtension, LegacyCustomisationsApiEx readonly i18n: I18nApi; readonly navigation: NavigationApi; readonly rootNode: HTMLElement; + readonly stores: StoresApi; } // @alpha export interface BuiltinsApi { - getRoomViewComponent(): React.ComponentType; + renderRoomAvatar(roomId: string, size?: string): React.ReactNode; + renderRoomView(roomId: string): React.ReactNode; } // @alpha @deprecated (undocumented) @@ -64,6 +80,12 @@ export interface ChatExportCustomisations { }; } +// @public +export interface ClientApi { + getAccountDataApi: () => AccountDataApi; + getRoom: (id: string) => Room | null; +} + // @alpha @deprecated (undocumented) export interface ComponentVisibilityCustomisations { shouldShowComponent?(component: "UIComponent.sendInvites" | "UIComponent.roomCreation" | "UIComponent.spaceCreation" | "UIComponent.exploreRooms" | "UIComponent.addIntegrations" | "UIComponent.filterContainer" | "UIComponent.roomOptionsMenu"): boolean; @@ -311,11 +333,24 @@ export interface ProfileApiExtension { readonly profile: Watchable; } +// @public +export interface Room { + getLastActiveTimestamp: () => number; + id: string; + name: Watchable; +} + // @alpha @deprecated (undocumented) export interface RoomListCustomisations { isRoomVisible?(room: Room): boolean; } +// @public +export interface RoomListStoreApi { + getRooms(): Room[]; + waitForReady(): Promise; +} + // @alpha export interface RoomViewProps { roomId?: string; @@ -334,6 +369,11 @@ export interface SpacePanelItemProps { tooltip?: string; } +// @public +export interface StoresApi { + getRoomListStore(): RoomListStoreApi; +} + // @public export type Translations = Record { constructor(currentValue: T); + // Warning: (ae-forgotten-export) The symbol "WatchFn" needs to be exported by the entry point index.d.ts + // + // (undocumented) + protected readonly listeners: Set>; // (undocumented) unwatch(listener: (value: T) => void): void; // (undocumented) diff --git a/packages/element-web-module-api/src/api/actions.ts b/packages/element-web-module-api/src/api/actions.ts new file mode 100644 index 0000000..5019f74 --- /dev/null +++ b/packages/element-web-module-api/src/api/actions.ts @@ -0,0 +1,18 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +/** + * Exposes certain action that can be performed on element-web. + * @public + */ +export interface ActionsApi { + /** + * Open a room in element-web. + * @param roomId - id of the room to open + */ + openRoom: (roomId: string) => void; +} diff --git a/packages/element-web-module-api/src/api/builtins.ts b/packages/element-web-module-api/src/api/builtins.ts index 99d60e0..cf43795 100644 --- a/packages/element-web-module-api/src/api/builtins.ts +++ b/packages/element-web-module-api/src/api/builtins.ts @@ -25,11 +25,19 @@ export interface RoomViewProps { */ export interface BuiltinsApi { /** - * Returns the RoomView component used by Element Web to render a room such that - * modules can render it as part of their own custom room views. + * Render room avatar component from element-web. * * @alpha - * @returns The RoomView component. + * @param roomId - Id of the room + * @param size - Size of the avatar to render */ - getRoomViewComponent(): React.ComponentType; + renderRoomAvatar(roomId: string, size?: string): React.ReactNode; + + /** + * Render room view component from element-web. + * + * @alpha + * @param roomId - Id of the room + */ + renderRoomView(roomId: string): React.ReactNode; } diff --git a/packages/element-web-module-api/src/api/client.ts b/packages/element-web-module-api/src/api/client.ts new file mode 100644 index 0000000..1b9bed9 --- /dev/null +++ b/packages/element-web-module-api/src/api/client.ts @@ -0,0 +1,45 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import type { Room } from "../models/Room"; + +/** + * Modify account data stored on the homeserver. + * @public + */ +export interface AccountDataApi { + /** + * Fetch account data stored from homeserver. + */ + get(eventType: string): unknown; + /** + * Sett account data on the homeserver. + */ + set(eventType: string, content: unknown): Promise; + /** + * Delete account data from homeserver. + */ + delete(eventType: string): Promise; +} + +/** + * Access some limited functionality from the SDK. + * @public + */ +export interface ClientApi { + /** + * Use this to modify account data on the homeserver. + */ + getAccountDataApi: () => AccountDataApi; + + /** + * Fetch room by id from SDK. + * @param id - Id of the room to get + * @returns Room object from SDK + */ + getRoom: (id: string) => Room | null; +} diff --git a/packages/element-web-module-api/src/api/index.ts b/packages/element-web-module-api/src/api/index.ts index dacc750..b9a5a32 100644 --- a/packages/element-web-module-api/src/api/index.ts +++ b/packages/element-web-module-api/src/api/index.ts @@ -17,6 +17,9 @@ import { AccountAuthApiExtension } from "./auth.ts"; import { ProfileApiExtension } from "./profile.ts"; import { ExtrasApi } from "./extras.ts"; import { BuiltinsApi } from "./builtins.ts"; +import { StoresApi } from "./stores.ts"; +import { ClientApi } from "./client.ts"; +import { ActionsApi } from "./actions.ts"; /** * Module interface for modules to implement. @@ -123,6 +126,21 @@ export interface Api */ readonly extras: ExtrasApi; + /** + * Allows modules to access a limited functionality of certain stores from Element Web. + */ + readonly stores: StoresApi; + + /** + * Access some very specific functionality from MatrixClient. + */ + readonly client: ClientApi; + + /** + * Exposes certain predefined actions that can be performed on Element Web. + */ + readonly actions: ActionsApi; + /** * Create a ReactDOM root for rendering React components. * Exposed to allow modules to avoid needing to bundle their own ReactDOM. diff --git a/packages/element-web-module-api/src/api/stores.ts b/packages/element-web-module-api/src/api/stores.ts new file mode 100644 index 0000000..469a52b --- /dev/null +++ b/packages/element-web-module-api/src/api/stores.ts @@ -0,0 +1,35 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import type { Room } from "../models/Room"; + +/** + * Provides some basic functionality of the Room List Store from element-web. + * @public + */ +export interface RoomListStoreApi { + /** + * Get a flat list of sorted room from the RLS. + */ + getRooms(): Room[]; + + /** + * Returns a promise that resolves when RLS is ready. + */ + waitForReady(): Promise; +} + +/** + * Provides access to certain stores from element-web. + * @public + */ +export interface StoresApi { + /** + * Use this to access limited functionality of the RLS from element-web. + */ + getRoomListStore(): RoomListStoreApi; +} diff --git a/packages/element-web-module-api/src/api/watchable.ts b/packages/element-web-module-api/src/api/watchable.ts index 2f82a9b..3fda595 100644 --- a/packages/element-web-module-api/src/api/watchable.ts +++ b/packages/element-web-module-api/src/api/watchable.ts @@ -26,7 +26,7 @@ function isObject(value: unknown): value is object { * @public */ export class Watchable { - private readonly listeners = new Set>(); + protected readonly listeners = new Set>(); public constructor(private currentValue: T) {} diff --git a/packages/element-web-module-api/src/index.ts b/packages/element-web-module-api/src/index.ts index e89adc4..15f1734 100644 --- a/packages/element-web-module-api/src/index.ts +++ b/packages/element-web-module-api/src/index.ts @@ -10,6 +10,7 @@ export type { Api, Module, ModuleFactory } from "./api"; export type { Config, ConfigApi } from "./api/config"; export type { I18nApi, Variables, Translations } from "./api/i18n"; export type * from "./models/event"; +export type * from "./models/Room"; export type * from "./api/custom-components"; export type * from "./api/extras"; export type * from "./api/legacy-modules"; @@ -19,4 +20,7 @@ export type * from "./api/dialog"; export type * from "./api/profile"; export type * from "./api/navigation"; export type * from "./api/builtins"; +export type * from "./api/stores"; +export type * from "./api/client"; +export type * from "./api/actions"; export * from "./api/watchable"; diff --git a/packages/element-web-module-api/src/models/Room.ts b/packages/element-web-module-api/src/models/Room.ts new file mode 100644 index 0000000..df2f1c8 --- /dev/null +++ b/packages/element-web-module-api/src/models/Room.ts @@ -0,0 +1,28 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import { Watchable } from "../api/watchable"; + +/** + * Represents a room from element-web. + * @public + */ +export interface Room { + /** + * Id of this room. + */ + id: string; + /** + * {@link Watchable} holding the name for this room. + */ + name: Watchable; + /** + * Get the timestamp of the last message in this room. + * @returns last active timestamp + */ + getLastActiveTimestamp: () => number; +}