fix: Implementation of Mandatory System Gesture Insets to Avoid Conflicts with System Gestures (#286)

* fix: gesture conflict in seek gesture

* fix: gesture conflict in volume and brightness gestures

* refactor: move to separate method and add implementation for previous Android versions

* lint: run ktlintFormat

---------

Co-authored-by: Jarne Demeulemeester <jarnedemeulemeester@gmail.com>
This commit is contained in:
Anil Kumar Beesetti 2023-02-14 01:53:12 +05:30 committed by GitHub
parent 49cf26e543
commit e32a390d1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 5 deletions

View file

@ -1,13 +1,16 @@
package dev.jdtech.jellyfin.utils
import android.annotation.SuppressLint
import android.content.res.Resources
import android.media.AudioManager
import android.os.Build
import android.os.SystemClock
import android.provider.Settings
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.View
import android.view.WindowInsets
import android.view.WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
import android.view.WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF
import androidx.media3.ui.AspectRatioFrameLayout
@ -47,6 +50,9 @@ class PlayerGestureHelper(
private var lastScaleEvent: Long = 0
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
private val screenHeight = Resources.getSystem().displayMetrics.heightPixels
private val tapGestureDetector = GestureDetector(
playerView.context,
object : GestureDetector.SimpleOnGestureListener() {
@ -82,8 +88,8 @@ class PlayerGestureHelper(
distanceX: Float,
distanceY: Float
): Boolean {
if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_TOP))
return false
// Excludes area where app gestures conflicting with system gestures
if (inExclusionArea(firstEvent)) return false
// Check whether swipe was oriented vertically
if (abs(distanceY / distanceX) < 2) {
@ -120,8 +126,8 @@ class PlayerGestureHelper(
distanceX: Float,
distanceY: Float
): Boolean {
if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_TOP))
return false
// Excludes area where app gestures conflicting with system gestures
if (inExclusionArea(firstEvent)) return false
if (abs(distanceY / distanceX) < 2) return false
@ -267,6 +273,26 @@ class PlayerGestureHelper(
return String.format("%s%02d:%02d:%02d", sign, seconds / 3600, (seconds / 60) % 60, seconds % 60)
}
/**
* Check if [firstEvent] is in the gesture exclusion area
*/
private fun inExclusionArea(firstEvent: MotionEvent): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val insets = playerView.rootWindowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.systemGestures())
if ((firstEvent.x < insets.left) || (firstEvent.x > (screenWidth - insets.right)) ||
(firstEvent.y < insets.top) || (firstEvent.y > (screenHeight - insets.bottom))
)
return true
} else if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_VERTICAL) ||
firstEvent.y > screenHeight - playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_VERTICAL) ||
firstEvent.x < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_HORIZONTAL) ||
firstEvent.x > screenWidth - playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_HORIZONTAL)
)
return true
return false
}
init {
if (appPreferences.playerBrightnessRemember) {
activity.window.attributes.screenBrightness = appPreferences.playerBrightness

View file

@ -2,7 +2,8 @@ package dev.jdtech.jellyfin
object Constants {
// player
const val GESTURE_EXCLUSION_AREA_TOP = 48
const val GESTURE_EXCLUSION_AREA_VERTICAL = 48
const val GESTURE_EXCLUSION_AREA_HORIZONTAL = 24
const val FULL_SWIPE_RANGE_SCREEN_RATIO = 0.66f
const val ZOOM_SCALE_BASE = 1f
const val ZOOM_SCALE_THRESHOLD = 0.01f