@@ -41,14 +41,15 @@ import 'narrow.dart';
4141class Unreads extends ChangeNotifier {
4242 factory Unreads ({required UnreadMessagesSnapshot initial, required selfUserId}) {
4343 int totalCount = 0 ;
44- final streams = < int , Map < String , QueueList < int >> > {};
44+ final streams = < int , StreamUnreads > {};
4545 final dms = < DmNarrow , QueueList <int >> {};
4646 final mentions = Set .of (initial.mentions);
4747
4848 for (final unreadStreamSnapshot in initial.streams) {
4949 final streamId = unreadStreamSnapshot.streamId;
5050 final topic = unreadStreamSnapshot.topic;
51- (streams[streamId] ?? = {})[topic] = QueueList .from (unreadStreamSnapshot.unreadMessageIds);
51+ (streams[streamId] ?? = StreamUnreads .empty ())
52+ .topics[topic] = QueueList .from (unreadStreamSnapshot.unreadMessageIds);
5253 totalCount += unreadStreamSnapshot.unreadMessageIds.length;
5354 }
5455
@@ -96,7 +97,7 @@ class Unreads extends ChangeNotifier {
9697 int _totalCount;
9798
9899 /// Unread stream messages, as: stream ID → topic → message ID.
99- final Map <int , Map < String , QueueList < int >> > streams;
100+ final Map <int , StreamUnreads > streams;
100101
101102 /// Unread DM messages, as: DM narrow → message ID.
102103 final Map <DmNarrow , QueueList <int >> dms;
@@ -327,22 +328,23 @@ class Unreads extends ChangeNotifier {
327328 // TODO use efficient lookups
328329 bool _slowIsPresentInStreams (int messageId) {
329330 return streams.values.any (
330- (topics ) => topics.values.any (
331+ (streamUnreads ) => streamUnreads. topics.values.any (
331332 (messageIds) => messageIds.contains (messageId),
332333 ),
333334 );
334335 }
335336
336337 void _addLastInStreamTopic (int messageId, int streamId, String topic) {
337- ((streams[streamId] ?? = {})[topic] ?? = QueueList ()).addLast (messageId);
338+ final streamUnreads = streams[streamId] ?? = StreamUnreads .empty ();
339+ (streamUnreads.topics[topic] ?? = QueueList ()).addLast (messageId);
338340 _totalCount += 1 ;
339341 }
340342
341343 // [messageIds] must be sorted ascending and without duplicates.
342344 void _addAllInStreamTopic (QueueList <int > messageIds, int streamId, String topic) {
343345 int numAdded = 0 ;
344- final topics = streams[streamId] ?? = {} ;
345- topics.update (topic,
346+ final streamUnreads = streams[streamId] ?? = StreamUnreads . empty () ;
347+ streamUnreads. topics.update (topic,
346348 ifAbsent: () {
347349 numAdded = messageIds.length;
348350 return messageIds;
@@ -363,9 +365,9 @@ class Unreads extends ChangeNotifier {
363365 void _slowRemoveAllInStreams (Set <int > idsToRemove) {
364366 int numRemoved = 0 ;
365367 final newlyEmptyStreams = [];
366- for (final MapEntry (key: streamId, value: topics ) in streams.entries) {
368+ for (final MapEntry (key: streamId, value: streamUnreads ) in streams.entries) {
367369 final newlyEmptyTopics = [];
368- for (final MapEntry (key: topic, value: messageIds) in topics.entries) {
370+ for (final MapEntry (key: topic, value: messageIds) in streamUnreads. topics.entries) {
369371 final lengthBefore = messageIds.length;
370372 messageIds.removeWhere ((id) => idsToRemove.contains (id));
371373 numRemoved += lengthBefore - messageIds.length;
@@ -374,9 +376,9 @@ class Unreads extends ChangeNotifier {
374376 }
375377 }
376378 for (final topic in newlyEmptyTopics) {
377- topics.remove (topic);
379+ streamUnreads. topics.remove (topic);
378380 }
379- if (topics.isEmpty) {
381+ if (streamUnreads. topics.isEmpty) {
380382 newlyEmptyStreams.add (streamId);
381383 }
382384 }
@@ -387,18 +389,18 @@ class Unreads extends ChangeNotifier {
387389 }
388390
389391 void _removeAllInStreamTopic (Set <int > incomingMessageIds, int streamId, String topic) {
390- final topics = streams[streamId];
391- if (topics == null ) return ;
392- final messageIds = topics[topic];
392+ final streamUnreads = streams[streamId];
393+ if (streamUnreads == null ) return ;
394+ final messageIds = streamUnreads. topics[topic];
393395 if (messageIds == null ) return ;
394396
395397 // ([QueueList] doesn't have a `removeAll`)
396398 final lengthBefore = messageIds.length;
397399 messageIds.removeWhere ((id) => incomingMessageIds.contains (id));
398400 _totalCount -= lengthBefore - messageIds.length;
399401 if (messageIds.isEmpty) {
400- topics.remove (topic);
401- if (topics.isEmpty) {
402+ streamUnreads. topics.remove (topic);
403+ if (streamUnreads. topics.isEmpty) {
402404 streams.remove (streamId);
403405 }
404406 }
@@ -452,3 +454,13 @@ class Unreads extends ChangeNotifier {
452454 _totalCount -= numRemoved;
453455 }
454456}
457+
458+ class StreamUnreads {
459+ StreamUnreads ({required this .topics});
460+ StreamUnreads .empty () : topics = {};
461+
462+ Map <String , QueueList <int >> topics;
463+
464+ @visibleForTesting
465+ Map <String , dynamic > toJson () => {'topics' : topics};
466+ }
0 commit comments