From 0a405a7446892dac2a71be7edf4f700ecae25db9 Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@ymail.com>
Date: Wed, 13 Apr 2022 20:40:00 +0200
Subject: [PATCH] Store notification counts across restarts

---
 src/Cache.cpp                  | 23 ++++++++++++++++-------
 src/CacheStructs.h             |  3 +++
 src/timeline/TimelineModel.cpp |  8 +++++---
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/src/Cache.cpp b/src/Cache.cpp
index f4a014c1c..f3ad4fc54 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -1543,18 +1543,12 @@ Cache::updateState(const std::string &room, const mtx::responses::StateEvents &s
     saveStateEvents(txn, statesdb, stateskeydb, membersdb, eventsDb, room, state.events);
 
     RoomInfo updatedInfo;
-    updatedInfo.name       = getRoomName(txn, statesdb, membersdb).toStdString();
-    updatedInfo.topic      = getRoomTopic(txn, statesdb).toStdString();
-    updatedInfo.avatar_url = getRoomAvatarUrl(txn, statesdb, membersdb).toStdString();
-    updatedInfo.version    = getRoomVersion(txn, statesdb).toStdString();
-    updatedInfo.is_space   = getRoomIsSpace(txn, statesdb);
 
     {
         std::string_view data;
         if (roomsDb_.get(txn, room, data)) {
             try {
-                RoomInfo tmp     = json::parse(std::string_view(data.data(), data.size()));
-                updatedInfo.tags = tmp.tags;
+                RoomInfo updatedInfo = json::parse(std::string_view(data.data(), data.size()));
             } catch (const json::exception &e) {
                 nhlog::db()->warn("failed to parse room info: room_id ({}), {}: {}",
                                   room,
@@ -1564,6 +1558,12 @@ Cache::updateState(const std::string &room, const mtx::responses::StateEvents &s
         }
     }
 
+    updatedInfo.name       = getRoomName(txn, statesdb, membersdb).toStdString();
+    updatedInfo.topic      = getRoomTopic(txn, statesdb).toStdString();
+    updatedInfo.avatar_url = getRoomAvatarUrl(txn, statesdb, membersdb).toStdString();
+    updatedInfo.version    = getRoomVersion(txn, statesdb).toStdString();
+    updatedInfo.is_space   = getRoomIsSpace(txn, statesdb);
+
     roomsDb_.put(txn, room, json(updatedInfo).dump());
     updateSpaces(txn, {room}, {room});
     txn.commit();
@@ -1628,6 +1628,9 @@ Cache::saveState(const mtx::responses::Sync &res)
         updatedInfo.version    = getRoomVersion(txn, statesdb).toStdString();
         updatedInfo.is_space   = getRoomIsSpace(txn, statesdb);
 
+        updatedInfo.notification_count = room.second.unread_notifications.notification_count;
+        updatedInfo.highlight_count    = room.second.unread_notifications.highlight_count;
+
         if (updatedInfo.is_space) {
             bool space_updates = false;
             for (const auto &e : room.second.state.events)
@@ -4693,6 +4696,9 @@ to_json(json &j, const RoomInfo &info)
     j["join_rule"]    = info.join_rule;
     j["guest_access"] = info.guest_access;
 
+    j["notification_count"] = info.notification_count;
+    j["highlight_count"]    = info.highlight_count;
+
     if (info.member_count != 0)
         j["member_count"] = info.member_count;
 
@@ -4713,6 +4719,9 @@ from_json(const json &j, RoomInfo &info)
     info.join_rule    = j.at("join_rule");
     info.guest_access = j.at("guest_access");
 
+    info.notification_count = j.value("notification_count", 0);
+    info.highlight_count    = j.value("highlight_count", 0);
+
     if (j.count("member_count"))
         info.member_count = j.at("member_count");
 
diff --git a/src/CacheStructs.h b/src/CacheStructs.h
index a208fcf8d..b39170582 100644
--- a/src/CacheStructs.h
+++ b/src/CacheStructs.h
@@ -88,6 +88,9 @@ struct RoomInfo
     bool guest_access                      = false;
     //! The list of tags associated with this room
     std::vector<std::string> tags;
+
+    uint16_t highlight_count    = 0;
+    uint16_t notification_count = 0;
 };
 
 void
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index e80cc659b..8d7b7919f 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -349,11 +349,13 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
 {
     lastMessage_.timestamp = 0;
 
-    if (auto create =
-          cache::client()->getStateEvent<mtx::events::state::Create>(room_id_.toStdString()))
-        this->isSpace_ = create->content.type == mtx::events::state::room_type::space;
     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;
+
     // this connection will simplify adding the plainRoomNameChanged() signal everywhere that it
     // needs to be
     connect(this, &TimelineModel::roomNameChanged, this, &TimelineModel::plainRoomNameChanged);
-- 
GitLab