@@ -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). 
9293final  Map <DmNarrow , QueueList <int >> dms;
@@ -187,7 +188,9 @@ class Unreads extends ChangeNotifier {
187188
188189  int  countInTopicNarrow (int  streamId, TopicName  topic) {
189190    final  topics =  streams[streamId];
190-     return  topics? [topic]? .length ??  0 ;
191+     if  (topics ==  null ) return  0 ;
192+     final  qlist =  topics.get (topic);
193+     return  qlist? .length ??  0 ;
191194  }
192195
193196  int  countInDmNarrow (DmNarrow  narrow) =>  dms[narrow]? .length ??  0 ;
@@ -443,26 +446,30 @@ class Unreads extends ChangeNotifier {
443446  // TODO use efficient lookups 
444447  bool  _slowIsPresentInStreams (int  messageId) {
445448    return  streams.values.any (
446-       (topics) =>  topics.values.any (
449+       (topics) =>  topics.values () .any (
447450        (messageIds) =>  messageIds.contains (messageId),
448451      ),
449452    );
450453  }
451454
452455  void  _addLastInStreamTopic (int  messageId, int  streamId, TopicName  topic) {
453-     ((streams[streamId] ?? =  {})[topic] ?? =  QueueList ()).addLast (messageId);
456+     if  ((streams[streamId] ?? =  TopicMap <QueueList <int >>()).get (topic) ==  null ) {
457+       streams[streamId]? .set (topic, QueueList <int >());
458+     }
459+     (streams[streamId] ?? =  TopicMap <QueueList <int >>()).get (topic)? .addLast (messageId);
454460  }
455461
456462  // [messageIds] must be sorted ascending and without duplicates. 
457463  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-     );
464+     final  topics =  streams[streamId] ?? =  TopicMap <QueueList <int >>();
465+     if  (topics.has (topic)) {
466+       // If the topic already exists, update its message ids with setUnion 
467+     topics.set (topic, setUnion (topics.get (topic) ??  QueueList <int >(), messageIds));
468+     } else  {
469+       // If the topic does not exist, insert the new messageIds list 
470+     topics.set (topic, messageIds);
471+     }
472+ 
466473  }
467474
468475  // TODO use efficient model lookups 
@@ -477,9 +484,9 @@ class Unreads extends ChangeNotifier {
477484        }
478485      }
479486      for  (final  topic in  newlyEmptyTopics) {
480-         topics.remove (topic);
487+         topics.delete (topic);
481488      }
482-       if  (topics.isEmpty ) {
489+       if  (topics.size == 0 ) {
483490        newlyEmptyStreams.add (streamId);
484491      }
485492    }
@@ -491,14 +498,14 @@ class Unreads extends ChangeNotifier {
491498  void  _removeAllInStreamTopic (Set <int > incomingMessageIds, int  streamId, TopicName  topic) {
492499    final  topics =  streams[streamId];
493500    if  (topics ==  null ) return ;
494-     final  messageIds =  topics[ topic] ;
501+     final  messageIds =  topics. get ( topic) ;
495502    if  (messageIds ==  null ) return ;
496503
497504    // ([QueueList] doesn't have a `removeAll`) 
498505    messageIds.removeWhere ((id) =>  incomingMessageIds.contains (id));
499506    if  (messageIds.isEmpty) {
500-       topics.remove (topic);
501-       if  (topics.isEmpty ) {
507+       topics.delete (topic);
508+       if  (topics.size == 0 ) {
502509        streams.remove (streamId);
503510      }
504511    }
0 commit comments