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:
2026-06-11 16:53:00 +03:00
parent e97b7282ff
commit 370dfd95bc
+22 -1
View File
@@ -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"