Fix desktop hover and emoji playback; share Android chat background

This commit is contained in:
evgeny committed 2026-10-02 23:19:13 +03:00
1 parent 35648a19ce
commit 1e9264735b
13 files changed
+338 -51

No files matched your search

+46 -1
View File
@@ -1,5 +1,7 @@
#include "chatview.h"
#include "messagedelegate.h"
#include "emoji.h"
#include "debug_ui.h"
#include <QPainter>
#include <QClipboard>
#include <QApplication>
@@ -8,6 +10,20 @@
#include <QKeyEvent>
#include <QScrollBar>
// Текст и реакции сообщения используют общий набор анимированных значков.
static QSet<QString> animatedEmojiPaths(const QModelIndex &index) {
QSet<QString> paths;
const QString text = index.data(MsgTextRole).toString();
for (auto it = g_animatedEmojiMap.constBegin(); it != g_animatedEmojiMap.constEnd(); ++it) {
if (text.contains(it.key())) paths.insert(it.value());
}
for (const auto &reaction : index.data(MsgReactionsRole).toList()) {
const QString path = g_animatedEmojiMap.value(reaction.toMap().value("emoji").toString());
if (!path.isEmpty()) paths.insert(path);
}
return paths;
}
ChatView::ChatView(QWidget *parent)
: QListView(parent)
{
@@ -65,6 +81,24 @@ void ChatView::paintEvent(QPaintEvent *event) {
p.drawTiledPixmap(viewport()->rect(), m_background);
}
QListView::paintEvent(event);
QSet<QString> visible;
if (model()) {
const QRect area = viewport()->rect();
for (int row = 0; row < model()->rowCount(); ++row) {
const QModelIndex index = model()->index(row, 0);
if (!visualRect(index).intersects(area)) continue;
const QString message = QStringLiteral("%1/%2/%3/")
.arg(index.data(MsgChannelIdRole).toString()).arg(index.data(MsgIdRole).toLongLong())
.arg(index.data(MsgIsOutgoingRole).toInt());
for (const auto &path : animatedEmojiPaths(index)) visible.insert(message + path);
}
}
const int appeared = (visible - m_visibleAnimations).size();
m_visibleAnimations = visible;
if (appeared > 0) {
GUI_DEBUG("ChatView: visible animation trigger appeared=%d visible=%d", appeared, (int)visible.size());
emit animationTriggered();
}
}
bool ChatView::isRowSelected(const QModelIndex &idx) const {
@@ -95,6 +129,13 @@ void ChatView::mousePressEvent(QMouseEvent *event) {
QListView::mousePressEvent(event);
}
bool ChatView::viewportEvent(QEvent *event) {
if (event->type() == QEvent::Leave && m_lastHovered.isValid()) {
m_lastHovered = QPersistentModelIndex();
}
return QListView::viewportEvent(event);
}
void ChatView::mouseMoveEvent(QMouseEvent *event) {
if (!m_selecting && m_pressIndex.isValid()) {
int dx = event->pos().x() - m_pressPos.x();
@@ -115,7 +156,11 @@ void ChatView::mouseMoveEvent(QMouseEvent *event) {
QModelIndex idx = indexAt(viewport()->mapFrom(this, event->pos()));
if (idx != QModelIndex(m_lastHovered)) {
m_lastHovered = idx;
emit hoveredIndexChanged(idx);
const auto paths = animatedEmojiPaths(idx);
if (!paths.isEmpty()) {
GUI_DEBUG("ChatView: hover animation trigger row=%d icons=%d", idx.row(), (int)paths.size());
emit animationTriggered();
}
}
}
if (!m_selecting) {