Added option to migrate manga from manga details
(cherry picked from commit 3a4780e19b79e9afcb3e830cb02c52bd1c66bddf)
This commit is contained in:
parent
f47e9b6e14
commit
18f90587f2
@ -37,10 +37,7 @@ import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.main.offsetFabAppbarHeight
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.migration.MigrationController
|
||||
import eu.kanade.tachiyomi.ui.migration.MigrationInterface
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.view.inflate
|
||||
@ -68,8 +65,7 @@ class LibraryController(
|
||||
TabbedController,
|
||||
ActionMode.Callback,
|
||||
ChangeMangaCategoriesDialog.Listener,
|
||||
DeleteLibraryMangasDialog.Listener,
|
||||
MigrationInterface {
|
||||
DeleteLibraryMangasDialog.Listener {
|
||||
|
||||
/**
|
||||
* Position of the active category.
|
||||
@ -486,16 +482,8 @@ class LibraryController(
|
||||
R.id.action_select_all -> selectAllCategoryManga()
|
||||
R.id.action_select_inverse -> selectInverseCategoryManga()
|
||||
R.id.action_migrate -> {
|
||||
router.pushController(
|
||||
if (preferences.skipPreMigration().getOrDefault()) {
|
||||
MigrationListController.create(
|
||||
MigrationProcedureConfig(
|
||||
selectedMangas.mapNotNull { it.id }, null)
|
||||
)
|
||||
} else {
|
||||
PreMigrationController.create(selectedMangas.mapNotNull { it.id })
|
||||
}
|
||||
.withFadeTransaction())
|
||||
val skipPre = preferences.skipPreMigration().getOrDefault()
|
||||
PreMigrationController.navigateToMigration(skipPre, router, selectedMangas.mapNotNull { it.id })
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
else -> return false
|
||||
@ -503,15 +491,6 @@ class LibraryController(
|
||||
return true
|
||||
}
|
||||
|
||||
override fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean): Manga? {
|
||||
if (manga.id != prevManga.id) {
|
||||
presenter.migrateManga(prevManga, manga, replace = replace)
|
||||
}
|
||||
val nextManga = migratingMangas.firstOrNull() ?: return null
|
||||
migratingMangas.remove(nextManga)
|
||||
return nextManga
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
// Clear all the manga selections and notify child views.
|
||||
selectedMangas.clear()
|
||||
|
@ -30,6 +30,10 @@ import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.recent.history.HistoryController
|
||||
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.source.SourceController
|
||||
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
@ -219,6 +223,16 @@ class MangaInfoController(private val fromSource: Boolean = false) :
|
||||
// EXH <--
|
||||
}
|
||||
|
||||
// EXH -->
|
||||
private fun openSmartSearch() {
|
||||
val smartSearchConfig = SourceController.SmartSearchConfig(presenter.manga.title, presenter.manga.id!!)
|
||||
|
||||
parentController?.router?.pushController(SourceController(Bundle().apply {
|
||||
putParcelable(SourceController.SMART_SEARCH_CONFIG, smartSearchConfig)
|
||||
}).withFadeTransaction())
|
||||
}
|
||||
// EXH <--
|
||||
|
||||
/**
|
||||
* Check if manga is initialized.
|
||||
* If true update view with manga information,
|
||||
|
@ -6,6 +6,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.bluelinelabs.conductor.Router
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
@ -151,6 +152,18 @@ class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), F
|
||||
companion object {
|
||||
private const val MANGA_IDS_EXTRA = "manga_ids"
|
||||
|
||||
fun navigateToMigration(skipPre: Boolean, router: Router, mangaIds: List<Long>) {
|
||||
router.pushController(
|
||||
if (skipPre) {
|
||||
MigrationListController.create(
|
||||
MigrationProcedureConfig(mangaIds, null)
|
||||
)
|
||||
} else {
|
||||
create(mangaIds)
|
||||
}.withFadeTransaction().tag(if (skipPre) MigrationListController.TAG else null)
|
||||
)
|
||||
}
|
||||
|
||||
fun create(mangaIds: List<Long>): PreMigrationController {
|
||||
return PreMigrationController(Bundle().apply {
|
||||
putLongArray(MANGA_IDS_EXTRA, mangaIds.toLongArray())
|
||||
|
@ -14,6 +14,7 @@ import androidx.core.graphics.ColorUtils
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
@ -26,11 +27,14 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.migration.MigrationMangaDialog
|
||||
import eu.kanade.tachiyomi.ui.migration.SearchController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.util.await
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
@ -204,8 +208,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id)
|
||||
val chapters = try {
|
||||
source.fetchChapterList(localManga)
|
||||
.toSingle().await(Schedulers.io()) }
|
||||
catch (e: java.lang.Exception) {
|
||||
.toSingle().await(Schedulers.io()) } catch (e: java.lang.Exception) {
|
||||
Timber.e(e)
|
||||
emptyList<SChapter>()
|
||||
} ?: emptyList()
|
||||
@ -372,15 +375,38 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
fun migrateMangas() {
|
||||
launchUI {
|
||||
adapter?.performMigrations(false)
|
||||
router.popCurrentController()
|
||||
navigateOut()
|
||||
}
|
||||
}
|
||||
|
||||
fun copyMangas() {
|
||||
launchUI {
|
||||
adapter?.performMigrations(true)
|
||||
navigateOut()
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateOut() {
|
||||
if (migratingManga?.size == 1) {
|
||||
launchUI {
|
||||
val hasDetails = router.backstack.any { it.controller() is MangaController }
|
||||
if (hasDetails) {
|
||||
val manga = migratingManga?.firstOrNull()?.searchResult?.get()?.let {
|
||||
db.getManga(it).executeOnIO()
|
||||
}
|
||||
if (manga != null) {
|
||||
val newStack = router.backstack.filter {
|
||||
it.controller() !is MangaController &&
|
||||
it.controller() !is MigrationListController &&
|
||||
it.controller() !is PreMigrationController
|
||||
} + MangaController(manga).withFadeTransaction()
|
||||
router.setBackstack(newStack, FadeChangeHandler())
|
||||
return@launchUI
|
||||
}
|
||||
}
|
||||
router.popCurrentController()
|
||||
}
|
||||
} else router.popCurrentController()
|
||||
}
|
||||
|
||||
override fun handleBack(): Boolean {
|
||||
@ -440,6 +466,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
|
||||
companion object {
|
||||
const val CONFIG_EXTRA = "config_extra"
|
||||
const val TAG = "migration_list"
|
||||
|
||||
fun create(config: MigrationProcedureConfig): MigrationListController {
|
||||
return MigrationListController(Bundle().apply {
|
||||
|
@ -102,8 +102,8 @@ class MigrationProcessAdapter(
|
||||
// Update chapters read
|
||||
if (MigrationFlags.hasChapters(flags)) {
|
||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||
val maxChapterRead = prevMangaChapters.filter { it.read }
|
||||
.maxBy { it.chapter_number }?.chapter_number
|
||||
val maxChapterRead =
|
||||
prevMangaChapters.filter { it.read }.maxBy { it.chapter_number }?.chapter_number
|
||||
if (maxChapterRead != null) {
|
||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
||||
for (chapter in dbChapters) {
|
||||
@ -135,8 +135,6 @@ class MigrationProcessAdapter(
|
||||
db.updateMangaFavorite(prevManga).executeAsBlocking()
|
||||
}
|
||||
manga.favorite = true
|
||||
db.updateMangaFavorite(manga).executeAsBlocking()
|
||||
|
||||
// SearchPresenter#networkToLocalManga may have updated the manga title, so ensure db gets updated title
|
||||
db.updateMangaTitle(manga).executeAsBlocking()
|
||||
// }
|
||||
|
@ -0,0 +1,24 @@
|
||||
package eu.kanade.tachiyomi.util.system
|
||||
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetObject
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutCollectionOfObjects
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutObject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
suspend fun <T> PreparedGetListOfObjects<T>.executeOnIO(): List<T> {
|
||||
return withContext(Dispatchers.IO) { executeAsBlocking() }
|
||||
}
|
||||
|
||||
suspend fun <T> PreparedGetObject<T>.executeOnIO(): T? {
|
||||
return withContext(Dispatchers.IO) { executeAsBlocking() }
|
||||
}
|
||||
|
||||
suspend fun <T> PreparedPutObject<T>.executeOnIO() {
|
||||
withContext(Dispatchers.IO) { executeAsBlocking() }
|
||||
}
|
||||
|
||||
suspend fun <T> PreparedPutCollectionOfObjects<T>.executeOnIO() {
|
||||
withContext(Dispatchers.IO) { executeAsBlocking() }
|
||||
}
|
@ -573,6 +573,7 @@
|
||||
<string name="migration_selection_prompt">Select a source to migrate from</string>
|
||||
<string name="select">Select</string>
|
||||
<string name="migrate">Migrate</string>
|
||||
<string name="migrate_">Migrate %1$s</string>
|
||||
<string name="copy">Copy</string>
|
||||
<string name="migrating">Migrating…</string>
|
||||
<string name="migration">Migration</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user