From 9826b556995d34b3f39ac222b51f2e8b1b47d92b Mon Sep 17 00:00:00 2001 From: TEMP Date: Sun, 16 Aug 2026 13:53:58 -0400 Subject: [PATCH 1/3] fix(tv): re-enable navigation_home nextFocusRight so D-pad can reach 'None' provider button --- app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 5d39f6554cd..923d7d1a984 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -763,7 +763,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricCa // navigation to home for the second time as onNavDestinationSelected will not get called // when first loading up the app - // R.id.navigation_home -> R.id.home_preview_change_api + R.id.navigation_home -> R.id.home_change_api R.id.navigation_search -> R.id.main_search R.id.navigation_library -> R.id.main_search R.id.navigation_downloads -> R.id.download_appbar From 2acb95b72ac7aaa68cb2c3ad542b30fa0b1d02fa Mon Sep 17 00:00:00 2001 From: TEMP Date: Sun, 16 Aug 2026 14:11:59 -0400 Subject: [PATCH 2/3] fix(tv): re-point rail focus at provider button on every arrival at home The previous attempt only handled rail-button navigation to home via onNavDestinationSelected. Returning via the back stack (popBackStack) or on first load never re-pointed the rail's nextFocusRightId, so D-pad right from the rail could not reach the 'None' / provider selector button. Move the home case into addOnDestinationChangedListener, which fires on every arrival at home regardless of navigation path (rail button, back stack pop, first load). --- .../lagradost/cloudstream3/MainActivity.kt | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 923d7d1a984..8159b2510da 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -763,7 +763,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricCa // navigation to home for the second time as onNavDestinationSelected will not get called // when first loading up the app - R.id.navigation_home -> R.id.home_change_api + // R.id.navigation_home -> R.id.home_preview_change_api R.id.navigation_search -> R.id.main_search R.id.navigation_library -> R.id.main_search R.id.navigation_downloads -> R.id.download_appbar @@ -1681,6 +1681,24 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricCa attachBackPressedCallback("MainActivity") { showConfirmExitDialog(settingsManager) } + // Re-point nav rail focus at the provider button on every arrival + // (rail button, back stack pop, first load), so D-pad right always + // reaches the "None" / provider selector button. + if (isLayout(TV or EMULATOR)) { + val fromView = binding?.navRailView + if (fromView != null) { + fromView.nextFocusRightId = R.id.home_change_api + for (focusView in arrayOf( + R.id.navigation_downloads, + R.id.navigation_home, + R.id.navigation_search, + R.id.navigation_library, + R.id.navigation_settings, + )) { + fromView.findViewById(focusView)?.nextFocusRightId = R.id.home_change_api + } + } + } } else detachBackPressedCallback("MainActivity") } From ed32dc6566adb9c7b5c6386e676990e3dceef406 Mon Sep 17 00:00:00 2001 From: TEMP Date: Sun, 23 Aug 2026 15:28:32 -0400 Subject: [PATCH 3/3] fix(tv): rail right-focus only targets provider button at scroll top --- .../lagradost/cloudstream3/MainActivity.kt | 18 --------------- .../cloudstream3/ui/home/HomeFragment.kt | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 8159b2510da..5d39f6554cd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -1681,24 +1681,6 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricCa attachBackPressedCallback("MainActivity") { showConfirmExitDialog(settingsManager) } - // Re-point nav rail focus at the provider button on every arrival - // (rail button, back stack pop, first load), so D-pad right always - // reaches the "None" / provider selector button. - if (isLayout(TV or EMULATOR)) { - val fromView = binding?.navRailView - if (fromView != null) { - fromView.nextFocusRightId = R.id.home_change_api - for (focusView in arrayOf( - R.id.navigation_downloads, - R.id.navigation_home, - R.id.navigation_search, - R.id.navigation_library, - R.id.navigation_settings, - )) { - fromView.findViewById(focusView)?.nextFocusRightId = R.id.home_change_api - } - } - } } else detachBackPressedCallback("MainActivity") } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt index 0e52baff6b9..dddcec5163f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt @@ -18,6 +18,7 @@ import android.widget.Toast import androidx.activity.ComponentActivity import androidx.appcompat.app.AlertDialog import androidx.core.net.toUri +import androidx.core.view.doOnLayout import androidx.core.view.isGone import androidx.core.view.isInvisible import androidx.core.view.isVisible @@ -771,9 +772,12 @@ class HomeFragment : BaseFragment( } } super.onScrolled(recyclerView, dx, dy) + updateTvRailFocus() } }) + homeMasterRecycler.doOnLayout { updateTvRailFocus() } + } //Load value for toggling Random button. Hide at startup @@ -949,6 +953,24 @@ class HomeFragment : BaseFragment( }*/ } + private fun updateTvRailFocus() { + if (!isLayout(TV or EMULATOR)) return + val target = + if (binding?.homeMasterRecycler?.computeVerticalScrollOffset() == 0) R.id.home_change_api + else View.NO_ID + val rail = activity?.findViewById(R.id.nav_rail_view) ?: return + rail.nextFocusRightId = target + for (focusView in arrayOf( + R.id.navigation_downloads, + R.id.navigation_home, + R.id.navigation_search, + R.id.navigation_library, + R.id.navigation_settings, + )) { + rail.findViewById(focusView)?.nextFocusRightId = target + } + } + private fun handleTvBackPress(helper: BackPressedCallbackHelper.CallbackHelper) { // Only apply custom behavior on TV interface if (!isLayout(TV)) {