Convert import helper methods to suspend functions.

This commit is contained in:
Isira Seneviratne 2023-02-03 20:51:25 +05:30
parent a5d6d8d9df
commit 3d7ef76d52
3 changed files with 71 additions and 66 deletions

View File

@ -4,6 +4,8 @@ import android.content.Context
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.widget.Toast import android.widget.Toast
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
fun Context.toastFromMainThread(text: String) { fun Context.toastFromMainThread(text: String) {
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {
@ -18,3 +20,11 @@ fun Context.toastFromMainThread(text: String) {
fun Context.toastFromMainThread(stringId: Int) { fun Context.toastFromMainThread(stringId: Int) {
toastFromMainThread(getString(stringId)) toastFromMainThread(getString(stringId))
} }
suspend fun Context.toastFromMainDispatcher(text: String) = withContext(Dispatchers.Main) {
Toast.makeText(this@toastFromMainDispatcher, text, Toast.LENGTH_SHORT).show()
}
suspend fun Context.toastFromMainDispatcher(stringId: Int) {
toastFromMainDispatcher(getString(stringId))
}

View File

@ -3,7 +3,6 @@ package com.github.libretube.helpers
import android.app.Activity import android.app.Activity
import android.net.Uri import android.net.Uri
import android.util.Log import android.util.Log
import android.widget.Toast
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.JsonHelper import com.github.libretube.api.JsonHelper
import com.github.libretube.api.PlaylistsHelper import com.github.libretube.api.PlaylistsHelper
@ -11,15 +10,11 @@ import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.SubscriptionHelper import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.db.DatabaseHolder.Companion.Database import com.github.libretube.db.DatabaseHolder.Companion.Database
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.toastFromMainThread import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.obj.ImportPlaylist import com.github.libretube.obj.ImportPlaylist
import com.github.libretube.obj.ImportPlaylistFile import com.github.libretube.obj.ImportPlaylistFile
import com.github.libretube.obj.NewPipeSubscription import com.github.libretube.obj.NewPipeSubscription
import com.github.libretube.obj.NewPipeSubscriptions import com.github.libretube.obj.NewPipeSubscriptions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream import kotlinx.serialization.json.encodeToStream
@ -29,25 +24,21 @@ object ImportHelper {
/** /**
* Import subscriptions by a file uri * Import subscriptions by a file uri
*/ */
fun importSubscriptions(activity: Activity, uri: Uri?) { suspend fun importSubscriptions(activity: Activity, uri: Uri) {
if (uri == null) return
try { try {
val applicationContext = activity.applicationContext SubscriptionHelper.importSubscriptions(getChannelsFromUri(activity, uri))
val channels = getChannelsFromUri(activity, uri) activity.toastFromMainDispatcher(R.string.importsuccess)
CoroutineScope(Dispatchers.IO).launch {
SubscriptionHelper.importSubscriptions(channels)
}.invokeOnCompletion {
applicationContext.toastFromMainThread(R.string.importsuccess)
}
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
Log.e(TAG(), e.toString()) Log.e(TAG(), e.toString())
activity.toastFromMainThread( activity.toastFromMainDispatcher(
activity.getString(R.string.unsupported_file_format) + activity.getString(R.string.unsupported_file_format) +
" (${activity.contentResolver.getType(uri)})" " (${activity.contentResolver.getType(uri)})"
) )
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG(), e.toString()) Log.e(TAG(), e.toString())
Toast.makeText(activity, e.localizedMessage, Toast.LENGTH_SHORT).show() e.localizedMessage?.let {
activity.toastFromMainDispatcher(it)
}
} }
} }
@ -82,37 +73,31 @@ object ImportHelper {
/** /**
* Write the text to the document * Write the text to the document
*/ */
@OptIn(ExperimentalSerializationApi::class) suspend fun exportSubscriptions(activity: Activity, uri: Uri) {
fun exportSubscriptions(activity: Activity, uri: Uri?) { val token = PreferenceHelper.getToken()
if (uri == null) return val subs = if (token.isNotEmpty()) {
runBlocking(Dispatchers.IO) { RetrofitInstance.authApi.subscriptions(token)
val token = PreferenceHelper.getToken() } else {
val subs = if (token.isNotEmpty()) { val subscriptions = Database.localSubscriptionDao().getAll().map { it.channelId }
RetrofitInstance.authApi.subscriptions(token) RetrofitInstance.authApi.unauthenticatedSubscriptions(subscriptions)
} else {
val subscriptions = Database.localSubscriptionDao().getAll().map { it.channelId }
RetrofitInstance.authApi.unauthenticatedSubscriptions(subscriptions)
}
val newPipeChannels = subs.map {
NewPipeSubscription(it.name, 0, "https://www.youtube.com${it.url}")
}
val newPipeSubscriptions = NewPipeSubscriptions(subscriptions = newPipeChannels)
activity.contentResolver.openOutputStream(uri)?.use {
JsonHelper.json.encodeToStream(newPipeSubscriptions, it)
}
activity.toastFromMainThread(R.string.exportsuccess)
} }
val newPipeChannels = subs.map {
NewPipeSubscription(it.name, 0, "https://www.youtube.com${it.url}")
}
val newPipeSubscriptions = NewPipeSubscriptions(subscriptions = newPipeChannels)
activity.contentResolver.openOutputStream(uri)?.use {
JsonHelper.json.encodeToStream(newPipeSubscriptions, it)
}
activity.toastFromMainDispatcher(R.string.exportsuccess)
} }
/** /**
* Import Playlists * Import Playlists
*/ */
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
fun importPlaylists(activity: Activity, uri: Uri?) { suspend fun importPlaylists(activity: Activity, uri: Uri) {
if (uri == null) return
val importPlaylists = mutableListOf<ImportPlaylist>() val importPlaylists = mutableListOf<ImportPlaylist>()
when (val fileType = activity.contentResolver.getType(uri)) { when (val fileType = activity.contentResolver.getType(uri)) {
@ -137,7 +122,7 @@ object ImportHelper {
importPlaylists.addAll(playlistFile?.playlists.orEmpty()) importPlaylists.addAll(playlistFile?.playlists.orEmpty())
} }
else -> { else -> {
activity.applicationContext.toastFromMainThread("Unsupported file type $fileType") activity.toastFromMainDispatcher("Unsupported file type $fileType")
return return
} }
} }
@ -146,15 +131,13 @@ object ImportHelper {
importPlaylists.forEach { playlist -> importPlaylists.forEach { playlist ->
playlist.videos = playlist.videos.map { it.takeLast(11) } playlist.videos = playlist.videos.map { it.takeLast(11) }
} }
CoroutineScope(Dispatchers.IO).launch { try {
try { PlaylistsHelper.importPlaylists(importPlaylists)
PlaylistsHelper.importPlaylists(importPlaylists) activity.toastFromMainDispatcher(R.string.success)
activity.applicationContext.toastFromMainThread(R.string.success) } catch (e: Exception) {
} catch (e: Exception) { Log.e(TAG(), e.toString())
Log.e(TAG(), e.toString()) e.localizedMessage?.let {
e.localizedMessage?.let { activity.toastFromMainDispatcher(it)
activity.applicationContext.toastFromMainThread(it)
}
} }
} }
} }
@ -162,18 +145,14 @@ object ImportHelper {
/** /**
* Export Playlists * Export Playlists
*/ */
fun exportPlaylists(activity: Activity, uri: Uri?) { suspend fun exportPlaylists(activity: Activity, uri: Uri) {
if (uri == null) return val playlists = PlaylistsHelper.exportPlaylists()
val playlistFile = ImportPlaylistFile("Piped", 1, playlists)
runBlocking { activity.contentResolver.openOutputStream(uri)?.use {
val playlists = PlaylistsHelper.exportPlaylists() JsonHelper.json.encodeToStream(playlistFile, it)
val playlistFile = ImportPlaylistFile("Piped", 1, playlists)
activity.contentResolver.openOutputStream(uri)?.use {
JsonHelper.json.encodeToStream(playlistFile, it)
}
activity.toastFromMainThread(R.string.exportsuccess)
} }
activity.toastFromMainDispatcher(R.string.exportsuccess)
} }
} }

View File

@ -44,20 +44,36 @@ class BackupRestoreSettings : BasePreferenceFragment() {
private val getSubscriptionsFile = registerForActivityResult( private val getSubscriptionsFile = registerForActivityResult(
ActivityResultContracts.GetContent() ActivityResultContracts.GetContent()
) { ) {
ImportHelper.importSubscriptions(requireActivity(), it) it?.let {
lifecycleScope.launch(Dispatchers.IO) {
ImportHelper.importSubscriptions(requireActivity(), it)
}
}
} }
private val createSubscriptionsFile = registerForActivityResult(CreateDocument(JSON)) { private val createSubscriptionsFile = registerForActivityResult(CreateDocument(JSON)) {
ImportHelper.exportSubscriptions(requireActivity(), it) it?.let {
lifecycleScope.launch(Dispatchers.IO) {
ImportHelper.exportSubscriptions(requireActivity(), it)
}
}
} }
/** /**
* result listeners for importing and exporting playlists * result listeners for importing and exporting playlists
*/ */
private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.GetContent()) { private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.GetContent()) {
ImportHelper.importPlaylists(requireActivity(), it) it?.let {
lifecycleScope.launch(Dispatchers.IO) {
ImportHelper.importPlaylists(requireActivity(), it)
}
}
} }
private val createPlaylistsFile = registerForActivityResult(CreateDocument(JSON)) { private val createPlaylistsFile = registerForActivityResult(CreateDocument(JSON)) {
ImportHelper.exportPlaylists(requireActivity(), it) it?.let {
lifecycleScope.launch(Dispatchers.IO) {
ImportHelper.exportPlaylists(requireActivity(), it)
}
}
} }
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {