docs: update README — accurate feature list + Android native app description

Removed:
- "WebView wrapper" — Android is native Jetpack Compose, not a WebView
- "Artwork pre-warming / pre-buffer on cold start" — not implemented this way
- ABS chapters/speed/sleep/progress on Android — web only for now

Added:
- Lyrics section: lrclib.net, fallback chain, in-memory cache, synced scroll
- Android: last played song in MiniPlayer across restarts
- Android: ABS library browser tab (hidden until configured)
- Android: no login flash on startup
- Settings: connection status dots, save button top+bottom, matched web order
- Multi-artist support in NowPlaying
- Artist cards with images in search
- Genre browsing
- ABS web vs Android split into separate entries
- Accurate Android project structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-15 23:56:02 +02:00
1 parent 613d5156fa
commit ba16f88355
1 file changed
+59 -23
+59 -23
View File
@@ -1,7 +1,7 @@
# NovaSonic # NovaSonic
A self-hosted music streaming PWA and Android app for Navidrome / Subsonic-compatible servers. A self-hosted music streaming PWA and Android app for Navidrome / Subsonic-compatible servers.
Built with Vite + vanilla ES modules, served via nginx in Docker. Built with Vite + vanilla ES modules (web) and Jetpack Compose + Media3/ExoPlayer (Android).
--- ---
@@ -12,26 +12,35 @@ Built with Vite + vanilla ES modules, served via nginx in Docker.
- Browse artists, albums, playlists, starred tracks, and random picks - Browse artists, albums, playlists, starred tracks, and random picks
- Sort and filter views with chip filters - Sort and filter views with chip filters
- Search / filter bar inside playlist detail and favorites (instant, client-side) - Search / filter bar inside playlist detail and favorites (instant, client-side)
- Synced and plain lyrics via LRCLIB (auto-fetched per track)
- Play count display — optional toggle in Settings - Play count display — optional toggle in Settings
- Star and context menu on every song row - Star and context menu on every song row
- Genre browsing with genre-filtered song lists
### Lyrics
- Synced (word-by-word highlighted) and plain lyrics via lrclib.net
- Auto-fetched per track — no manual setup needed
- Fallback chain: exact match with duration → exact match without duration (catches version mismatches) → artist+title search → title-only search
- In-memory cache per session — no repeated network requests for the same track
- Android: smooth scroll animation keeps the active line centered
### Artist Pages ### Artist Pages
- Full-bleed hero card — artist photo as portrait + blurred background (desktop); full-bleed image with name overlay (mobile) - Full-bleed hero card — artist photo as portrait + blurred background (desktop); full-bleed image with name overlay (mobile)
- Bio, similar artists, top songs pulled from Last.fm via Navidrome - Bio, similar artists, top songs pulled from Last.fm via Navidrome
- Concert events via Ticketmaster (upcoming shows with venue, date, ticket link) - Concert events via Ticketmaster (upcoming shows with venue, date, ticket link)
- Albums cross-referenced against iTunes catalog — shows what's downloaded, partially downloaded, or missing - Albums cross-referenced against iTunes catalog — shows what's downloaded, partially downloaded, or missing
- Artist cards with images in search results
- Quick actions: play top songs, shuffle all, open concerts - Quick actions: play top songs, shuffle all, open concerts
### Playback ### Playback
- Queue management with shuffle, repeat (all / one), and radio mode (endless random) - Queue management with shuffle, repeat (all / one), and radio mode (endless similar songs)
- Spotify-style shuffle — pre-shuffles the full queue so every song plays exactly once - Spotify-style shuffle — pre-shuffles the full queue so every song plays exactly once
- Now Playing overlay with swipe-to-dismiss - Now Playing overlay: synced lyrics, queue view, star, multi-artist links
- Multi-artist support — OpenSubsonic `artists` array shown as individual clickable links
- Gapless-style playback — next track pre-buffered 60 seconds before current track ends - Gapless-style playback — next track pre-buffered 60 seconds before current track ends
- Lock screen / notification media controls (Android / iOS / desktop) - Lock screen / notification media controls (Android / iOS / desktop)
- Scrobbling — reported to Navidrome (configurable: 15 s / 30 s / ⅓ / ⅔ / end) - Scrobbling to Navidrome (configurable: 15 s / 30 s / ⅓ / ⅔ / end)
### Discovery ### Discovery (Erkunden tab)
- iTunes / Last.fm integration — charts, global search, 30-second previews, similar artists, recommendations - iTunes / Last.fm integration — charts, global search, 30-second previews, similar artists, recommendations
- Song Importer — paste a Spotify, YouTube, YouTube Music, or SoundCloud link to preview and download tracks - Song Importer — paste a Spotify, YouTube, YouTube Music, or SoundCloud link to preview and download tracks
@@ -50,22 +59,39 @@ Built with Vite + vanilla ES modules, served via nginx in Docker.
### Playlists ### Playlists
- Create, edit, and delete playlists - Create, edit, and delete playlists
- Edit name, description, cover art, public/private toggle - Add / remove tracks
- Add / remove tracks; reorder via drag and drop - Filter/search within a playlist
### Audiobookshelf Integration ### Audiobookshelf Integration (Web)
- Browse and stream audiobooks from your Audiobookshelf server - Browse and stream audiobooks from your Audiobookshelf server
- Chapters list, playback speed, sleep timer, progress sync - Chapters list with chapter-by-chapter navigation
- Playback speed control
- Sleep timer
- Progress sync — current position saved back to ABS server
### App ### Audiobookshelf Integration (Android)
- PWA — installable on Android / iOS / desktop - Browse ABS libraries and audiobook list with covers, author, and runtime
- Android APK — native WebView wrapper with Media3 / ExoPlayer backend - Tab appears in navigation only when ABS URL + API key are configured in Settings
- Native OS notification with skip buttons
- Pre-buffers last played track on cold start for instant resume ### Settings
- Artwork pre-warming so notification never shows blank cover - Connection status indicators (green / red dot) for ABS server and NovaSonic backend — tested live with a button
- Save button at top and bottom of settings for easy access
- Order matches web: Theme → Bibliothek → Audiobookshelf → Discover APIs → Navidrome Server
### App — Web PWA
- Installable on Android / iOS / desktop
- Randomized home greetings
- Multiple color themes, dark mode, mobile-first responsive layout - Multiple color themes, dark mode, mobile-first responsive layout
- German UI - German UI
### App — Android (native)
- Native Jetpack Compose app with Material3 design — not a WebView wrapper
- Media3 / ExoPlayer backend for reliable audio playback
- OS notification with skip / play / pause buttons
- Last played song persisted across restarts — shown in mini player bar; tap play to resume
- Audiobookshelf library browser (tab hidden until ABS is configured)
- No login screen flash on startup when credentials are already saved
--- ---
## Project Structure ## Project Structure
@@ -75,7 +101,7 @@ NovaSonic/
├── src/ ├── src/
│ ├── player/ │ ├── player/
│ │ ├── player.js # Playback, queue, transport, media session, preload │ │ ├── player.js # Playback, queue, transport, media session, preload
│ │ └── nowplaying.js # Now Playing overlay │ │ └── nowplaying.js # Now Playing overlay + synced lyrics
│ ├── views/ │ ├── views/
│ │ ├── detail.js # Artist / album detail pages │ │ ├── detail.js # Artist / album detail pages
│ │ ├── views.js # Navigation, page loaders, search │ │ ├── views.js # Navigation, page loaders, search
@@ -87,9 +113,9 @@ NovaSonic/
│ │ ├── youtube.js # YouTube importer │ │ ├── youtube.js # YouTube importer
│ │ ├── soundcloud.js # SoundCloud importer │ │ ├── soundcloud.js # SoundCloud importer
│ │ ├── navigation.js # Client-side router │ │ ├── navigation.js # Client-side router
│ │ └── abs.js # Audiobookshelf integration │ │ └── abs.js # Audiobookshelf integration (web)
│ ├── ui/ │ ├── ui/
│ │ ├── ui.js # Modals, sidebar, settings, context menu │ │ ├── ui.js # Modals, sidebar, context menu
│ │ ├── components.js # Song rows, cards, shared UI │ │ ├── components.js # Song rows, cards, shared UI
│ │ ├── downloads.js # Download modal + job tracker │ │ ├── downloads.js # Download modal + job tracker
│ │ ├── metadata.js # Metadata editor │ │ ├── metadata.js # Metadata editor
@@ -98,19 +124,28 @@ NovaSonic/
│ │ └── settings.js # Settings page │ │ └── settings.js # Settings page
│ ├── state.js # Shared mutable state (S object) │ ├── state.js # Shared mutable state (S object)
│ ├── utils.js # md5, esc, formatDur, toast │ ├── utils.js # md5, esc, formatDur, toast
│ ├── api.js # Subsonic API, iTunes API, cover art │ ├── api.js # Subsonic API, iTunes API, cover art, romaji display
│ └── main.js # App init, audio wiring, window globals │ └── main.js # App init, audio wiring, window globals
├── backend/ ├── backend/
│ ├── novasonic-server.js # Express API: downloads, metadata, events proxy │ ├── novasonic-server.js # Express API: downloads, metadata, events proxy, ABS proxy
│ └── lib/ │ └── lib/
│ ├── config.js # Env var → config object │ ├── config.js # Env var → config object
│ ├── jobs.js # In-memory download job store │ ├── jobs.js # In-memory download job store
│ ├── metadata.js # iTunes lookup, artwork, lyrics, filename helpers │ ├── metadata.js # iTunes lookup, artwork, filename helpers
│ ├── ytdlp.js # yt-dlp download + ffmpeg metadata embedding │ ├── ytdlp.js # yt-dlp download + ffmpeg metadata embedding
│ ├── squid.js # Qobuz (squid.wtf) download backend │ ├── squid.js # Qobuz (squid.wtf) download backend
│ ├── downloader.js # Unified downloadTrack / downloadAlbumTracks │ ├── downloader.js # Unified downloadTrack / downloadAlbumTracks
│ └── romaji.js # Japanese → romaji search index │ └── romaji.js # Japanese → romaji search index
├── android/ # Android APK (WebView + Media3/ExoPlayer) ├── android/ # Native Android app (Jetpack Compose + Media3)
│ └── app/src/main/kotlin/com/novasonic/app/
│ ├── api/ # SubsonicClient, AbsClient, LrcLibClient, ItunesClient
│ ├── data/ # PrefsStore (DataStore), MusicRepository
│ ├── player/ # PlayerController, MusicService (Media3)
│ ├── ui/
│ │ ├── screen/ # HomeScreen, NowPlayingScreen, AbsScreen, SettingsScreen, …
│ │ ├── component/ # MiniPlayer, SongRow, SongContextSheet, …
│ │ └── theme/ # Color, Type, Theme
│ └── viewmodel/ # ViewModel per screen
├── public/ ├── public/
│ ├── sw.js # Service worker │ ├── sw.js # Service worker
│ ├── manifest.json # PWA manifest │ ├── manifest.json # PWA manifest
@@ -167,6 +202,7 @@ This starts both the frontend (nginx on port 8080) and the backend (Node.js on p
1. Open the app and enter your Navidrome server URL, username and password 1. Open the app and enter your Navidrome server URL, username and password
2. Optionally add a Last.fm API key in Settings for recommendations and artist bios 2. Optionally add a Last.fm API key in Settings for recommendations and artist bios
3. Optionally connect Audiobookshelf in Settings to stream audiobooks 3. Optionally connect Audiobookshelf in Settings to stream audiobooks
4. Optionally add the NovaSonic backend URL in Settings to enable downloads
--- ---