summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorAlexander Bantyev <balsoft@balsoft.ru>2021-06-17 22:27:37 +0300
committerAlexander Bantyev <balsoft@balsoft.ru>2021-06-18 16:38:55 +0300
commit9f798e76ede3672d91276b1be7dd20de5459c9df (patch)
treea17b1c2fbdc6248d9ce09682bfb5bafc898d0286 /src/timeline
parentTranslated using Weblate (Esperanto) (diff)
downloadnheko-9f798e76ede3672d91276b1be7dd20de5459c9df.tar.xz
Allow editing unsent messages
As of 0db4d71ec2483c7ac5a7b536737fee8fc53a76d7 (Prevent edits of
unsent messages), messages that are edits of (or replies to) unsent
messages were not allowed. This change was made because otherwise
the edits were discarded due to use of txnid rather than mxid in the
"m.relates_to" object. Remove this restriction and fix the issue by
replacing txnid with mxid in all related events when the message is
sent (and we obtain mxid from the server).
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/EventStore.cpp32
-rw-r--r--src/timeline/TimelineModel.cpp18
2 files changed, 43 insertions, 7 deletions
diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index 4a9f0fff..3667433b 100644
--- a/src/timeline/EventStore.cpp
+++ b/src/timeline/EventStore.cpp
@@ -185,6 +185,33 @@ EventStore::EventStore(std::string room_id, QObject *)
           [this](std::string txn_id, std::string event_id) {
                   nhlog::ui()->debug("sent {}", txn_id);
 
+                  // Replace the event_id in pending edits/replies/redactions with the actual
+                  // event_id of this event
+                  for (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 (mtx::common::Relation &rel : relations.relations) {
+                                          if (rel.event_id == txn_id)
+                                                  rel.event_id = event_id;
+                                  }
+
+                                  mtx::accessors::set_relations(related_event.data, relations);
+
+                                  cache::client()->replaceEvent(
+                                    room_id_, related_event_id, related_event);
+
+                                  auto id = idToIndex(event_id);
+
+                                  events_by_id_.remove({room_id_, related_event_id});
+                                  events_.remove({room_id_, toInternalIdx(*id)});
+
+                                  emit dataChanged(*id, *id);
+                          }
+                  }
+
                   http::client()->read_event(
                     room_id_, event_id, [this, event_id](mtx::http::RequestErr err) {
                             if (err) {
@@ -193,6 +220,11 @@ EventStore::EventStore(std::string room_id, QObject *)
                             }
                     });
 
+                  auto id = idToIndex(event_id);
+
+                  if (id)
+                          emit dataChanged(id.value(), id.value());
+
                   cache::client()->removePendingStatus(room_id_, txn_id);
                   this->current_txn             = "";
                   this->current_txn_error_count = 0;
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index f29f929e..e2e5551b 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -375,6 +375,15 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
         connect(&events, &EventStore::updateFlowEventId, this, [this](std::string event_id) {
                 this->updateFlowEventId(event_id);
         });
+        connect(&events,
+                &EventStore::messageSent,
+                this,
+                [this](std::string txn_id, std::string event_id) {
+                        if (edit_.toStdString() == txn_id) {
+                                edit_ = QString::fromStdString(event_id);
+                                emit editChanged(edit_);
+                        }
+                });
 
         showEventTimer.callOnTimeout(this, &TimelineModel::scrollTimerEvent);
 }
@@ -568,10 +577,8 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
         case IsEdited:
                 return QVariant(relations(event).replaces().has_value());
         case IsEditable:
-                return QVariant(!is_state_event(event) &&
-                                mtx::accessors::sender(event) ==
-                                  http::client()->user_id().to_string() &&
-                                !event_id(event).empty() && event_id(event).front() == '$');
+                return QVariant(!is_state_event(event) && mtx::accessors::sender(event) ==
+                                                            http::client()->user_id().to_string());
         case IsEncrypted: {
                 auto id              = event_id(event);
                 auto encrypted_event = events.get(id, "", false);
@@ -1796,9 +1803,6 @@ TimelineModel::formatMemberEvent(QString id)
 void
 TimelineModel::setEdit(QString newEdit)
 {
-        if (edit_.startsWith('m'))
-                return;
-
         if (newEdit.isEmpty()) {
                 resetEdit();
                 return;