feat(frontend): remember each section's last list URL in the navbar
The bottom-nav links pointed at the bare section roots, so leaving a list and tapping its tab again dropped the active filter/sort in the query string. The root layout (which never unmounts) now records the last list root URL — including its query — per section on navigation, and the nav links target that remembered URL. Only the list root is recorded, so detail pages, the trash sub-view, and the shallow-routed file viewer don't hijack the tab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
import { afterNavigate } from '$app/navigation';
|
||||||
import { themeStore, toggleTheme } from '$lib/stores/theme';
|
import { themeStore, toggleTheme } from '$lib/stores/theme';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
@@ -35,6 +36,21 @@
|
|||||||
|
|
||||||
const isLogin = $derived($page.url.pathname === '/login');
|
const isLogin = $derived($page.url.pathname === '/login');
|
||||||
const isAdmin = $derived($page.url.pathname.startsWith('/admin'));
|
const isAdmin = $derived($page.url.pathname.startsWith('/admin'));
|
||||||
|
|
||||||
|
// Remember the last list URL (with its query — filter/sort) per section, so
|
||||||
|
// tapping a nav item returns you to where you left off rather than the bare
|
||||||
|
// root. The root layout never unmounts, so this map persists across the whole
|
||||||
|
// session. Only the section's list root is recorded (e.g. /files, not
|
||||||
|
// /files/<id> or /files/trash) — the tab should reopen the list, not a
|
||||||
|
// sub-screen or the viewer.
|
||||||
|
let lastUrl = $state<Record<string, string>>({});
|
||||||
|
|
||||||
|
afterNavigate((nav) => {
|
||||||
|
const url = nav.to?.url;
|
||||||
|
if (!url) return;
|
||||||
|
const item = navItems.find((it) => it.match === url.pathname);
|
||||||
|
if (item) lastUrl[item.match] = url.pathname + url.search;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{@render children()}
|
{@render children()}
|
||||||
@@ -43,7 +59,12 @@
|
|||||||
<footer>
|
<footer>
|
||||||
{#each navItems as item}
|
{#each navItems as item}
|
||||||
{@const active = $page.url.pathname.startsWith(item.match)}
|
{@const active = $page.url.pathname.startsWith(item.match)}
|
||||||
<a href={item.href} class="nav" class:curr={active} aria-label={item.label}>
|
<a
|
||||||
|
href={lastUrl[item.match] ?? item.href}
|
||||||
|
class="nav"
|
||||||
|
class:curr={active}
|
||||||
|
aria-label={item.label}
|
||||||
|
>
|
||||||
{#if item.label === 'Categories'}
|
{#if item.label === 'Categories'}
|
||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
|
|||||||
Reference in New Issue
Block a user