Make imported playlist synchronizable (#196)

This commit is contained in:
vfsfitvnm
2022-09-13 11:22:06 +02:00
parent 6f4c46344b
commit 97aecc821f
6 changed files with 675 additions and 10 deletions

View File

@@ -206,6 +206,9 @@ interface Database {
@Query("UPDATE SongPlaylistMap SET position = position + 1 WHERE playlistId = :playlistId AND position >= :fromPosition AND position <= :toPosition")
fun incrementSongPositions(playlistId: Long, fromPosition: Int, toPosition: Int)
@Query("DELETE FROM SongPlaylistMap WHERE playlistId = :id")
fun clearPlaylist(id: Long)
@Query("SELECT loudnessDb FROM Format WHERE songId = :songId")
fun loudnessDb(songId: String): Flow<Float?>
@@ -349,7 +352,7 @@ interface Database {
views = [
SortedSongPlaylistMap::class
],
version = 16,
version = 17,
exportSchema = true,
autoMigrations = [
AutoMigration(from = 1, to = 2),
@@ -364,6 +367,7 @@ interface Database {
AutoMigration(from = 12, to = 13),
AutoMigration(from = 13, to = 14),
AutoMigration(from = 15, to = 16),
AutoMigration(from = 16, to = 17),
],
)
@TypeConverters(Converters::class)

View File

@@ -9,11 +9,5 @@ import androidx.room.PrimaryKey
data class Playlist(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val name: String,
) {
companion object {
val Empty = Playlist(
id = 0,
name = ""
)
}
}
val browseId: String? = null
)

View File

@@ -61,8 +61,12 @@ import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.toMediaItem
import it.vfsfitvnm.youtubemusic.YouTube
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
@ExperimentalFoundationApi
@ExperimentalAnimationApi
@@ -245,6 +249,43 @@ fun LocalPlaylistScreen(playlistId: Long) {
}
)
playlistWithSongs.playlist.browseId?.let { browseId ->
MenuEntry(
icon = R.drawable.sync,
text = "Sync",
onClick = {
menuState.hide()
transaction {
runBlocking(Dispatchers.IO) {
withContext(Dispatchers.IO) {
YouTube.playlist(browseId)?.map {
it.next()
}?.map { playlist ->
playlist.copy(items = playlist.items?.filter { it.info.endpoint != null })
}
}
}?.getOrNull()?.let { remotePlaylist ->
Database.clearPlaylist(playlistWithSongs.playlist.id)
remotePlaylist.items?.forEachIndexed { index, song ->
song.toMediaItem(browseId, remotePlaylist)?.let { mediaItem ->
Database.insert(mediaItem)
Database.insert(
SongPlaylistMap(
songId = mediaItem.mediaId,
playlistId = playlistId,
position = index
)
)
}
}
}
}
}
)
}
MenuEntry(
icon = R.drawable.trash,
text = "Delete",

View File

@@ -252,7 +252,8 @@ fun PlaylistScreen(browseId: String) {
Database.insert(
Playlist(
name = playlist.title
?: "Unknown"
?: "Unknown",
browseId = browseId
)
)