Skip to content

Commit

Permalink
translations test
Browse files Browse the repository at this point in the history
  • Loading branch information
reocat committed Nov 14, 2024
1 parent 9cf76ed commit 68e65f8
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 20 deletions.
4 changes: 4 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ android {
versionCode = 30
versionName = SimpleDateFormat("yyyyMMdd").format(Date())

multiDexEnabled = true

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

Expand Down Expand Up @@ -168,6 +170,8 @@ dependencies {

coreLibraryDesugaring(libs.desugaring)

implementation("androidx.multidex:multidex:2.0.1")

implementation(libs.timber)
implementation(libs.translator)

Expand Down
12 changes: 12 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@
# Keep Gateway data classes
-keep class com.my.kizzy.gateway.entities.** { <fields>; }

# Keep Ktor client engine and plugins
-keep class io.ktor.client.** { *; }
-keep class io.ktor.client.engine.** { *; }
-keep class io.ktor.client.plugins.** { *; }

# Keep Ktor client internal engine OkHttp
-keep class io.ktor.client.engine.okhttp.** { *; }

# Keep any other essential classes that may be obfuscated
-dontwarn io.ktor.**

# Don't print notes about potential mistakes or omissions in the configuration for kotlinx-serialization classes
# See also https://github.com/Kotlin/kotlinx.serialization/issues/1900
-dontnote kotlinx.serialization.**
Expand All @@ -73,3 +84,4 @@
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
-dontwarn org.slf4j.impl.StaticLoggerBinder

99 changes: 79 additions & 20 deletions app/src/main/java/com/dd3boh/outertune/ui/component/Lyrics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
Expand All @@ -50,6 +51,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.datastore.preferences.core.booleanPreferencesKey
import com.dd3boh.outertune.LocalPlayerConnection
import com.dd3boh.outertune.R
import com.dd3boh.outertune.constants.DarkModeKey
Expand All @@ -75,6 +77,8 @@ import com.dd3boh.outertune.utils.rememberPreference
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlin.time.Duration.Companion.seconds
import me.bush.translator.Language
import me.bush.translator.Translator

@Composable
fun Lyrics(
Expand All @@ -90,12 +94,23 @@ fun Lyrics(
val lyricsTextPosition by rememberEnumPreference(LyricsTextPositionKey, LyricsPosition.CENTER)

val mediaMetadata by playerConnection.mediaMetadata.collectAsState()
val translatedLyrics = remember { mutableStateOf("") }

val translationEnabled by rememberPreference(
key = booleanPreferencesKey("translation_enabled"),
defaultValue = false
)

val destinationLanguage = remember { mutableStateOf(Language.ENGLISH) }
val lyricsEntity by playerConnection.currentLyrics.collectAsState(initial = null)
val lyrics = remember(lyricsEntity) { lyricsEntity?.lyrics?.trim() }
val multilineLrc = rememberPreference(MultilineLrcKey, defaultValue = true)
val lyricTrim = rememberPreference(LyricTrimKey, defaultValue = false)
val multilineLrc by rememberPreference(MultilineLrcKey, defaultValue = true)
val lyricTrim by rememberPreference(LyricTrimKey, defaultValue = false)

val playerBackground by rememberEnumPreference(key = PlayerBackgroundStyleKey, defaultValue = PlayerBackgroundStyle.DEFAULT)
val playerBackground by rememberEnumPreference(
key = PlayerBackgroundStyleKey,
defaultValue = PlayerBackgroundStyle.DEFAULT
)

val darkTheme by rememberEnumPreference(DarkModeKey, defaultValue = DarkMode.AUTO)
val isSystemInDarkTheme = isSystemInDarkTheme()
Expand All @@ -106,7 +121,7 @@ fun Lyrics(
val lines = remember(lyrics) {
if (lyrics == null || lyrics == LYRICS_NOT_FOUND) emptyList()
else if (lyrics.startsWith("[")) listOf(HEAD_LYRICS_ENTRY) +
parseLyrics(lyrics, lyricTrim.value, multilineLrc.value)
parseLyrics(lyrics, lyricTrim, multilineLrc)
else lyrics.lines().mapIndexed { index, line -> LyricsEntry(index * 100L, line) }
}
val isSynced = remember(lyrics) {
Expand Down Expand Up @@ -138,7 +153,7 @@ fun Lyrics(
mutableStateOf(false)
}

LaunchedEffect(lyrics) {
LaunchedEffect(lyrics, translationEnabled) {
if (lyrics.isNullOrEmpty() || !lyrics.startsWith("[")) {
currentLineIndex = -1
return@LaunchedEffect
Expand All @@ -147,7 +162,17 @@ fun Lyrics(
delay(50)
val sliderPosition = sliderPositionProvider()
isSeeking = sliderPosition != null
currentLineIndex = findCurrentLineIndex(lines, sliderPosition ?: playerConnection.player.currentPosition)

if (translationEnabled && lyrics != null) {
translateLyrics(lyrics, destinationLanguage.value) { result ->
translatedLyrics.value = result
}
}

currentLineIndex = findCurrentLineIndex(
lines,
sliderPosition ?: playerConnection.player.currentPosition
)
}
}

Expand Down Expand Up @@ -184,11 +209,15 @@ fun Lyrics(
deferredCurrentLineIndex = currentLineIndex
if (lastPreviewTime == 0L) {
if (isSeeking) {
lazyListState.scrollToItem(currentLineIndex,
with(density) { 36.dp.toPx().toInt() } + calculateOffset())
lazyListState.scrollToItem(
currentLineIndex,
with(density) { 36.dp.toPx().toInt() } + calculateOffset()
)
} else {
lazyListState.animateScrollToItem(currentLineIndex,
with(density) { 36.dp.toPx().toInt() } + calculateOffset())
lazyListState.animateScrollToItem(
currentLineIndex,
with(density) { 36.dp.toPx().toInt() } + calculateOffset()
)
}
}
}
Expand All @@ -210,12 +239,19 @@ fun Lyrics(
.fadingEdge(vertical = 64.dp)
.nestedScroll(remember {
object : NestedScrollConnection {
override fun onPostScroll(consumed: Offset, available: Offset, source: NestedScrollSource): Offset {
override fun onPostScroll(
consumed: Offset,
available: Offset,
source: NestedScrollSource
): Offset {
lastPreviewTime = System.currentTimeMillis()
return super.onPostScroll(consumed, available, source)
}

override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
override suspend fun onPostFling(
consumed: Velocity,
available: Velocity
): Velocity {
lastPreviewTime = System.currentTimeMillis()
return super.onPostFling(consumed, available)
}
Expand Down Expand Up @@ -244,9 +280,7 @@ fun Lyrics(
}
}
} else {
itemsIndexed(
items = lines
) { index, item ->
itemsIndexed(items = lines) { index, item ->
Text(
text = item.text,
fontSize = 20.sp,
Expand All @@ -259,13 +293,26 @@ fun Lyrics(
fontWeight = FontWeight.Bold,
modifier = Modifier
.fillMaxWidth()
.clickable(enabled = isSynced) {
.clickable(enabled = isSynced || translationEnabled) {
playerConnection.player.seekTo(item.time)
lastPreviewTime = 0L
}
.padding(horizontal = 24.dp, vertical = 8.dp)
.alpha(if (!isSynced || index == displayedCurrentLineIndex) 1f else 0.5f)
)

if (translationEnabled && translatedLyrics.value.isNotEmpty()) {
Text(
text = translatedLyrics.value,
fontSize = 16.sp,
color = textColor,
textAlign = TextAlign.Center,
fontWeight = FontWeight.Normal,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 4.dp)
)
}
}
}
}
Expand Down Expand Up @@ -294,9 +341,7 @@ fun Lyrics(
.align(Alignment.BottomEnd)
.padding(end = 12.dp)
) {
IconButton(
onClick = { showLyrics = false }
) {
IconButton(onClick = { showLyrics = false }) {
Icon(
imageVector = Icons.Rounded.Close,
contentDescription = null,
Expand Down Expand Up @@ -325,5 +370,19 @@ fun Lyrics(
}
}

private suspend fun translateLyrics(
text: String,
destinationLanguage: Language,
onResult: (String) -> Unit
) {
val translator = Translator()
try {
val translation = translator.translate(text, destinationLanguage)
onResult(translation.translatedText)
} catch (e: Exception) {
onResult("Translation Error")
}
}

const val animateScrollDuration = 300L
val LyricsPreviewTime = 4.seconds
val LyricsPreviewTime = 4.seconds
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ room = "2.6.1"
hilt = "2.52"
ktor = "2.3.12"
ksp = "2.0.21-1.0.27"
multidex = "2.0.1"
translator = "1.1.1"

[libraries]
Expand Down Expand Up @@ -74,6 +75,8 @@ timber = { group = "com.jakewharton.timber", name = "timber", version = "5.0.1"

translator = { group = "com.github.therealbush", name = "translator", version.ref = "translator" }

androidx-multidex = { group = "androidx.multidex", name = "multidex", version.ref = "multidex" }

[plugins]
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
Expand Down

0 comments on commit 68e65f8

Please sign in to comment.