This commit is contained in:
tapframe 2026-03-11 21:45:12 +05:30
parent e3d7ddb04a
commit 61ee16b409
2 changed files with 41 additions and 4 deletions

View file

@ -17,9 +17,25 @@ object MetaDetailsRepository {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
private val _uiState = MutableStateFlow(MetaDetailsUiState())
val uiState: StateFlow<MetaDetailsUiState> = _uiState.asStateFlow()
private var activeRequestKey: String? = null
fun load(type: String, id: String) {
log.d { "load() called — type=$type id=$id" }
val requestKey = "$type:$id"
val currentState = _uiState.value
if (currentState.meta?.type == type && currentState.meta.id == id && !currentState.isLoading) {
log.d { "Skipping reload for cached meta — type=$type id=$id" }
activeRequestKey = requestKey
return
}
if (currentState.isLoading && activeRequestKey == requestKey) {
log.d { "Request already in flight — type=$type id=$id" }
return
}
activeRequestKey = requestKey
_uiState.value = MetaDetailsUiState(isLoading = true)
scope.launch {
@ -38,6 +54,7 @@ object MetaDetailsRepository {
_uiState.value = MetaDetailsUiState(
errorMessage = "No addon provides meta for this content.",
)
activeRequestKey = null
return@launch
}
@ -45,6 +62,7 @@ object MetaDetailsRepository {
val result = tryFetchMeta(manifest, type, id)
if (result != null) {
_uiState.value = MetaDetailsUiState(meta = result)
activeRequestKey = requestKey
return@launch
}
}
@ -52,10 +70,12 @@ object MetaDetailsRepository {
_uiState.value = MetaDetailsUiState(
errorMessage = "Could not load details from any addon.",
)
activeRequestKey = null
}
}
fun clear() {
activeRequestKey = null
_uiState.value = MetaDetailsUiState()
}

View file

@ -1,5 +1,7 @@
package com.nuvio.app.features.details
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@ -29,8 +31,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.nuvio.app.core.ui.nuvioPlatformExtraBottomPadding
@ -49,18 +53,31 @@ fun MetaDetailsScreen(
modifier: Modifier = Modifier,
) {
val uiState by MetaDetailsRepository.uiState.collectAsStateWithLifecycle()
val screenAlpha = remember(type, id) { Animatable(0f) }
val requestedMeta = uiState.meta?.takeIf { it.type == type && it.id == id }
val needsFreshLoad = requestedMeta == null && !uiState.isLoading
LaunchedEffect(type, id) {
LaunchedEffect(type, id, needsFreshLoad) {
if (!needsFreshLoad) {
screenAlpha.snapTo(1f)
return@LaunchedEffect
}
screenAlpha.snapTo(0f)
screenAlpha.animateTo(
targetValue = 1f,
animationSpec = tween(durationMillis = 220),
)
MetaDetailsRepository.load(type, id)
}
Box(
modifier = modifier
.fillMaxSize()
.alpha(screenAlpha.value)
.background(MaterialTheme.colorScheme.background),
) {
when {
uiState.isLoading -> {
uiState.isLoading || (uiState.meta != null && requestedMeta == null) -> {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center),
color = MaterialTheme.colorScheme.primary,
@ -88,8 +105,8 @@ fun MetaDetailsScreen(
}
}
uiState.meta != null -> {
val meta = uiState.meta!!
requestedMeta != null -> {
val meta = requestedMeta
val scrollState = rememberScrollState()
Column(
modifier = Modifier