From 588bd0f341e19028825ea70984cd2674bbb5dd1a Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Mon, 16 Feb 2026 15:28:25 -0800 Subject: [PATCH] Fix scroll to event behavior --- src/app/util/routes.ts | 26 ++++++++++++++++++-- src/routes/spaces/[relay]/[h]/+layout.svelte | 7 ++++++ src/routes/spaces/[relay]/[h]/+page.svelte | 9 ++++--- src/routes/spaces/[relay]/chat/+page.svelte | 8 +++--- 4 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 src/routes/spaces/[relay]/[h]/+layout.svelte diff --git a/src/app/util/routes.ts b/src/app/util/routes.ts index 28424bb4..001310d3 100644 --- a/src/app/util/routes.ts +++ b/src/app/util/routes.ts @@ -2,6 +2,7 @@ import type {Page} from "@sveltejs/kit" import {get} from "svelte/store" import * as nip19 from "nostr-tools/nip19" import {goto} from "$app/navigation" +import {page} from "$app/stores" import {nthEq} from "@welshman/lib" import type {TrustedEvent} from "@welshman/util" import {getAddress} from "@welshman/util" @@ -99,14 +100,35 @@ export const getPrimaryNavItemIndex = ($page: Page) => { } } +export const scrollToEvent = (id: string) => { + const element = document.querySelector(`[data-event="${id}"]`) as any + + if (element) { + element.scrollIntoView({behavior: "smooth", block: "center"}) + element.style = "filter: brightness(1.5); transition-property: all; transition-duration: 400ms;" + + setTimeout(() => { + element.style = "transition-property: all; transition-duration: 300ms;" + }, 800) + + setTimeout(() => { + element.style = "" + }, 800 + 400) + } + + return Boolean(element) +} + export const goToEvent = (event: TrustedEvent, options: Record = {}) => { const urls = Array.from(tracker.getRelays(event.id)) const path = getEventPath(event, urls) if (path.includes("://")) { window.open(path) - } else { - goto(path, options) + } else if (!scrollToEvent(event.id)) { + const replaceState = path.replace(/\?.*$/, "") === get(page).url.pathname + + goto(path, {replaceState, ...options}) } } diff --git a/src/routes/spaces/[relay]/[h]/+layout.svelte b/src/routes/spaces/[relay]/[h]/+layout.svelte new file mode 100644 index 00000000..efbb3754 --- /dev/null +++ b/src/routes/spaces/[relay]/[h]/+layout.svelte @@ -0,0 +1,7 @@ + + +{#key $page.url.searchParams.get("at")} + +{/key} diff --git a/src/routes/spaces/[relay]/[h]/+page.svelte b/src/routes/spaces/[relay]/[h]/+page.svelte index a64b798c..b5fca7ed 100644 --- a/src/routes/spaces/[relay]/[h]/+page.svelte +++ b/src/routes/spaces/[relay]/[h]/+page.svelte @@ -2,6 +2,7 @@ import {onMount, tick} from "svelte" import {readable} from "svelte/store" import {page} from "$app/stores" + import {goto} from "$app/navigation" import type {Readable} from "svelte/store" import {pubkey, publishThunk, waitForThunkError, joinRoom, leaveRoom} from "@welshman/app" import {now, int, formatTimestampAsDate, ago, MINUTE} from "@welshman/lib" @@ -60,6 +61,7 @@ const room = deriveRoom(url, h) const shouldProtect = canEnforceNip70(url) const membershipStatus = deriveUserRoomMembershipStatus(url, h) + const at = $derived(parseInt($page.url.searchParams.get("at") || String(now()))) const showRoomDetail = () => pushModal(RoomDetail, {url, h}) @@ -166,7 +168,7 @@ } const manageScrollPosition = () => { - showScrollButton = Math.abs(element?.scrollTop || 0) > 1500 + showScrollButton = Boolean(at) || Math.abs(element?.scrollTop || 0) > 1500 const newMessages = document.getElementById("new-messages") @@ -210,8 +212,7 @@ const scrollToBottom = () => { if ($page.url.searchParams.get("at")) { - at = now() - start() + goto($page.url.pathname, {replaceState: true}) } else { element?.scrollTo({top: 0, behavior: "smooth"}) } @@ -223,7 +224,6 @@ let isProgrammaticScroll = $state(false) let loadingBackward = $state(true) let loadingForward = $state(true) - let at = $state(parseInt($page.url.searchParams.get("at") || String(now()))) let share = $state(popKey("share")) let parent: TrustedEvent | undefined = $state() let element: HTMLElement | undefined = $state() @@ -353,6 +353,7 @@ observer.observe(chatCompose!) observer.observe(dynamicPadding!) + start() return () => { diff --git a/src/routes/spaces/[relay]/chat/+page.svelte b/src/routes/spaces/[relay]/chat/+page.svelte index 60a07433..e41ff886 100644 --- a/src/routes/spaces/[relay]/chat/+page.svelte +++ b/src/routes/spaces/[relay]/chat/+page.svelte @@ -1,6 +1,7 @@