Skip to content

Commit 711d659

Browse files
committed
unreads: Fix topic case-sensitivity.
Maps canoncalized topic names to a variant of the actual topic name. Fixes #980.
1 parent 449f326 commit 711d659

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

lib/model/unreads.dart

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ class Unreads extends ChangeNotifier {
4242
}) {
4343
final streams = <int, Map<TopicName, QueueList<int>>>{};
4444
final dms = <DmNarrow, QueueList<int>>{};
45+
// Maps the lowercased version of topic to one of the actual versions
46+
final topicMapper = <String, TopicName>{};
4547
final mentions = Set.of(initial.mentions);
4648

4749
for (final unreadChannelSnapshot in initial.channels) {
4850
final streamId = unreadChannelSnapshot.streamId;
4951
final topic = unreadChannelSnapshot.topic;
52+
topicMapper[topic.canonicalize()] = topic;
5053
(streams[streamId] ??= {})[topic] = QueueList.from(unreadChannelSnapshot.unreadMessageIds);
5154
}
5255

@@ -64,6 +67,7 @@ class Unreads extends ChangeNotifier {
6467
return Unreads._(
6568
channelStore: channelStore,
6669
streams: streams,
70+
topicMapper: topicMapper,
6771
dms: dms,
6872
mentions: mentions,
6973
oldUnreadsMissing: initial.oldUnreadsMissing,
@@ -74,6 +78,7 @@ class Unreads extends ChangeNotifier {
7478
Unreads._({
7579
required this.channelStore,
7680
required this.streams,
81+
required this.topicMapper,
7782
required this.dms,
7883
required this.mentions,
7984
required this.oldUnreadsMissing,
@@ -91,6 +96,9 @@ class Unreads extends ChangeNotifier {
9196
/// Unread DM messages, as: DM narrow → message IDs (sorted).
9297
final Map<DmNarrow, QueueList<int>> dms;
9398

99+
// Maps lowercase topic names for lookup to one of the variants of the topic (case preserving).
100+
final Map<String, TopicName> topicMapper;
101+
94102
/// Unread messages with the self-user @-mentioned, directly or by wildcard.
95103
///
96104
/// At initialization, if a message is:
@@ -380,9 +388,19 @@ class Unreads extends ChangeNotifier {
380388
}
381389
switch (detail.type) {
382390
case MessageType.stream:
391+
final topicKey = detail.topic!.canonicalize();
392+
TopicName actualTopicName;
393+
if (topicMapper[topicKey] != null) {
394+
actualTopicName = topicMapper[topicKey] as TopicName;
395+
} else {
396+
topicMapper[topicKey] = detail.topic!;
397+
actualTopicName = detail.topic!;
398+
}
399+
383400
final topics = (newlyUnreadInStreams[detail.streamId!] ??= {});
384-
final messageIds = (topics[detail.topic!] ??= QueueList());
401+
final messageIds = (topics[actualTopicName!] ??= QueueList());
385402
messageIds.add(messageId);
403+
386404
case MessageType.direct:
387405
final narrow = DmNarrow.ofUpdateMessageFlagsMessageDetail(selfUserId: selfUserId,
388406
detail);
@@ -450,7 +468,12 @@ class Unreads extends ChangeNotifier {
450468
}
451469

452470
void _addLastInStreamTopic(int messageId, int streamId, TopicName topic) {
453-
((streams[streamId] ??= {})[topic] ??= QueueList()).addLast(messageId);
471+
if (topicMapper[topic.canonicalize()] != null && topic.isSameAs(topicMapper[topic.canonicalize()]!)) {
472+
((streams[streamId] ??= {})[topicMapper[topic.canonicalize()]!] ??= QueueList()).addLast(messageId);
473+
} else {
474+
topicMapper[topic.canonicalize()] = topic;
475+
((streams[streamId] ??= {})[topic] ??= QueueList()).addLast(messageId);
476+
}
454477
}
455478

456479
// [messageIds] must be sorted ascending and without duplicates.

lib/widgets/inbox.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class _InboxPageState extends State<InboxPageBody> with PerAccountStoreAwareStat
136136
int countInStream = 0;
137137
bool streamHasMention = false;
138138
for (final MapEntry(key: topic, value: messageIds) in topics.entries) {
139-
if (!store.isTopicVisible(streamId, topic)) continue;
139+
if (!store.isTopicVisible(streamId, unreadsModel!=null ? (unreadsModel?.topicMapper[topic.canonicalize()])! : topic!)) continue;
140140
final countInTopic = messageIds.length;
141141
final hasMention = messageIds.any((messageId) => unreadsModel!.mentions.contains(messageId));
142142
if (hasMention) streamHasMention = true;

test/model/unreads_test.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ void main() {
6060

6161
final Map<int, Map<TopicName, QueueList<int>>> expectedStreams = {};
6262
final Map<DmNarrow, QueueList<int>> expectedDms = {};
63+
final Map<String, TopicName> topicMapper = {};
6364
final Set<int> expectedMentions = {};
6465
for (final message in messages) {
6566
if (message.flags.contains(MessageFlag.read)) {
@@ -68,7 +69,10 @@ void main() {
6869
switch (message) {
6970
case StreamMessage():
7071
final perTopic = expectedStreams[message.streamId] ??= {};
71-
final messageIds = perTopic[message.topic] ??= QueueList();
72+
if (topicMapper[message.topic.canonicalize()] == null) {
73+
topicMapper[message.topic.canonicalize()] = message.topic;
74+
}
75+
final messageIds = perTopic[topicMapper[message.topic.canonicalize()]!] ??= QueueList();
7276
messageIds.add(message.id);
7377
case DmMessage():
7478
final narrow = DmNarrow.ofMessage(message, selfUserId: eg.selfUser.userId);
@@ -332,6 +336,7 @@ void main() {
332336
final stream2 = eg.stream(streamId: 2);
333337
for (final (oldStream, newStream, oldTopic, newTopic) in [
334338
(stream1, stream1, 'a', 'a'),
339+
(stream1, stream1, 'a', 'A'),
335340
(stream1, stream1, 'a', 'b'),
336341
(stream1, stream2, 'a', 'a'),
337342
(stream1, stream2, 'a', 'b'),

0 commit comments

Comments
 (0)