Skip to content

Commit

Permalink
unreads: Fix topic case-sensitivity.
Browse files Browse the repository at this point in the history
Maps canoncalized topic names to
a variant of the actual topic name.

Fixes #980.
  • Loading branch information
apoorvapendse committed Feb 2, 2025
1 parent 449f326 commit 711d659
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
27 changes: 25 additions & 2 deletions lib/model/unreads.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ class Unreads extends ChangeNotifier {
}) {
final streams = <int, Map<TopicName, QueueList<int>>>{};
final dms = <DmNarrow, QueueList<int>>{};
// Maps the lowercased version of topic to one of the actual versions
final topicMapper = <String, TopicName>{};
final mentions = Set.of(initial.mentions);

for (final unreadChannelSnapshot in initial.channels) {
final streamId = unreadChannelSnapshot.streamId;
final topic = unreadChannelSnapshot.topic;
topicMapper[topic.canonicalize()] = topic;
(streams[streamId] ??= {})[topic] = QueueList.from(unreadChannelSnapshot.unreadMessageIds);
}

Expand All @@ -64,6 +67,7 @@ class Unreads extends ChangeNotifier {
return Unreads._(
channelStore: channelStore,
streams: streams,
topicMapper: topicMapper,
dms: dms,
mentions: mentions,
oldUnreadsMissing: initial.oldUnreadsMissing,
Expand All @@ -74,6 +78,7 @@ class Unreads extends ChangeNotifier {
Unreads._({
required this.channelStore,
required this.streams,
required this.topicMapper,
required this.dms,
required this.mentions,
required this.oldUnreadsMissing,
Expand All @@ -91,6 +96,9 @@ class Unreads extends ChangeNotifier {
/// Unread DM messages, as: DM narrow → message IDs (sorted).
final Map<DmNarrow, QueueList<int>> dms;

// Maps lowercase topic names for lookup to one of the variants of the topic (case preserving).
final Map<String, TopicName> topicMapper;

/// Unread messages with the self-user @-mentioned, directly or by wildcard.
///
/// At initialization, if a message is:
Expand Down Expand Up @@ -380,9 +388,19 @@ class Unreads extends ChangeNotifier {
}
switch (detail.type) {
case MessageType.stream:
final topicKey = detail.topic!.canonicalize();
TopicName actualTopicName;
if (topicMapper[topicKey] != null) {
actualTopicName = topicMapper[topicKey] as TopicName;
} else {
topicMapper[topicKey] = detail.topic!;
actualTopicName = detail.topic!;
}

final topics = (newlyUnreadInStreams[detail.streamId!] ??= {});
final messageIds = (topics[detail.topic!] ??= QueueList());
final messageIds = (topics[actualTopicName!] ??= QueueList());
messageIds.add(messageId);

case MessageType.direct:
final narrow = DmNarrow.ofUpdateMessageFlagsMessageDetail(selfUserId: selfUserId,
detail);
Expand Down Expand Up @@ -450,7 +468,12 @@ class Unreads extends ChangeNotifier {
}

void _addLastInStreamTopic(int messageId, int streamId, TopicName topic) {
((streams[streamId] ??= {})[topic] ??= QueueList()).addLast(messageId);
if (topicMapper[topic.canonicalize()] != null && topic.isSameAs(topicMapper[topic.canonicalize()]!)) {
((streams[streamId] ??= {})[topicMapper[topic.canonicalize()]!] ??= QueueList()).addLast(messageId);
} else {
topicMapper[topic.canonicalize()] = topic;
((streams[streamId] ??= {})[topic] ??= QueueList()).addLast(messageId);
}
}

// [messageIds] must be sorted ascending and without duplicates.
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/inbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class _InboxPageState extends State<InboxPageBody> with PerAccountStoreAwareStat
int countInStream = 0;
bool streamHasMention = false;
for (final MapEntry(key: topic, value: messageIds) in topics.entries) {
if (!store.isTopicVisible(streamId, topic)) continue;
if (!store.isTopicVisible(streamId, unreadsModel!=null ? (unreadsModel?.topicMapper[topic.canonicalize()])! : topic!)) continue;
final countInTopic = messageIds.length;
final hasMention = messageIds.any((messageId) => unreadsModel!.mentions.contains(messageId));
if (hasMention) streamHasMention = true;
Expand Down
7 changes: 6 additions & 1 deletion test/model/unreads_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void main() {

final Map<int, Map<TopicName, QueueList<int>>> expectedStreams = {};
final Map<DmNarrow, QueueList<int>> expectedDms = {};
final Map<String, TopicName> topicMapper = {};
final Set<int> expectedMentions = {};
for (final message in messages) {
if (message.flags.contains(MessageFlag.read)) {
Expand All @@ -68,7 +69,10 @@ void main() {
switch (message) {
case StreamMessage():
final perTopic = expectedStreams[message.streamId] ??= {};
final messageIds = perTopic[message.topic] ??= QueueList();
if (topicMapper[message.topic.canonicalize()] == null) {
topicMapper[message.topic.canonicalize()] = message.topic;
}
final messageIds = perTopic[topicMapper[message.topic.canonicalize()]!] ??= QueueList();
messageIds.add(message.id);
case DmMessage():
final narrow = DmNarrow.ofMessage(message, selfUserId: eg.selfUser.userId);
Expand Down Expand Up @@ -332,6 +336,7 @@ void main() {
final stream2 = eg.stream(streamId: 2);
for (final (oldStream, newStream, oldTopic, newTopic) in [
(stream1, stream1, 'a', 'a'),
(stream1, stream1, 'a', 'A'),
(stream1, stream1, 'a', 'b'),
(stream1, stream2, 'a', 'a'),
(stream1, stream2, 'a', 'b'),
Expand Down

0 comments on commit 711d659

Please sign in to comment.