From ddcc36aa26f5c769b9ad3092e215a74f11f29e4b Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 7 Oct 2026 17:11:43 +0200 Subject: [PATCH] Open desktop chat polls with a single left click --- tools/chatgui/src/messagedelegate.cpp | 23 ++++++++++++++++++++++- tools/chatgui/src/messagedelegate.h | 3 +++ tools/chatgui/src/messagelist.cpp | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/chatgui/src/messagedelegate.cpp b/tools/chatgui/src/messagedelegate.cpp index 8bb4ea4a..6d90a2f0 100644 --- a/tools/chatgui/src/messagedelegate.cpp +++ b/tools/chatgui/src/messagedelegate.cpp @@ -143,10 +143,19 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, for (const auto& chip : L.reactionChips) if (chip.rect.contains(point)) { reaction = chip.id; break; } const bool onReaction = mouse->button() == Qt::LeftButton && reaction != -2; const bool onAvatar=mouse->button()==Qt::LeftButton && !L.narrow && L.avatarRect.contains(mouse->pos()-option.rect.topLeft()); + const bool onPoll = index.data(MsgContentTypeRole).toString() == "poll" + && !index.data(MsgChannelIdRole).toString().startsWith("dm:") && L.bubbleRect.contains(point) + && (!L.reactionHeart.isValid() || point.y() < L.reactionHeart.top()); if (event->type()==QEvent::MouseButtonPress) { m_reactionPress = onReaction ? index : QModelIndex(); m_pressedReaction = reaction; m_reactionPressPosition = mouse->pos(); - m_avatarPress=onAvatar ? index : QModelIndex(); m_avatarPressPosition=mouse->pos(); return onAvatar || onReaction; + m_avatarPress=onAvatar ? index : QModelIndex(); m_avatarPressPosition=mouse->pos(); + m_pollPress = onPoll ? index : QModelIndex(); m_pollPressPosition = mouse->pos(); + return onAvatar || onReaction || onPoll; } + const auto* view = qobject_cast(option.widget); + const bool activatePoll = onPoll && m_pollPress == index && (mouse->pos() - m_pollPressPosition).manhattanLength() < 5 + && (!view || !view->textSelection().active); + m_pollPress = QPersistentModelIndex(); const bool hadReactionPress = m_reactionPress.isValid(); const bool activateAvatar=onAvatar && m_avatarPress==index && (mouse->pos()-m_avatarPressPosition).manhattanLength()<5; m_avatarPress=QPersistentModelIndex(); @@ -162,6 +171,18 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, if (onAvatar) return true; if (L.reactionHeart.isValid() && point.y() >= L.reactionHeart.top()) return true; + if (onPoll) { + if (!activatePoll) return true; + const QString messageId = index.data(MsgMessageKeyRole).toString(); + if (messageId.size() != 64) { + GUI_WARN("poll: cannot open message with invalid key row=%d key_bytes=%d", index.row(), int(messageId.size())); + return true; + } + GUI_INFO("poll: left click ch=%s message=%s", qPrintable(index.data(MsgChannelIdRole).toString()), qPrintable(messageId)); + emit pollRequested(messageId); + return true; + } + if (L.isVideo) { int dlState = index.data(MsgFileDownloadStateRole).toInt(); diff --git a/tools/chatgui/src/messagedelegate.h b/tools/chatgui/src/messagedelegate.h index 6414448e..3abee3ef 100644 --- a/tools/chatgui/src/messagedelegate.h +++ b/tools/chatgui/src/messagedelegate.h @@ -75,6 +75,7 @@ public: signals: void avatarRequested(const QString& channel, quint64 owner); void reactionRequested(const QModelIndex& index, int emoji); /* -1 открывает выбор реакции */ + void pollRequested(const QString& messageId); private: struct ReactionChip { QRect rect; int id; QString emoji; int count; bool mine; }; @@ -128,6 +129,8 @@ private: QPersistentModelIndex m_reactionPress; QPoint m_reactionPressPosition; int m_pressedReaction = -2; + QPersistentModelIndex m_pollPress; + QPoint m_pollPressPosition; std::function m_downloadCb; Layout calcLayout(const QStyleOptionViewItem &option, diff --git a/tools/chatgui/src/messagelist.cpp b/tools/chatgui/src/messagelist.cpp index e5c25189..0980981f 100644 --- a/tools/chatgui/src/messagelist.cpp +++ b/tools/chatgui/src/messagelist.cpp @@ -452,6 +452,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent showAvatarGallery(channel, owner); }); connect(msgDelegate, &MessageDelegate::reactionRequested, this, &MessageList::requestReaction); + connect(msgDelegate, &MessageDelegate::pollRequested, this, &MessageList::showPoll); msgDelegate->setDownloadCallback([](const QModelIndex& index) { QString target = index.data(MsgChannelIdRole).toString(); qint64 id = index.data(MsgIdRole).toLongLong();