Commit Graph
26 Commits
Author SHA1 Message Date
HoneyandClaude Sonnet 4.6 ca6dd87531 fix: drag-and-drop — set draggable upfront, add Firefox setData, fix duplicate dragend
draggable=true must be set before any mouse event (not on mousedown).
Firefox requires setData() for drag to work. Removed duplicate dragend
listener that was resetting draggable=false and conflicting with the first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 21:21:13 +02:00
HoneyandClaude Sonnet 4.6 8deeaa6475 feat: drag-and-drop reordering for playlist tracks
Drag handle appears on hover, moves items in DOM, syncs order to
songs array, and saves to Navidrome via createPlaylist 800ms after
last drop (debounced to avoid rapid API calls).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 21:15:48 +02:00
HoneyandClaude Sonnet 4.6 8a256b9463 feat: artist cards navigate-only (no play); add Top Songs + Shuffle buttons to artist detail page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 16:14:07 +02:00
HoneyandClaude Sonnet 4.6 a907773afb fix: artist link quotes in album detail; card art=play / info=navigate; artist play button via quickPlayArtist
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 16:03:53 +02:00
HoneyandClaude Sonnet 4.6 e75d90e165 fix: eliminate flash on skip, refresh home on nav
- renderQueue: in-place active-class update when queue unchanged — no DOM rebuild, no image reload
- updatePlayerUI: update img.src directly instead of replacing innerHTML
- _syncNpDirect: same img.src update for now-playing cover
- navigate('home'): always reloads home data so new albums appear without restart

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 09:21:12 +02:00
HoneyandClaude Sonnet 4.6 fef8578a27 feat: add greeting header and recently played row to home screen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 08:39:54 +02:00
HoneyandClaude Sonnet 4.6 a61436669e fix: per-span hover highlight, use • as artist separator everywhere
- CSS: target #player-artist-name span:hover and #np-artist-name span:hover so only the hovered artist name highlights, not all at once
- change artist separator from / to • in song items, player bar, now playing overlay, album header

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 00:51:38 +02:00
HoneyandClaude Sonnet 4.6 60c9cb6cbb fix: no artist/album links in playlist, add comma to artist split
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 00:35:05 +02:00
HoneyandClaude Sonnet 4.6 e5a80242e9 fix: split multi-artists by • and /, clickable artist/album in playlists and album detail
- components.js: expand artist split regex to handle both ' / ' and '•' separators
- views.js: enable artist+album links in playlist song items (were noArtistLink:true)
- views.js: enable artist links in album detail song items
- views.js: album header artist is now split and renders as clickable links

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 00:31:48 +02:00
HoneyandClaude Sonnet 4.6 51babd9e41 fix: bump SW cache to v39, split multi-artists by ' / ', name-search fallback for artist nav
- sw.js: ns-v38 → ns-v39 forces PWA cache clear so previous fixes take effect
- components: split s.artist by ' / ' in makeSongItem — each part becomes its
  own clickable link; noArtistLink turns all parts into plain text
- views: s_goArtist searches Navidrome by name when no artistId is available
  (needed for secondary artists that only have the primary artistId in the song)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 00:13:13 +02:00
HoneyandClaude Sonnet 4.6 9da48b88d8 fix: lyrics race condition, PC scroll, artwork matching, accidental artist/album taps
- nowplaying: add cancellation token to _loadNpLyrics to prevent stale async
  calls overwriting newer results (synced→plain race condition)
- nowplaying: replace scrollIntoView with explicit container.scrollTo to prevent
  page-level scroll on desktop (topbar shifting / gap at edge)
- backend: remove results[0] fallback in lookupItunesTrackMeta — only use
  exact title+artist match to avoid embedding wrong artwork
- components/views: makeSongItem accepts noArtistLink/noAlbumLink opts;
  album-detail disables both, playlist-detail disables artist link

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 23:42:29 +02:00
HoneyandClaude Sonnet 4.6 16b7faee2b refactor: split views.js and ui.js into focused modules
Extract 3 new files from oversized source files:
- src/components.js (~86 lines): makeCard, makeAlbumCard, makeSongItem,
  makeGlobalTrackItem, mkSection — reusable DOM builders
