add loading indicator to audio controller
This commit is contained in:
parent
72d6874880
commit
afceb43308
|
@ -16,6 +16,9 @@
|
|||
<SelectionState runConfigName="VideoPlayerControllerDropDownPreview">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="AudioPlayerControllerPreview">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
|
@ -20,25 +20,27 @@
|
|||
|
||||
package net.newpipe.newplayer.ui.audioplayer;
|
||||
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.FastForward
|
||||
import androidx.compose.material.icons.filled.FastRewind
|
||||
import androidx.compose.material.icons.filled.Pause
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.material.icons.filled.SkipNext
|
||||
import androidx.compose.material.icons.filled.SkipPrevious
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
@ -51,8 +53,7 @@ import net.newpipe.newplayer.R
|
|||
import net.newpipe.newplayer.model.NewPlayerUIState
|
||||
import net.newpipe.newplayer.model.NewPlayerViewModel
|
||||
import net.newpipe.newplayer.model.NewPlayerViewModelDummy
|
||||
import net.newpipe.newplayer.ui.common.RepeatModeButton
|
||||
import net.newpipe.newplayer.ui.common.ShuffleModeButton
|
||||
import net.newpipe.newplayer.ui.LoadingPlaceholder
|
||||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||
|
||||
@androidx.annotation.OptIn(UnstableApi::class)
|
||||
|
@ -63,12 +64,15 @@ fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIS
|
|||
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
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1F)
|
||||
.weight(1F), contentAlignment = Alignment.Center) {
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f),
|
||||
onClick = viewModel::prevStream,
|
||||
colors = lightAudioControlButtonColorScheme(),
|
||||
|
@ -83,25 +87,81 @@ fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIS
|
|||
}
|
||||
}
|
||||
|
||||
Box(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1F)
|
||||
.weight(1F), contentAlignment = Alignment.Center) {
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f),
|
||||
onClick = {
|
||||
viewModel.fastSeek(1)
|
||||
viewModel.finishFastSeek()
|
||||
},
|
||||
colors = lightAudioControlButtonColorScheme(),
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
imageVector = Icons.Filled.FastRewind,
|
||||
contentDescription = stringResource(R.string.widget_description_fast_rewind)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Button(
|
||||
modifier = Modifier.size(80.dp),
|
||||
onClick = if (uiState.playing) viewModel::pause else viewModel::play,
|
||||
shape = CircleShape
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
imageVector = if (uiState.playing) Icons.Filled.Pause else Icons.Filled.PlayArrow,
|
||||
contentDescription = stringResource(
|
||||
if (uiState.playing) R.string.widget_description_pause
|
||||
else R.string.widget_description_play
|
||||
if(uiState.isLoading) {
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.fillMaxSize().aspectRatio(1F),
|
||||
color = MaterialTheme.colorScheme.onSurface)
|
||||
}
|
||||
|
||||
} else {
|
||||
Icon(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
imageVector = if (uiState.playing) Icons.Filled.Pause else Icons.Filled.PlayArrow,
|
||||
contentDescription = stringResource(
|
||||
if (uiState.playing) R.string.widget_description_pause
|
||||
else R.string.widget_description_play
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Box(modifier = Modifier.size(80.dp), contentAlignment = Alignment.Center) {
|
||||
Box(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1F)
|
||||
.weight(1F), contentAlignment = Alignment.Center) {
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f),
|
||||
onClick = {
|
||||
viewModel.fastSeek(1)
|
||||
viewModel.finishFastSeek()
|
||||
},
|
||||
colors = lightAudioControlButtonColorScheme(),
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
imageVector = Icons.Filled.FastForward,
|
||||
contentDescription = stringResource(R.string.widget_description_fast_forward)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Box(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1F)
|
||||
.weight(1F), contentAlignment = Alignment.Center) {
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f),
|
||||
onClick = viewModel::nextStream,
|
||||
colors = lightAudioControlButtonColorScheme(),
|
||||
|
@ -115,7 +175,7 @@ fun AudioPlaybackController(viewModel: NewPlayerViewModel, uiState: NewPlayerUIS
|
|||
}
|
||||
}
|
||||
|
||||
RepeatModeButton(viewModel = viewModel, uiState = uiState)
|
||||
//RepeatModeButton(viewModel = viewModel, uiState = uiState)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +187,7 @@ fun AudioPlayerControllerPreview() {
|
|||
VideoPlayerTheme {
|
||||
AudioPlaybackController(
|
||||
viewModel = NewPlayerViewModelDummy(),
|
||||
uiState = NewPlayerUIState.DUMMY.copy(playList = emptyList())
|
||||
uiState = NewPlayerUIState.DUMMY.copy(playList = emptyList(), isLoading = true)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ package net.newpipe.newplayer.ui.audioplayer
|
|||
|
||||
import android.app.Activity
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
@ -73,7 +74,7 @@ import net.newpipe.newplayer.utils.getEmbeddedUiConfig
|
|||
@Composable
|
||||
fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||
|
||||
val embeddedUiConfig = if(LocalContext.current is Activity)
|
||||
val embeddedUiConfig = if (LocalContext.current is Activity)
|
||||
getEmbeddedUiConfig(activity = LocalContext.current as Activity)
|
||||
else
|
||||
EmbeddedUiConfig.DUMMY
|
||||
|
@ -107,25 +108,30 @@ fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
|||
)
|
||||
)
|
||||
}
|
||||
Button(onClick = {
|
||||
viewModel.changeUiMode(UIModeState.AUDIO_CHAPTER_SELECT, embeddedUiConfig)
|
||||
}, colors = lightAudioControlButtonColorScheme()) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.MenuBook,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.chapter
|
||||
androidx.compose.animation.AnimatedVisibility(visible = uiState.chapters.isNotEmpty()) {
|
||||
Button(onClick = {
|
||||
viewModel.changeUiMode(UIModeState.AUDIO_CHAPTER_SELECT, embeddedUiConfig)
|
||||
}, colors = lightAudioControlButtonColorScheme()) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.MenuBook,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.chapter
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
Button(onClick = {
|
||||
viewModel.changeUiMode(UIModeState.AUDIO_STREAM_SELECT, embeddedUiConfig)
|
||||
}, colors = lightAudioControlButtonColorScheme()) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.List,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.widget_descriptoin_playlist_item_selection
|
||||
|
||||
androidx.compose.animation.AnimatedVisibility(visible = 1 < uiState.playList.size) {
|
||||
Button(onClick = {
|
||||
viewModel.changeUiMode(UIModeState.AUDIO_STREAM_SELECT, embeddedUiConfig)
|
||||
}, colors = lightAudioControlButtonColorScheme()) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.List,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.widget_descriptoin_playlist_item_selection
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Menu()
|
||||
|
@ -136,7 +142,7 @@ fun AudioBottomUI(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
|||
private fun Menu() {
|
||||
var showMenu: Boolean by remember { mutableStateOf(false) }
|
||||
|
||||
val embeddedUiConfig = if(LocalContext.current is Activity)
|
||||
val embeddedUiConfig = if (LocalContext.current is Activity)
|
||||
getEmbeddedUiConfig(activity = LocalContext.current as Activity)
|
||||
else
|
||||
EmbeddedUiConfig.DUMMY
|
||||
|
@ -183,14 +189,17 @@ private fun Menu() {
|
|||
)
|
||||
},
|
||||
onClick = { /*TODO*/ showMenu = false })
|
||||
DropdownMenuItem(text = { Text(stringResource(R.string.pip_button_description)) }, onClick = { /*TODO*/ }, leadingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PictureInPicture,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.pip_button_description
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(R.string.pip_button_description)) },
|
||||
onClick = { /*TODO*/ },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PictureInPicture,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.pip_button_description
|
||||
)
|
||||
)
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
<string name="menu_item_language">Language</string>
|
||||
<string name="menu_item_playback_speed">Playback speed</string>
|
||||
<string name="widget_description_previous_stream">Previous stream</string>
|
||||
<string name="widget_description_fast_rewind">Fast rewind</string>
|
||||
<string name="widget_description_next_stream">Next stream</string>
|
||||
<string name="widget_description_fast_forward">Fast forward</string>
|
||||
<string name="widget_description_play">Play</string>
|
||||
<string name="widget_description_pause">Pause</string>
|
||||
<string name="widget_description_toggle_fullscreen">Toggle fullscreen</string>
|
||||
|
|
Loading…
Reference in New Issue