@@ -28,7 +28,9 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.key
@@ -37,6 +39,7 @@ import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -98,6 +101,11 @@ fun PlayerScreen(state: AppState) {
}
}
/** Soft drop shadow so overlay text stays readable on bright video. */
private val OverlayText = TextStyle (
shadow = Shadow ( Color ( 0xB3000000 ) , Offset ( 0f , 2f ) , blurRadius = 8f ) ,
)
private fun formatClock ( millis : Long ) : String =
SimpleDateFormat ( " HH:mm " , Locale . GERMANY ) . format ( Date ( millis ) )
@@ -146,7 +154,8 @@ private fun Overlay(state: AppState) {
. padding ( top = 22. dp , end = 30. dp ) ,
verticalAlignment = Alignment . CenterVertically ,
) {
Text ( name , color = CastarrColors . muted , fontFamily = AppFont , fontSize = 12. sp )
Text ( name , color = CastarrColors . muted , fontFamily = AppFont ,
style = OverlayText , fontSize = 12. sp )
Spacer ( Modifier . width ( 8. dp ) )
Box (
Modifier
@@ -178,18 +187,38 @@ private fun Overlay(state: AppState) {
statusWord ,
color = CastarrColors . muted ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 12. sp ,
)
}
Spacer ( Modifier . height ( 4. dp ) )
}
Text (
state . currentChannel ?. name . orEmpty ( ) ,
color = CastarrColors . fg ,
fontFamily = AppFont ,
fontSize = 30. sp ,
fontWeight = FontWeight . Medium ,
)
Row ( verticalAlignment = Alignment . Bottom ) {
// Channel number inline before the name (matches the list
// and the number-pad zapping).
val number = state . currentChannel ?. let { current ->
state . activeChannels ( ) . indexOfFirst { it . url == current . url } + 1
} ?: 0
if ( number > 0 ) {
Text (
" $number " ,
color = CastarrColors . accent ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 30. sp ,
fontWeight = FontWeight . SemiBold ,
)
Spacer ( Modifier . width ( 14. dp ) )
}
Text (
state . currentChannel ?. name . orEmpty ( ) ,
color = CastarrColors . fg ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 30. sp ,
fontWeight = FontWeight . Medium ,
)
}
val info = state . currentChannel ?. let { state . nowNext ( it ) }
val now = info ?. now ?. takeUnless { isEpgPlaceholder ( it . title ) }
@@ -200,6 +229,7 @@ private fun Overlay(state: AppState) {
now . title ,
color = CastarrColors . fg ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 18. sp ,
)
Spacer ( Modifier . width ( 14. dp ) )
@@ -207,6 +237,7 @@ private fun Overlay(state: AppState) {
" ${formatClock(now.start)} – ${formatClock(now.stop)} " ,
color = CastarrColors . muted ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 14. sp ,
)
}
@@ -219,6 +250,7 @@ private fun Overlay(state: AppState) {
" Danach: ${next.title} ( ${formatClock(next.start)} ) " ,
color = CastarrColors . faint ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 14. sp ,
)
}
@@ -267,6 +299,7 @@ private fun Overlay(state: AppState) {
" ▲ ▼ Sender wechseln " ,
color = CastarrColors . faint ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 12. sp ,
)
}
@@ -346,6 +379,7 @@ private fun PillButton(
Text (
label ,
fontFamily = AppFont ,
style = OverlayText ,
fontSize = 14. sp ,
fontWeight = FontWeight . Medium ,
modifier = Modifier . padding ( horizontal = 18. dp , vertical = 9. dp ) ,