summaryrefslogtreecommitdiff
path: root/ui/routes/(app)
diff options
context:
space:
mode:
Diffstat (limited to 'ui/routes/(app)')
-rw-r--r--ui/routes/(app)/+layout.js8
-rw-r--r--ui/routes/(app)/+layout.svelte125
-rw-r--r--ui/routes/(app)/ch/[channel]/+page.svelte25
-rw-r--r--ui/routes/(app)/me/+page.svelte2
4 files changed, 51 insertions, 109 deletions
diff --git a/ui/routes/(app)/+layout.js b/ui/routes/(app)/+layout.js
new file mode 100644
index 0000000..651bc8c
--- /dev/null
+++ b/ui/routes/(app)/+layout.js
@@ -0,0 +1,8 @@
+import * as session from '$lib/session.svelte.js';
+
+export async function load() {
+ let s = await session.boot();
+ return {
+ session: s
+ };
+}
diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte
index 7818505..9ec5244 100644
--- a/ui/routes/(app)/+layout.svelte
+++ b/ui/routes/(app)/+layout.svelte
@@ -8,61 +8,42 @@
import TinyGesture from 'tinygesture';
import * as api from '$lib/apiServer.js';
- import {
- channelsList,
- channelsMetaList,
- currentUser,
- logins,
- messages,
- onEvent
- } from '$lib/store';
import ChannelList from '$lib/components/ChannelList.svelte';
import CreateChannelForm from '$lib/components/CreateChannelForm.svelte';
- let events = null;
let gesture = null;
+ const { data, children } = $props();
+ const { session } = data;
+
+ onMount(session.begin.bind(session));
+ onDestroy(session.end.bind(session));
+
let pageContext = getContext('page');
- let { children } = $props();
- let loading = $state(true);
let channel = $derived(page.params.channel);
- let rawChannels = $derived($channelsList.channels);
- let rawChannelsMeta = $derived($channelsMetaList.channelsMeta);
- let rawMessages = $derived($messages);
-
- let enrichedChannels = $derived.by(() => {
- const channels = rawChannels;
- const channelsMeta = rawChannelsMeta;
- const messages = rawMessages;
+ let rawChannels = $derived(session.channels);
+ let rawChannelsMeta = $derived(session.local.all);
+ let rawMessages = $derived(session.messages);
+ function enrichChannels(channels, channelsMeta, messages) {
const enrichedChannels = [];
- if (channels && messages) {
- for (let ch of channels) {
- let runs = messages.inChannel(ch.id);
- let lastRun = runs?.slice(-1)[0];
- let lastMessage = lastRun?.messages.slice(-1)[0];
- let lastMessageAt = lastMessage?.at;
- let hasUnreads = lastMessageAt > channelsMeta[ch.id]?.lastReadAt;
- enrichedChannels.push({
- ...ch,
- hasUnreads
- });
- }
+ for (const ch of channels.values()) {
+ const channelMessages = messages.filter((message) => message.channel === ch.id);
+ const lastMessage = channelMessages.slice(-1)[0];
+ const lastMessageAt = lastMessage?.at;
+ const lastReadAt = channelsMeta.get(ch.id)?.lastReadAt;
+ const hasUnreads = lastReadAt === null || lastMessageAt > lastReadAt;
+ enrichedChannels.push({
+ ...ch,
+ hasUnreads
+ });
}
return enrichedChannels;
- });
-
- function onBooted(boot) {
- currentUser.set({
- id: boot.login.id,
- username: boot.login.name
- });
- logins.update((value) => value.setLogins(boot.logins));
- channelsList.update((value) => value.setChannels(boot.channels));
- messages.update((value) => value.setMessages(boot.messages));
}
+ const enrichedChannels = $derived(enrichChannels(rawChannels, rawChannelsMeta, rawMessages));
+
function setUpGestures() {
if (!browser) {
// Meaningless if we're not in a browser, so...
@@ -77,46 +58,14 @@
});
}
- onMount(async () => {
- let response = await api.boot();
- switch (response.status) {
- case 200:
- onBooted(response.data);
- events = api.subscribeToEvents(response.data.resume_point);
- events.onmessage = onEvent.fromMessage;
- break;
- case 401:
- currentUser.set(null);
- await goto('/login');
- break;
- case 503:
- currentUser.set(null);
- await goto('/setup');
- break;
- default:
- // TODO: display error.
- break;
- }
- setUpGestures();
-
- loading = false;
- });
+ onMount(setUpGestures);
onDestroy(async () => {
- if (events !== null) {
- events.close();
- }
if (gesture !== null) {
gesture.destroy();
}
});
- function onbeforeunload(event) {
- if (events !== null) {
- events.close();
- }
- }
-
const STORE_KEY_LAST_ACTIVE = 'pilcrow:lastActiveChannel';
function getLastActiveChannel() {
@@ -142,25 +91,19 @@
}
</script>
-<svelte:window {onbeforeunload} />
-
<svelte:head>
<!-- TODO: unread count? -->
<title>pilcrow</title>
</svelte:head>
-{#if loading}
- <h2>Loading&hellip;</h2>
-{:else}
- <div id="interface">
- <nav id="sidebar" data-expanded={pageContext.showMenu}>
- <ChannelList active={channel} channels={enrichedChannels} />
- <div class="create-channel">
- <CreateChannelForm {createChannel} />
- </div>
- </nav>
- <main>
- {@render children?.()}
- </main>
- </div>
-{/if}
+<div id="interface">
+ <nav id="sidebar" data-expanded={pageContext.showMenu}>
+ <ChannelList active={channel} channels={enrichedChannels} />
+ <div class="create-channel">
+ <CreateChannelForm {createChannel} />
+ </div>
+ </nav>
+ <main>
+ {@render children?.()}
+ </main>
+</div>
diff --git a/ui/routes/(app)/ch/[channel]/+page.svelte b/ui/routes/(app)/ch/[channel]/+page.svelte
index 095e66a..c8507cc 100644
--- a/ui/routes/(app)/ch/[channel]/+page.svelte
+++ b/ui/routes/(app)/ch/[channel]/+page.svelte
@@ -3,24 +3,17 @@
import { page } from '$app/state';
import ActiveChannel from '$lib/components/ActiveChannel.svelte';
import MessageInput from '$lib/components/MessageInput.svelte';
- import { channelsList, channelsMetaList, currentUser, logins, messages } from '$lib/store';
+ import { runs } from '$lib/runs.js';
import * as api from '$lib/apiServer';
- let channel = $derived(page.params.channel);
- let messageRuns = $derived(
- $messages.inChannel(channel).map(({ sender, messages }) => {
- let senderName = $derived($logins.get(sender));
- let ownMessage = $derived($currentUser !== null && $currentUser.id === sender);
-
- return {
- sender: senderName,
- ownMessage,
- messages
- };
- })
- );
+ const { data } = $props();
+ const { session } = data;
let activeChannel;
+ const channel = $derived(page.params.channel);
+ const messages = $derived(session.messages.filter((message) => message.channel === channel));
+ const messageRuns = $derived(runs(messages, session.currentUser));
+
function inView(parentElement, element) {
const parRect = parentElement.getBoundingClientRect();
const parentTop = parRect.top;
@@ -49,12 +42,12 @@
const lastInView = getLastVisibleMessage();
if (lastInView) {
const at = DateTime.fromISO(lastInView.dataset.at);
- $channelsMetaList.updateLastReadAt(channel, at);
+ session.local.updateLastReadAt(channel, at);
}
}
$effect(() => {
- const _ = $messages.inChannel(channel);
+ const _ = session.messages;
setLastRead();
});
diff --git a/ui/routes/(app)/me/+page.svelte b/ui/routes/(app)/me/+page.svelte
index ab214e9..0c960c8 100644
--- a/ui/routes/(app)/me/+page.svelte
+++ b/ui/routes/(app)/me/+page.svelte
@@ -5,14 +5,12 @@
import { goto } from '$app/navigation';
import * as api from '$lib/apiServer.js';
- import { currentUser } from '$lib/store';
let invites = $state([]);
async function logOut() {
const response = await api.logOut();
if (200 <= response.status && response.status < 300) {
- currentUser.set(null);
await goto('/login');
}
}