Commit graph

20 commits

Author SHA1 Message Date
7413163d57 Live lyrics system — full implementation
Companion API (4 new endpoints):
- GET /lyrics/search — proxy to LRCLIB, returns matches with sync status
- GET /lyrics/fetch — exact match by artist/title/duration, caches in SQLite
- GET /lyrics/get — checks embedded tags > .lrc sidecar > DB cache
- POST /lyrics/embed — writes LRC into audio file tags via mutagen + .lrc sidecar
- New lyrics table in companion database

iOS data layer (LyricsModels.swift):
- LyricLine/LyricWord structs with Codable conformance
- Full LRC parser (line-level + enhanced word-level timestamps)
- LRC serializer (toLRC) for saving edited timings
- LyricsCache with memory + disk tiers keyed by artist-title

iOS manager (LyricsManager.swift):
- Source pipeline: embedded > .lrc sidecar > local cache > LRCLIB auto-fetch
- Binary search line/word tracking (O(log n))
- Word-level progress for karaoke gradient fill
- Hooked into AudioPlayer time observer (0.5s sync) and pushWidgetState (song change)

iOS views:
- LyricsOverlayView: karaoke word-by-word highlighting via FlowLayout + KaraokeWordView
  gradient fill sweep, ScrollViewReader auto-scroll, tap any line to seek
- LyricsSearchSheet: LRCLIB search with debounced input, duration mismatch warnings,
  preview sheet, import to cache
- LyricsEditorView: tap-to-sync mode, per-line ±0.1s adjust buttons, global offset
  sheet, save to device or embed in file via Companion API

NowPlayingView integration:
- Lyrics toggle button (quote.bubble) in bottom controls bar
- Portrait layout swaps album art for lyrics overlay with animation
- Blur panel: .ultraThinMaterial with gradient mask so visualizer fades through
- Lyrics search/editor sheets wired with notification observer

Mini player lyric ticker:
- Both standard and compact mini player bars show current lyric line
- Accent pink with ♪ prefix, falls back to artist name when no lyrics
- Push transition animation on line changes

Bug fixes included:
- NavidromePlayerApp: removed unnecessary try on CompanionAPIService.shared
- Info.plist: added LSSupportsOpeningDocumentsInPlace for document type support
2026-04-13 09:01:30 -07:00
0a1a46df47 Widget glassmorphism redesign 2026-04-12 19:57:20 -07:00
Dallas Groot
b9844b23cd Performance audit, Now Playing widget, crossfade stability, cover art embedding, DJ profile bulk cache
PERFORMANCE AUDIT
- Removed 16 dead SubsonicClient methods (~117 lines)
- Added NSCache memory tier to LibraryCache, AlbumCoverStore,
ArtistCoverStore, RadioCoverStore
- Replaced weak polynomial hash with FNV-1a 64-bit in ImageCache
- Split PlaybackStateStore into save() (full queue) and savePosition()
(time only)
- Reused single SubsonicClient in OfflineManager instead of
per-download allocation
- Added periodic ImageCache disk trim every 50 writes
- Changed AudioPreFetcher to fuzzy offline match
(isSongAvailableOffline)
- Removed dead code: hasCompanionLibrary, downloadedSongIds, isActive,
CachedImageLoader.task
- Fixed thread safety: inline JSONEncoder/JSONDecoder in LibraryCache
(no shared instances)

WIDGET EXTENSION (new target: NavidromeWidget)
- v2 glassmorphism design: blurred album art background + frosted
glass panel
- Waveform scrubber: 40-bar Canvas with tap-to-seek (20 segments via
SeekToIntent)
- Color-adaptive theming: CIAreaAverage dominant color extraction with
HSB contrast adjustment
- Transport controls: previous/play-pause/next with interactive
AppIntents
- Up Next footer with crossfade countdown from Smart DJ profiles
- Large widget: 3-item queue list with numbered rows
- Small/Medium/Large sizes matching design mockups
- App Group communication via WidgetSharedState (UserDefaults)
- Darwin notification observer for widget→app commands
- Foreground command pickup for suspended app recovery
- Idempotency guards on all widget commands

CROSSFADE & PLAYBACK FIXES
- Fixed dual audio on single-song queue: guard nextSong.id ==
currentSong?.id in prepareNextForCrossfade
- Fixed crossfade play path never calling pushWidgetState (returned
before reaching it)
- Fixed crossfade needsNextTrack callback missing queue persistence +
widget push
- Fixed toggleShuffle queue not persisted after PlaybackStateStore
split
- Added nowPlayingSyncTimer restart on foreground (Lock Screen seek
bar drift)
- Added AVPlayer currentTime/duration sync in resumeVisTimers before
vis timer restart
(fixes waveform distortion after background — confirmed by Apple
Forums + SoundCloud engineering)

