Commit Graph
316 Commits
Author SHA1 Message Date
HoneyandClaude Sonnet 4.6 b7afa19f70 feat: romaji artist names, Apple Music autofill, romaji index invalidation
- Artist grid and detail header now show romaji names when toggle is on.
  Builds a Map<artistId, artistRomaji> from the existing song romaji index
  so no extra API call is needed.

- Apple Music autofill button added to edit modal next to MusicBrainz.
  Reuses the existing lookupItunesTrackMeta backend function via a new
  GET /api/itunes/lookup endpoint — fills album, year, genre, track#,
  and cover art.

- Romaji index is invalidated after every successful download so newly
  added songs appear with correct sort tags without requiring a page reload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 12:26:51 +02:00
HoneyandClaude Sonnet 4.6 212491aa89 fix: convert katakana proper nouns (e.g. ヨルシカ) to romaji in sort tags
When kuromoji marks a katakana token as reading '*' (unknown word — common
for band names like ヨルシカ), the code fell back to the surface_form which
is still katakana. _hiraToRomaji can't handle katakana so it passed through
unchanged, causing sort tags to show ヨルシカ instead of Yorushika.

Fix: if the surface_form contains katakana and reading is *, convert it
mechanically via _kataToHira + _hiraToRomaji — katakana-to-romaji is always
unambiguous and needs no dictionary.

Also add a Japanese-char guard in the frontend when applying romaji index
values, so stale cache entries can never overwrite correct values with Japanese.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:52:35 +02:00
HoneyandClaude Sonnet 4.6 e6d85e63a8 fix: clear sort tag fields synchronously before async fill
Sort tag fields were not reset when opening a new song's edit modal,
so values from the previously opened song persisted until the async
romaji index fetch completed (or indefinitely if it found no entry).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 00:40:16 +02:00
HoneyandClaude Sonnet 4.6 fb605b0b31 fix: ignore Japanese sort tags from file in edit modal
File sort tags containing Japanese characters are incorrect (sort tags
should be romaji/ASCII). Ignore them and keep the romaji index value
instead so the edit modal always shows the correct romaji pre-fill.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 20:39:49 +02:00
HoneyandClaude Sonnet 4.6 c73665af58 fix: load sort tags regardless of romaji toggle state
romajiLookup returned null when the index wasn't loaded (only loaded when
showRomaji is ON). Now fetchRomajiIndex is called on-demand in the edit modal
so sort tags pre-fill from the index works even when the toggle is OFF.
Actual file tags from /api/song-sorttags still overwrite as the final step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 20:14:51 +02:00
HoneyandClaude Sonnet 4.6 255ea1969c feat: load actual file sort tags in edit modal + remove settings hints
- backend: new GET /api/song-sorttags reads TITLESORT/ARTISTSORT/ALBUMARTISTSORT/
  ALBUMSORT directly from the file via ffprobe
- ui.js: pre-fill sort fields from romaji index, then overwrite with real file
  tags from the backend (shows actual values even if manually set)
- index.html: remove redundant hint texts in settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 22:42:34 +02:00
HoneyandClaude Sonnet 4.6 5dda1a7101 fix: iTunes Japanese artist lookup + sort tag editing in info modal
- views.js: skip ASCII word-match when artist name is non-ASCII so Japanese
  artists (e.g. ヨルシカ) resolve correctly to an iTunes artist ID
