add more logic to the audio player
This commit is contained in:
parent
ea0f20a578
commit
72d6874880
|
@ -141,7 +141,10 @@ fun NewPlayerUI(
|
||||||
uiState.uiMode == UIModeState.EMBEDDED_VIDEO_CHAPTER_SELECT
|
uiState.uiMode == UIModeState.EMBEDDED_VIDEO_CHAPTER_SELECT
|
||||||
) {
|
) {
|
||||||
VideoPlayerUi(viewModel = viewModel, uiState = uiState)
|
VideoPlayerUi(viewModel = viewModel, uiState = uiState)
|
||||||
} else if (uiState.uiMode == UIModeState.FULLSCREEN_AUDIO) {
|
} else if (uiState.uiMode == UIModeState.FULLSCREEN_AUDIO ||
|
||||||
|
uiState.uiMode == UIModeState.AUDIO_STREAM_SELECT ||
|
||||||
|
uiState.uiMode == UIModeState.AUDIO_CHAPTER_SELECT
|
||||||
|
) {
|
||||||
AudioPlayerUI(viewModel = viewModel, uiState = uiState)
|
AudioPlayerUI(viewModel = viewModel, uiState = uiState)
|
||||||
} else {
|
} else {
|
||||||
LoadingPlaceholder(uiState.embeddedUiRatio)
|
LoadingPlaceholder(uiState.embeddedUiRatio)
|
||||||
|
|
|
@ -59,23 +59,21 @@ import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||||
Row(modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically) {
|
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
ShuffleModeButton(viewModel = viewModel, uiState = uiState)
|
ShuffleModeButton(viewModel = viewModel, uiState = uiState)
|
||||||
|
|
||||||
Box(modifier = Modifier.size(80.dp), contentAlignment = Alignment.Center) {
|
Box(modifier = Modifier.size(80.dp), contentAlignment = Alignment.Center) {
|
||||||
androidx.compose.animation.AnimatedVisibility(
|
|
||||||
uiState.currentPlaylistItemIndex != 0,
|
|
||||||
enter = fadeIn(animationSpec = tween(400)),
|
|
||||||
exit = fadeOut(animationSpec = tween(400))
|
|
||||||
|
|
||||||
) {
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.aspectRatio(1f),
|
.aspectRatio(1f),
|
||||||
onClick = {},
|
onClick = viewModel::prevStream,
|
||||||
colors = lightAudioControlButtonColorScheme()
|
colors = lightAudioControlButtonColorScheme(),
|
||||||
|
enabled =
|
||||||
|
uiState.currentPlaylistItemIndex != 0
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
@ -84,7 +82,6 @@ fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIS
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.size(80.dp),
|
modifier = Modifier.size(80.dp),
|
||||||
|
@ -92,6 +89,7 @@ fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIS
|
||||||
shape = CircleShape
|
shape = CircleShape
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
imageVector = if (uiState.playing) Icons.Filled.Pause else Icons.Filled.PlayArrow,
|
imageVector = if (uiState.playing) Icons.Filled.Pause else Icons.Filled.PlayArrow,
|
||||||
contentDescription = stringResource(
|
contentDescription = stringResource(
|
||||||
if (uiState.playing) R.string.widget_description_pause
|
if (uiState.playing) R.string.widget_description_pause
|
||||||
|
@ -101,17 +99,13 @@ fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIS
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(modifier = Modifier.size(80.dp), contentAlignment = Alignment.Center) {
|
Box(modifier = Modifier.size(80.dp), contentAlignment = Alignment.Center) {
|
||||||
androidx.compose.animation.AnimatedVisibility(
|
|
||||||
uiState.currentPlaylistItemIndex < uiState.playList.size - 1,
|
|
||||||
enter = fadeIn(animationSpec = tween(400)),
|
|
||||||
exit = fadeOut(animationSpec = tween(400))
|
|
||||||
) {
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.aspectRatio(1f),
|
.aspectRatio(1f),
|
||||||
onClick = {},
|
onClick = viewModel::nextStream,
|
||||||
colors = lightAudioControlButtonColorScheme()
|
colors = lightAudioControlButtonColorScheme(),
|
||||||
|
enabled = uiState.currentPlaylistItemIndex < uiState.playList.size - 1
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
@ -120,7 +114,6 @@ fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIS
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RepeatModeButton(viewModel = viewModel, uiState = uiState)
|
RepeatModeButton(viewModel = viewModel, uiState = uiState)
|
||||||
}
|
}
|
||||||
|
@ -134,7 +127,7 @@ fun AudioPlayerControllerPreview() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
AudioPlaybackController(
|
AudioPlaybackController(
|
||||||
viewModel = NewPlayerViewModelDummy(),
|
viewModel = NewPlayerViewModelDummy(),
|
||||||
uiState = NewPlayerUIState.DUMMY
|
uiState = NewPlayerUIState.DUMMY.copy(playList = emptyList())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -57,7 +57,8 @@ import net.newpipe.newplayer.utils.getInsets
|
||||||
@Composable
|
@Composable
|
||||||
fun lightAudioControlButtonColorScheme() = ButtonDefaults.buttonColors().copy(
|
fun lightAudioControlButtonColorScheme() = ButtonDefaults.buttonColors().copy(
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
containerColor = MaterialTheme.colorScheme.background,
|
||||||
contentColor = MaterialTheme.colorScheme.onSurface
|
contentColor = MaterialTheme.colorScheme.onSurface,
|
||||||
|
disabledContainerColor = MaterialTheme.colorScheme.background
|
||||||
)
|
)
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
package net.newpipe.newplayer.ui.audioplayer
|
package net.newpipe.newplayer.ui.audioplayer
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
@ -55,19 +56,28 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import net.newpipe.newplayer.R
|
import net.newpipe.newplayer.R
|
||||||
|
import net.newpipe.newplayer.model.EmbeddedUiConfig
|
||||||
import net.newpipe.newplayer.model.NewPlayerUIState
|
import net.newpipe.newplayer.model.NewPlayerUIState
|
||||||
import net.newpipe.newplayer.model.NewPlayerViewModel
|
import net.newpipe.newplayer.model.NewPlayerViewModel
|
||||||
import net.newpipe.newplayer.model.NewPlayerViewModelDummy
|
import net.newpipe.newplayer.model.NewPlayerViewModelDummy
|
||||||
|
import net.newpipe.newplayer.model.UIModeState
|
||||||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
|
import net.newpipe.newplayer.utils.getEmbeddedUiConfig
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||||
|
|
||||||
|
val embeddedUiConfig = if(LocalContext.current is Activity)
|
||||||
|
getEmbeddedUiConfig(activity = LocalContext.current as Activity)
|
||||||
|
else
|
||||||
|
EmbeddedUiConfig.DUMMY
|
||||||
|
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -75,7 +85,9 @@ fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||||
.weight(1f), horizontalArrangement = Arrangement.SpaceAround
|
.weight(1f), horizontalArrangement = Arrangement.SpaceAround
|
||||||
) {
|
) {
|
||||||
Button(
|
Button(
|
||||||
onClick = { /*TODO*/ },
|
onClick = {
|
||||||
|
viewModel.changeUiMode(UIModeState.EMBEDDED_AUDIO, embeddedUiConfig)
|
||||||
|
},
|
||||||
colors = lightAudioControlButtonColorScheme()
|
colors = lightAudioControlButtonColorScheme()
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -85,7 +97,9 @@ fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Button(onClick = { /*TODO*/ }, colors = lightAudioControlButtonColorScheme()) {
|
Button(onClick = {
|
||||||
|
viewModel.changeUiMode(UIModeState.FULLSCREEN_VIDEO, embeddedUiConfig)
|
||||||
|
}, colors = lightAudioControlButtonColorScheme()) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.LiveTv,
|
imageVector = Icons.Filled.LiveTv,
|
||||||
contentDescription = stringResource(
|
contentDescription = stringResource(
|
||||||
|
@ -93,7 +107,9 @@ fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Button(onClick = { /*TODO*/ }, colors = lightAudioControlButtonColorScheme()) {
|
Button(onClick = {
|
||||||
|
viewModel.changeUiMode(UIModeState.AUDIO_CHAPTER_SELECT, embeddedUiConfig)
|
||||||
|
}, colors = lightAudioControlButtonColorScheme()) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.MenuBook,
|
imageVector = Icons.AutoMirrored.Filled.MenuBook,
|
||||||
contentDescription = stringResource(
|
contentDescription = stringResource(
|
||||||
|
@ -101,7 +117,9 @@ fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Button(onClick = { /*TODO*/ }, colors = lightAudioControlButtonColorScheme()) {
|
Button(onClick = {
|
||||||
|
viewModel.changeUiMode(UIModeState.AUDIO_STREAM_SELECT, embeddedUiConfig)
|
||||||
|
}, colors = lightAudioControlButtonColorScheme()) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.List,
|
imageVector = Icons.AutoMirrored.Filled.List,
|
||||||
contentDescription = stringResource(
|
contentDescription = stringResource(
|
||||||
|
@ -118,6 +136,11 @@ fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||||
private fun Menu() {
|
private fun Menu() {
|
||||||
var showMenu: Boolean by remember { mutableStateOf(false) }
|
var showMenu: Boolean by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val embeddedUiConfig = if(LocalContext.current is Activity)
|
||||||
|
getEmbeddedUiConfig(activity = LocalContext.current as Activity)
|
||||||
|
else
|
||||||
|
EmbeddedUiConfig.DUMMY
|
||||||
|
|
||||||
Box {
|
Box {
|
||||||
IconButton(onClick = {
|
IconButton(onClick = {
|
||||||
showMenu = true
|
showMenu = true
|
||||||
|
|
|
@ -56,5 +56,5 @@
|
||||||
<string name="stream_thumbnail">Stream Thumbnail</string>
|
<string name="stream_thumbnail">Stream Thumbnail</string>
|
||||||
<string name="details_view_button_description">Switch to details view</string>
|
<string name="details_view_button_description">Switch to details view</string>
|
||||||
<string name="fullscreen_button_description">Switch to fullscreen video mode</string>
|
<string name="fullscreen_button_description">Switch to fullscreen video mode</string>
|
||||||
<string name="pip_button_description">Switch to picture in picture mode</string>
|
<string name="pip_button_description">Picture in picture</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue