From 3c1ac5ad46adca3b70a3d48fb467af10e5976323 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 28 Feb 2024 16:24:28 +0100 Subject: [PATCH 1/5] add sendContentLoaded option to widgetClient Signed-off-by: Timo K --- src/embedded.ts | 12 +++++++++++- src/matrix.ts | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/embedded.ts b/src/embedded.ts index 178d74b2ec7..e9d1e4e126f 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -108,11 +108,21 @@ export class RoomWidgetClient extends MatrixClient { private lifecycle?: AbortController; private syncState: SyncState | null = null; + /** + * + * @param widgetApi - the widget api to use for the embedded "fake" client + * @param opts - Client related options + * @param sendContentLoaded - Whether to send a content loaded event. + * Set to false if: the widget uses waitForIFrameLoad=true, or if the + * the widget wants to send the ContentLoaded action at a later point in time + * after initial setup. + */ public constructor( private readonly widgetApi: WidgetApi, private readonly capabilities: ICapabilities, private readonly roomId: string, opts: IMatrixClientCreateOpts, + sendContentLoaded = true, ) { super(opts); @@ -165,7 +175,7 @@ export class RoomWidgetClient extends MatrixClient { // does *not* (yes, that is the right way around) wait for this event. Let's // start sending this, then once this has rolled out, we can change element-web to // use waitForIFrameLoad=false and have a widget API that's less racy. - widgetApi.sendContentLoaded(); + if (sendContentLoaded) widgetApi.sendContentLoaded(); } public async startClient(opts: IStartClientOpts = {}): Promise { diff --git a/src/matrix.ts b/src/matrix.ts index 9dd83affade..6b947729d8e 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -169,6 +169,7 @@ export function createRoomWidgetClient( capabilities: ICapabilities, roomId: string, opts: ICreateClientOpts, + sendContentLoaded = true, ): MatrixClient { - return new RoomWidgetClient(widgetApi, capabilities, roomId, amendClientOpts(opts)); + return new RoomWidgetClient(widgetApi, capabilities, roomId, amendClientOpts(opts), sendContentLoaded); } From 8c8d62f3921eae6f8b15d563f1edd034baae3341 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 1 Mar 2024 19:56:59 +0100 Subject: [PATCH 2/5] review Signed-off-by: Timo K --- src/embedded.ts | 7 +++---- src/matrix.ts | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/embedded.ts b/src/embedded.ts index e9d1e4e126f..abaf224cc5f 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -112,10 +112,9 @@ export class RoomWidgetClient extends MatrixClient { * * @param widgetApi - the widget api to use for the embedded "fake" client * @param opts - Client related options - * @param sendContentLoaded - Whether to send a content loaded event. - * Set to false if: the widget uses waitForIFrameLoad=true, or if the - * the widget wants to send the ContentLoaded action at a later point in time - * after initial setup. + * @param sendContentLoaded - Whether to send a content loaded widget action immediately after initial setup. + * Set to `false` if the widget uses `waitForIFrameLoad=true` (in this case the client does not expect a content loaded action at all), + * or if the the widget wants to send the `ContentLoaded` action at a later point in time after the initial setup. */ public constructor( private readonly widgetApi: WidgetApi, diff --git a/src/matrix.ts b/src/matrix.ts index 6b947729d8e..4e12c9feba4 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -164,6 +164,20 @@ export function createClient(opts: ICreateClientOpts): MatrixClient { return new MatrixClient(amendClientOpts(opts)); } +/** + * Construct a Matrix Client that works in a widget. + * This client has a subset of features compared to a full client. + * It uses the widget-api to communicate with matrix. (widget \<-\> client \<-\> homeserver) + * @returns A new matrix client with a subset of features. + * @param opts - The configuration options for this client. These configuration + * options will be passed directly to {@link MatrixClient}. + * @param widgetApi - The widget api to use for communication. + * @param capabilities - The capabilities the widget client will request. + * @param roomId - The room id the widget is associated with. + * @param sendContentLoaded - Whether to send a content loaded widget action immediately after initial setup. + * Set to `false` if the widget uses `waitForIFrameLoad=true` (in this case the client does not expect a content loaded action at all), + * or if the the widget wants to send the `ContentLoaded` action at a later point in time after the initial setup. + */ export function createRoomWidgetClient( widgetApi: WidgetApi, capabilities: ICapabilities, From 9ca48f80d8517e1f451e440e9799cea807075b27 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 4 Mar 2024 15:12:17 +0100 Subject: [PATCH 3/5] add tests Signed-off-by: Timo K --- spec/unit/embedded.spec.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/spec/unit/embedded.spec.ts b/spec/unit/embedded.spec.ts index 115e0a419ca..e1e6f0513a1 100644 --- a/spec/unit/embedded.spec.ts +++ b/spec/unit/embedded.spec.ts @@ -87,9 +87,12 @@ describe("RoomWidgetClient", () => { client.stopClient(); }); - const makeClient = async (capabilities: ICapabilities): Promise => { + const makeClient = async ( + capabilities: ICapabilities, + sendContentLoaded: boolean | undefined = undefined, + ): Promise => { const baseUrl = "https://example.org"; - client = createRoomWidgetClient(widgetApi, capabilities, "!1:example.org", { baseUrl }); + client = createRoomWidgetClient(widgetApi, capabilities, "!1:example.org", { baseUrl }, sendContentLoaded); expect(widgetApi.start).toHaveBeenCalled(); // needs to have been called early in order to not miss messages widgetApi.emit("ready"); await client.startClient(); @@ -143,7 +146,7 @@ describe("RoomWidgetClient", () => { }); }); - describe("messages", () => { + describe("initialization", () => { it("requests permissions for specific message types", async () => { await makeClient({ sendMessage: [MsgType.Text], receiveMessage: [MsgType.Text] }); expect(widgetApi.requestCapabilityForRoomTimeline).toHaveBeenCalledWith("!1:example.org"); @@ -158,6 +161,15 @@ describe("RoomWidgetClient", () => { expect(widgetApi.requestCapabilityToReceiveMessage).toHaveBeenCalledWith(); }); + it("sends content loaded when configured", async () => { + await makeClient({}); + expect(widgetApi.sendContentLoaded).toHaveBeenCalled(); + }); + + it("does not sent content loaded when configured", async () => { + await makeClient({}, false); + expect(widgetApi.sendContentLoaded).not.toHaveBeenCalled(); + }); // No point in testing sending and receiving since it's done exactly the // same way as non-message events }); @@ -305,12 +317,14 @@ describe("RoomWidgetClient", () => { expect(await emittedSync).toEqual(SyncState.Syncing); }); }); + describe("oidc token", () => { it("requests an oidc token", async () => { await makeClient({}); expect(await client.getOpenIdToken()).toStrictEqual(testOIDCToken); }); }); + it("gets TURN servers", async () => { const server1: ITurnServer = { uris: [ From 3893f303f0c0fd59f2743ff29c8780ccc4e83499 Mon Sep 17 00:00:00 2001 From: Timo K Date: Tue, 5 Mar 2024 12:17:05 +0100 Subject: [PATCH 4/5] another try to get the coverage up Signed-off-by: Timo K --- src/embedded.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/embedded.ts b/src/embedded.ts index abaf224cc5f..da1920cd026 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -121,7 +121,7 @@ export class RoomWidgetClient extends MatrixClient { private readonly capabilities: ICapabilities, private readonly roomId: string, opts: IMatrixClientCreateOpts, - sendContentLoaded = true, + sendContentLoaded: boolean, ) { super(opts); From f3e36bb41e0cb66992fd1c21a653b951d0e5c17d Mon Sep 17 00:00:00 2001 From: Timo K Date: Tue, 5 Mar 2024 17:54:47 +0100 Subject: [PATCH 5/5] self review Signed-off-by: Timo K --- src/embedded.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/embedded.ts b/src/embedded.ts index da1920cd026..8730c22ee3f 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -110,8 +110,10 @@ export class RoomWidgetClient extends MatrixClient { /** * - * @param widgetApi - the widget api to use for the embedded "fake" client - * @param opts - Client related options + * @param widgetApi - The widget api to use for communication. + * @param capabilities - The capabilities the widget client will request. + * @param roomId - The room id the widget is associated with. + * @param opts - The configuration options for this client. * @param sendContentLoaded - Whether to send a content loaded widget action immediately after initial setup. * Set to `false` if the widget uses `waitForIFrameLoad=true` (in this case the client does not expect a content loaded action at all), * or if the the widget wants to send the `ContentLoaded` action at a later point in time after the initial setup.