diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-04 19:54:40 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-04 19:54:40 +0200 |
| commit | bd1b907ba22464bb869bcc10cc9327ed74c44791 (patch) | |
| tree | c593b55f9a5fd4912104c33cddf59f894c9308aa /src/mainwindow.h | |
| parent | a1f11aa861136fca3ec464e0a6268abeed1d8109 (diff) | |
| download | qtmaildir-bd1b907ba22464bb869bcc10cc9327ed74c44791.tar.gz qtmaildir-bd1b907ba22464bb869bcc10cc9327ed74c44791.zip | |
feat(ui): make Delete a toggle, and expire transient status messages
Items 16 and 33.
Delete now removes the `deleted` tag when every selected thread already
carries it, so pressing it twice puts a thread back. One direction for
the whole selection, never per row: toggling each independently would
leave a single keystroke with the selection in two states, which is
worse than either outcome.
Status messages are classified rather than blanket-timed, which is the
substance of item 33. Events expire after six seconds and fall back to
the last query's thread count: "Sync complete", "Nothing to undo", the
skip notice, the per-action "Archive: 3 threads". State does not expire:
"Searching...", "Syncing...", the selection count, and "Sync failed
(exit N)", because an error must not vanish before it is read.
A test caught a mistake in that routing. Making the per-action message
transient armed the timer during select-all, since tagSelected() runs on
a selection onSelectionChanged() had just described, and the count would
then be replaced while it was still true. Writing the count now cancels
any transient still counting down.
QStatusBar::showMessage() would give the same behaviour but the label is
added with addWidget() beside permanent widgets, so adopting it means
reworking that arrangement. One timer beside the label is the smaller
change.
Both fixes verified by reverting them and watching the tests fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/mainwindow.h')
| -rw-r--r-- | src/mainwindow.h | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/mainwindow.h b/src/mainwindow.h index 61722aa..2edeb79 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -84,6 +84,11 @@ public: /// `assets/mailsync.sh` is the reference implementation of this contract. static constexpr int kSyncSkippedExitCode = 75; + /// How long a transient status message stays before the bar falls back to + /// the thread count. Long enough to read a sentence, short enough that a + /// stale "Sync complete" does not sit there describing the present. + static constexpr int kStatusMessageMs = 6000; + /// Path of the machine-written UI state file. Deliberately not /// Config::defaultPath(): the config is hand-edited and must never gain a /// base64 geometry blob, nor be rewritten on exit (QSettings does not @@ -115,6 +120,14 @@ private slots: void onWorkerError(const QString &message); void onSyncFinished(bool success, int exitCode); + /// Shows a message that describes an event and takes it back after a few + /// seconds, restoring the last query's thread count. + /// + /// Use this for events ("Sync complete"), never for state: the selection + /// count must persist while the selection does. A private slot so tests can + /// drive it through the meta-object. + void showTransientStatus(const QString &text); + /// Reacts to a sync started outside this window, by cron or by hand. /// /// A private slot rather than a plain method so tests can drive it through @@ -254,6 +267,15 @@ private: QPushButton *m_syncButton = nullptr; QLabel *m_statusLabel = nullptr; + /// Expires a transient status message. See showTransientStatus(). + QTimer *m_statusTimer = nullptr; + + /// The message m_statusTimer armed for, so it takes back only its own. + QString m_transientMessage; + + /// What the status bar falls back to: the last query's thread count. + QString m_defaultStatus; + /// Says how many tag changes have not been seen to reach the mail store. /// Hidden entirely at zero rather than reading "0 unsynced", which is noise. QLabel *m_pendingLabel = nullptr; |
