feat: artist separator normalization + separator hints in metadata editor

- Normalize •, ·, ;, , separators on save (both edit and download paths)
- Fix ndSong scope bug (was inaccessible outside try block in edit-metadata)
- Apply _normalizeArtists to artist/albumArtist before ffmpeg tags and file rename
- Storage format: Artist A;Artist B (no space, Navidrome/MusicBrainz style)
- Display format: Artist A; Artist B (space, via _fmtArtists in frontend)
- Show separator hint below label in metadata editor fields
- Remove hover effect on player bar song title

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-05-23 22:43:51 +02:00
1 parent 7ba5b8ce9a
commit 4842c89c4e
5 files changed
+40 -19

No files matched your search

+15 -8
View File
@@ -235,6 +235,13 @@ document.addEventListener('click', e => {
});
// ─── SONG INFO MODAL ───
// Normalize various artist separators (•, ;, ,) for display in the edit form.
// Track artist → "Serph; Zun" | Album artist → "Serph, Zun"
function _fmtArtists(str, sep) {
if (!str) return '';
return str.split(/\s*[•·;,]\s*/).map(s => s.trim()).filter(Boolean).join(sep);
}
function _renderInfoModal(s) {
const cv = coverUrl(s.coverArt, 200);
document.getElementById('info-cover').innerHTML = cv
@@ -278,10 +285,10 @@ export async function showSongInfo(s) {
// If edit mode was already opened before getSong returned, refresh the fields
// so the form shows the authoritative data (albumArtist, etc.) from Navidrome
if (document.getElementById('info-edit-mode').style.display !== 'none') {
document.getElementById('ie-title').value = full.title || '';
document.getElementById('ie-artist').value = full.artist || '';
document.getElementById('ie-albumartist').value = full.albumArtist || '';
document.getElementById('ie-album').value = full.album || '';
document.getElementById('ie-title').value = full.title || '';
document.getElementById('ie-artist').value = _fmtArtists(full.artist, '; ') || '';
document.getElementById('ie-albumartist').value = _fmtArtists(full.albumArtist, ', ') || '';
document.getElementById('ie-album').value = full.album || '';
document.getElementById('ie-genre').value = full.genre || '';
document.getElementById('ie-year').value = full.year || '';
document.getElementById('ie-track').value = full.track || '';
@@ -319,10 +326,10 @@ export function toggleInfoEdit() {
btn.classList.add('active');
// Populate fields from current song
document.getElementById('ie-title').value = s.title || '';
document.getElementById('ie-artist').value = s.artist || '';
document.getElementById('ie-albumartist').value = s.albumArtist || '';
document.getElementById('ie-album').value = s.album || '';
document.getElementById('ie-title').value = s.title || '';
document.getElementById('ie-artist').value = _fmtArtists(s.artist, '; ') || '';
document.getElementById('ie-albumartist').value = _fmtArtists(s.albumArtist, ', ') || '';
document.getElementById('ie-album').value = s.album || '';
document.getElementById('ie-genre').value = s.genre || '';
document.getElementById('ie-year').value = s.year || '';
document.getElementById('ie-track').value = s.track || '';