aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md48
1 files changed, 48 insertions, 0 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 aa56727..3ace9d2 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
@@ -258,6 +258,10 @@ taking that too literally.
| 182 | An edit made during a sync is announced twice and never says it is waiting | defect | XS | **done 2026-08-29**, unreleased, on `thread-row-identity`, found by hand. The hold branches set a deliberately NON-transient label; all three callers overwrote it a line later with the bare action, so the user was told the write had landed and then told again when it really did. `announceAction()` adds the wait to the action rather than replacing it, since that announcement is what stands in for the confirmation dialog this project rules out. Section in the closed file |
| 183 | `undoingAMarkReadRestoresOnlyWhatWasUnread` fails about 1 run in 9 under the full suite | testing | ? | open, 2026-08-29, measured. Item 176's regression test, which guards the undo that rewrote 44 messages of real mail. Nine runs on master: 4 standalone, 3 under `ctest -R mainwindow`, 3 under the FULL parallel suite, and the single failure was in the last group. Not a regression, the base commit behaves the same. Probably the same root cause as item 136 and worth solving with it |
| 184 | New mail waits up to ten minutes, because sync is a fixed cron tick | workflow | ? | open, 2026-08-29, from the user: the 10 minute tick "has always bothered me", and it is already a compromise down from 30. Outgoing edits are immediate (`auto_sync_delay_ms`), so this is the INCOMING half only. Polling faster is not the answer; IMAP IDLE is, and it lives in a watcher that triggers `mailsync.sh`, NOT in qtmaildir, which does no network protocol work. Needs decisions first: which watcher, whether it packages on Slackware, and what the server supports. **Blocked on 174**, whose status file is the reporting channel this needs anyway |
+| 185 | The message-pane bar offers Reply and Forward on a trashed message | presentation | S | **done 2026-08-29**, unreleased, with 186. The bar has a third branch keyed on the SELECTION being in a trash folder, the same predicate the menus use: Restore, Delete permanently and Empty trash replace the reply pair, and Restore alone is tinted. Added `purge`, the selection-scoped sibling of `empty_trash`, which inherits both its safeguards. Refilled from the digest as well as from the selection, since a conversation's trash-ness is not known until every path is reported. Section in the closed file. Original entry: `MainWindow::refreshMessageBarActions()` (`mainwindow.cpp:2311`) swaps the bar's message half for a DRAFT and for nothing else, so the trash view shows the two actions that make least sense there. The notes ask for Restore and Delete permanently in their place, and for Delete to move here from the main toolbar (item 186). The visibility rules already exist in `refreshTrashActions()`; what is missing is the bar consulting them |
+| 186 | Delete sits on the main toolbar rather than beside Reply and Forward | presentation | XS | **done 2026-08-29**, unreleased, with 185. Moved to the message bar's ordinary branch; still in the Message and context menus. Section in the closed file. Original entry: `toolBar->addAction(... "delete")` at `mainwindow.cpp:2251`. The user places it with the message actions, so this rides with item 185 rather than being done alone: moving it before the bar is trash-aware leaves Delete in a bar that still offers Reply on trashed mail |
+| 187 | There is no Spam view beside Trash | workflow | S | open, 2026-08-29, from the notes. `kQueryGenerators` (`config.cpp:62`) holds six generators and no `spam`, while the `spam` ACTION has existed since 0.2.x and writes the tag. So mail can be marked spam and never listed. A tag generator like `unread`, not a folder one like `trash`: nothing in the config names a spam folder, and adding one would make it a per-account mandatory key like `trash` |
+| 188 | Does Empty trash respect the account selector? | question | XS | **answered 2026-08-29** by reading the code, no work needed. It does: `MainWindow::emptyTrash()` (`mainwindow.cpp:6567`) reads `m_accountBox->currentData()` and uses `allTrashQuery()` only for All accounts, and the confirmation names which. Recorded so the notes' question has an answer rather than sitting open |
Sizes are rough: XS under an hour, S a sitting, M a session.
@@ -1413,3 +1417,47 @@ repository.**
174 or 125 better than a file does, and it adds a process that can wedge and
take mail delivery with it. What the user wants is a watcher, which is a
different thing in a different place.
+
+
+## 187. There is no Spam view beside Trash
+
+**Observed.** The user asks for a Spam view next to Trash. Mail can be marked
+spam today and there is no filter that lists it.
+
+**Cause.** `kQueryGenerators` (`config.cpp:62`) is a closed set of six:
+`unread`, `inbox`, `flagged`, `sent`, `drafts`, `trash`. There is no `spam`.
+The `spam` action has existed since the first toolbar and writes the tag
+(`mainwindow.cpp:1760`, adds `spam`, removes `inbox`), so the write half is
+built and the read half is missing.
+
+**Approach.** A TAG generator, like `unread` and `flagged`, not a folder one
+like `trash`: add `spam` to `kQueryGenerators`, return `spam` from
+`generatorTag()`, and give it a label in `builtinFilter()`. Threaded rather
+than flat, matching Trash. That is the whole change; `Config::resolvedQuery()`
+already composes a tag generator with the account selector.
+
+**Constraints.**
+
+- **Do NOT make it a folder generator.** No account config names a spam
+ folder, and adding one would be a new mandatory per-account key with the
+ item 103 hazard attached: a folder name that does not exist is CREATED and
+ propagates to the server.
+- **The label is translated, the generator is not.** `spam` is stored in
+ `queries.json` and matched against a closed set, so it is wire format; see
+ the `flagged`/"Important" note in `builtinFilter()`.
+- **Adding a generator changes queries.json's readable set**, so an older
+ build reading a file that names `spam` reports an unknown generator and
+ KEEPS the row. That is the existing behaviour and needs no version bump.
+- **The button row is fixed and left to right.** Decide where Spam sits with
+ the user; the obvious place is beside Trash, which puts it last.
+
+## 188. Does Empty trash respect the account selector?
+
+**Answered on 2026-08-29 by reading the code; no work follows from it.** It
+does. `MainWindow::emptyTrash()` (`mainwindow.cpp:6567`) reads
+`m_accountBox->currentData()`, uses `Config::allTrashQuery()` only when that is
+empty and the account's own `trashQuery()` otherwise, and the confirmation
+dialog names the scope ("every account" or the account's display name).
+
+Recorded rather than dropped so the notes' question has an answer here, which
+is where the user will look for it.