Skip to content

Commit 6054679

Browse files
committed
message: Update all edit timestamps on UpdateMessageEvent
This is equivalent for a content edit (where there's just one message affected), but differs when multiple messages are affected, as can happen with a message move.
1 parent b548faa commit 6054679

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

lib/model/message.dart

+17-7
Original file line numberDiff line numberDiff line change
@@ -93,32 +93,42 @@ class MessageStoreImpl with MessageStore {
9393
}
9494

9595
void handleUpdateMessageEvent(UpdateMessageEvent event) {
96+
_handleUpdateMessageEventTimestamp(event);
9697
_handleUpdateMessageEventContent(event);
9798
// TODO(#150): Handle message moves. The views' recipient headers
9899
// may need updating, and consequently showSender too.
100+
for (final view in _messageListViews) {
101+
view.notifyListenersIfAnyMessagePresent(event.messageIds);
102+
}
99103
}
100104

101-
void _handleUpdateMessageEventContent(UpdateMessageEvent event) {
102-
final message = messages[event.messageId];
103-
if (message == null) return;
104-
105+
void _handleUpdateMessageEventTimestamp(UpdateMessageEvent event) {
105106
// TODO(server-5): Cut this fallback; rely on renderingOnly from FL 114
106107
final isRenderingOnly = event.renderingOnly ?? (event.userId == null);
107-
if (event.editTimestamp != null && !isRenderingOnly) {
108+
if (event.editTimestamp == null || isRenderingOnly) {
108109
// A rendering-only update gets omitted from the message edit history,
109110
// and [Message.lastEditTimestamp] is the last timestamp of that history.
110111
// So on a rendering-only update, the timestamp doesn't get updated.
112+
return;
113+
}
114+
115+
for (final messageId in event.messageIds) {
116+
final message = messages[messageId];
117+
if (message == null) continue;
111118
message.lastEditTimestamp = event.editTimestamp;
112119
}
120+
}
113121

114-
message.flags = event.flags;
122+
void _handleUpdateMessageEventContent(UpdateMessageEvent event) {
123+
final message = messages[event.messageId];
124+
if (message == null) return;
115125

126+
message.flags = event.flags;
116127
if (event.renderedContent != null) {
117128
assert(message.contentType == 'text/html',
118129
"Message contentType was ${message.contentType}; expected text/html.");
119130
message.content = event.renderedContent!;
120131
}
121-
122132
if (event.isMeMessage != null) {
123133
message.isMeMessage = event.isMeMessage!;
124134
}

lib/model/message_list.dart

+4-1
Original file line numberDiff line numberDiff line change
@@ -467,11 +467,14 @@ class MessageListView with ChangeNotifier, _MessageSequence {
467467
}
468468
}
469469

470+
/// Update data derived from the content of the given message.
471+
///
472+
/// This does not notify listeners.
473+
/// The caller should ensure that happens later.
470474
void messageContentChanged(int messageId) {
471475
final index = _findMessageWithId(messageId);
472476
if (index != -1) {
473477
_reparseContent(index);
474-
notifyListeners();
475478
}
476479
}
477480

test/model/message_test.dart

+28
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,34 @@ void main() {
162162
});
163163

164164
group('handleUpdateMessageEvent', () {
165+
test('update timestamps on all messages', () async {
166+
const t1 = 1718748879;
167+
const t2 = t1 + 60;
168+
final message1 = eg.streamMessage(lastEditTimestamp: null);
169+
final message2 = eg.streamMessage(lastEditTimestamp: t1);
170+
// This event is a bit artificial, but convenient.
171+
// TODO use a realistic move-messages event here
172+
final updateEvent = Event.fromJson({
173+
...eg.updateMessageEditEvent(message1).toJson(),
174+
'message_ids': [message1.id, message2.id],
175+
'edit_timestamp': t2,
176+
}) as UpdateMessageEvent;
177+
await prepare();
178+
await prepareMessages([message1, message2]);
179+
180+
check(store).messages.values.unorderedMatches(<Condition<Message>>[
181+
(it) => it.lastEditTimestamp.isNull,
182+
(it) => it.lastEditTimestamp.equals(t1),
183+
]);
184+
185+
await store.handleEvent(updateEvent);
186+
checkNotifiedOnce();
187+
check(store).messages.values.unorderedMatches(<Condition<Message>>[
188+
(it) => it.lastEditTimestamp.equals(t2),
189+
(it) => it.lastEditTimestamp.equals(t2),
190+
]);
191+
});
192+
165193
test('update a message', () async {
166194
final originalMessage = eg.streamMessage(
167195
content: "<p>Hello, world</p>");

0 commit comments

Comments
 (0)