- src/spotify.js (~187 lines): loadSpotifyImporter, resolveSpotifyLink,
  clearSpotifyPreview, spotifyDlAll, and private render/artwork helpers
- src/nowplaying.js (~255 lines): openNowPlaying, closeNowPlaying,
  syncNowPlaying, switchNpTab, full lyrics engine, renderNpQueue,
  npGoArtist/Album, openNpMenu/closeNpMenu

views.js: 1121 → 864 lines
ui.js:     706 → 462 lines

Update imports in main.js, player.js, views.js accordingly.
Build verified: 15 modules, no errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 19:20:00 +02:00
HoneyandClaude Sonnet 4.6 4bdf3c7cbc fix(views): merge duplicate api.js imports into one line
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 19:11:21 +02:00
HoneyandClaude Sonnet 4.6 5446d83ab3 feat(spotify): lazy-load per-track iTunes artwork for playlists/albums
Adds POST /api/spotify/track-artwork endpoint that takes an array of
{idx, trackName, artistName} and returns iTunes artwork URLs in batches
of 8 concurrent requests.

Frontend calls this after rendering the track list, then patches each
.gtrack-art element with the correct album cover as results arrive.
Also updates _spotifyResolved.tracks so downloads use the right artwork.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 18:19:08 +02:00
HoneyandClaude Sonnet 4.6 393b88c823 fix(spotify): handle GraphQL embed structure, all artists, correct metadata
- _spTrackItem now unwraps GraphQL-style {data:{__typename,...}} wrappers
- _spAllArtists joins all featured artists (e.g. "Kløn, Renzyx")
- _spArtwork adds albumOfTrack path used by newer Spotify embed
- fetchSpotifyEmbed: added entity.content.items / entity.data fallback paths
- Track download now uses Spotify metadata directly (album, art, year,
  trackNum) when provided — avoids iTunes returning wrong album for
  multi-artist tracks
- Playlist trackList also tries entity.content.items and entity.tracks.items
- Frontend: redesigned preview card with green top accent, bigger art,
  playlist checkbox styled as pill with Spotify color on check, album
  button shows actual album name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 01:59:12 +02:00
HoneyandClaude Sonnet 4.6 cfa8a8cd49 fix: use Spotify public web-player token — no Premium/API account needed
Replace Client Credentials flow with Spotify's public web-player token endpoint
(open.spotify.com/get_access_token) which works without any account or Premium.
Remove Spotify credential fields from UI entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 01:32:56 +02:00
HoneyandClaude Sonnet 4.6 f7a5247f17 feat: Spotify Importer — link → yt-dlp download + optional Navidrome playlist
- New 'Spotify Importer' page under Entdecken (sidebar + mobile nav)
- Backend: POST /api/spotify/resolve — resolves track/album/playlist URLs via Spotify API
- Backend: new 'playlist' download type accepting pre-resolved track list (no iTunes re-fetch)
- Frontend: paste Spotify link → preview with cover, type badge, track list
  - Track: single download or full album via iTunes fallback
  - Album: download all tracks with Spotify metadata
  - Playlist: download all tracks + optional 'Als Navidrome-Playlist speichern' checkbox
- Navidrome playlist creation: searches library by title/artist after download, creates playlist
- Spotify Client ID + Secret stored in app settings (setup screen + settings modal)
- iTunes metadata tags kept for all downloaded files (existing pipeline unchanged)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 00:56:11 +02:00
HoneyandClaude Sonnet 4.6 9bf6d189df fix: artist hero banner taller on desktop, fix right-side overlay bleed
- Hero height 220px mobile → 320px desktop (min-width: 769px)
- Larger artist name (46px) and more padding on desktop
- Overlay gradient now also darkens the right edge instead of fading to transparent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 22:12:38 +02:00
HoneyandClaude Sonnet 4.6 976e80f86d feat: all-songs view as separate page, iTunes album detail page
- 'Alle X Songs' button now navigates to a dedicated page instead of expanding inline
- Partial/not-downloaded albums now open an iTunes album detail page with track list,
  preview buttons and download option
