Drawn transport icons instead of glyphs (Android renders those as emoji)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,8 +12,8 @@ android {
|
|||||||
applicationId = "dev.castarr.tv"
|
applicationId = "dev.castarr.tv"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 9
|
versionCode = 10
|
||||||
versionName = "0.4.1"
|
versionName = "0.5.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release signing from environment (see ~/.keys/castarr-release.env on the
|
// Release signing from environment (see ~/.keys/castarr-release.env on the
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ private fun TopBar(state: AppState) {
|
|||||||
Spacer(Modifier.width(18.dp))
|
Spacer(Modifier.width(18.dp))
|
||||||
}
|
}
|
||||||
TabItem(
|
TabItem(
|
||||||
if (state.screen == AppState.Screen.LIVE) "⚙ Einstellungen" else "‹ Zurück zu Live",
|
if (state.screen == AppState.Screen.LIVE) "Einstellungen" else "Zurück zu Live",
|
||||||
selected = false,
|
selected = false,
|
||||||
) {
|
) {
|
||||||
state.screen = if (state.screen == AppState.Screen.LIVE) AppState.Screen.SETTINGS
|
state.screen = if (state.screen == AppState.Screen.LIVE) AppState.Screen.SETTINGS
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.castarr.tv.ui
|
package dev.castarr.tv.ui
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -24,6 +25,7 @@ import androidx.compose.ui.focus.FocusRequester
|
|||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.Path
|
||||||
import androidx.compose.ui.input.key.onKeyEvent
|
import androidx.compose.ui.input.key.onKeyEvent
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -32,6 +34,7 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.media3.ui.PlayerView
|
import androidx.media3.ui.PlayerView
|
||||||
import androidx.tv.material3.ClickableSurfaceDefaults
|
import androidx.tv.material3.ClickableSurfaceDefaults
|
||||||
|
import androidx.tv.material3.LocalContentColor
|
||||||
import androidx.tv.material3.Surface
|
import androidx.tv.material3.Surface
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import dev.castarr.tv.AppState
|
import dev.castarr.tv.AppState
|
||||||
@@ -234,11 +237,12 @@ private fun Overlay(state: AppState) {
|
|||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
PillButton(
|
PillButton(
|
||||||
label = if (state.playerState == "paused") "▶ Weiter" else "⏸ Pause",
|
label = if (state.playerState == "paused") "Weiter" else "Pause",
|
||||||
|
icon = if (state.playerState == "paused") PillIcon.PLAY else PillIcon.PAUSE,
|
||||||
focusRequester = playFocus,
|
focusRequester = playFocus,
|
||||||
) { state.player.toggle() }
|
) { state.player.toggle() }
|
||||||
Spacer(Modifier.width(10.dp))
|
Spacer(Modifier.width(10.dp))
|
||||||
PillButton(label = "■ Beenden") { state.stopPlayback() }
|
PillButton(label = "Beenden", icon = PillIcon.STOP) { state.stopPlayback() }
|
||||||
if (state.audioTracks.size > 1) {
|
if (state.audioTracks.size > 1) {
|
||||||
Spacer(Modifier.width(10.dp))
|
Spacer(Modifier.width(10.dp))
|
||||||
val current = state.audioTracks.firstOrNull { it.selected }
|
val current = state.audioTracks.firstOrNull { it.selected }
|
||||||
@@ -256,9 +260,12 @@ private fun Overlay(state: AppState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum class PillIcon { PLAY, PAUSE, STOP }
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PillButton(
|
private fun PillButton(
|
||||||
label: String,
|
label: String,
|
||||||
|
icon: PillIcon? = null,
|
||||||
focusRequester: FocusRequester? = null,
|
focusRequester: FocusRequester? = null,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -273,12 +280,45 @@ private fun PillButton(
|
|||||||
focusedContentColor = CastarrColors.onAccent,
|
focusedContentColor = CastarrColors.onAccent,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
Text(
|
Row(
|
||||||
label,
|
|
||||||
fontFamily = AppFont,
|
|
||||||
fontSize = 14.sp,
|
|
||||||
fontWeight = FontWeight.Medium,
|
|
||||||
modifier = Modifier.padding(horizontal = 18.dp, vertical = 9.dp),
|
modifier = Modifier.padding(horizontal = 18.dp, vertical = 9.dp),
|
||||||
)
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
if (icon != null) {
|
||||||
|
// Drawn, not typed — glyphs like U+23F8 render as emoji on
|
||||||
|
// Android and have no business on this screen.
|
||||||
|
val color = LocalContentColor.current
|
||||||
|
Canvas(Modifier.size(11.dp)) {
|
||||||
|
when (icon) {
|
||||||
|
PillIcon.PLAY -> drawPath(
|
||||||
|
Path().apply {
|
||||||
|
moveTo(0f, 0f)
|
||||||
|
lineTo(size.width, size.height / 2f)
|
||||||
|
lineTo(0f, size.height)
|
||||||
|
close()
|
||||||
|
},
|
||||||
|
color,
|
||||||
|
)
|
||||||
|
PillIcon.PAUSE -> {
|
||||||
|
val bar = size.width * 0.32f
|
||||||
|
drawRect(color, size = androidx.compose.ui.geometry.Size(bar, size.height))
|
||||||
|
drawRect(
|
||||||
|
color,
|
||||||
|
topLeft = androidx.compose.ui.geometry.Offset(size.width - bar, 0f),
|
||||||
|
size = androidx.compose.ui.geometry.Size(bar, size.height),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
PillIcon.STOP -> drawRect(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(Modifier.width(9.dp))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
fontFamily = AppFont,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user