From 9f5b647fb38d1f362c557d707274597189942c48 Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Sun, 27 Feb 2022 05:02:54 +0100
Subject: [PATCH] Fix editing pending messages

---
 src/Cache.cpp               | 22 ++++++++++++++++++++++
 src/Cache_p.h               |  1 +
 src/timeline/EventStore.cpp | 18 ++++++++----------
 3 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/src/Cache.cpp b/src/Cache.cpp
index 6bad336a3..be3dfe697 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -2931,6 +2931,28 @@ Cache::savePendingMessage(const std::string &room_id,
 
     txn.commit();
 }
+std::vector<std::string>
+Cache::pendingEvents(const std::string &room_id)
+{
+    auto txn     = ro_txn(env_);
+    auto pending = getPendingMessagesDb(txn, room_id);
+
+    std::vector<std::string> related_ids;
+
+    try {
+        {
+            auto pendingCursor = lmdb::cursor::open(txn, pending);
+            std::string_view tsIgnored, pendingTxn;
+            while (pendingCursor.get(tsIgnored, pendingTxn, MDB_NEXT)) {
+                related_ids.emplace_back(pendingTxn.data(), pendingTxn.size());
+            }
+        }
+    } catch (const lmdb::error &e) {
+        nhlog::db()->error("pending events error: {}", e.what());
+    }
+
+    return related_ids;
+}
 
 std::optional<mtx::events::collections::TimelineEvent>
 Cache::firstPendingMessage(const std::string &room_id)
diff --git a/src/Cache_p.h b/src/Cache_p.h
index 8e5fa547b..472c8e4c9 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -218,6 +218,7 @@ public:
     uint64_t saveOldMessages(const std::string &room_id, const mtx::responses::Messages &res);
     void savePendingMessage(const std::string &room_id,
                             const mtx::events::collections::TimelineEvent &message);
+    std::vector<std::string> pendingEvents(const std::string &room_id);
     std::optional<mtx::events::collections::TimelineEvent>
     firstPendingMessage(const std::string &room_id);
     void removePendingStatus(const std::string &room_id, const std::string &txn_id);
diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index 8e244f422..f7d15b617 100644
--- a/src/timeline/EventStore.cpp
+++ b/src/timeline/EventStore.cpp
@@ -187,15 +187,13 @@ EventStore::EventStore(std::string room_id, QObject *)
 
           // FIXME (introduced by balsoft): this doesn't work for encrypted events, but
           // allegedly it's hard to fix so I'll leave my first contribution at that
-          for (const auto &related_event_id : cache::client()->relatedEvents(room_id_, txn_id)) {
-              if (cache::client()->getEvent(room_id_, related_event_id)) {
-                  auto related_event =
-                    cache::client()->getEvent(room_id_, related_event_id).value();
-                  auto relations = mtx::accessors::relations(related_event.data);
+          for (const auto &pending_event_id : cache::client()->pendingEvents(room_id_)) {
+              if (auto pending_event = cache::client()->getEvent(room_id_, pending_event_id)) {
+                  auto relations = mtx::accessors::relations(pending_event->data);
 
                   // Replace the blockquote in fallback reply
                   auto related_text = std::get_if<mtx::events::RoomEvent<mtx::events::msg::Text>>(
-                    &related_event.data);
+                    &pending_event->data);
                   if (related_text && relations.reply_to() == txn_id) {
                       size_t index = related_text->content.formatted_body.find(txn_id);
                       if (index != std::string::npos) {
@@ -209,13 +207,13 @@ EventStore::EventStore(std::string room_id, QObject *)
                           rel.event_id = event_id;
                   }
 
-                  mtx::accessors::set_relations(related_event.data, std::move(relations));
+                  mtx::accessors::set_relations(pending_event->data, std::move(relations));
 
-                  cache::client()->replaceEvent(room_id_, related_event_id, related_event);
+                  cache::client()->replaceEvent(room_id_, pending_event_id, *pending_event);
 
-                  auto idx = idToIndex(related_event_id);
+                  auto idx = idToIndex(pending_event_id);
 
-                  events_by_id_.remove({room_id_, related_event_id});
+                  events_by_id_.remove({room_id_, pending_event_id});
                   events_.remove({room_id_, toInternalIdx(*idx)});
               }
           }
-- 
GitLab