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:
2026-07-23 21:31:51 +02:00
parent 7660a33dfc
commit 2b42b74912
3 changed files with 35 additions and 3 deletions
+1 -1
View File
@@ -202,7 +202,7 @@ function createLibraryStore() {
const repo = auth.getRepository();
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'}`);
if (item.people && item.people.length > 0) {
item.people.forEach((p, i) => {
+31
View File
@@ -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] ?? "";
}
+3 -2
View File
@@ -4,6 +4,7 @@
import { page } from "$app/stores";
import { goto } from "$app/navigation";
import { navigateBack } from "$lib/utils/navigation";
import { kindLabel } from "$lib/utils/mediaKind";
import { commands } from "$lib/api/bindings";
import type { MediaItem, Library } from "$lib/api/types";
import { library, libraryItems, isLibraryLoading, currentLibrary, libraries } from "$lib/stores/library";
@@ -402,8 +403,8 @@
<!-- Metadata -->
<div class="flex items-center gap-4 text-sm text-gray-400">
{#if item.type}
<span class="px-2 py-1 bg-[var(--color-surface)] rounded">{item.type}</span>
{#if kindLabel(item.kind)}
<span class="px-2 py-1 bg-[var(--color-surface)] rounded">{kindLabel(item.kind)}</span>
{/if}
{#if item.durationMs}
<span>{formatDuration(item.durationMs)}</span>