From 761943f98fa455da58bb2cacaa05689525038a6b Mon Sep 17 00:00:00 2001 From: Black Hat Date: Sun, 21 Jul 2019 16:11:26 +0800 Subject: [PATCH] Display reactions in MessageDelegate. --- .../Component/Timeline/MessageDelegate.qml | 6 +++ .../Component/Timeline/ReactionDelegate.qml | 28 +++++++++++++ imports/Spectral/Component/Timeline/qmldir | 1 + res.qrc | 1 + src/messageeventmodel.cpp | 39 +++++++++++++++++-- src/messageeventmodel.h | 2 + 6 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 imports/Spectral/Component/Timeline/ReactionDelegate.qml diff --git a/imports/Spectral/Component/Timeline/MessageDelegate.qml b/imports/Spectral/Component/Timeline/MessageDelegate.qml index 2531ff9e6..c6a77c8aa 100644 --- a/imports/Spectral/Component/Timeline/MessageDelegate.qml +++ b/imports/Spectral/Component/Timeline/MessageDelegate.qml @@ -220,6 +220,12 @@ ColumnLayout { cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor } } + + ReactionDelegate { + Layout.bottomMargin: 8 + Layout.leftMargin: 16 + Layout.rightMargin: 16 + } } } } diff --git a/imports/Spectral/Component/Timeline/ReactionDelegate.qml b/imports/Spectral/Component/Timeline/ReactionDelegate.qml new file mode 100644 index 000000000..9865f5eb7 --- /dev/null +++ b/imports/Spectral/Component/Timeline/ReactionDelegate.qml @@ -0,0 +1,28 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import Spectral.Setting 0.1 + +RowLayout { + visible: reaction || false + + Repeater { + model: reaction + + delegate: Control { + horizontalPadding: 4 + verticalPadding: 0 + + background: Rectangle { + radius: height / 2 + color: MPalette.banner + } + + contentItem: Label { + text: modelData.reaction + " " + modelData.count + font.pixelSize: 10 + } + } + } +} + diff --git a/imports/Spectral/Component/Timeline/qmldir b/imports/Spectral/Component/Timeline/qmldir index 03ed87550..e1f5b7b4e 100644 --- a/imports/Spectral/Component/Timeline/qmldir +++ b/imports/Spectral/Component/Timeline/qmldir @@ -5,3 +5,4 @@ SectionDelegate 2.0 SectionDelegate.qml ImageDelegate 2.0 ImageDelegate.qml FileDelegate 2.0 FileDelegate.qml VideoDelegate 2.0 VideoDelegate.qml +ReactionDelegate 2.0 ReactionDelegate.qml diff --git a/res.qrc b/res.qrc index a65bdab65..0827f905b 100644 --- a/res.qrc +++ b/res.qrc @@ -57,5 +57,6 @@ imports/Spectral/Dialog/OpenFolderDialog.qml imports/Spectral/Component/Timeline/VideoDelegate.qml imports/Spectral/Component/AutoRectangle.qml + imports/Spectral/Component/Timeline/ReactionDelegate.qml diff --git a/src/messageeventmodel.cpp b/src/messageeventmodel.cpp index c1f5a54ae..bffae7ca2 100644 --- a/src/messageeventmodel.cpp +++ b/src/messageeventmodel.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,7 @@ QHash MessageEventModel::roleNames() const { roles[ShowAuthorRole] = "showAuthor"; roles[ShowSectionRole] = "showSection"; roles[BubbleShapeRole] = "bubbleShape"; + roles[ReactionRole] = "reaction"; return roles; } @@ -357,7 +359,7 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const { return EventStatus::Hidden; } - if (is(evt)) + if (is(evt) || is(evt)) return EventStatus::Hidden; if (evt.isRedacted()) return EventStatus::Hidden; @@ -417,9 +419,9 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const { return QVariantMap{ {"eventId", replyEventId}, {"display", utils::cleanHTML(utils::removeReply( - m_currentRoom->eventToString(replyEvt, Qt::RichText)))}, - {"author", QVariant::fromValue(m_currentRoom->user(replyEvt.senderId()))} - }; + m_currentRoom->eventToString(replyEvt, Qt::RichText)))}, + {"author", + QVariant::fromValue(m_currentRoom->user(replyEvt.senderId()))}}; } if (role == ShowAuthorRole) { @@ -478,6 +480,35 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const { return BubbleShapes::MiddleShape; } + if (role == ReactionRole) { + const auto& annotations = + m_currentRoom->relatedEvents(evt, EventRelation::Annotation()); + if (annotations.isEmpty()) + return {}; + QMap> reactions; + for (const auto& a : annotations) { + if (auto e = eventCast(a)) + reactions[e->relation().key].append( + static_cast(m_currentRoom->user(e->senderId()))); + } + + QVariantList res; + QMap>::const_iterator i = + reactions.constBegin(); + while (i != reactions.constEnd()) { + QVariantList authors; + for (auto author : i.value()) { + authors.append(QVariant::fromValue(author)); + } + res.append(QVariantMap{{"reaction", i.key()}, + {"count", i.value().count()}, + {"authors", authors}}); + ++i; + } + + return res; + } + return {}; } diff --git a/src/messageeventmodel.h b/src/messageeventmodel.h index 7933b4ea6..38dd301b0 100644 --- a/src/messageeventmodel.h +++ b/src/messageeventmodel.h @@ -34,6 +34,8 @@ class MessageEventModel : public QAbstractListModel { BubbleShapeRole, + ReactionRole, + // For debugging EventResolvedTypeRole, };