Browse Source

Read group avatar metadata separately from image bytes

master
evgeny 6 days ago
parent
commit
a816b842e5
  1. 6
      src/chat/group_avatar.c
  2. 14
      tools/chatgui/db/db_manager.cpp
  3. 3
      tools/chatgui/db/db_manager.h

6
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; 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); 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) { 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; if (item && item->node_id == peer && item->conn && item->ready_notified && !item->transport_down) return 1;
} }
return 0; 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 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) { for (struct ll_entry* ge = ctx->inst->topo_groups->group_list->head; ge; ge = ge->next) {
struct TOPO_GROUP* group = (struct TOPO_GROUP*)ge; 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) { 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; 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; struct ga_peer* p = ga_find(ctx, group->group_id, item->node_id, 1); if (!p) continue;
p->seen = 1; p->seen = 1;

14
tools/chatgui/db/db_manager.cpp

@ -113,7 +113,7 @@ QList<ChannelRow> DbManager::getChannels(ChannelSortMode sort) const {
char sql[512]; snprintf(sql, sizeof(sql), char sql[512]; snprintf(sql, sizeof(sql),
"SELECT channel_id, name, owner_node_id," "SELECT channel_id, name, owner_node_id,"
" x25519_pubkey, x25519_privkey, ed25519_pubkey, ed25519_privkey, signature," " 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); " FROM channels%s", orderBy);
sqlite3_stmt* stmt = prepareOrNull(sql); sqlite3_stmt* stmt = prepareOrNull(sql);
if (!stmt) return list; if (!stmt) return list;
@ -131,6 +131,8 @@ QList<ChannelRow> DbManager::getChannels(ChannelSortMode sort) const {
r.lastPosMsgId = sqlite3_column_int64(stmt, 9); r.lastPosMsgId = sqlite3_column_int64(stmt, 9);
r.lastMsgAt = sqlite3_column_int64(stmt, 10); r.lastMsgAt = sqlite3_column_int64(stmt, 10);
r.createdAt = sqlite3_column_int64(stmt, 11); r.createdAt = sqlite3_column_int64(stmt, 11);
r.avatarVersion = (quint64)sqlite3_column_int64(stmt, 12);
r.avatarHash = colBlob(stmt, 13);
list.append(r); list.append(r);
} }
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
@ -144,6 +146,16 @@ QList<ChannelRow> DbManager::getChannels(ChannelSortMode sort) const {
return list; 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 { bool DbManager::isChannelMember(const QString& chId, quint64 nodeId) const {
const QByteArray sql = QStringLiteral("SELECT 1 FROM \"%1\" WHERE node_id=?").arg(peersTableName(chId)).toUtf8(); const QByteArray sql = QStringLiteral("SELECT 1 FROM \"%1\" WHERE node_id=?").arg(peersTableName(chId)).toUtf8();
sqlite3_stmt* statement = prepareOrNull(sql.constData()); sqlite3_stmt* statement = prepareOrNull(sql.constData());

3
tools/chatgui/db/db_manager.h

@ -29,6 +29,8 @@ struct ChannelRow {
qint64 lastMsgAt = 0; qint64 lastMsgAt = 0;
qint64 createdAt = 0; qint64 createdAt = 0;
int unreadCount = 0; int unreadCount = 0;
quint64 avatarVersion = 0;
QByteArray avatarHash;
}; };
struct MessageRow { struct MessageRow {
@ -95,6 +97,7 @@ public:
/* ── Каналы ── */ /* ── Каналы ── */
QList<ChannelRow> getChannels(ChannelSortMode sort = ChannelSortMode::Alphabetical) const; QList<ChannelRow> getChannels(ChannelSortMode sort = ChannelSortMode::Alphabetical) const;
QByteArray getChannelAvatar(const QString& channelId) const;
QString getChannelLastMessage(const QString& channelId) const; QString getChannelLastMessage(const QString& channelId) const;
int getUnreadCount(const QString& channelId, qint64 lastReadMsgId) const; int getUnreadCount(const QString& channelId, qint64 lastReadMsgId) const;

Loading…
Cancel
Save