chatgui: fix scroll jump on refresh, force debounce, add DEBUG logs
- Same-channel refresh: save scroll pos in memory, restore from memory (no DB race) - Force m_readDebounce->start() after loadChannel (scrollToBottom may not trigger valueChanged) - DEBUG_DEBUG logs in updateReadPosition, saveChannelState, onMessageReceived, setChannelUnreadCount
This commit is contained in:
1 parent
0c4862c66a
commit
37c5fa5607
4 files changed
+53
-7
No files matched your search
@@ -245,11 +245,15 @@ void ChannelList::setChannelUnreadCount(const QString& channelId, int count) {
|
||||
for (int row = 0; row < m_model->rowCount(); row++) {
|
||||
QStandardItem* item = m_model->item(row);
|
||||
if (item && item->data(ChannelChannelIdRole).toString() == channelId) {
|
||||
int old = item->data(ChannelUnreadCountRole).toInt();
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "ChannelList::setChannelUnreadCount ch=%s %d->%d",
|
||||
qPrintable(channelId), old, count);
|
||||
item->setData(count, ChannelUnreadCountRole);
|
||||
emit m_model->dataChanged(m_model->index(row, 0), m_model->index(row, 0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "ChannelList::setChannelUnreadCount ch=%s not found", qPrintable(channelId));
|
||||
}
|
||||
|
||||
int ChannelList::getChannelUnreadCount(const QString& channelId) const {
|
||||
|
||||
@@ -327,14 +327,17 @@ void MainWindow::showSettings() {
|
||||
}
|
||||
|
||||
void MainWindow::onMessageReceived(const char* ch_id) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "MainWindow: msg received ch=%s", ch_id);
|
||||
SoundManager::instance()->play("msg_incoming");
|
||||
QString cid = QString::fromUtf8(ch_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "MainWindow::onMessageReceived ch=%s cur=%s",
|
||||
qPrintable(cid), qPrintable(m_currentChannelId));
|
||||
SoundManager::instance()->play("msg_incoming");
|
||||
if (m_messageList) {
|
||||
if (cid == m_currentChannelId) {
|
||||
m_messageList->refresh();
|
||||
} else if (m_channelList) {
|
||||
int unread = m_channelList->getChannelUnreadCount(cid) + 1;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "MainWindow::onMessageReceived increment unread ch=%s %d->%d",
|
||||
qPrintable(cid), unread - 1, unread);
|
||||
m_channelList->setChannelUnreadCount(cid, unread);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ extern "C" {
|
||||
#include "../transport/chat_core.h"
|
||||
#include "../../lib/u_async.h"
|
||||
#include "../../lib/mem.h"
|
||||
#include "../../lib/debug_config.h"
|
||||
}
|
||||
|
||||
static QPixmap makeAvatar(const QColor &color, const QString &letter, int size = 36) {
|
||||
@@ -176,16 +177,30 @@ MessageList::MessageList(DbManager* db, QWidget *parent)
|
||||
void MessageList::loadChannel(const QString& channelId) {
|
||||
QWidget* prevFocus = QApplication::focusWidget();
|
||||
|
||||
bool sameChannel = (m_currentChannelId == channelId);
|
||||
|
||||
/* Save state of current channel before switching */
|
||||
if (!m_currentChannelId.isEmpty() && m_currentChannelId != channelId)
|
||||
saveChannelState();
|
||||
if (!m_currentChannelId.isEmpty()) {
|
||||
if (!sameChannel) {
|
||||
saveChannelState();
|
||||
} else {
|
||||
QModelIndex topIdx = m_view->indexAt(QPoint(0, 0));
|
||||
m_savedTopMsgId = topIdx.isValid() ? topIdx.data(MsgIdRole).toLongLong() : 0;
|
||||
QScrollBar* sb = m_view->verticalScrollBar();
|
||||
m_wasAtBottom = sb && (sb->value() >= sb->maximum());
|
||||
}
|
||||
}
|
||||
|
||||
m_model->clear();
|
||||
m_avatarCache.clear();
|
||||
m_currentChannelId = channelId;
|
||||
m_readDebounce->stop();
|
||||
m_lastReadMsgId = m_db->getUiStateInt64(
|
||||
QStringLiteral("ch_%1_last_read").arg(channelId), 0);
|
||||
if (!m_db || !m_db->isOpen()) return;
|
||||
|
||||
if (sameChannel)
|
||||
m_lastReadMsgId = m_db->getUiStateInt64(
|
||||
QStringLiteral("ch_%1_last_read").arg(channelId), 0);
|
||||
|
||||
if (!m_db || !m_db->isOpen()) return;
|
||||
|
||||
auto msgs = m_db->getMessages(channelId, 100);
|
||||
@@ -211,7 +226,22 @@ void MessageList::loadChannel(const QString& channelId) {
|
||||
m_model->appendRow(item);
|
||||
}
|
||||
|
||||
restoreScrollPosition(channelId);
|
||||
if (sameChannel) {
|
||||
if (m_wasAtBottom || m_savedTopMsgId == 0)
|
||||
m_view->scrollToBottom();
|
||||
else
|
||||
for (int row = 0; row < m_model->rowCount(); row++)
|
||||
if (m_model->item(row)->data(MsgIdRole).toLongLong() == m_savedTopMsgId) {
|
||||
m_view->scrollTo(m_model->index(row, 0), QAbstractItemView::PositionAtTop);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
m_lastReadMsgId = m_db->getUiStateInt64(
|
||||
QStringLiteral("ch_%1_last_read").arg(channelId), 0);
|
||||
restoreScrollPosition(channelId);
|
||||
}
|
||||
|
||||
m_readDebounce->start();
|
||||
|
||||
if (prevFocus)
|
||||
prevFocus->setFocus();
|
||||
@@ -264,6 +294,8 @@ void MessageList::saveChannelState() {
|
||||
lastPosMsgId = topIdx.data(MsgIdRole).toLongLong();
|
||||
|
||||
qint64 lastReadMsgId = m_lastReadMsgId;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "MessageList::saveChannelState ch=%s read=%lld pos=%lld",
|
||||
qPrintable(m_currentChannelId), (long long)lastReadMsgId, (long long)lastPosMsgId);
|
||||
if (lastReadMsgId == 0 && lastPosMsgId == 0) return;
|
||||
|
||||
QByteArray cid = m_currentChannelId.toUtf8();
|
||||
@@ -326,6 +358,11 @@ void MessageList::updateReadPosition() {
|
||||
newReadMsgId = msgId;
|
||||
}
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG,
|
||||
"MessageList::updateReadPosition ch=%s oldRead=%lld newRead=%lld lastVisRow=%d/%d",
|
||||
qPrintable(m_currentChannelId), (long long)m_lastReadMsgId,
|
||||
(long long)newReadMsgId, lastFullyVisibleRow, m_model->rowCount());
|
||||
|
||||
if (newReadMsgId > m_lastReadMsgId) {
|
||||
m_lastReadMsgId = newReadMsgId;
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ private:
|
||||
QHash<quint64, QColor> m_avatarCache;
|
||||
qint64 m_lastReadMsgId = 0;
|
||||
QTimer* m_readDebounce;
|
||||
qint64 m_savedTopMsgId = 0;
|
||||
bool m_wasAtBottom = false;
|
||||
|
||||
void saveChannelState();
|
||||
void restoreScrollPosition(const QString& channelId);
|
||||
|
||||
Reference in new issue
Block a user