restructure code and remove boilerplate by propagating viewmodel and uistate
This commit is contained in:
parent
0d6227071e
commit
819dc80387
|
@ -38,7 +38,7 @@ data class VideoPlayerUIState(
|
||||||
val isLoading: Boolean,
|
val isLoading: Boolean,
|
||||||
val durationInMs: Long,
|
val durationInMs: Long,
|
||||||
val playbackPositionInMs: Long,
|
val playbackPositionInMs: Long,
|
||||||
val fastseekSeconds: Int,
|
val fastSeekSeconds: Int,
|
||||||
val soundVolume: Float,
|
val soundVolume: Float,
|
||||||
|
|
||||||
// when null use system value
|
// when null use system value
|
||||||
|
@ -58,7 +58,7 @@ data class VideoPlayerUIState(
|
||||||
isLoading = true,
|
isLoading = true,
|
||||||
durationInMs = 0,
|
durationInMs = 0,
|
||||||
playbackPositionInMs = 0,
|
playbackPositionInMs = 0,
|
||||||
fastseekSeconds = 0,
|
fastSeekSeconds = 0,
|
||||||
soundVolume = 0f,
|
soundVolume = 0f,
|
||||||
brightness = null
|
brightness = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -279,7 +279,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
override fun fastSeek(count: Int) {
|
override fun fastSeek(count: Int) {
|
||||||
mutableUiState.update {
|
mutableUiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
fastseekSeconds = count * (newPlayer?.fastSeekAmountSec ?: 10)
|
fastSeekSeconds = count * (newPlayer?.fastSeekAmountSec ?: 10)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,13 +289,13 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun finishFastSeek() {
|
override fun finishFastSeek() {
|
||||||
val fastSeekAmount = mutableUiState.value.fastseekSeconds
|
val fastSeekAmount = mutableUiState.value.fastSeekSeconds
|
||||||
if (fastSeekAmount != 0) {
|
if (fastSeekAmount != 0) {
|
||||||
Log.d(TAG, "$fastSeekAmount")
|
Log.d(TAG, "$fastSeekAmount")
|
||||||
|
|
||||||
newPlayer?.currentPosition = (newPlayer?.currentPosition ?: 0) + (fastSeekAmount * 1000)
|
newPlayer?.currentPosition = (newPlayer?.currentPosition ?: 0) + (fastSeekAmount * 1000)
|
||||||
mutableUiState.update {
|
mutableUiState.update {
|
||||||
it.copy(fastseekSeconds = 0)
|
it.copy(fastSeekSeconds = 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,84 +356,4 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
|
|
||||||
|
|
||||||
} ?: minContentRatio
|
} ?: minContentRatio
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val dummy = object : VideoPlayerViewModel {
|
|
||||||
override var newPlayer: NewPlayer? = null
|
|
||||||
override val internalPlayer: Player? = null
|
|
||||||
override val uiState = MutableStateFlow(VideoPlayerUIState.DEFAULT)
|
|
||||||
override var minContentRatio = 4F / 3F
|
|
||||||
override var maxContentRatio = 16F / 9F
|
|
||||||
override var contentFitMode = ContentScale.FIT_INSIDE
|
|
||||||
|
|
||||||
override fun initUIState(instanceState: Bundle) {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun addCallbackListener(listener: VideoPlayerViewModel.Listener) {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun play() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun switchToEmbeddedView() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun switchToFullscreen() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showUi() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hideUi() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun seekPositionChanged(newValue: Float) {
|
|
||||||
println("dymmy seekPositionChanged: newValue: ${newValue}")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun seekingFinished() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun embeddedDraggedDown(offset: Float) {
|
|
||||||
println("dymmy embeddedDraggedDown: offset: ${offset}")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fastSeek(steps: Int) {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun finishFastSeek() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun brightnessChange(changeRate: Float, currentValue: Float) {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun volumeChange(changeRate: Float) {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pause() {
|
|
||||||
println("dummy pause")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prevStream() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun nextStream() {
|
|
||||||
println("dummy impl")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package net.newpipe.newplayer.model
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.media3.common.Player
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import net.newpipe.newplayer.NewPlayer
|
||||||
|
import net.newpipe.newplayer.ui.ContentScale
|
||||||
|
|
||||||
|
open class VideoPlayerViewModelDummy : VideoPlayerViewModel {
|
||||||
|
override var newPlayer: NewPlayer? = null
|
||||||
|
override val internalPlayer: Player? = null
|
||||||
|
override val uiState = MutableStateFlow(VideoPlayerUIState.DEFAULT)
|
||||||
|
override var minContentRatio = 4F / 3F
|
||||||
|
override var maxContentRatio = 16F / 9F
|
||||||
|
override var contentFitMode = ContentScale.FIT_INSIDE
|
||||||
|
|
||||||
|
override fun initUIState(instanceState: Bundle) {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addCallbackListener(listener: VideoPlayerViewModel.Listener) {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun switchToEmbeddedView() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun switchToFullscreen() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showUi() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hideUi() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun seekPositionChanged(newValue: Float) {
|
||||||
|
println("dymmy seekPositionChanged: newValue: ${newValue}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun seekingFinished() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun embeddedDraggedDown(offset: Float) {
|
||||||
|
println("dymmy embeddedDraggedDown: offset: ${offset}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fastSeek(steps: Int) {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun finishFastSeek() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun brightnessChange(changeRate: Float, currentValue: Float) {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun volumeChange(changeRate: Float) {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pause() {
|
||||||
|
println("dummy pause")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun prevStream() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextStream() {
|
||||||
|
println("dummy impl")
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,54 +48,34 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerUIState
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModelImpl
|
||||||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
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.GestureUI
|
import net.newpipe.newplayer.ui.videoplayer.GestureUI
|
||||||
import net.newpipe.newplayer.utils.getScreenBrightnes
|
import net.newpipe.newplayer.utils.getDefaultBrightness
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun VideoPlayerControllerUI(
|
fun VideoPlayerControllerUI(
|
||||||
isPlaying: Boolean,
|
viewModel: VideoPlayerViewModel,
|
||||||
fullscreen: Boolean,
|
uiState: VideoPlayerUIState
|
||||||
uiVissible: Boolean,
|
|
||||||
seekPosition: Float,
|
|
||||||
isLoading: Boolean,
|
|
||||||
durationInMs: Long,
|
|
||||||
playbackPositionInMs: Long,
|
|
||||||
bufferedPercentage: Float,
|
|
||||||
fastSeekSeconds: Int,
|
|
||||||
soundVolume: Float,
|
|
||||||
brightnes: Float,
|
|
||||||
play: () -> Unit,
|
|
||||||
pause: () -> Unit,
|
|
||||||
prevStream: () -> Unit,
|
|
||||||
nextStream: () -> Unit,
|
|
||||||
switchToFullscreen: () -> Unit,
|
|
||||||
switchToEmbeddedView: () -> Unit,
|
|
||||||
showUi: () -> Unit,
|
|
||||||
hideUi: () -> Unit,
|
|
||||||
seekPositionChanged: (Float) -> Unit,
|
|
||||||
seekingFinished: () -> Unit,
|
|
||||||
embeddedDraggedDownBy: (Float) -> Unit,
|
|
||||||
fastSeek: (Int) -> Unit,
|
|
||||||
finishFastSeek: () -> Unit,
|
|
||||||
brightnessChange: (Float, Float) -> Unit,
|
|
||||||
volumeChange: (Float) -> Unit
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
if (fullscreen) {
|
if (uiState.fullscreen) {
|
||||||
BackHandler {
|
BackHandler {
|
||||||
switchToEmbeddedView()
|
viewModel.switchToEmbeddedView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val internalBrightnessChange = { rateChange: Float ->
|
val internalBrightnessChange = { rateChange: Float ->
|
||||||
val systemBrightness = getScreenBrightnes(context as Activity)
|
val systemBrightness = getDefaultBrightness(context as Activity)
|
||||||
brightnessChange(rateChange, systemBrightness)
|
viewModel.brightnessChange(rateChange, systemBrightness)
|
||||||
}
|
}
|
||||||
|
|
||||||
val insets =
|
val insets =
|
||||||
|
@ -103,35 +83,23 @@ fun VideoPlayerControllerUI(
|
||||||
.union(WindowInsets.displayCutout)
|
.union(WindowInsets.displayCutout)
|
||||||
.union(WindowInsets.waterfall)
|
.union(WindowInsets.waterfall)
|
||||||
|
|
||||||
if (!uiVissible) {
|
if (!uiState.uiVissible) {
|
||||||
GestureUI(
|
GestureUI(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
// .windowInsetsPadding(WindowInsets.systemGestures),
|
// .windowInsetsPadding(WindowInsets.systemGestures),
|
||||||
hideUi = hideUi,
|
viewModel = viewModel,
|
||||||
showUi = showUi,
|
uiState = uiState
|
||||||
uiVissible = uiVissible,
|
|
||||||
fullscreen = fullscreen,
|
|
||||||
fastSeekSeconds = fastSeekSeconds,
|
|
||||||
brightnes = brightnes,
|
|
||||||
soundVolume = soundVolume,
|
|
||||||
switchToFullscreen = switchToFullscreen,
|
|
||||||
switchToEmbeddedView = switchToEmbeddedView,
|
|
||||||
embeddedDraggedDownBy = embeddedDraggedDownBy,
|
|
||||||
fastSeek = fastSeek,
|
|
||||||
fastSeekFinished = finishFastSeek,
|
|
||||||
brightnessChange = internalBrightnessChange,
|
|
||||||
volumeChange = volumeChange
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedVisibility(uiVissible) {
|
AnimatedVisibility(uiState.uiVissible) {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier.fillMaxSize(), color = Color(0x75000000)
|
modifier = Modifier.fillMaxSize(), color = Color(0x75000000)
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoading) {
|
if (uiState.isLoading) {
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -143,41 +111,25 @@ fun VideoPlayerControllerUI(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedVisibility(uiVissible) {
|
AnimatedVisibility(uiState.uiVissible) {
|
||||||
GestureUI(
|
GestureUI(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.windowInsetsPadding(WindowInsets.systemGestures),
|
.windowInsetsPadding(WindowInsets.systemGestures),
|
||||||
hideUi = hideUi,
|
viewModel = viewModel,
|
||||||
showUi = showUi,
|
uiState = uiState
|
||||||
uiVissible = uiVissible,
|
|
||||||
fullscreen = fullscreen,
|
|
||||||
fastSeekSeconds = fastSeekSeconds,
|
|
||||||
soundVolume = soundVolume,
|
|
||||||
brightnes = brightnes,
|
|
||||||
switchToFullscreen = switchToFullscreen,
|
|
||||||
switchToEmbeddedView = switchToEmbeddedView,
|
|
||||||
embeddedDraggedDownBy = embeddedDraggedDownBy,
|
|
||||||
fastSeek = fastSeek,
|
|
||||||
fastSeekFinished = finishFastSeek,
|
|
||||||
volumeChange = volumeChange,
|
|
||||||
brightnessChange = internalBrightnessChange
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
CenterUI(
|
CenterUI(
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
isPlaying = isPlaying,
|
viewModel = viewModel,
|
||||||
isLoading = isLoading,
|
uiState = uiState
|
||||||
play = play,
|
|
||||||
pause = pause,
|
|
||||||
prevStream = prevStream,
|
|
||||||
nextStream = nextStream
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = if (fullscreen) Modifier.windowInsetsPadding(insets) else Modifier
|
modifier = if (uiState.fullscreen) Modifier.windowInsetsPadding(insets) else Modifier
|
||||||
) {
|
) {
|
||||||
TopUI(
|
TopUI(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -193,15 +145,8 @@ fun VideoPlayerControllerUI(
|
||||||
.padding(start = 16.dp, end = 16.dp)
|
.padding(start = 16.dp, end = 16.dp)
|
||||||
.defaultMinSize(minHeight = 40.dp)
|
.defaultMinSize(minHeight = 40.dp)
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
isFullscreen = fullscreen,
|
viewModel = viewModel,
|
||||||
durationInMs = durationInMs,
|
uiState = uiState
|
||||||
playbackPositionInMs = playbackPositionInMs,
|
|
||||||
seekPosition = seekPosition,
|
|
||||||
bufferedPercentage = bufferedPercentage,
|
|
||||||
switchToFullscreen = switchToFullscreen,
|
|
||||||
switchToEmbeddedView = switchToEmbeddedView,
|
|
||||||
seekPositionChanged = seekPositionChanged,
|
|
||||||
seekingFinished = seekingFinished
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,32 +181,7 @@ fun PreviewBackgroundSurface(
|
||||||
fun VideoPlayerControllerUIPreviewEmbedded() {
|
fun VideoPlayerControllerUIPreviewEmbedded() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
PreviewBackgroundSurface {
|
PreviewBackgroundSurface {
|
||||||
VideoPlayerControllerUI(isPlaying = false,
|
VideoPlayerControllerUI(VideoPlayerViewModelDummy(), VideoPlayerUIState.DEFAULT)
|
||||||
fullscreen = false,
|
|
||||||
uiVissible = true,
|
|
||||||
seekPosition = 0.3F,
|
|
||||||
isLoading = false,
|
|
||||||
durationInMs = 9 * 60 * 1000,
|
|
||||||
playbackPositionInMs = 6 * 60 * 1000,
|
|
||||||
bufferedPercentage = 0.4f,
|
|
||||||
fastSeekSeconds = 0,
|
|
||||||
soundVolume = 0f,
|
|
||||||
brightnes = 0f,
|
|
||||||
play = {},
|
|
||||||
pause = {},
|
|
||||||
prevStream = {},
|
|
||||||
nextStream = {},
|
|
||||||
switchToFullscreen = {},
|
|
||||||
switchToEmbeddedView = {},
|
|
||||||
showUi = {},
|
|
||||||
hideUi = {},
|
|
||||||
seekPositionChanged = {},
|
|
||||||
seekingFinished = {},
|
|
||||||
embeddedDraggedDownBy = {},
|
|
||||||
fastSeek = {},
|
|
||||||
finishFastSeek = {},
|
|
||||||
brightnessChange = { a, b ->},
|
|
||||||
volumeChange = {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,32 +191,7 @@ fun VideoPlayerControllerUIPreviewEmbedded() {
|
||||||
fun VideoPlayerControllerUIPreviewLandscape() {
|
fun VideoPlayerControllerUIPreviewLandscape() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
PreviewBackgroundSurface {
|
PreviewBackgroundSurface {
|
||||||
VideoPlayerControllerUI(isPlaying = true,
|
VideoPlayerControllerUI(VideoPlayerViewModelDummy(), VideoPlayerUIState.DEFAULT)
|
||||||
fullscreen = true,
|
|
||||||
uiVissible = true,
|
|
||||||
seekPosition = 0.3F,
|
|
||||||
isLoading = true,
|
|
||||||
durationInMs = 9 * 60 * 1000,
|
|
||||||
playbackPositionInMs = 6 * 60 * 1000,
|
|
||||||
bufferedPercentage = 0.4f,
|
|
||||||
fastSeekSeconds = 0,
|
|
||||||
brightnes = 0f,
|
|
||||||
soundVolume = 0f,
|
|
||||||
play = {},
|
|
||||||
pause = {},
|
|
||||||
prevStream = {},
|
|
||||||
nextStream = {},
|
|
||||||
switchToEmbeddedView = {},
|
|
||||||
switchToFullscreen = {},
|
|
||||||
showUi = {},
|
|
||||||
hideUi = {},
|
|
||||||
seekPositionChanged = {},
|
|
||||||
seekingFinished = {},
|
|
||||||
embeddedDraggedDownBy = {},
|
|
||||||
fastSeek = {},
|
|
||||||
finishFastSeek = {},
|
|
||||||
brightnessChange = { a, b -> },
|
|
||||||
volumeChange = {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,33 +201,7 @@ fun VideoPlayerControllerUIPreviewLandscape() {
|
||||||
fun VideoPlayerControllerUIPreviewPortrait() {
|
fun VideoPlayerControllerUIPreviewPortrait() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
PreviewBackgroundSurface {
|
PreviewBackgroundSurface {
|
||||||
VideoPlayerControllerUI(
|
VideoPlayerControllerUI(VideoPlayerViewModelDummy(), VideoPlayerUIState.DEFAULT)
|
||||||
isPlaying = false,
|
|
||||||
fullscreen = true,
|
|
||||||
uiVissible = true,
|
|
||||||
seekPosition = 0.3F,
|
|
||||||
isLoading = false,
|
|
||||||
durationInMs = 9 * 60 * 1000,
|
|
||||||
playbackPositionInMs = 6 * 60 * 1000,
|
|
||||||
bufferedPercentage = 0.4f,
|
|
||||||
fastSeekSeconds = 0,
|
|
||||||
brightnes = 0f,
|
|
||||||
soundVolume = 0f,
|
|
||||||
play = {},
|
|
||||||
pause = {},
|
|
||||||
prevStream = {},
|
|
||||||
nextStream = {},
|
|
||||||
switchToEmbeddedView = {},
|
|
||||||
switchToFullscreen = {},
|
|
||||||
showUi = {},
|
|
||||||
hideUi = {},
|
|
||||||
seekPositionChanged = {},
|
|
||||||
seekingFinished = {},
|
|
||||||
embeddedDraggedDownBy = {},
|
|
||||||
fastSeek = {},
|
|
||||||
finishFastSeek = {},
|
|
||||||
brightnessChange = { a, b -> },
|
|
||||||
volumeChange = {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,11 +53,11 @@ import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleEventObserver
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||||
import net.newpipe.newplayer.model.VideoPlayerViewModelImpl
|
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
||||||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
import net.newpipe.newplayer.utils.LockScreenOrientation
|
import net.newpipe.newplayer.utils.LockScreenOrientation
|
||||||
import net.newpipe.newplayer.utils.getScreenBrightnes
|
import net.newpipe.newplayer.utils.getDefaultBrightness
|
||||||
import net.newpipe.newplayer.utils.setScreenBrightnes
|
import net.newpipe.newplayer.utils.setScreenBrightness
|
||||||
|
|
||||||
private const val TAG = "VideoPlayerUI"
|
private const val TAG = "VideoPlayerUI"
|
||||||
|
|
||||||
|
@ -89,8 +89,7 @@ fun VideoPlayerUI(
|
||||||
// Setup fullscreen
|
// Setup fullscreen
|
||||||
if (uiState.fullscreen) {
|
if (uiState.fullscreen) {
|
||||||
LaunchedEffect(key1 = true) {
|
LaunchedEffect(key1 = true) {
|
||||||
WindowCompat.getInsetsController(window, view)
|
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = false
|
||||||
.isAppearanceLightStatusBars = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,13 +129,12 @@ fun VideoPlayerUI(
|
||||||
val screenRatio =
|
val screenRatio =
|
||||||
displayMetrics.widthPixels.toFloat() / displayMetrics.heightPixels.toFloat()
|
displayMetrics.widthPixels.toFloat() / displayMetrics.heightPixels.toFloat()
|
||||||
|
|
||||||
val systemScreenBrightnes = getScreenBrightnes(activity)
|
val defaultBrightness = getDefaultBrightness(activity)
|
||||||
|
|
||||||
LaunchedEffect(key1 = uiState.brightness) {
|
LaunchedEffect(key1 = uiState.brightness) {
|
||||||
Log.d(TAG, "New Brightnes: ${uiState.brightness}")
|
Log.d(TAG, "New Brightnes: ${uiState.brightness}")
|
||||||
setScreenBrightnes(
|
setScreenBrightness(
|
||||||
uiState.brightness
|
uiState.brightness ?: defaultBrightness, activity
|
||||||
?: if (systemScreenBrightnes < 0f) 0.5f else systemScreenBrightnes, activity
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,33 +158,7 @@ fun VideoPlayerUI(
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoPlayerControllerUI(
|
VideoPlayerControllerUI(
|
||||||
isPlaying = uiState.playing,
|
viewModel, uiState = uiState
|
||||||
fullscreen = uiState.fullscreen,
|
|
||||||
uiVissible = uiState.uiVissible,
|
|
||||||
seekPosition = uiState.seekerPosition,
|
|
||||||
isLoading = uiState.isLoading,
|
|
||||||
durationInMs = uiState.durationInMs,
|
|
||||||
playbackPositionInMs = uiState.playbackPositionInMs,
|
|
||||||
bufferedPercentage = uiState.bufferedPercentage,
|
|
||||||
fastSeekSeconds = uiState.fastseekSeconds,
|
|
||||||
brightnes = uiState.brightness
|
|
||||||
?: if (systemScreenBrightnes < 0f) 0.5f else systemScreenBrightnes,
|
|
||||||
soundVolume = uiState.soundVolume,
|
|
||||||
play = viewModel::play,
|
|
||||||
pause = viewModel::pause,
|
|
||||||
prevStream = viewModel::prevStream,
|
|
||||||
nextStream = viewModel::nextStream,
|
|
||||||
switchToFullscreen = viewModel::switchToFullscreen,
|
|
||||||
switchToEmbeddedView = viewModel::switchToEmbeddedView,
|
|
||||||
showUi = viewModel::showUi,
|
|
||||||
hideUi = viewModel::hideUi,
|
|
||||||
seekPositionChanged = viewModel::seekPositionChanged,
|
|
||||||
seekingFinished = viewModel::seekingFinished,
|
|
||||||
embeddedDraggedDownBy = viewModel::embeddedDraggedDown,
|
|
||||||
fastSeek = viewModel::fastSeek,
|
|
||||||
finishFastSeek = viewModel::finishFastSeek,
|
|
||||||
volumeChange = viewModel::volumeChange,
|
|
||||||
brightnessChange = viewModel::brightnessChange
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,6 +225,6 @@ fun PlaySurface(
|
||||||
@Composable
|
@Composable
|
||||||
fun PlayerUIPreviewEmbeded() {
|
fun PlayerUIPreviewEmbeded() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
VideoPlayerUI(viewModel = VideoPlayerViewModelImpl.dummy)
|
VideoPlayerUI(viewModel = VideoPlayerViewModelDummy())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,6 +23,8 @@ package net.newpipe.newplayer.ui.theme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerUIState
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
||||||
import net.newpipe.newplayer.ui.PreviewBackgroundSurface
|
import net.newpipe.newplayer.ui.PreviewBackgroundSurface
|
||||||
import net.newpipe.newplayer.ui.VideoPlayerControllerUI
|
import net.newpipe.newplayer.ui.VideoPlayerControllerUI
|
||||||
|
|
||||||
|
@ -72,32 +74,20 @@ val video_player_scrim = Color(0xFF000000)
|
||||||
fun VideoPlayerControllerUIPreviewEmbeddedColorPreview() {
|
fun VideoPlayerControllerUIPreviewEmbeddedColorPreview() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
PreviewBackgroundSurface {
|
PreviewBackgroundSurface {
|
||||||
VideoPlayerControllerUI(isPlaying = false,
|
VideoPlayerControllerUI(
|
||||||
fullscreen = false,
|
viewModel = VideoPlayerViewModelDummy(),
|
||||||
uiVissible = true,
|
uiState = VideoPlayerUIState.DEFAULT.copy(
|
||||||
seekPosition = 0.3F,
|
playing = true,
|
||||||
isLoading = false,
|
fullscreen = false,
|
||||||
durationInMs = 9*60*1000,
|
uiVissible = true,
|
||||||
playbackPositionInMs = 6*60*1000,
|
seekerPosition = 0.3f,
|
||||||
bufferedPercentage = 0.4f,
|
isLoading = false,
|
||||||
fastSeekSeconds = 10,
|
durationInMs = 9 * 60 * 1000,
|
||||||
brightnes = 0f,
|
playbackPositionInMs = 6 * 60 * 1000,
|
||||||
soundVolume = 0f,
|
bufferedPercentage = 0.4f,
|
||||||
play = {},
|
fastSeekSeconds = 10,
|
||||||
pause = {},
|
),
|
||||||
prevStream = {},
|
)
|
||||||
nextStream = {},
|
|
||||||
switchToFullscreen = {},
|
|
||||||
switchToEmbeddedView = {},
|
|
||||||
showUi = {},
|
|
||||||
hideUi = {},
|
|
||||||
seekPositionChanged = {},
|
|
||||||
seekingFinished = {},
|
|
||||||
embeddedDraggedDownBy = {},
|
|
||||||
fastSeek = {},
|
|
||||||
finishFastSeek = {},
|
|
||||||
brightnessChange = {a, b ->},
|
|
||||||
volumeChange = {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.core.os.ConfigurationCompat
|
import androidx.core.os.ConfigurationCompat
|
||||||
import net.newpipe.newplayer.R
|
import net.newpipe.newplayer.R
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerUIState
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
||||||
import net.newpipe.newplayer.ui.seeker.DefaultSeekerColor
|
import net.newpipe.newplayer.ui.seeker.DefaultSeekerColor
|
||||||
import net.newpipe.newplayer.ui.seeker.Seeker
|
import net.newpipe.newplayer.ui.seeker.Seeker
|
||||||
import net.newpipe.newplayer.ui.seeker.SeekerColors
|
import net.newpipe.newplayer.ui.seeker.SeekerColors
|
||||||
|
@ -52,39 +55,33 @@ import kotlin.math.min
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomUI(
|
fun BottomUI(
|
||||||
modifier: Modifier,
|
modifier: Modifier, viewModel: VideoPlayerViewModel, uiState: VideoPlayerUIState
|
||||||
isFullscreen: Boolean,
|
|
||||||
seekPosition: Float,
|
|
||||||
durationInMs: Long,
|
|
||||||
playbackPositionInMs: Long,
|
|
||||||
bufferedPercentage: Float,
|
|
||||||
switchToFullscreen: () -> Unit,
|
|
||||||
switchToEmbeddedView: () -> Unit,
|
|
||||||
seekPositionChanged: (Float) -> Unit,
|
|
||||||
seekingFinished: () -> Unit
|
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
) {
|
) {
|
||||||
Text(getTimeStringFromMs(playbackPositionInMs, getLocale() ?: Locale.US))
|
Text(getTimeStringFromMs(uiState.playbackPositionInMs, getLocale() ?: Locale.US))
|
||||||
Seeker(
|
Seeker(
|
||||||
Modifier.weight(1F),
|
Modifier.weight(1F),
|
||||||
value = seekPosition,
|
value = uiState.seekerPosition,
|
||||||
onValueChange = seekPositionChanged,
|
onValueChange = viewModel::seekPositionChanged,
|
||||||
onValueChangeFinished = seekingFinished,
|
onValueChangeFinished = viewModel::seekingFinished,
|
||||||
readAheadValue = bufferedPercentage,
|
readAheadValue = uiState.bufferedPercentage,
|
||||||
colors = customizedSeekerColors()
|
colors = customizedSeekerColors()
|
||||||
)
|
)
|
||||||
|
|
||||||
//Slider(value = 0.4F, onValueChange = {}, modifier = Modifier.weight(1F))
|
//Slider(value = 0.4F, onValueChange = {}, modifier = Modifier.weight(1F))
|
||||||
|
|
||||||
Text(getTimeStringFromMs(durationInMs, getLocale() ?: Locale.US))
|
Text(getTimeStringFromMs(uiState.durationInMs, getLocale() ?: Locale.US))
|
||||||
|
|
||||||
IconButton(onClick = if (isFullscreen) switchToEmbeddedView else switchToFullscreen) {
|
IconButton(
|
||||||
|
onClick = if (uiState.fullscreen) viewModel::switchToEmbeddedView
|
||||||
|
else viewModel::switchToFullscreen
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = if (isFullscreen) Icons.Filled.FullscreenExit
|
imageVector = if (uiState.fullscreen) Icons.Filled.FullscreenExit
|
||||||
else Icons.Filled.Fullscreen,
|
else Icons.Filled.Fullscreen,
|
||||||
contentDescription = stringResource(R.string.widget_description_toggle_fullscreen)
|
contentDescription = stringResource(R.string.widget_description_toggle_fullscreen)
|
||||||
)
|
)
|
||||||
|
@ -93,7 +90,7 @@ fun BottomUI(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun customizedSeekerColors() : SeekerColors {
|
private fun customizedSeekerColors(): SeekerColors {
|
||||||
val colors = DefaultSeekerColor(
|
val colors = DefaultSeekerColor(
|
||||||
progressColor = MaterialTheme.colorScheme.primary,
|
progressColor = MaterialTheme.colorScheme.primary,
|
||||||
thumbColor = MaterialTheme.colorScheme.primary,
|
thumbColor = MaterialTheme.colorScheme.primary,
|
||||||
|
@ -124,7 +121,7 @@ private const val MILLIS_PER_DAY =
|
||||||
private const val MILLIS_PER_HOUR = MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND
|
private const val MILLIS_PER_HOUR = MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND
|
||||||
private const val MILLIS_PER_MINUTE = SECONDS_PER_MINUTE * MILLIS_PER_SECOND
|
private const val MILLIS_PER_MINUTE = SECONDS_PER_MINUTE * MILLIS_PER_SECOND
|
||||||
|
|
||||||
private fun getTimeStringFromMs(timeSpanInMs: Long, locale: Locale) : String {
|
private fun getTimeStringFromMs(timeSpanInMs: Long, locale: Locale): String {
|
||||||
val days = timeSpanInMs / MILLIS_PER_DAY
|
val days = timeSpanInMs / MILLIS_PER_DAY
|
||||||
val millisThisDay = timeSpanInMs - days * MILLIS_PER_DAY
|
val millisThisDay = timeSpanInMs - days * MILLIS_PER_DAY
|
||||||
val hours = millisThisDay / MILLIS_PER_HOUR
|
val hours = millisThisDay / MILLIS_PER_HOUR
|
||||||
|
@ -153,15 +150,14 @@ fun VideoPlayerControllerBottomUIPreview() {
|
||||||
Surface(color = Color.Black) {
|
Surface(color = Color.Black) {
|
||||||
BottomUI(
|
BottomUI(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
isFullscreen = true,
|
viewModel = VideoPlayerViewModelDummy(),
|
||||||
seekPosition = 0.4F,
|
uiState = VideoPlayerUIState.DEFAULT.copy(
|
||||||
durationInMs = 90 * 60 * 1000,
|
fullscreen = true,
|
||||||
playbackPositionInMs = 3 * 60 * 1000,
|
seekerPosition = 0.4f,
|
||||||
bufferedPercentage = 0.4f,
|
durationInMs = 90 * 60 * 1000,
|
||||||
switchToFullscreen = { },
|
playbackPositionInMs = 3 * 60 * 1000,
|
||||||
switchToEmbeddedView = { },
|
bufferedPercentage = 0.4f
|
||||||
seekPositionChanged = {},
|
),
|
||||||
seekingFinished = {}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,41 +42,41 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import net.newpipe.newplayer.R
|
import net.newpipe.newplayer.R
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerUIState
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModelImpl
|
||||||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CenterUI(
|
fun CenterUI(
|
||||||
modifier: Modifier,
|
modifier: Modifier = Modifier,
|
||||||
isPlaying: Boolean,
|
viewModel: VideoPlayerViewModel,
|
||||||
isLoading: Boolean,
|
uiState: VideoPlayerUIState
|
||||||
play: () -> Unit,
|
|
||||||
pause: () -> Unit,
|
|
||||||
nextStream: () -> Unit,
|
|
||||||
prevStream: () -> Unit
|
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
) {
|
) {
|
||||||
if (!isLoading) {
|
if (!uiState.isLoading) {
|
||||||
CenterControllButton(
|
CenterControllButton(
|
||||||
buttonModifier = Modifier.size(80.dp),
|
buttonModifier = Modifier.size(80.dp),
|
||||||
iconModifier = Modifier.size(40.dp),
|
iconModifier = Modifier.size(40.dp),
|
||||||
icon = Icons.Filled.SkipPrevious,
|
icon = Icons.Filled.SkipPrevious,
|
||||||
contentDescriptoion = stringResource(R.string.widget_description_previous_stream),
|
contentDescriptoion = stringResource(R.string.widget_description_previous_stream),
|
||||||
onClick = prevStream
|
onClick = viewModel::prevStream
|
||||||
)
|
)
|
||||||
|
|
||||||
CenterControllButton(
|
CenterControllButton(
|
||||||
buttonModifier = Modifier.size(80.dp),
|
buttonModifier = Modifier.size(80.dp),
|
||||||
iconModifier = Modifier.size(60.dp),
|
iconModifier = Modifier.size(60.dp),
|
||||||
icon = if (isPlaying) Icons.Filled.Pause else Icons.Filled.PlayArrow,
|
icon = if (uiState.playing) Icons.Filled.Pause else Icons.Filled.PlayArrow,
|
||||||
contentDescriptoion = stringResource(
|
contentDescriptoion = stringResource(
|
||||||
if (isPlaying) R.string.widget_description_pause
|
if (uiState.playing) R.string.widget_description_pause
|
||||||
else R.string.widget_description_play
|
else R.string.widget_description_play
|
||||||
),
|
),
|
||||||
onClick = if (isPlaying) pause else play
|
onClick = if (uiState.playing) viewModel::pause else viewModel::play
|
||||||
)
|
)
|
||||||
|
|
||||||
CenterControllButton(
|
CenterControllButton(
|
||||||
|
@ -84,7 +84,7 @@ fun CenterUI(
|
||||||
iconModifier = Modifier.size(40.dp),
|
iconModifier = Modifier.size(40.dp),
|
||||||
icon = Icons.Filled.SkipNext,
|
icon = Icons.Filled.SkipNext,
|
||||||
contentDescriptoion = stringResource(R.string.widget_description_next_stream),
|
contentDescriptoion = stringResource(R.string.widget_description_next_stream),
|
||||||
onClick = nextStream
|
onClick = viewModel::nextStream
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,13 +122,12 @@ fun VideoPlayerControllerUICenterUIPreview() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
Surface(color = Color.Black) {
|
Surface(color = Color.Black) {
|
||||||
CenterUI(
|
CenterUI(
|
||||||
modifier = Modifier,
|
viewModel = VideoPlayerViewModelDummy(),
|
||||||
isPlaying = true,
|
uiState = VideoPlayerUIState.DEFAULT.copy(
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
play = { },
|
playing = true
|
||||||
pause = { },
|
)
|
||||||
nextStream = { }) {
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ package net.newpipe.newplayer.ui.videoplayer
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerUIState
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||||
import net.newpipe.newplayer.ui.videoplayer.gesture_ui.EmbeddedGestureUI
|
import net.newpipe.newplayer.ui.videoplayer.gesture_ui.EmbeddedGestureUI
|
||||||
import net.newpipe.newplayer.ui.videoplayer.gesture_ui.FullscreenGestureUI
|
import net.newpipe.newplayer.ui.videoplayer.gesture_ui.FullscreenGestureUI
|
||||||
|
|
||||||
|
@ -39,54 +41,15 @@ val INDICATOR_BACKGROUND_COLOR = Color.Black.copy(alpha = 0.3f)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GestureUI(
|
fun GestureUI(
|
||||||
modifier: Modifier,
|
modifier: Modifier, viewModel: VideoPlayerViewModel, uiState: VideoPlayerUIState
|
||||||
hideUi: () -> Unit,
|
|
||||||
showUi: () -> Unit,
|
|
||||||
uiVissible: Boolean,
|
|
||||||
fullscreen: Boolean,
|
|
||||||
fastSeekSeconds: Int,
|
|
||||||
brightnes: Float,
|
|
||||||
soundVolume: Float,
|
|
||||||
switchToFullscreen: () -> Unit,
|
|
||||||
switchToEmbeddedView: () -> Unit,
|
|
||||||
embeddedDraggedDownBy: (Float) -> Unit,
|
|
||||||
fastSeek: (Int) -> Unit,
|
|
||||||
fastSeekFinished: () -> Unit,
|
|
||||||
volumeChange: (Float) -> Unit,
|
|
||||||
brightnessChange: (Float) -> Unit,
|
|
||||||
) {
|
) {
|
||||||
val defaultOnRegularTap = {
|
if (uiState.fullscreen) {
|
||||||
if (uiVissible) {
|
|
||||||
hideUi()
|
|
||||||
} else {
|
|
||||||
showUi()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fullscreen) {
|
|
||||||
FullscreenGestureUI(
|
FullscreenGestureUI(
|
||||||
modifier = modifier,
|
modifier = modifier, viewModel = viewModel, uiState = uiState
|
||||||
uiVisible = uiVissible,
|
)
|
||||||
fastSeekSeconds = fastSeekSeconds,
|
|
||||||
hideUi = hideUi,
|
|
||||||
showUi = showUi,
|
|
||||||
fastSeek = fastSeek,
|
|
||||||
brightnes = brightnes,
|
|
||||||
volume = soundVolume,
|
|
||||||
switchToEmbeddedView = switchToEmbeddedView,
|
|
||||||
fastSeekFinished = fastSeekFinished,
|
|
||||||
volumeChange = volumeChange,
|
|
||||||
brightnesChange = brightnessChange)
|
|
||||||
} else {
|
} else {
|
||||||
EmbeddedGestureUI(
|
EmbeddedGestureUI(
|
||||||
modifier = modifier,
|
modifier = modifier, viewModel = viewModel, uiState = uiState
|
||||||
fastSeekSeconds = fastSeekSeconds,
|
)
|
||||||
uiVissible = uiVissible,
|
|
||||||
switchToFullscreen = switchToFullscreen,
|
|
||||||
embeddedDraggedDownBy = embeddedDraggedDownBy,
|
|
||||||
fastSeek = fastSeek,
|
|
||||||
fastSeekFinished = fastSeekFinished,
|
|
||||||
hideUi = hideUi,
|
|
||||||
showUi = showUi)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,6 +32,9 @@ 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.tooling.preview.Preview
|
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.theme.VideoPlayerTheme
|
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
import net.newpipe.newplayer.ui.videoplayer.FAST_SEEK_MODE_DURATION
|
import net.newpipe.newplayer.ui.videoplayer.FAST_SEEK_MODE_DURATION
|
||||||
|
|
||||||
|
@ -39,49 +42,34 @@ private const val TAG = "EmbeddedGestureUI"
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun EmbeddedGestureUI(
|
fun EmbeddedGestureUI(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier, viewModel: VideoPlayerViewModel, uiState: VideoPlayerUIState
|
||||||
fastSeekSeconds: Int,
|
|
||||||
uiVissible: Boolean,
|
|
||||||
switchToFullscreen: () -> Unit,
|
|
||||||
embeddedDraggedDownBy: (Float) -> Unit,
|
|
||||||
fastSeek: (Int) -> Unit,
|
|
||||||
fastSeekFinished: () -> Unit,
|
|
||||||
hideUi: () -> Unit,
|
|
||||||
showUi: () -> Unit
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val handleDownwardMovement = { movement: TouchedPosition ->
|
val handleDownwardMovement = { movement: TouchedPosition ->
|
||||||
Log.d(TAG, "${movement.x}:${movement.y}")
|
Log.d(TAG, "${movement.x}:${movement.y}")
|
||||||
if (0 < movement.y) {
|
if (0 < movement.y) {
|
||||||
embeddedDraggedDownBy(movement.y)
|
viewModel.embeddedDraggedDown(movement.y)
|
||||||
} else {
|
} else {
|
||||||
switchToFullscreen()
|
viewModel.switchToFullscreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val defaultOnRegularTap = {
|
val defaultOnRegularTap = {
|
||||||
if (uiVissible) {
|
if (uiState.uiVissible) {
|
||||||
hideUi()
|
viewModel.hideUi()
|
||||||
} else {
|
} else {
|
||||||
showUi()
|
viewModel.showUi()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(modifier = modifier) {
|
Row(modifier = modifier) {
|
||||||
GestureSurface(
|
GestureSurface(
|
||||||
modifier = Modifier
|
modifier = Modifier.weight(1f), onRegularTap = defaultOnRegularTap, onMultiTap = {
|
||||||
.weight(1f),
|
viewModel.fastSeek(-it)
|
||||||
multiTapTimeoutInMs = FAST_SEEK_MODE_DURATION,
|
}, onMultiTapFinished = viewModel::finishFastSeek, onMovement = handleDownwardMovement
|
||||||
onRegularTap = defaultOnRegularTap,
|
|
||||||
onMultiTap = {
|
|
||||||
fastSeek(-it)
|
|
||||||
},
|
|
||||||
onMultiTapFinished = fastSeekFinished,
|
|
||||||
onMovement = handleDownwardMovement
|
|
||||||
) {
|
) {
|
||||||
FadedAnimationForSeekFeedback(
|
FadedAnimationForSeekFeedback(
|
||||||
fastSeekSeconds,
|
uiState.fastSeekSeconds, backwards = true
|
||||||
backwards = true
|
|
||||||
) { fastSeekSecondsToDisplay ->
|
) { fastSeekSecondsToDisplay ->
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
FastSeekVisualFeedback(
|
FastSeekVisualFeedback(
|
||||||
|
@ -93,15 +81,13 @@ fun EmbeddedGestureUI(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GestureSurface(
|
GestureSurface(
|
||||||
modifier = Modifier
|
modifier = Modifier.weight(1f),
|
||||||
.weight(1f),
|
|
||||||
multiTapTimeoutInMs = FAST_SEEK_MODE_DURATION,
|
|
||||||
onRegularTap = defaultOnRegularTap,
|
onRegularTap = defaultOnRegularTap,
|
||||||
onMovement = handleDownwardMovement,
|
onMovement = handleDownwardMovement,
|
||||||
onMultiTap = fastSeek,
|
onMultiTap = viewModel::fastSeek,
|
||||||
onMultiTapFinished = fastSeekFinished
|
onMultiTapFinished = viewModel::finishFastSeek
|
||||||
) {
|
) {
|
||||||
FadedAnimationForSeekFeedback(fastSeekSeconds) { fastSeekSecondsToDisplay ->
|
FadedAnimationForSeekFeedback(uiState.fastSeekSeconds) { fastSeekSecondsToDisplay ->
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
FastSeekVisualFeedback(
|
FastSeekVisualFeedback(
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
|
@ -122,14 +108,21 @@ fun EmbeddedGestureUIPreview() {
|
||||||
Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) {
|
Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) {
|
||||||
EmbeddedGestureUI(
|
EmbeddedGestureUI(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
hideUi = { },
|
viewModel = object : VideoPlayerViewModelDummy() {
|
||||||
showUi = { },
|
override fun switchToEmbeddedView() {
|
||||||
uiVissible = false,
|
println("switch to fullscreen")
|
||||||
fastSeekSeconds = 0,
|
}
|
||||||
switchToFullscreen = { println("switch to fullscreen") },
|
|
||||||
embeddedDraggedDownBy = { println("embedded dragged down") },
|
override fun embeddedDraggedDown(offset: Float) {
|
||||||
fastSeek = { println("Fast seek by $it steps") },
|
println("embedded view dragged down by $offset")
|
||||||
fastSeekFinished = {})
|
}
|
||||||
|
|
||||||
|
override fun fastSeek(steps: Int) {
|
||||||
|
println("fast seek by $steps steps")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uiState = VideoPlayerUIState.DEFAULT,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,12 @@
|
||||||
|
|
||||||
package net.newpipe.newplayer.ui.videoplayer.gesture_ui
|
package net.newpipe.newplayer.ui.videoplayer.gesture_ui
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.core.Spring
|
import androidx.compose.animation.core.Spring
|
||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.scaleIn
|
|
||||||
import androidx.compose.animation.scaleOut
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
@ -44,9 +42,13 @@ 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.layout.onGloballyPositioned
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
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.theme.VideoPlayerTheme
|
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
import net.newpipe.newplayer.ui.videoplayer.FAST_SEEK_MODE_DURATION
|
import net.newpipe.newplayer.utils.getDefaultBrightness
|
||||||
|
|
||||||
private enum class IndicatorMode {
|
private enum class IndicatorMode {
|
||||||
NONE,
|
NONE,
|
||||||
|
@ -57,17 +59,8 @@ private enum class IndicatorMode {
|
||||||
@Composable
|
@Composable
|
||||||
fun FullscreenGestureUI(
|
fun FullscreenGestureUI(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
uiVisible: Boolean,
|
viewModel: VideoPlayerViewModel,
|
||||||
fastSeekSeconds: Int,
|
uiState: VideoPlayerUIState
|
||||||
volume: Float,
|
|
||||||
brightnes: Float,
|
|
||||||
hideUi: () -> Unit,
|
|
||||||
showUi: () -> Unit,
|
|
||||||
fastSeek: (Int) -> Unit,
|
|
||||||
fastSeekFinished: () -> Unit,
|
|
||||||
switchToEmbeddedView: () -> Unit,
|
|
||||||
volumeChange: (Float) -> Unit,
|
|
||||||
brightnesChange: (Float) -> Unit
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var heightPx by remember {
|
var heightPx by remember {
|
||||||
|
@ -80,13 +73,17 @@ fun FullscreenGestureUI(
|
||||||
|
|
||||||
val defaultOnRegularTap = {
|
val defaultOnRegularTap = {
|
||||||
|
|
||||||
if (uiVisible) {
|
if (uiState.uiVisible) {
|
||||||
hideUi()
|
viewModel.hideUi()
|
||||||
} else {
|
} else {
|
||||||
showUi()
|
viewModel.showUi()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val activity = LocalContext.current as Activity
|
||||||
|
|
||||||
|
val defaultBrightness = getDefaultBrightness(activity)
|
||||||
|
|
||||||
Box(modifier = modifier.onGloballyPositioned { coordinates ->
|
Box(modifier = modifier.onGloballyPositioned { coordinates ->
|
||||||
heightPx = coordinates.size.height.toFloat()
|
heightPx = coordinates.size.height.toFloat()
|
||||||
}) {
|
}) {
|
||||||
|
@ -97,9 +94,9 @@ fun FullscreenGestureUI(
|
||||||
onRegularTap = defaultOnRegularTap,
|
onRegularTap = defaultOnRegularTap,
|
||||||
onMultiTap = {
|
onMultiTap = {
|
||||||
println("multitap ${-it}")
|
println("multitap ${-it}")
|
||||||
fastSeek(-it)
|
viewModel.fastSeek(-it)
|
||||||
},
|
},
|
||||||
onMultiTapFinished = fastSeekFinished,
|
onMultiTapFinished = viewModel::finishFastSeek,
|
||||||
onUp = {
|
onUp = {
|
||||||
indicatorMode = IndicatorMode.NONE
|
indicatorMode = IndicatorMode.NONE
|
||||||
},
|
},
|
||||||
|
@ -110,13 +107,13 @@ fun FullscreenGestureUI(
|
||||||
indicatorMode = IndicatorMode.BRIGHTNESS_INDICATOR_VISSIBLE
|
indicatorMode = IndicatorMode.BRIGHTNESS_INDICATOR_VISSIBLE
|
||||||
|
|
||||||
if (heightPx != 0f) {
|
if (heightPx != 0f) {
|
||||||
brightnesChange(-change.y / heightPx)
|
viewModel.brightnessChange(-change.y / heightPx, defaultBrightness)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
FadedAnimationForSeekFeedback(
|
FadedAnimationForSeekFeedback(
|
||||||
fastSeekSeconds,
|
uiState.fastSeekSeconds,
|
||||||
backwards = true
|
backwards = true
|
||||||
) { fastSeekSecondsToDisplay ->
|
) { fastSeekSecondsToDisplay ->
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
|
@ -134,7 +131,7 @@ fun FullscreenGestureUI(
|
||||||
onRegularTap = defaultOnRegularTap,
|
onRegularTap = defaultOnRegularTap,
|
||||||
onMovement = { movement ->
|
onMovement = { movement ->
|
||||||
if (0 < movement.y) {
|
if (0 < movement.y) {
|
||||||
switchToEmbeddedView()
|
viewModel.switchToEmbeddedView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -142,8 +139,8 @@ fun FullscreenGestureUI(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f),
|
.weight(1f),
|
||||||
onRegularTap = defaultOnRegularTap,
|
onRegularTap = defaultOnRegularTap,
|
||||||
onMultiTap = fastSeek,
|
onMultiTap = viewModel::fastSeek,
|
||||||
onMultiTapFinished = fastSeekFinished,
|
onMultiTapFinished = viewModel::finishFastSeek,
|
||||||
onUp = {
|
onUp = {
|
||||||
indicatorMode = IndicatorMode.NONE
|
indicatorMode = IndicatorMode.NONE
|
||||||
},
|
},
|
||||||
|
@ -153,12 +150,12 @@ fun FullscreenGestureUI(
|
||||||
) {
|
) {
|
||||||
indicatorMode = IndicatorMode.VOLUME_INDICATOR_VISSIBLE
|
indicatorMode = IndicatorMode.VOLUME_INDICATOR_VISSIBLE
|
||||||
if (heightPx != 0f) {
|
if (heightPx != 0f) {
|
||||||
volumeChange(-change.y / heightPx)
|
viewModel.volumeChange(-change.y / heightPx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
FadedAnimationForSeekFeedback(fastSeekSeconds) { fastSeekSecondsToDisplay ->
|
FadedAnimationForSeekFeedback(uiState.fastSeekSeconds) { fastSeekSecondsToDisplay ->
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
FastSeekVisualFeedback(
|
FastSeekVisualFeedback(
|
||||||
modifier = Modifier.align(Alignment.CenterStart),
|
modifier = Modifier.align(Alignment.CenterStart),
|
||||||
|
@ -174,7 +171,7 @@ fun FullscreenGestureUI(
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
visible = indicatorMode == IndicatorMode.VOLUME_INDICATOR_VISSIBLE,
|
visible = indicatorMode == IndicatorMode.VOLUME_INDICATOR_VISSIBLE,
|
||||||
) {
|
) {
|
||||||
VolumeCircle(volumeFraction = volume)
|
VolumeCircle(volumeFraction = uiState.soundVolume)
|
||||||
}
|
}
|
||||||
|
|
||||||
IndicatorAnimation(
|
IndicatorAnimation(
|
||||||
|
@ -182,7 +179,7 @@ fun FullscreenGestureUI(
|
||||||
visible = indicatorMode == IndicatorMode.BRIGHTNESS_INDICATOR_VISSIBLE,
|
visible = indicatorMode == IndicatorMode.BRIGHTNESS_INDICATOR_VISSIBLE,
|
||||||
) {
|
) {
|
||||||
VolumeCircle(
|
VolumeCircle(
|
||||||
volumeFraction = brightnes,
|
volumeFraction = uiState.brightness ?: defaultBrightness,
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
isBrightness = true
|
isBrightness = true
|
||||||
)
|
)
|
||||||
|
@ -233,17 +230,13 @@ fun FullscreenGestureUIPreview() {
|
||||||
Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) {
|
Surface(modifier = Modifier.wrapContentSize(), color = Color.DarkGray) {
|
||||||
FullscreenGestureUI(
|
FullscreenGestureUI(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
hideUi = { },
|
object : VideoPlayerViewModelDummy() {
|
||||||
showUi = { },
|
override fun fastSeek(steps: Int) {
|
||||||
uiVisible = false,
|
println("fast seek by $steps steps")
|
||||||
fastSeekSeconds = 0,
|
}
|
||||||
volume = 0f,
|
},
|
||||||
brightnes = 0f,
|
VideoPlayerUIState.DEFAULT
|
||||||
fastSeek = { println("fast seek by $it steps") },
|
)
|
||||||
fastSeekFinished = {},
|
|
||||||
switchToEmbeddedView = {},
|
|
||||||
brightnesChange = {},
|
|
||||||
volumeChange = {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +249,7 @@ fun FullscreenGestureUIPreviewInteractive() {
|
||||||
mutableStateOf(0)
|
mutableStateOf(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var brightnesValue by remember {
|
var brightnessValue by remember {
|
||||||
mutableStateOf(0f)
|
mutableStateOf(0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,23 +265,38 @@ fun FullscreenGestureUIPreviewInteractive() {
|
||||||
Surface(modifier = Modifier.wrapContentSize(), color = Color.Gray) {
|
Surface(modifier = Modifier.wrapContentSize(), color = Color.Gray) {
|
||||||
FullscreenGestureUI(
|
FullscreenGestureUI(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
hideUi = { uiVisible = false },
|
object : VideoPlayerViewModelDummy() {
|
||||||
showUi = { uiVisible = true },
|
override fun hideUi() {
|
||||||
uiVisible = uiVisible,
|
uiVisible = false
|
||||||
fastSeekSeconds = seekSeconds,
|
}
|
||||||
volume = soundVolume,
|
|
||||||
brightnes = brightnesValue,
|
override fun showUi() {
|
||||||
fastSeek = { seekSeconds = it * 10 },
|
uiVisible = true
|
||||||
fastSeekFinished = {
|
}
|
||||||
seekSeconds = 0
|
|
||||||
|
override fun fastSeek(steps: Int) {
|
||||||
|
seekSeconds = steps * 10
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun finishFastSeek() {
|
||||||
|
seekSeconds = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun brightnessChange(changeRate: Float, currentValue: Float) {
|
||||||
|
brightnessValue = (brightnessValue + changeRate).coerceIn(0f, 1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun volumeChange(changeRate: Float) {
|
||||||
|
soundVolume = (soundVolume + changeRate).coerceIn(0f, 1f)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
switchToEmbeddedView = {},
|
uiState = VideoPlayerUIState.DEFAULT.copy(
|
||||||
brightnesChange = {
|
uiVissible = uiVisible,
|
||||||
brightnesValue = (brightnesValue + it).coerceIn(0f, 1f)
|
fastSeekSeconds = seekSeconds,
|
||||||
},
|
soundVolume = soundVolume,
|
||||||
volumeChange = {
|
brightness = brightnessValue
|
||||||
soundVolume = (soundVolume + it).coerceIn(0f, 1f)
|
),
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedVisibility(uiVisible) {
|
AnimatedVisibility(uiVisible) {
|
||||||
|
|
|
@ -24,7 +24,6 @@ import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.ContextWrapper
|
import android.content.ContextWrapper
|
||||||
import android.view.Window
|
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
@ -45,14 +44,14 @@ fun LockScreenOrientation(orientation: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
fun getScreenBrightnes(activity: Activity) : Float {
|
fun getDefaultBrightness(activity: Activity) : Float {
|
||||||
val window = activity.window
|
val window = activity.window
|
||||||
val layout = window.attributes as WindowManager.LayoutParams
|
val layout = window.attributes as WindowManager.LayoutParams
|
||||||
return layout.screenBrightness
|
return if(layout.screenBrightness < 0) 0.5f else layout.screenBrightness
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
fun setScreenBrightnes(value:Float, activity: Activity) {
|
fun setScreenBrightness(value:Float, activity: Activity) {
|
||||||
val window = activity.window
|
val window = activity.window
|
||||||
val layout = window.attributes as WindowManager.LayoutParams
|
val layout = window.attributes as WindowManager.LayoutParams
|
||||||
layout.screenBrightness = value
|
layout.screenBrightness = value
|
||||||
|
|
Loading…
Reference in New Issue