From f316dbed439c2dea2c570d6cab1f694f6df6df6f Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@ymail.com>
Date: Fri, 8 Apr 2022 03:24:10 +0200
Subject: [PATCH] Fix a few issues with receiving to_device messages in initial
 sync

---
 CMakeLists.txt                   |  2 +-
 io.github.NhekoReborn.Nheko.yaml |  2 +-
 src/Cache.cpp                    | 20 ++++++++++++++------
 src/Cache_p.h                    |  1 +
 src/ChatPage.cpp                 | 31 ++++++++++++++++---------------
 5 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1bd5e81a0..a4b72e989 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -401,7 +401,7 @@ if(USE_BUNDLED_MTXCLIENT)
 	FetchContent_Declare(
 		MatrixClient
 		GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
-		GIT_TAG        888601932b876c9a8bb8e1f3b198ce1a5f1252fa
+		GIT_TAG        c5e8def06f0fc64aa150f30d5c9c366e876120e1
 		)
 	set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
 	set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
diff --git a/io.github.NhekoReborn.Nheko.yaml b/io.github.NhekoReborn.Nheko.yaml
index 69a4f6d66..78096ef3e 100644
--- a/io.github.NhekoReborn.Nheko.yaml
+++ b/io.github.NhekoReborn.Nheko.yaml
@@ -176,7 +176,7 @@ modules:
     buildsystem: cmake-ninja
     name: mtxclient
     sources:
-      - commit: 888601932b876c9a8bb8e1f3b198ce1a5f1252fa
+      - commit: c5e8def06f0fc64aa150f30d5c9c366e876120e1
         #tag: v0.7.0
         type: git
         url: https://github.com/Nheko-Reborn/mtxclient.git
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 6493d047e..ff8c7651c 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -1574,7 +1574,7 @@ Cache::saveState(const mtx::responses::Sync &res)
     using namespace mtx::events;
     auto local_user_id = this->localUserId_.toStdString();
 
-    auto currentBatchToken = nextBatchToken();
+    auto currentBatchToken = res.next_batch;
 
     auto txn = lmdb::txn::begin(env_);
 
@@ -3942,8 +3942,15 @@ Cache::roomVerificationStatus(const std::string &room_id)
                 trust = crypto::TOFU;
         }
 
-        if (!keysToRequest.empty())
-            markUserKeysOutOfDate(txn, keysDb, keysToRequest, "");
+        if (!keysToRequest.empty()) {
+            std::string_view token;
+
+            bool result = syncStateDb_.get(txn, NEXT_BATCH_KEY, token);
+
+            if (!result)
+                token = "";
+            markUserKeysOutOfDate(txn, keysDb, keysToRequest, std::string(token));
+        }
 
     } catch (std::exception &e) {
         nhlog::db()->error("Failed to calculate verification status for {}: {}", room_id, e.what());
@@ -4123,11 +4130,11 @@ Cache::userKeys_(const std::string &user_id, lmdb::txn &txn)
         if (res) {
             return json::parse(keys).get<UserKeyCache>();
         } else {
-            return {};
+            return std::nullopt;
         }
     } catch (std::exception &e) {
         nhlog::db()->error("Failed to retrieve user keys for {}: {}", user_id, e.what());
-        return {};
+        return std::nullopt;
     }
 }
 
@@ -4365,7 +4372,7 @@ Cache::query_keys(const std::string &user_id,
     QObject *context{new QObject(this)};
     QObject::connect(
       this,
-      &Cache::verificationStatusChanged,
+      &Cache::userKeysUpdateFinalize,
       context,
       [cb, user_id, context_ = context, this](std::string updated_user) mutable {
           if (user_id == updated_user) {
@@ -4390,6 +4397,7 @@ Cache::query_keys(const std::string &user_id,
           }
 
           emit userKeysUpdate(last_changed, res);
+          emit userKeysUpdateFinalize(user_id);
       });
 }
 
diff --git a/src/Cache_p.h b/src/Cache_p.h
index 472c8e4c9..67755575d 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -317,6 +317,7 @@ signals:
     void roomReadStatus(const std::map<QString, bool> &status);
     void removeNotification(const QString &room_id, const QString &event_id);
     void userKeysUpdate(const std::string &sync_token, const mtx::responses::QueryKeys &keyQuery);
+    void userKeysUpdateFinalize(const std::string &user_id);
     void verificationStatusChanged(const std::string &userid);
     void selfVerificationStatusChanged();
     void secretChanged(const std::string name);
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 43455e869..0550c7f31 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -560,25 +560,26 @@ ChatPage::startInitialSync()
             }
         }
 
-        nhlog::net()->info("initial sync completed");
-
-        try {
-            cache::client()->saveState(res);
+        QTimer::singleShot(0, this, [this, res] {
+            nhlog::net()->info("initial sync completed");
+            try {
+                cache::client()->saveState(res);
 
-            olm::handle_to_device_messages(res.to_device.events);
+                olm::handle_to_device_messages(res.to_device.events);
 
-            emit initializeViews(std::move(res));
-            emit initializeMentions(cache::getTimelineMentions());
+                emit initializeViews(std::move(res));
+                emit initializeMentions(cache::getTimelineMentions());
 
-            cache::calculateRoomReadStatus();
-        } catch (const lmdb::error &e) {
-            nhlog::db()->error("failed to save state after initial sync: {}", e.what());
-            startInitialSync();
-            return;
-        }
+                cache::calculateRoomReadStatus();
+            } catch (const lmdb::error &e) {
+                nhlog::db()->error("failed to save state after initial sync: {}", e.what());
+                startInitialSync();
+                return;
+            }
 
-        emit trySyncCb();
-        emit contentLoaded();
+            emit trySyncCb();
+            emit contentLoaded();
+        });
     });
 }
 
-- 
GitLab