Repository navigation
fix(chat-list): mark read moves READ to the highest stored message id - #1955
Merged
Merged
Conversation
Mark as Read from the chat list left the unread badge up, e.g. 4 dropped to 3. markAsRead took its target from ChatMessageDao.getLatest, which orders by timestamp only. The badge compares the READ pointer by id against the newest visible message, ordered by timestamp then id. When two messages share a millisecond and the older row is the later insert (the feed writes a chat's newest message before the history load fills in older ones), getLatest returns the older one and READ lands short. Both sides read the same local table, so the store is not behind the badge; the two queries disagree on order. Opening the chat works because it advances to the id of a message on screen. The list path now uses MAX(message_id) over positive ids, tombstones included. Excluding negative ids also stops an unsent placeholder from being picked, which used to send the server a negative READ.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Mark as Read from the chat list (swipe, select mode, Read All) left the unread badge up: a badge of 4 dropped to 3 instead of clearing. Opening the chat cleared it.
Cause
MessagingDelegate.markAsReadtook its target fromChatMessageDataSource.getLatestMessageId, which readChatMessageDao.getLatest:The badge (
FeedProjection.unreadCount) compares the READ pointer by id against the newest visible message, whichgetLatestVisibleorders bytimestamp_epoch_ms DESC, message_id DESC. When two messages share a millisecond and the older row was inserted later,getLatestreturns the older one. That ordering is normal: the feed write stores a chat's newest message first, and the history load fills in older ones afterwards. READ then lands below the newest message and the count drops instead of clearing.The store is not behind the server here. The badge reads the same local table (
FeedSyncDelegate.buildFeedFromDbandtoSummaryboth usegetLatestVisible), and the feed write persists each chat's preview row before the transcript loads. So the metadata'slast_message_idwould not move the pointer any further than the highest stored id does. The two queries just order the rows differently.Opening the chat works because
ChatViewModeladvances to the id of a message on screen.Fix
New
ChatMessageDao.getNewestMessageId:MAX(message_id)over positive ids, tombstones included. That is the order the badge compares in.getLatestMessageId, whose only caller ismarkAsRead, now uses it. Leaving out negative ids also means an unsent placeholder can't be picked anymore. A placeholder's timestamp comes from the device clock, so it could win the old timestamp sort, and the server would then get a negative READ. That case doesn't produce this bug, since a pending send is the user's own message and the badge already reads 0, but the server shouldn't get a negative READ either way.getLatestkeeps its other callers (hasMessagesand the receive buzz) unchanged.Test
MarkReadAnchorTest(persistence sources, Robolectric, real database):