fix more fast forward foo

This commit is contained in:
Christian Schabesberger 2024-08-07 17:33:49 +02:00
parent 628ba4db1b
commit 2b197b62b7
10 changed files with 167 additions and 144 deletions

View File

@ -52,8 +52,7 @@ interface NewPlayer {
fun prepare() fun prepare()
fun play() fun play()
fun pause() fun pause()
fun fastSeekForward(ntimes: Int = 1) fun fastSeek(steps: Int)
fun fastSeekBackward(ntimes: Int = 1)
fun seekTo(millisecond: Long) fun seekTo(millisecond: Long)
fun addToPlaylist(newItem: String) fun addToPlaylist(newItem: String)
fun addListener(callbackListener: Listener) fun addListener(callbackListener: Listener)
@ -115,14 +114,9 @@ class NewPlayerImpl(override val internal_player: Player, override val repositor
internal_player.pause() internal_player.pause()
} }
override fun fastSeekForward(ntimes: Int) { override fun fastSeek(steps: Int) {
val currentPosition = internal_player.currentPosition val currentPosition = internal_player.currentPosition
internal_player.seekTo(currentPosition + fastSeekAmountSec * 1000 * ntimes) internal_player.seekTo(currentPosition + fastSeekAmountSec * 1000 * steps)
}
override fun fastSeekBackward(ntimes: Int) {
val currentPosition = internal_player.currentPosition
internal_player.seekTo(currentPosition - fastSeekAmountSec * 1000 * ntimes)
} }
override fun seekTo(millisecond: Long) { override fun seekTo(millisecond: Long) {

View File

@ -54,7 +54,7 @@ data class VideoPlayerUIState(
isLoading = true, isLoading = true,
durationInMs = 0, durationInMs = 0,
playbackPositionInMs = 0, playbackPositionInMs = 0,
fastseekSeconds = 10 fastseekSeconds = 0
) )
} }
} }

View File

