Skip to content

Add skeleton of handling a move UpdateMessageEvent #753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 21, 2024

Conversation

gnprice
Copy link
Member

@gnprice gnprice commented Jun 18, 2024

This PR is stacked atop #751.

Main commit:

The way the Zulip server API expresses whether there was a move,
and if so what kind of move, is a bit quirky. This change adds
logic to interpret that information into a more canonical form.

The logic here is translated from what we have in zulip-mobile:
https://github.com/zulip/zulip-mobile/blob/e352f563e/src/api/misc.js#L26

This doesn't yet do anything to actually update our data structures,
and it's an NFC change for release builds. The only behavior change
is new asserts that fire when the event from the server is malformed.


This is based on part of my draft branch for handling moved messages, #150. This covers the portion of that branch that's involved in just interpreting what an UpdateMessageEvent is saying about a message move, which is logic that will be needed in #171 / #750 too — so @PIG208 you'll want to rebase atop this.

The remainder of the draft branch is about actually updating Message.topic and Message.streamId to reflect a message move, and starting to update the data structures in MessageListView accordingly. So those changes will be needed for #150 but aren't involved in #171, and I'll leave them be for now and return to them sometime later.

@gnprice gnprice added the a-api Implementing specific parts of the Zulip server API label Jun 18, 2024
@gnprice gnprice requested review from chrisbobbe and PIG208 June 18, 2024 22:47
Comment on lines +170 to +173
// This event is a bit artificial, but convenient.
// TODO use a realistic move-messages event here
final updateEvent = Event.fromJson({
...eg.updateMessageEditEvent(message1).toJson(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PIG208 as part of #171 you'll be writing a helper for conveniently making UpdateMessageEvent values representing a move (an eg.updateMessageMoveEvent similar to the existing eg.updateMessageEditEvent). So then you can follow that with a small commit fixing this TODO.

return;
}

if (event.newTopic == null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this check a bit confusing (as well as the following one on origStreamId) before looking at the API doc. It could be helpful to spell out what we are expecting these checks (something that I can add in my PRs stacked atop this).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah, these are a bit terse.

Would this version explain it?

@@ -139,6 +139,9 @@ class MessageStoreImpl with MessageStore {
   }
 
   void _handleUpdateMessageEventMove(UpdateMessageEvent event) {
+    // The interaction between the fields of these events are a bit tricky.
+    // For reference, see: https://zulip.com/api/get-events#update_message
+
     if (event.origTopic == null) {
       // There was no move.
       assert(() {
@@ -154,10 +157,12 @@ class MessageStoreImpl with MessageStore {
     }
 
     if (event.newTopic == null) {
-      assert(debugLog('Malformed UpdateMessageEvent: move but no topic')); // TODO(log)
+      // The `subject` field (aka newTopic) is documented to be present on moves.
+      assert(debugLog('Malformed UpdateMessageEvent: move but no newTopic')); // TODO(log)
       return;
     }
     if (event.origStreamId == null) {
+      // The `stream_id` field (aka origStreamId) is documented to be present on moves.
       assert(debugLog('Malformed UpdateMessageEvent: move but no origStreamId')); // TODO(log)
       return;
     }

(That also fixes "no topic" to "no newTopic" — that's from a draft where I'd renamed that field only to "topic" rather than "newTopic".)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this works.

@gnprice gnprice force-pushed the pr-move-message-skeleton branch from e5e635e to 2f3ef32 Compare June 20, 2024 19:16
@chrisbobbe
Copy link
Collaborator

GitHub is showing that this has a conflict; Greg, could you resolve that please?

@gnprice gnprice force-pushed the pr-move-message-skeleton branch from 2f3ef32 to 058b711 Compare June 21, 2024 00:17
@gnprice
Copy link
Member Author

gnprice commented Jun 21, 2024

Sure — rebased.

Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool; thanks! One small comment below; if you think it's not an issue, or it's just an API-doc issue, please merge at will.

Comment on lines 95 to 104
void handleUpdateMessageEvent(UpdateMessageEvent event) {
_handleUpdateMessageEventTimestamp(event);
_handleUpdateMessageEventContent(event);
// TODO(#150): Handle message moves. The views' recipient headers
// may need updating, and consequently showSender too.
for (final view in _messageListViews) {
view.notifyListenersIfAnyMessagePresent(event.messageIds);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

message: Update all edit timestamps on UpdateMessageEvent

So in this commit, message lists check event.messageIds to see if they need to notify listeners, and they don't check event.messageId for that purpose. I think the API doc isn't quite explicit that message_ids will include the message ID for a pure content edit: https://zulip.com/api/get-events#update_message

I might be splitting hairs, though. On the message_id field, the doc does have this:

[…] the separate message_ids field, which is guaranteed to include message_id.

…but then again, here's the full sentence that quote is from:

If the channel or topic was changed, the set of moved messages is encoded in the separate message_ids field, which is guaranteed to include message_id.

I did just test a pure content edit, though, and the message ID did appear in message_ids.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does appear to be the case that message_ids always show up.

However, this feels like one of the cases where it will be more convenient if we know that the field should never be missing or nullable. Having our OpenAPI spec properly defined so that a "only present if ..." field is marked as nullable/required explicitly will definitely help.

Copy link
Collaborator

@chrisbobbe chrisbobbe Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so I'm not actually looking at whether the message_ids field is present or not; I'm assuming it is present. I'm looking for an API guarantee that, in a pure content-edit event, message_ids will include the ID of the edited message, instead of being an empty array. If it can be an empty array, then I expect a message list would fail to show the new content immediately, because we wouldn't be calling MessageListView.notifyListeners.

Copy link
Member Author

@gnprice gnprice Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I agree it'd be good to have that better nailed down. We have this in our API types in zulip-mobile:

  // Any stream/topic changes apply to all of message_ids, which is
  //   guaranteed to include message_id.
  // TODO(server-future): It'd be nice for these to be sorted; NB they may
  //   not be.  As of server 5.0-dev-3868-gca17a452f (2022-02), there's no
  //   guarantee of that in the API nor, apparently, in the implementation.
  message_ids: $ReadOnlyArray<number>,

Looks like that dates to zulip/zulip-mobile@4ce9e20 . That's actually after the era where we'd started having good API docs outside the zulip-mobile type definitions. But I don't see in that PR thread zulip/zulip-mobile#5155 , or the chat thread it links to, any discussion of this particular question.

Anyway, I do think we intend to make that guarantee. I'll ask in the thread and see about making it explicit in the API docs.

→ done: https://chat.zulip.org/#narrow/stream/378-api-design/topic/.60update_message.60.20event/near/1833971

@gnprice gnprice force-pushed the pr-move-message-skeleton branch from 058b711 to 00bd054 Compare June 21, 2024 22:17
@gnprice
Copy link
Member Author

gnprice commented Jun 21, 2024

Updated to add an assert checking the condition discussed above.

gnprice added 3 commits June 21, 2024 16:47
This way they nicely round-trip, which can be handy for tests.
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.
The way the Zulip server API expresses whether there was a move,
and if so what kind of move, is a bit quirky.  This change adds
logic to interpret that information into a more canonical form.

The logic here is translated from what we have in zulip-mobile:
  https://github.com/zulip/zulip-mobile/blob/e352f563e/src/api/misc.js#L26

This doesn't yet do anything to actually update our data structures,
and it's an NFC change for release builds.  The only behavior change
is new asserts that fire when the event from the server is malformed.
@chrisbobbe chrisbobbe force-pushed the pr-move-message-skeleton branch from 00bd054 to 155895a Compare June 21, 2024 23:48
@chrisbobbe
Copy link
Collaborator

Thanks, LGTM! Merging.

@chrisbobbe chrisbobbe merged commit 155895a into zulip:main Jun 21, 2024
1 check passed
@gnprice gnprice deleted the pr-move-message-skeleton branch June 24, 2024 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a-api Implementing specific parts of the Zulip server API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants