From 46acb489691e5298181ce52bfe847889ee06fe68 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 28 Aug 2026 18:37:47 +0200 Subject: feat: read a thread's digest from the index Senders, unread messages and an activity histogram for the dashboard, as a plain value struct over a queued signal. Everything comes from the index, so no message file is opened; the unread list is capped and unreadTotal carries the real number. --- src/notmuchworker.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/notmuchworker.h') diff --git a/src/notmuchworker.h b/src/notmuchworker.h index 8171f3c..a0c8feb 100644 --- a/src/notmuchworker.h +++ b/src/notmuchworker.h @@ -24,6 +24,7 @@ #include #include +#include "threaddigest.h" #include "types.h" struct _notmuch_database; @@ -110,6 +111,35 @@ public slots: void loadThreadTree(const QString &threadId, const QString &matchQuery, quint64 generation); + /// Everything the thread dashboard shows, from ONE walk of the index. + /// + /// Sender counts, the newest unread messages, and an activity histogram, + /// all served from the index: no message file is opened, which is the + /// contract ThreadDigest states and the reason this can run on every + /// selection. See threaddigest.h. + /// + /// \p generation is the DASHBOARD's own counter, never m_generation's + /// query generation. Bumping that one would discard a thread load in + /// flight and blank the message pane because the user selected a row, + /// which is the rule requestMessageCounts and countSenders already follow. + /// + /// A thread id the index does not hold yields an EMPTY digest rather than + /// silence, for the reason loadMessage() documents: a caller that arms + /// state on the request and disarms it on the reply otherwise waits for + /// ever. + void loadThreadDigest(const QString &threadId, quint64 generation); + +public: + /// The first thread id matching \p query, for tests. + /// + /// A test knows a message id and needs the thread id the digest call + /// takes; nothing in the UI ever needs this, since every caller there + /// already holds a thread id from a query result. Not a slot, so it cannot + /// be reached across the thread boundary by accident. + QString threadIdForTesting(const QString &query); + +public slots: + /// Loads ONE message, for a message row selected in the list. /// /// Emits messageLoaded with an empty vector when the id is unknown, which @@ -315,6 +345,10 @@ signals: void threadTreeLoaded(const QVector &nodes, quint64 generation); void messageLoaded(const QVector &messages, quint64 generation); + + /// The dashboard's digest. `generation` is the dashboard's own counter, + /// echoed back so a stale answer can be discarded. + void threadDigestLoaded(const ThreadDigest &digest, quint64 generation); void tagsApplied(const TagChange &change); /// Carries the ids that ACTUALLY moved, which may be fewer than requested. -- cgit v1.2.3