From f7da8eebadbd6b22a909d4d0d83eb0b0388fd997 Mon Sep 17 00:00:00 2001 From: Black Hat Date: Tue, 30 Jul 2019 21:29:55 +0800 Subject: [PATCH] Reactions are refreshed correctly in the timeline. --- .../Timeline/MessageDelegateContextMenu.qml | 35 +++++++++++------- include/libQuotient | 2 +- src/messageeventmodel.cpp | 37 ++++++++++++++----- src/spectralroom.cpp | 9 +---- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml b/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml index b536fcb03..f3a53c517 100644 --- a/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml +++ b/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml @@ -12,31 +12,38 @@ Menu { id: root - Flow { + Item { width: parent.width + height: 32 - spacing: 0 + Row { + anchors.centerIn: parent - Repeater { - model: ["👍", "👎️", "😄", "🎉", "🚀", "👀"] + spacing: 0 - delegate: ItemDelegate { - width: 32 - height: 32 + Repeater { + model: ["👍", "👎️", "😄", "🎉", "🚀", "👀"] - contentItem: Label { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter + delegate: ItemDelegate { + width: 32 + height: 32 - font.pixelSize: 16 - text: modelData + contentItem: Label { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font.pixelSize: 16 + text: modelData + } + + onClicked: currentRoom.toggleReaction(eventId, modelData) } - - onClicked: currentRoom.toggleReaction(eventId, modelData) } } } + MenuSeparator {} + MenuItem { text: "View Source" diff --git a/include/libQuotient b/include/libQuotient index 2fb22758c..64bea52b8 160000 --- a/include/libQuotient +++ b/include/libQuotient @@ -1 +1 @@ -Subproject commit 2fb22758c1668d65e9400fe7d35857ddc54fcc6a +Subproject commit 64bea52b8672df45e5a0bd2ca54fe6a0fd97a7b2 diff --git a/src/messageeventmodel.cpp b/src/messageeventmodel.cpp index d836cc13e..94cca3d59 100644 --- a/src/messageeventmodel.cpp +++ b/src/messageeventmodel.cpp @@ -136,6 +136,10 @@ void MessageEventModel::setRoom(SpectralRoom* room) { refreshLastUserEvents(refreshEvent(newEvent->id()) - timelineBaseIndex()); }); + connect(m_currentRoom, &Room::updatedEvent, this, + [this](const QString& eventId) { + refreshEventRoles(eventId, {ReactionRole}); + }); connect(m_currentRoom, &Room::fileTransferProgress, this, &MessageEventModel::refreshEvent); connect(m_currentRoom, &Room::fileTransferCompleted, this, @@ -178,15 +182,24 @@ void MessageEventModel::refreshEventRoles(int row, const QVector& roles) { emit dataChanged(idx, idx, roles); } -int MessageEventModel::refreshEventRoles(const QString& eventId, +int MessageEventModel::refreshEventRoles(const QString& id, const QVector& roles) { - const auto it = m_currentRoom->findInTimeline(eventId); - if (it == m_currentRoom->timelineEdge()) { - qWarning() << "Trying to refresh inexistent event:" << eventId; - return -1; + // On 64-bit platforms, difference_type for std containers is long long + // but Qt uses int throughout its interfaces; hence casting to int below. + int row = -1; + // First try pendingEvents because it is almost always very short. + const auto pendingIt = m_currentRoom->findPendingEvent(id); + if (pendingIt != m_currentRoom->pendingEvents().end()) + row = int(pendingIt - m_currentRoom->pendingEvents().begin()); + else { + const auto timelineIt = m_currentRoom->findInTimeline(id); + if (timelineIt == m_currentRoom->timelineEdge()) { + qWarning() << "Trying to refresh inexistent event:" << id; + return -1; + } + row = int(timelineIt - m_currentRoom->messageEvents().rbegin()) + + timelineBaseIndex(); } - const auto row = - it - m_currentRoom->messageEvents().rbegin() + timelineBaseIndex(); refreshEventRoles(row, roles); return row; } @@ -485,14 +498,20 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const { m_currentRoom->relatedEvents(evt, EventRelation::Annotation()); if (annotations.isEmpty()) return {}; - QMap> reactions; + QMap> reactions = {}; for (const auto& a : annotations) { + if (a->isRedacted()) // Just in case? + continue; if (auto e = eventCast(a)) reactions[e->relation().key].append( static_cast(m_currentRoom->user(e->senderId()))); } - QVariantList res; + if (reactions.isEmpty()) { + return {}; + } + + QVariantList res = {}; QMap>::const_iterator i = reactions.constBegin(); while (i != reactions.constEnd()) { diff --git a/src/spectralroom.cpp b/src/spectralroom.cpp index bba8a8f51..f22471206 100644 --- a/src/spectralroom.cpp +++ b/src/spectralroom.cpp @@ -432,7 +432,7 @@ void SpectralRoom::toggleReaction(const QString& eventId, const auto& evt = **eventIt; - QStringList redactEventIds; // What if there are multiple reaction events? + QStringList redactEventIds; // What if there are multiple reaction events? const auto& annotations = relatedEvents(evt, EventRelation::Annotation()); if (!annotations.isEmpty()) { @@ -450,15 +450,10 @@ void SpectralRoom::toggleReaction(const QString& eventId, } if (!redactEventIds.isEmpty()) { - qDebug() << "Remove reaction event" << redactEventIds << "of event" - << eventId << ":" << reaction; for (auto redactEventId : redactEventIds) { - redactEvent(redactEventId); + redactEvent(redactEventId); } } else { - qDebug() << "Add reaction event" << eventId << ":" << reaction; postEvent(new ReactionEvent(EventRelation::annotate(eventId, reaction))); } - - qDebug() << "End of SpectralRoom::toggleReaction()"; }