Skip to content

Commit

Permalink
subscription_list: Show @-mention marker when that applies
Browse files Browse the repository at this point in the history
Fixes: zulip#747
  • Loading branch information
Khader-1 committed Sep 11, 2024
1 parent f6aff21 commit 90e493a
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 3 deletions.
22 changes: 22 additions & 0 deletions lib/model/unreads.dart
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,28 @@ class Unreads extends ChangeNotifier {
}
}

Set<int> get channelsWithUnreadMentions {
final channels = <int>{};
for (var messageId in mentions) {
final streamId = _reverseStreamsLookup[messageId]?.streamId;
if (streamId != null) {
channels.add(streamId);
}
}
return channels;
}

Set<int> get channelsWithUnmutedMentions {
final channels = <int>{};
for (var messageId in mentions) {
final info = _reverseStreamsLookup[messageId]!;
if (channelStore.isTopicVisible(info.streamId, info.topic)) {
channels.add(info.streamId);
}
}
return channels;
}

void handleMessageEvent(MessageEvent event) {
final message = event.message;
if (message.flags.contains(MessageFlag.read)) {
Expand Down
18 changes: 15 additions & 3 deletions lib/widgets/subscription_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,24 @@ class _SubscriptionList extends StatelessWidget {

@override
Widget build(BuildContext context) {
final channelsWithMentions = unreadsModel!.channelsWithUnreadMentions;
final channelsWithUnmutedMentions = unreadsModel!.channelsWithUnmutedMentions;
return SliverList.builder(
itemCount: subscriptions.length,
itemBuilder: (BuildContext context, int index) {
final subscription = subscriptions[index];
final unreadCount = unreadsModel!.countInChannel(subscription.streamId);
final showMutedUnreadBadge = unreadCount == 0
&& unreadsModel!.countInChannelNarrow(subscription.streamId) > 0;
final hasMentions = channelsWithMentions.contains(subscription.streamId);
final hasOnlyMutedMentions = !subscription.isMuted
&& channelsWithMentions.contains(subscription.streamId)
&& !channelsWithUnmutedMentions.contains(subscription.streamId);
return SubscriptionItem(subscription: subscription,
unreadCount: unreadCount,
showMutedUnreadBadge: showMutedUnreadBadge);
showMutedUnreadBadge: showMutedUnreadBadge,
hasMentions: hasMentions,
hasOnlyMutedMentions: hasOnlyMutedMentions);
});
}
}
Expand All @@ -206,11 +214,15 @@ class SubscriptionItem extends StatelessWidget {
required this.subscription,
required this.unreadCount,
required this.showMutedUnreadBadge,
required this.hasMentions,
required this.hasOnlyMutedMentions,
});

final Subscription subscription;
final int unreadCount;
final bool showMutedUnreadBadge;
final bool hasMentions;
final bool hasOnlyMutedMentions;

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -258,7 +270,7 @@ class SubscriptionItem extends StatelessWidget {
subscription.name)))),
if (hasUnreads) ...[
const SizedBox(width: 12),
// TODO(#747) show @-mention indicator when it applies
AtMentionMarker(muted: !subscription.isMuted && hasOnlyMutedMentions),
Opacity(
opacity: opacity,
child: UnreadCountBadge(
Expand All @@ -267,7 +279,7 @@ class SubscriptionItem extends StatelessWidget {
bold: true)),
] else if (showMutedUnreadBadge) ...[
const SizedBox(width: 12),
// TODO(#747) show @-mention indicator when it applies
if (hasMentions) const AtMentionMarker(muted: true),
const MutedUnreadBadge(),
],
const SizedBox(width: 16),
Expand Down
42 changes: 42 additions & 0 deletions test/model/unreads_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,48 @@ 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);
});

test('channelsWithUnmutedMentions', () async {
final stream1 = eg.stream();
final stream2 = eg.stream();
final stream3 = eg.stream();
final streams = [stream1, stream2, stream3];

prepare();

await channelStore.addStreams(streams);
await channelStore.addSubscriptions([
eg.subscription(stream1),
eg.subscription(stream2),
eg.subscription(stream3, isMuted: true)]);

await channelStore.addUserTopic(stream1, 'a normal', UserTopicVisibilityPolicy.none);
await channelStore.addUserTopic(stream2, 'b muted', UserTopicVisibilityPolicy.muted);
await channelStore.addUserTopic(stream3, 'c normal', UserTopicVisibilityPolicy.none);


fillWithMessages([
eg.streamMessage(stream: stream1, flags: [MessageFlag.mentioned], topic: 'a normal'),
eg.streamMessage(stream: stream2, flags: [MessageFlag.mentioned], topic: 'b muted'),
eg.streamMessage(stream: stream3, flags: [MessageFlag.mentioned], topic: 'c normal'),
]);

check(model.channelsWithUnmutedMentions.single).equals(stream1.streamId);
});
});

group('DM messages', () {
Expand Down
54 changes: 54 additions & 0 deletions test/widgets/subscription_list_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,58 @@ void main() {
checkStreamNameWght(mutedStreamWithUnmutedUnreads.name, 400);
checkStreamNameWght(mutedStreamWithNoUnmutedUnreads.name, 400);
});

group('@-mention marker', () {
Iterable<AtMentionMarker> getAtMentionMarkers(WidgetTester tester) {
return tester.widgetList<AtMentionMarker>(find.byType(AtMentionMarker));
}

testWidgets('is shown when subscription has unread mentions', (tester) async {
final streamWithMentions = eg.stream();
final streamWithNoMentions = eg.stream();

await setupStreamListPage(tester,
subscriptions: [
eg.subscription(streamWithMentions),
eg.subscription(streamWithNoMentions),
],
userTopics: [
eg.userTopicItem(streamWithMentions, 'a', UserTopicVisibilityPolicy.none),
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]),
]),
);

check(getAtMentionMarkers(tester)).single;
});

testWidgets('is muted when subscription has only muted mentions', (tester) async {
final streamWithMentions = eg.stream();
final streamWithOnlyMutedMentions = eg.stream();

await setupStreamListPage(tester,
subscriptions: [
eg.subscription(streamWithMentions),
eg.subscription(streamWithOnlyMutedMentions, isMuted: true),
],
userTopics: [
eg.userTopicItem(streamWithMentions, 'a', UserTopicVisibilityPolicy.none),
eg.userTopicItem(streamWithOnlyMutedMentions, 'b', UserTopicVisibilityPolicy.none),
],
unreadMsgs: eg.unreadMsgs(
mentions: [1, 2],
channels: [
UnreadChannelSnapshot(streamId: streamWithMentions.streamId, topic: 'a', unreadMessageIds: [1]),
UnreadChannelSnapshot(streamId: streamWithOnlyMutedMentions.streamId, topic: 'b', unreadMessageIds: [2]),
]),
);

check(getAtMentionMarkers(tester).map((e) => e.muted)).deepEquals([false, true]);
});
});
}

0 comments on commit 90e493a

Please sign in to comment.