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 9325f067f8..70f7e36865 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 @@ -21,13 +21,14 @@ import android.view.MotionEvent import android.view.Surface import android.view.View import android.view.ViewGroup +import android.view.WindowInsets import android.view.WindowManager import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES import android.view.animation.AlphaAnimation import android.view.animation.Animation import android.view.animation.AnimationUtils -import androidx.annotation.OptIn import android.widget.LinearLayout +import androidx.annotation.OptIn import androidx.core.graphics.blue import androidx.core.graphics.green import androidx.core.graphics.red @@ -76,6 +77,7 @@ import kotlin.math.max import kotlin.math.min import kotlin.math.round + const val MINIMUM_SEEK_TIME = 7000L // when swipe seeking const val MINIMUM_VERTICAL_SWIPE = 2.0f // in percentage const val MINIMUM_HORIZONTAL_SWIPE = 2.0f // in percentage @@ -202,12 +204,34 @@ open class FullScreenPlayer : AbstractPlayerFragment() { throw NotImplementedError() } - /** Returns false if the touch is on the status bar or navigation bar*/ - private fun isValidTouch(rawX: Float, rawY: Float): Boolean { - val statusHeight = statusBarHeight ?: 0 - // val navHeight = navigationBarHeight ?: 0 - // nav height is removed because screenWidth already takes into account that - return rawY > statusHeight && rawX < screenWidth //- navHeight + /** + * [isValidTouch] should be called on a [View] spanning across the screen for reliable results. + * + * Android has supported gesture navigation properly since API-30. We get the absolute screen dimens using + * [WindowManager.getCurrentWindowMetrics] and remove the stable insets + * {[WindowInsets.getInsetsIgnoringVisibility]} to get a safe perimeter. + * This approach supports any and all types of necessary system insets. + * + * @return false if the touch is on the status bar or navigation bar + * */ + private fun View.isValidTouch(rawX: Float, rawY: Float): Boolean { + // NOTE: screenWidth is without the navbar width when 3button nav is turned on. + if(Build.VERSION.SDK_INT >= 30) { + // real = absolute dimen without any default deductions like navbar width + val windowMetrics = (context?.getSystemService(Context.WINDOW_SERVICE) as? WindowManager)?.currentWindowMetrics + val realScreenHeight = windowMetrics?.let { windowMetrics.bounds.bottom - windowMetrics.bounds.top } ?: screenHeight + val realScreenWidth = windowMetrics?.let { windowMetrics.bounds.right - windowMetrics.bounds.left } ?: screenWidth + + val insets = rootWindowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) + val isOutsideHeight = rawY < insets.top || rawY > (realScreenHeight - insets.bottom) + val isOutsideWidth = if(windowMetrics == null) rawX < screenWidth + else rawX < insets.left || rawX > (realScreenWidth - insets.right) + + return !(isOutsideWidth || isOutsideHeight) + } else { + val statusHeight = statusBarHeight ?: 0 + return rawY > statusHeight && rawX < screenWidth + } } override fun exitedPipMode() { @@ -937,7 +961,7 @@ open class FullScreenPlayer : AbstractPlayerFragment() { when (event.action) { MotionEvent.ACTION_DOWN -> { // validates if the touch is inside of the player area - isCurrentTouchValid = isValidTouch(currentTouch.x, currentTouch.y) + isCurrentTouchValid = view.isValidTouch(currentTouch.x, currentTouch.y) /*if (isCurrentTouchValid && player_episode_list?.isVisible == true) { player_episode_list?.isVisible = false } else*/ if (isCurrentTouchValid) {