diff --git a/web/src/lib/components/timeline/base-components/base-timeline-viewer.svelte b/web/src/lib/components/timeline/base-components/base-timeline-viewer.svelte index 980fc8d9c4..7c082b18fb 100644 --- a/web/src/lib/components/timeline/base-components/base-timeline-viewer.svelte +++ b/web/src/lib/components/timeline/base-components/base-timeline-viewer.svelte @@ -13,6 +13,7 @@ import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { mobileDevice } from '$lib/stores/mobile-device.svelte'; import { onMount, type Snippet } from 'svelte'; + import type { UpdatePayload } from 'vite'; interface Props { customThumbnailLayout?: Snippet<[TimelineAsset]>; @@ -189,12 +190,24 @@ { - const asset = $page.url.searchParams.get('at'); - if (asset) { - $gridScrollTarget = { at: asset }; + onAfterUpdate={(payload: UpdatePayload) => { + // when hmr happens, skeleton is initialized to true by default + // normally, loading asset-grid is part of a navigation event, and the completion of + // that event triggers a scroll-to-asset, if necessary, when then clears the skeleton. + // this handler will run the navigation/scroll-to-asset handler when hmr is performed, + // preventing skeleton from showing after hmr + const finishHmr = () => { + const asset = $page.url.searchParams.get('at'); + if (asset) { + $gridScrollTarget = { at: asset }; + } + void completeNav(); + }; + const assetGridUpdate = payload.updates.some((update) => update.path.endsWith('base-timeline-viewer.svelte')); + if (assetGridUpdate) { + // wait 500ms for the update to be fully swapped in + setTimeout(finishHmr, 500); } - void completeNav(); }} /> diff --git a/web/src/lib/components/timeline/base-components/hmr.svelte b/web/src/lib/components/timeline/base-components/hmr.svelte index 29ca885c25..d6120d7cbf 100644 --- a/web/src/lib/components/timeline/base-components/hmr.svelte +++ b/web/src/lib/components/timeline/base-components/hmr.svelte @@ -3,29 +3,14 @@ import type { UpdatePayload } from 'vite'; interface Props { - onHmr: () => void; + onAfterUpdate: (payload: UpdatePayload) => void; } - let { onHmr }: Props = $props(); + let { onAfterUpdate }: Props = $props(); onMount(() => { - const hmrSupport = () => { - // when hmr happens, skeleton is initialized to true by default - // normally, loading asset-grid is part of a navigation event, and the completion of - // that event triggers a scroll-to-asset, if necessary, when then clears the skeleton. - // this handler will run the navigation/scroll-to-asset handler when hmr is performed, - // preventing skeleton from showing after hmr - if (import.meta && import.meta?.hot) { - const afterUpdate = (payload: UpdatePayload) => { - const assetGridUpdate = payload.updates.some((update) => update.path.endsWith('base-timeline-viewer.svelte')); - if (assetGridUpdate) { - setTimeout(onHmr, 500); - } - }; - import.meta.hot?.on('vite:afterUpdate', afterUpdate); - return () => import.meta.hot?.off('vite:afterUpdate', afterUpdate); - } - return () => void 0; - }; - return hmrSupport(); + if (import.meta && import.meta?.hot) { + import.meta.hot?.on('vite:afterUpdate', onAfterUpdate); + return () => import.meta.hot?.off('vite:afterUpdate', onAfterUpdate); + } });