Skip to content

Commit 830ab64

Browse files
committed
unreads: Handle updates when there are moved messages
Signed-off-by: Zixuan James Li <[email protected]>
1 parent 715da90 commit 830ab64

File tree

2 files changed

+167
-1
lines changed

2 files changed

+167
-1
lines changed

lib/model/unreads.dart

+19-1
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,31 @@ class Unreads extends ChangeNotifier {
296296
madeAnyUpdate |= mentions.add(messageId);
297297
}
298298

299-
// TODO(#901) handle moved messages
299+
madeAnyUpdate |= _handleMessageMove(event);
300300

301301
if (madeAnyUpdate) {
302302
notifyListeners();
303303
}
304304
}
305305

306+
bool _handleMessageMove(UpdateMessageEvent event) {
307+
if (event.moveData == null) {
308+
// No moved messages.
309+
return false;
310+
}
311+
final UpdateMessageMoveData(
312+
:origStreamId, :newStreamId, :origTopic, :newTopic) = event.moveData!;
313+
314+
final messageToMoveIds = _removeAllInStreamTopic(
315+
event.messageIds.toSet(), origStreamId, origTopic);
316+
if (messageToMoveIds == null || messageToMoveIds.isEmpty) {
317+
// No known unreads affected by move; nothing to do.
318+
return false;
319+
}
320+
_addAllInStreamTopic(messageToMoveIds..sort(), newStreamId, newTopic);
321+
return true;
322+
}
323+
306324
void handleDeleteMessageEvent(DeleteMessageEvent event) {
307325
mentions.removeAll(event.messageIds);
308326
final messageIdsSet = Set.of(event.messageIds);

test/model/unreads_test.dart

+148
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,154 @@ void main() {
469469
}
470470
}
471471
});
472+
473+
group('moves', () {
474+
final origChannel = eg.stream();
475+
const origTopic = 'origTopic';
476+
const newTopic = 'newTopic';
477+
478+
group('move read messages', () {
479+
final readMessages = List<StreamMessage>.generate(10,
480+
(_) => eg.streamMessage(
481+
stream: origChannel, topic: origTopic, flags: [MessageFlag.read]));
482+
483+
test('to new topic', () {
484+
prepare();
485+
fillWithMessages(readMessages);
486+
487+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
488+
origMessages: readMessages,
489+
newTopicStr: newTopic));
490+
checkNotNotified();
491+
checkMatchesMessages([]);
492+
});
493+
494+
test('from topic with unreads', () {
495+
prepare();
496+
final unreadMessage = eg.streamMessage(
497+
stream: origChannel, topic: origTopic);
498+
fillWithMessages([...readMessages, unreadMessage]);
499+
500+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
501+
origMessages: readMessages,
502+
newTopicStr: newTopic));
503+
checkNotNotified();
504+
checkMatchesMessages([unreadMessage]);
505+
});
506+
507+
test('to topic with unreads', () {
508+
prepare();
509+
final unreadMessage = eg.streamMessage(
510+
stream: origChannel, topic: newTopic);
511+
fillWithMessages([...readMessages, unreadMessage]);
512+
513+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
514+
origMessages: readMessages,
515+
newTopicStr: newTopic,
516+
));
517+
checkNotNotified();
518+
checkMatchesMessages([unreadMessage]);
519+
});
520+
});
521+
522+
group('move unread messages', () {
523+
final unreadMessages = List<StreamMessage>.generate(10,
524+
(_) => eg.streamMessage(stream: origChannel, topic: origTopic));
525+
526+
test('to new topic', () {
527+
prepare();
528+
fillWithMessages(unreadMessages);
529+
530+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
531+
origMessages: unreadMessages,
532+
newTopicStr: newTopic));
533+
checkNotifiedOnce();
534+
checkMatchesMessages([
535+
for (final message in unreadMessages)
536+
Message.fromJson(message.toJson()..['subject'] = newTopic),
537+
]);
538+
});
539+
540+
test('to new channel', () {
541+
prepare();
542+
final newChannel = eg.stream();
543+
fillWithMessages(unreadMessages);
544+
545+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
546+
origMessages: unreadMessages,
547+
newStreamId: newChannel.streamId));
548+
checkNotifiedOnce();
549+
checkMatchesMessages([
550+
for (final message in unreadMessages)
551+
Message.fromJson(
552+
message.toJson()..['stream_id'] = newChannel.streamId),
553+
]);
554+
});
555+
556+
test('from topic containing other unreads', () {
557+
prepare();
558+
final unreadMessage = eg.streamMessage(
559+
stream: origChannel, topic: origTopic);
560+
fillWithMessages([...unreadMessages, unreadMessage]);
561+
562+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
563+
origMessages: unreadMessages,
564+
newTopicStr: newTopic));
565+
checkNotifiedOnce();
566+
checkMatchesMessages([
567+
for (final message in unreadMessages)
568+
Message.fromJson(message.toJson()..['subject'] = newTopic),
569+
unreadMessage,
570+
]);
571+
});
572+
573+
test('to topic containing other unreads', () {
574+
prepare();
575+
final unreadMessage = eg.streamMessage(
576+
stream: origChannel, topic: newTopic);
577+
fillWithMessages([...unreadMessages, unreadMessage]);
578+
579+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
580+
origMessages: unreadMessages,
581+
newTopicStr: newTopic));
582+
checkNotifiedOnce();
583+
checkMatchesMessages([
584+
for (final message in unreadMessages)
585+
Message.fromJson(message.toJson()..['subject'] = newTopic),
586+
unreadMessage,
587+
]);
588+
});
589+
590+
test('tolerate unsorted messages', () {
591+
prepare();
592+
final unreadMessages = List.generate(10,
593+
(i) => eg.streamMessage(id: 1000-i, stream: origChannel, topic: origTopic));
594+
fillWithMessages(unreadMessages);
595+
596+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
597+
origMessages: unreadMessages,
598+
newTopicStr: newTopic));
599+
checkNotifiedOnce();
600+
checkMatchesMessages([
601+
for (final message in unreadMessages)
602+
Message.fromJson(message.toJson()..['subject'] = newTopic)
603+
]);
604+
});
605+
606+
test('tolerate unreads unknown to the model', () {
607+
prepare();
608+
final unknownUnreadMessage = eg.streamMessage(
609+
stream: eg.stream(), topic: origTopic);
610+
fillWithMessages(unreadMessages);
611+
612+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
613+
origMessages: [unknownUnreadMessage],
614+
newTopicStr: newTopic));
615+
checkNotNotified();
616+
checkMatchesMessages(unreadMessages);
617+
});
618+
});
619+
});
472620
});
473621

474622

0 commit comments

Comments
 (0)