refactor(manga): Removing runBlocking

This commit is contained in:
Ahmad Ansori Palembani 2024-12-08 07:53:06 +07:00
parent f114320123
commit 2f8ae26a83
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
5 changed files with 233 additions and 209 deletions

View file

@ -101,6 +101,7 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.getResourceDrawable import eu.kanade.tachiyomi.util.system.getResourceDrawable
import eu.kanade.tachiyomi.util.system.ignoredSystemInsets import eu.kanade.tachiyomi.util.system.ignoredSystemInsets
import eu.kanade.tachiyomi.util.system.isImeVisible import eu.kanade.tachiyomi.util.system.isImeVisible
import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.materialAlertDialog import eu.kanade.tachiyomi.util.system.materialAlertDialog
import eu.kanade.tachiyomi.util.system.openInBrowser import eu.kanade.tachiyomi.util.system.openInBrowser
@ -128,7 +129,7 @@ import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.text import eu.kanade.tachiyomi.util.view.text
import eu.kanade.tachiyomi.util.view.withFadeTransaction import eu.kanade.tachiyomi.util.view.withFadeTransaction
import eu.kanade.tachiyomi.widget.EmptyView import eu.kanade.tachiyomi.widget.EmptyView
import java.util.* import java.util.Locale
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.max import kotlin.math.max
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -2191,9 +2192,11 @@ open class LibraryController(
*/ */
private fun showChangeMangaCategoriesSheet() { private fun showChangeMangaCategoriesSheet() {
val activity = activity ?: return val activity = activity ?: return
selectedMangas.toList().moveCategories(activity) { viewScope.launchIO {
presenter.getLibrary() selectedMangas.toList().moveCategories(activity) {
destroyActionModeIfNeeded() presenter.getLibrary()
destroyActionModeIfNeeded()
}
} }
} }

View file

@ -111,12 +111,14 @@ import eu.kanade.tachiyomi.util.system.isLandscape
import eu.kanade.tachiyomi.util.system.isOnline import eu.kanade.tachiyomi.util.system.isOnline
import eu.kanade.tachiyomi.util.system.isPromptChecked import eu.kanade.tachiyomi.util.system.isPromptChecked
import eu.kanade.tachiyomi.util.system.isTablet import eu.kanade.tachiyomi.util.system.isTablet
import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.materialAlertDialog import eu.kanade.tachiyomi.util.system.materialAlertDialog
import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat
import eu.kanade.tachiyomi.util.system.setCustomTitleAndMessage import eu.kanade.tachiyomi.util.system.setCustomTitleAndMessage
import eu.kanade.tachiyomi.util.system.timeSpanFromNow import eu.kanade.tachiyomi.util.system.timeSpanFromNow
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.system.withUIContext
import eu.kanade.tachiyomi.util.view.activityBinding import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.copyToClipboard import eu.kanade.tachiyomi.util.view.copyToClipboard
import eu.kanade.tachiyomi.util.view.findChild import eu.kanade.tachiyomi.util.view.findChild
@ -1633,10 +1635,12 @@ class MangaDetailsController :
private fun showCategoriesSheet() { private fun showCategoriesSheet() {
val adding = !presenter.manga.favorite val adding = !presenter.manga.favorite
presenter.manga.moveCategories(activity!!, adding) { viewScope.launchIO {
updateHeader() presenter.manga.moveCategories(activity!!, adding) {
if (adding) { updateHeader()
showAddedSnack() if (adding) {
showAddedSnack()
}
} }
} }
} }
@ -1644,32 +1648,37 @@ class MangaDetailsController :
private fun toggleMangaFavorite() { private fun toggleMangaFavorite() {
val view = view ?: return val view = view ?: return
val activity = activity ?: return val activity = activity ?: return
snack?.dismiss() viewScope.launchIO {
snack = presenter.manga.addOrRemoveToFavorites( withUIContext { snack?.dismiss() }
presenter.preferences, snack = presenter.manga.addOrRemoveToFavorites(
view, presenter.preferences,
activity, view,
presenter.sourceManager, activity,
this, presenter.sourceManager,
onMangaAdded = { migrationInfo -> this@MangaDetailsController,
migrationInfo?.let { onMangaAdded = { migrationInfo ->
migrationInfo?.let {
presenter.fetchChapters(andTracking = true)
}
updateHeader()
showAddedSnack()
},
onMangaMoved = {
updateHeader()
presenter.fetchChapters(andTracking = true) presenter.fetchChapters(andTracking = true)
},
onMangaDeleted = {
updateHeader()
presenter.confirmDeletion()
},
scope = viewScope,
)
if (snack?.duration == Snackbar.LENGTH_INDEFINITE) {
withUIContext {
val favButton = getHeader()?.binding?.favoriteButton
(activity as? MainActivity)?.setUndoSnackBar(snack, favButton)
} }
updateHeader() }
showAddedSnack()
},
onMangaMoved = {
updateHeader()
presenter.fetchChapters(andTracking = true)
},
onMangaDeleted = {
updateHeader()
presenter.confirmDeletion()
},
)
if (snack?.duration == Snackbar.LENGTH_INDEFINITE) {
val favButton = getHeader()?.binding?.favoriteButton
(activity as? MainActivity)?.setUndoSnackBar(snack, favButton)
} }
} }

View file

@ -43,8 +43,10 @@ import eu.kanade.tachiyomi.util.addOrRemoveToFavorites
import eu.kanade.tachiyomi.util.system.connectivityManager import eu.kanade.tachiyomi.util.system.connectivityManager
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.e import eu.kanade.tachiyomi.util.system.e
import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.openInBrowser import eu.kanade.tachiyomi.util.system.openInBrowser
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.system.withUIContext
import eu.kanade.tachiyomi.util.view.activityBinding import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.applyBottomAnimatedInsets import eu.kanade.tachiyomi.util.view.applyBottomAnimatedInsets
import eu.kanade.tachiyomi.util.view.fullAppBarHeight import eu.kanade.tachiyomi.util.view.fullAppBarHeight
@ -766,22 +768,27 @@ open class BrowseSourceController(bundle: Bundle) :
val manga = (adapter?.getItem(position) as? BrowseSourceItem?)?.manga ?: return val manga = (adapter?.getItem(position) as? BrowseSourceItem?)?.manga ?: return
val view = view ?: return val view = view ?: return
val activity = activity ?: return val activity = activity ?: return
snack?.dismiss() viewScope.launchIO {
snack = manga.addOrRemoveToFavorites( withUIContext { snack?.dismiss() }
preferences, snack = manga.addOrRemoveToFavorites(
view, preferences,
activity, view,
presenter.sourceManager, activity,
this, presenter.sourceManager,
onMangaAdded = { this@BrowseSourceController,
adapter?.notifyItemChanged(position) onMangaAdded = {
snack = view.snack(MR.strings.added_to_library) adapter?.notifyItemChanged(position)
}, snack = view.snack(MR.strings.added_to_library)
onMangaMoved = { adapter?.notifyItemChanged(position) }, },
onMangaDeleted = { presenter.confirmDeletion(manga) }, onMangaMoved = { adapter?.notifyItemChanged(position) },
) onMangaDeleted = { presenter.confirmDeletion(manga) },
if (snack?.duration == Snackbar.LENGTH_INDEFINITE) { scope = viewScope,
(activity as? MainActivity)?.setUndoSnackBar(snack) )
if (snack?.duration == Snackbar.LENGTH_INDEFINITE) {
withUIContext {
(activity as? MainActivity)?.setUndoSnackBar(snack)
}
}
} }
} }

