open streem selection ui
This commit is contained in:
parent
8ad95be57a
commit
8684bf95e1
|
@ -54,6 +54,6 @@ interface VideoPlayerViewModel {
|
||||||
fun finishFastSeek()
|
fun finishFastSeek()
|
||||||
fun brightnessChange(changeRate: Float, systemBrightness: Float)
|
fun brightnessChange(changeRate: Float, systemBrightness: Float)
|
||||||
fun volumeChange(changeRate: Float)
|
fun volumeChange(changeRate: Float)
|
||||||
fun openStreamSelection(selectChapter: Boolean)
|
fun openStreamSelection(selectChapter: Boolean, embeddedUiConfig: EmbeddedUiConfig)
|
||||||
fun closeStreamSelection()
|
fun closeStreamSelection()
|
||||||
}
|
}
|
|
@ -65,7 +65,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
private var uiVisibilityJob: Job? = null
|
private var uiVisibilityJob: Job? = null
|
||||||
private var progressUpdaterJob: Job? = null
|
private var progressUpdaterJob: Job? = null
|
||||||
|
|
||||||
// this is necesary to restore the embedded view UI configuration when returning from fullscreen
|
// this is necesary to restore the embedded view UI configuration when returning from fullscreen
|
||||||
private var embeddedUiConfig: EmbeddedUiConfig? = null
|
private var embeddedUiConfig: EmbeddedUiConfig? = null
|
||||||
|
|
||||||
private val audioManager =
|
private val audioManager =
|
||||||
|
@ -166,8 +166,10 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
val currentMode = mutableUiState.value.uiMode.toPlayMode()
|
val currentMode = mutableUiState.value.uiMode.toPlayMode()
|
||||||
if (currentMode != newMode) {
|
if (currentMode != newMode) {
|
||||||
mutableUiState.update {
|
mutableUiState.update {
|
||||||
it.copy(uiMode = UIModeState.fromPlayMode(newMode),
|
it.copy(
|
||||||
embeddedUiConfig = embeddedUiConfig)
|
uiMode = UIModeState.fromPlayMode(newMode),
|
||||||
|
embeddedUiConfig = embeddedUiConfig
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,21 +359,20 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openStreamSelection(selectChapter: Boolean) {
|
override fun openStreamSelection(selectChapter: Boolean, embeddedUiConfig: EmbeddedUiConfig) {
|
||||||
mutableUiState.update {
|
println("gurken openSelection ${embeddedUiConfig}")
|
||||||
it.copy(
|
uiVisibilityJob?.cancel()
|
||||||
uiMode = if (selectChapter) it.uiMode.getChapterSelectUiState()
|
if (!uiState.value.uiMode.fullscreen) {
|
||||||
else it.uiMode.getStreamSelectUiState()
|
this.embeddedUiConfig = embeddedUiConfig
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
updateUiMode(
|
||||||
|
if (selectChapter) uiState.value.uiMode.getChapterSelectUiState()
|
||||||
|
else uiState.value.uiMode.getStreamSelectUiState()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun closeStreamSelection() {
|
override fun closeStreamSelection() {
|
||||||
mutableUiState.update {
|
updateUiMode(uiState.value.uiMode.getUiHiddenState())
|
||||||
it.copy(
|
|
||||||
uiMode = it.uiMode.getUiHiddenState()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun switchToEmbeddedView() {
|
override fun switchToEmbeddedView() {
|
||||||
|
@ -381,6 +382,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun switchToFullscreen(embeddedUiConfig: EmbeddedUiConfig) {
|
override fun switchToFullscreen(embeddedUiConfig: EmbeddedUiConfig) {
|
||||||
|
println("gurken fullscreen: ${embeddedUiConfig}")
|
||||||
uiVisibilityJob?.cancel()
|
uiVisibilityJob?.cancel()
|
||||||
finishFastSeek()
|
finishFastSeek()
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ open class VideoPlayerViewModelDummy : VideoPlayerViewModel {
|
||||||
println("dummy impl")
|
println("dummy impl")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openStreamSelection(selectChapter: Boolean) {
|
override fun openStreamSelection(selectChapter: Boolean, embeddedUiConfig: EmbeddedUiConfig) {
|
||||||
println("dummy impl")
|
println("dummy impl")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ 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.GestureUI
|
import net.newpipe.newplayer.ui.videoplayer.GestureUI
|
||||||
import net.newpipe.newplayer.utils.getDefaultBrightness
|
import net.newpipe.newplayer.utils.getDefaultBrightness
|
||||||
|
import net.newpipe.newplayer.utils.getInsets
|
||||||
|
|
||||||
val CONTROLLER_UI_BACKGROUND_COLOR = Color(0x75000000)
|
val CONTROLLER_UI_BACKGROUND_COLOR = Color(0x75000000)
|
||||||
|
|
||||||
|
@ -76,8 +77,7 @@ fun VideoPlayerControllerUI(
|
||||||
viewModel.brightnessChange(rateChange, systemBrightness)
|
viewModel.brightnessChange(rateChange, systemBrightness)
|
||||||
}
|
}
|
||||||
|
|
||||||
val insets =
|
val insets = getInsets()
|
||||||
WindowInsets.systemBars.union(WindowInsets.displayCutout).union(WindowInsets.waterfall)
|
|
||||||
|
|
||||||
AnimatedVisibility(uiState.uiMode.controllerUiVisible) {
|
AnimatedVisibility(uiState.uiMode.controllerUiVisible) {
|
||||||
Surface(
|
Surface(
|
||||||
|
|
|
@ -98,9 +98,7 @@ fun VideoPlayerUI(
|
||||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars =
|
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars =
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
println("gurken dings")
|
|
||||||
uiState.embeddedUiConfig?.let {
|
uiState.embeddedUiConfig?.let {
|
||||||
println("gurken bumbs")
|
|
||||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars =
|
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars =
|
||||||
it.systemBarInLightMode
|
it.systemBarInLightMode
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
import androidx.compose.foundation.layout.wrapContentSize
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
|
@ -68,6 +69,7 @@ import net.newpipe.newplayer.utils.BitmapThumbnail
|
||||||
import net.newpipe.newplayer.utils.OnlineThumbnail
|
import net.newpipe.newplayer.utils.OnlineThumbnail
|
||||||
import net.newpipe.newplayer.utils.Thumbnail
|
import net.newpipe.newplayer.utils.Thumbnail
|
||||||
import net.newpipe.newplayer.utils.VectorThumbnail
|
import net.newpipe.newplayer.utils.VectorThumbnail
|
||||||
|
import net.newpipe.newplayer.utils.getInsets
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun StreamSelectUI(
|
fun StreamSelectUI(
|
||||||
|
@ -75,7 +77,13 @@ fun StreamSelectUI(
|
||||||
viewModel: VideoPlayerViewModel,
|
viewModel: VideoPlayerViewModel,
|
||||||
uiState: VideoPlayerUIState
|
uiState: VideoPlayerUIState
|
||||||
) {
|
) {
|
||||||
Surface(modifier = Modifier.fillMaxSize(), color = CONTROLLER_UI_BACKGROUND_COLOR) {
|
val insets = getInsets()
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.windowInsetsPadding(insets),
|
||||||
|
color = CONTROLLER_UI_BACKGROUND_COLOR
|
||||||
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
if (isChapterSelect) {
|
if (isChapterSelect) {
|
||||||
|
@ -150,7 +158,7 @@ private fun ChapterItem(
|
||||||
when (thumbnail) {
|
when (thumbnail) {
|
||||||
is OnlineThumbnail -> AsyncImage(
|
is OnlineThumbnail -> AsyncImage(
|
||||||
model = thumbnail.url,
|
model = thumbnail.url,
|
||||||
contentDescription =contentDescription
|
contentDescription = contentDescription
|
||||||
)
|
)
|
||||||
|
|
||||||
is BitmapThumbnail -> Image(
|
is BitmapThumbnail -> Image(
|
||||||
|
@ -206,7 +214,7 @@ private fun StreamItem(
|
||||||
when (thumbnail) {
|
when (thumbnail) {
|
||||||
is OnlineThumbnail -> AsyncImage(
|
is OnlineThumbnail -> AsyncImage(
|
||||||
model = thumbnail.url,
|
model = thumbnail.url,
|
||||||
contentDescription =contentDescription
|
contentDescription = contentDescription
|
||||||
)
|
)
|
||||||
|
|
||||||
is BitmapThumbnail -> Image(
|
is BitmapThumbnail -> Image(
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
package net.newpipe.newplayer.ui.videoplayer
|
package net.newpipe.newplayer.ui.videoplayer
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
@ -38,6 +39,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
@ -49,6 +51,7 @@ import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||||
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
||||||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
import net.newpipe.newplayer.ui.theme.video_player_onSurface
|
import net.newpipe.newplayer.ui.theme.video_player_onSurface
|
||||||
|
import net.newpipe.newplayer.utils.getEmbeddedUiConfig
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TopUI(
|
fun TopUI(
|
||||||
|
@ -56,6 +59,7 @@ fun TopUI(
|
||||||
viewModel: VideoPlayerViewModel,
|
viewModel: VideoPlayerViewModel,
|
||||||
uiState: VideoPlayerUIState
|
uiState: VideoPlayerUIState
|
||||||
) {
|
) {
|
||||||
|
val embeddedUiConfig = getEmbeddedUiConfig(activity = LocalContext.current as Activity)
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
@ -88,7 +92,7 @@ fun TopUI(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { viewModel.openStreamSelection(selectChapter = true) },
|
onClick = { viewModel.openStreamSelection(selectChapter = true, embeddedUiConfig) },
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.MenuBook,
|
imageVector = Icons.AutoMirrored.Filled.MenuBook,
|
||||||
|
@ -96,7 +100,7 @@ fun TopUI(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { viewModel.openStreamSelection(selectChapter = false) },
|
onClick = { viewModel.openStreamSelection(selectChapter = false, embeddedUiConfig) },
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.List,
|
imageVector = Icons.AutoMirrored.Filled.List,
|
||||||
|
|
|
@ -25,6 +25,11 @@ import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.ContextWrapper
|
import android.content.ContextWrapper
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.displayCutout
|
||||||
|
import androidx.compose.foundation.layout.systemBars
|
||||||
|
import androidx.compose.foundation.layout.union
|
||||||
|
import androidx.compose.foundation.layout.waterfall
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
@ -94,6 +99,10 @@ fun getEmbeddedUiConfig(activity: Activity): EmbeddedUiConfig {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun getInsets() =
|
||||||
|
WindowInsets.systemBars.union(WindowInsets.displayCutout).union(WindowInsets.waterfall)
|
||||||
|
|
||||||
private const val HOURS_PER_DAY = 24
|
private const val HOURS_PER_DAY = 24
|
||||||
private const val MINUTES_PER_HOUR = 60
|
private const val MINUTES_PER_HOUR = 60
|
||||||
private const val SECONDS_PER_MINUTE = 60
|
private const val SECONDS_PER_MINUTE = 60
|
||||||
|
|
Loading…
Reference in New Issue