Skip to content

Commit

Permalink
home: Sort leading emoji first in channel names
Browse files Browse the repository at this point in the history
Fixes: #1202
  • Loading branch information
lakshya1goel committed Jan 22, 2025
1 parent 5e8d0a8 commit 79e0820
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/widgets/subscription_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,22 @@ class _SubscriptionListPageBodyState extends State<SubscriptionListPageBody> wit
});
}

final _startsWithEmojiRegex = RegExp(r'^\p{Emoji}', unicode: true);

void _sortSubs(List<Subscription> list) {
list.sort((a, b) {
if (a.isMuted && !b.isMuted) return 1;
if (!a.isMuted && b.isMuted) return -1;

// A user gave feedback wanting zulip-flutter to match web in putting
// emoji-prefixed channels first; see #1202.
// For matching web's ordering completely, see:
// https://github.com/zulip/zulip-flutter/issues/1165
final aStartsWithEmoji = _startsWithEmojiRegex.hasMatch(a.name);
final bStartsWithEmoji = _startsWithEmojiRegex.hasMatch(b.name);
if (aStartsWithEmoji && !bStartsWithEmoji) return -1;
if (!aStartsWithEmoji && bStartsWithEmoji) return 1;

// TODO(i18n): add locale-aware sorting
return a.name.toLowerCase().compareTo(b.name.toLowerCase());
});
Expand Down
26 changes: 26 additions & 0 deletions test/widgets/subscription_list_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,32 @@ void main() {
]);
check(listedStreamIds(tester)).deepEquals([2, 1, 3, 4, 6, 5]);
});

testWidgets('channels with names starting with an emoji are above channel names that do not start with an emoji', (tester) async {
await setupStreamListPage(tester, subscriptions: [
eg.subscription(eg.stream(streamId: 1, name: 'Happy 😊 Stream')),
eg.subscription(eg.stream(streamId: 2, name: 'Alpha Stream')),
eg.subscription(eg.stream(streamId: 3, name: '🚀 Rocket Stream')),
eg.subscription(eg.stream(streamId: 4, name: 'Beta Stream')),
]);

check(listedStreamIds(tester)).deepEquals([3, 2, 4, 1]);
});

testWidgets('channels with names starting with an emoji, pinned, unpinned, muted, and unmuted are sorted correctly', (tester) async {
await setupStreamListPage(tester, subscriptions: [
eg.subscription(eg.stream(streamId: 1, name: '😊 Happy Stream'), pinToTop: true, isMuted: false),
eg.subscription(eg.stream(streamId: 2, name: '🚀 Rocket Stream'), pinToTop: true, isMuted: true),
eg.subscription(eg.stream(streamId: 3, name: 'Alpha Stream'), pinToTop: true, isMuted: false),
eg.subscription(eg.stream(streamId: 4, name: 'Beta Stream'), pinToTop: true, isMuted: true),
eg.subscription(eg.stream(streamId: 5, name: '🌟 Star Stream'), pinToTop: false, isMuted: false),
eg.subscription(eg.stream(streamId: 6, name: '🔥 Fire Stream'), pinToTop: false, isMuted: true),
eg.subscription(eg.stream(streamId: 7, name: 'Gamma Stream'), pinToTop: false, isMuted: false),
eg.subscription(eg.stream(streamId: 8, name: 'Delta Stream'), pinToTop: false, isMuted: true),
]);

check(listedStreamIds(tester)).deepEquals([1, 3, 2, 4, 5, 7, 6, 8]);
});
});

testWidgets('unread badge shows with unreads', (tester) async {
Expand Down

0 comments on commit 79e0820

Please sign in to comment.