Skip to content

Commit 6cbc7aa

Browse files
committed
unreads: Handle updates when there are moved messages
Signed-off-by: Zixuan James Li <[email protected]>
1 parent 02a69d1 commit 6cbc7aa

File tree

2 files changed

+148
-1
lines changed

2 files changed

+148
-1
lines changed

lib/model/unreads.dart

+26-1
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,38 @@ 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+
final messageMove = event.moveData;
308+
if (messageMove == null) {
309+
// No moved messages or malformed event.
310+
return false;
311+
}
312+
313+
final topics = streams[messageMove.origStreamId];
314+
if (topics == null || topics[messageMove.origTopic] == null) {
315+
// No known unreads affected by move; nothing to do.
316+
return false;
317+
}
318+
319+
final messageToMoveIds = _removeAllInStreamTopic(
320+
event.messageIds.toSet(),
321+
messageMove.origStreamId, messageMove.origTopic);
322+
if (messageToMoveIds.isEmpty) {
323+
return false;
324+
}
325+
_addAllInStreamTopic(
326+
messageToMoveIds..sort(),
327+
messageMove.newStreamId, messageMove.newTopic);
328+
return true;
329+
}
330+
306331
void handleDeleteMessageEvent(DeleteMessageEvent event) {
307332
mentions.removeAll(event.messageIds);
308333
final messageIdsSet = Set.of(event.messageIds);

test/model/unreads_test.dart

+122
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,128 @@ 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('from topic with unreads', () {
541+
prepare();
542+
final unreadMessage = eg.streamMessage(
543+
stream: origChannel, topic: origTopic);
544+
fillWithMessages([...unreadMessages, unreadMessage]);
545+
546+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
547+
origMessages: unreadMessages,
548+
newTopicStr: newTopic));
549+
checkNotifiedOnce();
550+
checkMatchesMessages([
551+
for (final message in unreadMessages)
552+
Message.fromJson(message.toJson()..['subject'] = newTopic),
553+
unreadMessage,
554+
]);
555+
});
556+
557+
test('to topic with unreads', () {
558+
prepare();
559+
final unreadMessage = eg.streamMessage(
560+
stream: origChannel, topic: newTopic);
561+
fillWithMessages([...unreadMessages, unreadMessage]);
562+
563+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
564+
origMessages: unreadMessages,
565+
newTopicStr: newTopic));
566+
checkNotifiedOnce();
567+
checkMatchesMessages([
568+
for (final message in unreadMessages)
569+
Message.fromJson(message.toJson()..['subject'] = newTopic),
570+
unreadMessage,
571+
]);
572+
});
573+
574+
test('to new channel', () {
575+
final message = eg.streamMessage(
576+
id: 1, stream: origChannel, topic: origTopic);
577+
final newChannel = eg.stream();
578+
prepare();
579+
fillWithMessages([message]);
580+
581+
model.handleUpdateMessageEvent(eg.updateMessageEventMoveFrom(
582+
origMessages: [message],
583+
newStreamId: newChannel.streamId,
584+
newTopicStr: newTopic));
585+
checkNotifiedOnce();
586+
checkMatchesMessages([
587+
Message.fromJson(message.toJson()
588+
..['stream_id'] = newChannel.streamId
589+
..['subject'] = newTopic),
590+
]);
591+
});
592+
});
593+
});
472594
});
473595

474596

0 commit comments

Comments
 (0)