You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gnprice opened this issue
Mar 21, 2024
· 2 comments
Labels
a-apiImplementing specific parts of the Zulip server APIa-composeCompose box, autocomplete, attaching files/imagesa-contentParsing and rendering Zulip HTML content, notably message contentsa-syncEvent queue; retry; local echo; races
When you send a message, the message should eventually show up in the message list you're looking at: our sendMessage API request completes, then the server sends us a MessageEvent reflecting the new message. If you have a good network connection to the server and the server is functioning normally, this all happens pretty quickly.
But when that isn't the case, it's important for us to give some feedback in the UI to let the user know that their message is being sent. For example if we don't do that, the user may think it didn't work and they need to manually try again (by retyping the message); that's annoying to do and then leads to an unintended duplicate message. Here's a report of that in zulip-mobile, where we do show such feedback but apparently have a bug where it can be missing: zulip/zulip-mobile#2374 (comment)
Currently in this beta app we have no such feedback at all. In web and in zulip-mobile, when you hit send we immediately show a "local echo" of the message: the client parses the Markdown for itself, turns that into HTML attempting to mimic what the server will do, and renders it. (Plus a subtle cue to indicate the message isn't yet finished sending.) We should do something similar in this app.
The tricky part here is the implementation of Zulip's Markdown-based syntax. There are a few different ways this could happen:
There's a long-term plan for Zulip to develop and migrate to a new Djot-based message syntax, with a Rust implementation. When that's done, we can link the same Rust implementation into zulip-flutter that we use on the server.
It's unlikely that migration will be complete before we're rolling this app out to users in general. So we'll need one of the other solutions first.
We can transcribe Zulip web's Markdown implementation into Dart. Can probably get a usable version if I give it a couple days' focused work.
marked.js, the third-party main file at the core of that implementation, is real opaque if you want to make substantive changes. But it looks like its logic would be straightforward to clone, verbatim.
Note also that options like zulip and gfm are always the same in Zulip’s use, simplifying things.
Some of the extra logic that Zulip adds in our own file markdown.ts might be more annoying. Or it might not.
This is the solution I expect us to use for resolving this issue.
We could temporarily do a quick hack where we don't parse the message's markup at all: we either say something generic like "(Sending message…)", or possibly we show the raw message source as plain text.
I think a solution like this will inevitably look pretty janky: it won't quite match how the final message will look, and so there'll be a two-step effect where first this placeholder appears and then things shift again to show the actual message. The jankiness might be mitigated a bit if we put it on a debounce timer: e.g. we only show the placeholder if it's been like 300ms since we started to send, so that if you do get a fast reply from the server then there's no extra shift.
We might do this if we start hearing that the lack of feedback is really bugging people, and feel other priorities are more urgent for the kind of effort required for the proper solution described above. In that case we'll still want the proper solution before launch.
Related issues
We'll need to track in our state when a message starts getting sent, and then when we get the resulting MessageEvent from the server to complete the flow. That means an outbox system: Implement outbox system #133
(For purposes of this issue, it'll be enough to have a simplified outbox system with no retry.)
The text was updated successfully, but these errors were encountered:
gnprice
added
a-content
Parsing and rendering Zulip HTML content, notably message contents
a-compose
Compose box, autocomplete, attaching files/images
a-api
Implementing specific parts of the Zulip server API
labels
Mar 21, 2024
What if the App warns the user (with a pop-up) that due to connection problems sending messages is taking too long?Meanwhile the App will keep trying to send the message until the response from server.
A pop-up like that could be a potential alternative quick hack, in place of the quick hack mentioned above:
We could temporarily do a quick hack where we don't parse the message's markup at all: we either say something generic like "(Sending message…)", or possibly we show the raw message source as plain text.
But to fully resolve this issue we'll still want something smoother, like we have in zulip-mobile and Zulip web. Like this:
We can transcribe Zulip web's Markdown implementation into Dart. Can probably get a usable version if I give it a couple days' focused work.
a-apiImplementing specific parts of the Zulip server APIa-composeCompose box, autocomplete, attaching files/imagesa-contentParsing and rendering Zulip HTML content, notably message contentsa-syncEvent queue; retry; local echo; races
When you send a message, the message should eventually show up in the message list you're looking at: our
sendMessage
API request completes, then the server sends us aMessageEvent
reflecting the new message. If you have a good network connection to the server and the server is functioning normally, this all happens pretty quickly.But when that isn't the case, it's important for us to give some feedback in the UI to let the user know that their message is being sent. For example if we don't do that, the user may think it didn't work and they need to manually try again (by retyping the message); that's annoying to do and then leads to an unintended duplicate message. Here's a report of that in zulip-mobile, where we do show such feedback but apparently have a bug where it can be missing: zulip/zulip-mobile#2374 (comment)
Currently in this beta app we have no such feedback at all. In web and in zulip-mobile, when you hit send we immediately show a "local echo" of the message: the client parses the Markdown for itself, turns that into HTML attempting to mimic what the server will do, and renders it. (Plus a subtle cue to indicate the message isn't yet finished sending.) We should do something similar in this app.
The tricky part here is the implementation of Zulip's Markdown-based syntax. There are a few different ways this could happen:
There's a long-term plan for Zulip to develop and migrate to a new Djot-based message syntax, with a Rust implementation. When that's done, we can link the same Rust implementation into zulip-flutter that we use on the server.
It's unlikely that migration will be complete before we're rolling this app out to users in general. So we'll need one of the other solutions first.
We can transcribe Zulip web's Markdown implementation into Dart. Can probably get a usable version if I give it a couple days' focused work.
marked.js
, the third-party main file at the core of that implementation, is real opaque if you want to make substantive changes. But it looks like its logic would be straightforward to clone, verbatim.zulip
andgfm
are always the same in Zulip’s use, simplifying things.markdown.ts
might be more annoying. Or it might not.This is the solution I expect us to use for resolving this issue.
We could temporarily do a quick hack where we don't parse the message's markup at all: we either say something generic like "(Sending message…)", or possibly we show the raw message source as plain text.
I think a solution like this will inevitably look pretty janky: it won't quite match how the final message will look, and so there'll be a two-step effect where first this placeholder appears and then things shift again to show the actual message. The jankiness might be mitigated a bit if we put it on a debounce timer: e.g. we only show the placeholder if it's been like 300ms since we started to send, so that if you do get a fast reply from the server then there's no extra shift.
We might do this if we start hearing that the lack of feedback is really bugging people, and feel other priorities are more urgent for the kind of effort required for the proper solution described above. In that case we'll still want the proper solution before launch.
Related issues
MessageEvent
from the server to complete the flow. That means an outbox system:Implement outbox system #133
(For purposes of this issue, it'll be enough to have a simplified outbox system with no retry.)
The text was updated successfully, but these errors were encountered: