From 692c6119b44ef0f034d45ec3c445eaf616db672a Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Mon, 4 May 2020 20:17:57 +0200
Subject: [PATCH] Fix joined rooms dropping to the bottom at first

---
 src/Cache.cpp                  | 27 ++++++++++++++++++++++-----
 src/ChatPage.cpp               |  4 ++--
 src/timeline/TimelineModel.cpp | 27 +++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/src/Cache.cpp b/src/Cache.cpp
index aca01c1ad..016ba3715 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -1314,16 +1314,33 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id)
 
         std::string timestamp, msg;
 
-        QSettings settings;
         const auto local_user = utils::localUser();
 
+        DescInfo fallbackDesc{};
+
         auto cursor = lmdb::cursor::open(txn, db);
         while (cursor.get(timestamp, msg, MDB_NEXT)) {
                 auto obj = json::parse(msg);
 
-                if (obj.count("event") == 0 || !(obj["event"]["type"] == "m.room.message" ||
-                                                 obj["event"]["type"] == "m.sticker" ||
-                                                 obj["event"]["type"] == "m.room.encrypted"))
+                if (obj.count("event") == 0)
+                        continue;
+
+                if (fallbackDesc.event_id.isEmpty() && obj["event"]["type"] == "m.room.member" &&
+                    obj["event"]["state_key"] == local_user.toStdString() &&
+                    obj["event"]["content"]["membership"] == "join") {
+                        uint64_t ts  = obj["event"]["origin_server_ts"];
+                        auto time    = QDateTime::fromMSecsSinceEpoch(ts);
+                        fallbackDesc = DescInfo{QString::fromStdString(obj["event"]["event_id"]),
+                                                local_user,
+                                                tr("You joined this room"),
+                                                utils::descriptiveTime(time),
+                                                ts,
+                                                time};
+                }
+
+                if (!(obj["event"]["type"] == "m.room.message" ||
+                      obj["event"]["type"] == "m.sticker" ||
+                      obj["event"]["type"] == "m.room.encrypted"))
                         continue;
 
                 mtx::events::collections::TimelineEvent event;
@@ -1335,7 +1352,7 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id)
         }
         cursor.close();
 
-        return DescInfo{};
+        return fallbackDesc;
 }
 
 std::map<QString, bool>
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 689e9ca4a..ae3c7a117 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -1009,13 +1009,13 @@ ChatPage::trySync()
                           cache::saveState(res);
                           olm::handle_to_device_messages(res.to_device);
 
-                          emit syncUI(res.rooms);
-
                           auto updates = cache::roomUpdates(res);
 
                           emit syncTopBar(updates);
                           emit syncRoomlist(updates);
 
+                          emit syncUI(res.rooms);
+
                           emit syncTags(cache::roomTagUpdates(res));
 
                           // if we process a lot of syncs (1 every 200ms), this means we clean the
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 340bae390..1c0abd175 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -518,6 +518,20 @@ isMessage(const mtx::events::EncryptedEvent<T> &)
         return true;
 }
 
+// Workaround. We also want to see a room at the top, if we just joined it
+auto
+isYourJoin(const mtx::events::StateEvent<mtx::events::state::Member> &e)
+{
+        return e.content.membership == mtx::events::state::Membership::Join &&
+               e.state_key == http::client()->user_id().to_string();
+}
+template<typename T>
+auto
+isYourJoin(const mtx::events::Event<T> &)
+{
+        return false;
+}
+
 void
 TimelineModel::updateLastMessage()
 {
@@ -530,6 +544,19 @@ TimelineModel::updateLastMessage()
                         }
                 }
 
+                if (std::visit([](const auto &e) -> bool { return isYourJoin(e); }, event)) {
+                        auto time   = mtx::accessors::origin_server_ts(event);
+                        uint64_t ts = time.toMSecsSinceEpoch();
+                        emit manager_->updateRoomsLastMessage(
+                          room_id_,
+                          DescInfo{QString::fromStdString(mtx::accessors::event_id(event)),
+                                   QString::fromStdString(http::client()->user_id().to_string()),
+                                   tr("You joined this room"),
+                                   utils::descriptiveTime(time),
+                                   ts,
+                                   time});
+                        return;
+                }
                 if (!std::visit([](const auto &e) -> bool { return isMessage(e); }, event))
                         continue;
 
-- 
GitLab