chatgui: remember last read message, restore scroll position, show unread count badge

Store read/scroll positions per channel via ui_state table (key-value).
Draw red +N badge on channel list items for unread messages.
Fix getMessages() to fetch last N messages (was fetching first N).
This commit is contained in:
Evgeny committed 2026-07-23 23:47:35 +03:00
1 parent de14f82048
commit 86d227bffe
10 files changed
+158 -12

No files matched your search

+25 -2
View File
@@ -116,6 +116,9 @@ QList<ChannelRow> DbManager::getChannels() const {
list.append(r);
}
sqlite3_finalize(stmt);
for (auto& ch : list) {
ch.unreadCount = getUnreadCount(ch.channelId, ch.lastReadMsgId);
}
return list;
}
@@ -125,7 +128,7 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit) const {
QList<MessageRow> list;
QString sql = QStringLiteral(
"SELECT id, node_id, data, timestamp, chain_hash, author_signature"
" FROM \"%1\" ORDER BY timestamp, author_signature ASC LIMIT ?").arg(msgTableName(chId));
" FROM \"%1\" ORDER BY timestamp DESC, author_signature DESC LIMIT ?").arg(msgTableName(chId));
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData());
if (!stmt) return list;
sqlite3_bind_int(stmt, 1, limit);
@@ -157,7 +160,7 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit) const {
m.signature = colBlob(stmt, 5);
m.isOutgoing = (m.authorNodeId == myId);
m.isRead = true;
list.append(m);
list.prepend(m);
}
sqlite3_finalize(stmt);
return list;
@@ -383,6 +386,26 @@ int DbManager::getUiStateInt(const QString& key, int defaultVal) const {
return ok ? v : defaultVal;
}
qint64 DbManager::getUiStateInt64(const QString& key, qint64 defaultVal) const {
QString val = getUiState(key);
if (val.isEmpty()) return defaultVal;
bool ok = false;
qint64 v = val.toLongLong(&ok);
return ok ? v : defaultVal;
}
int DbManager::getUnreadCount(const QString& channelId, qint64 lastReadMsgId) const {
QString sql = QStringLiteral(
"SELECT COUNT(*) FROM \"%1\" WHERE id > ?").arg(msgTableName(channelId));
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData());
if (!stmt) return 0;
sqlite3_bind_int64(stmt, 1, lastReadMsgId);
int count = 0;
if (sqlite3_step(stmt) == SQLITE_ROW) count = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
return count;
}
/* ── sync operations (read-only, for gui_bridge) ── */
QByteArray DbManager::syncListChannels() const {