@@ -47,12 +47,6 @@ import type CardService from '../services/card-service';
47
47
import type CommandService from '../services/command-service' ;
48
48
import type MatrixService from '../services/matrix-service' ;
49
49
50
- interface SkillId {
51
- skillCardId : string ;
52
- skillEventId : string ;
53
- isActive : boolean ;
54
- }
55
-
56
50
interface Args {
57
51
named : {
58
52
roomId : string | undefined ;
@@ -62,6 +56,8 @@ interface Args {
62
56
63
57
export class RoomResource extends Resource < Args > {
64
58
private _messageCache : TrackedMap < string , Message > = new TrackedMap ( ) ;
59
+ private _skillEventIdToCardIdCache : TrackedMap < string , string > =
60
+ new TrackedMap ( ) ;
65
61
private _skillCardsCache : TrackedMap < string , SkillCard > = new TrackedMap ( ) ;
66
62
private _nameEventsCache : TrackedMap < string , RoomNameEvent > =
67
63
new TrackedMap ( ) ;
@@ -103,7 +99,33 @@ export class RoomResource extends Resource<Args> {
103
99
if ( ! memberIds || ! memberIds . includes ( this . matrixService . aiBotUserId ) ) {
104
100
return ;
105
101
}
106
- await this . loadFromEvents ( roomId ) ;
102
+
103
+ let index = this . _messageCache . size ;
104
+ // This is brought up to this level so if the
105
+ // load task is rerun we can stop processing
106
+ for ( let event of this . sortedEvents ) {
107
+ switch ( event . type ) {
108
+ case 'm.room.member' :
109
+ await this . loadRoomMemberEvent ( roomId , event ) ;
110
+ break ;
111
+ case 'm.room.message' :
112
+ if ( this . isCardFragmentEvent ( event ) ) {
113
+ await this . loadCardFragment ( event ) ;
114
+ } else {
115
+ await this . loadRoomMessage ( { roomId, event, index } ) ;
116
+ }
117
+ break ;
118
+ case APP_BOXEL_COMMAND_RESULT_EVENT_TYPE :
119
+ this . updateMessageCommandResult ( { roomId, event, index } ) ;
120
+ break ;
121
+ case 'm.room.create' :
122
+ await this . loadRoomCreateEvent ( event ) ;
123
+ break ;
124
+ case 'm.room.name' :
125
+ await this . loadRoomNameEvent ( event ) ;
126
+ break ;
127
+ }
128
+ }
107
129
} catch ( e ) {
108
130
throw new Error ( `Error loading room ${ e } ` ) ;
109
131
}
@@ -165,61 +187,41 @@ export class RoomResource extends Resource<Args> {
165
187
return this . events . sort ( ( a , b ) => a . origin_server_ts - b . origin_server_ts ) ;
166
188
}
167
189
168
- @cached
169
- get skillIds ( ) : SkillId [ ] {
190
+ get allSkillEventIds ( ) : Set < string > {
170
191
let skillsConfig = this . matrixRoom ?. skillsConfig ;
171
192
if ( ! skillsConfig ) {
172
- return [ ] ;
193
+ return new Set ( ) ;
173
194
}
174
- let result : SkillId [ ] = [ ] ;
175
- for ( let eventId of [
195
+ return new Set ( [
176
196
...skillsConfig . enabledEventIds ,
177
197
...skillsConfig . disabledEventIds ,
178
- ] ) {
179
- let cardDoc ;
180
- try {
181
- cardDoc = this . serializedCardFromFragments ( eventId ) ;
182
- } catch {
183
- // the skill card fragments might not be loaded yet
198
+ ] ) ;
199
+ }
200
+
201
+ get skills ( ) : Skill [ ] {
202
+ let skillsConfig = this . matrixRoom ?. skillsConfig ;
203
+ if ( ! skillsConfig ) {
204
+ return [ ] ;
205
+ }
206
+ let result : Skill [ ] = [ ] ;
207
+ for ( let skillEventId of this . allSkillEventIds ) {
208
+ let cardId = this . _skillEventIdToCardIdCache . get ( skillEventId ) ;
209
+ if ( ! cardId ) {
184
210
continue ;
185
211
}
186
- if ( ! cardDoc . data . id ) {
212
+ let skillCard = this . _skillCardsCache . get ( cardId ) ;
213
+ if ( ! skillCard ) {
187
214
continue ;
188
215
}
189
- let cardId = cardDoc . data . id ;
190
- if ( ! this . _skillCardsCache . has ( cardId ) ) {
191
- this . cardService
192
- . createFromSerialized ( cardDoc . data , cardDoc )
193
- . then ( ( skillsCard ) => {
194
- this . _skillCardsCache . set ( cardId , skillsCard as SkillCard ) ;
195
- } ) ;
196
- }
197
216
result . push ( {
198
- skillCardId : cardDoc . data . id ,
199
- skillEventId : eventId ,
200
- isActive : skillsConfig . enabledEventIds . includes ( eventId ) ,
217
+ card : skillCard ,
218
+ skillEventId,
219
+ isActive : skillsConfig . enabledEventIds . includes ( skillEventId ) ,
201
220
} ) ;
202
221
}
203
222
return result ;
204
223
}
205
224
206
- @cached
207
- get skills ( ) : Skill [ ] {
208
- return this . skillIds
209
- . map ( ( { skillCardId, skillEventId, isActive } ) => {
210
- let card = this . _skillCardsCache . get ( skillCardId ) ;
211
- if ( card ) {
212
- return {
213
- card,
214
- skillEventId,
215
- isActive,
216
- } ;
217
- }
218
- return null ;
219
- } )
220
- . filter ( Boolean ) as Skill [ ] ;
221
- }
222
-
223
225
@cached
224
226
get created ( ) {
225
227
if ( this . _createEvent ) {
@@ -280,30 +282,6 @@ export class RoomResource extends Resource<Args> {
280
282
}
281
283
} ) ;
282
284
283
- private async loadFromEvents ( roomId : string ) {
284
- let index = this . _messageCache . size ;
285
-
286
- for ( let event of this . sortedEvents ) {
287
- switch ( event . type ) {
288
- case 'm.room.member' :
289
- await this . loadRoomMemberEvent ( roomId , event ) ;
290
- break ;
291
- case 'm.room.message' :
292
- this . loadRoomMessage ( { roomId, event, index } ) ;
293
- break ;
294
- case APP_BOXEL_COMMAND_RESULT_EVENT_TYPE :
295
- this . updateMessageCommandResult ( { roomId, event, index } ) ;
296
- break ;
297
- case 'm.room.create' :
298
- await this . loadRoomCreateEvent ( event ) ;
299
- break ;
300
- case 'm.room.name' :
301
- await this . loadRoomNameEvent ( event ) ;
302
- break ;
303
- }
304
- }
305
- }
306
-
307
285
private async loadRoomMemberEvent (
308
286
roomId : string ,
309
287
event : InviteEvent | JoinEvent | LeaveEvent ,
@@ -330,23 +308,6 @@ export class RoomResource extends Resource<Args> {
330
308
roomId : string ;
331
309
event : MessageEvent | CommandEvent | CardMessageEvent ;
332
310
index : number ;
333
- } ) {
334
- if ( event . content . msgtype === APP_BOXEL_CARDFRAGMENT_MSGTYPE ) {
335
- this . _fragmentCache . set ( event . event_id , event . content ) ;
336
- return ;
337
- }
338
-
339
- this . upsertMessage ( { roomId, event, index } ) ;
340
- }
341
-
342
- private upsertMessage ( {
343
- roomId,
344
- event,
345
- index,
346
- } : {
347
- roomId : string ;
348
- event : MessageEvent | CommandEvent | CardMessageEvent ;
349
- index : number ;
350
311
} ) {
351
312
let effectiveEventId = this . getEffectiveEventId ( event ) ;
352
313
@@ -362,6 +323,7 @@ export class RoomResource extends Resource<Args> {
362
323
index,
363
324
serializedCardFromFragments : this . serializedCardFromFragments ,
364
325
events : this . events ,
326
+ skills : this . skills ,
365
327
} ) ;
366
328
367
329
if ( ! message ) {
@@ -407,6 +369,7 @@ export class RoomResource extends Resource<Args> {
407
369
index,
408
370
serializedCardFromFragments : this . serializedCardFromFragments ,
409
371
events : this . events ,
372
+ skills : this . skills ,
410
373
commandResultEvent : event ,
411
374
} ) ;
412
375
messageBuilder . updateMessageCommandResult ( message ) ;
@@ -508,6 +471,47 @@ export class RoomResource extends Resource<Args> {
508
471
! this . isDisplayingCode ( message ) ,
509
472
) ;
510
473
}
474
+
475
+ private async loadCardFragment (
476
+ event : CardMessageEvent & {
477
+ content : { msgtype : typeof APP_BOXEL_CARDFRAGMENT_MSGTYPE } ;
478
+ } ,
479
+ ) {
480
+ let eventId = event . event_id ;
481
+ this . _fragmentCache . set ( eventId , event . content ) ;
482
+ if (
483
+ ! this . allSkillEventIds . has ( eventId ) ||
484
+ this . _skillEventIdToCardIdCache . has ( eventId )
485
+ ) {
486
+ return ;
487
+ }
488
+ await this . loadSkillCardIntoCache ( eventId ) ;
489
+ }
490
+
491
+ private async loadSkillCardIntoCache ( eventId : string ) {
492
+ let cardDoc = this . serializedCardFromFragments ( eventId ) ;
493
+ if ( ! cardDoc . data . id ) {
494
+ console . warn (
495
+ `No card id found for skill event id ${ eventId } , this should not happen, this can happen if you add a skill card to a room without saving it, and without giving it an ID` ,
496
+ ) ;
497
+ return ;
498
+ }
499
+ let cardId = cardDoc . data . id ;
500
+ let skillCard = ( await this . cardService . createFromSerialized (
501
+ cardDoc . data ,
502
+ cardDoc ,
503
+ ) ) as SkillCard ;
504
+ this . _skillCardsCache . set ( cardId , skillCard ) ;
505
+ this . _skillEventIdToCardIdCache . set ( eventId , cardId ) ;
506
+ }
507
+
508
+ private isCardFragmentEvent (
509
+ event : MessageEvent | CommandEvent | CardMessageEvent ,
510
+ ) : event is CardMessageEvent & {
511
+ content : { msgtype : typeof APP_BOXEL_CARDFRAGMENT_MSGTYPE } ;
512
+ } {
513
+ return event . content . msgtype === APP_BOXEL_CARDFRAGMENT_MSGTYPE ;
514
+ }
511
515
}
512
516
513
517
export function getRoom (
0 commit comments