From 879a117cba62df57dfcb0c0dfd4383308fa07f13 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sat, 8 Aug 2026 10:22:33 +0200 Subject: feat(model): expose a thread's replies as child rows setThreadMessages drops the depth-0 message: it is the thread's first message and the root row already stands for it. Keeping it would show a thread of seven as one root and seven children, contradicting the reply count the row advertises. Calling again replaces rather than appends, so a thread reloaded after a sync does not list its replies twice. A message row reports its own sender and subject, not the thread's. That is the mistake worth guarding: the thread's author summary usually contains the first sender too, so reading it renders something plausible for the root's own reply and wrong for every other one. Mutation-checked, and the wrong version returns 'Alice' where 'Bob' belongs. Child rows carry no tag pills. The strip is a row-wide band of the thread's tags; one under each reply would stripe the list and repeat identical tags down the expansion. --- src/threadlistmodel.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/threadlistmodel.h') diff --git a/src/threadlistmodel.h b/src/threadlistmodel.h index 1aa0271..a7ce5d3 100644 --- a/src/threadlistmodel.h +++ b/src/threadlistmodel.h @@ -84,6 +84,18 @@ public: /// model because it owns the TagColors instance; a delegate reading /// config itself would be a second source of truth. PillColoursRole, + + /// True when the row is a MESSAGE row rather than a thread root. + /// Drives both the action scope and whether the view paints a tag + /// strip under the row. + IsMessageRole, + + /// The message id behind a message row. Empty on a thread root. + MessageIdRole, + + /// The message's reply depth, for the view's indentation. 1 for a + /// direct reply, since depth 0 is the root row itself. + MessageDepthRole, }; /// Row fill for a thread tagged `deleted`, and for one tagged `spam`. @@ -131,6 +143,23 @@ public: ThreadSummary threadAt(int row) const; + /// Fills in a thread's message rows once the worker has walked its tree. + /// + /// The depth-0 message is dropped: it is the thread's first message and the + /// ROOT row already stands for it. Keeping it would show a thread of seven + /// as one root and seven children, contradicting the reply count the row + /// advertises. Calling again replaces the rows rather than appending, so a + /// thread reloaded after a sync does not list its replies twice. + void setThreadMessages(const QString &threadId, + const QVector &nodes); + + /// True when the index is a message row rather than a thread root. + bool isMessageRow(const QModelIndex &index) const; + + /// The message row's node, or a default-constructed one for any index that + /// is not a message row. + MessageNode messageAt(const QModelIndex &index) const; + /// The account keys behind a thread's account tags, for item 49's /// per-account sync. /// -- cgit v1.2.3