COVER ART PIPELINE
- Fixed pushWidgetState cover art size mismatch (300→600 to match
fetchAndSetArtwork)
- Added custom cover art key differentiation ("custom_" prefix forces
re-blur)
- Changed server art lookup from memoryOnlyImage to cachedImage
(memory+disk fallback)
- Added POST /library/cover-art-by-path endpoint (was missing — iOS
fallback hit 404)
- Added navidrome_id fallback on existing cover art endpoint
- Added embed_cover_art_in_file/embed_cover_art_in_directory: mutagen
writes cover art
directly into FLAC/MP3/M4A/OGG metadata tags so Navidrome serves
updated art
- All three upload paths (by-id, by-path, upload-tracks) now embed +
trigger_scan

COMPANION API FIXES
- Fixed _create_task recursion (was calling itself instead of
asyncio.create_task)
- Fixed navidrome_db NameError on /library/conflicts endpoint
- Reduced WebSocket connect/disconnect logging (only first-client and
all-disconnected)

SMART DJ PROFILE PREFETCH
- New endpoint: GET /smart-dj/profiles/export (bulk JSON, gzip
automatic)
- SmartDJCache.loadBulkCache() reads single file on launch (instant)
- SmartDJCache.bulkImport() writes all profiles in one atomic file
- CompanionAPIService.fetchAllProfiles() fetches entire profile set in
one request
- Wired into NavidromePlayerApp.task after server connect
- SmartCrossfadeManager unchanged — already reads from SmartDJCache
first

WEBSOCKET NOISE REDUCTION
- iOS: silent reconnect retries, only log milestones (#1, #5, every
20th)
- iOS: log "reconnected after N attempts" on success, silent initial
connect
- Python: only log first client connect and all-clients-disconnected

Files: 13 modified, 8 new (including companion-api/main.py)
2026-04-12 19:24:22 -07:00
Dallas Groot
58be99b40b remove UIRequiresFullScreen
just remove UIRequiresFullScreen. The UILaunchScreen empty dict alone
is sufficient on iOS 26 to satisfy the launch screen requirement.
2026-04-10 07:20:20 -07:00
Dallas Groot
84a41432c5 ui fixes 2026-04-10 07:15:49 -07:00
Dallas Groot
07ef5bc8e8 bug fixes 2026-04-10 07:00:30 -07:00
d0cfb4053a revert 63114f02fb
revert fixed project info
2026-04-10 00:31:29 -07:00
Dallas Groot
63114f02fb fixed project info 2026-04-10 00:22:17 -07:00
5fc531b888 fixed Testflight Submission 2026-04-08 15:59:11 -07:00
2823fe9b7a fixed bundleid 2026-04-08 15:11:33 -07:00
Dallas Groot
16097f5ff2 Watch overhaul other changes 2026-04-03 19:20:55 -07:00
Dallas Groot
f39eaff281 3-Dot Menu Grid Layout — Replaced List-based sheet with a grid of button pairs: Instant Mix | Add to Playlist, Go to Album | Go to Artist, Download/Remove | Send to Watch, Get Info | Edit Tags. 2026-04-03 15:48:37 -07:00
Dallas Groot
34f9cb4232 Auto-commit before update (2026-04-03 15:47) 2026-04-03 15:47:48 -07:00
Dallas Groot
7bc999af6b made wording better on both Microphone and Photo access 2026-04-01 10:55:53 -07:00
Dallas Groot
1009f86baa quick fix 2026-03-28 18:24:48 -07:00
Dallas Groot
97a1e112cd fixed icon 2026-03-28 18:16:43 -07:00
Dallas Groot
166aad77f5 re added icons hopefuly fo good this time 2026-03-28 17:07:33 -07:00
Dallas Groot
bc47f58162 Update from NavidromePlayer.zip (2026-03-28 16:47) 2026-03-28 16:47:28 -07:00
Dallas Groot
2f06e9bdab added icon assets and xcode prjoect 2026-03-28 14:11:30 -07:00
Dallas Groot
d8041c0019 NavidromePlayer: iOS + watchOS Navidrome/Subsonic music player
Features:
- Dual-AVPlayer Smart DJ crossfade with LUFS normalization
- Mitsuha-style FFT visualizer (real-time + offline pre-computed)
- Companion API integration (Smart DJ, tag editing, vis frames)
- Offline-first SyncEngine with delta sync and album detail pre-caching
- Audio pre-fetcher for gapless queue playback
- Optimistic action queue (star/unstar with background retry)
- ShazamKit recognition with MusicKit preview playback
- Radio streaming with HLS/PLS/M3U support and buffer seek
- Watch app with Crown Sequencer and Ultra speaker support
- Batch metadata editing with album_artist fix for split albums
- Cache-first UI pattern across all views
- NWPathMonitor offline detection with reactive song greying
2026-03-28 20:49:47 +00:00