From 9607edef22c24a95c393d385dfb9e6a45d35b3e1 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 31 Jan 2023 16:12:19 +0100 Subject: [PATCH 1/4] Simplify the local playlist handling --- .../github/libretube/api/PlaylistsHelper.kt | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt index 81d100e5c6..d3e8af3dec 100644 --- a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt +++ b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt @@ -19,12 +19,12 @@ import com.github.libretube.extensions.toastFromMainThread import com.github.libretube.obj.ImportPlaylist import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.ProxyHelper -import java.io.IOException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.withContext import retrofit2.HttpException +import java.io.IOException object PlaylistsHelper { private val pipedPlaylistRegex = @@ -138,28 +138,24 @@ object PlaylistsHelper { } } - suspend fun removeFromPlaylist(playlistId: String, index: Int) { - if (!loggedIn) { + suspend fun removeFromPlaylist(playlistId: String, index: Int): Boolean { + return if (!loggedIn) { val transaction = DatabaseHolder.Database.localPlaylistsDao().getAll() .first { it.playlist.id.toString() == playlistId } DatabaseHolder.Database.localPlaylistsDao().removePlaylistVideo( transaction.videos[index] ) - if (transaction.videos.size > 1) { - if (index == 0) { - transaction.videos[1].thumbnailUrl?.let { - transaction.playlist.thumbnailUrl = it - } - DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(transaction.playlist) - } - return + // set a new playlist thumbnail if the first video got removed + if (index == 0) { + transaction.playlist.thumbnailUrl = transaction.videos.getOrNull(1)?.thumbnailUrl ?: "" } - // remove thumbnail if playlist now empty - transaction.playlist.thumbnailUrl = "" DatabaseHolder.Database.localPlaylistsDao().updatePlaylist(transaction.playlist) + true } else { - val playlist = PlaylistId(playlistId = playlistId, index = index) - RetrofitInstance.authApi.removeFromPlaylist(PreferenceHelper.getToken(), playlist) + RetrofitInstance.authApi.removeFromPlaylist( + PreferenceHelper.getToken(), + PlaylistId(playlistId = playlistId, index = index) + ).message == "ok" } } @@ -167,13 +163,8 @@ object PlaylistsHelper { for (playlist in playlists) { val playlistId = createPlaylist(playlist.name!!, appContext) ?: continue // if logged in, add the playlists by their ID via an api call - val success: Boolean = if (loggedIn) { - addToPlaylist( - playlistId, - *playlist.videos.map { - StreamItem(url = it) - }.toTypedArray() - ) + val success = if (loggedIn) { + addToPlaylist(playlistId, *playlist.videos.map { StreamItem(url = it) }.toTypedArray()) } else { // if not logged in, all video information needs to become fetched manually try { From f274dd205b382a7ae977ecef05f030fdb0a72171 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 31 Jan 2023 16:23:34 +0100 Subject: [PATCH 2/4] Fix the importing of playlists --- .../github/libretube/api/PlaylistsHelper.kt | 36 ++++++++----------- .../com/github/libretube/util/ImportHelper.kt | 8 ++++- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt index d3e8af3dec..9f87257007 100644 --- a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt +++ b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt @@ -19,12 +19,12 @@ import com.github.libretube.extensions.toastFromMainThread import com.github.libretube.obj.ImportPlaylist import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.ProxyHelper +import java.io.IOException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.withContext import retrofit2.HttpException -import java.io.IOException object PlaylistsHelper { private val pipedPlaylistRegex = @@ -68,30 +68,25 @@ object PlaylistsHelper { } } - suspend fun createPlaylist( - playlistName: String, - appContext: Context - ): String? { + suspend fun createPlaylist(playlistName: String, appContext: Context?): String? { if (!loggedIn) { val playlist = LocalPlaylist(name = playlistName, thumbnailUrl = "") DatabaseHolder.Database.localPlaylistsDao().createPlaylist(playlist) return DatabaseHolder.Database.localPlaylistsDao().getAll() .last().playlist.id.toString() } else { - val response = try { + return try { RetrofitInstance.authApi.createPlaylist(token, Playlists(name = playlistName)) } catch (e: IOException) { - appContext.toastFromMainThread(R.string.unknown_error) + appContext?.toastFromMainThread(R.string.unknown_error) return null } catch (e: HttpException) { Log.e(TAG(), e.toString()) - appContext.toastFromMainThread(R.string.server_error) + appContext?.toastFromMainThread(R.string.server_error) return null + }.playlistId.also { + appContext?.toastFromMainThread(R.string.playlistCreated) } - if (response.playlistId != null) { - appContext.toastFromMainThread(R.string.playlistCreated) - } - return response.playlistId } } @@ -159,26 +154,23 @@ object PlaylistsHelper { } } - suspend fun importPlaylists(appContext: Context, playlists: List) { + suspend fun importPlaylists(playlists: List) { for (playlist in playlists) { - val playlistId = createPlaylist(playlist.name!!, appContext) ?: continue + val playlistId = createPlaylist(playlist.name!!, null) ?: continue // if logged in, add the playlists by their ID via an api call - val success = if (loggedIn) { - addToPlaylist(playlistId, *playlist.videos.map { StreamItem(url = it) }.toTypedArray()) + if (loggedIn) { + addToPlaylist(playlistId, *playlist.videos.map { + StreamItem(url = it) + }.toTypedArray()) } else { // if not logged in, all video information needs to become fetched manually - try { + runCatching { val streamItems = playlist.videos.map { RetrofitInstance.api.getStreams(it).toStreamItem(it) } addToPlaylist(playlistId, *streamItems.toTypedArray()) - } catch (e: Exception) { - false } } - appContext.toastFromMainThread( - if (success) R.string.importsuccess else R.string.server_error - ) } } diff --git a/app/src/main/java/com/github/libretube/util/ImportHelper.kt b/app/src/main/java/com/github/libretube/util/ImportHelper.kt index 3163f341f2..7855e18a29 100644 --- a/app/src/main/java/com/github/libretube/util/ImportHelper.kt +++ b/app/src/main/java/com/github/libretube/util/ImportHelper.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.encodeToStream import okio.use @@ -109,6 +110,7 @@ class ImportHelper( /** * Import Playlists */ + @OptIn(ExperimentalSerializationApi::class) fun importPlaylists(uri: Uri?) { if (uri == null) return @@ -141,9 +143,13 @@ class ImportHelper( } } + // convert the YouTube URLs to videoIds + importPlaylists.forEach { playlist -> + playlist.videos = playlist.videos.map { it.takeLast(11) } + } CoroutineScope(Dispatchers.IO).launch { try { - PlaylistsHelper.importPlaylists(activity, importPlaylists) + PlaylistsHelper.importPlaylists(importPlaylists) activity.applicationContext.toastFromMainThread(R.string.success) } catch (e: Exception) { Log.e(TAG(), e.toString()) From a096247c9409335ce255ddb73f4df8f2d0c5a518 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 31 Jan 2023 16:29:13 +0100 Subject: [PATCH 3/4] Import playlists asynchronously --- .../github/libretube/api/PlaylistsHelper.kt | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt index 9f87257007..f4e2cabc9a 100644 --- a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt +++ b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt @@ -19,6 +19,7 @@ import com.github.libretube.extensions.toastFromMainThread import com.github.libretube.obj.ImportPlaylist import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.ProxyHelper +import gen._base._base_java__assetres.srcjar.R.id.async import java.io.IOException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -154,24 +155,29 @@ object PlaylistsHelper { } } - suspend fun importPlaylists(playlists: List) { - for (playlist in playlists) { - val playlistId = createPlaylist(playlist.name!!, null) ?: continue - // if logged in, add the playlists by their ID via an api call - if (loggedIn) { - addToPlaylist(playlistId, *playlist.videos.map { - StreamItem(url = it) - }.toTypedArray()) - } else { - // if not logged in, all video information needs to become fetched manually - runCatching { - val streamItems = playlist.videos.map { - RetrofitInstance.api.getStreams(it).toStreamItem(it) + suspend fun importPlaylists(playlists: List) = withContext(Dispatchers.IO) { + playlists.map { playlist -> + async { + val playlistId = createPlaylist(playlist.name!!, null) ?: return@async + // if logged in, add the playlists by their ID via an api call + if (loggedIn) { + addToPlaylist( + playlistId, + *playlist.videos.map { + StreamItem(url = it) + }.toTypedArray() + ) + } else { + // if not logged in, all video information needs to become fetched manually + runCatching { + val streamItems = playlist.videos.map { + async { RetrofitInstance.api.getStreams(it).toStreamItem(it) } + }.awaitAll() + addToPlaylist(playlistId, *streamItems.toTypedArray()) } - addToPlaylist(playlistId, *streamItems.toTypedArray()) } } - } + }.awaitAll() } suspend fun exportPlaylists(): List = withContext(Dispatchers.IO) { From 296ca42a196620f7ca7c201969b5bb2e53084a28 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 31 Jan 2023 16:35:00 +0100 Subject: [PATCH 4/4] Fix playlist importing issues --- .../com/github/libretube/api/PlaylistsHelper.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt index f4e2cabc9a..e5e5db44f9 100644 --- a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt +++ b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt @@ -157,8 +157,9 @@ object PlaylistsHelper { suspend fun importPlaylists(playlists: List) = withContext(Dispatchers.IO) { playlists.map { playlist -> + val playlistId = createPlaylist(playlist.name!!, null) async { - val playlistId = createPlaylist(playlist.name!!, null) ?: return@async + playlistId ?: return@async // if logged in, add the playlists by their ID via an api call if (loggedIn) { addToPlaylist( @@ -171,8 +172,17 @@ object PlaylistsHelper { // if not logged in, all video information needs to become fetched manually runCatching { val streamItems = playlist.videos.map { - async { RetrofitInstance.api.getStreams(it).toStreamItem(it) } - }.awaitAll() + async { + try { + RetrofitInstance.api.getStreams(it).toStreamItem(it) + } catch (e: Exception) { + null + } + } + } + .awaitAll() + .filterNotNull() + addToPlaylist(playlistId, *streamItems.toTypedArray()) } }