@ -48,8 +48,8 @@ interface VideoPlayerViewModel {
fun seekPositionChanged(newValue: Float) fun seekPositionChanged(newValue: Float)
fun seekingFinished() fun seekingFinished()
fun embeddedDraggedDown(offset: Float) fun embeddedDraggedDown(offset: Float)
fun fastSeekForward() fun fastSeek(count: Int)
fun fastSeekBackward() fun fastSeekFinished()
interface Listener { interface Listener {
fun onFullscreenToggle(isFullscreen: Boolean) {} fun onFullscreenToggle(isFullscreen: Boolean) {}

View File

@ -268,19 +268,23 @@ class VideoPlayerViewModelImpl @Inject constructor(
callbackListeners.forEach { it?.embeddedPlayerDraggedDown(offset) } callbackListeners.forEach { it?.embeddedPlayerDraggedDown(offset) }
} }
override fun fastSeekForward() { override fun fastSeek(count: Int) {
mutableUiState.update { it.copy(fastseekSeconds = newPlayer?.fastSeekAmountSec ?: 10) } mutableUiState.update {
newPlayer?.fastSeekForward() it.copy(
fastseekSeconds = count * (newPlayer?.fastSeekAmountSec ?: 10)
)
}
if (mutableUiState.value.uiVisible) { if (mutableUiState.value.uiVisible) {
resetHideUiDelayedJob() resetHideUiDelayedJob()
} }
} }
override fun fastSeekBackward() { override fun fastSeekFinished() {
mutableUiState.update { it.copy(fastseekSeconds = newPlayer?.fastSeekAmountSec ?: 10) } val fastSeekAmount = mutableUiState.value.fastseekSeconds
newPlayer?.fastSeekBackward() newPlayer?.fastSeek(fastSeekAmount)
if (mutableUiState.value.uiVisible) { mutableUiState.update {
resetHideUiDelayedJob() it.copy(fastseekSeconds = 0)
} }
} }
@ -362,11 +366,11 @@ class VideoPlayerViewModelImpl @Inject constructor(
println("dymmy embeddedDraggedDown: offset: ${offset}") println("dymmy embeddedDraggedDown: offset: ${offset}")
} }
override fun fastSeekForward() { override fun fastSeek(steps: Int) {
println("dummy impl") println("dummy impl")
} }
override fun fastSeekBackward() { override fun fastSeekFinished() {
println("dummy impl") println("dummy impl")
} }

View File

@ -74,8 +74,8 @@ fun VideoPlayerControllerUI(
seekPositionChanged: (Float) -> Unit, seekPositionChanged: (Float) -> Unit,
seekingFinished: () -> Unit, seekingFinished: () -> Unit,
embeddedDraggedDownBy: (Float) -> Unit, embeddedDraggedDownBy: (Float) -> Unit,
fastSeekBackward: () -> Unit, fastSeek: (Int) -> Unit,
fastSeekForward: () -> Unit, finishFastSeek: () -> Unit
) { ) {
if (fullscreen) { if (fullscreen) {
@ -98,12 +98,12 @@ fun VideoPlayerControllerUI(
showUi = showUi, showUi = showUi,
uiVissible = uiVissible, uiVissible = uiVissible,
fullscreen = fullscreen, fullscreen = fullscreen,
fastSeekSeconds = fastSeekSeconds,
switchToFullscreen = switchToFullscreen, switchToFullscreen = switchToFullscreen,
switchToEmbeddedView = switchToEmbeddedView, switchToEmbeddedView = switchToEmbeddedView,
embeddedDraggedDownBy = embeddedDraggedDownBy, embeddedDraggedDownBy = embeddedDraggedDownBy,
fastSeekForward = fastSeekForward, fastSeek = fastSeek,
fastSeekBackward = fastSeekBackward, fastSeekFinished = finishFastSeek
fastSeekSeconds = fastSeekSeconds
) )
} }
@ -134,12 +134,12 @@ fun VideoPlayerControllerUI(
showUi = showUi, showUi = showUi,
uiVissible = uiVissible, uiVissible = uiVissible,
fullscreen = fullscreen, fullscreen = fullscreen,
fastSeekSeconds = fastSeekSeconds,
switchToFullscreen = switchToFullscreen, switchToFullscreen = switchToFullscreen,
switchToEmbeddedView = switchToEmbeddedView, switchToEmbeddedView = switchToEmbeddedView,
embeddedDraggedDownBy = embeddedDraggedDownBy, embeddedDraggedDownBy = embeddedDraggedDownBy,
fastSeekForward = fastSeekForward, fastSeek = fastSeek,
fastSeekBackward = fastSeekBackward, fastSeekFinished = finishFastSeek
fastSeekSeconds = fastSeekSeconds
) )
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
@ -222,7 +222,7 @@ fun VideoPlayerControllerUIPreviewEmbedded() {
durationInMs = 9 * 60 * 1000, durationInMs = 9 * 60 * 1000,
playbackPositionInMs = 6 * 60 * 1000, playbackPositionInMs = 6 * 60 * 1000,
bufferedPercentage = 0.4f, bufferedPercentage = 0.4f,
fastSeekSeconds = 10, fastSeekSeconds = 0,
play = {}, play = {},
pause = {}, pause = {},
prevStream = {}, prevStream = {},
@ -234,8 +234,8 @@ fun VideoPlayerControllerUIPreviewEmbedded() {
seekPositionChanged = {}, seekPositionChanged = {},
seekingFinished = {}, seekingFinished = {},
embeddedDraggedDownBy = {}, embeddedDraggedDownBy = {},
fastSeekBackward = {}, fastSeek = {},
fastSeekForward = {}) finishFastSeek = {})
} }
} }
} }
@ -253,7 +253,7 @@ fun VideoPlayerControllerUIPreviewLandscape() {
durationInMs = 9 * 60 * 1000, durationInMs = 9 * 60 * 1000,
playbackPositionInMs = 6 * 60 * 1000, playbackPositionInMs = 6 * 60 * 1000,
bufferedPercentage = 0.4f, bufferedPercentage = 0.4f,
fastSeekSeconds = 10, fastSeekSeconds = 0,
play = {}, play = {},
pause = {}, pause = {},
prevStream = {}, prevStream = {},
@ -265,8 +265,8 @@ fun VideoPlayerControllerUIPreviewLandscape() {
seekPositionChanged = {}, seekPositionChanged = {},
seekingFinished = {}, seekingFinished = {},
embeddedDraggedDownBy = {}, embeddedDraggedDownBy = {},
fastSeekBackward = {}, fastSeek = {},
fastSeekForward = {}) finishFastSeek = {})
} }
} }
} }
@ -285,7 +285,7 @@ fun VideoPlayerControllerUIPreviewPortrait() {
durationInMs = 9 * 60 * 1000, durationInMs = 9 * 60 * 1000,
playbackPositionInMs = 6 * 60 * 1000, playbackPositionInMs = 6 * 60 * 1000,
bufferedPercentage = 0.4f, bufferedPercentage = 0.4f,
fastSeekSeconds = 10, fastSeekSeconds = 0,
play = {}, play = {},
pause = {}, pause = {},
prevStream = {}, prevStream = {},
@ -297,8 +297,8 @@ fun VideoPlayerControllerUIPreviewPortrait() {
seekPositionChanged = {}, seekPositionChanged = {},
seekingFinished = {}, seekingFinished = {},
embeddedDraggedDownBy = {}, embeddedDraggedDownBy = {},
fastSeekForward = {}, fastSeek = {},
fastSeekBackward = {}) finishFastSeek = {})
} }
} }
} }

