diff --git a/ts/messageModifiers/ReadSyncs.ts b/ts/messageModifiers/ReadSyncs.ts index 3c388e69f..01cd86355 100644 --- a/ts/messageModifiers/ReadSyncs.ts +++ b/ts/messageModifiers/ReadSyncs.ts @@ -115,6 +115,7 @@ export async function onSync(sync: ReadSyncAttributesType): Promise { const message = window.MessageController.register(found.id, found); const readAt = Math.min(sync.readAt, Date.now()); + const newestSentAt = sync.timestamp; // If message is unread, we mark it read. Otherwise, we update the expiration // timer to the time specified by the read sync if it's earlier than @@ -127,7 +128,11 @@ export async function onSync(sync: ReadSyncAttributesType): Promise { // onReadMessage may result in messages older than this one being // marked read. We want those messages to have the same expire timer // start time as this one, so we pass the readAt value through. - drop(message.getConversation()?.onReadMessage(message, readAt)); + drop( + message + .getConversation() + ?.onReadMessage(message, readAt, newestSentAt) + ); }; // only available during initialization diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index cd7570634..1770194cf 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -3306,7 +3306,11 @@ export class ConversationModel extends window.Backbone ); } - async onReadMessage(message: MessageModel, readAt?: number): Promise { + async onReadMessage( + message: MessageModel, + readAt?: number, + newestSentAt?: number + ): Promise { // We mark as read everything older than this message - to clean up old stuff // still marked unread in the database. If the user generally doesn't read in // the desktop app, so the desktop app only gets read syncs, we can very @@ -3321,7 +3325,7 @@ export class ConversationModel extends window.Backbone return this.queueJob('onReadMessage', () => // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.markRead(message.get('received_at')!, { - newestSentAt: message.get('sent_at'), + newestSentAt: newestSentAt || message.get('sent_at'), sendReadReceipts: false, readAt, }) diff --git a/ts/util/modifyTargetMessage.ts b/ts/util/modifyTargetMessage.ts index 73f564681..680341437 100644 --- a/ts/util/modifyTargetMessage.ts +++ b/ts/util/modifyTargetMessage.ts @@ -19,6 +19,7 @@ import { SeenStatus } from '../MessageSeenStatus'; import { SendActionType, sendStateReducer } from '../messages/MessageSendState'; import { canConversationBeUnarchived } from './canConversationBeUnarchived'; import { deleteForEveryone } from './deleteForEveryone'; +import { drop } from './drop'; import { handleEditMessage } from './handleEditMessage'; import { isGroup } from './whatTypeOfConversation'; import { isStory, isTapToView } from '../state/selectors/message'; @@ -167,6 +168,7 @@ export async function modifyTargetMessage( if (!isFirstRun && message.getPendingMarkRead()) { const markReadAt = message.getPendingMarkRead(); message.setPendingMarkRead(undefined); + const newestSentAt = readSync?.timestamp; // This is primarily to allow the conversation to mark all older // messages as read, as is done when we receive a read sync for @@ -175,7 +177,11 @@ export async function modifyTargetMessage( // We run message when `isFirstRun` is false so that it triggers when the // message and the other ones accompanying it in the batch are fully in // the database. - void message.getConversation()?.onReadMessage(message, markReadAt); + drop( + message + .getConversation() + ?.onReadMessage(message, markReadAt, newestSentAt) + ); } // Check for out-of-order view once open syncs