View file

@ -24,7 +24,9 @@ import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
import eu.kanade.tachiyomi.util.addOrRemoveToFavorites import eu.kanade.tachiyomi.util.addOrRemoveToFavorites
import eu.kanade.tachiyomi.util.system.extensionIntentForText import eu.kanade.tachiyomi.util.system.extensionIntentForText
import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat
import eu.kanade.tachiyomi.util.system.withUIContext
import eu.kanade.tachiyomi.util.view.activityBinding import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.isControllerVisible import eu.kanade.tachiyomi.util.view.isControllerVisible
import eu.kanade.tachiyomi.util.view.scrollViewWith import eu.kanade.tachiyomi.util.view.scrollViewWith
@ -114,34 +116,39 @@ open class GlobalSearchController(
val view = view ?: return val view = view ?: return
val activity = activity ?: return val activity = activity ?: return
snack?.dismiss() viewScope.launchIO {
snack = manga.addOrRemoveToFavorites( withUIContext { snack?.dismiss() }
preferences, snack = manga.addOrRemoveToFavorites(
view, preferences,
activity, view,
presenter.sourceManager, activity,
this, presenter.sourceManager,
onMangaAdded = { migrationInfo -> this@GlobalSearchController,
migrationInfo?.let { (source, stillFaved) -> onMangaAdded = { migrationInfo ->
val index = this.adapter migrationInfo?.let { (source, stillFaved) ->
?.currentItems?.indexOfFirst { it.source.id == source } ?: return@let val index = this@GlobalSearchController.adapter
val item = this.adapter?.getItem(index) ?: return@let ?.currentItems?.indexOfFirst { it.source.id == source } ?: return@let
val oldMangaIndex = item.results?.indexOfFirst { val item = this@GlobalSearchController.adapter?.getItem(index) ?: return@let
it.manga.title.lowercase() == manga.title.lowercase() val oldMangaIndex = item.results?.indexOfFirst {
} ?: return@let it.manga.title.lowercase() == manga.title.lowercase()
val oldMangaItem = item.results.getOrNull(oldMangaIndex) } ?: return@let
oldMangaItem?.manga?.favorite = stillFaved val oldMangaItem = item.results.getOrNull(oldMangaIndex)
val holder = binding.recycler.findViewHolderForAdapterPosition(index) as? GlobalSearchHolder oldMangaItem?.manga?.favorite = stillFaved
holder?.updateManga(oldMangaIndex) val holder = binding.recycler.findViewHolderForAdapterPosition(index) as? GlobalSearchHolder
holder?.updateManga(oldMangaIndex)
}
adapter.notifyItemChanged(position)
snack = view.snack(MR.strings.added_to_library)
},
onMangaMoved = { adapter.notifyItemChanged(position) },
onMangaDeleted = { presenter.confirmDeletion(manga) },
scope = viewScope,
)
if (snack?.duration == Snackbar.LENGTH_INDEFINITE) {
withUIContext {
(activity as? MainActivity)?.setUndoSnackBar(snack)
} }
adapter.notifyItemChanged(position) }
snack = view.snack(MR.strings.added_to_library)
},
onMangaMoved = { adapter.notifyItemChanged(position) },
onMangaDeleted = { presenter.confirmDeletion(manga) },
)
if (snack?.duration == Snackbar.LENGTH_INDEFINITE) {
(activity as? MainActivity)?.setUndoSnackBar(snack)
} }
} }