- Added page-artist-all-songs and page-itunes-album-detail to index.html
- Replaced _expandArtistAllSongs with loadArtistAllSongs + loadItunesAlbumDetail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:23:16 +02:00
HoneyandClaude Sonnet 4.6 72f6087043 feat: unified artist page with full iTunes/Navidrome album categorization
- loadArtistDetail now works for both Navidrome artists and iTunes-only
  artists (id=null + itunesArtistId). loadItunesArtistResults from global
  search now navigates to the same artist-detail page.
- Album sections: "In Library" (fully downloaded), "Unvollständig" (partial
  — e.g. 2/12 tracks), "Noch nicht heruntergeladen" (iTunes-only). Partial
  albums show X/Y badge and a direct download button on hover.
- iTunes albums now fetched via lookup endpoint (up to 200 albums) instead
  of search (max 20), fixing the missing-albums problem.
- "Alle X Songs in Library" expand button fetches all songs across albums
  and renders them grouped by album with play/context-menu support.
- Back button uses _navGoBack() for context-aware navigation.
- CSS: .section-count, .album-partial-badge, .card-dl-btn (hover reveal)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:10:52 +02:00
HoneyandClaude Sonnet 4.6 93b859bf0e feat: explicit metadata, lyrics embedding, E badge in global search
Backend:
- fetchLyrics() queries LRCLIB for plain + synced lyrics
- Synced lyrics saved as .lrc file (Navidrome reads these)
- Plain lyrics embedded via ffmpeg -metadata lyrics=
- ITUNESADVISORY=1 written for explicit tracks
- explicit flag passed through album/track download chain
- fetchItunesTracks + searchItunesAlbumTracks use country=us&explicit=Yes

Frontend:
- explicit:true sent in download payload from iTunes track data
- "E" badge shown on explicit tracks in global search track list

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:12:53 +02:00
HoneyandClaude Sonnet 4.6 3c5048f017 fix: use iTunes lookup endpoint for explicit artist tracks
iTunes search endpoint always returns cleaned versions.
Added itunesLookupArtistSongs() using /lookup?explicit=Yes which returns
the actual explicit tracks. Used in artist profile (global search) and
artist detail page (library). Album track lookup also gets explicit=Yes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 17:58:32 +02:00
HoneyandClaude Sonnet 4.6 fc951d103b fix: use iTunes US catalog + explicit=Yes to show all tracks including explicit
country=de silently filtered explicit content from iTunes results.
Switched to country=us&explicit=Yes so all songs appear regardless of explicit flag.
Removed wrong explicit-filtering code from views.js.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 17:48:35 +02:00
HoneyandClaude Sonnet 4.6 31e5940ab6 fix: remove library results from global search, filter explicit content
- Global search now shows only iTunes results (no Navidrome library section)
- All iTunes results (tracks, albums, artist pages, album detail, recommendations)
  filtered to exclude explicit content (trackExplicitness/collectionExplicitness === 'explicit')

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 17:43:31 +02:00
HoneyandClaude Sonnet 4.6 fa7e980f1a feat: player drag feedback, global search fixes, iTunes artist discovery
- Player bar: drag handle pill + live lift/peek animation when swiping up to NP
- Global search: now includes Navidrome library results alongside iTunes; fix songs not showing (filter wrapperType=track)
- iTunes artist page: hero banner with album art, top songs section
- Artist detail: iTunes global top tracks + extra albums not on server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 17:26:50 +02:00
HoneyandClaude Sonnet 4.6 9aded56713 Migrate to Vite + ES module architecture
Split monolithic app.js (~1850 lines) into maintainable ES modules:
- src/state.js  — shared mutable state (S object)
- src/utils.js  — md5, esc, formatDur, toast
- src/api.js    — Subsonic API, Navidrome REST, iTunes API
- src/player.js — playback, transport, queue, media session, preview
- src/views.js  — navigation, page loaders, card makers, search
- src/ui.js     — all modals, overlays, sidebar, settings
- src/pwa.js    — service worker registration + update banner
- src/main.js   — app init, connect, window globals

Updated Dockerfile to multi-stage (Node build → nginx serve).
Static assets (sw.js, manifest.json, icon.svg) moved to public/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 13:01:34 +02:00