From 0230624809ba81dc58df85cb36cee828b82cbf6c Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Mon, 6 Jun 2022 20:35:08 +0200 Subject: [PATCH] Add the ability to import a YouTube playlist link as local playlist --- .../vimusic/ui/screens/IntentUriScreen.kt | 114 ++++++++++++++++-- 1 file changed, 105 insertions(+), 9 deletions(-) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/IntentUriScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/IntentUriScreen.kt index e9bc748..b2841b1 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/IntentUriScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/IntentUriScreen.kt @@ -17,19 +17,30 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalDensity 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.route.RouteHandler +import it.vfsfitvnm.vimusic.Database 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.ui.components.Error +import it.vfsfitvnm.vimusic.ui.components.LocalMenuState import it.vfsfitvnm.vimusic.ui.components.Message import it.vfsfitvnm.vimusic.ui.components.TopAppBar +import it.vfsfitvnm.vimusic.ui.components.themed.Menu +import it.vfsfitvnm.vimusic.ui.components.themed.MenuCloseButton +import it.vfsfitvnm.vimusic.ui.components.themed.MenuEntry +import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette import it.vfsfitvnm.vimusic.utils.* import it.vfsfitvnm.youtubemusic.Outcome import it.vfsfitvnm.youtubemusic.YouTube import it.vfsfitvnm.youtubemusic.toNullable import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @ExperimentalAnimationApi @@ -54,10 +65,12 @@ fun IntentUriScreen(uri: Uri) { } host { + val menuState = LocalMenuState.current val colorPalette = LocalColorPalette.current val density = LocalDensity.current val player = LocalYoutubePlayer.current + val coroutineScope = rememberCoroutineScope() val shimmer = rememberShimmer(shimmerBounds = ShimmerBounds.Window) @@ -77,6 +90,44 @@ fun IntentUriScreen(uri: Uri) { } } + var isImportingAsPlaylist by remember { + mutableStateOf(false) + } + + if (isImportingAsPlaylist) { + TextFieldDialog( + hintText = "Enter the playlist name", + onDismiss = { + isImportingAsPlaylist = false + }, + onDone = { text -> + menuState.hide() + + coroutineScope.launch(Dispatchers.IO) { + Database.internal.runInTransaction { + val playlistId = Database.insert(Playlist(name = text)) + + items.valueOrNull + ?.map(YouTube.Item.Song::asMediaItem) + ?.forEachIndexed { index, mediaItem -> + if (Database.song(mediaItem.mediaId) == null) { + Database.insert(mediaItem) + } + + Database.insert( + SongInPlaylist( + songId = mediaItem.mediaId, + playlistId = playlistId, + position = index + ) + ) + } + } + } + } + ) + } + LazyColumn( state = lazyListState, horizontalAlignment = Alignment.CenterHorizontally, @@ -100,6 +151,47 @@ fun IntentUriScreen(uri: Uri) { .padding(horizontal = 16.dp) .size(24.dp) ) + + Image( + painter = painterResource(R.drawable.ellipsis_horizontal), + contentDescription = null, + colorFilter = ColorFilter.tint(colorPalette.text), + modifier = Modifier + .clickable { + menuState.display { + Menu { + MenuCloseButton(onClick = menuState::hide) + + MenuEntry( + icon = R.drawable.time, + text = "Enqueue", + enabled = player?.playbackState == Player.STATE_READY, + onClick = { + menuState.hide() + + items.valueOrNull + ?.map(YouTube.Item.Song::asMediaItem) + ?.let { mediaItems -> + player?.mediaController?.enqueue( + mediaItems + ) + } + } + ) + + MenuEntry( + icon = R.drawable.list, + text = "Import as playlist", + onClick = { + isImportingAsPlaylist = true + } + ) + } + } + } + .padding(horizontal = 16.dp, vertical = 8.dp) + .size(24.dp) + ) } } @@ -140,16 +232,20 @@ fun IntentUriScreen(uri: Uri) { } } else { itemsIndexed(currentItems.value) { index, item -> - SmallSongItem( - song = item, - thumbnailSizePx = density.run { 54.dp.roundToPx() }, - onClick = { - YoutubePlayer.Radio.reset() + SmallSongItem( + song = item, + thumbnailSizePx = density.run { 54.dp.roundToPx() }, + onClick = { + YoutubePlayer.Radio.reset() - player?.mediaController?.forcePlayAtIndex(currentItems.value.map(YouTube.Item.Song::asMediaItem), index) - pop() - } - ) + player?.mediaController?.forcePlayAtIndex( + currentItems.value.map( + YouTube.Item.Song::asMediaItem + ), index + ) + pop() + } + ) } } }