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 48d41f693..035a01eb9 100644 --- a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt +++ b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt @@ -6,17 +6,21 @@ import com.github.libretube.R import com.github.libretube.api.obj.Playlist import com.github.libretube.api.obj.PlaylistId import com.github.libretube.api.obj.Playlists +import com.github.libretube.constants.YOUTUBE_FRONTEND_URL import com.github.libretube.db.DatabaseHolder import com.github.libretube.db.obj.LocalPlaylist import com.github.libretube.enums.PlaylistType import com.github.libretube.extensions.TAG import com.github.libretube.extensions.awaitQuery +import com.github.libretube.extensions.toID import com.github.libretube.extensions.toLocalPlaylistItem import com.github.libretube.extensions.toStreamItem 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 kotlinx.coroutines.async +import kotlinx.coroutines.runBlocking import retrofit2.HttpException import java.io.IOException @@ -47,9 +51,9 @@ object PlaylistsHelper { return playlists } - suspend fun getPlaylist(playlistType: PlaylistType, playlistId: String): Playlist { + suspend fun getPlaylist(playlistId: String): Playlist { // load locally stored playlists with the auth api - return when (playlistType) { + return when (getPlaylistType()) { PlaylistType.PRIVATE -> RetrofitInstance.authApi.getPlaylist(playlistId) PlaylistType.PUBLIC -> RetrofitInstance.api.getPlaylist(playlistId) PlaylistType.LOCAL -> { @@ -66,7 +70,10 @@ object PlaylistsHelper { } } - suspend fun createPlaylist(playlistName: String, appContext: Context, onSuccess: () -> Unit) { + suspend fun createPlaylist( + playlistName: String, + appContext: Context + ): String? { if (!loggedIn()) { awaitQuery { DatabaseHolder.Database.localPlaylistsDao().createPlaylist( @@ -76,8 +83,9 @@ object PlaylistsHelper { ) ) } - onSuccess.invoke() - return + return awaitQuery { + DatabaseHolder.Database.localPlaylistsDao().getAll() + }.last().playlist.id.toString() } val response = try { RetrofitInstance.authApi.createPlaylist( @@ -86,18 +94,17 @@ object PlaylistsHelper { ) } catch (e: IOException) { appContext.toastFromMainThread(R.string.unknown_error) - return + return null } catch (e: HttpException) { Log.e(TAG(), e.toString()) appContext.toastFromMainThread(R.string.server_error) - return + return null } if (response.playlistId != null) { appContext.toastFromMainThread(R.string.playlistCreated) - onSuccess.invoke() - } else { - appContext.toastFromMainThread(R.string.unknown_error) + return response.playlistId!! } + return null } suspend fun addToPlaylist(playlistId: String, videoId: String): Boolean { @@ -176,19 +183,51 @@ object PlaylistsHelper { ) } - suspend fun importPlaylists(playlist: List) { - + suspend fun importPlaylists(appContext: Context, playlists: List) { + for (playlist in playlists) { + val playlistId = createPlaylist(playlist.name!!, appContext) ?: continue + runBlocking { + val tasks = playlist.videos.map { videoId -> + async { addToPlaylist(playlistId, videoId.substringAfter("=")) } + } + tasks.forEach { + it.await() + } + } + } } suspend fun exportPlaylists(): List { - + val playlists = getPlaylists() + val importLists = mutableListOf() + runBlocking { + val tasks = playlists.map { + async { + val list = getPlaylist(it.id!!) + importLists.add( + ImportPlaylist( + name = list.name, + type = "playlist", + visibility = "private", + videos = list.relatedStreams.orEmpty().map { + YOUTUBE_FRONTEND_URL + it.url!!.toID() + } + ) + ) + } + } + tasks.forEach { + it.await() + } + } + return importLists } - fun getPrivateType(): PlaylistType { + fun getPlaylistType(): PlaylistType { return if (loggedIn()) PlaylistType.PRIVATE else PlaylistType.LOCAL } - fun getPrivateType(playlistId: String): PlaylistType { + fun getPlaylistType(playlistId: String): PlaylistType { if (playlistId.all { it.isDigit() }) return PlaylistType.LOCAL if (playlistId.matches(pipedPlaylistRegex)) return PlaylistType.PRIVATE return PlaylistType.PUBLIC diff --git a/app/src/main/java/com/github/libretube/ui/fragments/HomeFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/HomeFragment.kt index 9417f44a7..f872acfeb 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/HomeFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/HomeFragment.kt @@ -108,7 +108,7 @@ class HomeFragment : BaseFragment() { runOnUiThread { makeVisible(binding.playlistsRV, binding.playlistsTV) binding.playlistsRV.layoutManager = LinearLayoutManager(context) - binding.playlistsRV.adapter = PlaylistsAdapter(playlists.toMutableList(), PlaylistsHelper.getPrivateType()) + binding.playlistsRV.adapter = PlaylistsAdapter(playlists.toMutableList(), PlaylistsHelper.getPlaylistType()) binding.playlistsRV.adapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) { diff --git a/app/src/main/java/com/github/libretube/ui/fragments/LibraryFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/LibraryFragment.kt index a38494316..ee8bce5ea 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/LibraryFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/LibraryFragment.kt @@ -123,7 +123,7 @@ class LibraryFragment : BaseFragment() { val playlistsAdapter = PlaylistsAdapter( playlists.toMutableList(), - PlaylistsHelper.getPrivateType() + PlaylistsHelper.getPlaylistType() ) // listen for playlists to become deleted diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt index 591a873b3..3ab9b72e2 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt @@ -99,7 +99,7 @@ class PlaylistFragment : BaseFragment() { binding.playlistScrollview.visibility = View.GONE lifecycleScope.launchWhenCreated { val response = try { - PlaylistsHelper.getPlaylist(playlistType, playlistId!!) + PlaylistsHelper.getPlaylist(playlistId!!) } catch (e: IOException) { println(e) Log.e(TAG(), "IOException, you might not have internet connection") diff --git a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt index e6171bb5b..530ce68f2 100644 --- a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt +++ b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt @@ -110,8 +110,8 @@ object PlayingQueue { fun insertPlaylist(playlistId: String, newCurrentStream: StreamItem) { CoroutineScope(Dispatchers.IO).launch { try { - val playlistType = PlaylistsHelper.getPrivateType(playlistId) - val playlist = PlaylistsHelper.getPlaylist(playlistType, playlistId) + val playlistType = PlaylistsHelper.getPlaylistType(playlistId) + val playlist = PlaylistsHelper.getPlaylist(playlistId) add( *playlist.relatedStreams .orEmpty() diff --git a/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt b/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt index 7d5e9b801..d1fb9e742 100644 --- a/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt +++ b/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt @@ -82,12 +82,9 @@ class NotificationWorker(appContext: Context, parameters: WorkerParameters) : var success = true runBlocking { - val task = async { - SubscriptionHelper.getFeed() - } // fetch the users feed val videoFeed = try { - task.await() + SubscriptionHelper.getFeed() } catch (e: Exception) { success = false return@runBlocking