Update sidebar to the new page
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { appNavLinks, isNavActive } from './navLinks';
|
||||
import { appNavSections, isNavActive } from './navLinks';
|
||||
import { playlistCover } from '$lib/utils/hrefs';
|
||||
import { liked } from '$lib/state/liked.svelte';
|
||||
import { createPlaylistModal } from '$lib/state/panels.svelte';
|
||||
@@ -29,7 +29,9 @@
|
||||
|
||||
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>
|
||||
|
||||
<aside
|
||||
@@ -39,9 +41,16 @@
|
||||
<Logo size="sm" />
|
||||
</a>
|
||||
|
||||
<nav class="flex flex-col gap-1">
|
||||
{#each navLinks as link (link.href)}
|
||||
{@const active = isNavActive(link.href)}
|
||||
{#each navSections as section, index (index)}
|
||||
{#if index > 0}
|
||||
<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
|
||||
href={link.href}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
@@ -57,6 +66,7 @@
|
||||
</a>
|
||||
{/each}
|
||||
</nav>
|
||||
{/each}
|
||||
|
||||
{#if user}
|
||||
<div class="mx-3 mt-6 mb-3.5 h-px bg-line"></div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
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>
|
||||
|
||||
<nav
|
||||
@@ -17,7 +17,7 @@
|
||||
style="padding-bottom:calc(0.4375rem + var(--mf-safe-b))"
|
||||
>
|
||||
{#each links as link (link.href)}
|
||||
{@const active = isNavActive(link.href)}
|
||||
{@const active = isNavActive(link)}
|
||||
<a
|
||||
href={link.href}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import { page } from '$app/state';
|
||||
import type { LucideIcon } from '@lucide/svelte';
|
||||
import Home from '@lucide/svelte/icons/house';
|
||||
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 { House, Compass, ListMusic, Heart, Music } from '@lucide/svelte';
|
||||
import type { SessionUser } from '$lib/types';
|
||||
|
||||
export interface AppNavLink {
|
||||
@@ -14,7 +8,13 @@ export interface AppNavLink {
|
||||
label: string;
|
||||
icon: LucideIcon;
|
||||
count?: number;
|
||||
primary: boolean;
|
||||
inMobileTabs: boolean;
|
||||
activeFor?: string[];
|
||||
}
|
||||
|
||||
export interface AppNavSection {
|
||||
title?: string;
|
||||
links: AppNavLink[];
|
||||
}
|
||||
|
||||
export interface AppNavCounts {
|
||||
@@ -22,27 +22,54 @@ export interface AppNavCounts {
|
||||
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;
|
||||
if (section !== undefined) return section === href;
|
||||
return href === '/' ? page.url.pathname === '/' : page.url.pathname.startsWith(href);
|
||||
}
|
||||
|
||||
export function appNavLinks(user: SessionUser | null, counts: AppNavCounts = {}): AppNavLink[] {
|
||||
if (!user) return [{ href: '/explore', label: 'Descubrir', icon: Compass, primary: true }];
|
||||
export function appNavSections(
|
||||
user: SessionUser | null,
|
||||
counts: AppNavCounts = {}
|
||||
): AppNavSection[] {
|
||||
if (!user)
|
||||
return [
|
||||
{ href: '/', label: 'Inicio', icon: Home, primary: true },
|
||||
{ href: '/explore', label: 'Descubrir', icon: Compass, primary: true },
|
||||
{ links: [{ href: '/explore', label: 'Descubrir', icon: Compass, inMobileTabs: true }] }
|
||||
];
|
||||
return [
|
||||
{
|
||||
links: [
|
||||
{ href: '/', label: 'Inicio', icon: House, inMobileTabs: true },
|
||||
{ href: '/explore', label: 'Descubrir', icon: Compass, inMobileTabs: true },
|
||||
{
|
||||
href: '/playlists',
|
||||
label: 'Playlists',
|
||||
icon: ListMusic,
|
||||
count: counts.playlists,
|
||||
primary: true
|
||||
inMobileTabs: true
|
||||
},
|
||||
{ href: '/liked', label: 'Me gusta', icon: Heart, count: counts.liked, primary: 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 }
|
||||
{ href: '/liked', label: 'Me gusta', icon: Heart, count: counts.liked, inMobileTabs: true }
|
||||
]
|
||||
},
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user