From 838e874493bf426cbc9bce1647c4fe567e5a5ae6 Mon Sep 17 00:00:00 2001 From: Khader M Khudair Date: Fri, 9 Aug 2024 23:25:58 +0300 Subject: [PATCH] subscription_list: Show @-mention indicator when it applies Fixes: #747 --- lib/model/unreads.dart | 11 ++++++++++ lib/widgets/subscription_list.dart | 17 +++++++++++--- test/model/unreads_test.dart | 14 ++++++++++++ test/widgets/subscription_list_test.dart | 28 ++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/lib/model/unreads.dart b/lib/model/unreads.dart index a115d0d4b3..fc5d1dbd0d 100644 --- a/lib/model/unreads.dart +++ b/lib/model/unreads.dart @@ -219,6 +219,17 @@ class Unreads extends ChangeNotifier { } } + Set get channelsWithUnreadMentions { + final channels = {}; + for (var messageId in mentions) { + final streamId = _reverseStreamsLookup[messageId]?.streamId; + if (streamId != null) { + channels.add(streamId); + } + } + return channels; + } + void handleMessageEvent(MessageEvent event) { final message = event.message; if (message.flags.contains(MessageFlag.read)) { diff --git a/lib/widgets/subscription_list.dart b/lib/widgets/subscription_list.dart index c8838e9c5f..5640e103fd 100644 --- a/lib/widgets/subscription_list.dart +++ b/lib/widgets/subscription_list.dart @@ -184,6 +184,7 @@ class _SubscriptionList extends StatelessWidget { @override Widget build(BuildContext context) { + final channelsWithMentions = unreadsModel!.channelsWithUnreadMentions; return SliverList.builder( itemCount: subscriptions.length, itemBuilder: (BuildContext context, int index) { @@ -191,9 +192,11 @@ class _SubscriptionList extends StatelessWidget { final unreadCount = unreadsModel!.countInChannel(subscription.streamId); final showMutedUnreadBadge = unreadCount == 0 && unreadsModel!.countInChannelNarrow(subscription.streamId) > 0; + final hasMentions = channelsWithMentions.contains(subscription.streamId); return SubscriptionItem(subscription: subscription, unreadCount: unreadCount, - showMutedUnreadBadge: showMutedUnreadBadge); + showMutedUnreadBadge: showMutedUnreadBadge, + hasMentions: hasMentions); }); } } @@ -205,11 +208,13 @@ class SubscriptionItem extends StatelessWidget { required this.subscription, required this.unreadCount, required this.showMutedUnreadBadge, + required this.hasMentions, }); final Subscription subscription; final int unreadCount; final bool showMutedUnreadBadge; + final bool hasMentions; @override Widget build(BuildContext context) { @@ -257,7 +262,10 @@ class SubscriptionItem extends StatelessWidget { subscription.name)))), if (hasUnreads) ...[ const SizedBox(width: 12), - // TODO(#747) show @-mention indicator when it applies + if (hasMentions) ...[ + const Text('@'), + const SizedBox(width: 8), + ], Opacity( opacity: opacity, child: UnreadCountBadge( @@ -266,7 +274,10 @@ class SubscriptionItem extends StatelessWidget { bold: true)), ] else if (showMutedUnreadBadge) ...[ const SizedBox(width: 12), - // TODO(#747) show @-mention indicator when it applies + if (hasMentions) ...[ + const Text('@'), + const SizedBox(width: 8), + ], const MutedUnreadBadge(), ], const SizedBox(width: 16), diff --git a/test/model/unreads_test.dart b/test/model/unreads_test.dart index b35f5c770e..b9866f4b21 100644 --- a/test/model/unreads_test.dart +++ b/test/model/unreads_test.dart @@ -298,6 +298,20 @@ void main() { }); } }); + + test('channelsWithUnreadMentions', () { + final stream1 = eg.stream(); + final stream2 = eg.stream(); + + prepare(); + fillWithMessages([ + eg.streamMessage(stream: stream1, flags: [MessageFlag.mentioned]), + eg.streamMessage(stream: stream1, flags: []), + eg.streamMessage(stream: stream2, flags: []), + ]); + + check(model.channelsWithUnreadMentions.single).equals(stream1.streamId); + }); }); group('DM messages', () { diff --git a/test/widgets/subscription_list_test.dart b/test/widgets/subscription_list_test.dart index 9909dc09e9..3f3fd17666 100644 --- a/test/widgets/subscription_list_test.dart +++ b/test/widgets/subscription_list_test.dart @@ -315,4 +315,32 @@ void main() { checkStreamNameWght(mutedStreamWithUnmutedUnreads.name, 400); checkStreamNameWght(mutedStreamWithNoUnmutedUnreads.name, 400); }); + + testWidgets('@-mention indicator is shown when subscription has unread mentions', (tester) async { + void checkMentionIndicatorsCount(int expectedCount) { + check(find.text('@').evaluate().length).equals(expectedCount); + } + + final streamWithMentions = eg.stream(); + final streamWithNoMentions = eg.stream(); + + await setupStreamListPage(tester, + subscriptions: [ + eg.subscription(streamWithMentions), + eg.subscription(streamWithNoMentions), + ], + userTopics: [ + eg.userTopicItem(streamWithMentions, 'a', UserTopicVisibilityPolicy.unmuted), + eg.userTopicItem(streamWithNoMentions, 'b', UserTopicVisibilityPolicy.muted), + ], + unreadMsgs: eg.unreadMsgs( + mentions: [1], + channels: [ + UnreadChannelSnapshot(streamId: streamWithMentions.streamId, topic: 'a', unreadMessageIds: [1]), + UnreadChannelSnapshot(streamId: streamWithNoMentions.streamId, topic: 'b', unreadMessageIds: [2]), + ]), + ); + + checkMentionIndicatorsCount(1); + }); }