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:
parent
49cf26e543
commit
e32a390d1a
2 changed files with 32 additions and 5 deletions
|
@ -1,13 +1,16 @@
|
||||||
package dev.jdtech.jellyfin.utils
|
package dev.jdtech.jellyfin.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.res.Resources
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
|
import android.os.Build
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.view.GestureDetector
|
import android.view.GestureDetector
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.ScaleGestureDetector
|
import android.view.ScaleGestureDetector
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.WindowInsets
|
||||||
import android.view.WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
|
import android.view.WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
|
||||||
import android.view.WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF
|
import android.view.WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF
|
||||||
import androidx.media3.ui.AspectRatioFrameLayout
|
import androidx.media3.ui.AspectRatioFrameLayout
|
||||||
|
@ -47,6 +50,9 @@ class PlayerGestureHelper(
|
||||||
|
|
||||||
private var lastScaleEvent: Long = 0
|
private var lastScaleEvent: Long = 0
|
||||||
|
|
||||||
|
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||||
|
private val screenHeight = Resources.getSystem().displayMetrics.heightPixels
|
||||||
|
|
||||||
private val tapGestureDetector = GestureDetector(
|
private val tapGestureDetector = GestureDetector(
|
||||||
playerView.context,
|
playerView.context,
|
||||||
object : GestureDetector.SimpleOnGestureListener() {
|
object : GestureDetector.SimpleOnGestureListener() {
|
||||||
|
@ -82,8 +88,8 @@ class PlayerGestureHelper(
|
||||||
distanceX: Float,
|
distanceX: Float,
|
||||||
distanceY: Float
|
distanceY: Float
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_TOP))
|
// Excludes area where app gestures conflicting with system gestures
|
||||||
return false
|
if (inExclusionArea(firstEvent)) return false
|
||||||
|
|
||||||
// Check whether swipe was oriented vertically
|
// Check whether swipe was oriented vertically
|
||||||
if (abs(distanceY / distanceX) < 2) {
|
if (abs(distanceY / distanceX) < 2) {
|
||||||
|
@ -120,8 +126,8 @@ class PlayerGestureHelper(
|
||||||
distanceX: Float,
|
distanceX: Float,
|
||||||
distanceY: Float
|
distanceY: Float
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_TOP))
|
// Excludes area where app gestures conflicting with system gestures
|
||||||
return false
|
if (inExclusionArea(firstEvent)) return false
|
||||||
|
|
||||||
if (abs(distanceY / distanceX) < 2) 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)
|
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 {
|
init {
|
||||||
if (appPreferences.playerBrightnessRemember) {
|
if (appPreferences.playerBrightnessRemember) {
|
||||||
activity.window.attributes.screenBrightness = appPreferences.playerBrightness
|
activity.window.attributes.screenBrightness = appPreferences.playerBrightness
|
||||||
|
|
|
@ -2,7 +2,8 @@ package dev.jdtech.jellyfin
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
// player
|
// 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 FULL_SWIPE_RANGE_SCREEN_RATIO = 0.66f
|
||||||
const val ZOOM_SCALE_BASE = 1f
|
const val ZOOM_SCALE_BASE = 1f
|
||||||
const val ZOOM_SCALE_THRESHOLD = 0.01f
|
const val ZOOM_SCALE_THRESHOLD = 0.01f
|
||||||
|
|
Loading…
Reference in a new issue