View file

@ -41,8 +41,9 @@ import eu.kanade.tachiyomi.util.view.withFadeTransaction
import eu.kanade.tachiyomi.widget.TriStateCheckBox import eu.kanade.tachiyomi.widget.TriStateCheckBox
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import yokai.domain.category.interactor.GetCategories import yokai.domain.category.interactor.GetCategories
@ -84,69 +85,69 @@ suspend fun Manga.shouldDownloadNewChapters(prefs: PreferencesHelper, getCategor
return categoriesForManga.any { it in includedCategories } return categoriesForManga.any { it in includedCategories }
} }
fun Manga.moveCategories(activity: Activity, onMangaMoved: () -> Unit) { suspend fun Manga.moveCategories(activity: Activity, onMangaMoved: () -> Unit) {
moveCategories(activity, false, onMangaMoved) moveCategories(activity, false, onMangaMoved)
} }
fun Manga.moveCategories( suspend fun Manga.moveCategories(
activity: Activity, activity: Activity,
addingToLibrary: Boolean, addingToLibrary: Boolean,
onMangaMoved: () -> Unit, onMangaMoved: () -> Unit,
) { ) {
val getCategories: GetCategories = Injekt.get() val getCategories: GetCategories = Injekt.get()
// FIXME: Don't do blocking val categories = getCategories.await()
val categories = runBlocking { getCategories.await() } val categoriesForManga = this.id?.let { mangaId -> getCategories.awaitByMangaId(mangaId) }.orEmpty()
val categoriesForManga = runBlocking {
this@moveCategories.id?.let { mangaId -> getCategories.awaitByMangaId(mangaId) }
.orEmpty()
}
val ids = categoriesForManga.mapNotNull { it.id }.toTypedArray() val ids = categoriesForManga.mapNotNull { it.id }.toTypedArray()
SetCategoriesSheet( withUIContext {
activity, SetCategoriesSheet(
this, activity,
categories.toMutableList(), this@moveCategories,
ids, categories.toMutableList(),
addingToLibrary, ids,
) { addingToLibrary,
onMangaMoved() ) {
if (addingToLibrary) { onMangaMoved()
autoAddTrack(onMangaMoved) if (addingToLibrary) {
} autoAddTrack(onMangaMoved)
}.show() }
}.show()
}
} }
fun List<Manga>.moveCategories( suspend fun List<Manga>.moveCategories(
activity: Activity, activity: Activity,
onMangaMoved: () -> Unit, onMangaMoved: () -> Unit,
) { ) {
if (this.isEmpty()) return if (this.isEmpty()) return
val getCategories: GetCategories = Injekt.get() val getCategories: GetCategories = Injekt.get()
// FIXME: Don't do blocking val categories = getCategories.await()
val categories = runBlocking { getCategories.await() }
val mangaCategories = map { manga -> val mangaCategories = map { manga ->
manga.id?.let { mangaId -> runBlocking { getCategories.awaitByMangaId(mangaId) } }.orEmpty() manga.id?.let { mangaId -> getCategories.awaitByMangaId(mangaId) }.orEmpty()
} }
val commonCategories = mangaCategories.reduce { set1, set2 -> set1.intersect(set2.toSet()).toMutableList() }.toSet() val commonCategories = mangaCategories.reduce { set1, set2 -> set1.intersect(set2.toSet()).toMutableList() }.toSet()
val mixedCategories = mangaCategories.flatten().distinct().subtract(commonCategories).toMutableList() val mixedCategories = mangaCategories.flatten().distinct().subtract(commonCategories).toMutableList()
SetCategoriesSheet(
activity, withUIContext {
this, SetCategoriesSheet(
categories.toMutableList(), activity,
categories.map { this@moveCategories,
when (it) { categories.toMutableList(),
in commonCategories -> TriStateCheckBox.State.CHECKED categories.map {
in mixedCategories -> TriStateCheckBox.State.IGNORE when (it) {
else -> TriStateCheckBox.State.UNCHECKED in commonCategories -> TriStateCheckBox.State.CHECKED
} in mixedCategories -> TriStateCheckBox.State.IGNORE
}.toTypedArray(), else -> TriStateCheckBox.State.UNCHECKED
false, }
) { }.toTypedArray(),
onMangaMoved() false,
}.show() ) {
onMangaMoved()
}.show()
}
} }
fun Manga.addOrRemoveToFavorites( suspend fun Manga.addOrRemoveToFavorites(
preferences: PreferencesHelper, preferences: PreferencesHelper,
view: View, view: View,
activity: Activity, activity: Activity,
@ -160,15 +161,12 @@ fun Manga.addOrRemoveToFavorites(
setMangaCategories: SetMangaCategories = Injekt.get(), setMangaCategories: SetMangaCategories = Injekt.get(),
getManga: GetManga = Injekt.get(), getManga: GetManga = Injekt.get(),
updateManga: UpdateManga = Injekt.get(), updateManga: UpdateManga = Injekt.get(),
@OptIn(DelicateCoroutinesApi::class)
scope: CoroutineScope = GlobalScope,
): Snackbar? { ): Snackbar? {
if (!favorite) { if (!favorite) {
if (checkForDupes) { if (checkForDupes) {
val duplicateManga = runBlocking(Dispatchers.IO) { val duplicateManga = getManga.awaitDuplicateFavorite(this.title, this.source)
getManga.awaitDuplicateFavorite(
this@addOrRemoveToFavorites.title,
this@addOrRemoveToFavorites.source,
)
}
if (duplicateManga != null) { if (duplicateManga != null) {
showAddDuplicateDialog( showAddDuplicateDialog(
this, this,
@ -187,6 +185,7 @@ fun Manga.addOrRemoveToFavorites(
onMangaAdded, onMangaAdded,
onMangaMoved, onMangaMoved,
onMangaDeleted, onMangaDeleted,
scope = scope,
) )
}, },
migrateManga = { source, faved -> migrateManga = { source, faved ->
@ -197,8 +196,7 @@ fun Manga.addOrRemoveToFavorites(
} }
} }
// FIXME: Don't do blocking val categories = getCategories.await()
val categories = runBlocking { getCategories.await() }
val defaultCategoryId = preferences.defaultCategory().get() val defaultCategoryId = preferences.defaultCategory().get()
val defaultCategory = categories.find { it.id == defaultCategoryId } val defaultCategory = categories.find { it.id == defaultCategoryId }
val lastUsedCategories = Category.lastCategoriesAddedTo.mapNotNull { catId -> val lastUsedCategories = Category.lastCategoriesAddedTo.mapNotNull { catId ->
@ -209,22 +207,23 @@ fun Manga.addOrRemoveToFavorites(
favorite = true favorite = true
date_added = Date().time date_added = Date().time
autoAddTrack(onMangaMoved) autoAddTrack(onMangaMoved)
// FIXME: Don't do blocking updateManga.await(
runBlocking { MangaUpdate(
updateManga.await( id = this@addOrRemoveToFavorites.id!!,
MangaUpdate( favorite = true,
id = this@addOrRemoveToFavorites.id!!, dateAdded = this@addOrRemoveToFavorites.date_added,
favorite = true,
dateAdded = this@addOrRemoveToFavorites.date_added,
)
) )
setMangaCategories.await(this@addOrRemoveToFavorites.id!!, listOf(defaultCategory.id!!.toLong())) )
} setMangaCategories.await(this@addOrRemoveToFavorites.id!!, listOf(defaultCategory.id!!.toLong()))
(activity as? MainActivity)?.showNotificationPermissionPrompt() (activity as? MainActivity)?.showNotificationPermissionPrompt()
onMangaMoved() onMangaMoved()
return view.snack(activity.getString(MR.strings.added_to_, defaultCategory.name)) { return withUIContext {
setAction(MR.strings.change) { view.snack(activity.getString(MR.strings.added_to_, defaultCategory.name)) {
moveCategories(activity, onMangaMoved) setAction(MR.strings.change) {
scope.launchIO {
moveCategories(activity, onMangaMoved)
}
}
} }
} }
} }
@ -235,35 +234,36 @@ fun Manga.addOrRemoveToFavorites(
favorite = true favorite = true
date_added = Date().time date_added = Date().time
autoAddTrack(onMangaMoved) autoAddTrack(onMangaMoved)
// FIXME: Don't do blocking updateManga.await(
runBlocking { MangaUpdate(
updateManga.await( id = this@addOrRemoveToFavorites.id!!,
MangaUpdate( favorite = true,
id = this@addOrRemoveToFavorites.id!!, dateAdded = this@addOrRemoveToFavorites.date_added,
favorite = true,
dateAdded = this@addOrRemoveToFavorites.date_added,
)
) )
setMangaCategories.await(this@addOrRemoveToFavorites.id!!, lastUsedCategories.map { it.id!!.toLong() }) )
} setMangaCategories.await(this@addOrRemoveToFavorites.id!!, lastUsedCategories.map { it.id!!.toLong() })
(activity as? MainActivity)?.showNotificationPermissionPrompt() (activity as? MainActivity)?.showNotificationPermissionPrompt()
onMangaMoved() onMangaMoved()
return view.snack( return withUIContext {
activity.getString( view.snack(
MR.strings.added_to_, activity.getString(
when (lastUsedCategories.size) { MR.strings.added_to_,
0 -> activity.getString(MR.strings.default_category).lowercase(Locale.ROOT) when (lastUsedCategories.size) {
1 -> lastUsedCategories.firstOrNull()?.name ?: "" 0 -> activity.getString(MR.strings.default_category).lowercase(Locale.ROOT)
else -> activity.getString( 1 -> lastUsedCategories.firstOrNull()?.name ?: ""
MR.plurals.category_plural, else -> activity.getString(
lastUsedCategories.size, MR.plurals.category_plural,
lastUsedCategories.size, lastUsedCategories.size,
) lastUsedCategories.size,
}, )
), },
) { ),
setAction(MR.strings.change) { ) {
moveCategories(activity, onMangaMoved) setAction(MR.strings.change) {
scope.launchIO {
moveCategories(activity, onMangaMoved)
}
}
} }
} }
} }
@ -271,27 +271,28 @@ fun Manga.addOrRemoveToFavorites(
favorite = true favorite = true
date_added = Date().time date_added = Date().time
autoAddTrack(onMangaMoved) autoAddTrack(onMangaMoved)
// FIXME: Don't do blocking updateManga.await(
runBlocking { MangaUpdate(
updateManga.await( id = this@addOrRemoveToFavorites.id!!,
MangaUpdate( favorite = true,
id = this@addOrRemoveToFavorites.id!!, dateAdded = this@addOrRemoveToFavorites.date_added,
favorite = true,
dateAdded = this@addOrRemoveToFavorites.date_added,
)
) )
setMangaCategories.await(this@addOrRemoveToFavorites.id!!, emptyList()) )
} setMangaCategories.await(this@addOrRemoveToFavorites.id!!, emptyList())
onMangaMoved() onMangaMoved()
(activity as? MainActivity)?.showNotificationPermissionPrompt() (activity as? MainActivity)?.showNotificationPermissionPrompt()
return if (categories.isNotEmpty()) { return withUIContext {
view.snack(activity.getString(MR.strings.added_to_, activity.getString(MR.strings.default_value))) { if (categories.isNotEmpty()) {
setAction(MR.strings.change) { view.snack(activity.getString(MR.strings.added_to_, activity.getString(MR.strings.default_value))) {
moveCategories(activity, onMangaMoved) setAction(MR.strings.change) {
scope.launchIO {
moveCategories(activity, onMangaMoved)
}
}
} }
} else {
view.snack(MR.strings.added_to_library)
} }
} else {
view.snack(MR.strings.added_to_library)
} }
} }
else -> { // Always ask else -> { // Always ask
@ -302,23 +303,19 @@ fun Manga.addOrRemoveToFavorites(
val lastAddedDate = date_added val lastAddedDate = date_added
favorite = false favorite = false
date_added = 0 date_added = 0
// FIXME: Don't do blocking updateManga.await(
runBlocking { MangaUpdate(
updateManga.await( id = this@addOrRemoveToFavorites.id!!,
MangaUpdate( favorite = false,
id = this@addOrRemoveToFavorites.id!!, dateAdded = 0,
favorite = false,
dateAdded = 0,
)
) )
} )
onMangaMoved() onMangaMoved()
return view.snack(view.context.getString(MR.strings.removed_from_library), Snackbar.LENGTH_INDEFINITE) { return view.snack(view.context.getString(MR.strings.removed_from_library), Snackbar.LENGTH_INDEFINITE) {
setAction(MR.strings.undo) { setAction(MR.strings.undo) {
favorite = true favorite = true
date_added = lastAddedDate date_added = lastAddedDate
// FIXME: Don't do blocking scope.launchIO {
runBlocking {
updateManga.await( updateManga.await(
MangaUpdate( MangaUpdate(
id = this@addOrRemoveToFavorites.id!!, id = this@addOrRemoveToFavorites.id!!,
@ -344,39 +341,40 @@ fun Manga.addOrRemoveToFavorites(
return null return null
} }
private fun Manga.showSetCategoriesSheet( private suspend fun Manga.showSetCategoriesSheet(
activity: Activity, activity: Activity,
categories: List<Category>, categories: List<Category>,
onMangaAdded: (Pair<Long, Boolean>?) -> Unit, onMangaAdded: (Pair<Long, Boolean>?) -> Unit,
onMangaMoved: () -> Unit, onMangaMoved: () -> Unit,
getCategories: GetCategories = Injekt.get(), getCategories: GetCategories = Injekt.get(),
) { ) {
// FIXME: Don't do blocking val categoriesForManga = getCategories.awaitByMangaId(this.id!!)
val categoriesForManga = runBlocking { getCategories.awaitByMangaId(this@showSetCategoriesSheet.id!!) }
val ids = categoriesForManga.mapNotNull { it.id }.toTypedArray() val ids = categoriesForManga.mapNotNull { it.id }.toTypedArray()
SetCategoriesSheet( withUIContext {
activity, SetCategoriesSheet(
this, activity,
categories.toMutableList(), this@showSetCategoriesSheet,
ids, categories.toMutableList(),
true, ids,
) { true,
(activity as? MainActivity)?.showNotificationPermissionPrompt() ) {
onMangaAdded(null) (activity as? MainActivity)?.showNotificationPermissionPrompt()
autoAddTrack(onMangaMoved) onMangaAdded(null)
}.show() autoAddTrack(onMangaMoved)
}.show()
}
} }
private fun showAddDuplicateDialog( private suspend fun showAddDuplicateDialog(
newManga: Manga, newManga: Manga,
libraryManga: Manga, libraryManga: Manga,
activity: Activity, activity: Activity,
sourceManager: SourceManager, sourceManager: SourceManager,
controller: Controller, controller: Controller,
addManga: () -> Unit, addManga: suspend () -> Unit,
migrateManga: (Long, Boolean) -> Unit, migrateManga: (Long, Boolean) -> Unit,
) { ) = withUIContext {
val source = sourceManager.getOrStub(libraryManga.source) val source = sourceManager.getOrStub(libraryManga.source)
val titles by lazy { MigrationFlags.titles(activity, libraryManga) } val titles by lazy { MigrationFlags.titles(activity, libraryManga) }
@ -415,7 +413,7 @@ private fun showAddDuplicateDialog(
MangaDetailsController(libraryManga) MangaDetailsController(libraryManga)
.withFadeTransaction(), .withFadeTransaction(),
) )
1 -> addManga() 1 -> launchIO { addManga() }
2 -> { 2 -> {
if (!newManga.initialized) { if (!newManga.initialized) {
activity.toast(MR.strings.must_view_details_before_migration, Toast.LENGTH_LONG) activity.toast(MR.strings.must_view_details_before_migration, Toast.LENGTH_LONG)