mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Added option to migrate manga from manga details
(cherry picked from commit 3a4780e19b79e9afcb3e830cb02c52bd1c66bddf)
This commit is contained in:
		| @@ -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,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 { | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user