Browse Source

Open reaction picker from desktop heart and toggle existing reactions

master
evgeny 4 days ago
parent
commit
f71e5531e0
  1. 30
      tools/chatgui/src/messagefeedback.cpp
  2. 12
      tools/chatgui/src/messagelist.cpp
  3. 3
      tools/chatgui/src/messagelist.h

30
tools/chatgui/src/messagefeedback.cpp

@ -18,6 +18,8 @@
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonArray>
#include <QMenu>
#include <QCursor>
#include <cstring>
extern "C" {
@ -26,6 +28,34 @@ extern "C" {
static QString feedbackText(const char* source) { return QCoreApplication::translate("ChatGui", source); }
void MessageList::addReactionActions(QMenu* menu, const QString& channel, const QString& messageId) {
QSet<int> mine;
for (const auto& value : m_feedback.value(messageId).value("reactions").toArray())
if (value.toObject().value("mine").toBool()) mine.insert(value.toObject().value("id").toInt());
for (unsigned i = 0; i < CHAT_REACTION_COUNT; i++) {
auto* action = menu->addAction(QString::fromUtf8(chat_reaction_emoji(i)));
action->setCheckable(true); action->setChecked(mine.contains(i));
connect(action, &QAction::triggered, this, [this, channel, messageId, i]() {
GUI_DEBUG("reaction: chosen ch=%s message=%s emoji=%u", qPrintable(channel), qPrintable(messageId), i);
sendFeedback({{"cmd", "react"}, {"ch", channel}, {"message_id", messageId}, {"emoji", (int)i}});
});
}
}
void MessageList::requestReaction(const QModelIndex& index, int emoji) {
const QString channel = index.data(MsgChannelIdRole).toString(), messageId = index.data(MsgMessageKeyRole).toString();
if (!index.isValid() || channel.isEmpty() || isDmChannel(channel) || messageId.size() != 64
|| emoji < -1 || emoji >= CHAT_REACTION_COUNT) {
GUI_WARN("reaction: invalid target ch=%s key_bytes=%d emoji=%d", qPrintable(channel), messageId.size(), emoji); return;
}
if (emoji >= 0) {
GUI_DEBUG("reaction: toggled ch=%s message=%s emoji=%d", qPrintable(channel), qPrintable(messageId), emoji);
sendFeedback({{"cmd", "react"}, {"ch", channel}, {"message_id", messageId}, {"emoji", emoji}}); return;
}
GUI_DEBUG("reaction: picker opened ch=%s message=%s", qPrintable(channel), qPrintable(messageId));
QMenu menu(m_view); addReactionActions(&menu, channel, messageId); menu.exec(QCursor::pos());
}
/* Итог для баббла и открытого диалога; строковые поля показываем как обычный текст. */
static QString pollSummary(const QJsonObject& poll) {
QString text = poll.value("question").toString();

12
tools/chatgui/src/messagelist.cpp

@ -451,6 +451,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
connect(msgDelegate, &MessageDelegate::avatarRequested, this, [](const QString& channel, quint64 owner) {
showAvatarGallery(channel, owner);
});
connect(msgDelegate, &MessageDelegate::reactionRequested, this, &MessageList::requestReaction);
msgDelegate->setDownloadCallback([](const QModelIndex& index) {
QString target = index.data(MsgChannelIdRole).toString();
qint64 id = index.data(MsgIdRole).toLongLong();
@ -1065,16 +1066,7 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
if (ct == "poll") connect(menu.addAction(QCoreApplication::translate("ChatGui", "Vote / results")), &QAction::triggered,
this, [this, messageId]() { showPoll(messageId); });
auto* reactions = menu.addMenu(QCoreApplication::translate("ChatGui", "React"));
QSet<int> mine;
for (const auto& value : m_feedback.value(messageId).value("reactions").toArray())
if (value.toObject().value("mine").toBool()) mine.insert(value.toObject().value("id").toInt());
for (unsigned i = 0; i < CHAT_REACTION_COUNT; i++) {
auto* action = reactions->addAction(QString::fromUtf8(chat_reaction_emoji(i)));
action->setCheckable(true); action->setChecked(mine.contains(i));
connect(action, &QAction::triggered, this, [this, messageId, i]() {
sendFeedback({{"cmd", "react"}, {"message_id", messageId}, {"emoji", (int)i}});
});
}
addReactionActions(reactions, idx.data(MsgChannelIdRole).toString(), messageId);
connect(menu.addAction(QCoreApplication::translate("ChatGui", "Clear reactions")), &QAction::triggered,
this, [this, messageId]() { sendFeedback({{"cmd", "react"}, {"message_id", messageId}, {"clear", true}}); });
}

3
tools/chatgui/src/messagelist.h

@ -21,6 +21,7 @@ class QLabel;
class QPushButton;
class RadioPanel;
class QDialog;
class QMenu;
struct MessageRow;
class MessageList : public QWidget {
@ -90,6 +91,8 @@ private:
void createPoll();
void showPoll(const QString& messageId);
void applyFeedback(const QJsonObject& state);
void requestReaction(const QModelIndex& index, int emoji);
void addReactionActions(QMenu* menu, const QString& channel, const QString& messageId);
QString authorName(quint64 nodeId) const;
void restoreScrollPosition(const QString& channelId);

Loading…
Cancel
Save