diff options
Diffstat (limited to 'ui/routes')
| -rw-r--r-- | ui/routes/(app)/+layout.svelte | 7 | ||||
| -rw-r--r-- | ui/routes/(app)/ch/[channel]/+page.svelte | 31 | ||||
| -rw-r--r-- | ui/routes/+layout.svelte | 30 |
3 files changed, 46 insertions, 22 deletions
diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte index 6339abd..888a185 100644 --- a/ui/routes/(app)/+layout.svelte +++ b/ui/routes/(app)/+layout.svelte @@ -6,7 +6,7 @@ import TinyGesture from 'tinygesture'; import { boot, subscribeToEvents } from '$lib/apiServer'; - import { channelsList, currentUser, logins, messages, onEvent } from '$lib/store'; + import { channelsList, channelsMetaList, currentUser, logins, messages, onEvent } from '$lib/store'; import ChannelList from '$lib/components/ChannelList.svelte'; import CreateChannelForm from '$lib/components/CreateChannelForm.svelte'; @@ -20,11 +20,14 @@ 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; + const enrichedChannels = []; if (channels && messages) { for (let ch of channels) { @@ -32,7 +35,7 @@ let lastRun = runs?.slice(-1)[0]; let lastMessage = lastRun?.messages.slice(-1)[0]; let lastMessageAt = lastMessage?.at; - let hasUnreads = lastMessageAt > ch.lastReadAt; + let hasUnreads = lastMessageAt > channelsMeta[ch.id]?.lastReadAt; enrichedChannels.push({ ...ch, hasUnreads diff --git a/ui/routes/(app)/ch/[channel]/+page.svelte b/ui/routes/(app)/ch/[channel]/+page.svelte index 84cb0ae..54ebda7 100644 --- a/ui/routes/(app)/ch/[channel]/+page.svelte +++ b/ui/routes/(app)/ch/[channel]/+page.svelte @@ -3,7 +3,7 @@ import { page } from '$app/state'; import ActiveChannel from '$lib/components/ActiveChannel.svelte'; import MessageInput from '$lib/components/MessageInput.svelte'; - import { channelsList, messages } from '$lib/store'; + import { channelsMetaList, messages } from '$lib/store'; let channel = $derived(page.params.channel); let messageRuns = $derived($messages.inChannel(channel)); @@ -22,27 +22,22 @@ } function getLastVisibleMessage() { - const parentElement = activeChannel; - const childElements = parentElement.getElementsByClassName('message'); - const lastInView = Array.from(childElements) - .reverse() - .find((el) => { - return inView(parentElement, el); - }); - return lastInView; + if (activeChannel) { + const childElements = activeChannel.getElementsByClassName('message'); + const lastInView = Array.from(childElements) + .reverse() + .find((el) => { + return inView(activeChannel, el); + }); + return lastInView; + } } function setLastRead() { - const channelObject = $channelsList.getChannel(channel); const lastInView = getLastVisibleMessage(); - if (!channelObject || !lastInView) { - return; - } - const at = DateTime.fromISO(lastInView.dataset.at); - // 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; + if (lastInView) { + const at = DateTime.fromISO(lastInView.dataset.at); + $channelsMetaList.updateLastReadAt(channel, at); } } diff --git a/ui/routes/+layout.svelte b/ui/routes/+layout.svelte index 750f1f8..18c0541 100644 --- a/ui/routes/+layout.svelte +++ b/ui/routes/+layout.svelte @@ -1,11 +1,15 @@ <script> import { setContext } from 'svelte'; - import { onNavigate } from '$app/navigation'; + import { browser } from '$app/environment'; + import { goto, onNavigate, afterNavigate } from '$app/navigation'; + import { page } from '$app/stores'; import '../app.css'; import logo from '$lib/assets/logo.png'; - + import { STORE_KEY_LAST_ACTIVE } from '$lib/constants'; import { currentUser } from '$lib/store'; + let activeChannel = $derived($page.params.channel); + let pageContext = $state({ showMenu: false }); @@ -16,6 +20,28 @@ pageContext.showMenu = !pageContext.showMenu; } + function getLastActiveChannel() { + return ( + browser && JSON.parse(localStorage.getItem(STORE_KEY_LAST_ACTIVE)) + ); + } + + function setLastActiveChannel(channelId) { + browser && localStorage.setItem( + STORE_KEY_LAST_ACTIVE, + JSON.stringify(channelId) + ); + } + + afterNavigate(() => { + const lastActiveChannel = getLastActiveChannel(); + if (!activeChannel && lastActiveChannel) { + goto(`/ch/${lastActiveChannel}`); + } else { + setLastActiveChannel(activeChannel || null); + } + }); + onNavigate(() => { pageContext.showMenu = false; }); |
