diff options
Diffstat (limited to 'docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md index 133a761..0f7181b 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md @@ -7348,3 +7348,47 @@ what a drafts folder is; they are separate readers and neither should start importing the other. --- + +## 153. A draft cannot be opened for editing, so it is write-only + +**Observed (user, 2026-08-24).** Found the moment item 138 gave drafts a +button: "Double clicking on a draft should open the message in the editor +window", and "there's no edit action anywhere, a draft is useless as is". + +**Cause (verified in code).** `DraftStore` had a `write()` and no reader, and +nothing anywhere opened a composer from an existing message. A draft therefore +rendered in the message pane like ordinary mail and could never be finished. + +**Outcome.** `ComposeContextBuilder::forDraft()`, a `Kind::Draft` that seeds +every field verbatim, `edit_draft` in the Message menu, and double-click. + +**Three things worth keeping.** + +**A resumed draft must own its file.** Maildir has no in-place edit, so an +autosave writes a new file and unlinks the old; a composer that did not know +its own path would leave the original behind and one message would become two. +`ComposeContext::draftPath` carries it into `m_draftPath`, which the autosave +already knew how to replace. + +**`MimeParser` had no `bcc` and nothing had ever needed one.** +`MessageBuilder` writes Bcc into the draft file deliberately and says why, so a +resumed draft that ignored it would drop every blind recipient from the message +the user then finishes and sends, silently. That is the failure this item was +most likely to ship. + +**The gate is not cosmetic.** `edit_draft` is offered only on a file inside a +configured drafts folder, matched on the PATH: a `draft` tag is not enough, +since notmuch surfaces the Maildir D flag as one and a message flagged by +another client sits in the inbox. Offered on ordinary mail, the composer would +own a file it did not write and the first autosave would DELETE a received +message. + +**And a live defect found on the way, which is the reason this took as long as +it did.** `updateComposeActions()` ran only from `onSelectionChanged`. Both +signals fire for an ordinary click, so nothing had ever noticed; but running a +query and setting the current index emits `currentRowChanged` ALONE, so the +enablement was computed against the previously selected row. Measured: Edit +draft stayed disabled on a draft selected that way, and the reply family had +the same blind spot without a test that could see it. It is now connected to +both signals. Reading `currentRowChanged` is safe here for the reason +`CLAUDE.md` gives: it answers "which row is current", and no count is read. |
