@@ -27,7 +27,7 @@ import { RoomState } from "./room-state";
2727import { ServerControlledNamespacedValue } from "../NamespacedValue" ;
2828import { logger } from "../logger" ;
2929import { ReadReceipt } from "./read-receipt" ;
30- import { ReceiptType } from "../@types/read_receipts" ;
30+ import { Receipt , ReceiptContent , ReceiptType } from "../@types/read_receipts" ;
3131
3232export enum ThreadEvent {
3333 New = "Thread.new" ,
@@ -50,6 +50,7 @@ interface IThreadOpts {
5050 room : Room ;
5151 client : MatrixClient ;
5252 pendingEventOrdering ?: PendingEventOrdering ;
53+ receipts ?: { event : MatrixEvent ; synthetic : boolean } [ ] ;
5354}
5455
5556export enum FeatureSupport {
@@ -127,6 +128,8 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
127128 this . room . on ( RoomEvent . LocalEchoUpdated , this . onEcho ) ;
128129 this . timelineSet . on ( RoomEvent . Timeline , this . onTimelineEvent ) ;
129130
131+ this . processReceipts ( opts . receipts ) ;
132+
130133 // even if this thread is thought to be originating from this client, we initialise it as we may be in a
131134 // gappy sync and a thread around this event may already exist.
132135 this . updateThreadMetadata ( ) ;
@@ -284,6 +287,26 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
284287 this . timeline = this . events ;
285288 }
286289
290+ /**
291+ * Processes the receipts that were caught during initial sync
292+ * When clients become aware of a thread, they try to retrieve those read receipts
293+ * and apply them to the current thread
294+ * @param receipts - A collection of the receipts cached from initial sync
295+ */
296+ private processReceipts ( receipts : { event : MatrixEvent ; synthetic : boolean } [ ] = [ ] ) : void {
297+ for ( const { event, synthetic } of receipts ) {
298+ const content = event . getContent < ReceiptContent > ( ) ;
299+ Object . keys ( content ) . forEach ( ( eventId : string ) => {
300+ Object . keys ( content [ eventId ] ) . forEach ( ( receiptType : ReceiptType | string ) => {
301+ Object . keys ( content [ eventId ] [ receiptType ] ) . forEach ( ( userId : string ) => {
302+ const receipt = content [ eventId ] [ receiptType ] [ userId ] as Receipt ;
303+ this . addReceiptToStructure ( eventId , receiptType as ReceiptType , userId , receipt , synthetic ) ;
304+ } ) ;
305+ } ) ;
306+ } ) ;
307+ }
308+ }
309+
287310 private getRootEventBundledRelationship ( rootEvent = this . rootEvent ) : IThreadBundledRelationship | undefined {
288311 return rootEvent ?. getServerAggregatedRelation < IThreadBundledRelationship > ( THREAD_RELATION_TYPE . name ) ;
289312 }
0 commit comments