diff options
Diffstat (limited to 'ui/lib/state/remote')
| -rw-r--r-- | ui/lib/state/remote/channels.svelte.js | 22 | ||||
| -rw-r--r-- | ui/lib/state/remote/logins.svelte.js | 18 | ||||
| -rw-r--r-- | ui/lib/state/remote/messages.svelte.js | 52 | ||||
| -rw-r--r-- | ui/lib/state/remote/state.svelte.js | 89 |
4 files changed, 181 insertions, 0 deletions
diff --git a/ui/lib/state/remote/channels.svelte.js b/ui/lib/state/remote/channels.svelte.js new file mode 100644 index 0000000..64edb09 --- /dev/null +++ b/ui/lib/state/remote/channels.svelte.js @@ -0,0 +1,22 @@ +import { SvelteMap } from 'svelte/reactivity'; + +export class Channels { + all = $state(); + + static boot(channels) { + const all = new SvelteMap(channels.map((channel) => [channel.id, channel])); + return new Channels({ all }); + } + + constructor({ all }) { + this.all = all; + } + + add({ id, name }) { + this.all.set(id, { id, name }); + } + + remove(id) { + this.all.delete(id); + } +} diff --git a/ui/lib/state/remote/logins.svelte.js b/ui/lib/state/remote/logins.svelte.js new file mode 100644 index 0000000..d19068d --- /dev/null +++ b/ui/lib/state/remote/logins.svelte.js @@ -0,0 +1,18 @@ +import { SvelteMap } from 'svelte/reactivity'; + +export class Logins { + all = $state(); + + static boot(logins) { + const all = new SvelteMap(logins.map((login) => [login.id, login])); + return new Logins({ all }); + } + + constructor({ all }) { + this.all = all; + } + + add({ id, name }) { + this.all.set(id, { id, name }); + } +} diff --git a/ui/lib/state/remote/messages.svelte.js b/ui/lib/state/remote/messages.svelte.js new file mode 100644 index 0000000..576a74e --- /dev/null +++ b/ui/lib/state/remote/messages.svelte.js @@ -0,0 +1,52 @@ +import { DateTime } from 'luxon'; +import { render } from '$lib/markdown.js'; + +class Message { + static boot({ id, at, channel, sender, body }) { + return new Message({ + id, + at: DateTime.fromISO(at), + channel, + sender, + body, + renderedBody: render(body) + }); + } + + constructor({ id, at, channel, sender, body, renderedBody }) { + this.id = id; + this.at = at; + this.channel = channel; + this.sender = sender; + this.body = body; + this.renderedBody = renderedBody; + } + + resolve(get) { + const { sender, ...rest } = this; + return new Message({ sender: get.sender(sender), ...rest }); + } +} + +export class Messages { + all = $state([]); + + static boot(messages) { + const all = messages.map(Message.boot); + return new Messages({ all }); + } + + constructor({ all }) { + this.all = all; + } + + add({ id, at, channel, sender, body }) { + const message = Message.boot({ id, at, channel, sender, body }); + this.all.push(message); + } + + remove(id) { + const index = this.all.findIndex((message) => message.id === id); + this.all.splice(index, 1); + } +} diff --git a/ui/lib/state/remote/state.svelte.js b/ui/lib/state/remote/state.svelte.js new file mode 100644 index 0000000..c4daf17 --- /dev/null +++ b/ui/lib/state/remote/state.svelte.js @@ -0,0 +1,89 @@ +import { Logins } from './logins.svelte.js'; +import { Channels } from './channels.svelte.js'; +import { Messages } from './messages.svelte.js'; + +export class State { + currentUser = $state(); + logins = $state(); + channels = $state(); + messages = $state(); + + static boot({ currentUser, logins, channels, messages, resumePoint }) { + return new State({ + currentUser, + logins: Logins.boot(logins), + channels: Channels.boot(channels), + messages: Messages.boot(messages), + resumePoint + }); + } + + constructor({ currentUser, logins, channels, messages, resumePoint }) { + this.currentUser = currentUser; + this.logins = logins; + this.channels = channels; + this.messages = messages; + this.resumePoint = resumePoint; + } + + onEvent(event) { + switch (event.type) { + case 'channel': + return this.onChannelEvent(event); + case 'login': + return this.onLoginEvent(event); + case 'message': + return this.onMessageEvent(event); + } + } + + onChannelEvent(event) { + switch (event.event) { + case 'created': + return this.onChannelCreated(event); + case 'deleted': + return this.onChannelDeleted(event); + } + } + + onChannelCreated(event) { + const { id, name } = event; + this.channels.add({ id, name }); + } + + onChannelDeleted(event) { + const { id } = event; + this.channels.remove(id); + } + + onLoginEvent(event) { + switch (event.event) { + case 'created': + return this.onLoginCreated(event); + } + } + + onLoginCreated(event) { + const { id, name } = event; + this.logins.add({ id, name }); + } + + onMessageEvent(event) { + switch (event.event) { + case 'sent': + return this.onMessageSent(event); + case 'deleted': + return this.onMessageDeleted(event); + } + } + + onMessageSent(event) { + const { id, at, channel, sender, body } = event; + this.messages.add({ id, at, channel, sender, body }); + } + + onMessageDeleted(event) { + const { id } = event; + this.messages.remove(id); + } +} |
