ui: add tags for dub and rebroadcast

This commit is contained in:
2026-02-10 04:26:10 -08:00
parent e0d6e5bc32
commit 48e5719813
7 changed files with 49 additions and 12 deletions

View File

@@ -19,6 +19,8 @@
artistName: string | null; artistName: string | null;
fileName?: string | null; fileName?: string | null;
globalPercent: number | null; globalPercent: number | null;
dub: boolean | null;
rebroadcast: boolean | null;
}; };
let { let {
@@ -30,6 +32,8 @@
artistName, artistName,
fileName = null, fileName = null,
globalPercent, globalPercent,
dub,
rebroadcast,
}: SongEntryProps = $props(); }: SongEntryProps = $props();
const typeLabelMap: Record<number, string> = { const typeLabelMap: Record<number, string> = {
@@ -54,6 +58,8 @@
songName, songName,
artistName, artistName,
fileName, fileName,
dub,
rebroadcast,
}), }),
); );
@@ -85,13 +91,16 @@
<div class="flex flex-col"> <div class="flex flex-col">
<div class="flex flex-wrap w-fit items-baseline gap-x-2 gap-y-1"> <div class="flex flex-wrap w-fit items-baseline gap-x-2 gap-y-1">
{animeName} {animeName}
<span <span class="tag">{displayTypeNumber}</span>
class="rounded bg-muted px-2 py-0.5 text-sm text-muted-foreground"
>{displayTypeNumber}</span
>
<span class="text-muted-foreground"> <span class="text-muted-foreground">
{globalPercent}% {globalPercent}%
</span> </span>
{#if dub}
<span title="Dub" class="tag">DUB</span>
{/if}
{#if rebroadcast}
<span title="Rebroadcast" class="tag">RB</span>
{/if}
</div> </div>
<div class="mt-1 w-fit text-foreground/80"> <div class="mt-1 w-fit text-foreground/80">

View File

@@ -118,6 +118,8 @@ export async function getAnimeWithSongsByAnnId(db: ClientDb, annId: number) {
annSongId: animeSongLinks.annSongId, annSongId: animeSongLinks.annSongId,
type: animeSongLinks.type, type: animeSongLinks.type,
number: animeSongLinks.number, number: animeSongLinks.number,
dub: animeSongLinks.dub,
rebroadcast: animeSongLinks.rebroadcast,
songName: songs.name, songName: songs.name,
fileName: songs.fileName, fileName: songs.fileName,
@@ -139,6 +141,8 @@ export async function getAnimeWithSongsByAnnId(db: ClientDb, annId: number) {
annSongId: r.annSongId, annSongId: r.annSongId,
type: r.type, type: r.type,
number: r.number, number: r.number,
dub: r.dub,
rebroadcast: r.rebroadcast,
songName: r.songName, songName: r.songName,
fileName: r.fileName, fileName: r.fileName,
globalPercent: r.globalPercent, globalPercent: r.globalPercent,
@@ -173,6 +177,8 @@ export async function getSongsForMalAnimeIds(
annSongId: animeSongLinks.annSongId, annSongId: animeSongLinks.annSongId,
type: animeSongLinks.type, type: animeSongLinks.type,
number: animeSongLinks.number, number: animeSongLinks.number,
dub: animeSongLinks.dub,
rebroadcast: animeSongLinks.rebroadcast,
songName: songs.name, songName: songs.name,
fileName: songs.fileName, fileName: songs.fileName,
@@ -233,6 +239,8 @@ export async function getSongsWithFilters(
type: animeSongLinks.type, type: animeSongLinks.type,
number: animeSongLinks.number, number: animeSongLinks.number,
dub: animeSongLinks.dub,
rebroadcast: animeSongLinks.rebroadcast,
animeAnnId: anime.annId, animeAnnId: anime.annId,
animeMainName: anime.mainName, animeMainName: anime.mainName,

View File

@@ -21,6 +21,8 @@ export type Track = {
type?: SongType; type?: SongType;
number?: number; number?: number;
fileName?: string | null; fileName?: string | null;
dub?: boolean | null;
rebroadcast?: boolean | null;
}; };
export type SongRowLike = { export type SongRowLike = {
@@ -31,6 +33,8 @@ export type SongRowLike = {
songName: string; songName: string;
artistName: string | null; artistName: string | null;
fileName?: string | null; fileName?: string | null;
dub: boolean | null;
rebroadcast: boolean | null;
}; };
/** /**
@@ -55,5 +59,7 @@ export function trackFromSongRow(row: SongRowLike): Track | null {
type: row.type, type: row.type,
number: row.number, number: row.number,
fileName, fileName,
dub: row.dub,
rebroadcast: row.rebroadcast,
}; };
} }

View File

@@ -36,6 +36,8 @@
songName: s.songName, songName: s.songName,
artistName: s.artistName, artistName: s.artistName,
fileName: s.fileName ?? null, fileName: s.fileName ?? null,
dub: Boolean(s.dub),
rebroadcast: Boolean(s.rebroadcast),
}), }),
) )
.filter((t) => t !== null); .filter((t) => t !== null);
@@ -57,8 +59,8 @@
{#if !data.annId} {#if !data.annId}
<h1 class="text-2xl font-semibold">Anime not found</h1> <h1 class="text-2xl font-semibold">Anime not found</h1>
<p class="mt-2 text-sm text-muted-foreground"> <p class="mt-2 text-sm text-muted-foreground">
The requested anime entry doesnt exist (or the route param wasnt a The requested anime entry doesnt exist (or the route param wasnt a valid
valid ANN id). ANN id).
</p> </p>
{:else if !data.animeWithSongs} {:else if !data.animeWithSongs}
<p class="mt-3 text-sm text-muted-foreground">Loading anime…</p> <p class="mt-3 text-sm text-muted-foreground">Loading anime…</p>
@@ -166,6 +168,8 @@
artistName={s.artistName} artistName={s.artistName}
fileName={s.fileName} fileName={s.fileName}
globalPercent={s.globalPercent} globalPercent={s.globalPercent}
dub={Boolean(s.dub)}
rebroadcast={Boolean(s.rebroadcast)}
/> />
</li> </li>
{/each} {/each}

View File

@@ -159,6 +159,10 @@
.chip input:checked + span { .chip input:checked + span {
@apply font-semibold; @apply font-semibold;
} }
.tag {
@apply rounded bg-muted px-2 py-0.5 text-sm text-muted-foreground;
}
} }
@layer scn { @layer scn {

View File

@@ -62,6 +62,8 @@
songName: r.songName, songName: r.songName,
artistName: songArtistLabel(r), artistName: songArtistLabel(r),
fileName: r.fileName, fileName: r.fileName,
dub: Boolean(r.dub),
rebroadcast: Boolean(r.rebroadcast),
}), }),
) )
.filter((t) => t !== null), .filter((t) => t !== null),
@@ -184,8 +186,8 @@
{#if (formMal ?? "").trim() && data.username && (data.malResponse?.data.length ?? 0) > 0 && data.songRows.length === 0} {#if (formMal ?? "").trim() && data.username && (data.malResponse?.data.length ?? 0) > 0 && data.songRows.length === 0}
<p class="mt-4 text-sm text-muted-foreground"> <p class="mt-4 text-sm text-muted-foreground">
No songs matched in the local database. This likely means none of the No songs matched in the local database. This likely means none of the MAL
MAL anime IDs exist in the AMQ DB. anime IDs exist in the AMQ DB.
</p> </p>
{/if} {/if}
@@ -204,6 +206,8 @@
artistName={songArtistLabel(r)} artistName={songArtistLabel(r)}
fileName={r.fileName} fileName={r.fileName}
globalPercent={r.globalPercent} globalPercent={r.globalPercent}
dub={Boolean(r.dub)}
rebroadcast={Boolean(r.rebroadcast)}
/> />
</li> </li>
{/each} {/each}

View File

@@ -49,6 +49,8 @@
songName: r.songName, songName: r.songName,
artistName: songArtistLabel(r), artistName: songArtistLabel(r),
fileName: r.fileName, fileName: r.fileName,
dub: Boolean(r.dub),
rebroadcast: Boolean(r.rebroadcast),
}), }),
) )
.filter((t) => t !== null), .filter((t) => t !== null),
@@ -124,9 +126,7 @@
label="Song Type" label="Song Type"
items={Object.keys(AmqSongLinkTypeMap).map((type) => ({ items={Object.keys(AmqSongLinkTypeMap).map((type) => ({
label: type, label: type,
value: AmqSongLinkTypeMap[ value: AmqSongLinkTypeMap[type as keyof typeof AmqSongLinkTypeMap],
type as keyof typeof AmqSongLinkTypeMap
],
}))} }))}
bind:value={params.type} bind:value={params.type}
/> />
@@ -190,6 +190,8 @@
artistName={songArtistLabel(r)} artistName={songArtistLabel(r)}
fileName={r.fileName} fileName={r.fileName}
globalPercent={r.globalPercent} globalPercent={r.globalPercent}
dub={Boolean(r.dub)}
rebroadcast={Boolean(r.rebroadcast)}
/> />
</li> </li>
{/each} {/each}