From 3e09ea97047c0f92ab6e4db2c9912d7315be27b3 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Thu, 22 Sep 2022 19:38:45 +0200 Subject: [PATCH] Probably fixed the extremely weird crashes on Android TV --- .../cloudstream3/ui/result/EpisodeAdapter.kt | 3 +- .../cloudstream3/ui/result/ResultFragment.kt | 60 ++++++++++++++++++- .../main/res/layout/fragment_result_tv.xml | 20 +++++-- 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt index 3abd827e..6fc81473 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt @@ -60,7 +60,7 @@ class EpisodeAdapter( private val clickCallback: (EpisodeClickEvent) -> Unit, private val downloadClickCallback: (DownloadClickEvent) -> Unit, ) : RecyclerView.Adapter() { - private var cardList: MutableList = mutableListOf() + var cardList: MutableList = mutableListOf() private val mBoundViewHolders: HashSet = HashSet() private fun getAllBoundViewHolders(): Set? { @@ -239,7 +239,6 @@ class EpisodeAdapter( itemView.setOnLongClickListener { clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card)) - return@setOnLongClickListener true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index 5fc61146..41defa41 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -95,6 +95,7 @@ import kotlinx.android.synthetic.main.fragment_result.result_vpn import kotlinx.android.synthetic.main.fragment_result_swipe.* import kotlinx.android.synthetic.main.fragment_result_tv.* import kotlinx.android.synthetic.main.result_sync.* +import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking @@ -412,7 +413,39 @@ open class ResultFragment : ResultTrailerPlayer() { is ResourceSome.Success -> { result_episodes?.isVisible = true result_episode_loading?.isVisible = false + + /* + * Okay so what is this fuckery? + * Basically Android TV will crash if you request a new focus while + * the adapter gets updated. + * + * This means that if you load thumbnails and request a next focus at the same time + * the app will crash without any way to catch it! + * + * How to bypass this? + * This code basically steals the focus for 500ms and puts it in an inescapable view + * then lets out the focus by requesting focus to result_episodes + */ + + // Do not use this.isTv, that is the player + val isTv = isTvSettings() + val hasEpisodes = + !(result_episodes?.adapter as? EpisodeAdapter?)?.cardList.isNullOrEmpty() + + if (isTv && hasEpisodes) { + // Make it impossible to focus anywhere else! + temporary_no_focus?.isFocusable = true + temporary_no_focus?.requestFocus() + } + (result_episodes?.adapter as? EpisodeAdapter?)?.updateList(episodes.value) + + if (isTv && hasEpisodes) main { + delay(500) + temporary_no_focus?.isFocusable = false + // This might make some people sad as it changes the focus when leaving an episode :( + result_episodes?.requestFocus() + } } } } @@ -458,7 +491,14 @@ open class ResultFragment : ResultTrailerPlayer() { val storedData = getStoredData(activity ?: context ?: return) ?: return //viewModel.clear() - viewModel.load(activity, storedData.url ?: return, storedData.apiName, storedData.showFillers, storedData.dubStatus, storedData.start) + viewModel.load( + activity, + storedData.url ?: return, + storedData.apiName, + storedData.showFillers, + storedData.dubStatus, + storedData.start + ) } } @@ -916,7 +956,14 @@ open class ResultFragment : ResultTrailerPlayer() { if (storedData?.url != null) { result_reload_connectionerror.setOnClickListener { - viewModel.load(activity, storedData.url, storedData.apiName, storedData.showFillers, storedData.dubStatus, storedData.start) + viewModel.load( + activity, + storedData.url, + storedData.apiName, + storedData.showFillers, + storedData.dubStatus, + storedData.start + ) } result_reload_connection_open_in_browser?.setOnClickListener { @@ -952,7 +999,14 @@ open class ResultFragment : ResultTrailerPlayer() { if (restart || !viewModel.hasLoaded()) { //viewModel.clear() - viewModel.load(activity, storedData.url, storedData.apiName, storedData.showFillers, storedData.dubStatus, storedData.start) + viewModel.load( + activity, + storedData.url, + storedData.apiName, + storedData.showFillers, + storedData.dubStatus, + storedData.start + ) } } } diff --git a/app/src/main/res/layout/fragment_result_tv.xml b/app/src/main/res/layout/fragment_result_tv.xml index 7c5b4edd..a428b80f 100644 --- a/app/src/main/res/layout/fragment_result_tv.xml +++ b/app/src/main/res/layout/fragment_result_tv.xml @@ -420,14 +420,14 @@ + android:minWidth="250dp" + android:nextFocusRight="@id/result_bookmark_button"> @@ -753,6 +753,16 @@ android:orientation="horizontal" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" tools:listitem="@layout/result_episode" /> + +