From b13c1eac01f2ddd7818fa1a5ba886892c5597053 Mon Sep 17 00:00:00 2001 From: LagradOst Date: Sun, 28 Nov 2021 13:18:01 +0100 Subject: [PATCH] android TV fix --- .../lagradost/cloudstream3/MainActivity.kt | 80 +++++++++++++++++-- .../ui/home/HomeChildItemAdapter.kt | 20 +++-- .../cloudstream3/ui/home/HomeFragment.kt | 32 +++++++- .../ui/home/HomeParentItemAdapter.kt | 7 +- .../cloudstream3/ui/player/PlayerFragment.kt | 13 ++- .../cloudstream3/ui/search/SearchAdaptor.kt | 6 +- .../ui/search/SearchResultBuilder.kt | 12 ++- app/src/main/res/layout/fragment_search.xml | 2 +- app/src/main/res/layout/homepage_parent.xml | 3 +- 9 files changed, 150 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 0c446f72..494d00fc 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -145,20 +145,84 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { } } + enum class FocusDirection { + Left, + Right, + Up, + Down, + } + + private fun getNextFocus(view: View?, direction: FocusDirection, depth: Int = 0): Int? { + if (view == null || depth >= 10) { + return null + } + + val nextId = when (direction) { + FocusDirection.Left -> { + view.nextFocusLeftId + } + FocusDirection.Up -> { + view.nextFocusUpId + } + FocusDirection.Right -> { + view.nextFocusRightId + } + FocusDirection.Down -> { + view.nextFocusDownId + } + } + + return if (nextId != -1) { + val next = findViewById(nextId) + //println("NAME: ${next.accessibilityClassName} | ${next?.isShown}" ) + + if (next?.isShown == false) { + getNextFocus(next, direction, depth + 1) + } else { + if (depth == 0) { + null + } else { + nextId + } + } + } else { + null + } + } + override fun dispatchKeyEvent(event: KeyEvent?): Boolean { event?.keyCode?.let { keyCode -> when (event.action) { ACTION_DOWN -> { - when (keyCode) { - KeyEvent.KEYCODE_DPAD_CENTER -> { - println("DPAD PRESSED $currentFocus") - if (currentFocus is SearchView || currentFocus is SearchView.SearchAutoComplete) { - println("current PRESSED") - showInputMethod(currentFocus?.findFocus()) + if (currentFocus != null) { + val next = when (keyCode) { + KeyEvent.KEYCODE_DPAD_LEFT -> getNextFocus(currentFocus, FocusDirection.Left) + KeyEvent.KEYCODE_DPAD_RIGHT -> getNextFocus(currentFocus, FocusDirection.Right) + KeyEvent.KEYCODE_DPAD_UP -> getNextFocus(currentFocus, FocusDirection.Up) + KeyEvent.KEYCODE_DPAD_DOWN -> getNextFocus(currentFocus, FocusDirection.Down) + + else -> null + } + + if (next != null && next != -1) { + val nextView = findViewById(next) + if(nextView != null) { + nextView.requestFocus() + return true + } + } + + when (keyCode) { + + KeyEvent.KEYCODE_DPAD_CENTER -> { + println("DPAD PRESSED $currentFocus") + if (currentFocus is SearchView || currentFocus is SearchView.SearchAutoComplete) { + println("current PRESSED") + showInputMethod(currentFocus?.findFocus()) + } } } } - //println("Keycode: $keyCode") //showToast( // this, @@ -169,7 +233,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { } } - if(keyEventListener?.invoke(event) == true) { + if (keyEventListener?.invoke(event) == true) { return true } return super.dispatchKeyEvent(event) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt index 0fbc8156..74abedf7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt @@ -12,13 +12,19 @@ import com.lagradost.cloudstream3.ui.search.SearchResultBuilder class HomeChildItemAdapter( var cardList: List, val layout: Int = R.layout.home_result_grid, - private val clickCallback: (SearchClickCallback) -> Unit + private val nextFocusUp: Int? = null, + private val nextFocusDown: Int? = null, + private val clickCallback: (SearchClickCallback) -> Unit, ) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return CardViewHolder( - LayoutInflater.from(parent.context).inflate(layout, parent, false), clickCallback, itemCount + LayoutInflater.from(parent.context).inflate(layout, parent, false), + clickCallback, + itemCount, + nextFocusUp, + nextFocusDown ) } @@ -39,19 +45,23 @@ class HomeChildItemAdapter( } class CardViewHolder - constructor(itemView: View, private val clickCallback: (SearchClickCallback) -> Unit, val itemCount: Int) : + constructor( + itemView: View, private val clickCallback: (SearchClickCallback) -> Unit, private val itemCount: Int, + private val nextFocusUp: Int? = null, + private val nextFocusDown: Int? = null, + ) : RecyclerView.ViewHolder(itemView) { fun bind(card: SearchResponse, index: Int) { // TV focus fixing - val nextFocusBehavior = when(index){ + val nextFocusBehavior = when (index) { 0 -> true itemCount - 1 -> false else -> null } - SearchResultBuilder.bind(clickCallback, card, itemView, nextFocusBehavior) + SearchResultBuilder.bind(clickCallback, card, itemView, nextFocusBehavior, nextFocusUp, nextFocusDown) itemView.tag = index //val ani = ScaleAnimation(0.9f, 1.0f, 0.9f, 1f) //ani.fillAfter = true 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 da514a36..5c7fb5a8 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 @@ -35,6 +35,7 @@ import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST import com.lagradost.cloudstream3.ui.search.* import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallback +import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.utils.AppUtils import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult import com.lagradost.cloudstream3.utils.DataStore.getKey @@ -212,7 +213,12 @@ class HomeFragment : Fragment() { val randomSize = items.size home_main_poster_recyclerview.adapter = - HomeChildItemAdapter(items, R.layout.home_result_big_grid) { callback -> + HomeChildItemAdapter( + items, + R.layout.home_result_big_grid, + nextFocusUp = home_main_poster_recyclerview.nextFocusUpId, + nextFocusDown = home_main_poster_recyclerview.nextFocusDownId + ) { callback -> handleSearchClickCallback(activity, callback) } home_main_poster_recyclerview.post { @@ -339,7 +345,11 @@ class HomeFragment : Fragment() { } } - home_bookmarked_child_recyclerview.adapter = HomeChildItemAdapter(ArrayList()) { callback -> + home_bookmarked_child_recyclerview.adapter = HomeChildItemAdapter( + ArrayList(), + nextFocusUp = home_bookmarked_child_recyclerview?.nextFocusUpId, + nextFocusDown = home_bookmarked_child_recyclerview?.nextFocusDownId + ) { callback -> if (callback.action == SEARCH_ACTION_SHOW_METADATA) { val id = callback.card.id if (id != null) { @@ -355,7 +365,11 @@ class HomeFragment : Fragment() { } } - home_watch_child_recyclerview.adapter = HomeChildItemAdapter(ArrayList()) { callback -> + home_watch_child_recyclerview.adapter = HomeChildItemAdapter( + ArrayList(), + nextFocusUp = home_watch_child_recyclerview?.nextFocusUpId, + nextFocusDown = home_watch_child_recyclerview?.nextFocusDownId + ) { callback -> if (callback.action == SEARCH_ACTION_SHOW_METADATA) { val id = callback.card.id if (id != null) { @@ -423,6 +437,16 @@ class HomeFragment : Fragment() { // nice profile pic on homepage home_profile_picture_holder?.isVisible = false context?.let { ctx -> + // just in case + if (ctx.isTvSettings()) { + home_change_api_loading?.isFocusable = true + home_change_api_loading?.isFocusableInTouchMode = true + home_change_api?.isFocusable = true + home_change_api?.isFocusableInTouchMode = true + home_bookmark_select?.isFocusable = true + home_bookmark_select?.isFocusableInTouchMode = true + } + for (syncApi in OAuth2API.OAuth2Apis) { val login = syncApi.loginInfo(ctx) val pic = login?.profilePicture @@ -433,5 +457,7 @@ class HomeFragment : Fragment() { } } } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt index 5ea32286..adc53da5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt @@ -47,7 +47,12 @@ class ParentItemAdapter( private val moreInfo: FrameLayout = itemView.home_child_more_info fun bind(info: HomePageList) { title.text = info.name - recyclerView.adapter = HomeChildItemAdapter(info.list, clickCallback = clickCallback) + recyclerView.adapter = HomeChildItemAdapter( + info.list, + clickCallback = clickCallback, + nextFocusUp = recyclerView.nextFocusUpId, + nextFocusDown = recyclerView.nextFocusDownId + ) (recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged() moreInfo.setOnClickListener { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt index 7d1dae83..840455ad 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt @@ -1018,7 +1018,7 @@ class PlayerFragment : Fragment() { private fun handleKeyEvent(event: KeyEvent): Boolean { event.keyCode.let { keyCode -> - when (event.action) { + when (keyCode) { // don't allow dpad move when hidden KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_DOWN, @@ -1032,6 +1032,17 @@ class PlayerFragment : Fragment() { return true } } + + // netflix capture back and hide ~monke + KeyEvent.KEYCODE_BACK -> { + if (isShowing) { + onClickChange() + return true + } + } + } + + when (event.action) { KeyEvent.ACTION_DOWN -> { when (keyCode) { KeyEvent.KEYCODE_DPAD_CENTER -> { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt index 90d2e611..6936fbd1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt @@ -38,7 +38,7 @@ class SearchAdapter( override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (holder) { is CardViewHolder -> { - holder.bind(cardList[position]) + holder.bind(cardList[position], position) } } } @@ -59,7 +59,7 @@ class SearchAdapter( private val compactView = itemView.context.getGridIsCompact() private val coverHeight: Int = if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt() - fun bind(card: SearchResponse) { + fun bind(card: SearchResponse, position: Int) { if (!compactView) { cardView.apply { layoutParams = FrameLayout.LayoutParams( @@ -69,7 +69,7 @@ class SearchAdapter( } } - SearchResultBuilder.bind(clickCallback, card, itemView,) + SearchResultBuilder.bind(clickCallback, card, itemView) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt index efc45a14..b5878f29 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt @@ -22,7 +22,9 @@ object SearchResultBuilder { clickCallback: (SearchClickCallback) -> Unit, card: SearchResponse, itemView: View, - nextFocusBehavior: Boolean? = null + nextFocusBehavior: Boolean? = null, + nextFocusUp: Int? = null, + nextFocusDown: Int? = null, ) { val cardView: ImageView = itemView.imageView val cardText: TextView? = itemView.imageText @@ -57,6 +59,14 @@ object SearchResultBuilder { ) } + if(nextFocusUp != null) { + bg.nextFocusUpId = nextFocusUp + } + + if(nextFocusDown != null) { + bg.nextFocusDownId = nextFocusDown + } + when (nextFocusBehavior) { true -> bg.nextFocusLeftId = bg.id false -> bg.nextFocusRightId = bg.id diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index d6827e9e..3aeb0c02 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -43,6 +43,7 @@ android:layout_gravity="center_vertical" app:iconifiedByDefault="false" tools:ignore="RtlSymmetry"> + - diff --git a/app/src/main/res/layout/homepage_parent.xml b/app/src/main/res/layout/homepage_parent.xml index 006b1d98..c80ceb09 100644 --- a/app/src/main/res/layout/homepage_parent.xml +++ b/app/src/main/res/layout/homepage_parent.xml @@ -8,8 +8,6 @@ android:layout_height="wrap_content">