diff options
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.md | 109 |
1 files changed, 109 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 417a980..7fedaf3 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 @@ -59,6 +59,9 @@ taking that too literally. | 18 | No visual cue that there are unsynced edits | feedback | S | open | | 19 | No prompt to sync on exit when edits are pending | behavior | S | open | | 20 | Thread view does not match the user's mental model | presentation | ? | open, unspecified | +| 21 | Default shortcuts are not sensible enough | discoverability | S | open | +| 22 | Translatability audit and i18n wiring | correctness | M | open | +| 23 | No way to save a search query from the UI | workflow | M | open | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -401,6 +404,26 @@ currently hardcodes `#bbb`, `#555`, `#000`, `#666`, `#ddd` and no background, and will look wrong under a dark theme. That is arguably its own item; see item 12 below if it gets split out. +### Refined by the user, 2026-08-04 + +Two concrete sub-items, from using the list rather than looking at it: + +- **"All items look unread (bold), maybe use regular for read items?"** + **Check this before changing anything.** Bold is ALREADY conditional: + `ThreadListModel::data()` sets it under `Qt::FontRole` only when + `thread.isUnread()` (`src/threadlistmodel.cpp:148-152`). So either the + observation is that the user's list genuinely is mostly unread, in which case + there is no bug and the fix is elsewhere (the density work below), or bold is + leaking onto read rows through some path the model does not control. Reproduce + against a query with a known mix, e.g. `tag:inbox and not tag:unread`, before + touching the font logic. + +- **A star column for flagged threads**, mirroring the paperclip column that + already exists for attachments. `ThreadSummary` carries the tags and + `flagged` is an ordinary notmuch tag, so this needs no new worker query, the + same way item 15's paperclip did not. Keep it narrow: an icon column, no + text. + ## 6. Opened message stays unread **Observed:** opening a message leaves it tagged unread; the user expects it to @@ -897,6 +920,92 @@ cost first. not design this item from the description above, which says only what is, not what was wanted. +## 21. Default shortcuts are not sensible enough + +**Observed (user, 2026-08-04):** "improve the default shortcuts to some sensed +defaults." + +**Unspecified in detail**, so ask which bindings feel wrong before proposing a +table. What is worth recording is the history, because the defaults have +already moved once and the reasons still constrain any second pass. + +**Where the current defaults came from.** 0.1.0 used bare letters. They were +replaced in the 0.2.0 menu work for two reasons that have not gone away: a +single letter cannot be a menu accelerator without claiming that letter +window-wide, and a bare capital such as `N` parses to an unshifted `Key_N`, +which no keystroke emits, so `toggle_unread`, `flag` and `sync` were dead keys +that appeared to be bound. See `KeyMap::defaultBindings()` and +`normalizeSequence()`. + +**Constraints on any new default.** + +- **Do not test reachability with synthetic input.** `QTest::keyClick()` does + not reproduce a keyboard layout: it reported `Ctrl++` as dead when it is + exactly what the `+` key emits on the user's Italian layout. Verify against + the real keyboard, as `CLAUDE.md` records. +- Every binding is overridable in `[keys]`, so this is about what a fresh + install feels like, not about what is possible. +- `Return` is a special case already resolved: it belongs to `open_thread` but + the query bar claims it back while focused, so a proposal that moves it must + not resurrect that bug. + +## 22. Translatability audit and i18n wiring + +**Observed (user, 2026-08-04):** "a full check of the codebase and wiring up of +the i18n system." + +**This is a debt `CLAUDE.md` already records.** The rule that every user-facing +string must be wrapped in `tr()` was added while building query completion, and +that file states plainly that "pre-existing code has not been audited against +this rule". This item is that audit, plus the loading machinery which does not +exist at all. + +**Two halves, and they are different sizes.** + +- *The audit.* Every user-visible string in `src/` checked for `tr()`, with the + translation context correct: a string in a free function needs + `Q_DECLARE_TR_FUNCTIONS`, since calling `QObject::tr()` compiles but files it + under the wrong context. `lupdate` output is the evidence here, not reading. +- *The wiring.* Nothing loads a `.qm` file today: there is no `QTranslator` in + `main.cpp`, no `.ts` files in the tree, and no CMake rule to build or install + them. Until that exists, a translated string has nowhere to come from. + +**Constraint:** query syntax is not user-facing text. notmuch keywords such as +`tag:` and `date:` are wire format and must never be translated, only the prose +describing them. The completion vocabulary is exactly this trap: the values are +literal, the descriptions are prose. + +**Verification:** run `lupdate` and read the generated `.ts`. A string that +does not appear there is not translatable, whatever the source looks like. + +## 23. No way to save a search query from the UI + +**Observed (user, 2026-08-04):** saved queries live in the config file only. +There is no way to keep a query you have just written without editing +`qtmaildir.conf` by hand. + +**Approach, and one real design question.** + +- A "save this query" action that names the current query bar contents and adds + it to `[queries]`. +- The user's own suggestion for presentation: **a few sensible ones as buttons, + the rest behind a menu.** Today `SavedQueryBar` shows them all, which does not + scale past a handful. + +**The design question is where the write goes.** `qtmaildir.conf` is hand-edited +and owned by the user, and item 1 established the rule that machine-written +state belongs in `uistate.conf` instead, precisely because QSettings preserves +neither comments nor key order and would quietly reformat the file on write. +Saved queries are not machine state though: they are user intent, they belong +with the hand-written ones, and splitting them across two files so the UI can +avoid touching one would be worse than either option. Decide explicitly, and +say so in the README whichever way it goes. + +**Relation to item 10.** Item 10 is postponed, but its second half proposed +exactly this: "saved queries that carry their own account scope, so one action +gets there". If saved queries gain an account scope here, item 10 may be +answered as a side effect rather than needing its own work. + --- ## Deferred, unsized, or split out |
