aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-20 12:53:26 +0200
committerDanilo M. <danix@danix.xyz>2026-08-20 12:53:26 +0200
commitfd42550c8f51c52cb7eca86b2557e82bc173dd04 (patch)
tree89fc900c2f99859f5be2ebf881ed2200fcd38688
parent02d27c9eb963b3357c8f9aa113fbb3eb14f9e7e7 (diff)
downloadqtmaildir-fd42550c8f51c52cb7eca86b2557e82bc173dd04.tar.gz
qtmaildir-fd42550c8f51c52cb7eca86b2557e82bc173dd04.zip
docs: lay out the send popup, item 123
Three rows in every state, so nothing reflows: status label, bar, right-aligned Undo. The bar changes mode rather than place, determinate and draining during the countdown because that has measurable progress, indeterminate once send_command starts because a send does not. Undo stays visible after it disables. A control that vanishes re-lays out the popup mid-operation, and a greyed one says why cancelling is no longer possible where an absent one looks like it was never offered. The status label sizes from the longest string it can hold in the current language rather than from its content: Italian "Rimozione della bozza..." is longer than "Removing draft...", so a content-sized label resizes the popup between stages, which is the jumping the fixed layout exists to prevent. Item 134 gains a requirement from this: the extracted widget must expose both bar modes, not only the indeterminate one MainWindow happens to need today. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDq53rMd3AQp7QmcZzpuBM
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md2
-rw-r--r--docs/superpowers/specs/2026-08-20-compose-and-send-design.md45
2 files changed, 41 insertions, 6 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 a35d9fa..3d5bcc3 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
@@ -203,7 +203,7 @@ taking that too literally.
| 131 | The markdown dialect and extensions are fixed | v2 | S | open, 2026-08-20, from the item 123 brainstorm. **Blocked on 123.** Configurable in the shape Hugo's config uses. Deliberately fixed initially: CommonMark plus autolink, strikethrough and tasklist |
| 132 | Every action must have a shortcut, and that no longer serves | policy | S | open, 2026-08-20, raised by the user during the item 123 brainstorm. `everyActionHasAShortcut` was written when the action list was short; item 123 adds six more, and each new action consumes a chord whether or not anyone would press it. Replacement is the shape `everyActionIsReachableFromAMenu()` already has: menu reachability required, shortcuts a chosen subset. **Not** done inside 123, which would confuse two changes |
| 133 | The composer shows no markdown syntax highlighting | v2 | S | open, 2026-08-20, from the item 123 brainstorm. **Blocked on 123.** A `QSyntaxHighlighter` over the composer's editor, so `**bold**` reads as bold while the buffer stays plain markdown. Standard Qt, no dependency. Deliberately after 123's formatting toolbar: agreeing with the grammar about nesting and about code spans suppressing what is inside them is the expensive part, and the toolbar is what makes the feature usable |
-| 134 | The busy indicator is built inline and is about to be built twice | maintenance | S | open, 2026-08-20, raised by the user during the item 123 brainstorm. An indeterminate `QProgressBar` beside a status label, built inline in `MainWindow` as `m_syncProgress`, and item 123's composer needs the same pairing. Extract a widget class and convert `MainWindow` to it. **Not blocked on 123**, and better done first: if 123 lands first it creates the class itself and this row closes with it. The user's position is general, build once and reuse, so the inline habit `CLAUDE.md` records is a description of the code rather than a rule to follow |
+| 134 | The busy indicator is built inline and is about to be built twice | maintenance | S | open, 2026-08-20, raised by the user during the item 123 brainstorm. An indeterminate `QProgressBar` beside a status label, built inline in `MainWindow` as `m_syncProgress`, and item 123's composer needs the same pairing. Extract a widget class and convert `MainWindow` to it. It must expose BOTH modes, not just the indeterminate one `MainWindow` happens to need: item 123's send popup drains a determinate bar during its undo countdown and switches the same widget to indeterminate when the command starts. **Not blocked on 123**, and better done first: if 123 lands first it creates the class itself and this row closes with it. The user's position is general, build once and reuse, so the inline habit `CLAUDE.md` records is a description of the code rather than a rule to follow |
Sizes are rough: XS under an hour, S a sitting, M a session.
diff --git a/docs/superpowers/specs/2026-08-20-compose-and-send-design.md b/docs/superpowers/specs/2026-08-20-compose-and-send-design.md
index f410d00..aade2d1 100644
--- a/docs/superpowers/specs/2026-08-20-compose-and-send-design.md
+++ b/docs/superpowers/specs/2026-08-20-compose-and-send-design.md
@@ -262,14 +262,49 @@ declares a struct field named `signals`.
countdown through to completion. It is modelled on Gmail's undo-send, and it is
what settles what "cancel" can mean here.
+Three rows, the same three in every state, so nothing reflows and the window
+never jumps:
+
+```
++-----------------------------------------+
+| Sending in 5... | status label
+| ##################................. | bar, DETERMINATE, draining
+| [ Undo ] | enabled
++-----------------------------------------+
+
++-----------------------------------------+
+| Sending... | then: Filing sent copy...
+| #######################################| bar, INDETERMINATE
+| [ Undo ] | visible, disabled
++-----------------------------------------+
+```
+
+**The bar changes mode, it does not change place.** During the countdown it is
+determinate and drains as the seconds pass, because a countdown has measurable
+progress. It becomes indeterminate (`setRange(0, 0)`) when `send_command`
+starts, because a send does not. This is why item 134's widget class must expose
+both modes rather than hardcoding the indeterminate one.
+
+**Undo stays visible after it disables**, rather than disappearing. A control
+that vanishes re-lays out the popup mid-operation, and a greyed Undo says why
+cancelling is no longer possible where an absent one only looks like it was
+never offered.
+
+The stages, in order:
+
```
-Sending in 5... [ Undo ] countdown running, Undo live
-Sending... [ Undo ] send_command running, Undo disabled
-Filing sent copy... DraftStore writing to the sent folder
-Removing draft... the draft revision is unlinked
- popup and composer both close
+Sending in N... the countdown, Undo live
+Sending... send_command running, Undo disabled
+Filing sent copy... DraftStore writing to the account's sent folder
+Removing draft... the draft revision is unlinked
+ popup and composer both close
```
+**The status label takes its width from the longest string it can hold, in the
+current language, not from its content.** Italian "Rimozione della bozza..." is
+longer than "Removing draft...", so a label sized to content resizes the popup
+between stages, which is the jumping the fixed layout exists to avoid.
+
**The delay is where cancelling is safe, and it is the only place it is.**
Nothing has reached a server during the countdown, so Undo means genuinely
nothing happened. Killing `send_command` once it is running does not: the