feat(library): genre sliders, artist links, and navigation utils
- music landing: diverse per-genre album sliders (online counts / offline wide-probe fallback) and home-screen library shortcuts - add ArtistLinks component and shared navigation/genreDiversity utils - player/playback-mode refinements across Rust and frontend
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import type { ArtistItem } from "$lib/api/types";
|
||||
|
||||
/**
|
||||
* Renders a comma-separated list of artist names. When the artists carry
|
||||
* ids (artistItems) each name links to that artist's detail page; otherwise
|
||||
* it falls back to plain text from the names-only `artists` array.
|
||||
*
|
||||
* Consolidates the artist-linking markup used on the player and detail
|
||||
* screens so every surface behaves the same way.
|
||||
*/
|
||||
interface Props {
|
||||
artistItems?: ArtistItem[] | null;
|
||||
artists?: string[] | null;
|
||||
/** Tailwind classes for the link colour/state. */
|
||||
linkClass?: string;
|
||||
/** Tailwind classes for the non-linkable fallback text. */
|
||||
textClass?: string;
|
||||
/** Called before navigating (e.g. to close a full-screen player). */
|
||||
onNavigate?: () => void;
|
||||
}
|
||||
|
||||
let {
|
||||
artistItems = null,
|
||||
artists = null,
|
||||
linkClass = "text-[var(--color-jellyfin)] hover:underline",
|
||||
textClass = "text-gray-400",
|
||||
onNavigate,
|
||||
}: Props = $props();
|
||||
|
||||
const linkable = $derived(
|
||||
(artistItems ?? []).filter((a) => a.id && a.id.trim() !== "")
|
||||
);
|
||||
|
||||
function handleClick(artistId: string, e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onNavigate?.();
|
||||
goto(`/library/${artistId}`);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if linkable.length > 0}
|
||||
<span class="inline-flex flex-wrap items-baseline gap-1">
|
||||
{#each linkable as artist, i (artist.id)}
|
||||
<button onclick={(e) => handleClick(artist.id, e)} class={linkClass}>
|
||||
{artist.name}
|
||||
</button>{#if i < linkable.length - 1}<span class={textClass}>,</span>{/if}
|
||||
{/each}
|
||||
</span>
|
||||
{:else if artists && artists.length > 0}
|
||||
<span class={textClass}>{artists.join(", ")}</span>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user