Skip to content

Commit 77ce1d8

Browse files
committed
Allow the embedded client to work without UpdateState version
fix awaiting for room state with and without new UpdateState method.
1 parent b595396 commit 77ce1d8

File tree

1 file changed

+54
-5
lines changed

1 file changed

+54
-5
lines changed

src/embedded.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
IWidgetApiResponse,
3030
IWidgetApiResponseData,
3131
IUpdateStateToWidgetActionRequest,
32+
UnstableApiVersion,
3233
} from "matrix-widget-api";
3334

3435
import { MatrixEvent, IEvent, IContent, EventStatus } from "./models/event.ts";
@@ -260,6 +261,10 @@ export class RoomWidgetClient extends MatrixClient {
260261
if (sendContentLoaded) widgetApi.sendContentLoaded();
261262
}
262263

264+
public async supportUpdateState(): Promise<boolean> {
265+
return (await this.widgetApi.getClientVersions())?.includes(UnstableApiVersion.MSC2762_UPDATE_STATE);
266+
}
267+
263268
public async startClient(opts: IStartClientOpts = {}): Promise<void> {
264269
this.lifecycle = new AbortController();
265270

@@ -284,14 +289,41 @@ export class RoomWidgetClient extends MatrixClient {
284289

285290
await this.widgetApiReady;
286291

292+
// sync room state:
293+
if (await this.supportUpdateState()) {
294+
// This will resolve once the client driver has sent us all the allowed room state.
295+
await this.roomStateSynced;
296+
} else {
297+
// Backfill the requested events
298+
// We only get the most recent event for every type + state key combo,
299+
// so it doesn't really matter what order we inject them in
300+
await Promise.all(
301+
this.capabilities.receiveState?.map(async ({ eventType, stateKey }) => {
302+
const rawEvents = await this.widgetApi.readStateEvents(eventType, undefined, stateKey, [
303+
this.roomId,
304+
]);
305+
const events = rawEvents.map((rawEvent) => new MatrixEvent(rawEvent as Partial<IEvent>));
306+
307+
if (this.syncApi instanceof SyncApi) {
308+
// Passing events as `stateAfterEventList` will update the state.
309+
await this.syncApi.injectRoomEvents(this.room!, undefined, events);
310+
} else {
311+
await this.syncApi!.injectRoomEvents(this.room!, events); // Sliding Sync
312+
}
313+
events.forEach((event) => {
314+
this.emit(ClientEvent.Event, event);
315+
logger.info(`Backfilled event ${event.getId()} ${event.getType()} ${event.getStateKey()}`);
316+
});
317+
}) ?? [],
318+
);
319+
}
320+
287321
if (opts.clientWellKnownPollPeriod !== undefined) {
288322
this.clientWellKnownIntervalID = setInterval(() => {
289323
this.fetchClientWellKnown();
290324
}, 1000 * opts.clientWellKnownPollPeriod);
291325
this.fetchClientWellKnown();
292326
}
293-
294-
await this.roomStateSynced;
295327
this.setSyncState(SyncState.Syncing);
296328
logger.info("Finished initial sync");
297329

@@ -563,11 +595,24 @@ export class RoomWidgetClient extends MatrixClient {
563595
await this.updateTxId(event);
564596

565597
if (this.syncApi instanceof SyncApi) {
566-
await this.syncApi.injectRoomEvents(this.room!, undefined, [], [event]);
598+
if (await this.supportUpdateState()) {
599+
await this.syncApi.injectRoomEvents(this.room!, undefined, [], [event]);
600+
} else {
601+
// Passing undefined for `stateAfterEventList` will make `injectRoomEvents` run in legacy mode
602+
// -> state events in `timelineEventList` will update the state.
603+
await this.syncApi.injectRoomEvents(this.room!, [], undefined, [event]);
604+
}
567605
} else {
568606
// Sliding Sync
569-
await this.syncApi!.injectRoomEvents(this.room!, [], [event]);
607+
if (await this.supportUpdateState()) {
608+
await this.syncApi!.injectRoomEvents(this.room!, [], [event]);
609+
} else {
610+
logger.error(
611+
"slididng sync cannot be used in widget mode if the client widget driver does not support the version: 'org.matrix.msc2762_update_state'",
612+
);
613+
}
570614
}
615+
571616
this.emit(ClientEvent.Event, event);
572617
this.setSyncState(SyncState.Syncing);
573618
logger.info(`Received event ${event.getId()} ${event.getType()}`);
@@ -597,7 +642,11 @@ export class RoomWidgetClient extends MatrixClient {
597642

598643
private onStateUpdate = async (ev: CustomEvent<IUpdateStateToWidgetActionRequest>): Promise<void> => {
599644
ev.preventDefault();
600-
645+
if (!(await this.supportUpdateState())) {
646+
logger.warn(
647+
"received update_state widget action but the widget driver did not claim to support 'org.matrix.msc2762_update_state'",
648+
);
649+
}
601650
for (const rawEvent of ev.detail.data.state) {
602651
// Verify the room ID matches, since it's possible for the client to
603652
// send us state updates from other rooms if this widget is always

0 commit comments

Comments
 (0)