diff --git a/ui/src/routes/+layout.svelte b/ui/src/routes/+layout.svelte index 676474a..6c055a0 100644 --- a/ui/src/routes/+layout.svelte +++ b/ui/src/routes/+layout.svelte @@ -208,48 +208,69 @@ libnovel + {#if data.user} - - Library - - - Discover - + + + +
+ {#if data.user?.role === 'admin'} Scrape Audio cache {/if} {data.user.username} -
-
+ + +
{:else}
@@ -262,6 +283,60 @@
{/if} + + + {#if data.user && menuOpen} +
+ (menuOpen = false)} + class="px-3 py-2.5 rounded-lg text-sm font-medium transition-colors {page.url.pathname.startsWith('/books') ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100'}" + > + Library + + (menuOpen = false)} + class="px-3 py-2.5 rounded-lg text-sm font-medium transition-colors {page.url.pathname.startsWith('/browse') ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100'}" + > + Discover + + (menuOpen = false)} + class="px-3 py-2.5 rounded-lg text-sm font-medium transition-colors {page.url.pathname === '/profile' ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100'}" + > + Profile ({data.user.username}) + + {#if data.user?.role === 'admin'} +
+

Admin

+ (menuOpen = false)} + class="px-3 py-2.5 rounded-lg text-sm font-medium transition-colors {page.url.pathname.startsWith('/admin/scrape') ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100'}" + > + Scrape tasks + + (menuOpen = false)} + class="px-3 py-2.5 rounded-lg text-sm font-medium transition-colors {page.url.pathname.startsWith('/admin/audio') ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100'}" + > + Audio cache + + {/if} +
+
+ +
+
+ {/if}
diff --git a/ui/src/routes/browse/+page.svelte b/ui/src/routes/browse/+page.svelte index 85ba2f9..5f7ac67 100644 --- a/ui/src/routes/browse/+page.svelte +++ b/ui/src/routes/browse/+page.svelte @@ -152,6 +152,16 @@ // Admin: refresh catalogue let refreshing = $state(false); + + // ── Scroll-to-top button ───────────────────────────────────────────────── + let showScrollTop = $state(false); + $effect(() => { + function onScroll() { + showScrollTop = window.scrollY > 400; + } + window.addEventListener('scroll', onScroll, { passive: true }); + return () => window.removeEventListener('scroll', onScroll); + }); @@ -559,3 +569,17 @@

All novels loaded

{/if} {/if} + + +{#if showScrollTop} + +{/if}