player: match the normalised D-pad key when scrolling the description (#23)

Scrolling the info text up still did nothing on the TV while down worked. The
handler only matched the raw nativeKeyEvent keycode; remotes don't all report
the same codes, so match Compose's normalised Key.DirectionUp/Down as well, and
always attempt the scroll (animateScrollBy clamps at the ends itself) instead of
gating it on the current offset.

Not reproducible on the emulator in either the debug or the release build, so
this targets the device difference rather than a confirmed fault.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Jeena 2026-10-15 14:56:00 +00:00
parent 654963436f
commit ddacf48906

View file

@ -47,6 +47,8 @@ import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withLink
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.type
import androidx.compose.ui.input.key.onPreviewKeyEvent
@ -244,22 +246,31 @@ private fun DescriptionScroll(
.onPreviewKeyEvent { ke ->
if (ke.type != KeyEventType.KeyDown) return@onPreviewKeyEvent false
val step = (viewportPx * 0.85f).coerceAtLeast(240f)
when (ke.nativeKeyEvent.keyCode) {
// UP/DOWN are always consumed: they scroll while there is room and
// otherwise do nothing, so focus stays here and the text can always
// be scrolled back up (issue #23 review).
KeyEvent.KEYCODE_DPAD_DOWN -> {
if (scroll.value < scroll.maxValue) scope.launch { scroll.animateScrollBy(step) }
val code = ke.nativeKeyEvent.keyCode
// Match Compose's normalised key AND the raw keycode: remotes don't all
// report the same native codes, and matching only the raw one left UP
// unhandled on some devices (issue #23 review).
val isUp = ke.key == Key.DirectionUp || code == KeyEvent.KEYCODE_DPAD_UP
val isDown = ke.key == Key.DirectionDown || code == KeyEvent.KEYCODE_DPAD_DOWN
val isLeft = ke.key == Key.DirectionLeft || code == KeyEvent.KEYCODE_DPAD_LEFT
val isCenter = ke.key == Key.DirectionCenter || ke.key == Key.Enter ||
code == KeyEvent.KEYCODE_DPAD_CENTER || code == KeyEvent.KEYCODE_ENTER
when {
// UP/DOWN are always consumed and always attempt the scroll (it
// clamps at the ends by itself), so focus stays here and the text
// can always be scrolled back up.
isDown -> {
scope.launch { scroll.animateScrollBy(step) }
true
}
KeyEvent.KEYCODE_DPAD_UP -> {
if (scroll.value > 0) scope.launch { scroll.animateScrollBy(-step) }
isUp -> {
scope.launch { scroll.animateScrollBy(-step) }
true
}
KeyEvent.KEYCODE_DPAD_LEFT -> {
isLeft -> {
onDismiss(); true
}
KeyEvent.KEYCODE_DPAD_CENTER, KeyEvent.KEYCODE_ENTER -> {
isCenter -> {
onActivate(); true
}
else -> false