Show radio loading state

This commit is contained in:
vfsfitvnm 2022-07-01 15:31:00 +02:00
parent 91edb9672e
commit 9139609cf3
3 changed files with 46 additions and 66 deletions

View file

@ -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
}

View file

@ -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)
)
}
}
}
}
}
}

View file

@ -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()
}