From 2df2046d1dc5d3e4133f89f634efa6a1726a2f30 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 12 Apr 2022 21:49:21 -0400 Subject: Display unread notifications for spaces --- src/timeline/CommunitiesModel.cpp | 54 ++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 4f650f49..b88896ee 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -9,12 +9,19 @@ #include "Cache.h" #include "Cache_p.h" +#include "ChatPage.h" #include "Logging.h" #include "UserSettingsPage.h" CommunitiesModel::CommunitiesModel(QObject *parent) : QAbstractListModel(parent) -{} +{ + connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { + // Simply updating every space is easier than tracking which ones need updated. + if (!spaces_.empty()) + emit dataChanged(index(2, 0), index(spaces_.size() + 2, 0), {Roles::UnreadMessages}); + }); +} QHash CommunitiesModel::roleNames() const @@ -28,6 +35,7 @@ CommunitiesModel::roleNames() const {Hidden, "hidden"}, {Depth, "depth"}, {Id, "id"}, + {UnreadMessages, "unreadMessages"}, }; } @@ -70,6 +78,8 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return ""; + case CommunitiesModel::Roles::UnreadMessages: + return 0; } } else if (index.row() == 1) { switch (role) { @@ -91,9 +101,11 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return "dm"; + case CommunitiesModel::Roles::UnreadMessages: + return 0; } } else if (index.row() - 2 < spaceOrder_.size()) { - auto id = spaceOrder_.tree.at(index.row() - 2).name; + auto id = spaceOrder_.tree.at(index.row() - 2).id; switch (role) { case CommunitiesModel::Roles::AvatarUrl: return QString::fromStdString(spaces_.at(id).avatar_url); @@ -110,7 +122,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return hiddentTagIds_.contains("space:" + id); case CommunitiesModel::Roles::Parent: { if (auto p = spaceOrder_.parent(index.row() - 2); p >= 0) - return spaceOrder_.tree[p].name; + return spaceOrder_.tree[p].id; return ""; } @@ -118,6 +130,8 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return spaceOrder_.tree.at(index.row() - 2).depth; case CommunitiesModel::Roles::Id: return "space:" + id; + case CommunitiesModel::Roles::UnreadMessages: + return getChildNotifications(id); } } else if (index.row() - 2 < tags_.size() + spaceOrder_.size()) { auto tag = tags_.at(index.row() - 2 - spaceOrder_.size()); @@ -171,6 +185,8 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return "tag:" + tag; + case CommunitiesModel::Roles::UnreadMessages: + return 0; } } return QVariant(); @@ -279,6 +295,7 @@ CommunitiesModel::initializeSidebar() hiddentTagIds_ = UserSettings::instance()->hiddenTags(); spaceOrder_.restoreCollapsed(); + endResetModel(); emit tagsChanged(); @@ -298,12 +315,12 @@ CommunitiesModel::FlatTree::storeCollapsed() for (const auto &e : tree) { if (e.depth > depth) { - current.push_back(e.name); + current.push_back(e.id); } else if (e.depth == depth) { - current.back() = e.name; + current.back() = e.id; } else { current.pop_back(); - current.back() = e.name; + current.back() = e.id; } if (e.collapsed) @@ -323,12 +340,12 @@ CommunitiesModel::FlatTree::restoreCollapsed() for (auto &e : tree) { if (e.depth > depth) { - current.push_back(e.name); + current.push_back(e.id); } else if (e.depth == depth) { - current.back() = e.name; + current.back() = e.id; } else { current.pop_back(); - current.back() = e.name; + current.back() = e.id; } if (elements.contains(current)) @@ -353,7 +370,6 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) bool tagsUpdated = false; for (const auto &[roomid, room] : sync_.rooms.join) { - (void)roomid; for (const auto &e : room.account_data.events) if (std::holds_alternative< mtx::events::AccountDataEvent>(e)) { @@ -392,7 +408,7 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) } void -CommunitiesModel::setCurrentTagId(QString tagId) +CommunitiesModel::setCurrentTagId(const QString &tagId) { if (tagId.startsWith(QLatin1String("tag:"))) { auto tag = tagId.mid(4); @@ -406,7 +422,7 @@ CommunitiesModel::setCurrentTagId(QString tagId) } else if (tagId.startsWith(QLatin1String("space:"))) { auto tag = tagId.mid(6); for (const auto &t : spaceOrder_.tree) { - if (t.name == tag) { + if (t.id == tag) { this->currentTagId_ = tagId; emit currentTagIdChanged(currentTagId_); return; @@ -449,6 +465,20 @@ CommunitiesModel::toggleTagId(QString tagId) emit hiddenTagsChanged(); } +int +CommunitiesModel::getChildNotifications(const QString &space_id) const +{ + auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(space_id.toStdString())); + int total{0}; + for (const auto &[child_id, child] : children) { + if (child.is_space) + total += getChildNotifications(child_id); + else + total += child.notification_count; + } + return total; +} + FilteredCommunitiesModel::FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent) : QSortFilterProxyModel(parent) { -- cgit 1.5.1 From e7c24b094fcf400acd6b038105e13272cf87d617 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 19 Apr 2022 20:49:37 -0400 Subject: Fix typoed variable name --- src/timeline/CommunitiesModel.cpp | 18 +++++++++--------- src/timeline/CommunitiesModel.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index b88896ee..116fa0a0 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -94,7 +94,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Collapsible: return false; case CommunitiesModel::Roles::Hidden: - return hiddentTagIds_.contains(QStringLiteral("dm")); + return hiddenTagIds_.contains(QStringLiteral("dm")); case CommunitiesModel::Roles::Parent: return ""; case CommunitiesModel::Roles::Depth: @@ -119,7 +119,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return idx != spaceOrder_.lastChild(idx); } case CommunitiesModel::Roles::Hidden: - return hiddentTagIds_.contains("space:" + id); + return hiddenTagIds_.contains("space:" + id); case CommunitiesModel::Roles::Parent: { if (auto p = spaceOrder_.parent(index.row() - 2); p >= 0) return spaceOrder_.tree[p].id; @@ -174,7 +174,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const switch (role) { case CommunitiesModel::Roles::Hidden: - return hiddentTagIds_.contains("tag:" + tag); + return hiddenTagIds_.contains("tag:" + tag); case CommunitiesModel::Roles::Collapsed: return true; case CommunitiesModel::Roles::Collapsible: @@ -293,7 +293,7 @@ CommunitiesModel::initializeSidebar() for (const auto &t : ts) tags_.push_back(QString::fromStdString(t)); - hiddentTagIds_ = UserSettings::instance()->hiddenTags(); + hiddenTagIds_ = UserSettings::instance()->hiddenTags(); spaceOrder_.restoreCollapsed(); endResetModel(); @@ -441,12 +441,12 @@ CommunitiesModel::setCurrentTagId(const QString &tagId) void CommunitiesModel::toggleTagId(QString tagId) { - if (hiddentTagIds_.contains(tagId)) { - hiddentTagIds_.removeOne(tagId); - UserSettings::instance()->setHiddenTags(hiddentTagIds_); + if (hiddenTagIds_.contains(tagId)) { + hiddenTagIds_.removeOne(tagId); + UserSettings::instance()->setHiddenTags(hiddenTagIds_); } else { - hiddentTagIds_.push_back(tagId); - UserSettings::instance()->setHiddenTags(hiddentTagIds_); + hiddenTagIds_.push_back(tagId); + UserSettings::instance()->setHiddenTags(hiddenTagIds_); } if (tagId.startsWith(QLatin1String("tag:"))) { diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index d54d9907..30980f00 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -152,7 +152,7 @@ private: QStringList tags_; QString currentTagId_; - QStringList hiddentTagIds_; + QStringList hiddenTagIds_; FlatTree spaceOrder_; std::map spaces_; -- cgit 1.5.1 From 169384f0fa41cc8a52428f27bc3042dc849dd8c9 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Tue, 19 Apr 2022 23:18:11 -0400 Subject: Add space notifications to room list --- resources/qml/RoomList.qml | 80 +++++++++++++++++++++++---------------- src/Utils.cpp | 15 ++++++++ src/Utils.h | 3 ++ src/timeline/CommunitiesModel.cpp | 17 +-------- src/timeline/CommunitiesModel.h | 2 - src/timeline/RoomlistModel.cpp | 5 ++- src/timeline/TimelineModel.cpp | 17 ++++++--- 7 files changed, 84 insertions(+), 55 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index 910fc252..126d82be 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -348,7 +348,45 @@ Page { height: avatar.height spacing: Nheko.paddingSmall + Component { + id: notificationBubble + + Rectangle { + visible: notificationCount > 0 + Layout.alignment: Qt.AlignRight + Layout.leftMargin: Nheko.paddingSmall + height: notificationBubbleText.height + Nheko.paddingMedium + width: Math.max(notificationBubbleText.width, height) + radius: height / 2 + color: hasLoudNotification ? Nheko.theme.red : roomItem.bubbleBackground + ToolTip.text: notificationCount + ToolTip.delay: Nheko.tooltipDelay + ToolTip.visible: notificationBubbleHover.hovered && (notificationCount > 9999) + + Label { + id: notificationBubbleText + + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + width: Math.max(implicitWidth + Nheko.paddingMedium, parent.height) + font.bold: true + font.pixelSize: fontMetrics.font.pixelSize * 0.8 + color: hasLoudNotification ? "white" : roomItem.bubbleText + text: notificationCount > 9999 ? "9999+" : notificationCount + + HoverHandler { + id: notificationBubbleHover + } + + } + + } + } + RowLayout { + id: titleRow + Layout.alignment: Qt.AlignTop Layout.fillWidth: true spacing: Nheko.paddingSmall @@ -374,9 +412,16 @@ Page { text: time } + Loader { + sourceComponent: notificationBubble + active: isSpace + } + } RowLayout { + id: subtextRow + Layout.fillWidth: true spacing: 0 visible: !isSpace @@ -392,40 +437,11 @@ Page { Layout.fillWidth: true } - Rectangle { - id: notificationBubble - - visible: notificationCount > 0 - Layout.alignment: Qt.AlignRight - Layout.leftMargin: Nheko.paddingSmall - height: notificationBubbleText.height + Nheko.paddingMedium - Layout.preferredWidth: Math.max(notificationBubbleText.width, height) - radius: height / 2 - color: hasLoudNotification ? Nheko.theme.red : roomItem.bubbleBackground - ToolTip.text: notificationCount - ToolTip.delay: Nheko.tooltipDelay - ToolTip.visible: notificationBubbleHover.hovered && (notificationCount > 9999) - - Label { - id: notificationBubbleText - - anchors.centerIn: parent - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - width: Math.max(implicitWidth + Nheko.paddingMedium, parent.height) - font.bold: true - font.pixelSize: fontMetrics.font.pixelSize * 0.8 - color: hasLoudNotification ? "white" : roomItem.bubbleText - text: notificationCount > 9999 ? "9999+" : notificationCount - - HoverHandler { - id: notificationBubbleHover - } - - } + Loader { + sourceComponent: notificationBubble + active: !isSpace } - } } diff --git a/src/Utils.cpp b/src/Utils.cpp index 0ac37d8e..aa36d3d9 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -27,6 +27,7 @@ #include #include "Cache.h" +#include "Cache_p.h" #include "Config.h" #include "EventAccessors.h" #include "Logging.h" @@ -880,3 +881,17 @@ utils::markRoomAsDirect(QString roomid, std::vector members) }); }); } + +int +utils::getChildNotificationsForSpace(const QString &spaceId) +{ + auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(spaceId.toStdString())); + int total{0}; + for (const auto &[childId, child] : children) { + if (child.is_space) + total += utils::getChildNotificationsForSpace(childId); + else + total += child.notification_count; + } + return total; +} diff --git a/src/Utils.h b/src/Utils.h index 0b6034ac..c20544f2 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -311,4 +311,7 @@ removeDirectFromRoom(QString roomid); void markRoomAsDirect(QString roomid, std::vector members); + +int +getChildNotificationsForSpace(const QString &spaceId); } diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 116fa0a0..724a6e60 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -12,6 +12,7 @@ #include "ChatPage.h" #include "Logging.h" #include "UserSettingsPage.h" +#include "Utils.h" CommunitiesModel::CommunitiesModel(QObject *parent) : QAbstractListModel(parent) @@ -131,7 +132,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Id: return "space:" + id; case CommunitiesModel::Roles::UnreadMessages: - return getChildNotifications(id); + return utils::getChildNotificationsForSpace(id); } } else if (index.row() - 2 < tags_.size() + spaceOrder_.size()) { auto tag = tags_.at(index.row() - 2 - spaceOrder_.size()); @@ -465,20 +466,6 @@ CommunitiesModel::toggleTagId(QString tagId) emit hiddenTagsChanged(); } -int -CommunitiesModel::getChildNotifications(const QString &space_id) const -{ - auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(space_id.toStdString())); - int total{0}; - for (const auto &[child_id, child] : children) { - if (child.is_space) - total += getChildNotifications(child_id); - else - total += child.notification_count; - } - return total; -} - FilteredCommunitiesModel::FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent) : QSortFilterProxyModel(parent) { diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index 30980f00..b29a5385 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -148,8 +148,6 @@ signals: void containsSubspacesChanged(); private: - int getChildNotifications(const QString &space_id) const; - QStringList tags_; QString currentTagId_; QStringList hiddenTagIds_; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 1cf16243..3b46c053 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -330,10 +330,13 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) Qt::DisplayRole, }); + if (getRoomById(room_id)->isSpace()) + return; // no need to update space notifications + int total_unread_msgs = 0; for (const auto &room : qAsConst(models)) { - if (!room.isNull()) + if (!room.isNull() && !room->isSpace()) total_unread_msgs += room->notificationCount(); } diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 3fe4c07f..308d358b 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -352,16 +352,23 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj { this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString()); - auto roomInfo = cache::singleRoomInfo(room_id_.toStdString()); - this->isSpace_ = roomInfo.is_space; - this->notification_count = roomInfo.notification_count; - this->highlight_count = roomInfo.highlight_count; - lastMessage_.timestamp = roomInfo.approximate_last_modification_ts; + auto roomInfo = cache::singleRoomInfo(room_id_.toStdString()); + this->isSpace_ = roomInfo.is_space; + this->notification_count = + isSpace_ ? utils::getChildNotificationsForSpace(room_id_) : roomInfo.notification_count; + this->highlight_count = roomInfo.highlight_count; + lastMessage_.timestamp = roomInfo.approximate_last_modification_ts; // this connection will simplify adding the plainRoomNameChanged() signal everywhere that it // needs to be connect(this, &TimelineModel::roomNameChanged, this, &TimelineModel::plainRoomNameChanged); + if (isSpace_) + connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { + notification_count = utils::getChildNotificationsForSpace(room_id_); + emit notificationsChanged(); + }); + connect( this, &TimelineModel::redactionFailed, -- cgit 1.5.1 From e446e3d6792ff6a1664934b24e19fc80ffbbd22e Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Wed, 20 Apr 2022 21:30:16 -0400 Subject: Add loud notifications for spaces --- resources/qml/CommunitiesList.qml | 8 ++++---- src/Utils.cpp | 18 +++++++++++------- src/Utils.h | 4 +++- src/timeline/CommunitiesModel.cpp | 8 +++++++- src/timeline/CommunitiesModel.h | 1 + src/timeline/TimelineModel.cpp | 9 ++++++--- 6 files changed, 32 insertions(+), 16 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/resources/qml/CommunitiesList.qml b/resources/qml/CommunitiesList.qml index f5f20a91..371e347e 100644 --- a/resources/qml/CommunitiesList.qml +++ b/resources/qml/CommunitiesList.qml @@ -164,7 +164,7 @@ Page { height: collapsedNotificationBubbleText.height + Nheko.paddingMedium width: Math.max(collapsedNotificationBubbleText.width, height) radius: height / 2 - color: /*hasLoudNotification ? Nheko.theme.red :*/ communityItem.bubbleBackground + color: model.hasLoudNotification ? Nheko.theme.red : communityItem.bubbleBackground ToolTip.text: model.unreadMessages ToolTip.delay: Nheko.tooltipDelay ToolTip.visible: collapsedNotificationBubbleHover.hovered && (model.unreadMessages > 9999) @@ -178,7 +178,7 @@ Page { width: Math.max(implicitWidth + Nheko.paddingMedium, parent.height) font.bold: true font.pixelSize: fontMetrics.font.pixelSize * 0.6 - color: /*hasLoudNotification ? "white" :*/ communityItem.bubbleText + color: model.hasLoudNotification ? "white" : communityItem.bubbleText text: model.unreadMessages > 9999 ? "9999+" : model.unreadMessages HoverHandler { @@ -214,7 +214,7 @@ Page { height: notificationBubbleText.height + Nheko.paddingMedium Layout.preferredWidth: Math.max(notificationBubbleText.width, height) radius: height / 2 - color: /*hasLoudNotification ? Nheko.theme.red :*/ communityItem.bubbleBackground + color: model.hasLoudNotification ? Nheko.theme.red : communityItem.bubbleBackground ToolTip.text: model.unreadMessages ToolTip.delay: Nheko.tooltipDelay ToolTip.visible: notificationBubbleHover.hovered && (model.unreadMessages > 9999) @@ -228,7 +228,7 @@ Page { width: Math.max(implicitWidth + Nheko.paddingMedium, parent.height) font.bold: true font.pixelSize: fontMetrics.font.pixelSize * 0.8 - color: /*hasLoudNotification ? "white" :*/ communityItem.bubbleText + color: model.hasLoudNotification ? "white" : communityItem.bubbleText text: model.unreadMessages > 9999 ? "9999+" : model.unreadMessages HoverHandler { diff --git a/src/Utils.cpp b/src/Utils.cpp index aa36d3d9..3a90bd50 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -882,16 +882,20 @@ utils::markRoomAsDirect(QString roomid, std::vector members) }); } -int +QPair utils::getChildNotificationsForSpace(const QString &spaceId) { auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(spaceId.toStdString())); - int total{0}; + QPair retVal; for (const auto &[childId, child] : children) { - if (child.is_space) - total += utils::getChildNotificationsForSpace(childId); - else - total += child.notification_count; + if (child.is_space) { + auto temp{utils::getChildNotificationsForSpace(childId)}; + retVal.first += temp.first; + retVal.second += temp.second; + } else { + retVal.first += child.notification_count; + retVal.second += child.highlight_count; + } } - return total; + return retVal; } diff --git a/src/Utils.h b/src/Utils.h index c20544f2..bdd56d55 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -312,6 +312,8 @@ removeDirectFromRoom(QString roomid); void markRoomAsDirect(QString roomid, std::vector members); -int +//! Returns a pair of integers representing the unread notifications in a space and how many of them +//! are loud notifications, respectively. +QPair getChildNotificationsForSpace(const QString &spaceId); } diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 724a6e60..ccc0adfe 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -37,6 +37,7 @@ CommunitiesModel::roleNames() const {Depth, "depth"}, {Id, "id"}, {UnreadMessages, "unreadMessages"}, + {HasLoudNotification, "hasLoudNotification"}, }; } @@ -80,6 +81,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Id: return ""; case CommunitiesModel::Roles::UnreadMessages: + case CommunitiesModel::Roles::HasLoudNotification: return 0; } } else if (index.row() == 1) { @@ -103,6 +105,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Id: return "dm"; case CommunitiesModel::Roles::UnreadMessages: + case CommunitiesModel::Roles::HasLoudNotification: return 0; } } else if (index.row() - 2 < spaceOrder_.size()) { @@ -132,7 +135,9 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Id: return "space:" + id; case CommunitiesModel::Roles::UnreadMessages: - return utils::getChildNotificationsForSpace(id); + return utils::getChildNotificationsForSpace(id).first; + case CommunitiesModel::Roles::HasLoudNotification: + return utils::getChildNotificationsForSpace(id).second > 0; } } else if (index.row() - 2 < tags_.size() + spaceOrder_.size()) { auto tag = tags_.at(index.row() - 2 - spaceOrder_.size()); @@ -187,6 +192,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Id: return "tag:" + tag; case CommunitiesModel::Roles::UnreadMessages: + case CommunitiesModel::Roles::HasLoudNotification: return 0; } } diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index b29a5385..7be98939 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -49,6 +49,7 @@ public: Depth, Id, UnreadMessages, + HasLoudNotification, }; struct FlatTree diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 308d358b..1a9f957b 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -355,8 +355,9 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj auto roomInfo = cache::singleRoomInfo(room_id_.toStdString()); this->isSpace_ = roomInfo.is_space; this->notification_count = - isSpace_ ? utils::getChildNotificationsForSpace(room_id_) : roomInfo.notification_count; - this->highlight_count = roomInfo.highlight_count; + isSpace_ ? utils::getChildNotificationsForSpace(room_id_).first : roomInfo.notification_count; + this->highlight_count = + isSpace_ ? utils::getChildNotificationsForSpace(room_id_).second : roomInfo.highlight_count; lastMessage_.timestamp = roomInfo.approximate_last_modification_ts; // this connection will simplify adding the plainRoomNameChanged() signal everywhere that it @@ -365,7 +366,9 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj if (isSpace_) connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { - notification_count = utils::getChildNotificationsForSpace(room_id_); + auto temp{utils::getChildNotificationsForSpace(room_id_)}; + notification_count = temp.first; + highlight_count = temp.second; emit notificationsChanged(); }); -- cgit 1.5.1 From f03c506bdf8a83b96fef9b05b565fabc27341e48 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 23 Apr 2022 22:58:44 -0400 Subject: Inform Qt that loud notifications changed --- src/timeline/CommunitiesModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index ccc0adfe..c89e7661 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -20,7 +20,7 @@ CommunitiesModel::CommunitiesModel(QObject *parent) connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { // Simply updating every space is easier than tracking which ones need updated. if (!spaces_.empty()) - emit dataChanged(index(2, 0), index(spaces_.size() + 2, 0), {Roles::UnreadMessages}); + emit dataChanged(index(2, 0), index(spaces_.size() + 2, 0), {Roles::UnreadMessages, Roles::HasLoudNotification}); }); } -- cgit 1.5.1 From 7e9646cc25e09aab594f10d6a2210b550d9fb0af Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 25 Apr 2022 20:54:40 -0400 Subject: Add notifications to all sidebar items --- src/timeline/CommunitiesModel.cpp | 53 +++++++++++++++++++++++++++++++-------- src/timeline/CommunitiesModel.h | 2 ++ 2 files changed, 45 insertions(+), 10 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index c89e7661..34da6157 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -20,7 +20,7 @@ CommunitiesModel::CommunitiesModel(QObject *parent) connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { // Simply updating every space is easier than tracking which ones need updated. if (!spaces_.empty()) - emit dataChanged(index(2, 0), index(spaces_.size() + 2, 0), {Roles::UnreadMessages, Roles::HasLoudNotification}); + emit dataChanged(index(0, 0), index(spaces_.size() + tags_.size() + 1, 0), {Roles::UnreadMessages, Roles::HasLoudNotification}); }); } @@ -80,9 +80,17 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return ""; - case CommunitiesModel::Roles::UnreadMessages: + case CommunitiesModel::Roles::UnreadMessages: { + int total{0}; + for (const auto &[id, info] : cache::getRoomInfo(cache::joinedRooms())) + total += info.notification_count; + return total; + } case CommunitiesModel::Roles::HasLoudNotification: - return 0; + for (const auto &[id, info] : cache::getRoomInfo(cache::joinedRooms())) + if (info.highlight_count > 0) + return true; + return false; } } else if (index.row() == 1) { switch (role) { @@ -104,9 +112,17 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return "dm"; - case CommunitiesModel::Roles::UnreadMessages: + case CommunitiesModel::Roles::UnreadMessages: { + int total{0}; + for (const auto &[id, info] : cache::getRoomInfo(directMessages_)) + total += info.notification_count; + return total; + } case CommunitiesModel::Roles::HasLoudNotification: - return 0; + for (const auto &[id, info] : cache::getRoomInfo(directMessages_)) + if (info.highlight_count > 0) + return true; + return false; } } else if (index.row() - 2 < spaceOrder_.size()) { auto id = spaceOrder_.tree.at(index.row() - 2).id; @@ -191,9 +207,22 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return "tag:" + tag; - case CommunitiesModel::Roles::UnreadMessages: - case CommunitiesModel::Roles::HasLoudNotification: - return 0; + case CommunitiesModel::Roles::UnreadMessages: { + int total{0}; + auto rooms{cache::joinedRooms()}; + for (const auto &[roomid, info] : cache::getRoomInfo(rooms)) + if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != std::end(info.tags)) + total += info.notification_count; + return total; + } + case CommunitiesModel::Roles::HasLoudNotification: { + auto rooms{cache::joinedRooms()}; + for (const auto &[roomid, info] : cache::getRoomInfo(rooms)) + if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != std::end(info.tags)) + if (info.highlight_count > 0) + return true; + return false; + } } } return QVariant(); @@ -403,8 +432,12 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) tagsUpdated = true; } for (const auto &e : sync_.account_data.events) { - if (std::holds_alternative< - mtx::events::AccountDataEvent>(e)) { + if (auto event = + std::get_if>(&e)) { + directMessages_.clear(); + for (const auto &[userId, roomIds] : event->content.user_to_rooms) + for (const auto &roomId : roomIds) + directMessages_.push_back(roomId); tagsUpdated = true; break; } diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index 7be98939..bcb487e7 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -50,6 +50,7 @@ public: Id, UnreadMessages, HasLoudNotification, + IsDirect, }; struct FlatTree @@ -154,6 +155,7 @@ private: QStringList hiddenTagIds_; FlatTree spaceOrder_; std::map spaces_; + std::vector directMessages_; friend class FilteredCommunitiesModel; }; -- cgit 1.5.1 From 4428e0e0b87f710501fb8210b8c310204bf3603e Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Mon, 25 Apr 2022 20:57:18 -0400 Subject: make lint --- src/timeline/CommunitiesModel.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 34da6157..8e1cf140 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -20,7 +20,9 @@ CommunitiesModel::CommunitiesModel(QObject *parent) connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { // Simply updating every space is easier than tracking which ones need updated. if (!spaces_.empty()) - emit dataChanged(index(0, 0), index(spaces_.size() + tags_.size() + 1, 0), {Roles::UnreadMessages, Roles::HasLoudNotification}); + emit dataChanged(index(0, 0), + index(spaces_.size() + tags_.size() + 1, 0), + {Roles::UnreadMessages, Roles::HasLoudNotification}); }); } @@ -211,14 +213,16 @@ CommunitiesModel::data(const QModelIndex &index, int role) const int total{0}; auto rooms{cache::joinedRooms()}; for (const auto &[roomid, info] : cache::getRoomInfo(rooms)) - if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != std::end(info.tags)) + if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != + std::end(info.tags)) total += info.notification_count; return total; } case CommunitiesModel::Roles::HasLoudNotification: { auto rooms{cache::joinedRooms()}; for (const auto &[roomid, info] : cache::getRoomInfo(rooms)) - if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != std::end(info.tags)) + if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != + std::end(info.tags)) if (info.highlight_count > 0) return true; return false; -- cgit 1.5.1 From 7cbde0712f2f46a8cbed133aa01889f2de99e0e5 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Thu, 28 Apr 2022 17:00:12 -0400 Subject: Allow muting spaces; other general improvements --- resources/qml/CommunitiesList.qml | 33 ++++++++++++++++++++++----- src/UserSettingsPage.cpp | 19 +++++++++++----- src/UserSettingsPage.h | 9 +++++--- src/timeline/CommunitiesModel.cpp | 47 ++++++++++++++++++++++++++++++++++----- src/timeline/CommunitiesModel.h | 3 +++ 5 files changed, 92 insertions(+), 19 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/resources/qml/CommunitiesList.qml b/resources/qml/CommunitiesList.qml index 62ac341a..5bc20dbe 100644 --- a/resources/qml/CommunitiesList.qml +++ b/resources/qml/CommunitiesList.qml @@ -37,14 +37,27 @@ Page { id: communityContextMenu property string tagId + property bool hidden + property bool muted - function show(id_, tags_) { + function show(id_, hidden_, muted_) { tagId = id_; + hidden = hidden_; + muted = muted_; open(); } + Platform.MenuItem { + text: qsTr("Do not show notification counts for this space or tag.") + checkable: true + checked: communityContextMenu.muted + onTriggered: Communities.toggleTagMute(communityContextMenu.tagId) + } + Platform.MenuItem { text: qsTr("Hide rooms with this tag or from this space by default.") + checkable: true + checked: communityContextMenu.hidden onTriggered: Communities.toggleTagId(communityContextMenu.tagId) } @@ -68,6 +81,7 @@ Page { required property string id required property int unreadMessages required property bool hasLoudNotification + required property bool muted height: avatarSize + 2 * Nheko.paddingMedium width: ListView.view.width @@ -76,7 +90,7 @@ Page { ToolTip.text: communityItem.tooltip ToolTip.delay: Nheko.tooltipDelay onClicked: Communities.setCurrentTagId(communityItem.id) - onPressAndHold: communityContextMenu.show(communityItem.id) + onPressAndHold: communityContextMenu.show(communityItem.id, communityItem.hidden, communityItem.muted) states: [ State { name: "highlight" @@ -113,7 +127,7 @@ Page { TapHandler { acceptedButtons: Qt.RightButton - onSingleTapped: communityContextMenu.show(communityItem.id) + onSingleTapped: communityContextMenu.show(communityItem.id, communityItem.hidden, communityItem.muted) gesturePolicy: TapHandler.ReleaseWithinBounds acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus | PointerDevice.TouchPad } @@ -174,6 +188,8 @@ Page { mayBeVisible: { if (!communitySidebar.collapsed) return false + else if (communityItem.muted) + return false else if (Settings.spaceNotifications === Settings.SpaceNotificationsOff) return false else if (Settings.spaceNotifications === Settings.SidebarHiddenRooms) @@ -215,10 +231,17 @@ Page { mayBeVisible: { if (communitySidebar.collapsed) return false + else if (communityItem.muted) + return false else if (Settings.spaceNotification === Settings.SpaceNotificationsOff) return false - else if ((Settings.spaceNotifications === Settings.SidebarHiddenRooms) && communityItem.hidden) - return true + else if (Settings.spaceNotifications === Settings.SidebarHiddenRooms) + { + if (communityItem.hidden) + return true + else + return false + } else return true } diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index c4cc339b..2c6dc782 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -140,7 +140,8 @@ UserSettings::load(std::optional profile) userId_ = settings.value(prefix + "auth/user_id", "").toString(); deviceId_ = settings.value(prefix + "auth/device_id", "").toString(); hiddenTags_ = settings.value(prefix + "user/hidden_tags", QStringList{}).toStringList(); - hiddenPins_ = settings.value(prefix + "user/hidden_pins", QStringList{}).toStringList(); + mutedTags_ = settings.value(prefix + "user/muted_tags", QStringList{"global"}).toStringList(); + hiddenPins_ = settings.value(prefix + "user/hidden_pins", QStringList{}).toStringList(); hiddenWidgets_ = settings.value(prefix + "user/hidden_widgets", QStringList{}).toStringList(); recentReactions_ = settings.value(prefix + "user/recent_reactions", QStringList{}).toStringList(); @@ -228,14 +229,21 @@ UserSettings::setGroupView(bool state) } void -UserSettings::setHiddenTags(QStringList hiddenTags) +UserSettings::setHiddenTags(const QStringList &hiddenTags) { hiddenTags_ = hiddenTags; save(); } void -UserSettings::setHiddenPins(QStringList hiddenTags) +UserSettings::setMutedTags(const QStringList &mutedTags) +{ + mutedTags_ = mutedTags; + save(); +} + +void +UserSettings::setHiddenPins(const QStringList &hiddenTags) { hiddenPins_ = hiddenTags; save(); @@ -243,7 +251,7 @@ UserSettings::setHiddenPins(QStringList hiddenTags) } void -UserSettings::setHiddenWidgets(QStringList hiddenTags) +UserSettings::setHiddenWidgets(const QStringList &hiddenTags) { hiddenWidgets_ = hiddenTags; save(); @@ -851,6 +859,7 @@ UserSettings::save() onlyShareKeysWithVerifiedUsers_); settings.setValue(prefix + "user/online_key_backup", useOnlineKeyBackup_); settings.setValue(prefix + "user/hidden_tags", hiddenTags_); + settings.setValue(prefix + "user/muted_tags", mutedTags_); settings.setValue(prefix + "user/hidden_pins", hiddenPins_); settings.setValue(prefix + "user/hidden_widgets", hiddenWidgets_); settings.setValue(prefix + "user/recent_reactions", recentReactions_); @@ -1451,7 +1460,7 @@ UserSettingsModel::data(const QModelIndex &index, int role) const case SpaceNotifications: return QStringList{QStringLiteral("Sidebar and room list"), QStringLiteral("Sidebar"), - QStringLiteral("Sidebar (hidden rooms only)"), + QStringLiteral("Sidebar (hidden spaces and tags only)"), QStringLiteral("Off")}; } } else if (role == Good) { diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index daf41383..db12b1e6 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -196,9 +196,10 @@ public: void setDeviceId(QString deviceId); void setHomeserver(QString homeserver); void setDisableCertificateValidation(bool disabled); - void setHiddenTags(QStringList hiddenTags); - void setHiddenPins(QStringList hiddenTags); - void setHiddenWidgets(QStringList hiddenTags); + void setHiddenTags(const QStringList &hiddenTags); + void setMutedTags(const QStringList &mutedTags); + void setHiddenPins(const QStringList &hiddenTags); + void setHiddenWidgets(const QStringList &hiddenTags); void setRecentReactions(QStringList recent); void setUseIdenticon(bool state); void setOpenImageExternal(bool state); @@ -263,6 +264,7 @@ public: QString homeserver() const { return homeserver_; } bool disableCertificateValidation() const { return disableCertificateValidation_; } QStringList hiddenTags() const { return hiddenTags_; } + QStringList mutedTags() const { return mutedTags_; } QStringList hiddenPins() const { return hiddenPins_; } QStringList hiddenWidgets() const { return hiddenWidgets_; } QStringList recentReactions() const { return recentReactions_; } @@ -385,6 +387,7 @@ private: QString deviceId_; QString homeserver_; QStringList hiddenTags_; + QStringList mutedTags_; QStringList hiddenPins_; QStringList hiddenWidgets_; QStringList recentReactions_; diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 8e1cf140..91f7d555 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -16,6 +16,8 @@ CommunitiesModel::CommunitiesModel(QObject *parent) : QAbstractListModel(parent) + , hiddenTagIds_{UserSettings::instance()->hiddenTags()} + , mutedTagIds_{UserSettings::instance()->mutedTags()} { connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { // Simply updating every space is easier than tracking which ones need updated. @@ -40,6 +42,7 @@ CommunitiesModel::roleNames() const {Id, "id"}, {UnreadMessages, "unreadMessages"}, {HasLoudNotification, "hasLoudNotification"}, + {Muted, "muted"}, }; } @@ -62,6 +65,13 @@ CommunitiesModel::setData(const QModelIndex &index, const QVariant &value, int r QVariant CommunitiesModel::data(const QModelIndex &index, int role) const { + if (role == CommunitiesModel::Roles::Muted) { + if (index.row() == 0) + return mutedTagIds_.contains(QStringLiteral("global")); + else + return mutedTagIds_.contains(data(index, CommunitiesModel::Roles::Id).toString()); + } + if (index.row() == 0) { switch (role) { case CommunitiesModel::Roles::AvatarUrl: @@ -333,7 +343,6 @@ CommunitiesModel::initializeSidebar() for (const auto &t : ts) tags_.push_back(QString::fromStdString(t)); - hiddenTagIds_ = UserSettings::instance()->hiddenTags(); spaceOrder_.restoreCollapsed(); endResetModel(); @@ -485,13 +494,11 @@ CommunitiesModel::setCurrentTagId(const QString &tagId) void CommunitiesModel::toggleTagId(QString tagId) { - if (hiddenTagIds_.contains(tagId)) { + if (hiddenTagIds_.contains(tagId)) hiddenTagIds_.removeOne(tagId); - UserSettings::instance()->setHiddenTags(hiddenTagIds_); - } else { + else hiddenTagIds_.push_back(tagId); - UserSettings::instance()->setHiddenTags(hiddenTagIds_); - } + UserSettings::instance()->setHiddenTags(hiddenTagIds_); if (tagId.startsWith(QLatin1String("tag:"))) { auto idx = tags_.indexOf(tagId.mid(4)); @@ -509,6 +516,34 @@ CommunitiesModel::toggleTagId(QString tagId) emit hiddenTagsChanged(); } +void +CommunitiesModel::toggleTagMute(QString tagId) +{ + if (tagId.isEmpty()) + tagId = QStringLiteral("global"); + + if (mutedTagIds_.contains(tagId)) + mutedTagIds_.removeOne(tagId); + else + mutedTagIds_.push_back(tagId); + UserSettings::instance()->setMutedTags(mutedTagIds_); + + if (tagId.startsWith(QLatin1String("tag:"))) { + auto idx = tags_.indexOf(tagId.mid(4)); + if (idx != -1) + emit dataChanged(index(idx + 1 + spaceOrder_.size()), + index(idx + 1 + spaceOrder_.size())); + } else if (tagId.startsWith(QLatin1String("space:"))) { + auto idx = spaceOrder_.indexOf(tagId.mid(6)); + if (idx != -1) + emit dataChanged(index(idx + 1), index(idx + 1)); + } else if (tagId == QLatin1String("dm")) { + emit dataChanged(index(1), index(1)); + } else if (tagId == QLatin1String("global")) { + emit dataChanged(index(0), index(0)); + } +} + FilteredCommunitiesModel::FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent) : QSortFilterProxyModel(parent) { diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index bcb487e7..5a659751 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -50,6 +50,7 @@ public: Id, UnreadMessages, HasLoudNotification, + Muted, IsDirect, }; @@ -141,6 +142,7 @@ public slots: return tagsWD; } void toggleTagId(QString tagId); + void toggleTagMute(QString tagId); FilteredCommunitiesModel *filtered() { return new FilteredCommunitiesModel(this, this); } signals: @@ -153,6 +155,7 @@ private: QStringList tags_; QString currentTagId_; QStringList hiddenTagIds_; + QStringList mutedTagIds_; FlatTree spaceOrder_; std::map spaces_; std::vector directMessages_; -- cgit 1.5.1 From f76fd4ca837ab7dcf17d7889cc555b20e5b9d654 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 15 Jul 2022 16:19:06 +0200 Subject: WIP --- src/timeline/CommunitiesModel.cpp | 142 ++++++++++++++++++++++++-------------- src/timeline/CommunitiesModel.h | 12 +++- src/timeline/TimelineModel.cpp | 24 ++----- src/timeline/TimelineModel.h | 3 +- 4 files changed, 107 insertions(+), 74 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 91f7d555..0d47c64d 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -18,15 +18,7 @@ CommunitiesModel::CommunitiesModel(QObject *parent) : QAbstractListModel(parent) , hiddenTagIds_{UserSettings::instance()->hiddenTags()} , mutedTagIds_{UserSettings::instance()->mutedTags()} -{ - connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { - // Simply updating every space is easier than tracking which ones need updated. - if (!spaces_.empty()) - emit dataChanged(index(0, 0), - index(spaces_.size() + tags_.size() + 1, 0), - {Roles::UnreadMessages, Roles::HasLoudNotification}); - }); -} +{} QHash CommunitiesModel::roleNames() const @@ -92,17 +84,10 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return ""; - case CommunitiesModel::Roles::UnreadMessages: { - int total{0}; - for (const auto &[id, info] : cache::getRoomInfo(cache::joinedRooms())) - total += info.notification_count; - return total; - } + case CommunitiesModel::Roles::UnreadMessages: + return (int)globalUnreads.notification_count; case CommunitiesModel::Roles::HasLoudNotification: - for (const auto &[id, info] : cache::getRoomInfo(cache::joinedRooms())) - if (info.highlight_count > 0) - return true; - return false; + return globalUnreads.highlight_count > 0; } } else if (index.row() == 1) { switch (role) { @@ -124,17 +109,10 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return "dm"; - case CommunitiesModel::Roles::UnreadMessages: { - int total{0}; - for (const auto &[id, info] : cache::getRoomInfo(directMessages_)) - total += info.notification_count; - return total; - } + case CommunitiesModel::Roles::UnreadMessages: + return (int)dmUnreads.notification_count; case CommunitiesModel::Roles::HasLoudNotification: - for (const auto &[id, info] : cache::getRoomInfo(directMessages_)) - if (info.highlight_count > 0) - return true; - return false; + return dmUnreads.highlight_count > 0; } } else if (index.row() - 2 < spaceOrder_.size()) { auto id = spaceOrder_.tree.at(index.row() - 2).id; @@ -162,10 +140,20 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return spaceOrder_.tree.at(index.row() - 2).depth; case CommunitiesModel::Roles::Id: return "space:" + id; - case CommunitiesModel::Roles::UnreadMessages: - return utils::getChildNotificationsForSpace(id).first; - case CommunitiesModel::Roles::HasLoudNotification: - return utils::getChildNotificationsForSpace(id).second > 0; + case CommunitiesModel::Roles::UnreadMessages: { + int count = 0; + auto end = spaceOrder_.lastChild(index.row() - 2); + for (int i = index.row() - 2; i <= end; i++) + count += spaceOrder_.tree[i].notificationCounts.notification_count; + return count; + } + case CommunitiesModel::Roles::HasLoudNotification: { + auto end = spaceOrder_.lastChild(index.row() - 2); + for (int i = index.row() - 2; i <= end; i++) + if (spaceOrder_.tree[i].notificationCounts.highlight_count > 0) + return true; + return false; + } } } else if (index.row() - 2 < tags_.size() + spaceOrder_.size()) { auto tag = tags_.at(index.row() - 2 - spaceOrder_.size()); @@ -219,24 +207,10 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return 0; case CommunitiesModel::Roles::Id: return "tag:" + tag; - case CommunitiesModel::Roles::UnreadMessages: { - int total{0}; - auto rooms{cache::joinedRooms()}; - for (const auto &[roomid, info] : cache::getRoomInfo(rooms)) - if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != - std::end(info.tags)) - total += info.notification_count; - return total; - } - case CommunitiesModel::Roles::HasLoudNotification: { - auto rooms{cache::joinedRooms()}; - for (const auto &[roomid, info] : cache::getRoomInfo(rooms)) - if (std::find(std::begin(info.tags), std::end(info.tags), tag.toStdString()) != - std::end(info.tags)) - if (info.highlight_count > 0) - return true; - return false; - } + case CommunitiesModel::Roles::UnreadMessages: + return (int)tagNotificationCache.at(tag).notification_count; + case CommunitiesModel::Roles::HasLoudNotification: + return (int)tagNotificationCache.at(tag).highlight_count > 0; } } return QVariant(); @@ -438,6 +412,72 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) e)) { tagsUpdated = true; } + + auto roomId = QString::fromStdString(roomid); + auto oldUnreads = roomNotificationCache[roomId]; + int notificationCDiff = -static_cast(oldUnreads.highlight_count) + + static_cast(room.unread_notifications.highlight_count); + int highlightCDiff = -static_cast(oldUnreads.highlight_count) + + static_cast(room.unread_notifications.highlight_count); + if (highlightCDiff || notificationCDiff) { + // bool hidden = hiddenTagIds_.contains(roomId); + globalUnreads.notification_count += notificationCDiff; + globalUnreads.highlight_count += highlightCDiff; + emit dataChanged(index(0), + index(0), + { + UnreadMessages, + HasLoudNotification, + }); + if (std::find(begin(directMessages_), end(directMessages_), roomid) != + end(directMessages_)) { + dmUnreads.notification_count += notificationCDiff; + dmUnreads.highlight_count += highlightCDiff; + emit dataChanged(index(1), + index(1), + { + UnreadMessages, + HasLoudNotification, + }); + } + + auto spaces = cache::client()->getParentRoomIds(roomid); + auto tags = cache::singleRoomInfo(roomid).tags; + + for (const auto &t : tags) { + auto tagId = QString::fromStdString(t); + auto &tNs = tagNotificationCache[tagId]; + tNs.notification_count += notificationCDiff; + tNs.highlight_count += highlightCDiff; + int idx = tags_.indexOf(tagId) + 2 + spaceOrder_.size(); + ; + emit dataChanged(index(idx), + index(idx), + { + UnreadMessages, + HasLoudNotification, + }); + } + + for (const auto &s : spaces) { + auto spaceId = QString::fromStdString(s); + + for (int i = 0; i < spaceOrder_.size(); i++) { + spaceOrder_.tree[i].notificationCounts.notification_count += notificationCDiff; + spaceOrder_.tree[i].notificationCounts.highlight_count += highlightCDiff; + + int idx = i; + do { + emit dataChanged(index(idx + 2), + index(idx + 2), + { + UnreadMessages, + HasLoudNotification, + }); + } while (idx != -1); + } + } + } } for (const auto &[roomid, room] : sync_.rooms.leave) { (void)room; diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index 5a659751..08269e21 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -22,7 +22,7 @@ class FilteredCommunitiesModel : public QSortFilterProxyModel Q_OBJECT public: - FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent = nullptr); + explicit FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent = nullptr); bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; bool filterAcceptsRow(int sourceRow, const QModelIndex &) const override; }; @@ -59,7 +59,10 @@ public: struct Elem { QString id; - int depth = 0; + int depth = 0; + + mtx::responses::UnreadNotifications notificationCounts = {0, 0}; + bool collapsed = false; }; @@ -160,5 +163,10 @@ private: std::map spaces_; std::vector directMessages_; + std::unordered_map roomNotificationCache; + std::unordered_map tagNotificationCache; + mtx::responses::UnreadNotifications globalUnreads{}; + mtx::responses::UnreadNotifications dmUnreads{}; + friend class FilteredCommunitiesModel; }; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index db56ac52..9b48a878 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -364,25 +364,11 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj { this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString()); - auto roomInfo = cache::singleRoomInfo(room_id_.toStdString()); - this->isSpace_ = roomInfo.is_space; - this->notification_count = - isSpace_ ? utils::getChildNotificationsForSpace(room_id_).first : roomInfo.notification_count; - this->highlight_count = - isSpace_ ? utils::getChildNotificationsForSpace(room_id_).second : roomInfo.highlight_count; - lastMessage_.timestamp = roomInfo.approximate_last_modification_ts; - - // this connection will simplify adding the plainRoomNameChanged() signal everywhere that it - // needs to be - connect(this, &TimelineModel::roomNameChanged, this, &TimelineModel::plainRoomNameChanged); - - if (isSpace_) - connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) { - auto temp{utils::getChildNotificationsForSpace(room_id_)}; - notification_count = temp.first; - highlight_count = temp.second; - emit notificationsChanged(); - }); + auto roomInfo = cache::singleRoomInfo(room_id_.toStdString()); + this->isSpace_ = roomInfo.is_space; + this->notification_count = roomInfo.notification_count; + this->highlight_count = roomInfo.highlight_count; + lastMessage_.timestamp = roomInfo.approximate_last_modification_ts; connect( this, diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 6d424981..47fd27f1 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -182,7 +182,7 @@ class TimelineModel : public QAbstractListModel bool paginationInProgress READ paginationInProgress NOTIFY paginationInProgressChanged) Q_PROPERTY(QString roomId READ roomId CONSTANT) Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) - Q_PROPERTY(QString plainRoomName READ plainRoomName NOTIFY plainRoomNameChanged) + Q_PROPERTY(QString plainRoomName READ plainRoomName NOTIFY roomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) Q_PROPERTY(QStringList pinnedMessages READ pinnedMessages NOTIFY pinnedMessagesChanged) @@ -429,7 +429,6 @@ signals: void encryptionChanged(); void trustlevelChanged(); void roomNameChanged(); - void plainRoomNameChanged(); void roomTopicChanged(); void pinnedMessagesChanged(); void widgetLinksChanged(); -- cgit 1.5.1 From 7b33d14277c3a3ca3db9bf1415c1a7372645b8e1 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 16 Jul 2022 03:07:00 +0200 Subject: Make notification count calculation more efficient --- resources/qml/CommunitiesList.qml | 60 ++++++++++++---------------- src/Utils.cpp | 18 --------- src/Utils.h | 5 --- src/timeline/CommunitiesModel.cpp | 84 ++++++++++++++++++++++++++++++--------- src/timeline/RoomlistModel.cpp | 17 ++++---- src/timeline/RoomlistModel.h | 8 +--- 6 files changed, 103 insertions(+), 89 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/resources/qml/CommunitiesList.qml b/resources/qml/CommunitiesList.qml index ec9ef940..ca63bffd 100644 --- a/resources/qml/CommunitiesList.qml +++ b/resources/qml/CommunitiesList.qml @@ -71,30 +71,20 @@ Page { property color unimportantText: Nheko.colors.buttonText property color bubbleBackground: Nheko.colors.highlight property color bubbleText: Nheko.colors.highlightedText - required property string avatarUrl - required property string displayName - required property string tooltip - required property bool collapsed - required property bool collapsible - required property bool hidden - required property int depth - required property string id - required property int unreadMessages - required property bool hasLoudNotification - required property bool muted + required property var model height: avatarSize + 2 * Nheko.paddingMedium width: ListView.view.width state: "normal" ToolTip.visible: hovered && collapsed - ToolTip.text: communityItem.tooltip + ToolTip.text: model.tooltip ToolTip.delay: Nheko.tooltipDelay - onClicked: Communities.setCurrentTagId(communityItem.id) - onPressAndHold: communityContextMenu.show(communityItem.id, communityItem.hidden, communityItem.muted) + onClicked: Communities.setCurrentTagId(model.id) + onPressAndHold: communityContextMenu.show(model.id, model.hidden, model.muted) states: [ State { name: "highlight" - when: (communityItem.hovered || communityItem.hidden) && !(Communities.currentTagId === communityItem.id) + when: (communityItem.hovered || model.hidden) && !(Communities.currentTagId === model.id) PropertyChanges { target: communityItem @@ -108,7 +98,7 @@ Page { }, State { name: "selected" - when: Communities.currentTagId == communityItem.id + when: Communities.currentTagId == model.id PropertyChanges { target: communityItem @@ -127,7 +117,7 @@ Page { TapHandler { acceptedButtons: Qt.RightButton - onSingleTapped: communityContextMenu.show(communityItem.id, communityItem.hidden, communityItem.muted) + onSingleTapped: communityContextMenu.show(model.id, model.hidden, model.muted) gesturePolicy: TapHandler.ReleaseWithinBounds acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus | PointerDevice.TouchPad } @@ -139,27 +129,27 @@ Page { spacing: Nheko.paddingMedium anchors.fill: parent anchors.margins: Nheko.paddingMedium - anchors.leftMargin: Nheko.paddingMedium + (communitySidebar.collapsed ? 0 : (fontMetrics.lineSpacing * communityItem.depth)) + anchors.leftMargin: Nheko.paddingMedium + (communitySidebar.collapsed ? 0 : (fontMetrics.lineSpacing * model.depth)) ImageButton { - visible: !communitySidebar.collapsed && communityItem.collapsible + visible: !communitySidebar.collapsed && model.collapsible Layout.preferredHeight: fontMetrics.lineSpacing Layout.preferredWidth: fontMetrics.lineSpacing Layout.alignment: Qt.AlignVCenter height: fontMetrics.lineSpacing width: fontMetrics.lineSpacing - image: communityItem.collapsed ? ":/icons/icons/ui/collapsed.svg" : ":/icons/icons/ui/expanded.svg" + image: model.collapsed ? ":/icons/icons/ui/collapsed.svg" : ":/icons/icons/ui/expanded.svg" ToolTip.visible: hovered ToolTip.delay: Nheko.tooltipDelay - ToolTip.text: communityItem.collapsed ? qsTr("Expand") : qsTr("Collapse") + ToolTip.text: model.collapsed ? qsTr("Expand") : qsTr("Collapse") hoverEnabled: true - onClicked: communityItem.collapsed = !communityItem.collapsed + onClicked: model.collapsed = !model.collapsed } Item { Layout.preferredWidth: fontMetrics.lineSpacing - visible: !communitySidebar.collapsed && !communityItem.collapsible && Communities.containsSubspaces + visible: !communitySidebar.collapsed && !model.collapsible && Communities.containsSubspaces } Avatar { @@ -170,22 +160,22 @@ Page { height: avatarSize width: avatarSize url: { - if (communityItem.avatarUrl.startsWith("mxc://")) - return communityItem.avatarUrl.replace("mxc://", "image://MxcImage/"); + if (model.avatarUrl.startsWith("mxc://")) + return model.avatarUrl.replace("mxc://", "image://MxcImage/"); else - return "image://colorimage/" + communityItem.avatarUrl + "?" + communityItem.unimportantText; + return "image://colorimage/" + model.avatarUrl + "?" + communityItem.unimportantText; } - roomid: communityItem.id - displayName: communityItem.displayName + roomid: model.id + displayName: model.displayName color: communityItem.backgroundColor NotificationBubble { - notificationCount: communityItem.unreadMessages - hasLoudNotification: communityItem.hasLoudNotification + notificationCount: model.unreadMessages + hasLoudNotification: model.hasLoudNotification bubbleBackgroundColor: communityItem.bubbleBackground bubbleTextColor: communityItem.bubbleText font.pixelSize: fontMetrics.font.pixelSize * 0.6 - mayBeVisible: communitySidebar.collapsed && !communityItem.muted && Settings.spaceNotifications + mayBeVisible: communitySidebar.collapsed && !model.muted && Settings.spaceNotifications anchors.right: avatar.right anchors.bottom: avatar.bottom anchors.margins: -Nheko.paddingSmall @@ -199,7 +189,7 @@ Page { color: communityItem.importantText Layout.fillWidth: true elideWidth: width - fullText: communityItem.displayName + fullText: model.displayName textFormat: Text.PlainText } @@ -208,11 +198,11 @@ Page { } NotificationBubble { - notificationCount: communityItem.unreadMessages - hasLoudNotification: communityItem.hasLoudNotification + notificationCount: model.unreadMessages + hasLoudNotification: model.hasLoudNotification bubbleBackgroundColor: communityItem.bubbleBackground bubbleTextColor: communityItem.bubbleText - mayBeVisible: !communitySidebar.collapsed && !communityItem.muted && Settings.spaceNotifications + mayBeVisible: !communitySidebar.collapsed && !model.muted && Settings.spaceNotifications Layout.alignment: Qt.AlignRight Layout.leftMargin: Nheko.paddingSmall } diff --git a/src/Utils.cpp b/src/Utils.cpp index 3a90bd50..d98669e0 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -881,21 +881,3 @@ utils::markRoomAsDirect(QString roomid, std::vector members) }); }); } - -QPair -utils::getChildNotificationsForSpace(const QString &spaceId) -{ - auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(spaceId.toStdString())); - QPair retVal; - for (const auto &[childId, child] : children) { - if (child.is_space) { - auto temp{utils::getChildNotificationsForSpace(childId)}; - retVal.first += temp.first; - retVal.second += temp.second; - } else { - retVal.first += child.notification_count; - retVal.second += child.highlight_count; - } - } - return retVal; -} diff --git a/src/Utils.h b/src/Utils.h index bdd56d55..0b6034ac 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -311,9 +311,4 @@ removeDirectFromRoom(QString roomid); void markRoomAsDirect(QString roomid, std::vector members); - -//! Returns a pair of integers representing the unread notifications in a space and how many of them -//! are loud notifications, respectively. -QPair -getChildNotificationsForSpace(const QString &spaceId); } diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 0d47c64d..c75f4265 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -208,9 +208,15 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Id: return "tag:" + tag; case CommunitiesModel::Roles::UnreadMessages: - return (int)tagNotificationCache.at(tag).notification_count; + if (auto it = tagNotificationCache.find(tag); it != tagNotificationCache.end()) + return (int)it->second.notification_count; + else + return 0; case CommunitiesModel::Roles::HasLoudNotification: - return (int)tagNotificationCache.at(tag).highlight_count > 0; + if (auto it = tagNotificationCache.find(tag); it != tagNotificationCache.end()) + return it->second.highlight_count > 0; + else + return 0; } } return QVariant(); @@ -265,6 +271,21 @@ CommunitiesModel::initializeSidebar() tags_.clear(); spaceOrder_.tree.clear(); spaces_.clear(); + tagNotificationCache.clear(); + globalUnreads.notification_count = {}; + dmUnreads.notification_count = {}; + + auto e = cache::client()->getAccountData(mtx::events::EventType::Direct); + if (e) { + if (auto event = + std::get_if>( + &e.value())) { + directMessages_.clear(); + for (const auto &[userId, roomIds] : event->content.user_to_rooms) + for (const auto &roomId : roomIds) + directMessages_.push_back(roomId); + } + } std::set ts; @@ -284,6 +305,19 @@ CommunitiesModel::initializeSidebar() } } } + + for (const auto &t : it->tags) { + auto tagId = QString::fromStdString(t); + auto &tNs = tagNotificationCache[tagId]; + tNs.notification_count += it->notification_count; + tNs.highlight_count += it->highlight_count; + } + + auto &e = roomNotificationCache[it.key()]; + e.highlight_count = it->highlight_count; + e.notification_count = it->notification_count; + globalUnreads.notification_count += it->notification_count; + globalUnreads.highlight_count += it->highlight_count; } // NOTE(Nico): We build a forrest from the Directed Cyclic(!) Graph of spaces. To do that we @@ -319,6 +353,14 @@ CommunitiesModel::initializeSidebar() spaceOrder_.restoreCollapsed(); + for (auto &space : spaceOrder_.tree) { + for (const auto &c : cache::client()->getChildRoomIds(space.id.toStdString())) { + const auto &counts = roomNotificationCache[QString::fromStdString(c)]; + space.notificationCounts.highlight_count += counts.highlight_count; + space.notificationCounts.notification_count += counts.notification_count; + } + } + endResetModel(); emit tagsChanged(); @@ -413,16 +455,21 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) tagsUpdated = true; } - auto roomId = QString::fromStdString(roomid); - auto oldUnreads = roomNotificationCache[roomId]; - int notificationCDiff = -static_cast(oldUnreads.highlight_count) + - static_cast(room.unread_notifications.highlight_count); - int highlightCDiff = -static_cast(oldUnreads.highlight_count) + - static_cast(room.unread_notifications.highlight_count); + auto roomId = QString::fromStdString(roomid); + auto &oldUnreads = roomNotificationCache[roomId]; + auto notificationCDiff = -static_cast(oldUnreads.notification_count) + + static_cast(room.unread_notifications.notification_count); + auto highlightCDiff = -static_cast(oldUnreads.highlight_count) + + static_cast(room.unread_notifications.highlight_count); + + auto applyDiff = [notificationCDiff, + highlightCDiff](mtx::responses::UnreadNotifications &n) { + n.highlight_count = static_cast(n.highlight_count) + highlightCDiff; + n.notification_count = static_cast(n.notification_count) + notificationCDiff; + }; if (highlightCDiff || notificationCDiff) { // bool hidden = hiddenTagIds_.contains(roomId); - globalUnreads.notification_count += notificationCDiff; - globalUnreads.highlight_count += highlightCDiff; + applyDiff(globalUnreads); emit dataChanged(index(0), index(0), { @@ -431,8 +478,7 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) }); if (std::find(begin(directMessages_), end(directMessages_), roomid) != end(directMessages_)) { - dmUnreads.notification_count += notificationCDiff; - dmUnreads.highlight_count += highlightCDiff; + applyDiff(dmUnreads); emit dataChanged(index(1), index(1), { @@ -446,11 +492,8 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) for (const auto &t : tags) { auto tagId = QString::fromStdString(t); - auto &tNs = tagNotificationCache[tagId]; - tNs.notification_count += notificationCDiff; - tNs.highlight_count += highlightCDiff; + applyDiff(tagNotificationCache[tagId]); int idx = tags_.indexOf(tagId) + 2 + spaceOrder_.size(); - ; emit dataChanged(index(idx), index(idx), { @@ -463,8 +506,10 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) auto spaceId = QString::fromStdString(s); for (int i = 0; i < spaceOrder_.size(); i++) { - spaceOrder_.tree[i].notificationCounts.notification_count += notificationCDiff; - spaceOrder_.tree[i].notificationCounts.highlight_count += highlightCDiff; + if (spaceOrder_.tree[i].id != spaceId) + continue; + + applyDiff(spaceOrder_.tree[i].notificationCounts); int idx = i; do { @@ -474,10 +519,13 @@ CommunitiesModel::sync(const mtx::responses::Sync &sync_) UnreadMessages, HasLoudNotification, }); + idx = spaceOrder_.parent(idx); } while (idx != -1); } } } + + roomNotificationCache[roomId] = room.unread_notifications; } for (const auto &[roomid, room] : sync_.rooms.leave) { (void)room; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 3b46c053..1869d2e0 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -642,15 +642,18 @@ RoomlistModel::clear() } void -RoomlistModel::joinPreview(QString roomid, QString parentSpace) +RoomlistModel::joinPreview(QString roomid) { if (previewedRooms.contains(roomid)) { - auto child = cache::client()->getStateEvent( - parentSpace.toStdString(), roomid.toStdString()); - ChatPage::instance()->joinRoomVia( - roomid.toStdString(), - (child && child->content.via) ? child->content.via.value() : std::vector{}, - false); + std::vector vias; + auto parents = cache::client()->getParentRoomIds(roomid.toStdString()); + for (const auto &p : parents) { + auto child = cache::client()->getStateEvent( + p, roomid.toStdString()); + if (child && child->content.via) + vias.insert(vias.end(), child->content.via->begin(), child->content.via->end()); + } + ChatPage::instance()->joinRoomVia(roomid.toStdString(), vias, false); } } void diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index cf2b45d8..61bf2e7c 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -105,7 +105,7 @@ public slots: return -1; } - void joinPreview(QString roomid, QString parentSpace); + void joinPreview(QString roomid); void acceptInvite(QString roomid); void declineInvite(QString roomid); void leave(QString roomid, QString reason = ""); @@ -169,11 +169,7 @@ public slots: { return mapFromSource(roomlistmodel->index(roomlistmodel->roomidToIndex(roomid))).row(); } - void joinPreview(QString roomid) - { - roomlistmodel->joinPreview(roomid, - filterType == FilterBy::Space ? filterStr : QLatin1String("")); - } + void joinPreview(QString roomid) { roomlistmodel->joinPreview(roomid); } void acceptInvite(QString roomid) { roomlistmodel->acceptInvite(roomid); } void declineInvite(QString roomid) { roomlistmodel->declineInvite(roomid); } void leave(QString roomid, QString reason = "") { roomlistmodel->leave(roomid, reason); } -- cgit 1.5.1