feat: lyrics tab (#113) - #117
Merged
Merged
Conversation
- Implemented lyrics navigation in CoreNavigator and NavGraphs. - Created data transfer objects (DTOs) for lyrics handling including LyricsCheckDto, LyricsDto, LyricsLineDto, LyricsRequestDto, PluginLyricsRequestDto, and PluginLyricsResultDto. - Developed DataLyricsRepository to manage lyrics fetching and searching online. - Added Lyrics and LyricsLine domain models to represent lyrics data. - Introduced LyricsUiState to manage UI state for lyrics display. - Created LyricsViewModel to handle business logic for lyrics. - Designed rough LyricsScreen composable for displaying lyrics with synchronization and online search capabilities. - Updated AppSettings to include preferences for lyrics plugin usage and auto-download settings.
The POC modified NowPlaying.kt which isn't the active screen post-#106. Move the lyrics icon into AnimatedPlayerSheet's bottom control row and collapse the sheet on tap so the lyrics screen is actually visible. Other fixes spotted while testing: - LyricsScreen was computing positionMs as seekPosition*1000, but seekPosition is a 0..1 fraction, so the value passed to PositionChanged maxed at 1000ms and the highlight never advanced past line 0. Multiply by track.duration too. - LyricsLineDto.time is Double. The server returns fractional ms like 128021.99999999999 which Gson refused to parse into Long, killing every lyrics fetch. - Drop the 300ms look-ahead in scheduleNextLine. Lines now advance at the actual line timestamp, which matches the audio for tracks with good LRC data. - Replace deprecated Icons.Default.ArrowBack with the AutoMirrored variant.
AntonioSanFer
approved these changes
Jun 9, 2026
AntonioSanFer
left a comment
There was a problem hiding this comment.
Everything seems great, and working 👍
- Implement smooth scaling and color transitions for lyric lines using `animateFloatAsState` and `animateColorAsState`. - Add a dynamic scaling effect where the active lyric line is larger than surrounding lines. - Refine alpha transparency logic to better distinguish between past, active, and upcoming lines. - Increase font size to 32.sp and adjust line height for improved readability. - Reduce vertical spacing between lines in the `LazyColumn`. - Apply `graphicsLayer` with a start-aligned `TransformOrigin` to anchor the scaling effect.
Member
|
👁️ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #113.
Picks up @AntonioSanFer's POC fork (the first commit on this branch, authored by them) and finishes it on top of #106 so it actually runs on current main.
What this adds
A dedicated lyrics screen reachable from the expanded player, with synced highlighting, click-to-seek, and online search fallback.
Where to find it: when the player sheet is expanded, the lyrics icon sits in the bottom control row (next to repeat / queue / shuffle). Tapping it collapses the sheet and opens the lyrics screen, with the mini-player still visible at the bottom for control.
Behavior
unsyncedchip in the header. No auto-scroll, no highlighting.Search onlinebutton that hits the/plugins/lyrics/searchplugin endpoint. The error message stays visible for 5 seconds then clears.useLyricsPluginpreference pluslyricsAutoDownload, the screen will automatically hit the plugin search endpoint when local lyrics are missing. IflyricsOverrideUnsyncedis on, it'll also override unsynced local lyrics with a synced version from a plugin source.What's in the diff
From @AntonioSanFer's POC (commit
87591c4):LyricsDto,LyricsLineDto,LyricsCheckDto,LyricsRequestDto,PluginLyricsRequestDto,PluginLyricsResultDtoLyrics,LyricsLineLyricsRepositoryinterface +DataLyricsRepositoryimplementation (/lyrics,/lyrics/check,/plugins/lyrics/search)LyricsScreencomposable (header with album art and back nav, synced/unsynced/empty body composables)LyricsViewModelwith line index calculation, scheduled advance, online searchLyricsUiState,LyricsUiEventAppSettings(plugin enabled, auto-download, override-unsynced)gotoLyrics()onCommonNavigator/CoreNavigator,LyricsScreenDestinationinNavGraphsNetworkApiServiceendpointsFollow-up commit (
cafe172):AnimatedPlayerSheet's control row. The POC modifiedNowPlaying.ktwhich isn't the active screen post-player:Add Player Animations #106, so the icon was invisible. Tap now collapses the sheet to partial then navigates so the lyrics screen is actually visible.LyricsScreen: was passingseekPosition * 1000(a 0..1000 fraction) where milliseconds were expected, so the highlight never moved past line 0. Multiply bytrack.durationtoo.LyricsLineDto.timefromLongtoDouble. The server returns fractional ms like128021.99999999999which Gson refused to parse intoLongand killed every fetch. Mapper truncates back toLongfor the domain model.scheduleNextLine. Lines now advance at the actual line timestamp, which matches the audio for tracks with good LRC data.statusBarsPadding()to the lyrics header so the back button and track info aren't covered by the system bar.Icons.Default.ArrowBackwithIcons.AutoMirrored.Filled.ArrowBack.Testing
Tested on a Pixel 7 Pro running the build from this branch:
One sample track (
Short N SweetbyNyashinski) had LRC timestamps roughly 2 seconds ahead of the actual sung audio. Every other track lined up, which points to bad data in that one LRC file rather than a sync issue in the code. The sync trace logs I ran during dev confirmed advances fire at the exact timestamps the LRC declares.Known follow-ups (out of scope for this PR)
AppSettings/AppSettingsRepositorybut there are no toggles in the settings screen yet, so they default to off.±n secondsadjustment would let the user fix sync without us changing the data.Credit
Lyrics architecture, DTOs, repository, ViewModel sync logic, and the initial
LyricsScreencomposable are @AntonioSanFer's work from https://github.com/AntonioSanFer/android/tree/feature/lyrics. The follow-up commit on this branch is the integration glue and a handful of bug fixes spotted while testing.