@@ -28,7 +28,6 @@ import {
28
28
WidgetApiAction ,
29
29
IWidgetApiResponse ,
30
30
IWidgetApiResponseData ,
31
- IUpdateStateToWidgetActionRequest ,
32
31
} from "matrix-widget-api" ;
33
32
34
33
import { MatrixEvent , IEvent , IContent , EventStatus } from "./models/event.ts" ;
@@ -137,7 +136,6 @@ export type EventHandlerMap = { [RoomWidgetClientEvent.PendingEventsChanged]: ()
137
136
export class RoomWidgetClient extends MatrixClient {
138
137
private room ?: Room ;
139
138
private readonly widgetApiReady : Promise < void > ;
140
- private readonly roomStateSynced : Promise < void > ;
141
139
private lifecycle ?: AbortController ;
142
140
private syncState : SyncState | null = null ;
143
141
@@ -191,11 +189,6 @@ export class RoomWidgetClient extends MatrixClient {
191
189
} ;
192
190
193
191
this . widgetApiReady = new Promise < void > ( ( resolve ) => this . widgetApi . once ( "ready" , resolve ) ) ;
194
- this . roomStateSynced = capabilities . receiveState ?. length
195
- ? new Promise < void > ( ( resolve ) =>
196
- this . widgetApi . once ( `action:${ WidgetApiToWidgetAction . UpdateState } ` , resolve ) ,
197
- )
198
- : Promise . resolve ( ) ;
199
192
200
193
// Request capabilities for the functionality this client needs to support
201
194
if (
@@ -248,7 +241,6 @@ export class RoomWidgetClient extends MatrixClient {
248
241
249
242
widgetApi . on ( `action:${ WidgetApiToWidgetAction . SendEvent } ` , this . onEvent ) ;
250
243
widgetApi . on ( `action:${ WidgetApiToWidgetAction . SendToDevice } ` , this . onToDevice ) ;
251
- widgetApi . on ( `action:${ WidgetApiToWidgetAction . UpdateState } ` , this . onStateUpdate ) ;
252
244
253
245
// Open communication with the host
254
246
widgetApi . start ( ) ;
@@ -284,16 +276,37 @@ export class RoomWidgetClient extends MatrixClient {
284
276
285
277
await this . widgetApiReady ;
286
278
279
+ // Backfill the requested events
280
+ // We only get the most recent event for every type + state key combo,
281
+ // so it doesn't really matter what order we inject them in
282
+ await Promise . all (
283
+ this . capabilities . receiveState ?. map ( async ( { eventType, stateKey } ) => {
284
+ const rawEvents = await this . widgetApi . readStateEvents ( eventType , undefined , stateKey , [ this . roomId ] ) ;
285
+ const events = rawEvents . map ( ( rawEvent ) => new MatrixEvent ( rawEvent as Partial < IEvent > ) ) ;
286
+
287
+ if ( this . syncApi instanceof SyncApi ) {
288
+ // Passing undefined for `stateAfterEventList` allows will make `injectRoomEvents` run in legacy mode
289
+ // -> state events in `timelineEventList` will update the state.
290
+ await this . syncApi . injectRoomEvents ( this . room ! , undefined , events ) ;
291
+ } else {
292
+ await this . syncApi ! . injectRoomEvents ( this . room ! , events ) ; // Sliding Sync
293
+ }
294
+ events . forEach ( ( event ) => {
295
+ this . emit ( ClientEvent . Event , event ) ;
296
+ logger . info ( `Backfilled event ${ event . getId ( ) } ${ event . getType ( ) } ${ event . getStateKey ( ) } ` ) ;
297
+ } ) ;
298
+ } ) ?? [ ] ,
299
+ ) ;
300
+
287
301
if ( opts . clientWellKnownPollPeriod !== undefined ) {
288
302
this . clientWellKnownIntervalID = setInterval ( ( ) => {
289
303
this . fetchClientWellKnown ( ) ;
290
304
} , 1000 * opts . clientWellKnownPollPeriod ) ;
291
305
this . fetchClientWellKnown ( ) ;
292
306
}
293
307
294
- await this . roomStateSynced ;
295
308
this . setSyncState ( SyncState . Syncing ) ;
296
- logger . info ( "Finished initial sync " ) ;
309
+ logger . info ( "Finished backfilling events " ) ;
297
310
298
311
this . matrixRTC . start ( ) ;
299
312
@@ -304,7 +317,6 @@ export class RoomWidgetClient extends MatrixClient {
304
317
public stopClient ( ) : void {
305
318
this . widgetApi . off ( `action:${ WidgetApiToWidgetAction . SendEvent } ` , this . onEvent ) ;
306
319
this . widgetApi . off ( `action:${ WidgetApiToWidgetAction . SendToDevice } ` , this . onToDevice ) ;
307
- this . widgetApi . off ( `action:${ WidgetApiToWidgetAction . UpdateState } ` , this . onStateUpdate ) ;
308
320
309
321
super . stopClient ( ) ;
310
322
this . lifecycle ! . abort ( ) ; // Signal to other async tasks that the client has stopped
@@ -562,15 +574,36 @@ export class RoomWidgetClient extends MatrixClient {
562
574
// Only inject once we have update the txId
563
575
await this . updateTxId ( event ) ;
564
576
577
+ // The widget API does not tell us whether a state event came from `state_after` or not so we assume legacy behaviour for now.
565
578
if ( this . syncApi instanceof SyncApi ) {
566
- await this . syncApi . injectRoomEvents ( this . room ! , undefined , [ ] , [ event ] ) ;
579
+ // The code will want to be something like:
580
+ // ```
581
+ // if (!params.addToTimeline && !params.addToState) {
582
+ // // Passing undefined for `stateAfterEventList` makes `injectRoomEvents` run in "legacy mode"
583
+ // // -> state events part of the `timelineEventList` parameter will update the state.
584
+ // this.injectRoomEvents(this.room!, [], undefined, [event]);
585
+ // } else {
586
+ // this.injectRoomEvents(this.room!, undefined, params.addToState ? [event] : [], params.addToTimeline ? [event] : []);
587
+ // }
588
+ // ```
589
+
590
+ // Passing undefined for `stateAfterEventList` allows will make `injectRoomEvents` run in legacy mode
591
+ // -> state events in `timelineEventList` will update the state.
592
+ await this . syncApi . injectRoomEvents ( this . room ! , [ ] , undefined , [ event ] ) ;
567
593
} else {
568
- // Sliding Sync
569
- await this . syncApi ! . injectRoomEvents ( this . room ! , [ ] , [ event ] ) ;
594
+ // The code will want to be something like:
595
+ // ```
596
+ // if (!params.addToTimeline && !params.addToState) {
597
+ // this.injectRoomEvents(this.room!, [], [event]);
598
+ // } else {
599
+ // this.injectRoomEvents(this.room!, params.addToState ? [event] : [], params.addToTimeline ? [event] : []);
600
+ // }
601
+ // ```
602
+ await this . syncApi ! . injectRoomEvents ( this . room ! , [ ] , [ event ] ) ; // Sliding Sync
570
603
}
571
604
this . emit ( ClientEvent . Event , event ) ;
572
605
this . setSyncState ( SyncState . Syncing ) ;
573
- logger . info ( `Received event ${ event . getId ( ) } ${ event . getType ( ) } ` ) ;
606
+ logger . info ( `Received event ${ event . getId ( ) } ${ event . getType ( ) } ${ event . getStateKey ( ) } ` ) ;
574
607
} else {
575
608
const { event_id : eventId , room_id : roomId } = ev . detail . data ;
576
609
logger . info ( `Received event ${ eventId } for a different room ${ roomId } ; discarding` ) ;
@@ -595,32 +628,6 @@ export class RoomWidgetClient extends MatrixClient {
595
628
await this . ack ( ev ) ;
596
629
} ;
597
630
598
- private onStateUpdate = async ( ev : CustomEvent < IUpdateStateToWidgetActionRequest > ) : Promise < void > => {
599
- ev . preventDefault ( ) ;
600
-
601
- for ( const rawEvent of ev . detail . data . state ) {
602
- // Verify the room ID matches, since it's possible for the client to
603
- // send us state updates from other rooms if this widget is always
604
- // on screen
605
- if ( rawEvent . room_id === this . roomId ) {
606
- const event = new MatrixEvent ( rawEvent as Partial < IEvent > ) ;
607
-
608
- if ( this . syncApi instanceof SyncApi ) {
609
- await this . syncApi . injectRoomEvents ( this . room ! , undefined , [ event ] ) ;
610
- } else {
611
- // Sliding Sync
612
- await this . syncApi ! . injectRoomEvents ( this . room ! , [ event ] ) ;
613
- }
614
- logger . info ( `Updated state entry ${ event . getType ( ) } ${ event . getStateKey ( ) } to ${ event . getId ( ) } ` ) ;
615
- } else {
616
- const { event_id : eventId , room_id : roomId } = ev . detail . data ;
617
- logger . info ( `Received state entry ${ eventId } for a different room ${ roomId } ; discarding` ) ;
618
- }
619
- }
620
-
621
- await this . ack ( ev ) ;
622
- } ;
623
-
624
631
private async watchTurnServers ( ) : Promise < void > {
625
632
const servers = this . widgetApi . getTurnServers ( ) ;
626
633
const onClientStopped = ( ) : void => {
0 commit comments