Merge pull request #2920 from Isira-Seneviratne/LocalPlaylistDao_suspend

Convert LocalPlaylistsDao methods to suspend functions.
This commit is contained in:
Bnyro 2023-01-31 11:36:02 +01:00 committed by GitHub
commit 41426f4fca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 137 deletions

View File

@ -12,7 +12,6 @@ import com.github.libretube.db.DatabaseHolder
import com.github.libretube.db.obj.LocalPlaylist import com.github.libretube.db.obj.LocalPlaylist
import com.github.libretube.enums.PlaylistType import com.github.libretube.enums.PlaylistType
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.awaitQuery
import com.github.libretube.extensions.toID import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toLocalPlaylistItem import com.github.libretube.extensions.toLocalPlaylistItem
import com.github.libretube.extensions.toStreamItem import com.github.libretube.extensions.toStreamItem
@ -35,26 +34,22 @@ object PlaylistsHelper {
private val token get() = PreferenceHelper.getToken() private val token get() = PreferenceHelper.getToken()
val loggedIn: Boolean get() = token != "" val loggedIn: Boolean get() = token.isNotEmpty()
suspend fun getPlaylists(): List<Playlists> { suspend fun getPlaylists(): List<Playlists> = withContext(Dispatchers.IO) {
if (loggedIn) return RetrofitInstance.authApi.getUserPlaylists(token) if (loggedIn) {
RetrofitInstance.authApi.getUserPlaylists(token)
val localPlaylists = awaitQuery { } else {
DatabaseHolder.Database.localPlaylistsDao().getAll() DatabaseHolder.Database.localPlaylistsDao().getAll()
.map {
Playlists(
id = it.playlist.id.toString(),
name = it.playlist.name,
thumbnail = ProxyHelper.rewriteUrl(it.playlist.thumbnailUrl),
videos = it.videos.size.toLong()
)
}
} }
val playlists = mutableListOf<Playlists>()
localPlaylists.forEach {
playlists.add(
Playlists(
id = it.playlist.id.toString(),
name = it.playlist.name,
thumbnail = ProxyHelper.rewriteUrl(it.playlist.thumbnailUrl),
videos = it.videos.size.toLong()
)
)
}
return playlists
} }
suspend fun getPlaylist(playlistId: String): Playlist { suspend fun getPlaylist(playlistId: String): Playlist {
@ -63,9 +58,8 @@ object PlaylistsHelper {
PlaylistType.PRIVATE -> RetrofitInstance.authApi.getPlaylist(playlistId) PlaylistType.PRIVATE -> RetrofitInstance.authApi.getPlaylist(playlistId)
PlaylistType.PUBLIC -> RetrofitInstance.api.getPlaylist(playlistId) PlaylistType.PUBLIC -> RetrofitInstance.api.getPlaylist(playlistId)
PlaylistType.LOCAL -> { PlaylistType.LOCAL -> {
val relation = awaitQuery { val relation = DatabaseHolder.Database.localPlaylistsDao().getAll()
DatabaseHolder.Database.localPlaylistsDao().getAll() .first { it.playlist.id.toString() == playlistId }
}.first { it.playlist.id.toString() == playlistId }
return Playlist( return Playlist(
name = relation.playlist.name, name = relation.playlist.name,
thumbnailUrl = ProxyHelper.rewriteUrl(relation.playlist.thumbnailUrl), thumbnailUrl = ProxyHelper.rewriteUrl(relation.playlist.thumbnailUrl),
@ -81,33 +75,26 @@ object PlaylistsHelper {
appContext: Context appContext: Context
): String? { ): String? {
if (!loggedIn) { if (!loggedIn) {
awaitQuery { val playlist = LocalPlaylist(name = playlistName, thumbnailUrl = "")
DatabaseHolder.Database.localPlaylistsDao().createPlaylist( DatabaseHolder.Database.localPlaylistsDao().createPlaylist(playlist)
LocalPlaylist( return DatabaseHolder.Database.localPlaylistsDao().getAll()
name = playlistName, .last().playlist.id.toString()
thumbnailUrl = "" } else {
) val response = try {
) RetrofitInstance.authApi.createPlaylist(token, Playlists(name = playlistName))
} catch (e: IOException) {
appContext.toastFromMainThread(R.string.unknown_error)
return null
} catch (e: HttpException) {
Log.e(TAG(), e.toString())
appContext.toastFromMainThread(R.string.server_error)
return null
}
if (response.playlistId != null) {
appContext.toastFromMainThread(R.string.playlistCreated)
} }
return awaitQuery {
DatabaseHolder.Database.localPlaylistsDao().getAll()
}.last().playlist.id.toString()
}
val response = try {
RetrofitInstance.authApi.createPlaylist(token, Playlists(name = playlistName))
} catch (e: IOException) {
appContext.toastFromMainThread(R.string.unknown_error)
return null
} catch (e: HttpException) {
Log.e(TAG(), e.toString())
appContext.toastFromMainThread(R.string.server_error)
return null
}
if (response.playlistId != null) {
appContext.toastFromMainThread(R.string.playlistCreated)
return response.playlistId return response.playlistId
} }
return null
} }
suspend fun addToPlaylist(playlistId: String, vararg videos: StreamItem): Boolean { suspend fun addToPlaylist(playlistId: String, vararg videos: StreamItem): Boolean {
@ -117,22 +104,19 @@ object PlaylistsHelper {
for (video in videos) { for (video in videos) {
val localPlaylistItem = video.toLocalPlaylistItem(playlistId) val localPlaylistItem = video.toLocalPlaylistItem(playlistId)
awaitQuery { // avoid duplicated videos in a playlist
// avoid duplicated videos in a playlist DatabaseHolder.Database.localPlaylistsDao()
DatabaseHolder.Database.localPlaylistsDao() .deletePlaylistItemsByVideoId(playlistId, localPlaylistItem.videoId)
.deletePlaylistItemsByVideoId(playlistId, localPlaylistItem.videoId)
// add the new video to the database // add the new video to the database
DatabaseHolder.Database.localPlaylistsDao().addPlaylistVideo(localPlaylistItem) DatabaseHolder.Database.localPlaylistsDao().addPlaylistVideo(localPlaylistItem)
if (localPlaylist.playlist.thumbnailUrl == "") { val playlist = localPlaylist.playlist
// set the new playlist thumbnail URL if (playlist.thumbnailUrl == "") {
localPlaylistItem.thumbnailUrl?.let { // set the new playlist thumbnail URL
localPlaylist.playlist.thumbnailUrl = it localPlaylistItem.thumbnailUrl?.let {
DatabaseHolder.Database.localPlaylistsDao().updatePlaylist( playlist.thumbnailUrl = it
localPlaylist.playlist DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(playlist)
)
}
} }
} }
} }
@ -144,61 +128,41 @@ object PlaylistsHelper {
} }
suspend fun renamePlaylist(playlistId: String, newName: String): Boolean { suspend fun renamePlaylist(playlistId: String, newName: String): Boolean {
if (!loggedIn) { return if (!loggedIn) {
val playlist = awaitQuery { val playlist = DatabaseHolder.Database.localPlaylistsDao().getAll()
DatabaseHolder.Database.localPlaylistsDao().getAll() .first { it.playlist.id.toString() == playlistId }.playlist
}.first { it.playlist.id.toString() == playlistId }.playlist
playlist.name = newName playlist.name = newName
awaitQuery { DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(playlist)
DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(playlist) true
} } else {
return true val playlist = PlaylistId(playlistId, newName = newName)
RetrofitInstance.authApi.renamePlaylist(token, playlist).playlistId != null
} }
return RetrofitInstance.authApi.renamePlaylist(
token,
PlaylistId(playlistId, newName = newName)
).playlistId != null
} }
suspend fun removeFromPlaylist(playlistId: String, index: Int) { suspend fun removeFromPlaylist(playlistId: String, index: Int) {
if (!loggedIn) { if (!loggedIn) {
val transaction = awaitQuery { val transaction = DatabaseHolder.Database.localPlaylistsDao().getAll()
DatabaseHolder.Database.localPlaylistsDao().getAll() .first { it.playlist.id.toString() == playlistId }
}.first { it.playlist.id.toString() == playlistId } DatabaseHolder.Database.localPlaylistsDao().removePlaylistVideo(
awaitQuery { transaction.videos[index]
DatabaseHolder.Database.localPlaylistsDao().removePlaylistVideo( )
transaction.videos[index]
)
}
if (transaction.videos.size > 1) { if (transaction.videos.size > 1) {
if (index == 0) { if (index == 0) {
transaction.videos[1].thumbnailUrl?.let { transaction.videos[1].thumbnailUrl?.let {
transaction.playlist.thumbnailUrl = it transaction.playlist.thumbnailUrl = it
} }
awaitQuery { DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(transaction.playlist)
DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(
transaction.playlist
)
}
} }
return return
} }
// remove thumbnail if playlist now empty // remove thumbnail if playlist now empty
awaitQuery { transaction.playlist.thumbnailUrl = ""
transaction.playlist.thumbnailUrl = "" DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(transaction.playlist)
DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(transaction.playlist) } else {
} val playlist = PlaylistId(playlistId = playlistId, index = index)
return RetrofitInstance.authApi.removeFromPlaylist(PreferenceHelper.getToken(), playlist)
} }
RetrofitInstance.authApi.removeFromPlaylist(
PreferenceHelper.getToken(),
PlaylistId(
playlistId = playlistId,
index = index
)
)
} }
suspend fun importPlaylists(appContext: Context, playlists: List<ImportPlaylist>) { suspend fun importPlaylists(appContext: Context, playlists: List<ImportPlaylist>) {

View File

@ -14,29 +14,26 @@ import com.github.libretube.db.obj.LocalPlaylistWithVideos
interface LocalPlaylistsDao { interface LocalPlaylistsDao {
@Transaction @Transaction
@Query("SELECT * FROM LocalPlaylist") @Query("SELECT * FROM LocalPlaylist")
fun getAll(): List<LocalPlaylistWithVideos> suspend fun getAll(): List<LocalPlaylistWithVideos>
@Insert @Insert
fun createPlaylist(playlist: LocalPlaylist) suspend fun createPlaylist(playlist: LocalPlaylist)
@Update @Update
fun updatePlaylist(playlist: LocalPlaylist) suspend fun updatePlaylist(playlist: LocalPlaylist)
@Delete
fun deletePlaylist(playlist: LocalPlaylist)
@Query("DELETE FROM localPlaylist WHERE id = :playlistId") @Query("DELETE FROM localPlaylist WHERE id = :playlistId")
fun deletePlaylistById(playlistId: String) suspend fun deletePlaylistById(playlistId: String)
@Insert @Insert
fun addPlaylistVideo(playlistVideo: LocalPlaylistItem) suspend fun addPlaylistVideo(playlistVideo: LocalPlaylistItem)
@Delete @Delete
fun removePlaylistVideo(playlistVideo: LocalPlaylistItem) suspend fun removePlaylistVideo(playlistVideo: LocalPlaylistItem)
@Query("DELETE FROM localPlaylistItem WHERE playlistId = :playlistId") @Query("DELETE FROM localPlaylistItem WHERE playlistId = :playlistId")
fun deletePlaylistItemsByPlaylistId(playlistId: String) suspend fun deletePlaylistItemsByPlaylistId(playlistId: String)
@Query("DELETE FROM localPlaylistItem WHERE playlistId = :playlistId AND videoId = :videoId") @Query("DELETE FROM localPlaylistItem WHERE playlistId = :playlistId AND videoId = :videoId")
fun deletePlaylistItemsByVideoId(playlistId: String, videoId: String) suspend fun deletePlaylistItemsByVideoId(playlistId: String, videoId: String)
} }

View File

@ -4,16 +4,15 @@ import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.PlaylistId import com.github.libretube.api.obj.PlaylistId
import com.github.libretube.db.DatabaseHolder import com.github.libretube.db.DatabaseHolder
import com.github.libretube.enums.PlaylistType import com.github.libretube.enums.PlaylistType
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.awaitQuery
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -28,44 +27,41 @@ class DeletePlaylistDialog(
.setTitle(R.string.deletePlaylist) .setTitle(R.string.deletePlaylist)
.setMessage(R.string.areYouSure) .setMessage(R.string.areYouSure)
.setPositiveButton(R.string.yes) { _, _ -> .setPositiveButton(R.string.yes) { _, _ ->
PreferenceHelper.getToken() lifecycleScope.launch(Dispatchers.IO) {
deletePlaylist() deletePlaylist()
}
} }
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.show() .show()
} }
private fun deletePlaylist() { private suspend fun deletePlaylist() {
if (playlistType == PlaylistType.LOCAL) { if (playlistType == PlaylistType.LOCAL) {
awaitQuery { DatabaseHolder.Database.localPlaylistsDao().deletePlaylistById(playlistId)
DatabaseHolder.Database.localPlaylistsDao().deletePlaylistById(playlistId) DatabaseHolder.Database.localPlaylistsDao().deletePlaylistItemsByPlaylistId(playlistId)
DatabaseHolder.Database.localPlaylistsDao().deletePlaylistItemsByPlaylistId( withContext(Dispatchers.Main) {
playlistId onSuccess()
)
} }
onSuccess.invoke()
return return
} }
CoroutineScope(Dispatchers.IO).launch { val response = try {
val response = try { RetrofitInstance.authApi.deletePlaylist(
RetrofitInstance.authApi.deletePlaylist( PreferenceHelper.getToken(),
PreferenceHelper.getToken(), PlaylistId(playlistId)
PlaylistId(playlistId) )
) } catch (e: Exception) {
} catch (e: Exception) { Log.e(TAG(), e.toString())
Log.e(TAG(), e.toString()) return
return@launch }
} try {
try { if (response.message == "ok") {
if (response.message == "ok") { withContext(Dispatchers.Main) {
withContext(Dispatchers.Main) { onSuccess()
onSuccess.invoke()
}
} }
} catch (e: Exception) {
Log.e(TAG(), e.toString())
} }
} catch (e: Exception) {
Log.e(TAG(), e.toString())
} }
} }
} }