diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/events/stateevent.h | 2 | ||||
-rw-r--r-- | lib/room.cpp | 39 |
2 files changed, 31 insertions, 10 deletions
diff --git a/lib/events/stateevent.h b/lib/events/stateevent.h index 76c749f5..d50500f2 100644 --- a/lib/events/stateevent.h +++ b/lib/events/stateevent.h @@ -42,7 +42,7 @@ namespace QMatrixClient { * of state in Matrix. * \sa https://matrix.org/docs/spec/client_server/unstable.html#types-of-room-events */ - using StateEventKey = std::pair<Event::Type, QString>; + using StateEventKey = std::pair<QString, QString>; template <typename ContentT> struct Prev diff --git a/lib/room.cpp b/lib/room.cpp index fd4add3b..38a4157e 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -178,10 +178,12 @@ class Room::Private template <typename EventT> const EventT* getCurrentState(QString stateKey = {}) const { - static const EventT emptyEvent { QJsonObject{} }; - return static_cast<const EventT*>( - currentState.value({EventT::typeId(), stateKey}, - &emptyEvent)); + static const EventT empty; + const auto* evt = + currentState.value({EventT::matrixTypeId(), stateKey}, &empty); + Q_ASSERT(evt->type() == EventT::typeId() && + evt->matrixType() == EventT::matrixTypeId()); + return static_cast<const EventT*>(evt); } bool isEventNotable(const TimelineItem& ti) const @@ -1117,7 +1119,8 @@ void Room::updateData(SyncRoomData&& data) for (auto&& eptr: data.state) { const auto& evt = *eptr; - d->baseState[{evt.type(),evt.stateKey()}] = move(eptr); + Q_ASSERT(evt.isStateEvent()); + d->baseState[{evt.matrixType(),evt.stateKey()}] = move(eptr); emitNamesChanged |= processStateEvent(evt); } @@ -1628,11 +1631,26 @@ bool Room::Private::processRedaction(const RedactionEvent& redaction) return true; } - // Make a new event from the redacted JSON, exchange events, - // notify everyone and delete the old event + // Make a new event from the redacted JSON and put it in the timeline + // instead of the redacted one. oldEvent will be deleted on return. auto oldEvent = ti.replaceEvent(makeRedacted(*ti, redaction)); - q->onRedaction(*oldEvent, *ti.event()); qCDebug(MAIN) << "Redacted" << oldEvent->id() << "with" << redaction.id(); + if (oldEvent->isStateEvent()) + { + const StateEventKey evtKey { oldEvent->matrixType(), oldEvent->stateKey() }; + Q_ASSERT(currentState.contains(evtKey)); + if (currentState[evtKey] == oldEvent.get()) + { + Q_ASSERT(ti.index() >= 0); // Historical states can't be in currentState + qCDebug(MAIN).nospace() << "Reverting state " + << oldEvent->matrixType() << "/" << oldEvent->stateKey(); + // Retarget the current state to the newly made event. + if (q->processStateEvent(*ti)) + emit q->namesChanged(q); + updateDisplayname(); + } + } + q->onRedaction(*oldEvent, *ti); emit q->replacedEvent(ti.event(), rawPtr(oldEvent)); return true; } @@ -1791,7 +1809,7 @@ bool Room::processStateEvent(const RoomEvent& e) if (!e.isStateEvent()) return false; - d->currentState[{e.type(),e.stateKey()}] = + d->currentState[{e.matrixType(),e.stateKey()}] = static_cast<const StateEventBase*>(&e); if (!is<RoomMemberEvent>(e)) qCDebug(EVENTS) << "Room state event:" << e; @@ -2060,7 +2078,10 @@ QJsonObject Room::Private::toJson() const QJsonArray stateEvents; for (const auto& evt: currentState) + { + Q_ASSERT(evt->isStateEvent()); stateEvents.append(evt->fullJson()); + } const auto stateObjName = joinState == JoinState::Invite ? QStringLiteral("invite_state") : QStringLiteral("state"); |