diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2025-05-06 01:07:54 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2025-05-06 01:26:27 -0400 |
| commit | e4273ffd945f16d6f74e9c64431808ea36148880 (patch) | |
| tree | 336758ee57f7c4fa5a53002d8082b8e1978496d5 /ui/routes/(app) | |
| parent | adc1aef3dbc6b9d5f08f215d527a37e7cc59ddd9 (diff) | |
Render "ghost" messages for unsent messages.
There is a subtle race conditon in this code, which is likely not fixable without a protocol change:
* Ghost messages can disappear before their "real" message replacement shows up, if the client finishes sending (i.e., receives an HTTP response on the POST) before the server delivers the real message.
* Ghost messages can be duplicated briefly, if the client receives the real message before the client finishes sending.
Both happen in practice; we make no ordering guarantees between requests.
To aviod this, we'd to give clients a way to correlate pending sends with received messages. This would require fundamentally the same capabilities, like per-operation nonces, that preventing duplicate operations will require.
Diffstat (limited to 'ui/routes/(app)')
| -rw-r--r-- | ui/routes/(app)/ch/[channel]/+page.svelte | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/ui/routes/(app)/ch/[channel]/+page.svelte b/ui/routes/(app)/ch/[channel]/+page.svelte index ccf455c..50b6a7d 100644 --- a/ui/routes/(app)/ch/[channel]/+page.svelte +++ b/ui/routes/(app)/ch/[channel]/+page.svelte @@ -12,7 +12,11 @@ const channel = $derived(page.params.channel); const messages = $derived(session.messages.filter((message) => message.channel === channel)); - const messageRuns = $derived(runs(messages, session.currentUser)); + const unsent = $derived(outbox.messages.filter((message) => message.channel === channel)); + const unsentSkeletons = $derived( + unsent.map((message) => message.toSkeleton($state.snapshot(session.currentUser))) + ); + const messageRuns = $derived(runs(messages.concat(unsentSkeletons), session.currentUser)); function inView(parentElement, element) { const parRect = parentElement.getBoundingClientRect(); |
