From 8173677475793b16bf965fea7bdb233fba2b4993 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 6 Oct 2026 13:04:57 +0200 Subject: [PATCH] Avoid refreshing avatar controls on unchanged member telemetry --- tools/chatgui/src/avatars/avatarmanager.cpp | 14 ++++++++++---- tools/chatgui/tests/test_avatars.cpp | 7 +++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tools/chatgui/src/avatars/avatarmanager.cpp b/tools/chatgui/src/avatars/avatarmanager.cpp index 38b9b76d..858deb23 100644 --- a/tools/chatgui/src/avatars/avatarmanager.cpp +++ b/tools/chatgui/src/avatars/avatarmanager.cpp @@ -92,6 +92,7 @@ void AvatarManager::onMembers(const QString& channel, int count, const uint8_t* return; } QSet seen; + const auto previousServers = m_servers.value(group); bool referencesChanged = false; if (full) m_servers[group].clear(); for (int i = 0; i < count; i++) { chat_member_display member{}; chat_core_deserialize_member(data + i * CHAT_MEMBER_DISPLAY_SIZE, &member); @@ -103,19 +104,24 @@ void AvatarManager::onMembers(const QString& channel, int count, const uint8_t* if (!ref.server || !mf_avatar_file_valid(member.avatar_file)) { ref.server = 0; ref.hash.clear(); } const Ref old = m_refs.value(context); m_refs[context] = ref; if (old.hash != ref.hash || old.server != ref.server) { + referencesChanged = true; m_retry.remove(context); m_failures.remove(context); emit changed(channel, ref.owner); } } if (full) for (const auto& context : m_refs.keys()) if (m_refs[context].group == group && !seen.contains(context)) removeMember(channel, m_refs[context].owner); - emit serversChanged(); scheduleOwn(group); pump(); - DEBUG_DEBUG(DEBUG_CATEGORY_MEDIA, "avatar: member snapshot channel=%s count=%d full=%d servers=%d refs=%d", - qPrintable(channel), count, int(full), m_servers.value(group).size(), m_refs.size()); + const bool serversChangedNow = previousServers != m_servers.value(group); + if (serversChangedNow) emit serversChanged(); + scheduleOwn(group); pump(); + if (full || referencesChanged || serversChangedNow) + DEBUG_DEBUG(DEBUG_CATEGORY_MEDIA, "avatar: member snapshot channel=%s count=%d full=%d servers=%d refs=%d", + qPrintable(channel), count, int(full), m_servers.value(group).size(), m_refs.size()); } void AvatarManager::removeMember(const QString& channel, quint64 owner) { const quint64 group = channel.toULongLong(); const QString context = key(group, owner); - m_refs.remove(context); m_wanted.remove(context); m_servers[group].remove(owner); + m_refs.remove(context); m_wanted.remove(context); + if (m_servers[group].remove(owner)) emit serversChanged(); emit changed(channel, owner); } diff --git a/tools/chatgui/tests/test_avatars.cpp b/tools/chatgui/tests/test_avatars.cpp index 25520fdb..04c53a35 100644 --- a/tools/chatgui/tests/test_avatars.cpp +++ b/tools/chatgui/tests/test_avatars.cpp @@ -108,6 +108,13 @@ private slots: { AvatarManager manager(&db); manager.initialize(); QTRY_COMPARE_WITH_TIMEOUT(manager.servers().size(), 1, 5000); + QSignalSpy unchangedServers(&manager, &AvatarManager::serversChanged); + for (const auto& channel : channels) { + uint8_t wire[CHAT_MEMBER_DISPLAY_SIZE]; + QCOMPARE(chat_core_get_single_member(testInstance, channel.channelId.toLatin1().constData(), testInstance->node_id, wire), 0); + manager.onMembers(channel.channelId, 1, wire, sizeof(wire), false); + } + QCOMPARE(unchangedServers.count(), 0); manager.uploadDefault(source, testInstance->node_id); QTRY_VERIFY_WITH_TIMEOUT(!manager.defaultImage().isNull(), 5000); for (const auto& channel : channels) {