Skip to content

Commit d794e67

Browse files
committed
Allow the embedded client to work without UpdateState version
1 parent c0e30ce commit d794e67

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
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,6 +289,31 @@ export class RoomWidgetClient extends MatrixClient {
284289

285290
await this.widgetApiReady;
286291

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

565595
if (this.syncApi instanceof SyncApi) {
566-
await this.syncApi.injectRoomEvents(this.room!, undefined, [], [event]);
596+
if (await this.supportUpdateState()) {
597+
await this.syncApi.injectRoomEvents(this.room!, undefined, [], [event]);
598+
} else {
599+
// Passing undefined for `stateAfterEventList` will make `injectRoomEvents` run in legacy mode
600+
// -> state events in `timelineEventList` will update the state.
601+
await this.syncApi.injectRoomEvents(this.room!, [], undefined, [event]);
602+
}
567603
} else {
568604
// Sliding Sync
569-
await this.syncApi!.injectRoomEvents(this.room!, [], [event]);
605+
if (await this.supportUpdateState()) {
606+
await this.syncApi!.injectRoomEvents(this.room!, [], [event]);
607+
} else {
608+
logger.error(
609+
"slididng sync cannot be used in widget mode if the client widget driver does not support the version: 'org.matrix.msc2762_update_state'",
610+
);
611+
}
570612
}
613+
571614
this.emit(ClientEvent.Event, event);
572615
this.setSyncState(SyncState.Syncing);
573616
logger.info(`Received event ${event.getId()} ${event.getType()}`);
@@ -597,7 +640,11 @@ export class RoomWidgetClient extends MatrixClient {
597640

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

0 commit comments

Comments
 (0)