forked from mirror/nheko
commit
7beaf868ef
@ -0,0 +1,76 @@ |
||||
import QtQuick 2.6 |
||||
import QtQuick.Controls 2.2 |
||||
|
||||
Flow { |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
spacing: 4 |
||||
|
||||
property alias reactions: repeater.model |
||||
|
||||
Repeater { |
||||
id: repeater |
||||
|
||||
AbstractButton { |
||||
id: reaction |
||||
text: model.key |
||||
hoverEnabled: true |
||||
implicitWidth: contentItem.childrenRect.width + contentItem.leftPadding*2 |
||||
implicitHeight: contentItem.childrenRect.height |
||||
|
||||
ToolTip.visible: hovered |
||||
ToolTip.text: model.users |
||||
|
||||
|
||||
contentItem: Row { |
||||
anchors.centerIn: parent |
||||
spacing: reactionText.implicitHeight/4 |
||||
leftPadding: reactionText.implicitHeight / 2 |
||||
rightPadding: reactionText.implicitHeight / 2 |
||||
|
||||
TextMetrics { |
||||
id: textMetrics |
||||
font.family: settings.emoji_font_family |
||||
elide: Text.ElideRight |
||||
elideWidth: 150 |
||||
text: reaction.text |
||||
} |
||||
|
||||
Text { |
||||
anchors.baseline: reactionCounter.baseline |
||||
id: reactionText |
||||
text: textMetrics.elidedText + (textMetrics.elidedText == textMetrics.text ? "" : "…") |
||||
font.family: settings.emoji_font_family |
||||
color: reaction.hovered ? colors.highlight : colors.text |
||||
maximumLineCount: 1 |
||||
} |
||||
|
||||
Rectangle { |
||||
id: divider |
||||
height: reactionCounter.implicitHeight * 1.4 |
||||
width: 1 |
||||
color: reaction.hovered ? colors.highlight : colors.text |
||||
} |
||||
|
||||
Text { |
||||
anchors.verticalCenter: divider.verticalCenter |
||||
id: reactionCounter |
||||
text: model.counter |
||||
font: reaction.font |
||||
color: reaction.hovered ? colors.highlight : colors.text |
||||
} |
||||
} |
||||
|
||||
background: Rectangle { |
||||
anchors.centerIn: parent |
||||
implicitWidth: reaction.implicitWidth |
||||
implicitHeight: reaction.implicitHeight |
||||
border.color: (reaction.hovered || model.selfReacted )? colors.highlight : colors.text |
||||
color: colors.base |
||||
border.width: 1 |
||||
radius: reaction.height / 2.0 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,98 @@ |
||||
#include "ReactionsModel.h" |
||||
|
||||
#include <Cache.h> |
||||
#include <MatrixClient.h> |
||||
|
||||
QHash<int, QByteArray> |
||||
ReactionsModel::roleNames() const |
||||
{ |
||||
return { |
||||
{Key, "key"}, |
||||
{Count, "counter"}, |
||||
{Users, "users"}, |
||||
{SelfReacted, "selfReacted"}, |
||||
}; |
||||
} |
||||
|
||||
int |
||||
ReactionsModel::rowCount(const QModelIndex &) const |
||||
{ |
||||
return static_cast<int>(reactions.size()); |
||||
} |
||||
|
||||
QVariant |
||||
ReactionsModel::data(const QModelIndex &index, int role) const |
||||
{ |
||||
const int i = index.row(); |
||||
if (i < 0 || i >= static_cast<int>(reactions.size())) |
||||
return {}; |
||||
|
||||
switch (role) { |
||||
case Key: |
||||
return QString::fromStdString(reactions[i].key); |
||||
case Count: |
||||
return static_cast<int>(reactions[i].reactions.size()); |
||||
case Users: { |
||||
QString users; |
||||
bool first = true; |
||||
for (const auto &reaction : reactions[i].reactions) { |
||||
if (!first) |
||||
users += ", "; |
||||
else |
||||
first = false; |
||||
users += QString::fromStdString( |
||||
cache::displayName(room_id_, reaction.second.sender)); |
||||
} |
||||
return users; |
||||
} |
||||
case SelfReacted: |
||||
for (const auto &reaction : reactions[i].reactions) |
||||
if (reaction.second.sender == http::client()->user_id().to_string()) |
||||
return true; |
||||
return false; |
||||
default: |
||||
return {}; |
||||
} |
||||
} |
||||
|
||||
void |
||||
ReactionsModel::addReaction(const std::string &room_id, |
||||
const mtx::events::RoomEvent<mtx::events::msg::Reaction> &reaction) |
||||
{ |
||||
room_id_ = room_id; |
||||
|
||||
int idx = 0; |
||||
for (auto &storedReactions : reactions) { |
||||
if (storedReactions.key == reaction.content.relates_to.key) { |
||||
storedReactions.reactions[reaction.event_id] = reaction; |
||||
emit dataChanged(index(idx, 0), index(idx, 0)); |
||||
return; |
||||
} |
||||
idx++; |
||||
} |
||||
|
||||
beginInsertRows(QModelIndex(), idx, idx); |
||||
reactions.push_back( |
||||
KeyReaction{reaction.content.relates_to.key, {{reaction.event_id, reaction}}}); |
||||
endInsertRows(); |
||||
} |
||||
|
||||
void |
||||
ReactionsModel::removeReaction(const mtx::events::RoomEvent<mtx::events::msg::Reaction> &reaction) |
||||
{ |
||||
int idx = 0; |
||||
for (auto &storedReactions : reactions) { |
||||
if (storedReactions.key == reaction.content.relates_to.key) { |
||||
storedReactions.reactions.erase(reaction.event_id); |
||||
|
||||
if (storedReactions.reactions.size() == 0) { |
||||
beginRemoveRows(QModelIndex(), idx, idx); |
||||
reactions.erase(reactions.begin() + idx); |
||||
endRemoveRows(); |
||||
} else |
||||
emit dataChanged(index(idx, 0), index(idx, 0)); |
||||
return; |
||||
} |
||||
idx++; |
||||
} |
||||
} |
@ -0,0 +1,41 @@ |
||||
#pragma once |
||||
|
||||
#include <QAbstractListModel> |
||||
#include <QHash> |
||||
|
||||
#include <utility> |
||||
#include <vector> |
||||
|
||||
#include <mtx/events/collections.hpp> |
||||
|
||||
class ReactionsModel : public QAbstractListModel |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
explicit ReactionsModel(QObject *parent = nullptr) { Q_UNUSED(parent); } |
||||
enum Roles |
||||
{ |
||||
Key, |
||||
Count, |
||||
Users, |
||||
SelfReacted, |
||||
}; |
||||
|
||||
QHash<int, QByteArray> roleNames() const override; |
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override; |
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; |
||||
|
||||
public slots: |
||||
void addReaction(const std::string &room_id, |
||||
const mtx::events::RoomEvent<mtx::events::msg::Reaction> &reaction); |
||||
void removeReaction(const mtx::events::RoomEvent<mtx::events::msg::Reaction> &reaction); |
||||
|
||||
private: |
||||
struct KeyReaction |
||||
{ |
||||
std::string key; |
||||
std::map<std::string, mtx::events::RoomEvent<mtx::events::msg::Reaction>> reactions; |
||||
}; |
||||
std::string room_id_; |
||||
std::vector<KeyReaction> reactions; |
||||
}; |
Loading…
Reference in new issue