From 2d33cbf6b1cd05e6fd340678f45755d969a36578 Mon Sep 17 00:00:00 2001 From: Azhar Momin Date: Tue, 17 Feb 2026 19:36:47 +0530 Subject: [PATCH] Show thread root event instead of latest thread event --- src/timeline/models/messagemodel.cpp | 19 ++++++++++++------- src/timeline/models/timelinemessagemodel.cpp | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/timeline/models/messagemodel.cpp b/src/timeline/models/messagemodel.cpp index be0c29907..6a557377b 100644 --- a/src/timeline/models/messagemodel.cpp +++ b/src/timeline/models/messagemodel.cpp @@ -183,6 +183,12 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const if (event.value().get().contentJson().contains("m.new_content"_L1)) { return EventStatus::Hidden; } + // A threaded event will be merged into the thread root event so + // also don't show. + const auto roomMessageEvent = eventCast(&event.value().get()); + if (roomMessageEvent && roomMessageEvent->relatesTo() && roomMessageEvent->relatesTo()->type == EventRelation::ThreadType) { + return EventStatus::Hidden; + } const auto pendingIt = eventRoom->findPendingEvent(event->get().transactionId()); if (pendingIt == eventRoom->pendingEvents().end()) { return EventStatus::Hidden; @@ -194,12 +200,9 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const return EventStatus::Hidden; } - auto roomMessageEvent = eventCast(&event.value().get()); - if (roomMessageEvent && (roomMessageEvent->isThreaded() || eventRoom->threads().contains(event.value().get().id()))) { - const auto &thread = eventRoom->threads().value(roomMessageEvent->isThreaded() ? roomMessageEvent->threadRootEventId() : event.value().get().id()); - if (thread.latestEventId != event.value().get().id()) { - return EventStatus::Hidden; - } + const auto roomMessageEvent = eventCast(&event.value().get()); + if (roomMessageEvent && roomMessageEvent->relatesTo() && roomMessageEvent->relatesTo()->type == EventRelation::ThreadType) { + return EventStatus::Hidden; } return EventStatus::Normal; } @@ -227,7 +230,7 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const if (role == IsThreadedRole) { if (auto roomMessageEvent = eventCast(&event.value().get())) { - return roomMessageEvent->isThreaded(); + return roomMessageEvent->isThreaded() || eventRoom->threads().contains(event->get().id()); } return {}; } @@ -236,6 +239,8 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const auto roomMessageEvent = eventCast(&event.value().get()); if (roomMessageEvent && roomMessageEvent->isThreaded()) { return roomMessageEvent->threadRootEventId(); + } else if (eventRoom->threads().contains(event->get().id())) { + return event->get().id(); } return {}; } diff --git a/src/timeline/models/timelinemessagemodel.cpp b/src/timeline/models/timelinemessagemodel.cpp index 9b791a815..cd198cc6b 100644 --- a/src/timeline/models/timelinemessagemodel.cpp +++ b/src/timeline/models/timelinemessagemodel.cpp @@ -6,6 +6,7 @@ #include "messagemodel_logging.h" #include +#include using namespace Quotient; @@ -125,6 +126,21 @@ void TimelineMessageModel::connectNewRoom() } } }); +#if Quotient_VERSION_MINOR > 9 + connect(m_room, &Room::newThread, this, [this](const QString &threadRootId) { + if (threadRootId.isEmpty()) { + return; + } + refreshEventRoles(threadRootId, {IsThreadedRole, ThreadRootRole}); + }); +#elif Quotient_VERSION_MINOR == 9 && Quotient_VERSION_PATCH >= 4 + connect(m_room, &Room::newThread, this, [this](const Thread &newThread) { + if (newThread.threadRootId.isEmpty()) { + return; + } + refreshEventRoles(newThread.threadRootId, {IsThreadedRole, ThreadRootRole}); + }); +#endif connect(m_room->connection(), &Connection::ignoredUsersListChanged, this, [this] { beginResetModel(); endResetModel();