web-player: TypeScript helpers (partial)
Add src/lib/actions/pressable.ts and clickOutside.ts (Svelte actions; role/tabindex stay static in markup for SSR accessibility, the action only adds click + Enter/Space) and src/lib/toggle.svelte.ts (createToggle), used by playlists.svelte.ts and queuePanel.svelte.ts. format.ts: adds plural(n, one, many); migrates the repo's 15 manual pluralizations, unifying them to lowercase (visible diff in Playlists, Home, liked, Explore). player.svelte.ts: adds toQueueItem, isQueueCurrent, playAllOrToggle, playShuffled; renames addToQueue -> playNextItem (the old name was misleading: it inserts next, not at the end). Migrates the 5 places that repeated the isCurrentQueue/playAll pattern (album, playlist, liked, mix, Home). Simplifies liked.svelte.ts and recentlyPlayed.ts with object spread instead of rebuilding every field by hand. navigation.svelte.ts: adds searchHref (migrates the duplicated buildHref from TopBar and Explore) and appNavLinks (added; its adoption in Sidebar/TabsBar is left for a later pass, as noted there). menus.svelte.ts: createTrackMenu() replaces the manual context-menu state (contextMenu + contextMenuStateFor + addToQueue) in Home, Explore and Mix. Deliberately left pending: removing tracks.ts's TrackTarget wrapper and its 8 accessors is deferred — it's the riskiest change in the plan, touches types across Home/Explore/Mix/menus, and couldn't be visually verified without Docker this session. Verified with npm run check/build.
This commit is contained in:
@@ -1,4 +1,13 @@
|
||||
import { afterNavigate } from '$app/navigation';
|
||||
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 type { SessionUser } from './types';
|
||||
|
||||
const HISTORY_INDEX = 'sveltekit:history';
|
||||
|
||||
@@ -54,3 +63,39 @@ export function isSectionActive(href: string, pathname: string, section?: string
|
||||
if (section !== undefined) return section === href;
|
||||
return href === '/' ? pathname === '/' : pathname.startsWith(href);
|
||||
}
|
||||
|
||||
export function searchHref(query: string): string {
|
||||
return query ? `/explore?q=${encodeURIComponent(query)}` : '/explore';
|
||||
}
|
||||
|
||||
export interface AppNavLink {
|
||||
href: string;
|
||||
label: string;
|
||||
icon: LucideIcon;
|
||||
count?: number;
|
||||
primary: boolean;
|
||||
}
|
||||
|
||||
export interface AppNavCounts {
|
||||
playlists?: number;
|
||||
liked?: number;
|
||||
}
|
||||
|
||||
export function appNavLinks(user: SessionUser | null, counts: AppNavCounts = {}): AppNavLink[] {
|
||||
if (!user) return [{ href: '/explore', label: 'Descubrir', icon: Compass, primary: true }];
|
||||
return [
|
||||
{ href: '/', label: 'Inicio', icon: Home, primary: true },
|
||||
{ href: '/explore', label: 'Descubrir', icon: Compass, primary: true },
|
||||
{
|
||||
href: '/playlists',
|
||||
label: 'Playlists',
|
||||
icon: ListMusic,
|
||||
count: counts.playlists,
|
||||
primary: 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 }
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user