diff options
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/lib/outbox.svelte.js | 47 | ||||
| -rw-r--r-- | ui/routes/(app)/+layout.js | 2 | ||||
| -rw-r--r-- | ui/routes/(app)/ch/[channel]/+page.svelte | 4 |
3 files changed, 51 insertions, 2 deletions
diff --git a/ui/lib/outbox.svelte.js b/ui/lib/outbox.svelte.js new file mode 100644 index 0000000..0681f29 --- /dev/null +++ b/ui/lib/outbox.svelte.js @@ -0,0 +1,47 @@ +import * as api from './apiServer.js'; +import * as md from './markdown.js'; + +class Message { + constructor(channel, body) { + this.channel = channel; + this.body = body; + this.renderedBody = md.render(body); + } +} + +export class Outbox { + pending = $state([]); + + static empty() { + return new Outbox([]); + } + + constructor(pending) { + this.pending = pending; + } + + send(channel, body) { + this.pending.push(new Message(channel, body)); + this.start(); + } + + start() { + if (this.sending) { + return; + } + // This is a promise transform primarily to keep the management of `this.sending` in one place, + // rather than spreading it across multiple methods. + this.sending = this.drain().finally(() => { + this.sending = null; + }); + } + + async drain() { + while (this.pending.length > 0) { + const { channel, body } = this.pending[0]; + + await api.retry(() => api.postToChannel(channel, body)); + this.pending.shift(); + } + } +} diff --git a/ui/routes/(app)/+layout.js b/ui/routes/(app)/+layout.js index 651bc8c..9c0afa8 100644 --- a/ui/routes/(app)/+layout.js +++ b/ui/routes/(app)/+layout.js @@ -1,8 +1,10 @@ import * as session from '$lib/session.svelte.js'; +import { Outbox } from '$lib/outbox.svelte.js'; export async function load() { let s = await session.boot(); return { + outbox: Outbox.empty(), session: s }; } diff --git a/ui/routes/(app)/ch/[channel]/+page.svelte b/ui/routes/(app)/ch/[channel]/+page.svelte index c8507cc..9506b67 100644 --- a/ui/routes/(app)/ch/[channel]/+page.svelte +++ b/ui/routes/(app)/ch/[channel]/+page.svelte @@ -7,7 +7,7 @@ import * as api from '$lib/apiServer'; const { data } = $props(); - const { session } = data; + const { session, outbox } = data; let activeChannel; const channel = $derived(page.params.channel); @@ -65,7 +65,7 @@ } async function sendMessage(message) { - await api.postToChannel(channel, message); + outbox.send(channel, message); } async function deleteMessage(id) { |
