domain: replace user-facing Jellyfin type badge with kind label (phase 3b)
The library detail page showed the raw Jellyfin item_type string
("MusicAlbum") to users. Add utils/mediaKind.ts with kindLabel(), a
presentation-only MediaKind -> human label map, and use it for the badge.
Flip the two remaining .type debug logs to .kind.
This removes the last user-visible Jellyfin vocabulary on the catalog
surface. primaryImageTag -> imageId rename (naming-only, ~40 sites across
catalog + player/merged types needing a Rust round-trip) intentionally
deferred as the lowest-value slice.
Frontend 644 tests, check clean.
This commit is contained in:
@@ -202,7 +202,7 @@ function createLibraryStore() {
|
|||||||
const repo = auth.getRepository();
|
const repo = auth.getRepository();
|
||||||
const item = await repo.getItem(itemId);
|
const item = await repo.getItem(itemId);
|
||||||
|
|
||||||
console.log(`[LibraryStore] loadItem(${itemId}): ${item.name} (${item.type})`);
|
console.log(`[LibraryStore] loadItem(${itemId}): ${item.name} (${item.kind})`);
|
||||||
console.log(`[LibraryStore] - Has people? ${item.people ? `YES (${item.people.length})` : 'NO'}`);
|
console.log(`[LibraryStore] - Has people? ${item.people ? `YES (${item.people.length})` : 'NO'}`);
|
||||||
if (item.people && item.people.length > 0) {
|
if (item.people && item.people.length > 0) {
|
||||||
item.people.forEach((p, i) => {
|
item.people.forEach((p, i) => {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Presentation helpers for the neutral MediaKind.
|
||||||
|
//
|
||||||
|
// MediaKind is the app's provider-neutral item classification (defined in Rust,
|
||||||
|
// generated into bindings). This module holds *display* concerns over it —
|
||||||
|
// human-readable labels — which are presentation, not domain, and so live in
|
||||||
|
// the frontend.
|
||||||
|
|
||||||
|
import type { MediaKind } from "$lib/api/types";
|
||||||
|
|
||||||
|
const KIND_LABELS: Record<MediaKind, string> = {
|
||||||
|
track: "Song",
|
||||||
|
album: "Album",
|
||||||
|
artist: "Artist",
|
||||||
|
playlist: "Playlist",
|
||||||
|
movie: "Movie",
|
||||||
|
series: "Series",
|
||||||
|
season: "Season",
|
||||||
|
episode: "Episode",
|
||||||
|
person: "Person",
|
||||||
|
channel: "Channel",
|
||||||
|
liveChannel: "Live TV",
|
||||||
|
channelItem: "Channel",
|
||||||
|
folder: "Folder",
|
||||||
|
other: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Human-readable label for a media kind (e.g. "Album"), or "" if unknown. */
|
||||||
|
export function kindLabel(kind: MediaKind | null | undefined): string {
|
||||||
|
if (!kind) return "";
|
||||||
|
return KIND_LABELS[kind] ?? "";
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import { page } from "$app/stores";
|
import { page } from "$app/stores";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { navigateBack } from "$lib/utils/navigation";
|
import { navigateBack } from "$lib/utils/navigation";
|
||||||
|
import { kindLabel } from "$lib/utils/mediaKind";
|
||||||
import { commands } from "$lib/api/bindings";
|
import { commands } from "$lib/api/bindings";
|
||||||
import type { MediaItem, Library } from "$lib/api/types";
|
import type { MediaItem, Library } from "$lib/api/types";
|
||||||
import { library, libraryItems, isLibraryLoading, currentLibrary, libraries } from "$lib/stores/library";
|
import { library, libraryItems, isLibraryLoading, currentLibrary, libraries } from "$lib/stores/library";
|
||||||
@@ -402,8 +403,8 @@
|
|||||||
|
|
||||||
<!-- Metadata -->
|
<!-- Metadata -->
|
||||||
<div class="flex items-center gap-4 text-sm text-gray-400">
|
<div class="flex items-center gap-4 text-sm text-gray-400">
|
||||||
{#if item.type}
|
{#if kindLabel(item.kind)}
|
||||||
<span class="px-2 py-1 bg-[var(--color-surface)] rounded">{item.type}</span>
|
<span class="px-2 py-1 bg-[var(--color-surface)] rounded">{kindLabel(item.kind)}</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if item.durationMs}
|
{#if item.durationMs}
|
||||||
<span>{formatDuration(item.durationMs)}</span>
|
<span>{formatDuration(item.durationMs)}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user