Skip to content

Commit 86d800c

Browse files
committed
message: Mutate messages for flags events here, instead of in msglists
Like a recent commit did for message edits, and one before that did for reactions, this fixes the part of 455 that's concerned with update-message-flags events. Like in the commit that dealt with message edits, this fixes the symptom of a dropped update when there are zero message lists open. In this case I'm *pretty* sure there wasn't a user-facing symptom with the double-processing situation when the message is in two or more open message lists. That's because I believe we don't give different behavior for a flag that's present multiple times in the `flags` list, vs. just once.
1 parent e69a8ce commit 86d800c

File tree

3 files changed

+87
-32
lines changed

3 files changed

+87
-32
lines changed

lib/model/message.dart

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,36 @@ class MessageStoreImpl with MessageStore {
133133
}
134134

135135
void handleUpdateMessageFlagsEvent(UpdateMessageFlagsEvent event) {
136-
for (final view in _messageListViews) {
137-
view.handleUpdateMessageFlagsEvent(event); // TODO update mainly in [messages] instead
136+
final isAdd = switch (event) {
137+
UpdateMessageFlagsAddEvent() => true,
138+
UpdateMessageFlagsRemoveEvent() => false,
139+
};
140+
141+
if (isAdd && (event as UpdateMessageFlagsAddEvent).all) {
142+
for (final message in messages.values) {
143+
message.flags.add(event.flag);
144+
}
145+
146+
for (final view in _messageListViews) {
147+
if (view.messages.isEmpty) continue;
148+
view.notifyListeners();
149+
}
150+
} else {
151+
bool knowAboutAny = false;
152+
for (final messageId in event.messages) {
153+
final message = messages[messageId];
154+
if (message == null) continue; // a message we don't know about yet
155+
knowAboutAny = true;
156+
157+
isAdd
158+
? message.flags.add(event.flag)
159+
: message.flags.remove(event.flag);
160+
}
161+
if (knowAboutAny) {
162+
for (final view in _messageListViews) {
163+
view.notifyListenersIfAnyMessagePresent(event.messages);
164+
}
165+
}
138166
}
139167
}
140168

lib/model/message_list.dart

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,15 @@ class MessageListView with ChangeNotifier, _MessageSequence {
444444
notifyListeners();
445445
}
446446

447+
/// Calls [super.notifyListeners].
448+
///
449+
/// Overridden here without annotations that would prevent us from calling it
450+
/// from [MessageStoreImpl].
451+
@override
452+
void notifyListeners() {
453+
super.notifyListeners();
454+
}
455+
447456
/// Notify listeners if the given message is present in this view.
448457
void notifyListenersIfMessagePresent(int messageId) {
449458
final index = _findMessageWithId(messageId);
@@ -452,6 +461,15 @@ class MessageListView with ChangeNotifier, _MessageSequence {
452461
}
453462
}
454463

464+
/// Notify listeners if any of the given messages is present in this view.
465+
void notifyListenersIfAnyMessagePresent(Iterable<int> messageIds) {
466+
final isAnyPresent = messageIds
467+
.any((messageId) => _findMessageWithId(messageId) != -1);
468+
if (isAnyPresent) {
469+
notifyListeners();
470+
}
471+
}
472+
455473
void messageContentChanged(int messageId) {
456474
final index = _findMessageWithId(messageId);
457475
if (index != -1) {
@@ -460,35 +478,6 @@ class MessageListView with ChangeNotifier, _MessageSequence {
460478
}
461479
}
462480

463-
void handleUpdateMessageFlagsEvent(UpdateMessageFlagsEvent event) {
464-
final isAdd = switch (event) {
465-
UpdateMessageFlagsAddEvent() => true,
466-
UpdateMessageFlagsRemoveEvent() => false,
467-
};
468-
469-
bool didUpdateAny = false;
470-
if (isAdd && (event as UpdateMessageFlagsAddEvent).all) {
471-
for (final message in messages) {
472-
message.flags.add(event.flag);
473-
didUpdateAny = true;
474-
}
475-
} else {
476-
for (final messageId in event.messages) {
477-
final index = _findMessageWithId(messageId);
478-
if (index != -1) {
479-
final message = messages[index];
480-
isAdd ? message.flags.add(event.flag) : message.flags.remove(event.flag);
481-
didUpdateAny = true;
482-
}
483-
}
484-
}
485-
if (!didUpdateAny) {
486-
return;
487-
}
488-
489-
notifyListeners();
490-
}
491-
492481
/// Called when the app is reassembled during debugging, e.g. for hot reload.
493482
///
494483
/// This will redo from scratch any computations we can, such as parsing

test/model/message_list_test.dart

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,33 @@ void main() {
306306
});
307307
});
308308

309+
group('notifyListenersIfAnyMessagePresent', () {
310+
final messages = List.generate(100, (i) => eg.streamMessage(id: 100 + i));
311+
312+
test('all messages present', () async {
313+
await prepare(narrow: const CombinedFeedNarrow());
314+
await prepareMessages(foundOldest: false, messages: messages);
315+
model.notifyListenersIfAnyMessagePresent([150, 151, 152]);
316+
checkNotifiedOnce();
317+
});
318+
319+
test('some messages present', () async {
320+
await prepare(narrow: const CombinedFeedNarrow());
321+
await prepareMessages(foundOldest: false,
322+
messages: messages.where((m) => m.id != 151).toList());
323+
model.notifyListenersIfAnyMessagePresent([150, 151, 152]);
324+
checkNotifiedOnce();
325+
});
326+
327+
test('no messages present', () async {
328+
await prepare(narrow: const CombinedFeedNarrow());
329+
await prepareMessages(foundOldest: false, messages:
330+
messages.where((m) => ![150, 151, 152].contains(m.id)).toList());
331+
model.notifyListenersIfAnyMessagePresent([150, 151, 152]);
332+
checkNotNotified();
333+
});
334+
});
335+
309336
group('messageContentChanged', () {
310337
test('message present', () async {
311338
await prepare(narrow: const CombinedFeedNarrow());
@@ -428,7 +455,18 @@ void main() {
428455
);
429456
});
430457

431-
// TODO(#455) message flags
458+
test('UpdateMessageFlagsEvent is applied even when message not in any msglists', () async {
459+
await checkApplied(
460+
mkEvent: (message) => UpdateMessageFlagsAddEvent(
461+
id: 1,
462+
flag: MessageFlag.starred,
463+
messages: [message.id],
464+
all: false,
465+
),
466+
doCheckMessageAfterFetch:
467+
(messageSubject) => messageSubject.flags.contains(MessageFlag.starred),
468+
);
469+
});
432470
});
433471

434472
test('reassemble', () async {

0 commit comments

Comments
 (0)