Skip to content

Commit

Permalink
home: Sort leading emoji first in channel names
Browse files Browse the repository at this point in the history
Update the channel sorting logic to match the channels order
of web by putting emoji-prefixed channels first.

Fixes: #1202
  • Loading branch information
lakshya1goel committed Jan 18, 2025
1 parent 5e8d0a8 commit 0c567a3
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 emoji in name are listed above non-emoji names', (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 emoji in name, 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 0c567a3

Please sign in to comment.