Show radio loading state
This commit is contained in:
parent
91edb9672e
commit
9139609cf3
|
@ -17,6 +17,9 @@ import android.support.v4.media.session.MediaSessionCompat
|
|||
import android.support.v4.media.session.PlaybackStateCompat
|
||||
import android.support.v4.media.session.PlaybackStateCompat.*
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat.startForegroundService
|
||||
import androidx.core.net.toUri
|
||||
|
@ -541,6 +544,9 @@ class PlayerService : Service(), Player.Listener, PlaybackStatsListener.Callback
|
|||
|
||||
private var radioJob: Job? = null
|
||||
|
||||
var isLoadingRadio by mutableStateOf(false)
|
||||
private set
|
||||
|
||||
fun startSleepTimer(delayMillis: Long) {
|
||||
timerJob?.cancel()
|
||||
|
||||
|
@ -581,6 +587,7 @@ class PlayerService : Service(), Player.Listener, PlaybackStatsListener.Callback
|
|||
endpoint?.playlistSetVideoId,
|
||||
endpoint?.params
|
||||
).let {
|
||||
isLoadingRadio = true
|
||||
radioJob = coroutineScope.launch(Dispatchers.Main) {
|
||||
if (justAdd) {
|
||||
player.addMediaItems(it.process().drop(1))
|
||||
|
@ -588,11 +595,13 @@ class PlayerService : Service(), Player.Listener, PlaybackStatsListener.Callback
|
|||
player.forcePlayFromBeginning(it.process())
|
||||
}
|
||||
radio = it
|
||||
isLoadingRadio = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stopRadio() {
|
||||
isLoadingRadio = false
|
||||
radioJob?.cancel()
|
||||
radio = null
|
||||
}
|
||||
|
|
|
@ -6,9 +6,7 @@ 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.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
|
@ -18,6 +16,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
|
@ -27,6 +26,8 @@ import androidx.compose.ui.platform.LocalHapticFeedback
|
|||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.media3.common.Player
|
||||
import com.valentinilk.shimmer.ShimmerBounds
|
||||
import com.valentinilk.shimmer.rememberShimmer
|
||||
import it.vfsfitvnm.reordering.rememberReorderingState
|
||||
import it.vfsfitvnm.reordering.verticalDragAfterLongPressToReorder
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
|
@ -35,6 +36,7 @@ import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
|
|||
import it.vfsfitvnm.vimusic.ui.components.BottomSheetState
|
||||
import it.vfsfitvnm.vimusic.ui.components.MusicBars
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.QueuedMediaItemMenu
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SmallSongItemShimmer
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LightColorPalette
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
|
||||
import it.vfsfitvnm.vimusic.utils.PlayerState
|
||||
|
@ -48,7 +50,7 @@ fun CurrentPlaylistView(
|
|||
onGlobalRouteEmitted: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val player = LocalPlayerServiceBinder.current?.player
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
val hapticFeedback = LocalHapticFeedback.current
|
||||
val density = LocalDensity.current
|
||||
val colorPalette = LocalColorPalette.current
|
||||
|
@ -88,13 +90,13 @@ fun CurrentPlaylistView(
|
|||
onClick = {
|
||||
if (isPlayingThisMediaItem) {
|
||||
if (isPaused) {
|
||||
player?.play()
|
||||
binder?.player?.play()
|
||||
} else {
|
||||
player?.pause()
|
||||
binder?.player?.pause()
|
||||
}
|
||||
} else {
|
||||
player?.playWhenReady = true
|
||||
player?.seekToDefaultPosition(index)
|
||||
binder?.player?.playWhenReady = true
|
||||
binder?.player?.seekToDefaultPosition(index)
|
||||
}
|
||||
},
|
||||
menuContent = {
|
||||
|
@ -113,7 +115,10 @@ fun CurrentPlaylistView(
|
|||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
.background(color = Color.Black.copy(alpha = 0.25f), shape = ThumbnailRoundness.shape)
|
||||
.background(
|
||||
color = Color.Black.copy(alpha = 0.25f),
|
||||
shape = ThumbnailRoundness.shape
|
||||
)
|
||||
.size(54.dp)
|
||||
) {
|
||||
if (isPaused) {
|
||||
|
@ -146,56 +151,29 @@ fun CurrentPlaylistView(
|
|||
)
|
||||
},
|
||||
onDragEnd = { reachedIndex ->
|
||||
player?.moveMediaItem(index, reachedIndex)
|
||||
binder?.player?.moveMediaItem(index, reachedIndex)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// if (YoutubePlayer.Radio.isActive && player != null) {
|
||||
// when (val nextContinuation = YoutubePlayer.Radio.nextContinuation) {
|
||||
// is Outcome.Loading, is Outcome.Success<*> -> {
|
||||
// if (nextContinuation is Outcome.Success<*>) {
|
||||
// item {
|
||||
// SideEffect {
|
||||
// coroutineScope.launch {
|
||||
// YoutubePlayer.Radio.process(
|
||||
// playerState.mediaController,
|
||||
// force = true
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// items(count = 3, key = { it }) { index ->
|
||||
// SmallSongItemShimmer(
|
||||
// shimmer = shimmer,
|
||||
// thumbnailSizeDp = 54.dp,
|
||||
// modifier = Modifier
|
||||
// .alpha(1f - index * 0.125f)
|
||||
// .fillMaxWidth()
|
||||
// .padding(vertical = 4.dp, horizontal = 16.dp)
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// is Outcome.Error -> item {
|
||||
// Error(
|
||||
// error = nextContinuation
|
||||
// )
|
||||
// }
|
||||
// is Outcome.Recovered<*> -> item {
|
||||
// Error(
|
||||
// error = nextContinuation.error,
|
||||
// onRetry = {
|
||||
// coroutineScope.launch {
|
||||
// YoutubePlayer.Radio.process(playerState.mediaController, force = true)
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// else -> {}
|
||||
// }
|
||||
// }
|
||||
item {
|
||||
if (binder?.isLoadingRadio == true) {
|
||||
val shimmer = rememberShimmer(shimmerBounds = ShimmerBounds.Window)
|
||||
|
||||
Column {
|
||||
repeat(3) { index ->
|
||||
SmallSongItemShimmer(
|
||||
shimmer = shimmer,
|
||||
thumbnailSizeDp = 54.dp,
|
||||
modifier = Modifier
|
||||
.alpha(1f - index * 0.125f)
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 4.dp, horizontal = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package it.vfsfitvnm.vimusic.utils
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.media3.common.MediaItem
|
||||
import it.vfsfitvnm.youtubemusic.Outcome
|
||||
import it.vfsfitvnm.youtubemusic.YouTube
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -13,13 +11,9 @@ data class YouTubeRadio(
|
|||
private val playlistSetVideoId: String? = null,
|
||||
private val parameters: String? = null
|
||||
) {
|
||||
var nextContinuation by mutableStateOf<Outcome<String?>>(Outcome.Initial)
|
||||
private var nextContinuation: String? = null
|
||||
|
||||
suspend fun process(): List<MediaItem> {
|
||||
val token = nextContinuation.valueOrNull
|
||||
|
||||
nextContinuation = Outcome.Loading
|
||||
|
||||
var mediaItems: List<MediaItem>? = null
|
||||
|
||||
nextContinuation = withContext(Dispatchers.IO) {
|
||||
|
@ -28,13 +22,12 @@ data class YouTubeRadio(
|
|||
playlistId = playlistId,
|
||||
params = parameters,
|
||||
playlistSetVideoId = playlistSetVideoId,
|
||||
continuation = token
|
||||
continuation = nextContinuation
|
||||
)
|
||||
}.map { nextResult ->
|
||||
mediaItems = nextResult.items?.map(YouTube.Item.Song::asMediaItem)
|
||||
|
||||
nextResult.continuation?.takeUnless { token == nextResult.continuation }
|
||||
}.recoverWith(token)
|
||||
nextResult.continuation?.takeUnless { nextContinuation == nextResult.continuation }
|
||||
}.recoverWith(nextContinuation).valueOrNull
|
||||
|
||||
return mediaItems ?: emptyList()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue