Added option to migrate manga from manga details

(cherry picked from commit 3a4780e19b79e9afcb3e830cb02c52bd1c66bddf)
This commit is contained in:
jobobby04 2020-04-17 13:23:44 -04:00 committed by Jobobby04
parent f47e9b6e14
commit 18f90587f2
7 changed files with 88 additions and 32 deletions

View File

@ -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()

View File

@ -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,

View File

@ -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())

View File

@ -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,17 +375,40 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
fun migrateMangas() {
launchUI {
adapter?.performMigrations(false)
router.popCurrentController()
navigateOut()
}
}
fun copyMangas() {
launchUI {
adapter?.performMigrations(true)
router.popCurrentController()
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 {
activity?.let {
MaterialDialog.Builder(it).title(R.string.stop_migration)
@ -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 {

View File

@ -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()
// }

View File

@ -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() }
}

View File

@ -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>