imap: Don't emit `MsgsNoticed` if a chat still has unseen messages
See discussion in https://github.com/chatmail/core/pull/6415:
On Android, MsgsNoticed removes all notifications of the current chat, so, it's too "dangerous" to emit it more often just to fix an edge case.
Then the code in
sync_seen_flags()is a bug because it emitsMsgsNoticedif some messages were seen on another device.
I confirm this behaviour. I sent several long messages from another profile, then opened the chat in Desktop, but have only seen the first one, and then saw that all notifications were removed in my Android, though the badge counter is still non-zero. This is a bug,
mark_seen_by_uid()must returnNoneinstead of the chat id if the chat still has other unseen messages. Or it should return an additional bool flag.
imap::Session::sync_seen_flags() is called after fetch_move_delete(), so the syncing device may already have more messages and remove fresh notifications. But even if we run sync_seen_flags() earlier, it would be a race condition in the IMAP loop, so it's better to only emit MsgsNoticed if all chat messages are seen.
Messages become "seen" when they are displayed on the screen. Message become "noticed" when the chat is opened. Badge counter displays the number of fresh messages and noticed messages are not count as fresh.
In many chats there is always at least one unseen message because the user at some point opened the chat and did not scroll through the whole backlog. If we don't emit MsgsNoticed because the chat still has unseen messages, then for many chats we will never emit MsgsNoticed.
The problem with MsgsNoticed event is that it does not tell which messages are noticed so UI cannot tell which notifications should be dismissed. If you receive messages A, B and C on your device, then B gets seen because the user opened it on another device, it means A and B should now become noticed and UI should dismiss notifications for A and B. Message C should not become noticed and its notification should be kept because it is not known it if was even received when the message B was seen on another device.
The problem with
MsgsNoticedevent is that it does not tell which messages are noticed [...]
Exactly. The current approach is to emit MsgsNoticed and effectively remove all notifications on the second device, but it can cause missing notifications. This doesn't look acceptable (though it's just my opinion), so either we should rework this completely or implement what this issue suggests for now. #6415 can make the situation a bit better, at least sometimes notifications will be removed on the second device (i didn't get why it was closed, it doesn't add any code that may lead to missing notifications).