diff --git a/src/Cache.cpp b/src/Cache.cpp
index 0d75ac51..2178bbfb 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -1681,6 +1681,27 @@ Cache::storeEvent(const std::string &room_id,
txn.commit();
}
+void
+Cache::replaceEvent(const std::string &room_id,
+ const std::string &event_id,
+ const mtx::events::collections::TimelineEvent &event)
+{
+ auto txn = lmdb::txn::begin(env_);
+ auto eventsDb = getEventsDb(txn, room_id);
+ auto relationsDb = getRelationsDb(txn, room_id);
+ auto event_json = mtx::accessors::serialize_event(event.data).dump();
+
+ {
+ eventsDb.del(txn, event_id);
+ eventsDb.put(txn, event_id, event_json);
+ for (auto relation : mtx::accessors::relations(event.data).relations) {
+ relationsDb.put(txn, relation.event_id, event_id);
+ }
+ }
+
+ txn.commit();
+}
+
std::vector<std::string>
Cache::relatedEvents(const std::string &room_id, const std::string &event_id)
{
diff --git a/src/Cache_p.h b/src/Cache_p.h
index f2911622..669f1895 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -184,6 +184,9 @@ public:
void storeEvent(const std::string &room_id,
const std::string &event_id,
const mtx::events::collections::TimelineEvent &event);
+ void replaceEvent(const std::string &room_id,
+ const std::string &event_id,
+ const mtx::events::collections::TimelineEvent &event);
std::vector<std::string> relatedEvents(const std::string &room_id,
const std::string &event_id);
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;
|