project-robius / robrix

Robrix: a multi-platform Matrix chat client written in Rust using the Makepad UI toolkit and the Robius app dev framework
MIT License
107 stars 18 forks source link

Properly handle the `ReplyPreviewClicked` action for replied-to messages that aren't yet synced to the timeline #223

Closed kevinaboos closed 4 days ago

kevinaboos commented 3 weeks ago

We need to include the unique event ID of the replied-to message in the ReplyPreviewClicked action.

The complex case here is when the replied-to message hasn't been retrieved from the server (via pagination) and isn't yet locally available in the timeline. Currently we just log a warning that says "TODO: jumping back to a replied-to message that isn't yet locally retrieved is currently unsupported.

Implementation Strategy

If the Matrix SDK properly supported changing an existing timeline's mode from TimelineFocus::Live to TimelineFocus::Event, then we could do this easily. However, despite the documentation stating that this is supported, it is currently not actually implemented.

Thus, the only way we can implement this right now is to kickoff a special kind of back-pagination request. This async request would be a long-running one that accepts an Event ID (here, the event ID of the replied-to message) and continually runs back pagination requests until the given event becomes available in that timeline's history. Then, when the event ID is found, the background async task will send a response back to the RoomScreen instance containing the newest timeline instance along with index of the target replied-to event, such that the RoomScreen can immediately jump to it.

While waiting, the UI can show a loading spinner, either in a background element or by showing a foreground popup/modal that explains what is happening. The benefit of a modal is that we can offer the user a Cancel button so they can abort the request if things are taking too long, and that we can also show a status label to the user about how many messages are being back paginated.

Relatedly, we may also want to place a timeout on this back pagination task, as it is quite possible that the old item may not actually be found in the timeline (it could've been removed, etc). If we show a user popup/modal during the loading sequence, then a timeout wouldn't be necessary as the user could just manually cancel it.