@@ -41,14 +41,15 @@ import 'narrow.dart';
41
41
class Unreads extends ChangeNotifier {
42
42
factory Unreads ({required UnreadMessagesSnapshot initial, required selfUserId}) {
43
43
int totalCount = 0 ;
44
- final streams = < int , Map < String , QueueList < int >> > {};
44
+ final streams = < int , StreamUnreads > {};
45
45
final dms = < DmNarrow , QueueList <int >> {};
46
46
final mentions = Set .of (initial.mentions);
47
47
48
48
for (final unreadStreamSnapshot in initial.streams) {
49
49
final streamId = unreadStreamSnapshot.streamId;
50
50
final topic = unreadStreamSnapshot.topic;
51
- (streams[streamId] ?? = {})[topic] = QueueList .from (unreadStreamSnapshot.unreadMessageIds);
51
+ (streams[streamId] ?? = StreamUnreads .empty ())
52
+ .topics[topic] = QueueList .from (unreadStreamSnapshot.unreadMessageIds);
52
53
totalCount += unreadStreamSnapshot.unreadMessageIds.length;
53
54
}
54
55
@@ -96,7 +97,7 @@ class Unreads extends ChangeNotifier {
96
97
int _totalCount;
97
98
98
99
/// Unread stream messages, as: stream ID → topic → message ID.
99
- final Map <int , Map < String , QueueList < int >> > streams;
100
+ final Map <int , StreamUnreads > streams;
100
101
101
102
/// Unread DM messages, as: DM narrow → message ID.
102
103
final Map <DmNarrow , QueueList <int >> dms;
@@ -327,22 +328,23 @@ class Unreads extends ChangeNotifier {
327
328
// TODO use efficient lookups
328
329
bool _slowIsPresentInStreams (int messageId) {
329
330
return streams.values.any (
330
- (topics ) => topics.values.any (
331
+ (streamUnreads ) => streamUnreads. topics.values.any (
331
332
(messageIds) => messageIds.contains (messageId),
332
333
),
333
334
);
334
335
}
335
336
336
337
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);
338
340
_totalCount += 1 ;
339
341
}
340
342
341
343
// [messageIds] must be sorted ascending and without duplicates.
342
344
void _addAllInStreamTopic (QueueList <int > messageIds, int streamId, String topic) {
343
345
int numAdded = 0 ;
344
- final topics = streams[streamId] ?? = {} ;
345
- topics.update (topic,
346
+ final streamUnreads = streams[streamId] ?? = StreamUnreads . empty () ;
347
+ streamUnreads. topics.update (topic,
346
348
ifAbsent: () {
347
349
numAdded = messageIds.length;
348
350
return messageIds;
@@ -363,9 +365,9 @@ class Unreads extends ChangeNotifier {
363
365
void _slowRemoveAllInStreams (Set <int > idsToRemove) {
364
366
int numRemoved = 0 ;
365
367
final newlyEmptyStreams = [];
366
- for (final MapEntry (key: streamId, value: topics ) in streams.entries) {
368
+ for (final MapEntry (key: streamId, value: streamUnreads ) in streams.entries) {
367
369
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) {
369
371
final lengthBefore = messageIds.length;
370
372
messageIds.removeWhere ((id) => idsToRemove.contains (id));
371
373
numRemoved += lengthBefore - messageIds.length;
@@ -374,9 +376,9 @@ class Unreads extends ChangeNotifier {
374
376
}
375
377
}
376
378
for (final topic in newlyEmptyTopics) {
377
- topics.remove (topic);
379
+ streamUnreads. topics.remove (topic);
378
380
}
379
- if (topics.isEmpty) {
381
+ if (streamUnreads. topics.isEmpty) {
380
382
newlyEmptyStreams.add (streamId);
381
383
}
382
384
}
@@ -387,18 +389,18 @@ class Unreads extends ChangeNotifier {
387
389
}
388
390
389
391
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];
393
395
if (messageIds == null ) return ;
394
396
395
397
// ([QueueList] doesn't have a `removeAll`)
396
398
final lengthBefore = messageIds.length;
397
399
messageIds.removeWhere ((id) => incomingMessageIds.contains (id));
398
400
_totalCount -= lengthBefore - messageIds.length;
399
401
if (messageIds.isEmpty) {
400
- topics.remove (topic);
401
- if (topics.isEmpty) {
402
+ streamUnreads. topics.remove (topic);
403
+ if (streamUnreads. topics.isEmpty) {
402
404
streams.remove (streamId);
403
405
}
404
406
}
@@ -452,3 +454,13 @@ class Unreads extends ChangeNotifier {
452
454
_totalCount -= numRemoved;
453
455
}
454
456
}
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