summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ui/lib/outbox.svelte.js47
-rw-r--r--ui/routes/(app)/+layout.js2
-rw-r--r--ui/routes/(app)/ch/[channel]/+page.svelte4
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) {