aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers/specs
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-02 16:52:45 +0200
committerDanilo M. <danix@danix.xyz>2026-08-04 12:52:11 +0200
commit0af917701973b67d7b7bf5e9ef37304040530015 (patch)
tree99393bd279f47d585405c0fdcd4f4c725fe31790 /docs/superpowers/specs
parent57693660ef3075c495925161b7c8c8371dc89b30 (diff)
downloadqtmaildir-0af917701973b67d7b7bf5e9ef37304040530015.tar.gz
qtmaildir-0af917701973b67d7b7bf5e9ef37304040530015.zip
docs: fold full thread rendering and batch tagging into spec and plan
Both were narrowed in the first draft and are now in scope. Newsletter threads make whole-thread rendering fundamental, and bulk archive is the main thing a GUI buys over neomutt. Two consequences fell out of thread rendering and are recorded in both documents. The thread renders as one document in one web view rather than one view per message, since a view each would spawn a Chromium render process each. Sharing a document makes cid: references collide when two messages use the same Content-ID, which is common across newsletters from one sender, so every reference is namespaced to cid:<prefix>!<id>. Deciding which messages render expanded needs the query, so loadThread now intersects it with the thread and MessageRef carries a matched flag. Batch tagging resolves thread ids to message ids on the worker in one combined query. Undo stores thread ids and re-resolves, staying correct after the selection moves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'docs/superpowers/specs')
-rw-r--r--docs/superpowers/specs/2026-08-02-qtmaildir-design.md29
1 files changed, 26 insertions, 3 deletions
diff --git a/docs/superpowers/specs/2026-08-02-qtmaildir-design.md b/docs/superpowers/specs/2026-08-02-qtmaildir-design.md
index 4764a71..045123e 100644
--- a/docs/superpowers/specs/2026-08-02-qtmaildir-design.md
+++ b/docs/superpowers/specs/2026-08-02-qtmaildir-design.md
@@ -273,6 +273,19 @@ messages expanded and unmatched ones collapsed to a one-line stub. Notmuch
provides reply structure, but an indented tree is significant work that does
not change what is readable.
+The whole thread renders as **one HTML document in one web view**, not one
+view per message. A newsletter thread can hold dozens of messages, and a
+`QWebEngineView` each would spawn a Chromium render process each.
+
+Sharing one document means `cid:` references from different messages collide:
+two newsletters both using `cid:logo@example.org` would resolve to whichever
+part won. Every reference is therefore rewritten to `cid:<prefix>!<id>` with a
+per-message prefix, and the scheme handler is keyed on that namespaced form.
+
+Determining which messages matched requires the query: `loadThread` intersects
+the user's current query with the thread, and each `MessageRef` carries a
+`matched` flag.
+
### Message to HTML
`MimeParser` walks the MIME tree and produces a chosen body part, inline CID
@@ -333,11 +346,18 @@ All actions funnel through one `applyTags(msgIds, add, remove)` path:
| Spam | `+spam -inbox` |
| Custom | user-entered add/remove |
+Actions apply to **every selected thread**, not just the open one. The UI holds
+thread ids rather than message ids for rows it never opened, so the worker
+resolves them: `applyTagsToThreads` builds one combined `thread:a or thread:b`
+query rather than issuing one query per thread, which matters when archiving
+hundreds of rows.
+
There is deliberately no dry-run and no destructive-action confirmation. Those
gates exist in mailctl to restrain an agent that cannot see its own target.
The GUI equivalent is **undo**: each applied mutation pushes its inverse onto
a `QUndoStack`, so the last tag change can be reversed. For a human, undo is
-strictly better than a confirmation dialog.
+strictly better than a confirmation dialog. The undo entry stores thread ids
+and re-resolves them, so it stays correct after the selection moves.
The UI updates optimistically and reverts with a status-bar error if the
worker reports failure.
@@ -404,8 +424,11 @@ Qt Test, three targets, all runnable without a real mailbox.
database; v1 tests pure logic and leaves the database layer to manual
verification.
- Large-message MIME parsing happens on the UI thread and could stutter on
- pathological messages. Deferred until measured.
-- Threading structure is flattened for display.
+ pathological messages. Opening a thread parses every message in it, so this
+ is more likely to show on a long thread than on a single message. Deferred
+ until measured.
+- Threading structure is flattened for display: messages appear in date order
+ with no reply indentation.
- The `QtWebEngineProcess` sandbox helper's installed location was not
verified during design. CMake handles it, but it is unconfirmed.