Fix DPAD/Menu key remaps leaking into login and other non-room pages

isRoomList() only matched the exact "/tv" room-list path, so the
"!isRoomList()" checks gating DPAD center/up/down/left/right and Menu
treated every OTHER page - including /login - as if it were inside a
room. Result: DPAD OK typed a literal space into focused text fields,
DPAD up/down typed 'p'/'n', and Menu typed 'x'.

Replaced with isInRoom() (path starts with "/tv/"), so these remaps
only apply on an actual room page. Also stopped BACK from reloading to
the room list from unrelated pages like /login, which discarded
whatever the user had typed and, since /tv requires auth, just bounced
straight back to /login anyway.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LHgWjmEJXsJEi1EVAoTp4K
This commit is contained in:
GGB
2026-09-17 20:28:47 +02:00
co-authored by Claude Sonnet 5
parent 3412357526
commit ba422bf089
@@ -30,15 +30,18 @@ import android.webkit.WebViewClient
* deshalb als Alias fuer die 'ContextMenu'-Taste, ausschliesslich fuer
* diesen App-Anwendungsfall.
*
* DPAD Center/Up/Down (und die entsprechenden Medientasten) werden NUR
* innerhalb eines Raums remapped (Space/P/N - siehe Design-Spec). Auf der
* Raumliste (/tv) haben sie dort keine Bedeutung: die Raumliste hat ihr
* eigenes Tastaturschema (ArrowUp/ArrowDown/Enter, siehe tv-rooms.js auf
* der Website) und muss die echten, unveraenderten Tasten bekommen, sonst
* bewegt sich der Fokus zwischen den Raum-Kacheln nie (genau der Fehler,
* der beim ersten Hardware-Test auftrat: die Raumliste laed, aber keine
* Taste tut etwas, weil DPAD_DOWN/CENTER als 'n'/Space statt als
* ArrowDown/Enter ankamen).
* DPAD Center/Up/Down/Left/Right, Menu und die entsprechenden Medientasten
* werden NUR innerhalb eines Raums (Pfad "/tv/<id>") remapped - siehe
* isInRoom(). Auf jeder anderen Seite (Raumliste "/tv", Login, Signup, ...)
* muessen sie unveraendert durchgereicht werden, sonst zerschiesst die
* Remapping-Logik dort Texteingaben. Zwei konkrete Bugs kamen genau daher,
* dass frueher statt isInRoom() die Umkehrung von isRoomList() geprueft
* wurde (also "ueberall ausser der Raumliste"), was auch Login/Signup
* einschloss: auf der Raumliste bewegte sich der Fokus zwischen den
* Raum-Kacheln nicht (DPAD_DOWN/CENTER kamen als 'n'/Space statt als
* ArrowDown/Enter an), und auf der Login-Seite tippte DPAD OK ein
* Leerzeichen in das fokussierte Textfeld statt das Formular zu bestaetigen
* (DPAD_CENTER kam als Space-Taste an statt als echtes Enter).
*/
class MainActivity : Activity() {
@@ -90,6 +93,7 @@ class MainActivity : Activity() {
private fun isFullscreen() = fullscreenView != null
private fun isRoomList() = currentPath == "/tv"
private fun isInRoom() = currentPath.startsWith("/tv/")
private fun sendKey(keyCode: Int, shift: Boolean = false) {
val metaState = if (shift) KeyEvent.META_SHIFT_ON else 0
@@ -115,11 +119,12 @@ class MainActivity : Activity() {
* Tastendrucks abgefangen wird (sonst haengt Chromiums interner
* Tastenstatus fest, weil ein Keydown ohne passendes Keyup ankaeme). */
private fun shouldIntercept(keyCode: Int): Boolean = when (keyCode) {
KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT,
KeyEvent.KEYCODE_MENU -> true
KeyEvent.KEYCODE_BACK -> true
KeyEvent.KEYCODE_MENU -> isRoomList() || isInRoom()
KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT,
KeyEvent.KEYCODE_DPAD_CENTER, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE,
KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
KeyEvent.KEYCODE_MEDIA_PREVIOUS, KeyEvent.KEYCODE_MEDIA_NEXT -> !isRoomList()
KeyEvent.KEYCODE_MEDIA_PREVIOUS, KeyEvent.KEYCODE_MEDIA_NEXT -> isInRoom()
else -> false
}
@@ -136,8 +141,13 @@ class MainActivity : Activity() {
KeyEvent.KEYCODE_MENU -> sendKey(KeyEvent.KEYCODE_X)
KeyEvent.KEYCODE_BACK -> when {
isRoomList() -> { /* verschluckt, keine weitere Aktion */ }
isFullscreen() -> sendKey(KeyEvent.KEYCODE_ESCAPE)
else -> webView.loadUrl(BuildConfig.WEBSITE_URL)
isInRoom() && isFullscreen() -> sendKey(KeyEvent.KEYCODE_ESCAPE)
isInRoom() -> webView.loadUrl(BuildConfig.WEBSITE_URL)
/* Login/Signup/sonstige Seiten: nichts tun, statt zur Raumliste
zu reloaden - sonst gehen unfertig ausgefuellte Formulare
verloren, und da /tv Login voraussetzt, landete man dort
sofort wieder auf der Login-Seite. */
else -> { /* verschluckt, keine weitere Aktion */ }
}
}
return true