summaryrefslogtreecommitdiff
path: root/ui/lib/store/messages.svelte.js
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-11-06 18:42:38 -0500
committerOwen Jacobson <owen@grimoire.ca>2024-11-06 20:44:21 -0500
commit14dc9e1c1581fa04b37e81d76499f705512660b2 (patch)
tree0a44ce50576fb501947fd7da1891a852981144b5 /ui/lib/store/messages.svelte.js
parent1776711aaad56efe67365d69e2e9f8aa76ee67ef (diff)
Split message runs after ten minutes' silence.
I've also refactored how runs are processed, to avoid re-splitting runs every time the channel view is rendered. They're generated when messages are ingested into the `$messages` store, instead.
Diffstat (limited to 'ui/lib/store/messages.svelte.js')
-rw-r--r--ui/lib/store/messages.svelte.js59
1 files changed, 59 insertions, 0 deletions
diff --git a/ui/lib/store/messages.svelte.js b/ui/lib/store/messages.svelte.js
new file mode 100644
index 0000000..1c59599
--- /dev/null
+++ b/ui/lib/store/messages.svelte.js
@@ -0,0 +1,59 @@
+const RUN_COALESCE_MAX_INTERVAL = 10 /* min */ * 60 /* sec */ * 1000; /* ms */
+
+export class Messages {
+ channels = $state({});
+
+ inChannel(channel) {
+ return this.channels[channel];
+ }
+
+ addMessage(channel, id, at, sender, body) {
+ let parsedAt = new Date(at);
+ const message = { id, at: parsedAt, body };
+
+ let runs = (this.channels[channel] ||= []);
+ let currentRun = runs.slice(-1)[0];
+ if (currentRun === undefined) {
+ currentRun = { sender, messages: [message] };
+ runs.push(currentRun);
+ } else {
+ let lastMessage = currentRun.messages.slice(-1)[0];
+ let newRun =
+ currentRun.sender !== sender || parsedAt - lastMessage.at > RUN_COALESCE_MAX_INTERVAL;
+
+ if (newRun) {
+ currentRun = { sender, messages: [message] };
+ runs.push(currentRun);
+ } else {
+ currentRun.messages.push(message);
+ }
+ }
+
+ return this;
+ }
+
+ setMessages(messages) {
+ this.channels = {};
+ for (let { channel, id, at, sender, body } of messages) {
+ this.addMessage(channel, id, at, sender, body);
+ }
+ return this;
+ }
+
+ deleteMessage(messageId) {
+ for (let channel in this.channels) {
+ this.channels[channel] = this.channels[channel]
+ .map(({ sender, messages }) => ({
+ sender,
+ messages: messages.filter(({ id }) => id != messageId)
+ }))
+ .filter(({ messages }) => messages.length > 0);
+ }
+ return this;
+ }
+
+ deleteChannel(id) {
+ delete this.channels[id];
+ return this;
+ }
+}