diff options
Diffstat (limited to 'docs/superpowers/plans')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 57 |
1 files changed, 56 insertions, 1 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 49b9613..c91884e 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 @@ -221,7 +221,7 @@ taking that too literally. | 149 | A reply's cursor lands on the attribution line, not on blank space | defect | XS | **done** 2026-08-24, unreleased, in TWO passes. The first fixed the cursor within each branch (`End` under Above, `Start` under Below) and the user still saw the old layout, because the branches were already right and the DEFAULT was wrong: `above` shipped, and the layout asked for is what `below` produces. Default flipped, and the composer now focuses the body whenever To: is already filled, which a Reply and a Forward always are. Both halves were invisible to the existing `theQuotePositionDecidesWhereTheQuoteLands`, which asserts the quote's position and never the cursor's | | 150 | The receive-only ribbon stays up after the message that raised it is gone | defect | S | **done** 2026-08-24, unreleased. One line in `MessageView::clear()`, beside the blocked-content bar, the stale notice and the attachment bar it already reset by hand. Only `setReceiveOnlyAccount()` hid the ribbon, which every SELECTION change reaches, so a row-to-row move was never the reproducer: it survived the FOUR routes that blank the pane without one (`clear_pane`, `clear_selection`, a new query, a multi-row selection). The first test written for it passed against the defect for exactly that reason | | 151 | The message-pane bars blend into the UI and carry no severity | presentation | S | **done** 2026-08-24, unreleased. Two severities as the user asked: yellow for a warning that only explains (the receive-only ribbon), blue for one offering an action (remote content blocked, stale thread), each with its own light and dark set read off `QPalette::Base` as `HtmlBuilder` does. The blocked row had to become a WIDGET first: it was a bare `QHBoxLayout`, which has nothing to paint a ground on, and its six `hide()` sites then had to move to the wrapper or a painted empty strip would show. Both action bars put the button right of a stretch | -| 152 | Signatures are not managed at all | v2 | ? | open, 2026-08-24, from the notes, and the user added a constraint the same day: a signature is **not tied to an account**, and is switched from a control in the composer's editor bar. That rules out the obvious `[account.*] signature` key as the whole answer. Still unspecified in the rest: where the text is stored, how it interacts with the quote, and whether the HTML part gets its own form | +| 152 | Signatures are not managed at all | v2 | S | **specified** 2026-08-24, unbuilt. Design in `specs/2026-08-24-signatures-design.md`; read that, not this row. Sized `?` until the brainstorm; it is an S. One markdown file per signature under `~/.config/qtmaildir/signatures/`, spliced into the composer buffer, so `MessageBuilder` needs NO change at all: it already derives both parts from one string, which is the transparency the user asked for. The constraint holds, and the per-account key the user then asked for does not break it: an account SEEDS the choice, the editor-bar switch keeps every signature reachable | | 153 | A draft cannot be opened for editing, so it is write-only | defect | M | **done** 2026-08-24, unreleased. `ComposeContextBuilder::forDraft()` reads a draft back into a context; a new `Kind::Draft` seeds the fields verbatim, takes the body with no quote framing, and carries `draftPath` so the autosave REPLACES the file instead of leaving a second copy. `MimeParser` gained `bcc`, which nothing read before: `MessageBuilder` writes Bcc into the draft deliberately, so a resumed draft that ignored it would silently drop every blind recipient. Reachable by double-click and by an `edit_draft` action, gated on the file being in a configured drafts folder because opening ordinary mail this way would make the first autosave DELETE a received message. Found a live defect on the way, see the section | | 154 | No read confirmation | v2 | ? | open, 2026-08-24, from the notes. `Disposition-Notification-To`, which is a header `MessageBuilder` would add and a request the message pane would have to honour or ignore on the receiving side. Unspecified: whether this is send-side only, and what the reader is asked | | 155 | No urgency switch on an outgoing message | v2 | S | open, 2026-08-24, from the notes: low, regular, high. `X-Priority` and `Importance`, headers `MessageBuilder` adds; regular writes neither. A control in the composer, and the same question item 144 answered for the HTML toggle applies to where it sits | @@ -1306,3 +1306,58 @@ production move rather than the test, this stops being a test-hygiene item and becomes a mail-safety one. --- + +## 152. Signatures are not managed at all + +**Observed (user, 2026-08-24, from the notes):** listed under "some basic +functionalities not brainstormed which didn't enter the first Send +implementation", as: + +> signatures: +> - not tied to an account, with a switch in the editor bar UI. + +**Specified 2026-08-24.** The design is in +`docs/superpowers/specs/2026-08-24-signatures-design.md`. Read that rather +than this section, which records only what the brainstorm settled and why. + +**The constraint is the shape of the item, and it survived a second key.** +Not tied to an account rules out `[account.*] signature` as the whole answer. +The user then asked for that key anyway, as a convenience, and it does not +reopen the constraint: the account supplies a STARTING value, the editor-bar +switch keeps every signature reachable under any account, and changing From: +stops re-seeding the moment the user touches the switch. Seeding is not +binding. + +**One choice must serve both forms, and that costs nothing.** +`MessageBuilder` already derives `text/plain` from `markdownBody` verbatim and +`text/html` from `MarkdownRenderer::toHtml()` over the same string +(`messagebuilder.cpp:321-324`). A markdown signature in the buffer therefore +gets both, correctly, with no change to `MessageBuilder` and no second code +path. The user's "transparent to the user" requirement is a property the +pipeline already has. + +A two-file variant (`work.md` plus an optional `work.html` overriding the +rendered form) was chosen and then dropped by the user the same session: it +buys designed HTML signatures at the cost of the signature no longer being +visible in the editor, since the two parts diverge and the buffer can hold +only one of them. + +**The switch is stateless, by using the delimiter rather than tracking a +range.** `seedBody()` deliberately refuses to track "my text" and "the quote" +as separate pieces (`composewindow.cpp:640-644`), and a signature switch is a +toggle by definition, so it cannot duck that question the way the quote did. +It answers it without state: the signature is the last `-- ` block not +followed by quoted lines, found by scanning. Nothing to desync from the undo +stack, and it survives editing above it. + +**`signature_position` covers both placements over one scan.** The user's own +habit is `end`, which is the default; `above_quote` exists because other +clients offer it. The scan needed the quote-aware clause for `above_quote` +anyway, so the key is roughly ten lines rather than one, and a naive tail rule +would have eaten the quote under the other placement. + +**Two things the design refuses.** No signature editor: the directory is +edited with the user's own editor, and a text editor inside a mail client is +not this project's to build. And a resumed draft seeds nothing, because the +saved body already carries whatever signature it was written with, and +seeding again would put a second one on a message written once. |
