aboutsummaryrefslogtreecommitdiffstats
path: root/src/threadlistmodel.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-14 20:02:14 +0200
committerDanilo M. <danix@danix.xyz>2026-08-14 20:02:14 +0200
commitbde7409ef817089298718376e46a57b2d303cf02 (patch)
tree5fea161c839e30474db0a16c79f20b5fca976ffb /src/threadlistmodel.h
parent66f1159136de5e2f032ddc83b5b4b4bde2659291 (diff)
downloadqtmaildir-bde7409ef817089298718376e46a57b2d303cf02.tar.gz
qtmaildir-bde7409ef817089298718376e46a57b2d303cf02.zip
fix(read): repaint the card when one message is marked read
Follows the message-scoped mark-read. The user reported the write going out with nothing visible changing: the status bar counted an unsynced edit while the card stayed bold and the message pane still showed the `unread` tag, until the next query corrected it. sendMessageTagChange made no optimistic model update on purpose, because applyTagChange is keyed by THREAD and repainting a whole row for a one-message edit would claim every reply had changed too. That trade is right for an explicit tag edit and wrong for auto mark-read, where the visible change IS the feature and the delay exists to deliver it. ThreadListModel::applyMessageTagChange updates the message wherever it is held, as a child row and as `first`, and lets the thread's summary follow only when the answer is unambiguous: a thread reads as unread while ANY message does, so the tag is cleared from the thread only when no other message still carries it. For an unexpanded multi-message thread the per-message tags are not loaded, so the summary is left for the next query rather than guessed at. Mutation checked: without the call the card holds `unread` for the full timeout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/threadlistmodel.h')
-rw-r--r--src/threadlistmodel.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/threadlistmodel.h b/src/threadlistmodel.h
index 2b8d2b0..f7abaf8 100644
--- a/src/threadlistmodel.h
+++ b/src/threadlistmodel.h
@@ -273,6 +273,23 @@ public:
void applyTagChange(const QString &threadId, const QStringList &added,
const QStringList &removed);
+ /// The same, scoped to ONE message.
+ ///
+ /// Updates that message's own tags wherever it is held: as a child row if
+ /// the thread is expanded, and as `first` when it is the thread's opening
+ /// message. The thread's summary tags follow only when the change is
+ /// unambiguous for the whole thread, which for `unread` means no other
+ /// message still carries it, since a thread reads as unread while any of
+ /// its messages does.
+ ///
+ /// Exists because auto mark-read touches one message and the card still
+ /// has to stop looking unread. applyTagChange() above cannot serve that:
+ /// it rewrites the thread's tags directly, which for a multi-message
+ /// thread would claim every reply had been read.
+ void applyMessageTagChange(const QString &messageId,
+ const QStringList &added,
+ const QStringList &removed);
+
private:
/// One thread root and the message rows expanded under it.
///