- index.html + styles.css: collapsible Sort-Tags section in edit modal
- ui.js: pre-fill sort fields from romaji index; include in save body
- novasonic-server.js: accept manual titleSort/artistSort/albumArtistSort/albumSort
  overrides; fall back to auto-computed romaji when not provided

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:49:47 +02:00
HoneyandClaude Sonnet 4.6 1c0d3eb4cc feat: remove Künstler sort pill from albums tab
Artists have their own dedicated tab so sorting albums by artist is redundant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:16:25 +02:00
HoneyandClaude Sonnet 4.6 5130ae24a9 feat: remove artist subtitle from album cards
Artist has its own tab so the redundant name below each album card isn't needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:15:01 +02:00
HoneyandClaude Sonnet 4.6 6a28ba786c fix: fetch romaji index on startup when showRomaji is enabled
On page reload the saved cfg restored showRomaji=true but _romajiMap was
never fetched, so all display helpers fell back to Japanese text. Await
fetchRomajiIndex before the first navigate when the setting is on.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:12:27 +02:00
HoneyandClaude Sonnet 4.6 1aff19e319 feat: keep Japanese in main tags, romaji in sort tags + frontend toggle
- Downloads now store original Japanese in TITLE/ARTIST/ALBUM tags
  so Apple Music, iTunes, YTM etc. all see the authentic original text
- Sort tags (TITLESORT/ARTISTSORT/ALBUMSORT) written with romaji for
  apps that use them for sorting/display
- iTunes-resolved English artist name used for ARTISTSORT and folder names
  when available (more accurate than kuromoji for known artists)
- rawArtist parameter added to downloadTrack so YTM search query uses
  the original Japanese channel name (fixes wrong song downloads)
- spotify.js: artistName preserved as original; itunesArtistName stored
  separately so the Spotify importer shows Japanese titles
- romaji index now includes titleRomaji/artistRomaji/albumRomaji fields
- Frontend: showRomaji setting (Settings > Bibliothek) — when on, player
  bar, now-playing, queue, and song lists all show romaji via index lookup
- refreshDisplayMode() updates all live UI when the toggle is saved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 14:58:53 +02:00
HoneyandClaude Sonnet 4.6 f1eabf7099 fix: playlist matching for romaji-stored Japanese tracks + punctuation cleanup
- Clean Japanese punctuation (、。・) in romajiForStorage so it doesn't pass through
- Add POST /api/romaji-convert endpoint for batch title conversion
- Add romajiConvert() to api.js
- Add third fallback in _createNdPlaylist: convert Japanese title to romaji and
  search Navidrome with it (for songs already downloaded with romaji tags)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 01:20:37 +02:00
HoneyandClaude Sonnet 4.6 c7bebd5691 fix: correct artist names and prevent wrong song downloads for Japanese tracks
- spotify.js: stop overwriting trackName with iTunes English title —
  yt-dlp must search with original Japanese title to find the right song
  (was downloading English covers e.g. Ghost In A Flower instead of 幽霊花)
- metadata.js: add title-only fallback in lookupItunesTrackMeta so tracks
  are found even when kuromoji gives wrong artist romanization (e.g.
  Terui Jun Sei vs iTunes Yoshimasa Terui); also return itunesArtistName
- novasonic-server.js: use itunesArtistName from iTunes lookup as the
  stored artist when available (single-track and playlist download paths)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 00:39:26 +02:00
HoneyandClaude Sonnet 4.6 392da7e021 fix: romaji for album names + Japanese playlist track matching
- ytdlp.js + novasonic-server.js: apply romajiForStorage to album tag
  and folder/rename paths (was only applied to artist/title before)
- ui.js: _createNdPlaylist falls back to romaji index for Japanese titles
  since Navidrome search3 doesn't index Japanese text properly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 00:36:16 +02:00
