@@ -40,7 +40,7 @@ import {
4040 ISupportedVersionsActionRequest ,
4141 ISupportedVersionsActionResponseData ,
4242} from "./interfaces/SupportedVersionsAction" ;
43- import { CurrentApiVersions } from "./interfaces/ApiVersion" ;
43+ import { ApiVersion , CurrentApiVersions , UnstableApiVersion } from "./interfaces/ApiVersion" ;
4444import { IScreenshotActionResponseData } from "./interfaces/ScreenshotAction" ;
4545import { IVisibilityActionRequestData } from "./interfaces/VisibilityAction" ;
4646import { IWidgetApiAcknowledgeResponseData , IWidgetApiResponseData } from "./interfaces/IWidgetApiResponse" ;
@@ -138,6 +138,7 @@ import { IUpdateStateToWidgetRequestData } from "./interfaces/UpdateStateAction"
138138export class ClientWidgetApi extends EventEmitter {
139139 public readonly transport : ITransport ;
140140
141+ private cachedWidgetVersions : ApiVersion [ ] | null = null ;
141142 // contentLoadedActionSent is used to check that only one ContentLoaded request is send.
142143 private contentLoadedActionSent = false ;
143144 private allowedCapabilities = new Set < Capability > ( ) ;
@@ -230,6 +231,24 @@ export class ClientWidgetApi extends EventEmitter {
230231 this . transport . stop ( ) ;
231232 }
232233
234+ public async getWidgetVersions ( ) : Promise < ApiVersion [ ] > {
235+ if ( Array . isArray ( this . cachedWidgetVersions ) ) {
236+ return Promise . resolve ( this . cachedWidgetVersions ) ;
237+ }
238+
239+ try {
240+ const r = await this . transport . send < IWidgetApiRequestEmptyData , ISupportedVersionsActionResponseData > (
241+ WidgetApiToWidgetAction . SupportedApiVersions ,
242+ { } ,
243+ ) ;
244+ this . cachedWidgetVersions = r . supported_versions ;
245+ return r . supported_versions ;
246+ } catch ( e ) {
247+ console . warn ( "non-fatal error getting supported widget versions: " , e ) ;
248+ return [ ] ;
249+ }
250+ }
251+
233252 private beginCapabilities ( ) : void {
234253 // widget has loaded - tell all the listeners that
235254 this . emit ( "preparing" ) ;
@@ -285,7 +304,7 @@ export class ClientWidgetApi extends EventEmitter {
285304
286305 private onIframeLoad ( ev : Event ) : void {
287306 if ( this . widget . waitForIframeLoad ) {
288- // If the widget is set to waitForIframeLoad the capabilities immediatly get setup after load.
307+ // If the widget is set to waitForIframeLoad the capabilities immediately get setup after load.
289308 // The client does not wait for the ContentLoaded action.
290309 this . beginCapabilities ( ) ;
291310 } else {
@@ -1007,7 +1026,7 @@ export class ClientWidgetApi extends EventEmitter {
10071026 public async feedEvent ( rawEvent : IRoomEvent , currentViewedRoomId : string ) : Promise < void > ;
10081027 /**
10091028 * Feeds an event to the widget. As a client you are expected to call this
1010- * for every new event in every room to which you are joined or invited.
1029+ * for every new event (including state events) in every room to which you are joined or invited.
10111030 * @param {IRoomEvent } rawEvent The event to (try to) send to the widget.
10121031 * @returns {Promise<void> } Resolves when delivered or if the widget is not
10131032 * able to read the event due to permissions, rejects if the widget failed
@@ -1087,10 +1106,12 @@ export class ClientWidgetApi extends EventEmitter {
10871106 events . push ( ...stateKeyMap . values ( ) ) ;
10881107 }
10891108 }
1090- await this . transport . send < IUpdateStateToWidgetRequestData > (
1091- WidgetApiToWidgetAction . UpdateState ,
1092- { state : events } ,
1093- ) ;
1109+ if ( ( await this . getWidgetVersions ( ) ) . includes ( UnstableApiVersion . MSC2762_UPDATE_STATE ) ) {
1110+ // Only send state updates when using UpdateState. Otherwise the SendEvent action will be responsible for state updates.
1111+ await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1112+ state : events ,
1113+ } ) ;
1114+ }
10941115 } finally {
10951116 this . flushRoomStateTask = null ;
10961117 }
@@ -1149,21 +1170,23 @@ export class ClientWidgetApi extends EventEmitter {
11491170 * room state entry.
11501171 * @returns {Promise<void> } Resolves when delivered or if the widget is not
11511172 * able to receive the room state due to permissions, rejects if the
1152- widget failed to handle the update.
1173+ * widget failed to handle the update.
11531174 */
11541175 public async feedStateUpdate ( rawEvent : IRoomEvent ) : Promise < void > {
1155- if ( rawEvent . state_key === undefined ) throw new Error ( ' Not a state event' ) ;
1176+ if ( rawEvent . state_key === undefined ) throw new Error ( " Not a state event" ) ;
11561177 if (
11571178 ( rawEvent . room_id === this . viewedRoomId || this . canUseRoomTimeline ( rawEvent . room_id ) )
11581179 && this . canReceiveStateEvent ( rawEvent . type , rawEvent . state_key )
11591180 ) {
11601181 // Updates could race with the initial push of the room's state
11611182 if ( this . pushRoomStateTasks . size === 0 ) {
11621183 // No initial push tasks are pending; safe to send immediately
1163- await this . transport . send < IUpdateStateToWidgetRequestData > (
1164- WidgetApiToWidgetAction . UpdateState ,
1165- { state : [ rawEvent ] } ,
1166- ) ;
1184+ if ( ( await this . getWidgetVersions ( ) ) . includes ( UnstableApiVersion . MSC2762_UPDATE_STATE ) ) {
1185+ // Only send state updates when using UpdateState. Otherwise the SendEvent action will be responsible for state updates.
1186+ await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1187+ state : [ rawEvent ] ,
1188+ } ) ;
1189+ }
11671190 } else {
11681191 // Lump the update in with whatever data will be sent in the
11691192 // initial push later. Even if we set it to an "outdated" entry
0 commit comments