SavedSong was in the local container alongside reference data, so it
got deleted whenever localStoreResetVersion was bumped. Move it to the
cloud container (CloudKit-synced) so saved songs persist across schema
changes. Update lyrics views to use cloudModelContextProvider.
Closes#4
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Navigation: present search as a sheet from library (avoids nested
NavigationStack), use view-based NavigationLink for song rows (fixes
double-push from duplicate navigationDestination).
Translation: Apple Translation inserts a blank line after every
translated line. Strip all blanks from the EN output, then re-insert
them at the same positions where the original ES has blanks. Result
is 1:1 line pairing between Spanish and English.
Store reset: revert localStoreResetVersion bump — adding SavedSong
is a lightweight SwiftData migration, no store nuke needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New feature in the Practice tab that lets users search for Spanish songs
by artist + title, fetch lyrics from LRCLIB (free, no API key), pull
album art from iTunes Search API, auto-translate to English via Apple's
on-device Translation framework, and save for offline reading.
Components:
- SavedSong SwiftData model (local container, no CloudKit sync)
- LyricsSearchService actor (LRCLIB + iTunes Search, concurrent)
- LyricsSearchView (artist/song fields, result list with album art)
- LyricsConfirmationView (lyrics preview, auto-translation, save)
- LyricsLibraryView (saved songs list, swipe to delete)
- LyricsReaderView (Spanish lines with English subtitles)
- Practice tab integration (Lyrics button with NavigationLink)
- localStoreResetVersion bumped to 3 for schema migration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>