Rework YouTube Radio

This commit is contained in:
vfsfitvnm
2022-06-11 23:01:06 +02:00
parent f39276875d
commit a0e42473e6
10 changed files with 222 additions and 219 deletions

View File

@@ -21,6 +21,7 @@ import coil.compose.AsyncImage
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.services.StartArtistRadioCommand
import it.vfsfitvnm.vimusic.ui.components.ExpandableText
import it.vfsfitvnm.vimusic.ui.components.Message
import it.vfsfitvnm.vimusic.ui.components.OutcomeItem
@@ -69,6 +70,7 @@ fun ArtistScreen(
}
host {
val player = LocalYoutubePlayer.current
val density = LocalDensity.current
val colorPalette = LocalColorPalette.current
val typography = LocalTypography.current
@@ -137,8 +139,7 @@ fun ArtistScreen(
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
YoutubePlayer.Radio.reset()
artist.shuffleEndpoint?.let(YoutubePlayer.Radio::setup)
player?.mediaController?.sendCustomCommand(StartArtistRadioCommand, artist.shuffleEndpoint.asBundle)
}
.shadow(elevation = 2.dp, shape = CircleShape)
.background(color = colorPalette.elevatedBackground, shape = CircleShape)
@@ -152,8 +153,7 @@ fun ArtistScreen(
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
YoutubePlayer.Radio.reset()
artist.radioEndpoint?.let(YoutubePlayer.Radio::setup)
player?.mediaController?.sendCustomCommand(StartArtistRadioCommand, artist.radioEndpoint.asBundle)
}
.shadow(elevation = 2.dp, shape = CircleShape)
.background(color = colorPalette.elevatedBackground, shape = CircleShape)

View File

@@ -1,6 +1,7 @@
package it.vfsfitvnm.vimusic.ui.screens
import android.net.Uri
import android.os.Bundle
import androidx.compose.animation.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -36,6 +37,7 @@ import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.models.SearchQuery
import it.vfsfitvnm.vimusic.models.SongWithInfo
import it.vfsfitvnm.vimusic.services.StopRadioCommand
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.components.themed.*
@@ -331,11 +333,10 @@ fun HomeScreen(
enabled = songCollection.isNotEmpty(),
onClick = {
menuState.hide()
YoutubePlayer.Radio.reset()
player?.mediaController?.forcePlayFromBeginning(
songCollection
.map(SongWithInfo::asMediaItem)
)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
it.forcePlayFromBeginning(songCollection.map(SongWithInfo::asMediaItem))
}
}
)
@@ -345,12 +346,10 @@ fun HomeScreen(
enabled = songCollection.isNotEmpty(),
onClick = {
menuState.hide()
YoutubePlayer.Radio.reset()
player?.mediaController?.forcePlayFromBeginning(
songCollection
.shuffled()
.map(SongWithInfo::asMediaItem)
)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
it.forcePlayFromBeginning(songCollection.shuffled().map(SongWithInfo::asMediaItem))
}
}
)
@@ -385,11 +384,10 @@ fun HomeScreen(
song = song,
thumbnailSize = thumbnailSize,
onClick = {
YoutubePlayer.Radio.reset()
player?.mediaController?.forcePlayAtIndex(
songCollection.map(SongWithInfo::asMediaItem),
index
)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
it.forcePlayAtIndex(songCollection.map(SongWithInfo::asMediaItem), index)
}
},
menuContent = {
when (preferences.homePageSongCollection) {

View File

@@ -1,6 +1,7 @@
package it.vfsfitvnm.vimusic.ui.screens
import android.net.Uri
import android.os.Bundle
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -26,6 +27,7 @@ import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.internal
import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.models.SongInPlaylist
import it.vfsfitvnm.vimusic.services.StopRadioCommand
import it.vfsfitvnm.vimusic.ui.components.Error
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.Message
@@ -238,13 +240,10 @@ fun IntentUriScreen(uri: Uri) {
song = item,
thumbnailSizePx = density.run { 54.dp.roundToPx() },
onClick = {
YoutubePlayer.Radio.reset()
player?.mediaController?.forcePlayAtIndex(
currentItems.value.map(
YouTube.Item.Song::asMediaItem
), index
)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
it.forcePlayAtIndex(currentItems.value.map(YouTube.Item.Song::asMediaItem), index)
}
}
)
}

View File

