Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sending ContentLoaded optional for a widgetClient #4086

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions spec/unit/embedded.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,12 @@ describe("RoomWidgetClient", () => {
client.stopClient();
});

const makeClient = async (capabilities: ICapabilities): Promise<void> => {
const makeClient = async (
capabilities: ICapabilities,
sendContentLoaded: boolean | undefined = undefined,
): Promise<void> => {
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();
Expand Down Expand Up @@ -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");
Expand All @@ -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
});
Expand Down Expand Up @@ -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: [
Expand Down
11 changes: 10 additions & 1 deletion src/embedded.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,20 @@ 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 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,
private readonly capabilities: ICapabilities,
private readonly roomId: string,
opts: IMatrixClientCreateOpts,
sendContentLoaded = true,
) {
super(opts);

Expand Down Expand Up @@ -165,7 +174,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();
toger5 marked this conversation as resolved.
Show resolved Hide resolved
}

public async startClient(opts: IStartClientOpts = {}): Promise<void> {
Expand Down
17 changes: 16 additions & 1 deletion src/matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,26 @@ 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,
roomId: string,
opts: ICreateClientOpts,
sendContentLoaded = true,
toger5 marked this conversation as resolved.
Show resolved Hide resolved
): MatrixClient {
return new RoomWidgetClient(widgetApi, capabilities, roomId, amendClientOpts(opts));
return new RoomWidgetClient(widgetApi, capabilities, roomId, amendClientOpts(opts), sendContentLoaded);
}
Loading