-
Notifications
You must be signed in to change notification settings - Fork 310
New read_for_sender
flag when sending a new message
#456
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
Conversation
For the time being, CZO is still showing FL 226 (that is, the changes in the linked PR have not been deployed yet). So this might be premature to merge at the moment as I haven't confirmed the functionality with a live server. |
34454f0
to
2a04d12
Compare
Huh — that's surprising, because IIUC those server changes went into Zulip Server 8.0. And I'd certainly expect anything released in 8.0 to have already been deployed on CZO and on Zulip Cloud before that release happened (which was at the end of last week). In any case, it certainly seems to be deployed now. Looking at https://chat.zulip.org/api/changelog , it shows this change as FL 236, and as the latest API change deployed: (Same story on zulip.com, i.e. Zulip Cloud.) So this should be ripe for testing against a live server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sirpengi! Two comments below.
Let's also test this PR live against a server that has this feature — either chat.zulip.org or Zulip Cloud should work, as discussed above.
test/api/route/messages_test.dart
Outdated
}); | ||
}); | ||
|
||
test('to server without read_by_sender support', () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conveniently, the Zulip server actually ignores extra parameters sent in a request. So we can simplify by always sending this parameter, without checking whether the server is new enough to understand it.
lib/api/route/messages.dart
Outdated
@@ -193,6 +194,7 @@ Future<SendMessageResult> sendMessage( | |||
'content': RawParameter(content), | |||
if (queueId != null) 'queue_id': queueId, | |||
if (localId != null) 'local_id': localId, | |||
if (supportsReadBySender) 'read_by_sender': true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than hardcoding this to true within the API bindings, let's make it a parameter of this function, and then the caller passes true for it.
That way, the binding remains a thin layer exposing basically the same API as the server does itself, just in Dart. That in turn means the call sites in the application code (the code outside lib/api/
) can be read more or less directly against the Zulip Server API. I think that's helpful for reducing the number of layers one needs to look through and making it easier to understand what the code is doing.
(This function does have one significant deviation from the underlying API, in the destination
argument. What's happening there is basically that this part of the Zulip Server API isn't written in a way that's readily compatible with good clear static types, and so some rearrangement is needed in order to do a solid job of translating the API into Dart. But hard-coding this parameter is a different kind of matter, which is more about the specific needs and use cases we expect our application to have rather than about translating into Dart.)
d00ea21
to
6c59f1e
Compare
@gnprice updated PR as per your comments and have checked this against CZO (I looked into the issue with the outdated FL and posted about it in CZO: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/zulipFeatureLevel.20out.20of.20sync ) |
And in fact this turns up some behavior that seems suspicious! We have a couple of parameters that we're JSON-encoding, but they're strings, and I suspect they're not meant to be JSON-encoded. That's an aspect of the Zulip Server API which is generally not properly documented: some string parameters get JSON-encoded, others passed literally. (In either case the resulting string is ultimately HTTP-form-encoded to go into the POST request body.) So the way to learn the answer will be to actually try to use this feature and see what works. For now, just leave comments to help make that debugging easier, by disclaiming the presumption that the existing code is right.
This flag allows the client to communicate to the server that the new message should be initially marked as read for its sender. Flag was added in FL 236, see: zulip/zulip#28204 Fixes: zulip#440
I think we're always going to want this parameter to be true for all the messages we send from the app. In the API bindings themselves, i.e. in lib/api/ , I generally prefer not to hard-code this sort of thing. That lets the API bindings be a faithful reflection of the Zulip Server API, with a minimum of ad-hoc specializations for the needs of our app. So that's why the `sendMessage` binding just takes the parameter from its caller. But this method PerAccountStore.sendMessage is already something specific to our app rather than an API binding; it doesn't do much now beyond wrap the API, but the reason it exists is to be the future home of our "outbox" logic. That means (a) recording the message locally so that we can display it immediately, (b) possibly retrying the send, and (c) if the send fails or times out, recording that fact so that our UI can present the user with that information and the option to retry. So that makes it a natural home for encapsulating any other logic that this app will always want when sending a message. In particular, passing this parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the revision!
Generally this looks good; a few comments below. Some are probably easier to explain by showing rather than telling (and others are trivial, line length); so I'll fix these up myself, including a couple of additional commits, and merge.
lib/model/store.dart
Outdated
// TODO implement outbox; see design at | ||
// https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M3881.20Sending.20outbox.20messages.20is.20fraught.20with.20issues/near/1405739 | ||
return _apiSendMessage(connection, destination: destination, content: content); | ||
return _apiSendMessage(connection, destination: destination, content: content, readBySender: readBySender); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: line too long
lib/widgets/compose_box.dart
Outdated
@@ -733,7 +733,7 @@ class _SendButtonState extends State<_SendButton> { | |||
|
|||
final store = PerAccountStoreWidget.of(context); | |||
final content = widget.contentController.textNormalized; | |||
store.sendMessage(destination: widget.getDestination(), content: content); | |||
store.sendMessage(destination: widget.getDestination(), content: content, readBySender: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: line too long
test/api/route/messages_test.dart
Outdated
@@ -304,7 +304,7 @@ void main() { | |||
}) async { | |||
connection.prepare(json: SendMessageResult(id: 42).toJson()); | |||
final result = await sendMessage(connection, | |||
destination: destination, content: content); | |||
destination: destination, content: content, readBySender: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to write this test a little differently; but probably the simplest way to express how is by just writing it. So I'll do that before merging.
(And in fact, when I go to write the style of test I'm thinking of, I discover a pre-existing behavior that's likely wrong! So I'll end up with a prep commit adding that test and a comment, then your main commit tweaked to add this new parameter to that test.)
lib/model/store.dart
Outdated
Future<void> sendMessage({required MessageDestination destination, required String content}) { | ||
Future<void> sendMessage({required MessageDestination destination, required String content, bool? readBySender}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So in contrast to the API binding layer, this method on PerAccountStore I think actually is a good place to hard-code this parameter to true. I'll just add a commit on top making that change.
Here's the commit message I wrote for that commit, explaining why:
send [nfc]: Always pass readBySender true
I think we're always going to want this parameter to be true
for all the messages we send from the app.
In the API bindings themselves, i.e. in lib/api/ , I generally
prefer not to hard-code this sort of thing. That lets the API
bindings be a faithful reflection of the Zulip Server API, with
a minimum of ad-hoc specializations for the needs of our app.
So that's why the `sendMessage` binding just takes the parameter
from its caller.
But this method PerAccountStore.sendMessage is already something
specific to our app rather than an API binding; it doesn't do much
now beyond wrap the API, but the reason it exists is to be the
future home of our "outbox" logic. That means (a) recording the
message locally so that we can display it immediately, (b) possibly
retrying the send, and (c) if the send fails or times out, recording
that fact so that our UI can present the user with that information
and the option to retry.
So that makes it a natural home for encapsulating any other logic
that this app will always want when sending a message.
In particular, passing this parameter.
6c59f1e
to
48dc619
Compare
PR is built on top of #447 in order for tests to pass.
Adds a new flag introduced in zulip/zulip#28204 .
Fixes: #440