@@ -10,6 +10,7 @@ import '../log.dart';
1010import 'algorithms.dart' ;
1111import 'narrow.dart' ;
1212import 'channel.dart' ;
13+ import 'topicmap.dart' ;
1314
1415/// The view-model for unread messages.
1516///
@@ -40,14 +41,14 @@ class Unreads extends ChangeNotifier {
4041 required int selfUserId,
4142 required ChannelStore channelStore,
4243 }) {
43- final streams = < int , Map < TopicName , QueueList <int >>> {};
44+ final streams = < int , TopicMap < QueueList <int >>> {};
4445 final dms = < DmNarrow , QueueList <int >> {};
4546 final mentions = Set .of (initial.mentions);
4647
4748 for (final unreadChannelSnapshot in initial.channels) {
4849 final streamId = unreadChannelSnapshot.streamId;
4950 final topic = unreadChannelSnapshot.topic;
50- (streams[streamId] ?? = {})[ topic] = QueueList .from (unreadChannelSnapshot.unreadMessageIds);
51+ (streams[streamId] ?? = TopicMap < QueueList < int >>()). set ( topic, QueueList .from (unreadChannelSnapshot.unreadMessageIds) );
5152 }
5253
5354 for (final unreadDmSnapshot in initial.dms) {
@@ -86,7 +87,7 @@ class Unreads extends ChangeNotifier {
8687 // int count;
8788
8889 /// Unread stream messages, as: stream ID → topic → message IDs (sorted).
89- final Map <int , Map < TopicName , QueueList <int >>> streams;
90+ final Map <int , TopicMap < QueueList <int >>> streams;
9091
9192 /// Unread DM messages, as: DM narrow → message IDs (sorted).
9293 final Map <DmNarrow , QueueList <int >> dms;
@@ -187,7 +188,7 @@ class Unreads extends ChangeNotifier {
187188
188189 int countInTopicNarrow (int streamId, TopicName topic) {
189190 final topics = streams[streamId];
190- return topics? [topic] ? .length ?? 0 ;
191+ return topics? .size ?? 0 ;
191192 }
192193
193194 int countInDmNarrow (DmNarrow narrow) => dms[narrow]? .length ?? 0 ;
@@ -443,26 +444,30 @@ class Unreads extends ChangeNotifier {
443444 // TODO use efficient lookups
444445 bool _slowIsPresentInStreams (int messageId) {
445446 return streams.values.any (
446- (topics) => topics.values.any (
447+ (topics) => topics.values () .any (
447448 (messageIds) => messageIds.contains (messageId),
448449 ),
449450 );
450451 }
451452
452453 void _addLastInStreamTopic (int messageId, int streamId, TopicName topic) {
453- ((streams[streamId] ?? = {})[topic] ?? = QueueList ()).addLast (messageId);
454+ if ((streams[streamId] ?? = TopicMap <QueueList <int >>()).get (topic) == null ) {
455+ streams[streamId]? .set (topic, QueueList <int >());
456+ }
457+ (streams[streamId] ?? = TopicMap <QueueList <int >>()).get (topic)? .addLast (messageId);
454458 }
455459
456460 // [messageIds] must be sorted ascending and without duplicates.
457461 void _addAllInStreamTopic (QueueList <int > messageIds, int streamId, TopicName topic) {
458- final topics = streams[streamId] ?? = {};
459- topics.update (topic,
460- ifAbsent: () => messageIds,
461- // setUnion dedupes existing and incoming unread IDs,
462- // so we tolerate zulip/zulip#22164, fixed in 6.0
463- // TODO(server-6) remove 6.0 comment
464- (existing) => setUnion (existing, messageIds),
465- );
462+ final topics = streams[streamId] ?? = TopicMap <QueueList <int >>();
463+ if (topics.has (topic)) {
464+ // If the topic already exists, update its message ids with setUnion
465+ topics.set (topic, setUnion (topics.get (topic) ?? QueueList <int >(), messageIds));
466+ } else {
467+ // If the topic does not exist, insert the new messageIds list
468+ topics.set (topic, messageIds);
469+ }
470+
466471 }
467472
468473 // TODO use efficient model lookups
@@ -477,9 +482,9 @@ class Unreads extends ChangeNotifier {
477482 }
478483 }
479484 for (final topic in newlyEmptyTopics) {
480- topics.remove (topic);
485+ topics.delete (topic);
481486 }
482- if (topics.isEmpty ) {
487+ if (topics.size == 0 ) {
483488 newlyEmptyStreams.add (streamId);
484489 }
485490 }
@@ -491,14 +496,14 @@ class Unreads extends ChangeNotifier {
491496 void _removeAllInStreamTopic (Set <int > incomingMessageIds, int streamId, TopicName topic) {
492497 final topics = streams[streamId];
493498 if (topics == null ) return ;
494- final messageIds = topics[ topic] ;
499+ final messageIds = topics. get ( topic) ;
495500 if (messageIds == null ) return ;
496501
497502 // ([QueueList] doesn't have a `removeAll`)
498503 messageIds.removeWhere ((id) => incomingMessageIds.contains (id));
499504 if (messageIds.isEmpty) {
500- topics.remove (topic);
501- if (topics.isEmpty ) {
505+ topics.delete (topic);
506+ if (topics.size == 0 ) {
502507 streams.remove (streamId);
503508 }
504509 }
0 commit comments