feat: album names use Navidrome sortName tag when showRomaji is on

dispAlbumName now takes the full album object and reads album.sortName
directly — no kuromoji fallback, no backend translation.
dispAlbum (song context) also drops the kuromoji fallback, keeping only
the sortAlbum/albumSort file tag.

Override list → Navidrome sort tag → raw Japanese name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-08 22:42:53 +02:00
1 parent 4c3ec5726c
commit e3987a6376
5 files changed
+19 -15

No files matched your search

+3 -3
View File
@@ -1,6 +1,6 @@
import { S } from '../state.js';
import { esc, toast } from '../utils.js';
import { api, coverUrl, itunesSearch, itunesLookupAlbum, itunesLookupArtistSongs, itunesLookupArtistAlbums, fetchRomajiIndex, dispArtistById, cacheArtistSortNames } from '../api.js';
import { api, coverUrl, itunesSearch, itunesLookupAlbum, itunesLookupArtistSongs, itunesLookupArtistAlbums, fetchRomajiIndex, dispArtistById, dispAlbumName, dispAlbum, cacheArtistSortNames } from '../api.js';
import { makeCard, makeAlbumCard, makeGlobalTrackItem, makeSongItem } from '../ui/components.js';
import { playQueue, dlSongLocal, toggleStar, parseArtists } from '../player/player.js';
import { showCtxMenu, openDlModal } from '../ui/ui.js';
@@ -380,7 +380,7 @@ export async function loadItunesAlbumDetail(album) {
export async function loadAlbumDetail(album) {
document.getElementById('album-back-btn').onclick = () =>
album._fromArtist ? navigate('artist-detail', album._fromArtist) : navigate('albums');
document.getElementById('album-detail-name').textContent = album.name || '';
document.getElementById('album-detail-name').textContent = dispAlbumName(album);
const artistEl = document.getElementById('album-detail-artist');
artistEl.innerHTML = parseArtists(album)
.map(a => `<span class="song-link" onclick="event.stopPropagation();s_goArtist(event,'${esc(a.originalName||a.name)}','${esc(a.id||'')}')">${esc(dispArtistById(a.id, a.name))}</span>`)
@@ -396,7 +396,7 @@ export async function loadAlbumDetail(album) {
const totalMin = Math.round(songs.reduce((s,t) => s+(t.duration||0), 0) / 60);
document.getElementById('album-detail-stats').textContent = `${songs.length} Titel · ${r.album.year||''} · ${totalMin} Min.`;
if (songs[0]) {
document.getElementById('album-detail-name').textContent = songs[0].album || album.name || '';
document.getElementById('album-detail-name').textContent = dispAlbum(songs[0]) || dispAlbumName(album);
artistEl.innerHTML = parseArtists(songs[0])
.map(a => `<span class="song-link" onclick="event.stopPropagation();s_goArtist(event,'${esc(a.originalName||a.name)}','${esc(a.id||'')}')">${esc(dispArtistById(a.id, a.name))}</span>`)
.join('<span style="color:var(--text3)"> • </span>') || '';
+2 -2
View File
@@ -1,6 +1,6 @@
import { S } from '../state.js';
import { esc } from '../utils.js';
import { api, apiCached, apiIsCached, coverUrl, fetchRomajiIndex, dispArtistById, cacheArtistSortNames } from '../api.js';
import { api, apiCached, apiIsCached, coverUrl, fetchRomajiIndex, dispArtistById, dispAlbumName, cacheArtistSortNames } from '../api.js';
import { makeCard, makeAlbumCard, makeSongItem } from '../ui/components.js';
import { playQueue } from '../player/player.js';
// Circular — safe (called inside event handlers)
@@ -60,7 +60,7 @@ async function loadHeroCard() {
${thumbUrl ? `<img class="home-hero-cover" src="${thumbUrl}" alt="${esc(album.name)}">` : ''}
<div class="home-hero-info">
<div class="home-hero-label">${heroLabel}</div>
<div class="home-hero-title">${esc(album.name || '')}</div>
<div class="home-hero-title">${esc(dispAlbumName(album))}</div>
<div class="home-hero-artist">${esc(dispArtistById(album.artistId, album.artist || ''))}</div>
</div>
<button class="home-hero-play" title="Abspielen">