aboutsummaryrefslogtreecommitdiffstats
path: root/src/mainwindow.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-28 19:00:59 +0200
committerDanilo M. <danix@danix.xyz>2026-08-28 19:00:59 +0200
commitae74237ca11640ceb68887b2c6d09ecf1befb342 (patch)
tree6ae37c5ed27eeb27c55a17febe16d03fa3553503 /src/mainwindow.h
parent46acb489691e5298181ce52bfe847889ee06fe68 (diff)
downloadqtmaildir-ae74237ca11640ceb68887b2c6d09ecf1befb342.tar.gz
qtmaildir-ae74237ca11640ceb68887b2c6d09ecf1befb342.zip
feat: show the dashboard when a conversation is selected
A thread row has no message to render, so the pane shows the conversation instead. A thread of one message still opens its message on one click, and the automatic mark-read is not armed for a row that displays nothing.
Diffstat (limited to 'src/mainwindow.h')
-rw-r--r--src/mainwindow.h44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 11f35e7..16bf8c4 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -41,6 +41,7 @@
#include "tagrules.h"
#include "syncmonitor.h"
#include "tagcolors.h"
+#include "threaddigest.h"
#include "types.h"
// Held by value: the parsed business-senders list is a member, and the load is
@@ -585,6 +586,22 @@ private slots:
/// Selects the remembered message once its thread's rows have loaded.
void applyPendingRecovery();
+
+ /// Selects \p messageId inside the currently selected conversation,
+ /// expanding it first (item 177).
+ ///
+ /// For the dashboard's unread entries. Deliberately NOT recoverStaleThread(),
+ /// which runs thread:<id> as a new query: the thread is already in the list
+ /// the user is looking at, and replacing that list to reach a row it
+ /// already holds would throw away the view they came from.
+ ///
+ /// A reply row does not exist until the expansion's replies arrive, so the
+ /// target is remembered and applied again when they do.
+ void selectMessageInCurrentThread(const QString &messageId);
+
+ /// Applies a pending selectMessageInCurrentThread() target, if any.
+ void applyPendingDashboardSelection();
+
void onThreadsReady(const QVector<ThreadSummary> &threads, quint64 generation);
void onQueryFinished(int total, quint64 generation);
void onThreadSelected(const QModelIndex &current, const QModelIndex &previous);
@@ -609,6 +626,15 @@ private slots:
/// Renders the single message a message row asked for.
void onMessageLoaded(const QVector<MessageRef> &messages,
quint64 generation);
+
+ /// Fills the conversation dashboard once the worker has read the digest.
+ ///
+ /// Guarded the way onMessageLoaded() is, and for the same reason: the
+ /// request crosses on a queued connection, so the answer arrives after
+ /// whatever the user did in the meantime. A digest for a thread the pane
+ /// has moved off, or one that arrives once the pane is showing a message,
+ /// must not repaint anything.
+ void onThreadDigestLoaded(const ThreadDigest &digest, quint64 generation);
void onWorkerError(const QString &message);
void onSyncFinished(bool success, int exitCode);
@@ -1601,6 +1627,24 @@ private:
QString m_lastQuery;
QString m_currentThreadId;
+ /// The digest request's own generation, bumped per request.
+ ///
+ /// Separate from m_generation, which is the QUERY generation: bumping that
+ /// one discards any thread load in flight and blanks the pane, so a
+ /// selection asking for a digest would cancel the work the selection
+ /// itself started.
+ quint64 m_digestGeneration = 0;
+
+ /// The thread the dashboard is showing, empty whenever it is not showing.
+ /// A late digest is matched against this, not against m_currentThreadId,
+ /// which is also set for a thread of one message that renders normally.
+ QString m_dashboardThreadId;
+
+ /// The message a dashboard entry asked for and the thread it is in, both
+ /// empty when nothing is waiting. See selectMessageInCurrentThread().
+ QString m_dashboardSelectMessageId;
+ QString m_dashboardSelectThreadId;
+
/// The message a MESSAGE row is showing, empty whenever the pane holds a
/// whole thread. The two are mutually exclusive and each clears the other,
/// so a late reply can tell which kind of selection it belongs to.