diff --git a/mobile/android/app/src/main/java/com/goon/mobile/MainActivity.kt b/mobile/android/app/src/main/java/com/goon/mobile/MainActivity.kt index 56c8006..c452133 100644 --- a/mobile/android/app/src/main/java/com/goon/mobile/MainActivity.kt +++ b/mobile/android/app/src/main/java/com/goon/mobile/MainActivity.kt @@ -5,9 +5,14 @@ import android.content.Context import android.content.pm.ActivityInfo import android.content.pm.PackageManager import android.content.res.Configuration +import android.graphics.drawable.Drawable +import android.graphics.drawable.GradientDrawable import android.os.Build import android.os.Bundle import android.util.Log +import android.util.TypedValue +import android.view.View +import java.lang.ref.WeakReference import com.facebook.react.ReactActivity import com.facebook.react.ReactActivityDelegate @@ -37,7 +42,9 @@ import expo.modules.ReactActivityDelegateWrapper */ open class MainActivity : ReactActivity() { override fun onCreate(savedInstanceState: Bundle?) { - if (!isTelevision()) { + // Tablet (krotszy bok >= 600 dp) zostaje bez blokady: pion na tablecie trzymanym w poziomie + // to waski pasek, a zdjecie blokady z JS (src/lib/tablet.ts) i tak przychodzi chwile pozniej. + if (!isTelevision() && resources.configuration.smallestScreenWidthDp < 600) { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } // Set the theme to AppTheme BEFORE onCreate to support @@ -55,6 +62,40 @@ open class MainActivity : ReactActivity() { } catch (e: Throwable) { Log.w("Goon", "Cast niedostepny na tym urzadzeniu: " + e.javaClass.simpleName) } + + installFocusRing() + } + + // Obwodka wokol elementu z fokusem pilota (Fire TV, Android TV, klawiatura). + // + // Pilot chodzi po zwyklych przyciskach RN, ale nic nie pokazywalo, gdzie jest fokus + // (zgloszenie 7768ae0c, Fire TV): widoki RN maja wlasne tlo bez stanu "focused", Android TV + // nie rysuje systemowego podswietlenia, a RN 0.76 na Androidzie nie przekazuje onFocus/onBlur + // do JS (sprawdzone 2026-10-15 na emulatorze: przycisk ma fokus, zdarzenie nie przychodzi). + // Dlatego natywnie: przy kazdej zmianie fokusu nowy widok dostaje foreground z obwodka, + // a poprzedni odzyskuje swoj. W trybie dotykowym (telefon) nic nie rysujemy. + private var ringView: WeakReference? = null + private var ringPrevForeground: Drawable? = null + + private fun installFocusRing() { + window.decorView.viewTreeObserver.addOnGlobalFocusChangeListener { _, newFocus -> + ringView?.get()?.let { it.foreground = ringPrevForeground } + ringView = null + ringPrevForeground = null + if (newFocus == null || newFocus.isInTouchMode) return@addOnGlobalFocusChangeListener + ringPrevForeground = newFocus.foreground + newFocus.foreground = makeFocusRing() + ringView = WeakReference(newFocus) + } + } + + private fun makeFocusRing(): Drawable { + val dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, resources.displayMetrics) + return GradientDrawable().apply { + shape = GradientDrawable.RECTANGLE + cornerRadius = 12 * dp + setStroke((3 * dp).toInt(), 0xFFF5EDE0.toInt()) + } } private fun isTelevision(): Boolean {