Add landscape mode to PlayerView
This commit is contained in:
parent
18362e99b0
commit
c55bccc7aa
1 changed files with 551 additions and 456 deletions
|
@ -1,6 +1,7 @@
|
||||||
package it.vfsfitvnm.vimusic.ui.views
|
package it.vfsfitvnm.vimusic.ui.views
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.media.audiofx.AudioEffect
|
import android.media.audiofx.AudioEffect
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import android.text.format.Formatter
|
import android.text.format.Formatter
|
||||||
|
@ -12,12 +13,10 @@ import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.BasicText
|
import androidx.compose.foundation.text.BasicText
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
@ -30,6 +29,7 @@ import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
@ -50,11 +50,8 @@ import it.vfsfitvnm.vimusic.ui.components.themed.BaseMediaItemMenu
|
||||||
import it.vfsfitvnm.vimusic.ui.components.themed.LoadingOrError
|
import it.vfsfitvnm.vimusic.ui.components.themed.LoadingOrError
|
||||||
import it.vfsfitvnm.vimusic.ui.styling.*
|
import it.vfsfitvnm.vimusic.ui.styling.*
|
||||||
import it.vfsfitvnm.vimusic.utils.*
|
import it.vfsfitvnm.vimusic.utils.*
|
||||||
import it.vfsfitvnm.youtubemusic.YouTube
|
|
||||||
import it.vfsfitvnm.youtubemusic.models.PlayerResponse
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,11 +62,12 @@ fun PlayerView(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val menuState = LocalMenuState.current
|
val menuState = LocalMenuState.current
|
||||||
val preferences = LocalPreferences.current
|
|
||||||
val colorPalette = LocalColorPalette.current
|
val colorPalette = LocalColorPalette.current
|
||||||
val typography = LocalTypography.current
|
val typography = LocalTypography.current
|
||||||
val binder = LocalPlayerServiceBinder.current
|
val binder = LocalPlayerServiceBinder.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val configuration = LocalConfiguration.current
|
||||||
|
|
||||||
val player = binder?.player
|
val player = binder?.player
|
||||||
val playerState = rememberPlayerState(player)
|
val playerState = rememberPlayerState(player)
|
||||||
|
@ -77,11 +75,6 @@ fun PlayerView(
|
||||||
player ?: return
|
player ?: return
|
||||||
playerState?.mediaItem ?: return
|
playerState?.mediaItem ?: return
|
||||||
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
val (thumbnailSizeDp, thumbnailSizePx) = Dimensions.thumbnails.player.song.let {
|
|
||||||
it to (it - 64.dp).px
|
|
||||||
}
|
|
||||||
|
|
||||||
BottomSheet(
|
BottomSheet(
|
||||||
state = layoutState,
|
state = layoutState,
|
||||||
|
@ -177,19 +170,70 @@ fun PlayerView(
|
||||||
playerState.mediaItem.mediaId.let(Database::song).distinctUntilChanged()
|
playerState.mediaItem.mediaId.let(Database::song).distinctUntilChanged()
|
||||||
}.collectAsState(initial = null, context = Dispatchers.IO)
|
}.collectAsState(initial = null, context = Dispatchers.IO)
|
||||||
|
|
||||||
var isShowingStatsForNerds by rememberSaveable {
|
when (configuration.orientation) {
|
||||||
mutableStateOf(false)
|
Configuration.ORIENTATION_LANDSCAPE -> {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 64.dp)
|
||||||
|
.background(colorPalette.background)
|
||||||
|
.padding(top = 16.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(0.66f)
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.padding(bottom = 16.dp)
|
||||||
|
) {
|
||||||
|
Thumbnail(
|
||||||
|
playerState = playerState,
|
||||||
|
song = song,
|
||||||
|
modifier = Modifier
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controls(
|
||||||
|
playerState = playerState,
|
||||||
|
song = song,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
.fillMaxHeight()
|
||||||
|
.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.padding(bottom = 64.dp)
|
||||||
.background(colorPalette.background)
|
.background(colorPalette.background)
|
||||||
.padding(bottom = 72.dp)
|
.padding(top = 16.dp)
|
||||||
.fillMaxSize()
|
|
||||||
) {
|
) {
|
||||||
var scrubbingPosition by remember(playerState.mediaItemIndex) {
|
Box(
|
||||||
mutableStateOf<Long?>(null)
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.25f)
|
||||||
|
.padding(horizontal = 32.dp, vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
Thumbnail(
|
||||||
|
playerState = playerState,
|
||||||
|
song = song,
|
||||||
|
modifier = Modifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls(
|
||||||
|
playerState = playerState,
|
||||||
|
song = song,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TopAppBar {
|
TopAppBar {
|
||||||
|
@ -211,18 +255,37 @@ fun PlayerView(
|
||||||
BaseMediaItemMenu(
|
BaseMediaItemMenu(
|
||||||
mediaItem = playerState.mediaItem,
|
mediaItem = playerState.mediaItem,
|
||||||
onGoToEqualizer = {
|
onGoToEqualizer = {
|
||||||
val intent = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply {
|
val intent =
|
||||||
putExtra(AudioEffect.EXTRA_AUDIO_SESSION, player.audioSessionId)
|
Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply {
|
||||||
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
|
putExtra(
|
||||||
putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
|
AudioEffect.EXTRA_AUDIO_SESSION,
|
||||||
|
player.audioSessionId
|
||||||
|
)
|
||||||
|
putExtra(
|
||||||
|
AudioEffect.EXTRA_PACKAGE_NAME,
|
||||||
|
context.packageName
|
||||||
|
)
|
||||||
|
putExtra(
|
||||||
|
AudioEffect.EXTRA_CONTENT_TYPE,
|
||||||
|
AudioEffect.CONTENT_TYPE_MUSIC
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intent.resolveActivity(context.packageManager) != null) {
|
if (intent.resolveActivity(context.packageManager) != null) {
|
||||||
val contract = ActivityResultContracts.StartActivityForResult()
|
val contract =
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
|
||||||
resultRegistryOwner?.activityResultRegistry?.register("", contract) {}?.launch(intent)
|
resultRegistryOwner?.activityResultRegistry
|
||||||
|
?.register("", contract) {}
|
||||||
|
?.launch(intent)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(context, "No equalizer app found!", Toast.LENGTH_SHORT).show()
|
Toast
|
||||||
|
.makeText(
|
||||||
|
context,
|
||||||
|
"No equalizer app found!",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDismiss = menuState::hide,
|
onDismiss = menuState::hide,
|
||||||
|
@ -235,6 +298,41 @@ fun PlayerView(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlayerBottomSheet(
|
||||||
|
playerState = playerState,
|
||||||
|
layoutState = rememberBottomSheetState(64.dp, layoutState.upperBound * 0.9f),
|
||||||
|
onGlobalRouteEmitted = layoutState.collapse,
|
||||||
|
padding = layoutState.upperBound * 0.1f,
|
||||||
|
song = song,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
@Composable
|
||||||
|
private fun Thumbnail(
|
||||||
|
playerState: PlayerState,
|
||||||
|
song: Song?,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val typography = LocalTypography.current
|
||||||
|
val context = LocalContext.current
|
||||||
|
val binder = LocalPlayerServiceBinder.current
|
||||||
|
val player = binder?.player ?: return
|
||||||
|
|
||||||
|
playerState.mediaItem ?: return
|
||||||
|
|
||||||
|
val (thumbnailSizeDp, thumbnailSizePx) = Dimensions.thumbnails.player.song.let {
|
||||||
|
it to (it - 64.dp).px
|
||||||
|
}
|
||||||
|
|
||||||
|
var isShowingStatsForNerds by rememberSaveable {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
|
||||||
if (playerState.error == null) {
|
if (playerState.error == null) {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = playerState.mediaItemIndex,
|
targetState = playerState.mediaItemIndex,
|
||||||
|
@ -247,9 +345,8 @@ fun PlayerView(
|
||||||
SizeTransform(clip = false)
|
SizeTransform(clip = false)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.weight(1f)
|
.aspectRatio(1f)
|
||||||
.align(Alignment.CenterHorizontally)
|
|
||||||
) {
|
) {
|
||||||
val artworkUri = remember(it) {
|
val artworkUri = remember(it) {
|
||||||
player.getMediaItemAt(it).mediaMetadata.artworkUri.thumbnail(
|
player.getMediaItemAt(it).mediaMetadata.artworkUri.thumbnail(
|
||||||
|
@ -259,9 +356,6 @@ fun PlayerView(
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(bottom = 32.dp)
|
|
||||||
.padding(horizontal = 32.dp)
|
|
||||||
.aspectRatio(1f)
|
|
||||||
.clip(ThumbnailRoundness.shape)
|
.clip(ThumbnailRoundness.shape)
|
||||||
.size(thumbnailSizeDp)
|
.size(thumbnailSizeDp)
|
||||||
) {
|
) {
|
||||||
|
@ -280,7 +374,7 @@ fun PlayerView(
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
)
|
)
|
||||||
|
|
||||||
androidx.compose.animation.AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = isShowingStatsForNerds,
|
visible = isShowingStatsForNerds,
|
||||||
enter = fadeIn(),
|
enter = fadeIn(),
|
||||||
exit = fadeOut(),
|
exit = fadeOut(),
|
||||||
|
@ -404,40 +498,6 @@ fun PlayerView(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (song != null && (contentLength == null || loudnessDb == null)) {
|
|
||||||
BasicText(
|
|
||||||
text = "FILL MISSING DATA",
|
|
||||||
style = typography.xxs.semiBold.color(BlackColorPalette.text),
|
|
||||||
modifier = Modifier
|
|
||||||
.clickable(
|
|
||||||
indication = rememberRipple(bounded = true),
|
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
|
||||||
onClick = {
|
|
||||||
song?.let { song ->
|
|
||||||
coroutineScope.launch(Dispatchers.IO) {
|
|
||||||
YouTube
|
|
||||||
.player(song.id)
|
|
||||||
?.map { body ->
|
|
||||||
Database.update(
|
|
||||||
song.copy(
|
|
||||||
loudnessDb = body.playerConfig?.audioConfig?.loudnessDb?.toFloat(),
|
|
||||||
contentLength = body.streamingData?.adaptiveFormats
|
|
||||||
?.findLast { format ->
|
|
||||||
format.itag == 251
|
|
||||||
}
|
|
||||||
?.let(PlayerResponse.StreamingData.AdaptiveFormat::contentLength)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.padding(all = 16.dp)
|
|
||||||
.align(Alignment.End)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,9 +505,7 @@ fun PlayerView(
|
||||||
} else {
|
} else {
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.weight(1f)
|
|
||||||
.align(Alignment.CenterHorizontally)
|
|
||||||
.padding(bottom = 32.dp)
|
.padding(bottom = 32.dp)
|
||||||
.padding(horizontal = 32.dp)
|
.padding(horizontal = 32.dp)
|
||||||
.size(thumbnailSizeDp)
|
.size(thumbnailSizeDp)
|
||||||
|
@ -461,23 +519,53 @@ fun PlayerView(
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Controls(
|
||||||
|
playerState: PlayerState,
|
||||||
|
song: Song?,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val typography = LocalTypography.current
|
||||||
|
val colorPalette = LocalColorPalette.current
|
||||||
|
val preferences = LocalPreferences.current
|
||||||
|
|
||||||
|
val binder = LocalPlayerServiceBinder.current
|
||||||
|
val player = binder?.player ?: return
|
||||||
|
|
||||||
|
var scrubbingPosition by remember(playerState.mediaItemIndex) {
|
||||||
|
mutableStateOf<Long?>(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 32.dp)
|
||||||
|
) {
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
BasicText(
|
BasicText(
|
||||||
text = playerState.mediaMetadata.title?.toString() ?: "",
|
text = playerState.mediaMetadata.title?.toString() ?: "",
|
||||||
style = typography.l.bold,
|
style = typography.l.bold,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 32.dp)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
BasicText(
|
BasicText(
|
||||||
text = playerState.mediaMetadata.artist?.toString() ?: "",
|
text = playerState.mediaMetadata.artist?.toString() ?: "",
|
||||||
style = typography.s.semiBold.secondary,
|
style = typography.s.semiBold.secondary,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 32.dp)
|
.weight(0.5f)
|
||||||
)
|
)
|
||||||
|
|
||||||
SeekBar(
|
SeekBar(
|
||||||
|
@ -500,20 +588,19 @@ fun PlayerView(
|
||||||
},
|
},
|
||||||
color = colorPalette.text,
|
color = colorPalette.text,
|
||||||
backgroundColor = colorPalette.textDisabled,
|
backgroundColor = colorPalette.textDisabled,
|
||||||
shape = RoundedCornerShape(8.dp),
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 24.dp, bottom = 12.dp)
|
.height(8.dp)
|
||||||
.padding(horizontal = 32.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 32.dp)
|
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(bottom = 16.dp)
|
|
||||||
) {
|
) {
|
||||||
BasicText(
|
BasicText(
|
||||||
text = DateUtils.formatElapsedTime(
|
text = DateUtils.formatElapsedTime(
|
||||||
|
@ -534,11 +621,16 @@ fun PlayerView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(vertical = 32.dp)
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(R.drawable.heart),
|
painter = painterResource(R.drawable.heart),
|
||||||
|
@ -551,10 +643,10 @@ fun PlayerView(
|
||||||
query {
|
query {
|
||||||
song?.let { song ->
|
song?.let { song ->
|
||||||
Database.update(song.toggleLike())
|
Database.update(song.toggleLike())
|
||||||
} ?: Database.insert(playerState.mediaItem, Song::toggleLike)
|
} ?: Database.insert(playerState.mediaItem!!, Song::toggleLike)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(horizontal = 16.dp)
|
.weight(1f)
|
||||||
.size(28.dp)
|
.size(28.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -564,15 +656,20 @@ fun PlayerView(
|
||||||
colorFilter = ColorFilter.tint(colorPalette.text),
|
colorFilter = ColorFilter.tint(colorPalette.text),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clickable(onClick = player::seekToPrevious)
|
.clickable(onClick = player::seekToPrevious)
|
||||||
.padding(horizontal = 16.dp)
|
.weight(1f)
|
||||||
.size(28.dp)
|
.size(28.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
val isPaused = playerState.playbackState == Player.STATE_ENDED || !playerState.playWhenReady
|
Spacer(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
val isPaused =
|
||||||
|
playerState.playbackState == Player.STATE_ENDED || !playerState.playWhenReady
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 8.dp)
|
|
||||||
.clickable {
|
.clickable {
|
||||||
if (isPaused) {
|
if (isPaused) {
|
||||||
if (player.playbackState == Player.STATE_IDLE) {
|
if (player.playbackState == Player.STATE_IDLE) {
|
||||||
|
@ -597,13 +694,18 @@ fun PlayerView(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(R.drawable.play_skip_forward),
|
painter = painterResource(R.drawable.play_skip_forward),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
colorFilter = ColorFilter.tint(colorPalette.text),
|
colorFilter = ColorFilter.tint(colorPalette.text),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clickable(onClick = player::seekToNext)
|
.clickable(onClick = player::seekToNext)
|
||||||
.padding(horizontal = 16.dp)
|
.weight(1f)
|
||||||
.size(28.dp)
|
.size(28.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -633,21 +735,14 @@ fun PlayerView(
|
||||||
preferences.repeatMode = repeatMode
|
preferences.repeatMode = repeatMode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(horizontal = 16.dp)
|
.weight(1f)
|
||||||
.size(28.dp)
|
.size(28.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PlayerBottomSheet(
|
Spacer(
|
||||||
playerState = playerState,
|
|
||||||
layoutState = rememberBottomSheetState(64.dp, layoutState.upperBound * 0.9f),
|
|
||||||
onGlobalRouteEmitted = layoutState.collapse,
|
|
||||||
padding = layoutState.upperBound * 0.1f,
|
|
||||||
song = song,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomCenter)
|
.weight(1f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue