summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2022-07-16 03:07:00 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2022-07-16 03:07:00 +0200
commit7b33d14277c3a3ca3db9bf1415c1a7372645b8e1 (patch)
tree489e39931b4db902bcbd862eac8e88745469cd6f /src
parentWIP (diff)
downloadnheko-7b33d14277c3a3ca3db9bf1415c1a7372645b8e1.tar.xz
Make notification count calculation more efficient
Diffstat (limited to 'src')
-rw-r--r--src/Utils.cpp18
-rw-r--r--src/Utils.h5
-rw-r--r--src/timeline/CommunitiesModel.cpp84
-rw-r--r--src/timeline/RoomlistModel.cpp17
-rw-r--r--src/timeline/RoomlistModel.h8
5 files changed, 78 insertions, 54 deletions
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<RoomMember> members) }); }); } - -QPair<int, int> -utils::getChildNotificationsForSpace(const QString &spaceId) -{ - auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(spaceId.toStdString())); - QPair<int, int> 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<RoomMember> members); - -//! Returns a pair of integers representing the unread notifications in a space and how many of them -//! are loud notifications, respectively. -QPair<int, int> -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<mtx::events::AccountDataEvent<mtx::events::account_data::Direct>>( + &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<std::string> 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<int64_t>(oldUnreads.highlight_count) + - static_cast<int64_t>(room.unread_notifications.highlight_count); - int highlightCDiff = -static_cast<int64_t>(oldUnreads.highlight_count) + - static_cast<int64_t>(room.unread_notifications.highlight_count); + auto roomId = QString::fromStdString(roomid); + auto &oldUnreads = roomNotificationCache[roomId]; + auto notificationCDiff = -static_cast<int64_t>(oldUnreads.notification_count) + + static_cast<int64_t>(room.unread_notifications.notification_count); + auto highlightCDiff = -static_cast<int64_t>(oldUnreads.highlight_count) + + static_cast<int64_t>(room.unread_notifications.highlight_count); + + auto applyDiff = [notificationCDiff, + highlightCDiff](mtx::responses::UnreadNotifications &n) { + n.highlight_count = static_cast<int64_t>(n.highlight_count) + highlightCDiff; + n.notification_count = static_cast<int64_t>(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<mtx::events::state::space::Child>( - parentSpace.toStdString(), roomid.toStdString()); - ChatPage::instance()->joinRoomVia( - roomid.toStdString(), - (child && child->content.via) ? child->content.via.value() : std::vector<std::string>{}, - false); + std::vector<std::string> vias; + auto parents = cache::client()->getParentRoomIds(roomid.toStdString()); + for (const auto &p : parents) { + auto child = cache::client()->getStateEvent<mtx::events::state::space::Child>( + 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); }