Skip to content

Commit 46ac2f3

Browse files
committed
home: Sort leading emoji first in channel names
Update the channel sorting logic to ensure streams with leading emojis in their names are listed above those without emojis. The updated sorting respects pinned, muted, and unmuted streams while handling emoji precedence and maintaining alphabetical order for ties. Fixes: zulip#1202
1 parent 3ff7096 commit 46ac2f3

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

lib/widgets/subscription_list.dart

+24
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,35 @@ class _SubscriptionListPageBodyState extends State<SubscriptionListPageBody> wit
4545
list.sort((a, b) {
4646
if (a.isMuted && !b.isMuted) return 1;
4747
if (!a.isMuted && b.isMuted) return -1;
48+
49+
final isEmojiA = _startsWithEmoji(a.name);
50+
final isEmojiB = _startsWithEmoji(b.name);
51+
if (isEmojiA != isEmojiB) {
52+
return isEmojiA ? -1 : 1;
53+
}
54+
4855
// TODO(i18n): add locale-aware sorting
4956
return a.name.toLowerCase().compareTo(b.name.toLowerCase());
5057
});
5158
}
5259

60+
bool _startsWithEmoji(String name) {
61+
final firstChar = name.characters.first;
62+
final int firstCharCode = firstChar.runes.first;
63+
64+
return (firstCharCode >= 0x1F600 && firstCharCode <= 0x1F64F) || // Emoticons
65+
(firstCharCode >= 0x1F300 && firstCharCode <= 0x1F5FF) || // Misc Symbols and Pictographs
66+
(firstCharCode >= 0x1F680 && firstCharCode <= 0x1F6FF) || // Transport and Map
67+
(firstCharCode >= 0x1F700 && firstCharCode <= 0x1F77F) || // Alchemical Symbols
68+
(firstCharCode >= 0x2600 && firstCharCode <= 0x26FF) || // Misc Symbols
69+
(firstCharCode >= 0x2700 && firstCharCode <= 0x27BF) || // Dingbats
70+
(firstCharCode >= 0xFE00 && firstCharCode <= 0xFE0F) || // Variation Selectors
71+
(firstCharCode >= 0x1F900 && firstCharCode <= 0x1F9FF) || // Supplemental Symbols and Pictographs
72+
(firstCharCode >= 0x1FA70 && firstCharCode <= 0x1FAFF) || // Symbols and Pictographs Extended-A
73+
(firstCharCode >= 0x1F1E6 && firstCharCode <= 0x1F1FF) || // Flags
74+
(firstCharCode >= 0x1F000 && firstCharCode <= 0x1FFFF); // Supplementary Multilingual Plane
75+
}
76+
5377
@override
5478
Widget build(BuildContext context) {
5579
// Design referenced from:

test/widgets/subscription_list_test.dart

+26
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,32 @@ void main() {
150150
]);
151151
check(listedStreamIds(tester)).deepEquals([2, 1, 3, 4, 6, 5]);
152152
});
153+
154+
testWidgets('channels with emoji in name are listed above non-emoji names', (tester) async {
155+
await setupStreamListPage(tester, subscriptions: [
156+
eg.subscription(eg.stream(streamId: 1, name: '😊 Happy Stream')),
157+
eg.subscription(eg.stream(streamId: 2, name: 'Alpha Stream')),
158+
eg.subscription(eg.stream(streamId: 3, name: '🚀 Rocket Stream')),
159+
eg.subscription(eg.stream(streamId: 4, name: 'Beta Stream')),
160+
]);
161+
162+
check(listedStreamIds(tester)).deepEquals([1, 3, 2, 4]);
163+
});
164+
165+
testWidgets('channels with emoji in name, pinned, unpinned, muted, and unmuted are sorted correctly', (tester) async {
166+
await setupStreamListPage(tester, subscriptions: [
167+
eg.subscription(eg.stream(streamId: 1, name: '😊 Happy Stream'), pinToTop: true, isMuted: false),
168+
eg.subscription(eg.stream(streamId: 2, name: '🚀 Rocket Stream'), pinToTop: true, isMuted: true),
169+
eg.subscription(eg.stream(streamId: 3, name: 'Alpha Stream'), pinToTop: true, isMuted: false),
170+
eg.subscription(eg.stream(streamId: 4, name: 'Beta Stream'), pinToTop: true, isMuted: true),
171+
eg.subscription(eg.stream(streamId: 5, name: '🌟 Star Stream'), pinToTop: false, isMuted: false),
172+
eg.subscription(eg.stream(streamId: 6, name: '🔥 Fire Stream'), pinToTop: false, isMuted: true),
173+
eg.subscription(eg.stream(streamId: 7, name: 'Gamma Stream'), pinToTop: false, isMuted: false),
174+
eg.subscription(eg.stream(streamId: 8, name: 'Delta Stream'), pinToTop: false, isMuted: true),
175+
]);
176+
177+
check(listedStreamIds(tester)).deepEquals([1,3,2,4,5,7,6,8]);
178+
});
153179
});
154180

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

0 commit comments

Comments
 (0)