put touch surface logic into touch surface itself
This commit is contained in:
parent
07a6b0a03f
commit
ae3ef47a3f
|
@ -82,6 +82,9 @@ interface NewPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewPlayerImpl(override val internal_player: Player, override val repository: MediaRepository) : NewPlayer {
|
class NewPlayerImpl(override val internal_player: Player, override val repository: MediaRepository) : NewPlayer {
|
||||||
|
|
||||||
|
private var callbackListeners: MutableList<NewPlayer.Listener> = ArrayList()
|
||||||
|
|
||||||
override val duartion: Long = internal_player.duration
|
override val duartion: Long = internal_player.duration
|
||||||
override val bufferedPercentage: Int = internal_player.bufferedPercentage
|
override val bufferedPercentage: Int = internal_player.bufferedPercentage
|
||||||
override var currentPosition: Long = internal_player.currentPosition
|
override var currentPosition: Long = internal_player.currentPosition
|
||||||
|
@ -112,22 +115,21 @@ class NewPlayerImpl(override val internal_player: Player, override val repositor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fastSeekForward() {
|
override fun fastSeekForward() {
|
||||||
TODO("Not yet implemented")
|
Log.d(TAG, "not implemented fast seek forward")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fastSeekBackward() {
|
override fun fastSeekBackward() {
|
||||||
TODO("Not yet implemented")
|
Log.d(TAG, "not implemented fast seek backward")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addToPlaylist(newItem: String) {
|
override fun addToPlaylist(newItem: String) {
|
||||||
TODO("Not yet implemented")
|
Log.d(TAG, "Not implemented add to playlist")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(callbackListener: NewPlayer.Listener) {
|
override fun addListener(callbackListener: NewPlayer.Listener) {
|
||||||
TODO("Not yet implemented")
|
callbackListeners.add(callbackListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun setStream(stream: MediaItem) {
|
override fun setStream(stream: MediaItem) {
|
||||||
if (internal_player.playbackState == Player.STATE_IDLE) {
|
if (internal_player.playbackState == Player.STATE_IDLE) {
|
||||||
internal_player.prepare()
|
internal_player.prepare()
|
||||||
|
|
|
@ -269,10 +269,16 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
|
|
||||||
override fun fastSeekForward() {
|
override fun fastSeekForward() {
|
||||||
newPlayer?.fastSeekForward()
|
newPlayer?.fastSeekForward()
|
||||||
|
if (mutableUiState.value.uiVisible) {
|
||||||
|
resetHideUiDelayedJob()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fastSeekBackward() {
|
override fun fastSeekBackward() {
|
||||||
newPlayer?.fastSeekBackward()
|
newPlayer?.fastSeekBackward()
|
||||||
|
if (mutableUiState.value.uiVisible) {
|
||||||
|
resetHideUiDelayedJob()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun switchToEmbeddedView() {
|
override fun switchToEmbeddedView() {
|
||||||
|
|
|
@ -50,7 +50,7 @@ import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
import net.newpipe.newplayer.ui.videoplayer.BottomUI
|
import net.newpipe.newplayer.ui.videoplayer.BottomUI
|
||||||
import net.newpipe.newplayer.ui.videoplayer.CenterUI
|
import net.newpipe.newplayer.ui.videoplayer.CenterUI
|
||||||
import net.newpipe.newplayer.ui.videoplayer.TopUI
|
import net.newpipe.newplayer.ui.videoplayer.TopUI
|
||||||
import net.newpipe.newplayer.ui.videoplayer.TouchUi
|
import net.newpipe.newplayer.ui.videoplayer.GestureUI
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun VideoPlayerControllerUI(
|
fun VideoPlayerControllerUI(
|
||||||
|
@ -89,7 +89,7 @@ fun VideoPlayerControllerUI(
|
||||||
.union(WindowInsets.waterfall)
|
.union(WindowInsets.waterfall)
|
||||||
|
|
||||||
if (!uiVissible) {
|
if (!uiVissible) {
|
||||||
TouchUi(
|
GestureUI(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
// .windowInsetsPadding(WindowInsets.systemGestures),
|
// .windowInsetsPadding(WindowInsets.systemGestures),
|
||||||
|
@ -124,7 +124,7 @@ fun VideoPlayerControllerUI(
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedVisibility(uiVissible) {
|
AnimatedVisibility(uiVissible) {
|
||||||
TouchUi(
|
GestureUI(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.windowInsetsPadding(WindowInsets.systemGestures),
|
.windowInsetsPadding(WindowInsets.systemGestures),
|
||||||
|
|
|
@ -93,7 +93,9 @@ fun VideoPlayerControllerUIPreviewEmbeddedColorPreview() {
|
||||||
hideUi = {},
|
hideUi = {},
|
||||||
seekPositionChanged = {},
|
seekPositionChanged = {},
|
||||||
seekingFinished = {},
|
seekingFinished = {},
|
||||||
embeddedDraggedDownBy = {})
|
embeddedDraggedDownBy = {},
|
||||||
|
fastSeekForward = {},
|
||||||
|
fastSeekBackward = {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
/* NewPlayer
|
||||||
|
*
|
||||||
|
* @author Christian Schabesberger
|
||||||
|
*
|
||||||
|
* Copyright (C) NewPipe e.V. 2024 <code(at)newpipe-ev.de>
|
||||||
|
*
|
||||||
|
* NewPlayer is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPlayer is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPlayer. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.newplayer.ui.videoplayer
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.input.pointer.pointerInteropFilter
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
private const val TAG = "TouchUi"
|
||||||
|
|
||||||
|
private data class TouchedPosition(val x: Float, val y: Float) {
|
||||||
|
operator fun minus(other: TouchedPosition) = TouchedPosition(this.x - other.x, this.y - other.y)
|
||||||
|
}
|
||||||
|
|
||||||
|
const val DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS: Long = 200
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun GestureUI(
|
||||||
|
modifier: Modifier,
|
||||||
|
hideUi: () -> Unit,
|
||||||
|
showUi: () -> Unit,
|
||||||
|
uiVissible: Boolean,
|
||||||
|
fullscreen: Boolean,
|
||||||
|
switchToFullscreen: () -> Unit,
|
||||||
|
switchToEmbeddedView: () -> Unit,
|
||||||
|
embeddedDraggedDownBy: (Float) -> Unit,
|
||||||
|
fastSeekBackward: () -> Unit,
|
||||||
|
fastSeekForward: () -> Unit,
|
||||||
|
) {
|
||||||
|
val defaultOnRegularTap = {
|
||||||
|
if (uiVissible) {
|
||||||
|
hideUi()
|
||||||
|
} else {
|
||||||
|
showUi()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fullscreen) {
|
||||||
|
Row(modifier = modifier) {
|
||||||
|
TouchSurface(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
onRegularTap = defaultOnRegularTap,
|
||||||
|
onDoubleTab = fastSeekBackward
|
||||||
|
)
|
||||||
|
TouchSurface(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
onRegularTap = defaultOnRegularTap,
|
||||||
|
onMovement = { movement ->
|
||||||
|
if (0 < movement.y) {
|
||||||
|
switchToEmbeddedView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
TouchSurface(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
onRegularTap = defaultOnRegularTap,
|
||||||
|
onDoubleTab = fastSeekForward
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else { // (!fullscreen)
|
||||||
|
val handleDownwardMovement = { movement: TouchedPosition ->
|
||||||
|
Log.d(TAG, "${movement.x}:${movement.y}")
|
||||||
|
if (0 < movement.y) {
|
||||||
|
embeddedDraggedDownBy(movement.y)
|
||||||
|
} else {
|
||||||
|
switchToFullscreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(modifier = modifier) {
|
||||||
|
TouchSurface(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
onDoubleTab = fastSeekBackward,
|
||||||
|
onRegularTap = defaultOnRegularTap,
|
||||||
|
onMovement = handleDownwardMovement
|
||||||
|
)
|
||||||
|
TouchSurface(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
onDoubleTab = fastSeekForward,
|
||||||
|
onRegularTap = defaultOnRegularTap,
|
||||||
|
onMovement = handleDownwardMovement
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
private fun TouchSurface(
|
||||||
|
modifier: Modifier,
|
||||||
|
color: Color = Color.Transparent,
|
||||||
|
onDoubleTab: () -> Unit = {},
|
||||||
|
onRegularTap: () -> Unit = {},
|
||||||
|
onMovement: (TouchedPosition) -> Unit = {}
|
||||||
|
) {
|
||||||
|
var moveOccured by remember {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastTouchedPosition by remember {
|
||||||
|
mutableStateOf(TouchedPosition(0f, 0f))
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastTouchTime by remember {
|
||||||
|
mutableStateOf(System.currentTimeMillis())
|
||||||
|
}
|
||||||
|
|
||||||
|
val composableScope = rememberCoroutineScope()
|
||||||
|
var regularTabJob: Job? by remember {
|
||||||
|
mutableStateOf(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val defaultActionDown = { event: MotionEvent ->
|
||||||
|
lastTouchedPosition = TouchedPosition(event.x, event.y)
|
||||||
|
moveOccured = false
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val defaultActionUp = { onDoubleTap: () -> Unit, onRegularTap: () -> Unit ->
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
if (!moveOccured) {
|
||||||
|
val timeSinceLastTouch = currentTime - lastTouchTime
|
||||||
|
if (timeSinceLastTouch <= DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS) {
|
||||||
|
regularTabJob?.cancel()
|
||||||
|
onDoubleTap()
|
||||||
|
} else {
|
||||||
|
regularTabJob = composableScope.launch {
|
||||||
|
delay(DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS)
|
||||||
|
onRegularTap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
moveOccured = false
|
||||||
|
lastTouchTime = currentTime
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
val handleMove = { event: MotionEvent, lambda: (movement: TouchedPosition) -> Unit ->
|
||||||
|
val currentTouchedPosition = TouchedPosition(event.x, event.y)
|
||||||
|
val movement = currentTouchedPosition - lastTouchedPosition
|
||||||
|
lastTouchedPosition = currentTouchedPosition
|
||||||
|
moveOccured = true
|
||||||
|
lambda(movement)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(modifier = modifier.pointerInteropFilter {
|
||||||
|
when (it.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> defaultActionDown(it)
|
||||||
|
MotionEvent.ACTION_UP -> defaultActionUp(onDoubleTab, onRegularTap)
|
||||||
|
MotionEvent.ACTION_MOVE -> handleMove(it, onMovement)
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Surface(color = color, modifier = Modifier.fillMaxSize()) {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,214 +0,0 @@
|
||||||
/* NewPlayer
|
|
||||||
*
|
|
||||||
* @author Christian Schabesberger
|
|
||||||
*
|
|
||||||
* Copyright (C) NewPipe e.V. 2024 <code(at)newpipe-ev.de>
|
|
||||||
*
|
|
||||||
* NewPlayer is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* NewPlayer is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with NewPlayer. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.newpipe.newplayer.ui.videoplayer
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.MotionEvent
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.input.pointer.pointerInteropFilter
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
private const val TAG = "TouchUi"
|
|
||||||
|
|
||||||
private data class TouchedPosition(val x: Float, val y: Float) {
|
|
||||||
operator fun minus(other: TouchedPosition) = TouchedPosition(this.x - other.x, this.y - other.y)
|
|
||||||
}
|
|
||||||
|
|
||||||
const val DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS:Long = 150
|
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
|
||||||
fun TouchUi(
|
|
||||||
modifier: Modifier,
|
|
||||||
hideUi: () -> Unit,
|
|
||||||
showUi: () -> Unit,
|
|
||||||
uiVissible: Boolean,
|
|
||||||
fullscreen: Boolean,
|
|
||||||
switchToFullscreen: () -> Unit,
|
|
||||||
switchToEmbeddedView: () -> Unit,
|
|
||||||
embeddedDraggedDownBy: (Float) -> Unit,
|
|
||||||
fastSeekBackward: () -> Unit,
|
|
||||||
fastSeekForward: () -> Unit,
|
|
||||||
) {
|
|
||||||
|
|
||||||
var moveOccured by remember {
|
|
||||||
mutableStateOf(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastTouchedPosition by remember {
|
|
||||||
mutableStateOf(TouchedPosition(0f, 0f))
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastTouchTime by remember {
|
|
||||||
mutableStateOf(System.currentTimeMillis())
|
|
||||||
}
|
|
||||||
|
|
||||||
val composableScope = rememberCoroutineScope()
|
|
||||||
var showUiJob: Job? by remember{
|
|
||||||
mutableStateOf(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
val defaultActionDown = { event: MotionEvent ->
|
|
||||||
lastTouchedPosition = TouchedPosition(event.x, event.y)
|
|
||||||
moveOccured = false
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
val defaultActionUp = { onDoubleTap: () -> Unit ->
|
|
||||||
val currentTime = System.currentTimeMillis()
|
|
||||||
if (!moveOccured) {
|
|
||||||
val timeSinceLastTouch = currentTime - lastTouchTime
|
|
||||||
if(timeSinceLastTouch <= DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS) {
|
|
||||||
showUiJob?.cancel()
|
|
||||||
onDoubleTap()
|
|
||||||
} else {
|
|
||||||
if (uiVissible) {
|
|
||||||
showUiJob = composableScope.launch {
|
|
||||||
delay(DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS)
|
|
||||||
hideUi()
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
showUiJob = composableScope.launch {
|
|
||||||
delay(DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS)
|
|
||||||
showUi()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
moveOccured = false
|
|
||||||
lastTouchTime = currentTime
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
val handleMove = { event: MotionEvent, lambda: (movement: TouchedPosition) -> Unit ->
|
|
||||||
val currentTouchedPosition = TouchedPosition(event.x, event.y)
|
|
||||||
val movement = currentTouchedPosition - lastTouchedPosition
|
|
||||||
lastTouchedPosition = currentTouchedPosition
|
|
||||||
moveOccured = true
|
|
||||||
lambda(movement)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fullscreen) {
|
|
||||||
Row(modifier = modifier) {
|
|
||||||
TouchSurface(modifier = Modifier.weight(1f)
|
|
||||||
.pointerInteropFilter {
|
|
||||||
when (it.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> defaultActionDown(it)
|
|
||||||
MotionEvent.ACTION_UP -> defaultActionUp(fastSeekBackward)
|
|
||||||
MotionEvent.ACTION_MOVE -> handleMove(it) { movement ->
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
TouchSurface(modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.pointerInteropFilter {
|
|
||||||
when (it.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> defaultActionDown(it)
|
|
||||||
MotionEvent.ACTION_UP -> defaultActionUp({})
|
|
||||||
MotionEvent.ACTION_MOVE -> handleMove(it) { movement ->
|
|
||||||
if (0 < movement.y) {
|
|
||||||
switchToEmbeddedView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
TouchSurface(modifier = Modifier.weight(1f)
|
|
||||||
.pointerInteropFilter {
|
|
||||||
when (it.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> defaultActionDown(it)
|
|
||||||
MotionEvent.ACTION_UP -> defaultActionUp(fastSeekForward)
|
|
||||||
MotionEvent.ACTION_MOVE -> handleMove(it) { movement ->
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Row(modifier = modifier) {
|
|
||||||
TouchSurface(modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.pointerInteropFilter {
|
|
||||||
when (it.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> defaultActionDown(it)
|
|
||||||
MotionEvent.ACTION_UP -> defaultActionUp(fastSeekBackward)
|
|
||||||
MotionEvent.ACTION_MOVE -> handleMove(it) { movement ->
|
|
||||||
Log.d(TAG, "${it.x}:${it.y}")
|
|
||||||
if (0 < movement.y) {
|
|
||||||
embeddedDraggedDownBy(movement.y)
|
|
||||||
} else {
|
|
||||||
switchToFullscreen()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
TouchSurface(modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.pointerInteropFilter {
|
|
||||||
when (it.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> defaultActionDown(it)
|
|
||||||
MotionEvent.ACTION_UP -> defaultActionUp(fastSeekForward)
|
|
||||||
MotionEvent.ACTION_MOVE -> handleMove(it) { movement ->
|
|
||||||
if (0 < movement.y) {
|
|
||||||
embeddedDraggedDownBy(movement.y)
|
|
||||||
} else {
|
|
||||||
switchToFullscreen()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TouchSurface(modifier: Modifier, color: Color = Color.Transparent) {
|
|
||||||
Box(modifier = modifier) {
|
|
||||||
Surface(color = color, modifier = Modifier.fillMaxSize()) {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="16dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M3,2 L22,12 L3,22 Z" />
|
||||||
|
</vector>
|
Loading…
Reference in New Issue