diff --git a/src/Cache.cpp b/src/Cache.cpp index cc8516ad..2be2ef02 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1815,7 +1815,7 @@ Cache::saveState(const mtx::responses::Sync &res) if (!std::visit([](const auto &e) -> bool { return isMessage(e); }, e)) continue; updatedInfo.approximate_last_modification_ts = - mtx::accessors::origin_server_ts(e).toMSecsSinceEpoch(); + std::visit([](const auto &e) -> bool { return e.origin_server_ts; }, e); } roomsDb_.put(txn, room.first, nlohmann::json(updatedInfo).dump()); @@ -2019,6 +2019,35 @@ Cache::singleRoomInfo(const std::string &room_id) return RoomInfo(); } +void +Cache::updateLastMessageTimestamp(const std::string &room_id, uint64_t ts) +{ + auto txn = lmdb::txn::begin(env_); + + try { + auto statesdb = getStatesDb(txn, room_id); + + std::string_view data; + + // Check if the room is joined. + if (roomsDb_.get(txn, room_id, data)) { + try { + RoomInfo tmp = nlohmann::json::parse(data).get(); + tmp.approximate_last_modification_ts = ts; + roomsDb_.put(txn, room_id, nlohmann::json(tmp).dump()); + txn.commit(); + return; + } catch (const nlohmann::json::exception &e) { + nhlog::db()->warn("failed to parse room info: room_id ({}), {}: {}", + room_id, + std::string(data.data(), data.size()), + e.what()); + } + } + } catch (const lmdb::error &e) { + nhlog::db()->warn("failed to read room info from db: room_id ({}), {}", room_id, e.what()); + } +} std::map Cache::getRoomInfo(const std::vector &rooms) @@ -4820,7 +4849,7 @@ from_json(const nlohmann::json &j, RoomInfo &info) info.join_rule = j.at("join_rule").get(); info.guest_access = j.at("guest_access").get(); - info.approximate_last_modification_ts = j.value("app_l_ts", 0); + info.approximate_last_modification_ts = j.value("app_l_ts", 0); info.notification_count = j.value("notification_count", 0); info.highlight_count = j.value("highlight_count", 0); diff --git a/src/Cache_p.h b/src/Cache_p.h index de123a95..cd42fa3e 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -165,6 +165,7 @@ public: RoomInfo singleRoomInfo(const std::string &room_id); std::vector roomsWithStateUpdates(const mtx::responses::Sync &res); std::map getRoomInfo(const std::vector &rooms); + void updateLastMessageTimestamp(const std::string &room_id, uint64_t ts); //! Calculates which the read status of a room. //! Whether all the events in the timeline have been read. diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index bb2644f3..1cf16243 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -298,6 +298,7 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) { Roles::HasLoudNotification, Roles::LastMessage, + Roles::Time, Roles::Timestamp, Roles::NotificationCount, Qt::DisplayRole, diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index c7c1bfc5..3fe4c07f 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1055,6 +1055,10 @@ TimelineModel::updateLastMessage() ts, time}; if (description != lastMessage_) { + if (lastMessage_.timestamp == 0) { + cache::client()->updateLastMessageTimestamp(room_id_.toStdString(), + description.timestamp); + } lastMessage_ = description; emit lastMessageChanged(); } @@ -1068,6 +1072,10 @@ TimelineModel::updateLastMessage() QString::fromStdString(http::client()->user_id().to_string()), cache::displayName(room_id_, QString::fromStdString(mtx::accessors::sender(*event)))); if (description != lastMessage_) { + if (lastMessage_.timestamp == 0) { + cache::client()->updateLastMessageTimestamp(room_id_.toStdString(), + description.timestamp); + } lastMessage_ = description; emit lastMessageChanged(); }