From 412fafc5b67ab581118ea8e1fd911c8e2300e349 Mon Sep 17 00:00:00 2001 From: Lambada10 <62511588+Lambada10@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:22:32 +0100 Subject: [PATCH 1/2] Add offset modes (direct/lrc tag) --- .../data/remote/UserSettingsController.kt | 11 +++++++++- .../songsync/ui/screens/about/AboutScreen.kt | 8 +++++++ .../about/components/OffsetModeSwitch.kt | 21 +++++++++++++++++++ .../screens/lyricsFetch/LyricsFetchScreen.kt | 1 + .../lyricsFetch/LyricsFetchViewModel.kt | 4 ++-- .../lyricsFetch/components/SuccessContent.kt | 9 +++++++- .../pl/lambada/songsync/util/LyricsUtils.kt | 20 ++++++++++++------ app/src/main/res/values/strings.xml | 2 ++ 8 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/pl/lambada/songsync/ui/screens/about/components/OffsetModeSwitch.kt diff --git a/app/src/main/java/pl/lambada/songsync/data/remote/UserSettingsController.kt b/app/src/main/java/pl/lambada/songsync/data/remote/UserSettingsController.kt index c3900c8..8da3b83 100644 --- a/app/src/main/java/pl/lambada/songsync/data/remote/UserSettingsController.kt +++ b/app/src/main/java/pl/lambada/songsync/data/remote/UserSettingsController.kt @@ -52,6 +52,9 @@ class UserSettingsController(private val dataStore: DataStore) { var showPath by mutableStateOf(dataStore.get(showPathKey, false)) private set + var directlyModifyTimestamps by mutableStateOf(dataStore.get(directlyModifyTimestampsKey, false)) + private set + var sortOrder by mutableStateOf( SortOrders.entries .find { it.queryName == dataStore.get(sortOrderKey, SortOrders.ASCENDING.queryName) }!! @@ -119,6 +122,11 @@ class UserSettingsController(private val dataStore: DataStore) { showPath = to } + fun updateDirectlyModifyTimestamps(to: Boolean) { + dataStore.set(directlyModifyTimestampsKey, to) + directlyModifyTimestamps = to + } + fun updateSortOrder(to: SortOrders) { dataStore.set(sortOrderKey, to.queryName) sortOrder = to @@ -142,4 +150,5 @@ private val pureBlackKey = booleanPreferencesKey("pure_black") private val sdCardPathKey = stringPreferencesKey("sd_card_path") private val showPathKey = booleanPreferencesKey("show_path") private val sortOrderKey = stringPreferencesKey("sort_order") -private val sortByKey = stringPreferencesKey("sort_by") \ No newline at end of file +private val sortByKey = stringPreferencesKey("sort_by") +private val directlyModifyTimestampsKey = booleanPreferencesKey("directly_modify_timestamps") \ No newline at end of file diff --git a/app/src/main/java/pl/lambada/songsync/ui/screens/about/AboutScreen.kt b/app/src/main/java/pl/lambada/songsync/ui/screens/about/AboutScreen.kt index bb17264..31d23e1 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/screens/about/AboutScreen.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/screens/about/AboutScreen.kt @@ -26,6 +26,7 @@ import pl.lambada.songsync.ui.screens.about.components.CreditsSection import pl.lambada.songsync.ui.screens.about.components.ExternalLinkSection import pl.lambada.songsync.ui.screens.about.components.MarqueeSwitch import pl.lambada.songsync.ui.screens.about.components.MultiPersonSwitch +import pl.lambada.songsync.ui.screens.about.components.OffsetModeSwitch import pl.lambada.songsync.ui.screens.about.components.PureBlackThemeSwitch import pl.lambada.songsync.ui.screens.about.components.SdCardPathSetting import pl.lambada.songsync.ui.screens.about.components.ShowPathSwitch @@ -105,6 +106,13 @@ fun AboutScreen( ) } + item { + OffsetModeSwitch( + selected = userSettingsController.directlyModifyTimestamps, + onToggle = { userSettingsController.updateDirectlyModifyTimestamps(it) } + ) + } + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { item { SdCardPathSetting( diff --git a/app/src/main/java/pl/lambada/songsync/ui/screens/about/components/OffsetModeSwitch.kt b/app/src/main/java/pl/lambada/songsync/ui/screens/about/components/OffsetModeSwitch.kt new file mode 100644 index 0000000..90102bb --- /dev/null +++ b/app/src/main/java/pl/lambada/songsync/ui/screens/about/components/OffsetModeSwitch.kt @@ -0,0 +1,21 @@ +package pl.lambada.songsync.ui.screens.about.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import pl.lambada.songsync.R +import pl.lambada.songsync.ui.components.AboutItem +import pl.lambada.songsync.ui.components.SwitchItem + +@Composable +fun OffsetModeSwitch( + selected: Boolean, + onToggle: (Boolean) -> Unit +) { + AboutItem(label = stringResource(R.string.offset_mode)) { + SwitchItem( + label = stringResource(R.string.offset_mode_summary), + selected = selected, + onClick = { onToggle(!selected) } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchScreen.kt b/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchScreen.kt index 6881148..42e8a9d 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchScreen.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchScreen.kt @@ -152,6 +152,7 @@ fun SharedTransitionScope.LyricsFetchScreen( viewModel.lrcOffset = 0 viewModel.queryState = QueryStatus.NotSubmitted }, + directOffset = viewModel.userSettingsController.directlyModifyTimestamps, offset = viewModel.lrcOffset, onSetOffset = { viewModel.lrcOffset = it }, onSaveLyrics = { diff --git a/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchViewModel.kt b/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchViewModel.kt index 0a77815..d37098d 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchViewModel.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/LyricsFetchViewModel.kt @@ -86,7 +86,7 @@ class LyricsFetchViewModel( context: Context, generatedUsingString: String ) { - val lrcContent = generateLrcContent(song, lyrics, generatedUsingString, lrcOffset) + val lrcContent = generateLrcContent(song, lyrics, generatedUsingString, lrcOffset, userSettingsController.directlyModifyTimestamps) val file = newLyricsFilePath(filePath, song) if (!isLegacyFileAccessRequired(filePath)) { @@ -127,7 +127,7 @@ class LyricsFetchViewModel( context: Context, song: SongInfo ) { - val lrcContent = generateLrcContent(song, lyrics, context.getString(R.string.generated_using), lrcOffset) + val lrcContent = generateLrcContent(song, lyrics, context.getString(R.string.generated_using), lrcOffset, userSettingsController.directlyModifyTimestamps) runCatching { embedLyricsInFile( diff --git a/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/components/SuccessContent.kt b/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/components/SuccessContent.kt index b324cce..29077cf 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/components/SuccessContent.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/screens/lyricsFetch/components/SuccessContent.kt @@ -38,6 +38,7 @@ fun SharedTransitionScope.SuccessContent( result: SongInfo, onTryAgain: () -> Unit, onEdit: () -> Unit, + directOffset: Boolean, offset: Int, onSetOffset: (Int) -> Unit, onSaveLyrics: (String) -> Unit, @@ -103,7 +104,13 @@ fun SharedTransitionScope.SuccessContent( LyricsFetchState.NotSubmitted -> { /* nothing */ } is LyricsFetchState.Success -> LyricsSuccessContent( - lyrics = applyOffsetToLyrics(it.lyrics, offset), + lyrics = it.lyrics.let { + if (offset != 0 && directOffset) { + applyOffsetToLyrics(it, offset) + } else { + it + } + }, offset = offset, onSetOffset = onSetOffset, onSaveLyrics = { onSaveLyrics(it.lyrics) }, diff --git a/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt b/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt index 22a5853..f5f339f 100644 --- a/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt +++ b/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt @@ -26,12 +26,17 @@ fun generateLrcContent( lyrics: String, generatedUsingString: String, offset: Int = 0, + directOffset: Boolean ): String { - return ("[ti:${song.songName}]\n" + + val offsetSign = if (offset >= 0) "+" else "" + val offsetStr = if (!directOffset) "[offset:${offsetSign}${offset}]\n" else "" + val lyrics = if (directOffset && offset != 0) applyOffsetToLyrics(lyrics, offset) else lyrics + + return "[ti:${song.songName}]\n" + "[ar:${song.artistName}]\n" + - "[by:$generatedUsingString]\n" + lyrics).let { - if (offset != 0) applyOffsetToLyrics(it, offset) else it - } + offsetStr + + "[by:$generatedUsingString]\n" + + lyrics } fun newLyricsFilePath(filePath: String?, song: SongInfo): File { @@ -251,7 +256,8 @@ private suspend fun downloadLyricsForSong( context, viewModel.userSettingsController.sdCardPath, songInfo, - it + it, + viewModel.userSettingsController.directlyModifyTimestamps ) onLyricsSaved() @@ -265,13 +271,15 @@ private fun formatAndSaveLyricsForSong( sdCardPath: String?, songInfo: SongInfo, lyrics: String, + directOffset: Boolean ) { val targetFile = song.filePath.toLrcFile() val lrcContent = generateLrcContent( songInfo, lyrics, - context.getString(R.string.generated_using) + context.getString(R.string.generated_using), + directOffset = directOffset ) writeLyricsToFile(targetFile, lrcContent, context, song, sdCardPath) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c32d78e..f640389 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -138,4 +138,6 @@ Ascending Descending Sort + Offset mode + Directly modify the lyrics timestamps instead of using offset LRC tag From 5d762bce01c8adaf99f8c54a6865a7183588065c Mon Sep 17 00:00:00 2001 From: Lambada10 <62511588+Lambada10@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:45:22 +0100 Subject: [PATCH 2/2] fix broken timestamp on negative time prevention --- app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt b/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt index f5f339f..212cf16 100644 --- a/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt +++ b/app/src/main/java/pl/lambada/songsync/util/LyricsUtils.kt @@ -324,7 +324,7 @@ fun applyOffsetToLyrics(lyrics: String, offset: Int): String { fun applyOffset(minute: Int, second: Int, millisecond: Int): String { val totalMilliseconds = (minute * 60 * 1000) + (second * 1000) + (millisecond * 10) + offset - if (totalMilliseconds < 0) return "[00:00.000]" // Prevent negative times + if (totalMilliseconds < 0) return "00:00.000" // Prevent negative times val newMinutes = (totalMilliseconds / 60000) % 60 val newSeconds = (totalMilliseconds / 1000) % 60