Skip to content

Commit 3f14b06

Browse files
committed
message: Handle UpdateMessageEvent for moving.
When a channel (a.k.a stream) or a topic gets updated on a message, we get a UpdateMessageEvent from the server. This updates the edit state to show the "edited" or "moved" marker properly on the messages affected, and leave other move related states (like streamId) untouched until we get to #150. Signed-off-by: Zixuan James Li <[email protected]>
1 parent c0802b3 commit 3f14b06

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

lib/model/message.dart

+21-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,10 @@ class MessageStoreImpl with MessageStore {
142142
// The interaction between the fields of these events are a bit tricky.
143143
// For reference, see: https://zulip.com/api/get-events#update_message
144144

145-
if (event.origTopic == null) {
145+
final bool isChannelMoved = event.newStreamId != null;
146+
bool isTopicMoved = event.origTopic != null;
147+
148+
if (!isTopicMoved && !isChannelMoved) {
146149
// There was no move.
147150
assert(() {
148151
if (event.newStreamId != null && event.origStreamId != null
@@ -167,10 +170,27 @@ class MessageStoreImpl with MessageStore {
167170
return;
168171
}
169172

173+
if (isTopicMoved) {
174+
// Eliminate the case when the topic is updated but resolved/unresolved.
175+
isTopicMoved = MessageEditState.areSameTopic(event.origTopic!, event.newTopic!);
176+
}
177+
178+
// When nothing has been moved,
179+
// return early as the messages' editStates need no update.
180+
if (!isTopicMoved && !isChannelMoved) return;
181+
170182
// final newStreamId = event.newStreamId; // null if topic-only move
171183
// final newTopic = event.newTopic!;
172184
// TODO(#150): Handle message moves. The views' recipient headers
173185
// may need updating, and consequently showSender too.
186+
// Currently only editState gets updated.
187+
for (final messageId in event.messageIds) {
188+
final message = messages[messageId];
189+
if (message == null) continue;
190+
// Do not override the edited marker if the message has also been moved.
191+
if (message.editState == MessageEditState.edited) continue;
192+
message.editState = MessageEditState.moved;
193+
}
174194
}
175195

176196
void handleDeleteMessageEvent(DeleteMessageEvent event) {

test/example_data.dart

+29
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,35 @@ UpdateMessageEvent updateMessageEditEvent(
420420
);
421421
}
422422

423+
UpdateMessageEvent updateMessageMoveEvent(
424+
Message origMessage, {
425+
int? messageId,
426+
int? newStreamId,
427+
String? origTopic,
428+
String? newTopic,
429+
}) {
430+
messageId ??= origMessage.id;
431+
return UpdateMessageEvent(
432+
id: 0,
433+
userId: selfUser.userId,
434+
renderingOnly: false,
435+
messageId: messageId,
436+
messageIds: [messageId],
437+
flags: origMessage.flags,
438+
editTimestamp: 1234567890, // TODO generate timestamp
439+
origStreamId: origMessage is StreamMessage ? origMessage.streamId : null,
440+
newStreamId: newStreamId,
441+
propagateMode: null,
442+
origTopic: origTopic,
443+
newTopic: newTopic,
444+
origContent: 'some probably-mismatched old Markdown',
445+
origRenderedContent: origMessage.content,
446+
content: 'some probably-mismatched new Markdown',
447+
renderedContent: origMessage.content,
448+
isMeMessage: false,
449+
);
450+
}
451+
423452
UpdateMessageFlagsRemoveEvent updateMessageFlagsRemoveEvent(
424453
MessageFlag flag,
425454
Iterable<Message> messages, {

test/model/message_test.dart

+42
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,48 @@ void main() {
269269
test('rendering-only update does not change timestamp (for old server versions)', () async {
270270
await checkRenderingOnly(legacy: true);
271271
});
272+
273+
group('Handle message edit state update', () {
274+
final message = eg.streamMessage();
275+
276+
Future<void> sendEvent(Message message, UpdateMessageEvent event) async {
277+
await prepare();
278+
await prepareMessages([message]);
279+
280+
await store.handleEvent(event);
281+
checkNotifiedOnce();
282+
}
283+
284+
test('message not moved update', () async {
285+
await sendEvent(message, eg.updateMessageMoveEvent(message));
286+
check(store).messages.values.single.editState.equals(MessageEditState.none);
287+
});
288+
289+
test('message topic moved update', () async {
290+
await sendEvent(message, eg.updateMessageMoveEvent(message,
291+
origTopic: 'old topic',
292+
newTopic: 'new topic',
293+
));
294+
check(store).messages.values.single.editState.equals(MessageEditState.moved);
295+
});
296+
297+
test('message topic resolved update', () async {
298+
await sendEvent(message, eg.updateMessageMoveEvent(message,
299+
origTopic: 'new topic',
300+
newTopic: '✔ new topic',
301+
));
302+
check(store).messages.values.single.editState.equals(MessageEditState.none);
303+
});
304+
305+
test('message stream moved update', () async {
306+
await sendEvent(message, eg.updateMessageMoveEvent(message,
307+
origTopic: 'topic',
308+
newTopic: 'topic',
309+
newStreamId: 20,
310+
));
311+
check(store).messages.values.single.editState.equals(MessageEditState.moved);
312+
});
313+
});
272314
});
273315

274316
group('handleUpdateMessageFlagsEvent', () {

0 commit comments

Comments
 (0)