@@ -19,6 +19,7 @@ import {
1919 MatrixCapabilities ,
2020 OpenIDRequestState ,
2121 SimpleObservable ,
22+ Symbols ,
2223 Widget ,
2324 WidgetDriver ,
2425 WidgetEventCapability ,
@@ -35,6 +36,7 @@ import {
3536 IContent ,
3637 MatrixError ,
3738 MatrixEvent ,
39+ Room ,
3840 Direction ,
3941 THREAD_RELATION_TYPE ,
4042 SendDelayedEventResponse ,
@@ -467,69 +469,70 @@ export class StopGapWidgetDriver extends WidgetDriver {
467469 }
468470 }
469471
470- /**
471- * Reads all events of the given type, and optionally `msgtype` (if applicable/defined),
472- * the user has access to. The widget API will have already verified that the widget is
473- * capable of receiving the events. Less events than the limit are allowed to be returned,
474- * but not more.
475- * @param roomId The ID of the room to look within.
476- * @param eventType The event type to be read.
477- * @param msgtype The msgtype of the events to be read, if applicable/defined.
478- * @param stateKey The state key of the events to be read, if applicable/defined.
479- * @param limit The maximum number of events to retrieve. Will be zero to denote "as many as
480- * possible".
481- * @param since When null, retrieves the number of events specified by the "limit" parameter.
482- * Otherwise, the event ID at which only subsequent events will be returned, as many as specified
483- * in "limit".
484- * @returns {Promise<IRoomEvent[]> } Resolves to the room events, or an empty array.
485- */
486- public async readRoomTimeline (
487- roomId : string ,
472+ private pickRooms ( roomIds ?: ( string | Symbols . AnyRoom ) [ ] ) : Room [ ] {
473+ const client = MatrixClientPeg . get ( ) ;
474+ if ( ! client ) throw new Error ( "Not attached to a client" ) ;
475+
476+ const targetRooms = roomIds
477+ ? roomIds . includes ( Symbols . AnyRoom )
478+ ? client . getVisibleRooms ( SettingsStore . getValue ( "feature_dynamic_room_predecessors" ) )
479+ : roomIds . map ( ( r ) => client . getRoom ( r ) )
480+ : [ client . getRoom ( SdkContextClass . instance . roomViewStore . getRoomId ( ) ! ) ] ;
481+ return targetRooms . filter ( ( r ) => ! ! r ) as Room [ ] ;
482+ }
483+
484+ public async readRoomEvents (
488485 eventType : string ,
489486 msgtype : string | undefined ,
490- stateKey : string | undefined ,
491- limit : number ,
492- since : string | undefined ,
487+ limitPerRoom : number ,
488+ roomIds ?: ( string | Symbols . AnyRoom ) [ ] ,
493489 ) : Promise < IRoomEvent [ ] > {
494- limit = limit > 0 ? Math . min ( limit , Number . MAX_SAFE_INTEGER ) : Number . MAX_SAFE_INTEGER ; // relatively arbitrary
495-
496- const room = MatrixClientPeg . safeGet ( ) . getRoom ( roomId ) ;
497- if ( room === null ) return [ ] ;
498- const results : MatrixEvent [ ] = [ ] ;
499- const events = room . getLiveTimeline ( ) . getEvents ( ) ; // timelines are most recent last
500- for ( let i = events . length - 1 ; i >= 0 ; i -- ) {
501- const ev = events [ i ] ;
502- if ( results . length >= limit ) break ;
503- if ( since !== undefined && ev . getId ( ) === since ) break ;
504-
505- if ( ev . getType ( ) !== eventType || ev . isState ( ) ) continue ;
506- if ( eventType === EventType . RoomMessage && msgtype && msgtype !== ev . getContent ( ) [ "msgtype" ] ) continue ;
507- if ( ev . getStateKey ( ) !== undefined && stateKey !== undefined && ev . getStateKey ( ) !== stateKey ) continue ;
508- results . push ( ev ) ;
509- }
490+ limitPerRoom = limitPerRoom > 0 ? Math . min ( limitPerRoom , Number . MAX_SAFE_INTEGER ) : Number . MAX_SAFE_INTEGER ; // relatively arbitrary
491+
492+ const rooms = this . pickRooms ( roomIds ) ;
493+ const allResults : IRoomEvent [ ] = [ ] ;
494+ for ( const room of rooms ) {
495+ const results : MatrixEvent [ ] = [ ] ;
496+ const events = room . getLiveTimeline ( ) . getEvents ( ) ; // timelines are most recent last
497+ for ( let i = events . length - 1 ; i > 0 ; i -- ) {
498+ if ( results . length >= limitPerRoom ) break ;
499+
500+ const ev = events [ i ] ;
501+ if ( ev . getType ( ) !== eventType || ev . isState ( ) ) continue ;
502+ if ( eventType === EventType . RoomMessage && msgtype && msgtype !== ev . getContent ( ) [ "msgtype" ] ) continue ;
503+ results . push ( ev ) ;
504+ }
510505
511- return results . map ( ( e ) => e . getEffectiveEvent ( ) as IRoomEvent ) ;
506+ results . forEach ( ( e ) => allResults . push ( e . getEffectiveEvent ( ) as IRoomEvent ) ) ;
507+ }
508+ return allResults ;
512509 }
513510
514- /**
515- * Reads the current values of all matching room state entries.
516- * @param roomId The ID of the room.
517- * @param eventType The event type of the entries to be read.
518- * @param stateKey The state key of the entry to be read. If undefined,
519- * all room state entries with a matching event type should be returned.
520- * @returns {Promise<IRoomEvent[]> } Resolves to the events representing the
521- * current values of the room state entries.
522- */
523- public async readRoomState ( roomId : string , eventType : string , stateKey : string | undefined ) : Promise < IRoomEvent [ ] > {
524- const room = MatrixClientPeg . safeGet ( ) . getRoom ( roomId ) ;
525- if ( room === null ) return [ ] ;
526- const state = room . getLiveTimeline ( ) . getState ( Direction . Forward ) ;
527- if ( state === undefined ) return [ ] ;
528-
529- if ( stateKey === undefined )
530- return state . getStateEvents ( eventType ) . map ( ( e ) => e . getEffectiveEvent ( ) as IRoomEvent ) ;
531- const event = state . getStateEvents ( eventType , stateKey ) ;
532- return event === null ? [ ] : [ event . getEffectiveEvent ( ) as IRoomEvent ] ;
511+ public async readStateEvents (
512+ eventType : string ,
513+ stateKey : string | undefined ,
514+ limitPerRoom : number ,
515+ roomIds ?: ( string | Symbols . AnyRoom ) [ ] ,
516+ ) : Promise < IRoomEvent [ ] > {
517+ limitPerRoom = limitPerRoom > 0 ? Math . min ( limitPerRoom , Number . MAX_SAFE_INTEGER ) : Number . MAX_SAFE_INTEGER ; // relatively arbitrary
518+
519+ const rooms = this . pickRooms ( roomIds ) ;
520+ const allResults : IRoomEvent [ ] = [ ] ;
521+ for ( const room of rooms ) {
522+ const results : MatrixEvent [ ] = [ ] ;
523+ const state = room . currentState . events . get ( eventType ) ;
524+ if ( state ) {
525+ if ( stateKey === "" || ! ! stateKey ) {
526+ const forKey = state . get ( stateKey ) ;
527+ if ( forKey ) results . push ( forKey ) ;
528+ } else {
529+ results . push ( ...Array . from ( state . values ( ) ) ) ;
530+ }
531+ }
532+
533+ results . slice ( 0 , limitPerRoom ) . forEach ( ( e ) => allResults . push ( e . getEffectiveEvent ( ) as IRoomEvent ) ) ;
534+ }
535+ return allResults ;
533536 }
534537
535538 public async askOpenID ( observer : SimpleObservable < IOpenIDUpdate > ) : Promise < void > {
@@ -690,17 +693,6 @@ export class StopGapWidgetDriver extends WidgetDriver {
690693 return { file : blob } ;
691694 }
692695
693- /**
694- * Gets the IDs of all joined or invited rooms currently known to the
695- * client.
696- * @returns The room IDs.
697- */
698- public getKnownRooms ( ) : string [ ] {
699- return MatrixClientPeg . safeGet ( )
700- . getVisibleRooms ( SettingsStore . getValue ( "feature_dynamic_room_predecessors" ) )
701- . map ( ( r ) => r . roomId ) ;
702- }
703-
704696 /**
705697 * Expresses a {@link MatrixError} as a JSON payload
706698 * for use by Widget API error responses.
0 commit comments