summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2020-07-20 00:42:48 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2020-07-20 00:42:48 +0200
commit19f27236ea82b1927c83e4e24c71b30061674ee7 (patch)
tree1f6449488bbbd4dc23827253bbf56096f8f949e7 /src
parentFix reaction display (diff)
downloadnheko-19f27236ea82b1927c83e4e24c71b30061674ee7.tar.xz
Fix reactions
Diffstat (limited to 'src')
-rw-r--r--src/EventAccessors.cpp19
-rw-r--r--src/EventAccessors.h2
-rw-r--r--src/timeline/EventStore.cpp14
-rw-r--r--src/timeline/TimelineModel.cpp3
-rw-r--r--src/timeline/TimelineModel.h9
-rw-r--r--src/timeline/TimelineViewManager.cpp45
-rw-r--r--src/timeline/TimelineViewManager.h8
7 files changed, 71 insertions, 29 deletions
diff --git a/src/EventAccessors.cpp b/src/EventAccessors.cpp

index 7071819b..0618206c 100644 --- a/src/EventAccessors.cpp +++ b/src/EventAccessors.cpp
@@ -223,6 +223,20 @@ struct EventInReplyTo } }; +struct EventRelatesTo +{ + template<class Content> + using related_ev_id_t = decltype(Content::relates_to.event_id); + template<class T> + std::string operator()(const mtx::events::Event<T> &e) + { + if constexpr (is_detected<related_ev_id_t, T>::value) { + return e.content.relates_to.event_id; + } + return ""; + } +}; + struct EventTransactionId { template<class T> @@ -378,6 +392,11 @@ mtx::accessors::in_reply_to_event(const mtx::events::collections::TimelineEvents { return std::visit(EventInReplyTo{}, event); } +std::string +mtx::accessors::relates_to_event_id(const mtx::events::collections::TimelineEvents &event) +{ + return std::visit(EventRelatesTo{}, event); +} std::string mtx::accessors::transaction_id(const mtx::events::collections::TimelineEvents &event) diff --git a/src/EventAccessors.h b/src/EventAccessors.h
index a7577d86..8f08ef1c 100644 --- a/src/EventAccessors.h +++ b/src/EventAccessors.h
@@ -53,6 +53,8 @@ mimetype(const mtx::events::collections::TimelineEvents &event); std::string in_reply_to_event(const mtx::events::collections::TimelineEvents &event); std::string +relates_to_event_id(const mtx::events::collections::TimelineEvents &event); +std::string transaction_id(const mtx::events::collections::TimelineEvents &event); int64_t diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index 0bd7a97e..eb1162cc 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp
@@ -202,6 +202,20 @@ EventStore::handleSync(const mtx::responses::Timeline &events) if (auto redaction = std::get_if<mtx::events::RedactionEvent<mtx::events::msg::Redaction>>( &event)) { + // fixup reactions + auto redacted = events_by_id_.object({room_id_, redaction->redacts}); + if (redacted) { + auto id = mtx::accessors::relates_to_event_id(*redacted); + if (!id.empty()) { + auto idx = idToIndex(id); + if (idx) { + events_by_id_.remove( + {room_id_, redaction->redacts}); + emit dataChanged(*idx, *idx); + } + } + } + relates_to = redaction->redacts; } else if (auto reaction = std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>( diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 85d2eb4e..8631eb83 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -1069,8 +1069,9 @@ struct SendMessageVisitor // reactions need to have the relation outside of ciphertext, or synapse / the homeserver // cannot handle it correctly. See the MSC for more details: // https://github.com/matrix-org/matrix-doc/blob/matthew/msc1849/proposals/1849-aggregations.md#end-to-end-encryption - void operator()(const mtx::events::RoomEvent<mtx::events::msg::Reaction> &msg) + void operator()(mtx::events::RoomEvent<mtx::events::msg::Reaction> msg) { + msg.type = mtx::events::EventType::Reaction; emit model_->addPendingMessageToStore(msg); } diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index cbe88fd2..f8a84f17 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -197,6 +197,15 @@ public: Q_INVOKABLE void cacheMedia(QString eventId); Q_INVOKABLE bool saveMedia(QString eventId) const; + std::vector<::Reaction> reactions(const std::string &event_id) + { + auto list = events.reactions(event_id); + std::vector<::Reaction> vec; + for (const auto &r : list) + vec.push_back(r.value<Reaction>()); + return vec; + } + void updateLastMessage(); void addEvents(const mtx::responses::Timeline &events); template<class T> diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 64af8afb..8cb72edd 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp
@@ -314,36 +314,39 @@ TimelineViewManager::queueEmoteMessage(const QString &msg) } void -TimelineViewManager::reactToMessage(const QString &roomId, - const QString &reactedEvent, - const QString &reactionKey, - const QString &selfReactedEvent) +TimelineViewManager::queueReactionMessage(const QString &reactedEvent, const QString &reactionKey) { + if (!timeline_) + return; + + auto reactions = timeline_->reactions(reactedEvent.toStdString()); + + QString selfReactedEvent; + for (const auto &reaction : reactions) { + if (reactionKey == reaction.key_) { + selfReactedEvent = reaction.selfReactedEvent_; + break; + } + } + + if (selfReactedEvent.startsWith("m")) + return; + // If selfReactedEvent is empty, that means we haven't previously reacted if (selfReactedEvent.isEmpty()) { - queueReactionMessage(roomId, reactedEvent, reactionKey); + mtx::events::msg::Reaction reaction; + reaction.relates_to.rel_type = mtx::common::RelationType::Annotation; + reaction.relates_to.event_id = reactedEvent.toStdString(); + reaction.relates_to.key = reactionKey.toStdString(); + + timeline_->sendMessage(reaction); // Otherwise, we have previously reacted and the reaction should be redacted } else { - auto model = models.value(roomId); - model->redactEvent(selfReactedEvent); + timeline_->redactEvent(selfReactedEvent); } } void -TimelineViewManager::queueReactionMessage(const QString &roomId, - const QString &reactedEvent, - const QString &reactionKey) -{ - mtx::events::msg::Reaction reaction; - reaction.relates_to.rel_type = mtx::common::RelationType::Annotation; - reaction.relates_to.event_id = reactedEvent.toStdString(); - reaction.relates_to.key = reactionKey.toStdString(); - - auto model = models.value(roomId); - model->sendMessage(reaction); -} - -void TimelineViewManager::queueImageMessage(const QString &roomid, const QString &filename, const std::optional<mtx::crypto::EncryptedFile> &file, diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index ed095058..63106916 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h
@@ -61,13 +61,7 @@ public slots: void setHistoryView(const QString &room_id); void updateColorPalette(); - void queueReactionMessage(const QString &roomId, - const QString &reactedEvent, - const QString &reaction); - void reactToMessage(const QString &roomId, - const QString &reactedEvent, - const QString &reactionKey, - const QString &selfReactedEvent); + void queueReactionMessage(const QString &reactedEvent, const QString &reactionKey); void queueTextMessage(const QString &msg); void queueEmoteMessage(const QString &msg); void queueImageMessage(const QString &roomid,