Skip to content
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

Local echo when sending messages #576

Open
gnprice opened this issue Mar 21, 2024 · 2 comments
Open

Local echo when sending messages #576

gnprice opened this issue Mar 21, 2024 · 2 comments
Labels
a-api Implementing specific parts of the Zulip server API a-compose Compose box, autocomplete, attaching files/images a-content Parsing and rendering Zulip HTML content, notably message contents a-sync Event queue; retry; local echo; races
Milestone

Comments

@gnprice
Copy link
Member

gnprice commented Mar 21, 2024

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.)
@gnprice 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
@gnprice gnprice added this to the Launch milestone Mar 21, 2024
@dalonzoo
Copy link

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.

@gnprice
Copy link
Member Author

gnprice commented Apr 1, 2024

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.

@gnprice gnprice added the a-sync Event queue; retry; local echo; races label Oct 22, 2024
@gnprice gnprice modified the milestones: Launch, Post-launch Nov 21, 2024
@gnprice gnprice modified the milestones: M6: Post-launch, M5: Launch Dec 18, 2024
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 a-compose Compose box, autocomplete, attaching files/images a-content Parsing and rendering Zulip HTML content, notably message contents a-sync Event queue; retry; local echo; races
Projects
Status: No status
Development

No branches or pull requests

2 participants