HoneyandClaude Sonnet 4.6 88533b8835 fix: verify iTunes artist name matches query before using result
iTunes ranks by popularity, so searching "WRLD Tunes" returned Juice WRLD
first. Now fetches 5 results and picks the first where all query words
appear in the iTunes artist name, preventing false-positive matches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 23:36:46 +02:00
HoneyandClaude Sonnet 4.6 36b09856ed fix: use iTunes names instead of kuromoji for Spotify Japanese tracks
Search iTunes with original Japanese names (accurate) rather than
pre-converting with kuromoji (inaccurate for uncommon names/readings).
iTunes returns the correct English artist name and title directly.
Also run iTunes enrichment for single-track Spotify imports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 23:13:34 +02:00
HoneyandClaude Sonnet 4.6 446c583f7f feat: normalize Japanese artist/title names to romaji at storage time
- Add romajiForStorage() to romaji.js — smart word spacing + Title Case
- ytdlp.js: apply to folder names, filenames, and embedded tags
- novasonic-server.js: apply in edit-metadata endpoint and Spotify resolve
- spotify.js: update track artist/name from iTunes canonical English names

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 20:22:22 +02:00
HoneyandClaude Sonnet 4.6 b63d93114a feat: show track number in iTunes album track list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:46:30 +02:00
HoneyandClaude Sonnet 4.6 1f13374438 fix: remove & as artist separator
Separators: • · ; , only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:32:19 +02:00
HoneyandClaude Sonnet 4.6 f03c6dfabd fix: remove space and / as artist separators, keep &
Separators: • · ; , & — space and / removed to avoid breaking multi-word artist names.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:31:52 +02:00
HoneyandClaude Sonnet 4.6 e5bb2bf2d3 feat: accept space, &, / as artist separators in metadata editor
- Space as fallback separator on save when no explicit separator present
  (Artist1 Artist2 → Artist1;Artist2)
- & and / added to explicit separator set everywhere
- navidromeArtist (download path) also handles /

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:30:18 +02:00
Honey 8a60ab2b98 Revert "feat: accept & and / as artist separators in metadata editor"
This reverts commit 64232a39fe.
2026-05-24 12:25:15 +02:00
HoneyandClaude Sonnet 4.6 64232a39fe feat: accept & and / as artist separators in metadata editor
_fmtArtists and _normalizeArtists now split on & and / in addition to
• · ; , — so "Arriez & King Dif" typed in the field normalizes correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:24:47 +02:00
HoneyandClaude Sonnet 4.6 11a31f85aa fix: populate albumArtist in metadata editor via getAlbum fallback
getSong often omits albumArtist; getAlbum always returns album.artist.
Enrich the song object before showing the edit form.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:50:22 +02:00
HoneyandClaude Sonnet 4.6 c6990cfd7b feat: remove album from song subtitle; add Go to Album in context menu
Album name no longer shown inline next to the artist — navigate via
right-click > Zum Album instead, available everywhere.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:47:43 +02:00
HoneyandClaude Sonnet 4.6 4842c89c4e 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>
2026-05-23 22:43:51 +02:00
HoneyandClaude Sonnet 4.6 7ba5b8ce9a feat: artist in filename, hide album=title subtitle, remove title hover
Naming convention (download + edit-metadata):
  Before: {01 - }Title.ext
  After:  {01 - }Artist1, Artist2 - Title.ext
- ytdlp.js: builds fileBase with artist prefix; findExistingTrack checks
  both new and old format so existing files aren't re-downloaded
