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 <cmark.h>
#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<RoomMember> 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<RoomMember> 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,
|