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 /docs | |
| 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 'docs')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md index 7f79100..67668d4 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md @@ -60,7 +60,7 @@ taking that too literally. | 13 | No visual feedback that an action stuck | feedback | S | **done** | | 14 | Tag column unreadable, tags need another home | presentation | M | **done** | | 15 | Attachments are parsed but unreachable from the UI | information | M | **done** | -| 16 | Delete on an already-deleted thread should undelete | behavior | S | open | +| 16 | Delete on an already-deleted thread should undelete | behavior | S | **done** | | 17 | No completion for tags in the query bar | workflow | M | **done** | | 18 | No visual cue that there are unsynced edits | feedback | S | **done** | | 19 | No prompt to sync on exit when edits are pending | behavior | S | **done** | @@ -77,7 +77,7 @@ taking that too literally. | 30 | The blank right pane is wasted space | presentation | M | open | | 31 | The quit prompt has no highlighted default button | discoverability | XS | **done** | | 32 | Esc does not blank the right pane | workflow | XS | **done** | -| 33 | Status bar messages never expire | feedback | S | open | +| 33 | Status bar messages never expire | feedback | S | **done** | | 34 | No overview of the Maildir itself | information | M | open | | 35 | No refresh of the thread list after a sync | workflow | M | open | | 36 | `test_mainwindow` cannot reach the worker | testing | S | open, on demand | @@ -797,6 +797,18 @@ Deleting a thread that already carries `deleted` removes it instead. - The same question applies to `spam` and `flag`. Do not change those in this item; note whether the answer generalises once `delete` is built. +### Outcome (done) + +Built as specced, including the all-or-nothing rule: undelete only when every +selected thread already carries `deleted`, otherwise delete the whole selection. +A test covers the mixed case and passed before the change, since the old +always-delete behaviour satisfies it; it is there to stop a later "improvement" +from toggling per row. + +**It generalises to `spam` and `flag`, and they were still left alone.** The +same shape would work, but neither has been asked for, and `flag` in particular +is already reachable both ways through the tag dialog. + ## 17. No completion for tags in the query bar **Observed:** typing a query means remembering the exact tag name, including @@ -1583,6 +1595,30 @@ completes. pane, which does persist, but the status text should outlast a two-second timeout. +### Outcome (done) + +`showTransientStatus()` sets the text and arms a 6 s single-shot timer that +restores the last query's thread count. Messages were classified rather than +blanket-timed, which is the whole substance of the item: + +- **Events expire:** "Sync complete", "Nothing to undo", "Sync already + running", the skip notice, the background-sync notice, and the per-action + "Archive: 3 threads". +- **State persists:** "Searching...", "Syncing...", "Syncing before + quitting...", "Background sync running...", the selection count, and + **"Sync failed (exit N)"**, per the constraint that an error must not vanish + before it is read. + +**A test caught a real mistake while routing them.** Making the per-action +message transient armed the timer during `selectAll()`, because `tagSelected()` +runs on a selection that `onSelectionChanged()` had just described. The count is +state and must outlive any transient still counting down, so writing it now +cancels the timer. + +`QStatusBar::showMessage()` was considered and not used: the label is added with +`addWidget()` alongside permanent widgets, so switching would mean reworking that +arrangement for the same behaviour. + ## 34. No overview of the Maildir itself **Observed (user, 2026-08-04):** wants "info on the maildir": total messages, |
