Fix desktop hover and emoji playback; share Android chat background
This commit is contained in:
1 parent
35648a19ce
commit
1e9264735b
13 files changed
+338
-51
No files matched your search
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user