- metadata.js: findExistingTrack accepts optional safeArtist param
- novasonic-server.js: file rename on title edit now includes artist
  (falls back to Navidrome's stored artist if not provided in body)

Song list subtitle: hide album name when album === title (singles where
the album is named after the track appear to duplicate the title)

Player bar: removed .player-title:hover underline/colour effect

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:33:35 +02:00
HoneyandClaude Sonnet 4.6 2dd3d7c7e5 fix: refresh edit form fields when getSong returns after edit mode opened
When the user opens the edit modal before the getSong async call returns,
the form fields are populated from the initial song object (from the song
list) which may omit albumArtist and other fields that only getSong
returns. Now, when getSong resolves and edit mode is already visible, all
form fields are updated to the authoritative Navidrome data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:28:28 +02:00
HoneyandClaude Sonnet 4.6 ae48ed4129 feat: YouTube/YT Music importer + album artist in view mode
- Info modal view now shows Album-Künstler row from Navidrome albumArtist
- Song Importer detects youtube.com / youtu.be URLs (red badge)
- New /api/youtube/resolve endpoint: yt-dlp --dump-json for single
  videos and playlists (up to 50 entries), enriched with iTunes lookup
  for proper album/year/genre/cover on single tracks
- New src/youtube.js renders preview card and delegates download to
  executeSpotifyDownload (which already handles sourceUrl → direct yt-dlp)
- Importer hint updated to list YouTube as a supported source

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 21:55:37 +02:00
HoneyandClaude Sonnet 4.6 3df1990d41 feat: add album artist field to metadata editor
Adds an editable Album-Künstler input to the info modal. Populated from
Navidrome's albumArtist field on open; saved as album_artist tag via
ffmpeg. Explicit value takes precedence; falls back to deriving from
artist (first semicolon segment) when artist is changed without an
explicit albumArtist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 21:50:45 +02:00
HoneyandClaude Sonnet 4.6 c052d6e913 fix: remove click-outside-to-close on info/metadata modal
The backdrop click handler was too easy to trigger accidentally,
especially when editing fields. Close button handles dismissal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 21:36:18 +02:00
HoneyandClaude Sonnet 4.6 d785a4c09a fix: SC metadata fields, albumartist & separator, importer clear, folder rename on album edit
- SC tracks: use artworkUrl/album/genre fields (not iTunes artworkUrl100/collectionName/primaryGenreName)
- Playlist handler: same SC field fallbacks for artwork, album, genre, year
- ytdlp.js: convert & to , in album_artist tag so Navidrome albumartist.Split works
- Importer: clear both previews on any URL input change, not just on clear
- edit-metadata: rename album folder on disk when album name changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 21:19:42 +02:00
HoneyandClaude Sonnet 4.6 62fefbb5e7 fix: import scDlSingle and scDlTrack in main.js to prevent runtime ReferenceError
Missing imports caused Object.assign(window,...) to throw before navigate
was ever assigned, breaking all onclick nav buttons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 20:56:16 +02:00
HoneyandClaude Sonnet 4.6 0e8eb311af fix: circular import causing navigate undefined; unified importer input
- Remove top-level ui.js import from soundcloud.js (broke views.js→soundcloud.js→ui.js→views.js cycle)
- Use window.executeSpotifyDownload() instead to avoid the circular dep
- Merge Spotify + SoundCloud into one unified URL input that auto-detects
  the service and colors the badge/button accordingly
- resolveImporterLink() routes to the correct handler based on URL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 20:39:21 +02:00
HoneyandClaude Sonnet 4.6 ee65183555 feat: SoundCloud downloader + rename page to Song Importer
- New src/soundcloud.js: resolves SoundCloud URLs via yt-dlp --dump-single-json,
  renders track/playlist preview with per-track download buttons
- Backend POST /api/soundcloud/resolve: extracts metadata (title, artist, genre,
  artwork, duration) directly from SoundCloud — no iTunes lookup needed
- ytdlp.js: sourceUrl param — if set, downloads directly from URL instead of
  ytsearch cascade (used for SoundCloud tracks)
- Spotify importer page renamed to Song Importer, now contains both
  Spotify and SoundCloud sections in one view

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 20:35:48 +02:00
HoneyandClaude Sonnet 4.6 5559857c15 feat: metadata editor with MusicBrainz autofill + cover art upload
- Info modal gets an edit pencil button that switches to edit form
- Editable fields: title, artist, album, genre, year, track#, disc#, total tracks
- Cover art: upload your own image or auto-fetch from Cover Art Archive via MusicBrainz
- MusicBrainz button queries /api/musicbrainz/lookup and autofills all fields
- Save POSTs to /api/edit-metadata which rewrites tags via ffmpeg and triggers Navidrome rescan
- Backend: GET /api/musicbrainz/lookup + POST /api/edit-metadata endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:22:11 +02:00
HoneyandClaude Sonnet 4.6 1a44f8bd73 feat: show newest albums first on home screen, recently played below
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:56:21 +02:00
HoneyandClaude Sonnet 4.6 a6e6af0333 fix: use parseArtists() on album detail page — stops Au/Ra splitting on /
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 14:13:02 +02:00
HoneyandClaude Sonnet 4.6 467ee8a0fe fix: consistent artist parsing across player, NP overlay, and song list
Extract parseArtists() helper — uses Navidrome's resolved artists array
when it has multiple entries, otherwise splits artist string on ';' only.
Removes old split on / that broke Au/Ra, HUNTR/X etc everywhere.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 13:08:33 +02:00
HoneyandClaude Sonnet 4.6 7b4e221881 fix: use Navidrome's resolved artists array instead of splitting on /
Manual split on / broke artist names like HUNTR/X and Au/Ra.
Now uses s.artists (OpenSubsonic array with correct IDs per artist)
and falls back to s.artist as a single unsplit link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 12:54:30 +02:00
HoneyandClaude Sonnet 4.6 4f83eebe79 feat: sort genre pills by total play count via backend
Page loads instantly with song-count order, then silently re-sorts
once the backend aggregates play counts across all songs. Result cached
20 min server-side to avoid repeated full-library fetches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 12:02:25 +02:00
HoneyandClaude Sonnet 4.6 790f02e5b4 feat: show 24 genre pills on desktop, 12 on mobile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 11:54:31 +02:00
HoneyandClaude Sonnet 4.6 6894e8a94a feat: Spotify-style shuffle — pre-shuffle queue, each song plays once
Shuffle now shuffles the queue array once (current song first, rest
randomised behind it) instead of picking a random index on every skip.
Toggling shuffle off restores the original queue order. Removed the
'once' repeat state added in the previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 00:31:50 +02:00
HoneyandClaude Sonnet 4.6 a8f56a9bc6 fix: genre shuffle/play no longer navigates away from genre page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 21:48:14 +02:00
HoneyandClaude Sonnet 4.6 89aeeb7421 fix: radio fill lock prevents concurrent fills; random fallback when similar songs exhausted
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 13:15:55 +02:00
HoneyandClaude Sonnet 4.6 b9a5c6468f refactor: dedup buildTrackList, extract topsong row helper, split romaji to lib
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:36:06 +02:00
HoneyandClaude Sonnet 4.6 79b878c546 fix: stay on queue tab when selecting song from NP queue view
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:27:53 +02:00
HoneyandClaude Sonnet 4.6 da185e1d96 fix: hero label shows source (Meistgespielt/Zuletzt gehört); play count column always visible when enabled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 09:53:43 +02:00
HoneyandClaude Sonnet 4.6 3128b06b24 fix: 15s scrobble, play count clarity, star always visible, all-songs actions
- Scrobble timer: 12s → 15s
- Play count moved after action buttons, shown as "23×" (distinct from duration)
- Song star/menu buttons always visible (removed opacity:0 hover-only rule)
- Artist all-songs page: added star + 3-dots to every row (same as top songs)
- Hero card: picks from full recent+frequent pool (was capped at first 5 = all frequent)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 09:47:06 +02:00
HoneyandClaude Sonnet 4.6 7e07fef7ba feat: timer scrobble (12s), artist topsong star+menu, play count toggle
Scrobbling:
- Replace end-of-track scrobble with 12s timer approach
- Android: schedule on onTrackChanged, cancel on pause
- Web: schedule in playCurrent, cancel in togglePlay pause + onEnded
- Skip/new track resets the timer automatically (new song ID)

Artist top songs:
- Add star button and 3-dots context menu to every top song row
- Topsong grid expanded to 5 columns to fit action buttons

Settings — play count toggle:
- New "Bibliothek" section with toggle switch
- When on: shows play count in album/playlist song rows
- Artist page always shows play count regardless of toggle
- Persisted in ns_cfg localStorage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 09:35:26 +02:00