fix: localize stream label at render, simplify parser test runBlocking

StreamItem.streamLabel now returns name.orEmpty() so the data class
stays locale-neutral. The four composable display sites
(StreamsScreen, PlayerSourcesPanel, PlayerEpisodesPanel,
PlayerControls) localize the blank case with
stringResource(Res.string.stream_default_name). DownloadsRepository's
fallbackTitle path is unchanged because buildFileName already does
.ifBlank { "download" }; DownloadItem.streamTitle is only re-read in
PlayerScreen which already has its own .ifBlank fallback.

Also drops the redundant outer runBlocking wrapper on the
assertFailsWith test in MetaDetailsParserTest — only the inner
runBlocking is needed since assertFailsWith's lambda is non-suspend.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aniket Tuli 2026-05-13 11:26:17 -07:00
parent 62d38f74f8
commit 71bea9a00f
6 changed files with 7 additions and 8 deletions

View file

@ -238,7 +238,7 @@ private fun PlayerHeader(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = streamTitle,
text = streamTitle.ifBlank { stringResource(Res.string.stream_default_name) },
style = typeScale.labelSm.copy(
fontSize = metrics.metadataSize,
lineHeight = metrics.metadataSize * 1.25f,

View file

@ -629,7 +629,7 @@ private fun EpisodeSourceStreamRow(
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = stream.streamLabel,
text = stream.streamLabel.ifBlank { stringResource(Res.string.stream_default_name) },
color = colorScheme.onSurface,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,

View file

@ -267,7 +267,7 @@ private fun SourceStreamRow(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Text(
text = stream.streamLabel,
text = stream.streamLabel.ifBlank { stringResource(Res.string.stream_default_name) },
color = colorScheme.onSurface,
style = MaterialTheme.typography.bodyMedium.copy(
fontSize = 14.sp,

View file

@ -13,7 +13,7 @@ data class StreamItem(
val behaviorHints: StreamBehaviorHints = StreamBehaviorHints(),
) {
val streamLabel: String
get() = name ?: "Stream"
get() = name.orEmpty()
val streamSubtitle: String?
get() = description

View file

@ -994,7 +994,7 @@ private fun StreamCard(
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = stream.streamLabel,
text = stream.streamLabel.ifBlank { stringResource(Res.string.stream_default_name) },
style = MaterialTheme.typography.bodyMedium.copy(
fontSize = 14.sp,
fontWeight = FontWeight.Bold,
@ -1060,7 +1060,7 @@ private fun StreamActionsSheet(
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Text(
text = stream.streamLabel,
text = stream.streamLabel.ifBlank { stringResource(Res.string.stream_default_name) },
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface,
fontWeight = FontWeight.SemiBold,

View file

@ -8,11 +8,10 @@ import kotlin.test.assertFailsWith
class MetaDetailsParserTest {
@Test
fun `parse rejects null meta object without json object cast crash`() = runBlocking {
fun `parse rejects null meta object without json object cast crash`() {
assertFailsWith<IllegalStateException> {
runBlocking { MetaDetailsParser.parse("""{"meta":null}""") }
}
Unit
}
@Test