View File

@ -164,8 +164,8 @@ fun VideoPlayerUI(
seekPositionChanged = viewModel::seekPositionChanged, seekPositionChanged = viewModel::seekPositionChanged,
seekingFinished = viewModel::seekingFinished, seekingFinished = viewModel::seekingFinished,
embeddedDraggedDownBy = viewModel::embeddedDraggedDown, embeddedDraggedDownBy = viewModel::embeddedDraggedDown,
fastSeekForward = viewModel::fastSeekForward, fastSeek = viewModel::fastSeek,
fastSeekBackward = viewModel::fastSeekBackward finishFastSeek = viewModel::fastSeekFinished
) )
} }
} }

View File

@ -95,8 +95,8 @@ fun VideoPlayerControllerUIPreviewEmbeddedColorPreview() {
seekPositionChanged = {}, seekPositionChanged = {},
seekingFinished = {}, seekingFinished = {},
embeddedDraggedDownBy = {}, embeddedDraggedDownBy = {},
fastSeekForward = {}, fastSeek = {},
fastSeekBackward = {}) finishFastSeek = {})
} }
} }
} }

View File

@ -34,7 +34,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -48,7 +47,6 @@ import net.newpipe.newplayer.ui.videoplayer.gesture_ui.TouchedPosition
private const val TAG = "TouchUi" private const val TAG = "TouchUi"
const val DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS: Long = 200 const val DELAY_UNTIL_SHOWING_UI_AFTER_TOUCH_IN_MS: Long = 200
const val SEEK_ANIMATION_DURATION_IN_MS = 400 const val SEEK_ANIMATION_DURATION_IN_MS = 400
const val FAST_SEEKMODE_DURATION = 500L const val FAST_SEEKMODE_DURATION = 500L
@ -66,8 +64,8 @@ fun GestureUI(
switchToFullscreen: () -> Unit, switchToFullscreen: () -> Unit,
switchToEmbeddedView: () -> Unit, switchToEmbeddedView: () -> Unit,
embeddedDraggedDownBy: (Float) -> Unit, embeddedDraggedDownBy: (Float) -> Unit,
fastSeekBackward: () -> Unit, fastSeek: (Int) -> Unit,
fastSeekForward: () -> Unit, fastSeekFinished: () -> Unit
) { ) {
val defaultOnRegularTap = { val defaultOnRegularTap = {
if (uiVissible) { if (uiVissible) {
@ -77,50 +75,6 @@ fun GestureUI(
} }
} }
var fastSeekBackwardBy:Int by remember {
mutableStateOf(0)
}
var fastSeekForwardBy:Int by remember {
mutableStateOf(0)
}
val composeScope = rememberCoroutineScope()
/*
val doForwardSeek = {
fastSeekModeForward = true
composeScope.launch {
delay(FAST_SEEKMODE_DURATION)
fastSeekModeForward = false
}
fastSeekForward()
}
var fastSeekModeTimeout: Job? = null
val resetFastSeekModeEnd = {
fastSeekModeTimeout?.cancel()
fastSeekModeTimeout = composeScope.launch {
delay(FAST_SEEKMODE_DURATION)
fastSeekModeBackward = false
}
}
val doBackwardSeek = {
fastSeekModeBackward = true
resetFastSeekModeEnd()
fastSeekBackward()
}
*/
val onMultitapBackward = { amount: Int ->
fastSeekBackwardBy = amount * fastSeekSeconds
}
val onMultitapForward = { amount: Int ->
fastSeekForwardBy = amount * fastSeekSeconds
}
if (fullscreen) { if (fullscreen) {
Row(modifier = modifier) { Row(modifier = modifier) {
TouchSurface( TouchSurface(
@ -128,12 +82,16 @@ fun GestureUI(
.weight(1f), .weight(1f),
multitapDurationInMs = FAST_SEEKMODE_DURATION, multitapDurationInMs = FAST_SEEKMODE_DURATION,
onRegularTap = defaultOnRegularTap, onRegularTap = defaultOnRegularTap,
onMultiTap = onMultitapBackward onMultiTap = {
println("multitap ${-it}")
fastSeek(-it)
},
onMultiTapFinished = fastSeekFinished
) { ) {
FadedAnimationForSeekFeedback(visible = fastSeekForwardBy != 0) { FadedAnimationForSeekFeedback(fastSeekSeconds, backwards = true) {
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
FastSeekVisualFeedback( FastSeekVisualFeedback(
seconds = fastSeekSeconds, seconds = -fastSeekSeconds,
backwards = true, backwards = true,
modifier = Modifier.align(Alignment.CenterEnd) modifier = Modifier.align(Alignment.CenterEnd)
) )
@ -156,9 +114,10 @@ fun GestureUI(
.weight(1f), .weight(1f),
onRegularTap = defaultOnRegularTap, onRegularTap = defaultOnRegularTap,
multitapDurationInMs = FAST_SEEKMODE_DURATION, multitapDurationInMs = FAST_SEEKMODE_DURATION,
onMultiTap = onMultitapForward onMultiTap = fastSeek,
onMultiTapFinished = fastSeekFinished
) { ) {
FadedAnimationForSeekFeedback(visible = fastSeekBackwardBy != 0) { FadedAnimationForSeekFeedback(fastSeekSeconds) {
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
FastSeekVisualFeedback( FastSeekVisualFeedback(
modifier = Modifier.align(Alignment.CenterStart), modifier = Modifier.align(Alignment.CenterStart),
@ -185,14 +144,17 @@ fun GestureUI(
.weight(1f), .weight(1f),
multitapDurationInMs = FAST_SEEKMODE_DURATION, multitapDurationInMs = FAST_SEEKMODE_DURATION,
onRegularTap = defaultOnRegularTap, onRegularTap = defaultOnRegularTap,
onMultiTap = onMultitapBackward, onMultiTap = {
fastSeek(-it)
},
onMultiTapFinished = fastSeekFinished,
onMovement = handleDownwardMovement onMovement = handleDownwardMovement
) { ) {
FadedAnimationForSeekFeedback(visible = fastSeekBackwardBy != 0) { FadedAnimationForSeekFeedback(fastSeekSeconds, backwards = true) {
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
FastSeekVisualFeedback( FastSeekVisualFeedback(
modifier = Modifier.align(Alignment.Center), modifier = Modifier.align(Alignment.Center),
seconds = fastSeekSeconds, seconds = -fastSeekSeconds,
backwards = true backwards = true
) )
} }
@ -204,9 +166,10 @@ fun GestureUI(
multitapDurationInMs = FAST_SEEKMODE_DURATION, multitapDurationInMs = FAST_SEEKMODE_DURATION,
onRegularTap = defaultOnRegularTap, onRegularTap = defaultOnRegularTap,
onMovement = handleDownwardMovement, onMovement = handleDownwardMovement,
onMultiTap = onMultitapForward onMultiTap = fastSeek,
onMultiTapFinished = fastSeekFinished
) { ) {
FadedAnimationForSeekFeedback(visible = fastSeekForwardBy != 0) { FadedAnimationForSeekFeedback(fastSeekSeconds) {
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
FastSeekVisualFeedback( FastSeekVisualFeedback(
modifier = Modifier.align(Alignment.Center), modifier = Modifier.align(Alignment.Center),
@ -223,56 +186,105 @@ fun GestureUI(
@Composable @Composable
fun FadedAnimationForSeekFeedback(visible: Boolean, content: @Composable () -> Unit) { fun FadedAnimationForSeekFeedback(
fastSeekSeconds: Int,
backwards: Boolean = false,
content: @Composable () -> Unit
) {
val vissible = if (backwards) {
fastSeekSeconds < 0
} else {
0 < fastSeekSeconds
}
val disapearEmediatly = if (backwards) {
0 < fastSeekSeconds
} else {
fastSeekSeconds < 0
}
if (!disapearEmediatly) {
AnimatedVisibility( AnimatedVisibility(
visible = visible, visible = vissible,
enter = fadeIn(animationSpec = tween(SEEK_ANIMATION_FADE_IN)), enter = fadeIn(animationSpec = tween(SEEK_ANIMATION_FADE_IN)),
exit = fadeOut(animationSpec = tween(SEEK_ANIMATION_FADE_OUT)) exit = fadeOut(
animationSpec = tween(SEEK_ANIMATION_FADE_OUT)
)
) { ) {
content() content()
} }
} }
}
@Preview(device = "spec:width=1080px,height=600px,dpi=440,orientation=landscape") @Preview(device = "spec:width=1080px,height=600px,dpi=440,orientation=landscape")
@Composable @Composable
fun FullscreenGestureUIPreview() { fun FullscreenGestureUIPreview() {
VideoPlayerTheme { VideoPlayerTheme {
Surface(modifier = Modifier.wrapContentSize(), color = Color.Black) { Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) {
GestureUI( GestureUI(
modifier = Modifier, modifier = Modifier,
hideUi = { }, hideUi = { },
showUi = { }, showUi = { },
uiVissible = false, uiVissible = false,
fullscreen = true, fullscreen = true,
fastSeekSeconds = 10, fastSeekSeconds = 0,
switchToFullscreen = { println("switch to fullscreen") }, switchToFullscreen = { println("switch to fullscreen") },
switchToEmbeddedView = { println("switch to embedded") }, switchToEmbeddedView = { println("switch to embedded") },
embeddedDraggedDownBy = { println("embedded dragged down") }, embeddedDraggedDownBy = { println("embedded dragged down") },
fastSeekBackward = { println("fast seek backward") }, fastSeek = { println("fast seek by $it steps") },
fastSeekForward = { println("fast seek forward") }) fastSeekFinished = {})
} }
} }
} }
@Preview(device = "spec:width=1080px,height=600px,dpi=440,orientation=landscape")
@Composable
fun FullscreenGestureUIPreviewInteractive() {
var seekSeconds by remember {
mutableStateOf(0)
}
VideoPlayerTheme {
Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) {
GestureUI(
modifier = Modifier,
hideUi = { },
showUi = { },
uiVissible = false,
fullscreen = true,
fastSeekSeconds = seekSeconds,
switchToFullscreen = { println("switch to fullscreen") },
switchToEmbeddedView = { println("switch to embedded") },
embeddedDraggedDownBy = { println("embedded dragged down") },
fastSeek = { seekSeconds = it * 10 },
fastSeekFinished = {
seekSeconds = 0
})
}
}
}
@Preview(device = "spec:width=600px,height=400px,dpi=440,orientation=landscape") @Preview(device = "spec:width=600px,height=400px,dpi=440,orientation=landscape")
@Composable @Composable
fun EmbeddedGestureUIPreview() { fun EmbeddedGestureUIPreview() {
VideoPlayerTheme { VideoPlayerTheme {
Surface(modifier = Modifier.wrapContentSize(), color = Color.Black) { Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) {
GestureUI( GestureUI(
modifier = Modifier, modifier = Modifier,
hideUi = { }, hideUi = { },
showUi = { }, showUi = { },
uiVissible = false, uiVissible = false,
fullscreen = false, fullscreen = false,
fastSeekSeconds = 10, fastSeekSeconds = 0,
switchToFullscreen = { println("switch to fullscreen") }, switchToFullscreen = { println("switch to fullscreen") },
switchToEmbeddedView = { println("switch to embedded") }, switchToEmbeddedView = { println("switch to embedded") },
embeddedDraggedDownBy = { println("embedded dragged down") }, embeddedDraggedDownBy = { println("embedded dragged down") },
fastSeekBackward = { println("fast seek backward") }, fastSeek = { println("Fast seek by $it steps") },
fastSeekForward = { println("fast seek forward") }) fastSeekFinished = {})
} }
} }
} }

View File

@ -26,9 +26,12 @@ import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -36,10 +39,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.android.material.color.MaterialColors
import net.newpipe.newplayer.R import net.newpipe.newplayer.R
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
import net.newpipe.newplayer.ui.videoplayer.SEEK_ANIMATION_DURATION_IN_MS import net.newpipe.newplayer.ui.videoplayer.SEEK_ANIMATION_DURATION_IN_MS
@ -106,7 +112,12 @@ fun FastSeekVisualFeedback(modifier: Modifier = Modifier, seconds: Int, backward
//val secondsString = stringResource(id = R.string.seconds) //val secondsString = stringResource(id = R.string.seconds)
val secondsString = "Seconds" val secondsString = "Seconds"
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) { Surface(
color = Color.Black.copy(alpha = 0.5f),
modifier = modifier.clip(RoundedCornerShape(50.dp))
) {
Box(modifier = Modifier.padding(10.dp, 5.dp)) {
Column(modifier = Modifier, horizontalAlignment = Alignment.CenterHorizontally) {
Row { Row {
SeekerIcon( SeekerIcon(
backwards = backwards, backwards = backwards,
@ -126,7 +137,8 @@ fun FastSeekVisualFeedback(modifier: Modifier = Modifier, seconds: Int, backward
} }
Text(text = "$seconds $secondsString") Text(text = "$seconds $secondsString")
} }
}
}
} }
@ -148,7 +160,7 @@ private fun SeekerIcon(backwards: Boolean, description: String, color: Color) {
@Composable @Composable
fun FastSeekVisualFeedbackPreviewBackwards() { fun FastSeekVisualFeedbackPreviewBackwards() {
VideoPlayerTheme { VideoPlayerTheme {
Surface(modifier = Modifier.wrapContentSize(), color = Color.Black) { Surface(modifier = Modifier.wrapContentSize(), color = Color.Gray) {
FastSeekVisualFeedback(seconds = 10, backwards = true) FastSeekVisualFeedback(seconds = 10, backwards = true)
} }
} }
@ -158,7 +170,7 @@ fun FastSeekVisualFeedbackPreviewBackwards() {
@Composable @Composable
fun FastSeekVisualFeedbackPreview() { fun FastSeekVisualFeedbackPreview() {
VideoPlayerTheme { VideoPlayerTheme {
Surface(modifier = Modifier.wrapContentSize(), color = Color.Black) { Surface(modifier = Modifier.wrapContentSize(), color = Color.Gray) {
FastSeekVisualFeedback(seconds = 10, backwards = false) FastSeekVisualFeedback(seconds = 10, backwards = false)
} }
} }

View File

@ -92,6 +92,7 @@ fun TouchSurface(
onMultiTap(multitapAmount) onMultiTap(multitapAmount)
cancelMultitapJob = composableScope.launch { cancelMultitapJob = composableScope.launch {
delay(multitapDurationInMs) delay(multitapDurationInMs)
multitapAmount = 0
onMultiTapFinished() onMultiTapFinished()
} }
} else { } else {