diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-10 09:33:44 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-10 09:33:44 +0200 |
| commit | 01419de209c2b5e2ae7b996e6b5ff1baa2efb3da (patch) | |
| tree | 25718fd36e87eac721f41b02cca46b6fb07e94d9 /src/types.h | |
| parent | f72dba9f6c463c6823d85701e51d8be38dd22a62 (diff) | |
| parent | e1dba2987a9a1e87b92801959df9c9d4f1375d2f (diff) | |
| download | qtmaildir-01419de209c2b5e2ae7b996e6b5ff1baa2efb3da.tar.gz qtmaildir-01419de209c2b5e2ae7b996e6b5ff1baa2efb3da.zip | |
Merge branch 'card-list': the thread pane as a list of cards
Replaces the five-column grid with a single column of three-line cards. Item 53
recorded that the columns, not the cues drawn inside them, were what made the
list read as a table of records; item 20 had already shipped finished, tested
and green and been rejected on sight for exactly that reason.
A card is sender and date, subject with the flag, attachment and reply-count
marks, and tags, at one uniform height. Replies indent under a continuous spine
and show only the tags their thread does not carry. The account colour runs down
the card's left edge, replacing the chip that used to eat a third of every
subject line, with matching swatches in the account dropdown. Sorting newest or
oldest first is new and remembered.
Closes items 20, 51, 53 and 60.
The four defects that mattered were all found by rendering cards to an image and
looking at them, with the suite green through every one: a date clipped on unread
cards because bold is wider than the font the layout measured, an accent bar
painted in a colour identical to the background, an expander pill in a palette
role a theme had made equal to Base, and three separate faults from trusting
notmuch's reply depth to mean structure when it only means how notmuch happened
to thread the mail.
Diffstat (limited to 'src/types.h')
| -rw-r--r-- | src/types.h | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/types.h b/src/types.h index 999d3f3..d04670e 100644 --- a/src/types.h +++ b/src/types.h @@ -63,6 +63,63 @@ struct MessageRef bool matched = true; }; +/// One message as a row in the thread list. +/// +/// Separate from MessageRef, which exists for RENDERING a thread and carries +/// only what the message pane needs. A row has to be drawn without opening the +/// message at all, so the display facts live here. +struct MessageNode +{ + QString messageId; + QString threadId; ///< The thread this message belongs to. + QString from; + QString subject; + QDateTime date; + QStringList tags; + QString filePath; + + /// Reply depth within the thread. 0 is the thread's first message, which + /// occupies the ROOT row rather than a child row: the user's model is + /// "N replies", so a thread of 7 shows 1 root and 6 descendants. + int depth = 0; + + bool isUnread() const { return tags.contains(QStringLiteral("unread")); } + bool isFlagged() const { return tags.contains(QStringLiteral("flagged")); } + + /// notmuch applies "attachment" while indexing, so this needs no MIME + /// parsing, exactly as on ThreadSummary. + bool hasAttachment() const + { + return tags.contains(QStringLiteral("attachment")); + } +}; + +/// What an action is about to touch, resolved from the selection. +/// +/// Exists because the thread list holds two kinds of row since item 20, so a +/// keypress alone no longer says whether it hit one message or seven. Actions +/// take one of these rather than a bare list of thread ids, and the status bar +/// reports it: this project's answer to that ambiguity is to make the scope +/// visible, not to add a confirmation dialog. See CLAUDE.md on why. +struct ActionScope +{ + QStringList threadIds; ///< Whole threads to act on. + QStringList messageIds; ///< Individual messages to act on. + + /// Messages the action will touch in total, for the status bar. A whole + /// thread contributes all of its messages, a message row contributes one. + int messageCount = 0; + + /// True when any whole thread is in scope, which drives the + /// "(whole thread)" suffix in the status bar. + bool wholeThread = false; + + bool isEmpty() const + { + return threadIds.isEmpty() && messageIds.isEmpty(); + } +}; + /// One tag mutation, kept so it can be inverted for undo. struct TagChange { @@ -93,5 +150,6 @@ struct DatabaseStats Q_DECLARE_METATYPE(ThreadSummary) Q_DECLARE_METATYPE(MessageRef) +Q_DECLARE_METATYPE(MessageNode) Q_DECLARE_METATYPE(TagChange) Q_DECLARE_METATYPE(DatabaseStats) |
