Tweak Lyrics code

This commit is contained in:
vfsfitvnm 2022-10-03 15:16:33 +02:00
parent 0ac516b39b
commit 16b6e6505a
2 changed files with 203 additions and 215 deletions

View file

@ -13,7 +13,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@ -30,10 +29,10 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.autoSaver
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
@ -46,7 +45,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.media3.common.C
import androidx.media3.common.MediaMetadata
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.kugou.KuGou
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
@ -55,6 +53,7 @@ import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.themed.Menu
import it.vfsfitvnm.vimusic.ui.components.themed.MenuEntry
import it.vfsfitvnm.vimusic.ui.components.themed.ShimmerHost
import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.DefaultDarkColorPalette
@ -66,7 +65,7 @@ import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.isShowingSynchronizedLyricsKey
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.relaunchableEffect
import it.vfsfitvnm.vimusic.utils.produceSaveableState
import it.vfsfitvnm.vimusic.utils.rememberPreference
import it.vfsfitvnm.vimusic.utils.verticalFadingEdge
import it.vfsfitvnm.youtubemusic.Innertube
@ -76,7 +75,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext
@ -103,19 +101,31 @@ fun Lyrics(
var isShowingSynchronizedLyrics by rememberPreference(isShowingSynchronizedLyricsKey, false)
var state by remember(mediaId, isShowingSynchronizedLyrics) {
mutableStateOf(LyricsState())
var isEditing by remember(mediaId, isShowingSynchronizedLyrics) {
mutableStateOf(false)
}
val fetchLyrics = relaunchableEffect(mediaId, isShowingSynchronizedLyrics) {
val lyrics by produceSaveableState(
initialValue = ".",
stateSaver = autoSaver<String?>(),
mediaId, isShowingSynchronizedLyrics
) {
if (isShowingSynchronizedLyrics) {
Database.synchronizedLyrics(mediaId)
} else {
Database.lyrics(mediaId)
}.distinctUntilChanged().map flowMap@{ lyrics ->
if (lyrics != null) return@flowMap lyrics
}
.flowOn(Dispatchers.IO)
.distinctUntilChanged()
.collect { value = it }
}
state = state.copy(isLoading = true)
var isError by remember(lyrics) {
mutableStateOf(false)
}
LaunchedEffect(lyrics == null) {
if (lyrics != null) return@LaunchedEffect
if (isShowingSynchronizedLyrics) {
val mediaMetadata = mediaMetadataProvider()
@ -137,25 +147,21 @@ fun Lyrics(
)?.map { it?.value }
} else {
Innertube.lyrics(NextBody(videoId = mediaId))
}?.map { newLyrics ->
}?.onSuccess { newLyrics ->
onLyricsUpdate(isShowingSynchronizedLyrics, mediaId, newLyrics ?: "")
state = state.copy(isLoading = false)
return@flowMap newLyrics ?: ""
}?.onFailure {
isError = true
}
}
state = state.copy(isLoading = false)
null
}.flowOn(Dispatchers.IO).collect { state = state.copy(lyrics = it) }
}
if (state.isEditing) {
if (isEditing) {
TextFieldDialog(
hintText = "Enter the lyrics",
initialTextInput = state.lyrics ?: "",
initialTextInput = lyrics ?: "",
singleLine = false,
maxLines = 10,
isTextInputValid = { true },
onDismiss = { state = state.copy(isEditing = false) },
onDismiss = { isEditing = false },
onDone = {
query {
if (isShowingSynchronizedLyrics) {
@ -163,7 +169,6 @@ fun Lyrics(
} else {
Database.updateLyrics(mediaId, it)
}
}
}
)
@ -181,7 +186,7 @@ fun Lyrics(
.background(Color.Black.copy(0.8f))
) {
AnimatedVisibility(
visible = !state.isLoading && state.lyrics == null,
visible = isError && lyrics == null,
enter = slideInVertically { -it },
exit = slideOutVertically { -it },
modifier = Modifier
@ -198,7 +203,7 @@ fun Lyrics(
}
AnimatedVisibility(
visible = state.lyrics?.let(String::isEmpty) ?: false,
visible = lyrics?.let(String::isEmpty) ?: false,
enter = slideInVertically { -it },
exit = slideOutVertically { -it },
modifier = Modifier
@ -214,22 +219,7 @@ fun Lyrics(
)
}
if (state.isLoading) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.shimmer()
) {
repeat(4) { index ->
TextPlaceholder(
color = colorPalette.onOverlayShimmer,
modifier = Modifier
.alpha(1f - index * 0.05f)
)
}
}
} else {
state.lyrics?.let { lyrics ->
lyrics?.let { lyrics ->
if (lyrics.isNotEmpty() && lyrics != ".") {
if (isShowingSynchronizedLyrics) {
val density = LocalDensity.current
@ -292,6 +282,14 @@ fun Lyrics(
}
}
if (lyrics == null && !isError) {
ShimmerHost(horizontalAlignment = Alignment.CenterHorizontally) {
repeat(4) {
TextPlaceholder(color = colorPalette.onOverlayShimmer)
}
}
}
Image(
painter = painterResource(R.drawable.ellipsis_horizontal),
contentDescription = null,
@ -317,7 +315,7 @@ fun Lyrics(
text = "Edit lyrics",
onClick = {
menuState.hide()
state = state.copy(isEditing = true)
isEditing = true
}
)
@ -353,23 +351,17 @@ fun Lyrics(
MenuEntry(
icon = R.drawable.download,
text = "Fetch lyrics again",
isEnabled = lyrics != null,
onClick = {
menuState.hide()
if (state.lyrics == null) {
fetchLyrics()
} else {
query {
if (isShowingSynchronizedLyrics) {
Database.updateSynchronizedLyrics(
mediaId,
null
)
Database.updateSynchronizedLyrics(mediaId, null)
} else {
Database.updateLyrics(mediaId, null)
}
}
}
}
)
}
}
@ -381,10 +373,3 @@ fun Lyrics(
}
}
}
}
private data class LyricsState(
val isLoading: Boolean = false,
val isEditing: Boolean = false,
val lyrics: String? = ".",
)

View file

@ -28,6 +28,7 @@ import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.service.LoginRequiredException
import it.vfsfitvnm.vimusic.service.PlayableFormatNotFoundException
import it.vfsfitvnm.vimusic.service.UnplayableException
@ -121,6 +122,7 @@ fun Thumbnail(
isDisplayed = isShowingLyrics && error == null,
onDismiss = { onShowLyrics(false) },
onLyricsUpdate = { areSynchronized, mediaId, lyrics ->
query {
if (areSynchronized) {
if (Database.updateSynchronizedLyrics(mediaId, lyrics) == 0) {
if (mediaId == mediaItem.mediaId) {
@ -138,6 +140,7 @@ fun Thumbnail(
}
}
}
}
},
size = thumbnailSizeDp,
mediaMetadataProvider = mediaItem::mediaMetadata,