diff --git a/mobile/lib/features/channels/me/me_chat_assistant.dart b/mobile/lib/features/channels/me/me_chat_assistant.dart index 53683a36abe..c21c361065f 100644 --- a/mobile/lib/features/channels/me/me_chat_assistant.dart +++ b/mobile/lib/features/channels/me/me_chat_assistant.dart @@ -106,25 +106,25 @@ useMeChatAssistant( } } // The owner's inventory name outranks the agent's self-published profile. - final names = watchMeAssistantNames( - ref, - agents, - saved: [selected, pending?.agent], - ); + // Only Solo reads these names; other chats must not watch every profile. + final names = enabled + ? watchMeAssistantNames(ref, agents, saved: [selected, pending?.agent]) + : null; // A known agent outside the inventory, such as an archived one, is labeled // against the live agents so it never reads as a live namesake. bool named(String pubkey) => - agents.any((agent) => agent.pubkey == pubkey) || - ref.read(userCacheProvider)[pubkey]?.displayName?.trim().isNotEmpty == - true; + names != null && + (agents.any((agent) => agent.pubkey == pubkey) || + ref.read(userCacheProvider)[pubkey]?.displayName?.trim().isNotEmpty == + true); final name = selected != null && named(selected) - ? names.labelFor(selected) + ? names!.labelFor(selected) : profile?.displayName; final avatarInitial = name?.trim().isNotEmpty == true ? name!.trim()[0].toUpperCase() : profile?.initial ?? '?'; String agentName(String pubkey) { - if (named(pubkey)) return names.labelFor(pubkey); + if (named(pubkey)) return names!.labelFor(pubkey); return pubkey.length > 12 ? '${pubkey.substring(0, 8)}…${pubkey.substring(pubkey.length - 4)}' : pubkey; diff --git a/mobile/test/features/channels/channel_detail_page_test.dart b/mobile/test/features/channels/channel_detail_page_test.dart index 7757af969f0..a9aef130cab 100644 --- a/mobile/test/features/channels/channel_detail_page_test.dart +++ b/mobile/test/features/channels/channel_detail_page_test.dart @@ -5033,8 +5033,10 @@ void main() { _testChannel, otherChannel, ]); + final profiles = _FakeUserCacheNotifier({}); await tester.pumpWidget( _buildTestable( + userCacheNotifier: profiles, messages: [ for (var i = 0; i < 5; i++) _textMsg( @@ -5062,6 +5064,22 @@ void main() { await tester.pumpAndSettle(); expect(rebuilt.whereType(), isEmpty); + + // A profile learned in another surface must not rebuild this ordinary + // channel: the Solo naming hook is disabled here. + rebuilt.clear(); + profiles.replace( + UserProfile(pubkey: 'f' * 64, displayName: 'Unrelated profile'), + ); + await tester.pumpAndSettle(); + expect( + rebuilt.where( + (widget) => + widget.runtimeType.toString() == '_ResolvedChannelDetailPage', + ), + isEmpty, + reason: 'an unrelated profile must not rebuild the open channel page', + ); }); testWidgets('clears the composer inset when membership is revoked', (