diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-26 19:16:37 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-26 19:16:37 +0200 |
| commit | 6ee94127510862139e89e8d653cd4994e27e5ffe (patch) | |
| tree | e8fefe65eac56d126b78240e7dc5a1af1eddaf6d /src/types.h | |
| parent | 06b0435830daaed49a2d5231dcb6f02ff0124d5d (diff) | |
| download | qtmaildir-6ee94127510862139e89e8d653cd4994e27e5ffe.tar.gz qtmaildir-6ee94127510862139e89e8d653cd4994e27e5ffe.zip | |
feat: snapshot the pending changes as rows
Item 119, first half: the data the list behind the unsynced-changes count
is built from, with no dialog and no worker, so the rules it has to follow
are testable on their own.
pendingChangeSnapshot() gathers the three queues the count sums into
PendingChange rows. Two properties are the whole point.
Scope follows the ACTION, not the storage. A held thread edit stays one
thread row, because a `*_thread` action made it and reporting its messages
instead would claim the user acted on each one; a netted tag edit and a held
move are message rows. The queues already encode that distinction, so
nothing is expanded and nothing is escalated.
The rows are grouped by id, so a message with several outstanding actions
appears once with its actions beneath it, which is the layout the user
asked for. The sort is stable, so those actions keep the order they were
made in; QHash has none of its own, and without it the list would reshuffle
between openings.
A snapshot, taken once and frozen. Subjects are empty here and filled by the
resolve step to come.
m_pendingTagEdits gains the action name beside the direction it already
kept. The direction alone was enough to count with; a list has to say what
each change was, and only the action that made it knows. It is carried from
TagChange::description rather than derived from the tag, so there is no
second table of tag names to labels to drift from the first.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P88Q3MCSCSQxKDy7pmXh9F
Diffstat (limited to 'src/types.h')
| -rw-r--r-- | src/types.h | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/types.h b/src/types.h index a0f772b..c78ab76 100644 --- a/src/types.h +++ b/src/types.h @@ -264,6 +264,45 @@ struct TagChange } }; +/// One outstanding change, for the list behind the unsynced-changes count. +/// +/// A SNAPSHOT taken when the user opens the list, then frozen: the count they +/// clicked is the count the list accounts for, and a dialog left open for +/// twenty minutes must not keep rewriting itself under them. +/// +/// The scope follows the ACTION, never the storage. A thread action names its +/// thread and reports how many messages it covered at snapshot time; a +/// message action names its message. That distinction is already kept, since a +/// held thread edit carries thread ids and everything else carries message +/// ids, so nothing has to be expanded to reconstruct it. +struct PendingChange +{ + /// The message or thread this change is about. Wire format, for resolving + /// a subject; never shown. + QString id; + + /// True when `id` is a THREAD id and the change covers the conversation. + bool isThread = false; + + /// What the user did, translated and ready to show ("Delete", "Mark + /// read"). Built where the change is recorded, since only there is the + /// direction of a tag write still known. + QString action; + + /// The subject, filled by the resolve step. Empty until then, and left + /// empty for an id the index no longer holds: the row still appears, since + /// dropping it would make the list disagree with the count. + QString subject; + + /// How many messages a thread change covered, at snapshot time. -1 for a + /// message change and for a thread whose resolve found nothing. + /// + /// At snapshot time and not at write time: a held thread edit applies when + /// the sync ends, and a reply landing in between makes the real number + /// larger. The number describes what the user is looking at. + int messageCount = -1; +}; + /// Database-level facts for the Maildir overview. /// /// Every field is -1 until answered, so a dialog opened against a database that |
