mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-08-07 11:52:34 +00:00
Fallback to title text when logos are unavailable
This commit is contained in:
parent
7f200c7c7d
commit
f2c9978f76
6 changed files with 71 additions and 22 deletions
|
|
@ -111,7 +111,7 @@ fun DetailFloatingHeader(
|
|||
.padding(horizontal = 10.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (meta.logo != null && !logoLoadError) {
|
||||
if (!meta.logo.isNullOrBlank() && !logoLoadError) {
|
||||
AsyncImage(
|
||||
model = meta.logo,
|
||||
contentDescription = stringResource(Res.string.detail_logo_content_description, meta.name),
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ import androidx.compose.material3.MaterialTheme
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
|
|
@ -79,6 +81,10 @@ fun DetailHero(
|
|||
val heroChromeTopPadding = WindowInsets.statusBars.asPaddingValues().calculateTopPadding() +
|
||||
8.dp +
|
||||
((40.dp - muteIconSize) / 2)
|
||||
var logoLoadError by remember(meta.id, meta.logo) {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
val logoUrl = meta.logo?.takeIf { it.isNotBlank() }
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
|
@ -198,9 +204,9 @@ fun DetailHero(
|
|||
.padding(bottom = 8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
if (meta.logo != null) {
|
||||
if (logoUrl != null && !logoLoadError) {
|
||||
AsyncImage(
|
||||
model = meta.logo,
|
||||
model = logoUrl,
|
||||
contentDescription = stringResource(Res.string.detail_logo_content_description, meta.name),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(if (isTablet) 0.56f else 0.6f)
|
||||
|
|
@ -208,6 +214,7 @@ fun DetailHero(
|
|||
.height(if (isTablet) 72.dp else 80.dp),
|
||||
alignment = Alignment.Center,
|
||||
contentScale = ContentScale.Fit,
|
||||
onError = { logoLoadError = true },
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -347,13 +349,18 @@ private fun HeroContentBlock(
|
|||
layout: HomeHeroLayout,
|
||||
onItemClick: ((MetaPreview) -> Unit)?,
|
||||
) {
|
||||
var logoLoadError by remember(item.type, item.id, item.logo) {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
val logoUrl = item.logo?.takeIf { it.isNotBlank() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = if (layout.isTablet) Alignment.Start else Alignment.CenterHorizontally,
|
||||
) {
|
||||
if (item.logo != null) {
|
||||
if (logoUrl != null && !logoLoadError) {
|
||||
AsyncImage(
|
||||
model = item.logo,
|
||||
model = logoUrl,
|
||||
contentDescription = item.name,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(layout.logoWidthFraction)
|
||||
|
|
@ -363,6 +370,7 @@ private fun HeroContentBlock(
|
|||
},
|
||||
alignment = if (layout.isTablet) Alignment.CenterStart else Alignment.Center,
|
||||
contentScale = ContentScale.Fit,
|
||||
onError = { logoLoadError = true },
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ import androidx.compose.material3.Surface
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -122,6 +125,8 @@ internal fun OpeningOverlay(
|
|||
),
|
||||
label = "openingOverlayContentScale",
|
||||
)
|
||||
var logoLoadError by remember(logo) { mutableStateOf(false) }
|
||||
val logoUrl = logo?.takeIf { it.isNotBlank() }
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
|
|
@ -178,14 +183,14 @@ internal fun OpeningOverlay(
|
|||
label = "openingOverlayP2pProgress",
|
||||
)
|
||||
val progressActive = targetProgress != null
|
||||
if (logo != null) {
|
||||
if (logoUrl != null && !logoLoadError) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(300.dp)
|
||||
.height(180.dp),
|
||||
) {
|
||||
AsyncImage(
|
||||
model = logo,
|
||||
model = logoUrl,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -197,10 +202,11 @@ internal fun OpeningOverlay(
|
|||
}
|
||||
},
|
||||
contentScale = ContentScale.Fit,
|
||||
onError = { logoLoadError = true },
|
||||
)
|
||||
if (progressActive) {
|
||||
AsyncImage(
|
||||
model = logo,
|
||||
model = logoUrl,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -377,6 +383,9 @@ internal fun PauseMetadataOverlay(
|
|||
horizontalSafePadding: Dp,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var logoLoadError by remember(logo) { mutableStateOf(false) }
|
||||
val logoUrl = logo?.takeIf { it.isNotBlank() }
|
||||
|
||||
BoxWithConstraints(
|
||||
modifier = modifier
|
||||
.background(
|
||||
|
|
@ -429,13 +438,14 @@ internal fun PauseMetadataOverlay(
|
|||
)
|
||||
androidx.compose.foundation.layout.Spacer(modifier = Modifier.height(if (compactHeight) 8.dp else 12.dp))
|
||||
|
||||
if (!logo.isNullOrBlank()) {
|
||||
if (logoUrl != null && !logoLoadError) {
|
||||
AsyncImage(
|
||||
model = logo,
|
||||
model = logoUrl,
|
||||
contentDescription = title,
|
||||
contentScale = ContentScale.Fit,
|
||||
alignment = Alignment.BottomStart,
|
||||
modifier = Modifier.height(logoHeight),
|
||||
onError = { logoLoadError = true },
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -152,6 +152,8 @@ fun StreamsScreen(
|
|||
val noDirectStreamLinkText = stringResource(Res.string.streams_no_direct_link)
|
||||
var streamActionsTarget by remember(videoId) { mutableStateOf<StreamItem?>(null) }
|
||||
var preferredFilterApplied by remember(videoId) { mutableStateOf(false) }
|
||||
var autoPlayOverlayLogoLoadError by remember(logo) { mutableStateOf(false) }
|
||||
val autoPlayOverlayLogoUrl = logo?.takeIf { it.isNotBlank() }
|
||||
val storedProgress = if (startFromBeginning) {
|
||||
null
|
||||
} else {
|
||||
|
|
@ -316,13 +318,24 @@ fun StreamsScreen(
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
if (!logo.isNullOrBlank()) {
|
||||
if (autoPlayOverlayLogoUrl != null && !autoPlayOverlayLogoLoadError) {
|
||||
AsyncImage(
|
||||
model = logo,
|
||||
contentDescription = null,
|
||||
model = autoPlayOverlayLogoUrl,
|
||||
contentDescription = title,
|
||||
modifier = Modifier
|
||||
.height(48.dp),
|
||||
contentScale = ContentScale.Fit,
|
||||
onError = { autoPlayOverlayLogoLoadError = true },
|
||||
)
|
||||
} else if (title.isNotBlank()) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.Black),
|
||||
color = Color.White,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
)
|
||||
}
|
||||
CircularProgressIndicator(
|
||||
|
|
@ -532,6 +545,9 @@ private fun MovieHeroBlock(
|
|||
logo: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var logoLoadError by remember(logo) { mutableStateOf(false) }
|
||||
val logoUrl = logo?.takeIf { it.isNotBlank() }
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -539,14 +555,15 @@ private fun MovieHeroBlock(
|
|||
.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top)),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (logo != null) {
|
||||
if (logoUrl != null && !logoLoadError) {
|
||||
AsyncImage(
|
||||
model = logo,
|
||||
contentDescription = null,
|
||||
model = logoUrl,
|
||||
contentDescription = title,
|
||||
modifier = Modifier
|
||||
.height(80.dp)
|
||||
.fillMaxWidth(0.85f),
|
||||
contentScale = ContentScale.Fit,
|
||||
onError = { logoLoadError = true },
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -222,19 +222,23 @@ private fun TabletMovieInfoPanel(
|
|||
logo: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var logoLoadError by remember(logo) { mutableStateOf(false) }
|
||||
val logoUrl = logo?.takeIf { it.isNotBlank() }
|
||||
|
||||
Column(
|
||||
modifier = modifier.fillMaxWidth(0.8f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
if (!logo.isNullOrBlank()) {
|
||||
if (logoUrl != null && !logoLoadError) {
|
||||
AsyncImage(
|
||||
model = logo,
|
||||
contentDescription = null,
|
||||
model = logoUrl,
|
||||
contentDescription = title,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(120.dp),
|
||||
contentScale = ContentScale.Fit,
|
||||
onError = { logoLoadError = true },
|
||||
)
|
||||
} else if (title.isNotBlank()) {
|
||||
Text(
|
||||
|
|
@ -277,6 +281,8 @@ private fun TabletEpisodeInfoPanel(
|
|||
showTitle: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var logoLoadError by remember(logo) { mutableStateOf(false) }
|
||||
val logoUrl = logo?.takeIf { it.isNotBlank() }
|
||||
val textShadow = Shadow(
|
||||
color = Color.Black,
|
||||
offset = Offset(0f, 0f),
|
||||
|
|
@ -288,14 +294,15 @@ private fun TabletEpisodeInfoPanel(
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
if (!logo.isNullOrBlank()) {
|
||||
if (logoUrl != null && !logoLoadError) {
|
||||
AsyncImage(
|
||||
model = logo,
|
||||
contentDescription = null,
|
||||
model = logoUrl,
|
||||
contentDescription = showTitle,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(120.dp),
|
||||
contentScale = ContentScale.Fit,
|
||||
onError = { logoLoadError = true },
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
|
|
|
|||
Loading…
Reference in a new issue