Skip to content

Commit f295ffa

Browse files
toger5robintown
authored andcommitted
Allow the embedded client to work without UpdateState version
1 parent 9398271 commit f295ffa

File tree

1 file changed

+50
-3
lines changed

1 file changed

+50
-3
lines changed

src/embedded.ts

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

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

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

@@ -283,6 +288,31 @@ export class RoomWidgetClient extends MatrixClient {
283288

284289
await this.widgetApiReady;
285290

291+
if (!(await this.supportUpdateState())) {
292+
// Backfill the requested events
293+
// We only get the most recent event for every type + state key combo,
294+
// so it doesn't really matter what order we inject them in
295+
await Promise.all(
296+
this.capabilities.receiveState?.map(async ({ eventType, stateKey }) => {
297+
const rawEvents = await this.widgetApi.readStateEvents(eventType, undefined, stateKey, [
298+
this.roomId,
299+
]);
300+
const events = rawEvents.map((rawEvent) => new MatrixEvent(rawEvent as Partial<IEvent>));
301+
302+
if (this.syncApi instanceof SyncApi) {
303+
// Passing events as `stateAfterEventList` will update the state.
304+
await this.syncApi.injectRoomEvents(this.room!, undefined, events);
305+
} else {
306+
await this.syncApi!.injectRoomEvents(this.room!, events); // Sliding Sync
307+
}
308+
events.forEach((event) => {
309+
this.emit(ClientEvent.Event, event);
310+
logger.info(`Backfilled event ${event.getId()} ${event.getType()} ${event.getStateKey()}`);
311+
});
312+
}) ?? [],
313+
);
314+
}
315+
286316
if (opts.clientWellKnownPollPeriod !== undefined) {
287317
this.clientWellKnownIntervalID = setInterval(() => {
288318
this.fetchClientWellKnown();
@@ -589,11 +619,24 @@ export class RoomWidgetClient extends MatrixClient {
589619
await this.updateTxId(event);
590620

591621
if (this.syncApi instanceof SyncApi) {
592-
await this.syncApi.injectRoomEvents(this.room!, undefined, [], [event]);
622+
if (await this.supportUpdateState()) {
623+
await this.syncApi.injectRoomEvents(this.room!, undefined, [], [event]);
624+
} else {
625+
// Passing undefined for `stateAfterEventList` will make `injectRoomEvents` run in legacy mode
626+
// -> state events in `timelineEventList` will update the state.
627+
await this.syncApi.injectRoomEvents(this.room!, [], undefined, [event]);
628+
}
593629
} else {
594630
// Sliding Sync
595-
await this.syncApi!.injectRoomEvents(this.room!, [], [event]);
631+
if (await this.supportUpdateState()) {
632+
await this.syncApi!.injectRoomEvents(this.room!, [], [event]);
633+
} else {
634+
logger.error(
635+
"slididng sync cannot be used in widget mode if the client widget driver does not support the version: 'org.matrix.msc2762_update_state'",
636+
);
637+
}
596638
}
639+
597640
this.emit(ClientEvent.Event, event);
598641
this.setSyncState(SyncState.Syncing);
599642
logger.info(`Received event ${event.getId()} ${event.getType()}`);
@@ -623,7 +666,11 @@ export class RoomWidgetClient extends MatrixClient {
623666

624667
private onStateUpdate = async (ev: CustomEvent<IUpdateStateToWidgetActionRequest>): Promise<void> => {
625668
ev.preventDefault();
626-
669+
if (!(await this.supportUpdateState())) {
670+
logger.warn(
671+
"received update_state widget action but the widget driver did not claim to support 'org.matrix.msc2762_update_state'",
672+
);
673+
}
627674
for (const rawEvent of ev.detail.data.state) {
628675
// Verify the room ID matches, since it's possible for the client to
629676
// send us state updates from other rooms if this widget is always

0 commit comments

Comments
 (0)