Skip to content

Commit fb2e21e

Browse files
committed
make guesture tabs trigger quicker
1 parent 6f383e7 commit fb2e21e

File tree

1 file changed

+80
-33
lines changed
  • new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui

1 file changed

+80
-33
lines changed

new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/GestureSurface.kt

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package net.newpipe.newplayer.ui.videoplayer.gesture_ui
2222

23+
import android.util.Log
2324
import android.view.MotionEvent
2425
import androidx.compose.foundation.layout.Box
2526
import androidx.compose.foundation.layout.fillMaxSize
@@ -36,13 +37,16 @@ import androidx.compose.ui.ExperimentalComposeUiApi
3637
import androidx.compose.ui.Modifier
3738
import androidx.compose.ui.graphics.Color
3839
import androidx.compose.ui.input.pointer.pointerInteropFilter
40+
import androidx.compose.ui.platform.LocalDensity
41+
import androidx.compose.ui.unit.dp
3942
import kotlinx.coroutines.Job
4043
import kotlinx.coroutines.delay
4144
import kotlinx.coroutines.launch
4245
import kotlin.math.abs
4346

44-
private const val MULTITAB_MODE_DELAY: Long = 300
47+
private const val TAG = "GestureSurface"
4548

49+
private const val ENTER_MULTITAB_MODE_DELAY: Long = 300
4650

4751
@Composable
4852
@OptIn(ExperimentalComposeUiApi::class)
@@ -67,59 +71,97 @@ internal fun GestureSurface(
6771
mutableFloatStateOf(0f)
6872
}
6973

74+
var lastFingerDownTime by remember {
75+
mutableStateOf(0L)
76+
}
77+
7078
var lastFingerUpTime by remember {
71-
mutableStateOf(System.currentTimeMillis())
79+
mutableStateOf(0L)
7280
}
7381

7482
val composableScope = rememberCoroutineScope()
7583
var regularTabJob: Job? by remember {
7684
mutableStateOf(null)
7785
}
7886

79-
val defaultActionDown = { event: MotionEvent ->
80-
lastTouchedPosition = TouchedPosition(event.x, event.y)
81-
yMovementSum = 0f
82-
83-
true
84-
}
85-
86-
var multitapAmount:Int by remember {
87+
var multitapAmount: Int by remember {
8788
mutableIntStateOf(0)
8889
}
8990

9091
var cancelMultitapJob: Job? by remember {
9192
mutableStateOf(null)
9293
}
9394

94-
val defaultActionUp = { onMultiTap: (Int) -> Unit, onRegularTap: () -> Unit ->
95-
onUp()
95+
val onMultitap = {
96+
Log.d(TAG, "Trigger multitab")
97+
regularTabJob?.cancel()
98+
cancelMultitapJob?.cancel()
99+
multitapAmount++
100+
onMultiTap(multitapAmount)
101+
cancelMultitapJob = composableScope.launch {
102+
delay(ENTER_MULTITAB_MODE_DELAY)
103+
multitapAmount = 0
104+
onMultiTapFinished()
105+
}
106+
}
107+
108+
/*
109+
* Only use this function in tab down.
110+
*/
111+
val isAMultitapEvent = {
112+
val currentTime = System.currentTimeMillis()
113+
val timeSinceLastFingerDown = currentTime - lastFingerDownTime
114+
timeSinceLastFingerDown <= ENTER_MULTITAB_MODE_DELAY
115+
}
116+
117+
val fingerDownAndUpHappenedInShortEnoughTimeForARegularTab = {
118+
val current = System.currentTimeMillis()
119+
val timeSinceLastFingerUp = current - lastFingerUpTime
120+
timeSinceLastFingerUp < ENTER_MULTITAB_MODE_DELAY
121+
}
96122

97-
if (yMovementSum < 10) {
98-
val currentTime = System.currentTimeMillis()
99-
val timeSinceLastTouch = currentTime - lastFingerUpTime
100-
if (timeSinceLastTouch <= MULTITAB_MODE_DELAY) {
101-
regularTabJob?.cancel()
102-
cancelMultitapJob?.cancel()
103-
multitapAmount++
104-
onMultiTap(multitapAmount)
105-
cancelMultitapJob = composableScope.launch {
106-
delay(MULTITAB_MODE_DELAY)
107-
multitapAmount = 0
108-
onMultiTapFinished()
109-
}
123+
val startToFigureOutIfItsRegularTab = {
124+
Log.d(TAG, " Maybe regular tab?")
125+
regularTabJob = composableScope.launch {
126+
delay(ENTER_MULTITAB_MODE_DELAY)
127+
128+
val isMultitab = isAMultitapEvent();
129+
val fingerDownUpOk = fingerDownAndUpHappenedInShortEnoughTimeForARegularTab()
130+
if (multitapAmount <= 0 && fingerDownUpOk) {
131+
onRegularTap()
132+
Log.d(TAG, " Yes Tab")
110133
} else {
111-
regularTabJob = composableScope.launch {
112-
delay(MULTITAB_MODE_DELAY)
113-
onRegularTap()
114-
}
134+
Log.d(TAG, " No Tab: multitab: $isMultitab, downUpOk: $fingerDownUpOk")
115135
}
136+
}
137+
}
138+
116139

117-
lastFingerUpTime = currentTime
140+
val handleActionDown = { event: MotionEvent ->
141+
Log.d(TAG, "finger down")
142+
lastTouchedPosition = TouchedPosition(event.x, event.y)
143+
yMovementSum = 0f
144+
if (isAMultitapEvent()) {
145+
onMultitap();
146+
} else {
147+
startToFigureOutIfItsRegularTab()
118148
}
149+
lastFingerDownTime = System.currentTimeMillis()
150+
true
151+
}
152+
153+
val handleActionUp = { onMultiTap: (Int) -> Unit, onRegularTap: () -> Unit ->
154+
Log.d(TAG, "finger up");
155+
onUp()
119156
yMovementSum = 0f
157+
lastFingerUpTime = System.currentTimeMillis();
120158
true
121159
}
122160

161+
val rangeAtWhichItsIntendedMovement = with(LocalDensity.current) {
162+
15.dp.toPx()
163+
}
164+
123165
val handleMove = { event: MotionEvent, lambda: (movement: TouchedPosition) -> Unit ->
124166
val currentTouchedPosition = TouchedPosition(event.x, event.y)
125167
val movement = currentTouchedPosition - lastTouchedPosition
@@ -128,17 +170,22 @@ internal fun GestureSurface(
128170

129171
yMovementSum += abs(movement.y)
130172

173+
if (yMovementSum < rangeAtWhichItsIntendedMovement) {
174+
Log.d(TAG, " cancel regular tab")
175+
regularTabJob?.cancel()
176+
}
177+
131178
// filter out left and right movements as these are not important for the app
132-
if(abs(movement.x) <= abs(movement.y)) {
179+
if (abs(movement.x) <= abs(movement.y)) {
133180
lambda(movement)
134181
}
135182
true
136183
}
137184

138185
Box(modifier = modifier.pointerInteropFilter {
139186
when (it.action) {
140-
MotionEvent.ACTION_DOWN -> defaultActionDown(it)
141-
MotionEvent.ACTION_UP -> defaultActionUp(onMultiTap, onRegularTap)
187+
MotionEvent.ACTION_DOWN -> handleActionDown(it)
188+
MotionEvent.ACTION_UP -> handleActionUp(onMultiTap, onRegularTap)
142189
MotionEvent.ACTION_MOVE -> handleMove(it, onMovement)
143190

144191
else -> false

0 commit comments

Comments
 (0)