Skip to content

Commit

Permalink
Fix showing edited message for historical messages
Browse files Browse the repository at this point in the history
Fixes #713
  • Loading branch information
TobiasFella committed Nov 5, 2023
1 parent 8c603ad commit 604929f
Showing 1 changed file with 50 additions and 43 deletions.
93 changes: 50 additions & 43 deletions Quotient/room.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ class Q_DECL_HIDDEN Room::Private {

bool isLocalUser(const User* u) const { return u == q->localUser(); }

void processRedactionsAndEdits(RoomEvents& events);

#ifdef Quotient_E2EE_ENABLED
UnorderedMap<QByteArray, QOlmInboundGroupSession> groupSessions;
Omittable<QOlmOutboundGroupSession> currentOutboundMegolmSession = none;
Expand Down Expand Up @@ -2878,6 +2880,51 @@ inline bool isEditing(const RoomEventPtr& ep)
false);
}

void Room::Private::processRedactionsAndEdits(RoomEvents& events)
{
// Pre-process redactions and edits so that events that get
// redacted/replaced in the same batch landed in the timeline already
// treated.
// NB: We have to store redacting/replacing events to the timeline too -
// see #220.
auto it = std::find_if(events.begin(), events.end(), isEditing);
for (const auto& eptr : RoomEventsRange(it, events.end())) {
if (auto* r = eventCast<RedactionEvent>(eptr)) {
// Try to find the target in the timeline, then in the batch.
if (processRedaction(*r))
continue;
if (auto targetIt = std::find_if(events.begin(), events.end(),
[id = r->redactedEvent()](const RoomEventPtr& ep) {
return ep->id() == id;
}); targetIt != events.end())
*targetIt = makeRedacted(**targetIt, *r);
else
qCDebug(STATE)
<< "Redaction" << r->id() << "ignored: target event"
<< r->redactedEvent() << "is not found";
// If the target event comes later, it comes already redacted.
}
if (auto* msg = eventCast<RoomMessageEvent>(eptr);
msg && !msg->replacedEvent().isEmpty()) {
if (processReplacement(*msg))
continue;
auto targetIt = std::find_if(events.begin(), events.end(),
[id = msg->replacedEvent()](const RoomEventPtr& ep) {
return ep->id() == id;
});
if (targetIt != it)
*targetIt = makeReplaced(**targetIt, *msg);
else // FIXME: hide the replacing event when target arrives later
qCDebug(EVENTS)
<< "Replacing event" << msg->id()
<< "ignored: target event" << msg->replacedEvent()
<< "is not found";
// Same as with redactions above, the replaced event coming
// later will come already with the new content.
}
}
}

Room::Changes Room::Private::addNewMessageEvents(RoomEvents&& events)
{
dropExtraneousEvents(events);
Expand All @@ -2889,49 +2936,7 @@ Room::Changes Room::Private::addNewMessageEvents(RoomEvents&& events)
QElapsedTimer et;
et.start();

{
// Pre-process redactions and edits so that events that get
// redacted/replaced in the same batch landed in the timeline already
// treated.
// NB: We have to store redacting/replacing events to the timeline too -
// see #220.
auto it = std::find_if(events.begin(), events.end(), isEditing);
for (const auto& eptr : RoomEventsRange(it, events.end())) {
if (auto* r = eventCast<RedactionEvent>(eptr)) {
// Try to find the target in the timeline, then in the batch.
if (processRedaction(*r))
continue;
if (auto targetIt = std::find_if(events.begin(), events.end(),
[id = r->redactedEvent()](const RoomEventPtr& ep) {
return ep->id() == id;
}); targetIt != events.end())
*targetIt = makeRedacted(**targetIt, *r);
else
qCDebug(STATE)
<< "Redaction" << r->id() << "ignored: target event"
<< r->redactedEvent() << "is not found";
// If the target event comes later, it comes already redacted.
}
if (auto* msg = eventCast<RoomMessageEvent>(eptr);
msg && !msg->replacedEvent().isEmpty()) {
if (processReplacement(*msg))
continue;
auto targetIt = std::find_if(events.begin(), it,
[id = msg->replacedEvent()](const RoomEventPtr& ep) {
return ep->id() == id;
});
if (targetIt != it)
*targetIt = makeReplaced(**targetIt, *msg);
else // FIXME: hide the replacing event when target arrives later
qCDebug(EVENTS)
<< "Replacing event" << msg->id()
<< "ignored: target event" << msg->replacedEvent()
<< "is not found";
// Same as with redactions above, the replaced event coming
// later will come already with the new content.
}
}
}
processRedactionsAndEdits(events);

// State changes arrive as a part of timeline; the current room state gets
// updated before merging events to the timeline because that's what
Expand Down Expand Up @@ -3034,6 +3039,8 @@ void Room::Private::addHistoricalMessageEvents(RoomEvents&& events)

decryptIncomingEvents(events);

processRedactionsAndEdits(events);

QElapsedTimer et;
et.start();
Changes changes {};
Expand Down

0 comments on commit 604929f

Please sign in to comment.