diff options
Diffstat (limited to 'ui/lib/store')
| -rw-r--r-- | ui/lib/store/channels.svelte.js | 115 | ||||
| -rw-r--r-- | ui/lib/store/logins.js | 22 | ||||
| -rw-r--r-- | ui/lib/store/messages.svelte.js | 79 |
3 files changed, 0 insertions, 216 deletions
diff --git a/ui/lib/store/channels.svelte.js b/ui/lib/store/channels.svelte.js deleted file mode 100644 index 9058d86..0000000 --- a/ui/lib/store/channels.svelte.js +++ /dev/null @@ -1,115 +0,0 @@ -import { DateTime } from 'luxon'; -import { get } from 'svelte/store'; -import { STORE_KEY_CHANNELS_DATA, EPOCH_STRING } from '$lib/constants'; - -export class Channels { - channels = $state([]); - - constructor({ channelsMetaList }) { - // This is the state wrapper around the channels meta object. Dammit. - this.channelsMetaList = channelsMetaList; - } - - getChannel(channelId) { - return this.channels.filter((ch) => ch.id === channelId)[0] || null; - } - - setChannels(channels) { - // Because this is called at initialization, we need to initialize the matching meta: - get(this.channelsMetaList).ensureChannels(channels); - this.channels = channels; - this.sort(); - return this; - } - - addChannel(id, name) { - const newChannel = { id, name }; - this.channels = [...this.channels, newChannel]; - get(this.channelsMetaList).initializeChannel(newChannel); - this.sort(); - return this; - } - - deleteChannel(id) { - const channelIndex = this.channels.map((e) => e.id).indexOf(id); - if (channelIndex !== -1) { - this.channels.splice(channelIndex, 1); - } - return this; - } - - sort() { - this.channels.sort((a, b) => { - if (a.name < b.name) { - return -1; - } else if (a.name > b.name) { - return 1; - } - return 0; - }); - } -} - -export class ChannelsMeta { - // Store channelId -> { draft = '', lastReadAt = null, scrollPosition = null } - channelsMeta = $state({}); - - constructor({ channelsMetaData }) { - const channelsMeta = objectMap(channelsMetaData, (ch) => { - let lastReadAt = ch.lastReadAt; - if (typeof lastReadAt === 'string') { - lastReadAt = DateTime.fromISO(lastReadAt); - } - if (!Boolean(lastReadAt)) { - lastReadAt = DateTime.fromISO(EPOCH_STRING); - } - return { - ...ch, - lastReadAt - }; - }); - this.channelsMeta = channelsMeta; - } - - writeOutToLocalStorage() { - localStorage.setItem(STORE_KEY_CHANNELS_DATA, JSON.stringify(this.channelsMeta)); - } - - updateLastReadAt(channelId, at) { - const channelObject = this.getChannel(channelId); - // Do it this way, rather than with Math.max tricks, to avoid assignment - // when we don't need it, to minimize reactive changes: - if (at > channelObject?.lastReadAt) { - channelObject.lastReadAt = at; - this.writeOutToLocalStorage(); - } - } - - ensureChannels(channelsList) { - channelsList.forEach(({ id }) => { - this.initializeChannel(id); - }); - } - - initializeChannel(channelId) { - if (!this.channelsMeta[channelId]) { - const channelData = { - lastReadAt: null, - draft: '', - scrollPosition: null - }; - this.channelsMeta[channelId] = channelData; - } - } - - getChannel(channelId) { - return this.channelsMeta[channelId] || null; - } -} - -function objectMap(object, mapFn) { - return Object.keys(object).reduce((result, key) => { - result[key] = mapFn(object[key]); - return result; - }, {}); -} diff --git a/ui/lib/store/logins.js b/ui/lib/store/logins.js deleted file mode 100644 index d449b3a..0000000 --- a/ui/lib/store/logins.js +++ /dev/null @@ -1,22 +0,0 @@ -export class Logins { - constructor() { - this.logins = {}; - } - - addLogin(id, name) { - this.logins[id] = name; - return this; - } - - setLogins(logins) { - this.logins = {}; - for (let { id, name } of logins) { - this.addLogin(id, name); - } - return this; - } - - get(id) { - return this.logins[id]; - } -} diff --git a/ui/lib/store/messages.svelte.js b/ui/lib/store/messages.svelte.js deleted file mode 100644 index dadade6..0000000 --- a/ui/lib/store/messages.svelte.js +++ /dev/null @@ -1,79 +0,0 @@ -import { DateTime } from 'luxon'; -import { marked } from 'marked'; -import DOMPurify from 'dompurify'; - -const RUN_COALESCE_MAX_INTERVAL = 10 /* min */ * 60 /* sec */ * 1000; /* ms */ - -export class Messages { - channels = $state({}); // Mapping<ChannelId, Message> - - inChannel(channel) { - return this.channels[channel] || []; - } - - addMessage(channel, id, { at, sender, body }) { - let parsedAt = DateTime.fromISO(at); - let renderedBody = DOMPurify.sanitize(marked.parse(body, { breaks: true })); - const message = { id, at: parsedAt, body, renderedBody }; - - // You might be thinking, can't this be - // - // let runs = (this.channels[channel] ||= []); - // - // Let me tell you, I thought that too. Javascript's semantics allow it. It - // didn't work - the first message in each channel was getting lost as the - // update to `this.channels` wasn't actually happening. I suspect this is - // due to the implementation of Svelte's `$state` rune, but I don't know it - // for sure. - // - // In any case, splitting the read and write up like this has the same - // semantics, and _works_. (This time, for sure!) - 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); - } - } - - this.channels[channel] = runs; - - 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; - } -} |