@@ -1,5 +1,6 @@
package it.vfsfitvnm.vimusic.ui.screens
import android.os.Bundle
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -30,6 +31,7 @@ import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.models.PlaylistWithSongs
import it.vfsfitvnm.vimusic.models.SongInPlaylist
import it.vfsfitvnm.vimusic.models.SongWithInfo
import it.vfsfitvnm.vimusic.services.StopRadioCommand
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.components.themed.*
@@ -232,12 +234,10 @@ fun LocalPlaylistScreen(
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
YoutubePlayer.Radio.reset()
player?.mediaController?.forcePlayFromBeginning(
playlistWithSongs.songs
.map(SongWithInfo::asMediaItem)
.shuffled()
)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
it.forcePlayFromBeginning(playlistWithSongs.songs.map(SongWithInfo::asMediaItem).shuffled())
}
}
.shadow(elevation = 2.dp, shape = CircleShape)
.background(
@@ -254,12 +254,10 @@ fun LocalPlaylistScreen(
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
YoutubePlayer.Radio.reset()
player?.mediaController?.forcePlayFromBeginning(
playlistWithSongs.songs.map(
SongWithInfo::asMediaItem
)
)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
it.forcePlayFromBeginning(playlistWithSongs.songs.map(SongWithInfo::asMediaItem))
}
}
.shadow(elevation = 2.dp, shape = CircleShape)
.background(
@@ -282,12 +280,10 @@ fun LocalPlaylistScreen(
song = song,
thumbnailSize = thumbnailSize,
onClick = {
YoutubePlayer.Radio.reset()
player?.mediaController?.forcePlayAtIndex(
playlistWithSongs.songs.map(
SongWithInfo::asMediaItem
), index
)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
it.forcePlayAtIndex(playlistWithSongs.songs.map(SongWithInfo::asMediaItem), index)
}
},
menuContent = {
InPlaylistMediaItemMenu(

View File

@@ -1,6 +1,7 @@
package it.vfsfitvnm.vimusic.ui.screens
import android.content.Intent
import android.os.Bundle
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
@@ -22,21 +23,22 @@ import androidx.compose.ui.unit.dp
import androidx.media3.common.Player
import coil.compose.AsyncImage
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
import it.vfsfitvnm.vimusic.internal
import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.models.SongInPlaylist
import it.vfsfitvnm.vimusic.services.StopRadioCommand
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.OutcomeItem
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.components.themed.*
import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.utils.*
import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
import it.vfsfitvnm.vimusic.ui.components.themed.*
import it.vfsfitvnm.youtubemusic.Outcome
import it.vfsfitvnm.youtubemusic.YouTube
import kotlinx.coroutines.Dispatchers
@@ -276,14 +278,16 @@ fun PlaylistOrAlbumScreen(
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
YoutubePlayer.Radio.reset()
playlistOrAlbum.items
?.shuffled()
?.mapNotNull { song ->
song.toMediaItem(browseId, playlistOrAlbum)
}?.let { mediaItems ->
player?.mediaController?.forcePlayFromBeginning(mediaItems)
}
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
playlistOrAlbum.items
?.shuffled()
?.mapNotNull { song ->
song.toMediaItem(browseId, playlistOrAlbum)
}?.let { mediaItems ->
it.forcePlayFromBeginning(mediaItems)
}
}
}
.shadow(elevation = 2.dp, shape = CircleShape)
.background(
@@ -300,12 +304,13 @@ fun PlaylistOrAlbumScreen(
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
YoutubePlayer.Radio.reset()
playlistOrAlbum.items?.mapNotNull { song ->
song.toMediaItem(browseId, playlistOrAlbum)
}?.let { mediaItems ->
player?.mediaController?.forcePlayFromBeginning(mediaItems)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
playlistOrAlbum.items?.mapNotNull { song ->
song.toMediaItem(browseId, playlistOrAlbum)
}?.let { mediaItems ->
it.forcePlayFromBeginning(mediaItems)
}
}
}
.shadow(elevation = 2.dp, shape = CircleShape)
@@ -326,12 +331,13 @@ fun PlaylistOrAlbumScreen(
authors = (song.authors ?: playlistOrAlbum.authors)?.joinToString("") { it.name },
durationText = song.durationText,
onClick = {
YoutubePlayer.Radio.reset()
playlistOrAlbum.items?.mapNotNull { song ->
song.toMediaItem(browseId, playlistOrAlbum)
}?.let { mediaItems ->
player?.mediaController?.forcePlayAtIndex(mediaItems, index)
player?.mediaController?.let {
it.sendCustomCommand(StopRadioCommand, Bundle.EMPTY)
playlistOrAlbum.items?.mapNotNull { song ->
song.toMediaItem(browseId, playlistOrAlbum)
}?.let { mediaItems ->
it.forcePlayAtIndex(mediaItems, index)
}
}
},
startContent = {

View File

@@ -1,5 +1,6 @@
package it.vfsfitvnm.vimusic.ui.screens
import android.os.Bundle
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -25,6 +26,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.core.os.bundleOf
import coil.compose.AsyncImage
import com.valentinilk.shimmer.Shimmer
import com.valentinilk.shimmer.ShimmerBounds
@@ -33,6 +35,7 @@ import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
import it.vfsfitvnm.vimusic.services.StartRadioCommand
import it.vfsfitvnm.vimusic.ui.components.*
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
@@ -42,6 +45,7 @@ import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.utils.*
import it.vfsfitvnm.youtubemusic.Outcome
import it.vfsfitvnm.youtubemusic.YouTube
import it.vfsfitvnm.youtubemusic.models.NavigationEndpoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -214,17 +218,13 @@ fun SearchResultScreen(
is YouTube.Item.Album -> playlistOrAlbumRoute(item.info.endpoint!!.browseId)
is YouTube.Item.Artist -> artistRoute(item.info.endpoint!!.browseId)
is YouTube.Item.Playlist -> playlistOrAlbumRoute(item.info.endpoint!!.browseId)
is YouTube.Item.Song -> {
player?.mediaController?.forcePlay(item.asMediaItem)
item.info.endpoint?.let {
YoutubePlayer.Radio.setup(it, false)
}
is YouTube.Item.Song -> player?.mediaController?.let {
it.forcePlay(item.asMediaItem)
it.sendCustomCommand(StartRadioCommand, item.info.endpoint.asBundle)
}
is YouTube.Item.Video -> {
player?.mediaController?.forcePlay(item.asMediaItem)
item.info.endpoint?.let {
YoutubePlayer.Radio.setup(it, false)
}
is YouTube.Item.Video -> player?.mediaController?.let {
it.forcePlay(item.asMediaItem)
it.sendCustomCommand(StartRadioCommand, item.info.endpoint.asBundle)
}
}
}
@@ -572,4 +572,14 @@ fun SmallArtistItem(
.weight(1f)
)
}
}
}
val NavigationEndpoint.Endpoint.Watch?.asBundle: Bundle
get() = this?.let {
bundleOf(
"videoId" to videoId,
"playlistId" to playlistId,
"playlistSetVideoId" to playlistSetVideoId,
"params" to params,
)
} ?: Bundle.EMPTY