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,
};