From db46c2960be5a549ed59bc0e4cee3a005b7fcfb1 Mon Sep 17 00:00:00 2001
From: Brice-W <brice@loki.network>
Date: Fri, 16 Jul 2021 13:32:58 +1000
Subject: [PATCH] update in marking read message

---
 .../conversation/ReadableMessage.tsx          |  2 +-
 ts/models/conversation.ts                     | 20 +++++++++++++++++--
 ts/test/test-utils/utils/message.ts           |  1 +
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/ts/components/conversation/ReadableMessage.tsx b/ts/components/conversation/ReadableMessage.tsx
index f907ca1b8..2dc6ed992 100644
--- a/ts/components/conversation/ReadableMessage.tsx
+++ b/ts/components/conversation/ReadableMessage.tsx
@@ -31,7 +31,7 @@ export const ReadableMessage = (props: ReadableMessageProps) => {
   useFocus(onChange);
 
   return (
-    <InView {...props} as="div" threshold={1} delay={200} triggerOnce={true}>
+    <InView {...props} as="div" threshold={1} delay={200} triggerOnce={false}>
       {props.children}
     </InView>
   );
diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts
index dd3dcf64e..0d035be28 100644
--- a/ts/models/conversation.ts
+++ b/ts/models/conversation.ts
@@ -92,6 +92,7 @@ export interface ConversationAttributes {
   triggerNotificationsFor: ConversationNotificationSettingType;
   isTrustedForAttachmentDownload: boolean;
   isPinned: boolean;
+  lastReadTimestamp: number;
 }
 
 export interface ConversationAttributesOptionals {
@@ -160,6 +161,7 @@ export const fillConvoAttributesWithDefaults = (
     triggerNotificationsFor: 'all', // if the settings is not set in the db, this is the default
     isTrustedForAttachmentDownload: false, // we don't trust a contact until we say so
     isPinned: false,
+    lastReadTimestamp: 0,
   });
 };
 
@@ -188,7 +190,16 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
     this.updateLastMessage = _.throttle(this.bouncyUpdateLastMessage.bind(this), 1000);
     this.throttledNotify = _.debounce(this.notify, 500, { maxWait: 1000 });
     //start right away the function is called, and wait 1sec before calling it again
-    this.markRead = _.debounce(this.markReadBouncy, 1000, { leading: true });
+    //this.markRead = _.debounce(this.markReadBouncy, 1000, { leading: true });
+    const markReadBouncy = _.debounce(this.markReadBouncy, 1000, { leading: true })
+    this.markRead = (newestUnreadDate: number) => {
+      const lastReadTimestamp = this.get('lastReadTimestamp');
+      if (newestUnreadDate > lastReadTimestamp)
+      this.set({
+        lastReadTimestamp: newestUnreadDate,
+      });
+      markReadBouncy(newestUnreadDate);
+    }
     // Listening for out-of-band data updates
 
     this.typingRefreshTimer = null;
@@ -903,6 +914,11 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
 
   public async markReadBouncy(newestUnreadDate: number, providedOptions: any = {}) {
 
+    const lastReadTimestamp = this.get('lastReadTimestamp');
+    if (newestUnreadDate < lastReadTimestamp) {
+      return;
+    }
+
     const options = providedOptions || {};
     _.defaults(options, { sendReadReceipts: true });
 
@@ -948,7 +964,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
       const cachedUnreadCountOnConvo = this.get('unreadCount');
       if (cachedUnreadCountOnConvo !== read.length) {
         // reset the unreadCount on the convo to the real one coming from markRead messages on the db
-        this.set({ unreadCount: 0 });
+        this.set({ unreadCount: realUnreadCount });
         await this.commit();
       } else {
         // window?.log?.info('markRead(): nothing newly read.');
diff --git a/ts/test/test-utils/utils/message.ts b/ts/test/test-utils/utils/message.ts
index 4d0cdf6f2..809a0a96e 100644
--- a/ts/test/test-utils/utils/message.ts
+++ b/ts/test/test-utils/utils/message.ts
@@ -89,6 +89,7 @@ export class MockConversation {
       triggerNotificationsFor: 'all',
       isTrustedForAttachmentDownload: false,
       isPinned: false,
+      lastReadTimestamp: 0,
     };
   }