Update sidebar to the new page

This commit is contained in:
2026-09-24 19:25:15 +02:00
parent 88487064e1
commit 4ac73d8fa3
3 changed files with 81 additions and 44 deletions
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/state'; import { page } from '$app/state';
import { appNavLinks, isNavActive } from './navLinks'; import { appNavSections, isNavActive } from './navLinks';
import { playlistCover } from '$lib/utils/hrefs'; import { playlistCover } from '$lib/utils/hrefs';
import { liked } from '$lib/state/liked.svelte'; import { liked } from '$lib/state/liked.svelte';
import { createPlaylistModal } from '$lib/state/panels.svelte'; import { createPlaylistModal } from '$lib/state/panels.svelte';
@@ -29,7 +29,9 @@
const visiblePlaylists = $derived(playlists.slice(0, SIDEBAR_PLAYLISTS_LIMIT)); const visiblePlaylists = $derived(playlists.slice(0, SIDEBAR_PLAYLISTS_LIMIT));
const navLinks = $derived(appNavLinks(user, { playlists: playlistCount, liked: liked.count })); const navSections = $derived(
appNavSections(user, { playlists: playlistCount, liked: liked.count })
);
</script> </script>
<aside <aside
@@ -39,9 +41,16 @@
<Logo size="sm" /> <Logo size="sm" />
</a> </a>
<nav class="flex flex-col gap-1"> {#each navSections as section, index (index)}
{#each navLinks as link (link.href)} {#if index > 0}
{@const active = isNavActive(link.href)} <div class="mx-3 mt-6 mb-3.5 h-px bg-line"></div>
{/if}
{#if section.title}
<span class="px-3 pb-2 text-eyebrow text-fg-2">{section.title}</span>
{/if}
<nav class="flex flex-col gap-2">
{#each section.links as link (link.href)}
{@const active = isNavActive(link)}
<a <a
href={link.href} href={link.href}
aria-current={active ? 'page' : undefined} aria-current={active ? 'page' : undefined}
@@ -57,6 +66,7 @@
</a> </a>
{/each} {/each}
</nav> </nav>
{/each}
{#if user} {#if user}
<div class="mx-3 mt-6 mb-3.5 h-px bg-line"></div> <div class="mx-3 mt-6 mb-3.5 h-px bg-line"></div>
@@ -9,7 +9,7 @@
let { user, class: klass = '' }: Props = $props(); let { user, class: klass = '' }: Props = $props();
const links = $derived(appNavLinks(user).filter((link) => link.primary)); const links = $derived(appNavLinks(user).filter((link) => link.inMobileTabs));
</script> </script>
<nav <nav
@@ -17,7 +17,7 @@
style="padding-bottom:calc(0.4375rem + var(--mf-safe-b))" style="padding-bottom:calc(0.4375rem + var(--mf-safe-b))"
> >
{#each links as link (link.href)} {#each links as link (link.href)}
{@const active = isNavActive(link.href)} {@const active = isNavActive(link)}
<a <a
href={link.href} href={link.href}
aria-current={active ? 'page' : undefined} aria-current={active ? 'page' : undefined}
+45 -18
View File
@@ -1,12 +1,6 @@
import { page } from '$app/state'; import { page } from '$app/state';
import type { LucideIcon } from '@lucide/svelte'; import type { LucideIcon } from '@lucide/svelte';
import Home from '@lucide/svelte/icons/house'; import { House, Compass, ListMusic, Heart, Music } from '@lucide/svelte';
import Compass from '@lucide/svelte/icons/compass';
import ListMusic from '@lucide/svelte/icons/list-music';
import Heart from '@lucide/svelte/icons/heart';
import Disc from '@lucide/svelte/icons/disc-2';
import Folder from '@lucide/svelte/icons/folder';
import Upload from '@lucide/svelte/icons/upload';
import type { SessionUser } from '$lib/types'; import type { SessionUser } from '$lib/types';
export interface AppNavLink { export interface AppNavLink {
@@ -14,7 +8,13 @@ export interface AppNavLink {
label: string; label: string;
icon: LucideIcon; icon: LucideIcon;
count?: number; count?: number;
primary: boolean; inMobileTabs: boolean;
activeFor?: string[];
}
export interface AppNavSection {
title?: string;
links: AppNavLink[];
} }
export interface AppNavCounts { export interface AppNavCounts {
@@ -22,27 +22,54 @@ export interface AppNavCounts {
liked?: number; liked?: number;
} }
export function isNavActive(href: string): boolean { export function isNavActive(link: AppNavLink): boolean {
return [link.href, ...(link.activeFor ?? [])].some(isPathActive);
}
function isPathActive(href: string): boolean {
const section: string | null | undefined = page.data.section; const section: string | null | undefined = page.data.section;
if (section !== undefined) return section === href; if (section !== undefined) return section === href;
return href === '/' ? page.url.pathname === '/' : page.url.pathname.startsWith(href); return href === '/' ? page.url.pathname === '/' : page.url.pathname.startsWith(href);
} }
export function appNavLinks(user: SessionUser | null, counts: AppNavCounts = {}): AppNavLink[] { export function appNavSections(
if (!user) return [{ href: '/explore', label: 'Descubrir', icon: Compass, primary: true }]; user: SessionUser | null,
counts: AppNavCounts = {}
): AppNavSection[] {
if (!user)
return [ return [
{ href: '/', label: 'Inicio', icon: Home, primary: true }, { links: [{ href: '/explore', label: 'Descubrir', icon: Compass, inMobileTabs: true }] }
{ href: '/explore', label: 'Descubrir', icon: Compass, primary: true }, ];
return [
{
links: [
{ href: '/', label: 'Inicio', icon: House, inMobileTabs: true },
{ href: '/explore', label: 'Descubrir', icon: Compass, inMobileTabs: true },
{ {
href: '/playlists', href: '/playlists',
label: 'Playlists', label: 'Playlists',
icon: ListMusic, icon: ListMusic,
count: counts.playlists, count: counts.playlists,
primary: true inMobileTabs: true
}, },
{ href: '/liked', label: 'Me gusta', icon: Heart, count: counts.liked, primary: true }, { href: '/liked', label: 'Me gusta', icon: Heart, count: counts.liked, inMobileTabs: true }
{ href: '/albums', label: 'Mis álbumes', icon: Disc, primary: false }, ]
{ href: '/library', label: 'Canciones subidas', icon: Folder, primary: false }, },
{ href: '/upload', label: 'Subir música', icon: Upload, primary: false } {
title: 'Estudio',
links: [
{
href: '/library',
label: 'Gestionar música',
icon: Music,
inMobileTabs: false,
activeFor: ['/albums', '/upload']
}
]
}
]; ];
} }
export function appNavLinks(user: SessionUser | null, counts: AppNavCounts = {}): AppNavLink[] {
return appNavSections(user, counts).flatMap((section) => section.links);
}