Change playlist import UI flow

This commit is contained in:
vfsfitvnm 2022-10-06 18:38:35 +02:00
parent 5b47484a40
commit ba9ae5c705
2 changed files with 38 additions and 39 deletions

View file

@ -296,9 +296,6 @@ interface Database {
@Query("SELECT * FROM Song WHERE title LIKE :query OR artistsText LIKE :query") @Query("SELECT * FROM Song WHERE title LIKE :query OR artistsText LIKE :query")
fun search(query: String): Flow<List<DetailedSong>> fun search(query: String): Flow<List<DetailedSong>>
@Query("SELECT EXISTS(SELECT 1 FROM Playlist WHERE browseId = :browseId)")
fun isImportedPlaylist(browseId: String): Flow<Boolean>
@Transaction @Transaction
@Query("SELECT Song.* FROM Event JOIN Song ON Song.id = songId GROUP BY songId ORDER BY SUM(CAST(playTime AS REAL) / (((:now - timestamp) / 86400000) + 1)) DESC LIMIT 1") @Query("SELECT Song.* FROM Event JOIN Song ON Song.id = songId GROUP BY songId ORDER BY SUM(CAST(playTime AS REAL) / (((:now - timestamp) / 86400000) + 1)) DESC LIMIT 1")
@RewriteQueriesToDropUnusedColumns @RewriteQueriesToDropUnusedColumns

View file

@ -14,7 +14,9 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.saveable.autoSaver import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@ -25,6 +27,7 @@ import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.R import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.models.Playlist import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.models.SongPlaylistMap import it.vfsfitvnm.vimusic.models.SongPlaylistMap
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.savers.InnertubePlaylistOrAlbumPageSaver import it.vfsfitvnm.vimusic.savers.InnertubePlaylistOrAlbumPageSaver
import it.vfsfitvnm.vimusic.savers.nullableSaver import it.vfsfitvnm.vimusic.savers.nullableSaver
import it.vfsfitvnm.vimusic.transaction import it.vfsfitvnm.vimusic.transaction
@ -37,6 +40,7 @@ import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder
import it.vfsfitvnm.vimusic.ui.components.themed.LayoutWithAdaptiveThumbnail import it.vfsfitvnm.vimusic.ui.components.themed.LayoutWithAdaptiveThumbnail
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.SecondaryTextButton import it.vfsfitvnm.vimusic.ui.components.themed.SecondaryTextButton
import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog
import it.vfsfitvnm.vimusic.ui.components.themed.adaptiveThumbnailContent import it.vfsfitvnm.vimusic.ui.components.themed.adaptiveThumbnailContent
import it.vfsfitvnm.vimusic.ui.items.SongItem import it.vfsfitvnm.vimusic.ui.items.SongItem
import it.vfsfitvnm.vimusic.ui.items.SongItemPlaceholder import it.vfsfitvnm.vimusic.ui.items.SongItemPlaceholder
@ -54,7 +58,6 @@ import it.vfsfitvnm.youtubemusic.Innertube
import it.vfsfitvnm.youtubemusic.models.bodies.BrowseBody import it.vfsfitvnm.youtubemusic.models.bodies.BrowseBody
import it.vfsfitvnm.youtubemusic.requests.playlistPage import it.vfsfitvnm.youtubemusic.requests.playlistPage
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ExperimentalFoundationApi @ExperimentalFoundationApi
@ -79,19 +82,39 @@ fun PlaylistSongList(
} }
} }
val isImported by produceSaveableState(
initialValue = null,
stateSaver = autoSaver<Boolean?>(),
) {
Database
.isImportedPlaylist(browseId)
.flowOn(Dispatchers.IO)
.collect { value = it }
}
val songThumbnailSizeDp = Dimensions.thumbnails.song val songThumbnailSizeDp = Dimensions.thumbnails.song
val songThumbnailSizePx = songThumbnailSizeDp.px val songThumbnailSizePx = songThumbnailSizeDp.px
var isImportingPlaylist by rememberSaveable {
mutableStateOf(false)
}
if (isImportingPlaylist) {
TextFieldDialog(
hintText = "Enter the playlist name",
initialTextInput = playlistPage?.title ?: "",
onDismiss = { isImportingPlaylist = false },
onDone = { text ->
query {
transaction {
val playlistId = Database.insert(Playlist(name = text, browseId = browseId))
playlistPage?.songsPage?.items
?.map(Innertube.SongItem::asMediaItem)
?.onEach(Database::insert)
?.mapIndexed { index, mediaItem ->
SongPlaylistMap(
songId = mediaItem.mediaId,
playlistId = playlistId,
position = index
)
}?.let(Database::insertSongPlaylistMaps)
}
}
}
)
}
val headerContent: @Composable () -> Unit = { val headerContent: @Composable () -> Unit = {
if (playlistPage == null) { if (playlistPage == null) {
HeaderPlaceholder( HeaderPlaceholder(
@ -116,30 +139,9 @@ fun PlaylistSongList(
) )
HeaderIconButton( HeaderIconButton(
icon = if (isImported == true) R.drawable.bookmark else R.drawable.bookmark_outline, icon = R.drawable.add,
color = colorPalette.accent, color = colorPalette.text,
onClick = { onClick = { isImportingPlaylist = true }
transaction {
val playlistId =
Database.insert(
Playlist(
name = playlistPage?.title ?: "Unknown",
browseId = browseId
)
)
playlistPage?.songsPage?.items
?.map(Innertube.SongItem::asMediaItem)
?.onEach(Database::insert)
?.mapIndexed { index, mediaItem ->
SongPlaylistMap(
songId = mediaItem.mediaId,
playlistId = playlistId,
position = index
)
}?.let(Database::insertSongPlaylistMaps)
}
}
) )
HeaderIconButton( HeaderIconButton(