diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-11-06 18:42:38 -0500 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-11-06 20:44:21 -0500 |
| commit | 14dc9e1c1581fa04b37e81d76499f705512660b2 (patch) | |
| tree | 0a44ce50576fb501947fd7da1891a852981144b5 /ui/lib/store/messages.svelte.js | |
| parent | 1776711aaad56efe67365d69e2e9f8aa76ee67ef (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.js | 59 |
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; + } +} |
