From 8ac9a5a6ff8960da77c88653d61a7c91c7f65d73 Mon Sep 17 00:00:00 2001 From: Christian Schabesberger Date: Mon, 19 Aug 2024 19:16:17 +0200 Subject: [PATCH] add ui mode states --- misc/tiny_placeholder.svg | 53 ++++++++++ .../newpipe/newplayer/ActivityBrainSlug.kt | 8 +- .../newpipe/newplayer/model/UIModeState.kt | 96 +++++++++++++++++++ .../newplayer/model/VideoPlayerUIState.kt | 6 +- .../model/VideoPlayerViewModelImpl.kt | 13 +-- .../newplayer/ui/VideoPlayerControllerUI.kt | 25 ++--- .../net/newpipe/newplayer/ui/VideoPlayerUI.kt | 19 ++-- .../net/newpipe/newplayer/ui/theme/Color.kt | 4 +- .../newplayer/ui/videoplayer/BottomUI.kt | 7 +- .../newplayer/ui/videoplayer/GestureUI.kt | 2 +- .../ui/videoplayer/StreamSelectUI.kt | 49 ++++++++++ .../gesture_ui/EmbeddedGestureUI.kt | 2 +- .../gesture_ui/FullscreenGestureUI.kt | 52 ++++------ 13 files changed, 256 insertions(+), 80 deletions(-) create mode 100644 misc/tiny_placeholder.svg create mode 100644 new-player/src/main/java/net/newpipe/newplayer/model/UIModeState.kt create mode 100644 new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/StreamSelectUI.kt diff --git a/misc/tiny_placeholder.svg b/misc/tiny_placeholder.svg new file mode 100644 index 0000000..b567e42 --- /dev/null +++ b/misc/tiny_placeholder.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + diff --git a/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt b/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt index 80d6a4b..5ee92fe 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt @@ -31,7 +31,7 @@ class ActivityBrainSlug(val viewModel: VideoPlayerViewModel) { set(value) { field = value field?.let { - if (viewModel.uiState.value.fullscreen) { + if (viewModel.uiState.value.uiMode.fullscreen) { removeSystemInsets() } else { addSystemInsets() @@ -43,7 +43,7 @@ class ActivityBrainSlug(val viewModel: VideoPlayerViewModel) { var fullscreenPlayerView: VideoPlayerView? = null set(value) { field = value - if (viewModel.uiState.value.fullscreen) { + if (viewModel.uiState.value.uiMode.fullscreen) { value?.visibility = View.VISIBLE field?.viewModel = viewModel } else { @@ -55,7 +55,7 @@ class ActivityBrainSlug(val viewModel: VideoPlayerViewModel) { var embeddedPlayerView: VideoPlayerView? = null set(value) { field = value - if (viewModel.uiState.value.fullscreen) { + if (viewModel.uiState.value.uiMode.fullscreen) { field?.viewModel = null value?.visibility = View.GONE } else { @@ -83,7 +83,7 @@ class ActivityBrainSlug(val viewModel: VideoPlayerViewModel) { fun addViewToHideOnFullscreen(view: View) { viewsToHideOnFullscreen.add(view) - if (viewModel.uiState.value.fullscreen) { + if (viewModel.uiState.value.uiMode.fullscreen) { view.visibility = View.GONE } } diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/UIModeState.kt b/new-player/src/main/java/net/newpipe/newplayer/model/UIModeState.kt new file mode 100644 index 0000000..3b21797 --- /dev/null +++ b/new-player/src/main/java/net/newpipe/newplayer/model/UIModeState.kt @@ -0,0 +1,96 @@ +package net.newpipe.newplayer.model + +enum class UIModeState { + PLACEHOLDER, + + EMBEDDED_VIDEO, + EMBEDDED_VIDEO_CONTROLLER_UI, + EMBEDDED_VIDEO_CHAPTER_SELECT, + EMBEDDED_VIDEO_STREAM_SELECT, + + FULLSCREEN_VIDEO, + FULLSCREEN_VIDEO_CONTROLLER_UI, + FULLSCREEN_VIDEO_CHAPTER_SELECT, + FULLSCREEN_VIDEO_STREAM_SELECT; + + val fullscreen: Boolean + get() = + when (this) { + EMBEDDED_VIDEO_CHAPTER_SELECT -> true + EMBEDDED_VIDEO_STREAM_SELECT -> true + FULLSCREEN_VIDEO -> true + FULLSCREEN_VIDEO_CONTROLLER_UI -> true + FULLSCREEN_VIDEO_CHAPTER_SELECT -> true + FULLSCREEN_VIDEO_STREAM_SELECT -> true + else -> false + } + + val controllerUiVisible: Boolean + get() = + when (this) { + EMBEDDED_VIDEO_CONTROLLER_UI -> true + FULLSCREEN_VIDEO_CONTROLLER_UI -> true + else -> false + } + + val systemUiVisible: Boolean + get() = + when (this) { + FULLSCREEN_VIDEO -> false + else -> true + } + + // STATE TRANSITIONS + + fun getControllerUiVisibleState() = + when (this) { + EMBEDDED_VIDEO -> EMBEDDED_VIDEO_CONTROLLER_UI + FULLSCREEN_VIDEO -> FULLSCREEN_VIDEO_CONTROLLER_UI + + else -> this + } + + + fun getUiHiddenState() = + when (this) { + FULLSCREEN_VIDEO -> FULLSCREEN_VIDEO + FULLSCREEN_VIDEO_CONTROLLER_UI -> FULLSCREEN_VIDEO + FULLSCREEN_VIDEO_CHAPTER_SELECT -> FULLSCREEN_VIDEO + FULLSCREEN_VIDEO_STREAM_SELECT -> FULLSCREEN_VIDEO + + + EMBEDDED_VIDEO -> EMBEDDED_VIDEO + EMBEDDED_VIDEO_CONTROLLER_UI -> EMBEDDED_VIDEO + EMBEDDED_VIDEO_CHAPTER_SELECT -> EMBEDDED_VIDEO + EMBEDDED_VIDEO_STREAM_SELECT -> EMBEDDED_VIDEO + + else -> this + } + + + fun getStreamSelectUiState() = + when (this) { + FULLSCREEN_VIDEO -> FULLSCREEN_VIDEO_STREAM_SELECT + FULLSCREEN_VIDEO_CHAPTER_SELECT -> FULLSCREEN_VIDEO_STREAM_SELECT + FULLSCREEN_VIDEO_CONTROLLER_UI -> FULLSCREEN_VIDEO_STREAM_SELECT + + EMBEDDED_VIDEO -> EMBEDDED_VIDEO_STREAM_SELECT + EMBEDDED_VIDEO_CHAPTER_SELECT -> EMBEDDED_VIDEO_STREAM_SELECT + EMBEDDED_VIDEO_CONTROLLER_UI -> EMBEDDED_VIDEO_STREAM_SELECT + + else -> this + } + + fun getChapterSelectUiState() = + when (this) { + FULLSCREEN_VIDEO -> FULLSCREEN_VIDEO_CHAPTER_SELECT + FULLSCREEN_VIDEO_STREAM_SELECT -> FULLSCREEN_VIDEO_CHAPTER_SELECT + FULLSCREEN_VIDEO_CONTROLLER_UI -> FULLSCREEN_VIDEO_CHAPTER_SELECT + + EMBEDDED_VIDEO -> EMBEDDED_VIDEO_CHAPTER_SELECT + EMBEDDED_VIDEO_STREAM_SELECT -> EMBEDDED_VIDEO_CHAPTER_SELECT + EMBEDDED_VIDEO_CONTROLLER_UI -> EMBEDDED_VIDEO_CHAPTER_SELECT + + else -> this + } +} \ No newline at end of file diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt index fdf22b2..4e75109 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt @@ -26,9 +26,8 @@ import net.newpipe.newplayer.ui.ContentScale @Parcelize data class VideoPlayerUIState( + val uiMode: UIModeState, val playing: Boolean, - var fullscreen: Boolean, - val uiVisible: Boolean, val contentRatio: Float, val embeddedUiRatio: Float, val contentFitMode: ContentScale, @@ -45,9 +44,8 @@ data class VideoPlayerUIState( ) : Parcelable { companion object { val DEFAULT = VideoPlayerUIState( + uiMode = UIModeState.PLACEHOLDER, playing = false, - fullscreen = false, - uiVisible = false, contentRatio = 16 / 9f, embeddedUiRatio = 16f / 9f, contentFitMode = ContentScale.FIT_INSIDE, diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt index e2b98b6..c26bac9 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt @@ -133,6 +133,7 @@ class VideoPlayerViewModelImpl @Inject constructor( override fun onVideoSizeChanged(videoSize: androidx.media3.common.VideoSize) { super.onVideoSizeChanged(videoSize) + updateContentRatio(VideoSize.fromMedia3VideoSize(videoSize)) } @@ -210,7 +211,7 @@ class VideoPlayerViewModelImpl @Inject constructor( override fun showUi() { mutableUiState.update { - it.copy(uiVisible = true) + it.copy(uiMode = it.uiMode.getControllerUiVisibleState()) } resetHideUiDelayedJob() resetProgressUpdatePeriodicallyJob() @@ -255,7 +256,7 @@ class VideoPlayerViewModelImpl @Inject constructor( progressUpdaterJob?.cancel() uiVisibilityJob?.cancel() mutableUiState.update { - it.copy(uiVisible = false) + it.copy(uiMode = it.uiMode.getUiHiddenState()) } } @@ -283,7 +284,7 @@ class VideoPlayerViewModelImpl @Inject constructor( ) } - if (mutableUiState.value.uiVisible) { + if (mutableUiState.value.uiMode.controllerUiVisible) { resetHideUiDelayedJob() } } @@ -301,7 +302,7 @@ class VideoPlayerViewModelImpl @Inject constructor( } override fun brightnessChange(changeRate: Float, systemBrightness: Float) { - if (mutableUiState.value.fullscreen) { + if (mutableUiState.value.uiMode.fullscreen) { val currentBrightness = mutableUiState.value.brightness ?: if (systemBrightness < 0f) 0.5f else systemBrightness Log.d( @@ -336,7 +337,7 @@ class VideoPlayerViewModelImpl @Inject constructor( uiVisibilityJob?.cancel() finishFastSeek() mutableUiState.update { - it.copy(fullscreen = false, uiVisible = false) + it.copy(uiMode = UIModeState.EMBEDDED_VIDEO) } } @@ -345,7 +346,7 @@ class VideoPlayerViewModelImpl @Inject constructor( uiVisibilityJob?.cancel() finishFastSeek() mutableUiState.update { - it.copy(fullscreen = true, uiVisible = false) + it.copy(uiMode = UIModeState.FULLSCREEN_VIDEO) } } diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt index 43808b7..05817c3 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt @@ -20,7 +20,6 @@ package net.newpipe.newplayer.ui - import android.app.Activity import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedVisibility @@ -57,15 +56,16 @@ import net.newpipe.newplayer.ui.videoplayer.TopUI import net.newpipe.newplayer.ui.videoplayer.GestureUI import net.newpipe.newplayer.utils.getDefaultBrightness +val CONTROLLER_UI_BACKGROUND_COLOR = Color(0x75000000) + @Composable fun VideoPlayerControllerUI( - viewModel: VideoPlayerViewModel, - uiState: VideoPlayerUIState + viewModel: VideoPlayerViewModel, uiState: VideoPlayerUIState ) { val context = LocalContext.current - if (uiState.fullscreen) { + if (uiState.uiMode.fullscreen) { BackHandler { viewModel.switchToEmbeddedView() } @@ -77,21 +77,16 @@ fun VideoPlayerControllerUI( } val insets = - WindowInsets.systemBars - .union(WindowInsets.displayCutout) - .union(WindowInsets.waterfall) + WindowInsets.systemBars.union(WindowInsets.displayCutout).union(WindowInsets.waterfall) - AnimatedVisibility(uiState.uiVisible) { + AnimatedVisibility(uiState.uiMode.controllerUiVisible) { Surface( - modifier = Modifier.fillMaxSize(), color = Color(0x75000000) + modifier = Modifier.fillMaxSize(), color = CONTROLLER_UI_BACKGROUND_COLOR ) {} } GestureUI( - modifier = Modifier - .fillMaxSize(), - viewModel = viewModel, - uiState = uiState + modifier = Modifier.fillMaxSize(), viewModel = viewModel, uiState = uiState ) if (uiState.isLoading) { @@ -106,7 +101,7 @@ fun VideoPlayerControllerUI( } } - AnimatedVisibility(uiState.uiVisible) { + AnimatedVisibility(uiState.uiMode.controllerUiVisible) { Box(modifier = Modifier.fillMaxSize()) { CenterUI( @@ -117,7 +112,7 @@ fun VideoPlayerControllerUI( } Box( - modifier = if (uiState.fullscreen) Modifier.windowInsetsPadding(insets) else Modifier + modifier = if (uiState.uiMode.fullscreen) Modifier.windowInsetsPadding(insets) else Modifier ) { TopUI( modifier = Modifier diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt index a963edf..76fb6a3 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt @@ -87,21 +87,21 @@ fun VideoPlayerUI( val lifecycleOwner = LocalLifecycleOwner.current // Setup fullscreen - if (uiState.fullscreen) { + if (uiState.uiMode.fullscreen) { LaunchedEffect(key1 = true) { WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = false } } // Setup immersive mode - if (uiState.fullscreen && !uiState.uiVisible) { - LaunchedEffect(key1 = true) { - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) - } - } else { + if (uiState.uiMode.systemUiVisible) { LaunchedEffect(key1 = false) { windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) } + } else { + LaunchedEffect(key1 = true) { + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + } } // Prepare stuff for the SurfaceView to which the video will be rendered @@ -117,7 +117,7 @@ fun VideoPlayerUI( } // Set Screen Rotation - if (uiState.fullscreen) { + if (uiState.uiMode.fullscreen) { if (uiState.contentRatio < 1) { LockScreenOrientation(orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) } else { @@ -141,7 +141,7 @@ fun VideoPlayerUI( // Set UI Surface( modifier = Modifier.then( - if (uiState.fullscreen) Modifier.fillMaxSize() + if (uiState.uiMode.fullscreen) Modifier.fillMaxSize() else Modifier .fillMaxWidth() .aspectRatio(uiState.embeddedUiRatio) @@ -152,7 +152,8 @@ fun VideoPlayerUI( player = viewModel.internalPlayer, lifecycle = lifecycle, fitMode = uiState.contentFitMode, - uiRatio = if (uiState.fullscreen) screenRatio else uiState.embeddedUiRatio, + uiRatio = if (uiState.uiMode.fullscreen) screenRatio + else uiState.embeddedUiRatio, contentRatio = uiState.contentRatio ) } diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt index d97649d..ed17b67 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt @@ -23,6 +23,7 @@ package net.newpipe.newplayer.ui.theme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview +import net.newpipe.newplayer.model.UIModeState import net.newpipe.newplayer.model.VideoPlayerUIState import net.newpipe.newplayer.model.VideoPlayerViewModelDummy import net.newpipe.newplayer.ui.PreviewBackgroundSurface @@ -77,9 +78,8 @@ fun VideoPlayerControllerUIPreviewEmbeddedColorPreview() { VideoPlayerControllerUI( viewModel = VideoPlayerViewModelDummy(), uiState = VideoPlayerUIState.DEFAULT.copy( + uiMode = UIModeState.EMBEDDED_VIDEO_CONTROLLER_UI, playing = true, - fullscreen = false, - uiVisible = true, seekerPosition = 0.3f, isLoading = false, durationInMs = 9 * 60 * 1000, diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt index 45fb5f5..c67e04a 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.core.os.ConfigurationCompat import net.newpipe.newplayer.R +import net.newpipe.newplayer.model.UIModeState import net.newpipe.newplayer.model.VideoPlayerUIState import net.newpipe.newplayer.model.VideoPlayerViewModel import net.newpipe.newplayer.model.VideoPlayerViewModelDummy @@ -77,11 +78,11 @@ fun BottomUI( Text(getTimeStringFromMs(uiState.durationInMs, getLocale() ?: Locale.US)) IconButton( - onClick = if (uiState.fullscreen) viewModel::switchToEmbeddedView + onClick = if (uiState.uiMode.fullscreen) viewModel::switchToEmbeddedView else viewModel::switchToFullscreen ) { Icon( - imageVector = if (uiState.fullscreen) Icons.Filled.FullscreenExit + imageVector = if (uiState.uiMode.fullscreen) Icons.Filled.FullscreenExit else Icons.Filled.Fullscreen, contentDescription = stringResource(R.string.widget_description_toggle_fullscreen) ) @@ -152,7 +153,7 @@ fun VideoPlayerControllerBottomUIPreview() { modifier = Modifier, viewModel = VideoPlayerViewModelDummy(), uiState = VideoPlayerUIState.DEFAULT.copy( - fullscreen = true, + uiMode = UIModeState.FULLSCREEN_VIDEO_CONTROLLER_UI, seekerPosition = 0.4f, durationInMs = 90 * 60 * 1000, playbackPositionInMs = 3 * 60 * 1000, diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/GestureUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/GestureUI.kt index 4afd155..725a625 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/GestureUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/GestureUI.kt @@ -36,7 +36,7 @@ val INDICATOR_BACKGROUND_COLOR = Color.Black.copy(alpha = 0.3f) fun GestureUI( modifier: Modifier, viewModel: VideoPlayerViewModel, uiState: VideoPlayerUIState ) { - if (uiState.fullscreen) { + if (uiState.uiMode.fullscreen) { FullscreenGestureUI( modifier = modifier, viewModel = viewModel, uiState = uiState ) diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/StreamSelectUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/StreamSelectUI.kt new file mode 100644 index 0000000..ede50da --- /dev/null +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/StreamSelectUI.kt @@ -0,0 +1,49 @@ +package net.newpipe.newplayer.ui.videoplayer + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import net.newpipe.newplayer.model.VideoPlayerUIState +import net.newpipe.newplayer.model.VideoPlayerViewModel +import net.newpipe.newplayer.model.VideoPlayerViewModelDummy +import net.newpipe.newplayer.ui.CONTROLLER_UI_BACKGROUND_COLOR +import net.newpipe.newplayer.ui.theme.VideoPlayerTheme + +@Composable +fun StreamSelectUI( + isChapterSelect: Boolean = false, + viewModel: VideoPlayerViewModel, + uiState: VideoPlayerUIState +) { + Surface(modifier = Modifier.fillMaxSize(), color = CONTROLLER_UI_BACKGROUND_COLOR) { + Scaffold( + topBar = { + + } + ) { + + } + } +} + + +private fun ChapterSelectTopBar() { + +} + +@Preview(device = "id:pixel_5") +@Composable +fun VideoPlayerStreamSelectUIPreview() { + VideoPlayerTheme { + Surface(modifier = Modifier.fillMaxSize(), color = Color.Green) { + StreamSelectUI( + viewModel = VideoPlayerViewModelDummy(), + uiState = VideoPlayerUIState.DEFAULT + ) + } + } +} \ No newline at end of file diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/EmbeddedGestureUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/EmbeddedGestureUI.kt index ac10731..5063a96 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/EmbeddedGestureUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/EmbeddedGestureUI.kt @@ -54,7 +54,7 @@ fun EmbeddedGestureUI( } val defaultOnRegularTap = { - if (uiState.uiVisible) { + if (uiState.uiMode.controllerUiVisible) { viewModel.hideUi() } else { viewModel.showUi() diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/FullscreenGestureUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/FullscreenGestureUI.kt index 262a235..8283d4a 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/FullscreenGestureUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/gesture_ui/FullscreenGestureUI.kt @@ -44,6 +44,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview +import net.newpipe.newplayer.model.UIModeState import net.newpipe.newplayer.model.VideoPlayerUIState import net.newpipe.newplayer.model.VideoPlayerViewModel import net.newpipe.newplayer.model.VideoPlayerViewModelDummy @@ -51,16 +52,12 @@ import net.newpipe.newplayer.ui.theme.VideoPlayerTheme import net.newpipe.newplayer.utils.getDefaultBrightness private enum class IndicatorMode { - NONE, - VOLUME_INDICATOR_VISSIBLE, - BRIGHTNESS_INDICATOR_VISSIBLE + NONE, VOLUME_INDICATOR_VISSIBLE, BRIGHTNESS_INDICATOR_VISSIBLE } @Composable fun FullscreenGestureUI( - modifier: Modifier = Modifier, - viewModel: VideoPlayerViewModel, - uiState: VideoPlayerUIState + modifier: Modifier = Modifier, viewModel: VideoPlayerViewModel, uiState: VideoPlayerUIState ) { var heightPx by remember { @@ -72,7 +69,7 @@ fun FullscreenGestureUI( } val defaultOnRegularTap = { - if (uiState.uiVisible) { + if (uiState.uiMode.controllerUiVisible) { viewModel.hideUi() } else { viewModel.showUi() @@ -87,9 +84,7 @@ fun FullscreenGestureUI( heightPx = coordinates.size.height.toFloat() }) { Row { - GestureSurface( - modifier = Modifier - .weight(1f), + GestureSurface(modifier = Modifier.weight(1f), onRegularTap = defaultOnRegularTap, onMultiTap = { println("multitap ${-it}") @@ -100,20 +95,16 @@ fun FullscreenGestureUI( indicatorMode = IndicatorMode.NONE }, onMovement = { change -> - if (indicatorMode == IndicatorMode.NONE - || indicatorMode == IndicatorMode.BRIGHTNESS_INDICATOR_VISSIBLE - ) { + if (indicatorMode == IndicatorMode.NONE || indicatorMode == IndicatorMode.BRIGHTNESS_INDICATOR_VISSIBLE) { indicatorMode = IndicatorMode.BRIGHTNESS_INDICATOR_VISSIBLE if (heightPx != 0f) { viewModel.brightnessChange(-change.y / heightPx, defaultBrightness) } } - } - ) { + }) { FadedAnimationForSeekFeedback( - uiState.fastSeekSeconds, - backwards = true + uiState.fastSeekSeconds, backwards = true ) { fastSeekSecondsToDisplay -> Box(modifier = Modifier.fillMaxSize()) { FastSeekVisualFeedback( @@ -124,19 +115,14 @@ fun FullscreenGestureUI( } } } - GestureSurface( - modifier = Modifier - .weight(1f), + GestureSurface(modifier = Modifier.weight(1f), onRegularTap = defaultOnRegularTap, onMovement = { movement -> if (0 < movement.y) { viewModel.switchToEmbeddedView() } - } - ) - GestureSurface( - modifier = Modifier - .weight(1f), + }) + GestureSurface(modifier = Modifier.weight(1f), onRegularTap = defaultOnRegularTap, onMultiTap = viewModel::fastSeek, onMultiTapFinished = viewModel::finishFastSeek, @@ -144,16 +130,13 @@ fun FullscreenGestureUI( indicatorMode = IndicatorMode.NONE }, onMovement = { change -> - if (indicatorMode == IndicatorMode.NONE - || indicatorMode == IndicatorMode.VOLUME_INDICATOR_VISSIBLE - ) { + if (indicatorMode == IndicatorMode.NONE || indicatorMode == IndicatorMode.VOLUME_INDICATOR_VISSIBLE) { indicatorMode = IndicatorMode.VOLUME_INDICATOR_VISSIBLE if (heightPx != 0f) { viewModel.volumeChange(-change.y / heightPx) } } - } - ) { + }) { FadedAnimationForSeekFeedback(uiState.fastSeekSeconds) { fastSeekSecondsToDisplay -> Box(modifier = Modifier.fillMaxSize()) { FastSeekVisualFeedback( @@ -228,13 +211,11 @@ fun FullscreenGestureUIPreview() { VideoPlayerTheme { Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) { FullscreenGestureUI( - modifier = Modifier, - object : VideoPlayerViewModelDummy() { + modifier = Modifier, object : VideoPlayerViewModelDummy() { override fun fastSeek(steps: Int) { println("fast seek by $steps steps") } - }, - VideoPlayerUIState.DEFAULT + }, VideoPlayerUIState.DEFAULT ) } } @@ -290,7 +271,8 @@ fun FullscreenGestureUIPreviewInteractive() { } }, uiState = VideoPlayerUIState.DEFAULT.copy( - uiVisible = uiVisible, + uiMode = if (uiVisible) UIModeState.FULLSCREEN_VIDEO_CONTROLLER_UI + else UIModeState.FULLSCREEN_VIDEO, fastSeekSeconds = seekSeconds, soundVolume = soundVolume, brightness = brightnessValue