@@ -203,11 +203,33 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
203203 ) : void => {
204204 // Add a synthesized receipt when paginating forward in the timeline
205205 if ( ! toStartOfTimeline ) {
206- room ! . addLocalEchoReceipt ( event . getSender ( ) ! , event , ReceiptType . Read ) ;
206+ const sender = event . getSender ( ) ;
207+ if ( sender && room && this . shouldSendLocalEchoReceipt ( sender , event ) ) {
208+ room . addLocalEchoReceipt ( sender , event , ReceiptType . Read ) ;
209+ }
207210 }
208211 this . onEcho ( event , toStartOfTimeline ?? false ) ;
209212 } ;
210213
214+ private shouldSendLocalEchoReceipt ( sender : string , event : MatrixEvent ) : boolean {
215+ const recursionSupport = this . client . canSupport . get ( Feature . RelationsRecursion ) ?? ServerSupport . Unsupported ;
216+
217+ if ( recursionSupport === ServerSupport . Unsupported ) {
218+ // Normally we add a local receipt, but if we don't have
219+ // recursion support, then events may arrive out of order, so we
220+ // only create a receipt if it's after our existing receipt.
221+ const oldReceiptEventId = this . getReadReceiptForUserId ( sender ) ?. eventId ;
222+ if ( oldReceiptEventId ) {
223+ const receiptEvent = this . findEventById ( oldReceiptEventId ) ;
224+ if ( receiptEvent && receiptEvent . getTs ( ) > event . getTs ( ) ) {
225+ return false ;
226+ }
227+ }
228+ }
229+
230+ return true ;
231+ }
232+
211233 private onLocalEcho = ( event : MatrixEvent ) : void => {
212234 this . onEcho ( event , false ) ;
213235 } ;
0 commit comments