TV Guide UI followup to #517 (#521)

## Description
- Instead of just replacing newline characters, collapse white-space
into single space characters which is roughly how the web UI does it
with CSS's `white-space: nowrap;`
- Use an actual arrow indicator instead of a `<` character for when a
program begins before the guide start

### Related issues
#517
https://github.com/damontecres/Wholphin/issues/434
https://github.com/damontecres/Wholphin/issues/435
https://github.com/damontecres/Wholphin/issues/436

### Screenshots
<img width="605" height="316" alt="image"
src="https://github.com/user-attachments/assets/6a5227b5-9960-4c6d-a086-a4a9867ea60b"
/>
This commit is contained in:
Ray 2025-12-20 14:47:28 -05:00 committed by GitHub
parent a65b93e064
commit 11dda19b8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 38 deletions

View file

@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -21,6 +22,8 @@ import androidx.tv.material3.Text
import androidx.tv.material3.contentColorFor
import androidx.tv.material3.surfaceColorAtElevation
import coil3.compose.AsyncImage
import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.ui.FontAwesome
import java.time.LocalDateTime
@Composable
@ -56,14 +59,7 @@ fun Program(
RoundedCornerShape(cornerSize)
}
}
val title =
remember(startedBeforeGuide) {
if (startedBeforeGuide) {
"< "
} else {
""
} + (program.name ?: program.id.toString())
}
val title = program.name ?: program.id.toString()
Box(
modifier =
modifier
@ -74,12 +70,27 @@ fun Program(
shape = shape,
),
) {
Row(
modifier = Modifier.fillMaxSize(),
) {
if (startedBeforeGuide) {
Text(
text = stringResource(R.string.fa_caret_left),
fontFamily = FontAwesome,
color = textColor,
fontSize = 16.sp,
modifier =
Modifier
.align(Alignment.CenterVertically)
.padding(start = 2.dp),
)
}
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
modifier =
Modifier
.fillMaxSize()
.padding(4.dp),
.padding(start = 2.dp, end = 4.dp, top = 4.dp, bottom = 4.dp),
) {
Text(
text = title,
@ -104,6 +115,7 @@ fun Program(
)
}
}
}
RecordingMarker(
isRecording = program.isRecording,
isSeriesRecording = program.isSeriesRecording,

View file

@ -229,11 +229,12 @@ class LiveTvViewModel
} else {
null
}
val name = (dto.seriesName ?: dto.name)?.replace(Regex("[\n\r]"), "")
// Clean up name/subtitles by collapsing whitespace (including newlines) into single spaces
val name = (dto.seriesName ?: dto.name)?.replace(Regex("\\s+"), " ")
val subtitle =
dto.episodeTitle
.takeIf { dto.isSeries ?: false }
?.replace(Regex("[\n\r]"), "")
?.replace(Regex("\\s+"), " ")
val p =
TvProgram(
id = dto.id,

View file

@ -14,6 +14,8 @@
<string name="fa_magnifying_glass_minus" translatable="false">&#xf010;</string>
<string name="fa_caret_up" translatable="false">&#xf0d8;</string>
<string name="fa_caret_down" translatable="false">&#xf0d7;</string>
<string name="fa_caret_left" translatable="false">&#xf0d9;</string>
<string name="fa_caret_right" translatable="false">&#xf0da;</string>
<string name="fa_heart" translatable="false">&#xf004;</string>
<string name="fa_video" translatable="false">&#xf03d;</string>
<string name="fa_play" translatable="false">&#xf04b;</string>