diff --git a/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt index 0abd16d1..7d1dc903 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt @@ -37,7 +37,7 @@ object CommonActivity { val onDialogDismissedEvent = Event() var playerEventListener: ((PlayerEventType) -> Unit)? = null - var keyEventListener: ((KeyEvent?) -> Boolean)? = null + var keyEventListener: ((Pair) -> Boolean)? = null var currentToast: Toast? = null @@ -134,8 +134,8 @@ object CommonActivity { } } - fun loadThemes(act: Activity? ) { - if(act == null) return + fun loadThemes(act: Activity?) { + if (act == null) return val settingsManager = PreferenceManager.getDefaultSharedPreferences(act) val currentTheme = @@ -323,6 +323,7 @@ object CommonActivity { val nextView = act.findViewById(next) if (nextView != null) { nextView.requestFocus() + keyEventListener?.invoke(Pair(event, true)) return true } } @@ -345,7 +346,7 @@ object CommonActivity { } } - if (keyEventListener?.invoke(event) == true) { + if (keyEventListener?.invoke(Pair(event, false)) == true) { return true } return null diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt index d8d808e4..6012ed77 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt @@ -58,7 +58,6 @@ const val PRELOAD_NEXT_EPISODE_PERCENTAGE = 80 const val NEXT_WATCH_EPISODE_PERCENTAGE = 95 abstract class AbstractPlayerFragment( - @LayoutRes val layout: Int, val player: IPlayer = CS3IPlayer() ) : Fragment() { var resizeMode: Int = 0 @@ -66,6 +65,9 @@ abstract class AbstractPlayerFragment( var subView: SubtitleView? = null var isBuffering = true + @LayoutRes + protected var layout: Int = R.layout.fragment_player + open fun nextEpisode() { throw NotImplementedError() } @@ -78,12 +80,12 @@ abstract class AbstractPlayerFragment( throw NotImplementedError() } - open fun playerDimensionsLoaded(widthHeight : Pair) { + open fun playerDimensionsLoaded(widthHeight: Pair) { throw NotImplementedError() } - private fun keepScreenOn(on : Boolean) { - if(on) { + private fun keepScreenOn(on: Boolean) { + if (on) { activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } else { activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -128,7 +130,7 @@ abstract class AbstractPlayerFragment( } // somehow the phone is wacked - if(!startedAnimation) { + if (!startedAnimation) { player_pause_play?.setImageResource(if (isPlayingRightNow) R.drawable.netflix_pause else R.drawable.netflix_play) } } else { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt index 8534f80e..1a92935c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt @@ -56,7 +56,7 @@ const val DOUBLE_TAB_MINIMUM_TIME_BETWEEN = 200L // this also affects the UI const val DOUBLE_TAB_PAUSE_PERCENTAGE = 0.15 // in both directions // All the UI Logic for the player -open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) { +open class FullScreenPlayer : AbstractPlayerFragment() { // state of player UI protected var isShowing = false protected var isLocked = false @@ -352,6 +352,7 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) { } activity?.hideSystemUI() animateLayoutChanges() + player_pause_play.requestFocus() } private fun toggleLock() { @@ -413,13 +414,15 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) { private fun updateLockUI() { player_lock?.setIconResource(if (isLocked) R.drawable.video_locked else R.drawable.video_unlocked) - val color = if (isLocked) context?.colorFromAttribute(R.attr.colorPrimary) - else Color.WHITE - if (color != null) { - player_lock?.setTextColor(color) - player_lock?.iconTint = ColorStateList.valueOf(color) - player_lock?.rippleColor = - ColorStateList.valueOf(Color.argb(50, color.red, color.green, color.blue)) + if (layout == R.layout.fragment_player) { + val color = if (isLocked) context?.colorFromAttribute(R.attr.colorPrimary) + else Color.WHITE + if (color != null) { + player_lock?.setTextColor(color) + player_lock?.iconTint = ColorStateList.valueOf(color) + player_lock?.rippleColor = + ColorStateList.valueOf(Color.argb(50, color.red, color.green, color.blue)) + } } } @@ -819,50 +822,71 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) { return true } - private fun handleKeyEvent(event: KeyEvent): Boolean { - event.keyCode.let { keyCode -> - when (event.action) { - KeyEvent.ACTION_DOWN -> { - when (keyCode) { - KeyEvent.KEYCODE_DPAD_CENTER, KeyEvent.KEYCODE_DPAD_UP -> { - if (!isShowing) { - onClickChange() - return true + private fun handleKeyEvent(event: KeyEvent, hasNavigated: Boolean): Boolean { + if (hasNavigated) { + autoHide() + } else { + event.keyCode.let { keyCode -> + when (event.action) { + KeyEvent.ACTION_DOWN -> { + when (keyCode) { + KeyEvent.KEYCODE_DPAD_CENTER -> { + if (!isShowing) { + if (!isLocked) player.handleEvent(CSPlayerEvent.PlayPauseToggle) + onClickChange() + return true + } + } + KeyEvent.KEYCODE_DPAD_UP -> { + if (!isShowing) { + onClickChange() + return true + } + } + KeyEvent.KEYCODE_DPAD_LEFT -> { + if (!isShowing && !isLocked) { + player.seekTime(-10000L) + return true + } else if (player_pause_play?.isFocused == true) { + player.seekTime(-30000L) + return true + } + } + KeyEvent.KEYCODE_DPAD_RIGHT -> { + if (!isShowing && !isLocked) { + player.seekTime(10000L) + return true + } else if (player_pause_play?.isFocused == true) { + player.seekTime(30000L) + return true + } } } } - - //println("Keycode: $keyCode") - //showToast( - // this, - // "Got Keycode $keyCode | ${KeyEvent.keyCodeToString(keyCode)} \n ${event?.action}", - // Toast.LENGTH_LONG - //) } - } - when (keyCode) { - // don't allow dpad move when hidden - KeyEvent.KEYCODE_DPAD_LEFT, - KeyEvent.KEYCODE_DPAD_DOWN, - KeyEvent.KEYCODE_DPAD_UP, - KeyEvent.KEYCODE_DPAD_RIGHT, - KeyEvent.KEYCODE_DPAD_DOWN_LEFT, - KeyEvent.KEYCODE_DPAD_DOWN_RIGHT, - KeyEvent.KEYCODE_DPAD_UP_LEFT, - KeyEvent.KEYCODE_DPAD_UP_RIGHT -> { - if (!isShowing) { - return true - } else { - autoHide() + when (keyCode) { + // don't allow dpad move when hidden + + KeyEvent.KEYCODE_DPAD_DOWN, + KeyEvent.KEYCODE_DPAD_UP, + KeyEvent.KEYCODE_DPAD_DOWN_LEFT, + KeyEvent.KEYCODE_DPAD_DOWN_RIGHT, + KeyEvent.KEYCODE_DPAD_UP_LEFT, + KeyEvent.KEYCODE_DPAD_UP_RIGHT -> { + if (!isShowing) { + return true + } else { + autoHide() + } } - } - // netflix capture back and hide ~monke - KeyEvent.KEYCODE_BACK -> { - if (isShowing) { - onClickChange() - return true + // netflix capture back and hide ~monke + KeyEvent.KEYCODE_BACK -> { + if (isShowing) { + onClickChange() + return true + } } } } @@ -940,12 +964,11 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) { } // handle tv controls directly based on player state - keyEventListener = { keyEvent -> - if (keyEvent != null) { - handleKeyEvent(keyEvent) - } else { - false - } + keyEventListener = { eventNav -> + val (event, hasNavigated) = eventNav + if (event != null) + handleKeyEvent(event, hasNavigated) + else false } try { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index 1e84ac31..936c6981 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -22,6 +22,7 @@ import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType import com.lagradost.cloudstream3.ui.result.ResultEpisode +import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe @@ -279,7 +280,7 @@ class GeneratorPlayer : FullScreenPlayer() { sourceDialog.dismissSafe(activity) } } - } catch (e : Exception) { + } catch (e: Exception) { logError(e) } } @@ -485,6 +486,10 @@ class GeneratorPlayer : FullScreenPlayer() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { + // this is used instead of layout-television to follow the settings and some TV devices are not classified as TV for some reason + layout = + if (context?.isTvSettings() == true) R.layout.fragment_player_tv else R.layout.fragment_player + viewModel = ViewModelProvider(this)[PlayerGeneratorViewModel::class.java] viewModel.attachGenerator(lastUsedGenerator) return super.onCreateView(inflater, container, savedInstanceState) diff --git a/app/src/main/res/color/player_button_tv.xml b/app/src/main/res/color/player_button_tv.xml new file mode 100644 index 00000000..f529e5b6 --- /dev/null +++ b/app/src/main/res/color/player_button_tv.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/player_on_button_tv.xml b/app/src/main/res/color/player_on_button_tv.xml new file mode 100644 index 00000000..2ca33a84 --- /dev/null +++ b/app/src/main/res/color/player_on_button_tv.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/player_button_tv.xml b/app/src/main/res/drawable/player_button_tv.xml new file mode 100644 index 00000000..dede0433 --- /dev/null +++ b/app/src/main/res/drawable/player_button_tv.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/player_gradient_tv.xml b/app/src/main/res/drawable/player_gradient_tv.xml new file mode 100644 index 00000000..79bb3af5 --- /dev/null +++ b/app/src/main/res/drawable/player_gradient_tv.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_player_tv.xml b/app/src/main/res/layout/fragment_player_tv.xml new file mode 100644 index 00000000..1bd765f1 --- /dev/null +++ b/app/src/main/res/layout/fragment_player_tv.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/player_custom_layout_tv.xml b/app/src/main/res/layout/player_custom_layout_tv.xml new file mode 100644 index 00000000..37dbddc0 --- /dev/null +++ b/app/src/main/res/layout/player_custom_layout_tv.xml @@ -0,0 +1,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 41ae22f9..740896ba 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -421,6 +421,32 @@ 10dp + +