From a816b842e5da5ee11679e7fc86ddbf9b293a1dd7 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 6 Oct 2026 13:43:49 +0200 Subject: [PATCH] Read group avatar metadata separately from image bytes --- src/chat/group_avatar.c | 6 +++--- tools/chatgui/db/db_manager.cpp | 14 +++++++++++++- tools/chatgui/db/db_manager.h | 3 +++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/chat/group_avatar.c b/src/chat/group_avatar.c index 9cc0a0b9..8a453eb1 100644 --- a/src/chat/group_avatar.c +++ b/src/chat/group_avatar.c @@ -173,7 +173,7 @@ static int ga_allowed(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t peer) if (!member_files_member(inst, group, inst->node_id, 0) || !member_files_member(inst, group, peer, 0)) return 0; struct TOPO_GROUP* g = topo_groups_find(inst->topo_groups, group); for (struct ll_entry* e = g && g->senders_list ? g->senders_list->head : NULL; e; e = e->next) { - struct TOPO_GROUP_CONN_ITEM* item = e->data; + struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data; if (item && item->node_id == peer && item->conn && item->ready_notified && !item->transport_down) return 1; } return 0; @@ -340,9 +340,9 @@ static void ga_tick(void* arg) { for (struct ga_peer* p = ctx->peers; p; p = p->next) p->seen = 0; for (struct ll_entry* ge = ctx->inst->topo_groups->group_list->head; ge; ge = ge->next) { struct TOPO_GROUP* group = (struct TOPO_GROUP*)ge; - if (group->group_type != TOPO_GROUP_TYPE_CHAT) continue; + if (group->group_type != TOPO_GROUP_TYPE_CHAT || !group->senders_list) continue; for (struct ll_entry* e = group->senders_list->head; e; e = e->next) { - struct TOPO_GROUP_CONN_ITEM* item = e->data; + struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data; if (!item || !item->conn || !item->ready_notified || item->transport_down || !ga_allowed(ctx->inst, group->group_id, item->node_id)) continue; struct ga_peer* p = ga_find(ctx, group->group_id, item->node_id, 1); if (!p) continue; p->seen = 1; diff --git a/tools/chatgui/db/db_manager.cpp b/tools/chatgui/db/db_manager.cpp index 02c39562..88bdf588 100644 --- a/tools/chatgui/db/db_manager.cpp +++ b/tools/chatgui/db/db_manager.cpp @@ -113,7 +113,7 @@ QList DbManager::getChannels(ChannelSortMode sort) const { char sql[512]; snprintf(sql, sizeof(sql), "SELECT channel_id, name, owner_node_id," " x25519_pubkey, x25519_privkey, ed25519_pubkey, ed25519_privkey, signature," - " last_read_msg_id, last_pos_msg_id, last_msg_at, created_at" + " last_read_msg_id, last_pos_msg_id, last_msg_at, created_at,avatar_version,avatar_hash" " FROM channels%s", orderBy); sqlite3_stmt* stmt = prepareOrNull(sql); if (!stmt) return list; @@ -131,6 +131,8 @@ QList DbManager::getChannels(ChannelSortMode sort) const { r.lastPosMsgId = sqlite3_column_int64(stmt, 9); r.lastMsgAt = sqlite3_column_int64(stmt, 10); r.createdAt = sqlite3_column_int64(stmt, 11); + r.avatarVersion = (quint64)sqlite3_column_int64(stmt, 12); + r.avatarHash = colBlob(stmt, 13); list.append(r); } sqlite3_finalize(stmt); @@ -144,6 +146,16 @@ QList DbManager::getChannels(ChannelSortMode sort) const { return list; } +QByteArray DbManager::getChannelAvatar(const QString& channelId) const { + sqlite3_stmt* st = prepareOrNull("SELECT avatar_data FROM channels WHERE channel_id=?"); if (!st) return {}; + const QByteArray id = channelId.toLatin1(); sqlite3_bind_text(st, 1, id.constData(), id.size(), SQLITE_TRANSIENT); + QByteArray bytes; + int rc = sqlite3_step(st); + if (rc == SQLITE_ROW) bytes = colBlob(st, 0); + else if (rc != SQLITE_DONE) GUI_ERROR("group avatar: database read failed channel=%s rc=%d", qPrintable(channelId), rc); + sqlite3_finalize(st); return bytes; +} + bool DbManager::isChannelMember(const QString& chId, quint64 nodeId) const { const QByteArray sql = QStringLiteral("SELECT 1 FROM \"%1\" WHERE node_id=?").arg(peersTableName(chId)).toUtf8(); sqlite3_stmt* statement = prepareOrNull(sql.constData()); diff --git a/tools/chatgui/db/db_manager.h b/tools/chatgui/db/db_manager.h index da73f76f..5153e7f7 100644 --- a/tools/chatgui/db/db_manager.h +++ b/tools/chatgui/db/db_manager.h @@ -29,6 +29,8 @@ struct ChannelRow { qint64 lastMsgAt = 0; qint64 createdAt = 0; int unreadCount = 0; + quint64 avatarVersion = 0; + QByteArray avatarHash; }; struct MessageRow { @@ -95,6 +97,7 @@ public: /* ── Каналы ── */ QList getChannels(ChannelSortMode sort = ChannelSortMode::Alphabetical) const; + QByteArray getChannelAvatar(const QString& channelId) const; QString getChannelLastMessage(const QString& channelId) const; int getUnreadCount(const QString& channelId, qint64 lastReadMsgId) const;