diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index 0b63390243..00793d4050 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -127,6 +127,8 @@ object PreferenceKeys { const val removeArticles = "remove_articles" + const val skipPreMigration = "skip_pre_migration" + @Deprecated("Use the preferences of the source") fun sourceUsername(sourceId: Long) = "pref_source_username_$sourceId" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index ad6758d0b0..cc81e18ab9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.data.preference import android.content.Context import android.net.Uri import android.os.Environment -import android.preference.PreferenceManager +import androidx.preference.PreferenceManager import com.f2prateek.rx.preferences.Preference import com.f2prateek.rx.preferences.RxSharedPreferences import eu.kanade.tachiyomi.R @@ -190,6 +190,14 @@ class PreferencesHelper(val context: Context) { fun trustedSignatures() = rxPrefs.getStringSet("trusted_signatures", emptySet()) + fun migrationSources() = rxPrefs.getString("migrate_sources", "") + + fun smartMigration() = rxPrefs.getBoolean("smart_migrate", false) + + fun useSourceWithMost() = rxPrefs.getBoolean("use_source_with_most", false) + + fun skipPreMigration() = rxPrefs.getBoolean(Keys.skipPreMigration, false) + fun upgradeFilters() { val filterDl = rxPrefs.getBoolean(Keys.filterDownloaded, false).getOrDefault() val filterUn = rxPrefs.getBoolean(Keys.filterUnread, false).getOrDefault() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 600b2223c0..8e348437aa 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -46,6 +46,7 @@ import eu.kanade.tachiyomi.ui.migration.MigrationController import eu.kanade.tachiyomi.ui.migration.MigrationInterface import eu.kanade.tachiyomi.ui.migration.SearchController import eu.kanade.tachiyomi.ui.migration.manga.design.MigrationDesignController +import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController import eu.kanade.tachiyomi.util.doOnApplyWindowInsets import eu.kanade.tachiyomi.util.inflate import eu.kanade.tachiyomi.util.marginBottom @@ -53,6 +54,7 @@ import eu.kanade.tachiyomi.util.marginTop import eu.kanade.tachiyomi.util.snack import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.updatePaddingRelative +import exh.ui.migration.manga.process.MigrationProcedureConfig import kotlinx.android.synthetic.main.library_controller.* import kotlinx.android.synthetic.main.main_activity.* import rx.Subscription @@ -470,11 +472,18 @@ class LibraryController( } R.id.action_migrate -> { router.pushController( - MigrationDesignController.create( - selectedMangas.mapNotNull { it.id } - ).withFadeTransaction()) + if (preferences.skipPreMigration().getOrDefault()) { + MigrationListController.create( + MigrationProcedureConfig( + selectedMangas.mapNotNull { it.id },null) + ) + } + else { + MigrationDesignController.create( selectedMangas.mapNotNull { it.id } ) + } + .withFadeTransaction()) destroyActionModeIfNeeded() - } //startMangaMigration() + } R.id.action_hide_title -> { val showAll = (selectedMangas.filter { (it as? LibraryManga)?.hide_title == true } ).size == selectedMangas.size @@ -494,18 +503,7 @@ class LibraryController( migratingMangas.remove(nextManga) return nextManga } - - private fun startMangaMigration() { - migratingMangas = selectedMangas.distinctBy { it.id }.toMutableSet() - destroyActionModeIfNeeded() - val manga = migratingMangas.firstOrNull() ?: return - val searchController = SearchController(manga) - searchController.totalProgress = migratingMangas.size - searchController.targetController = this - router.pushController(searchController.withFadeTransaction()) - migratingMangas.remove(manga) - } - + override fun onDestroyActionMode(mode: ActionMode?) { // Clear all the manga selections and notify child views. selectedMangas.clear() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MetadataFetchDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MetadataFetchDialog.kt index db85772272..5d231561ae 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MetadataFetchDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MetadataFetchDialog.kt @@ -6,7 +6,6 @@ import android.text.Html import com.afollestad.materialdialogs.MaterialDialog import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.SourceManager import timber.log.Timber import uy.kohesive.injekt.injectLazy @@ -18,8 +17,6 @@ class MetadataFetchDialog { val sourceManager: SourceManager by injectLazy() - val preferenceHelper: PreferencesHelper by injectLazy() - fun show(context: Activity) { //Too lazy to actually deal with orientation changes context.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt index e99663cda3..94b7d714b3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt @@ -11,14 +11,18 @@ import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.migration.manga.design.MigrationDesignController +import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.util.await import eu.kanade.tachiyomi.util.launchUI +import exh.ui.migration.manga.process.MigrationProcedureConfig import kotlinx.android.synthetic.main.migration_controller.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -137,7 +141,14 @@ class MigrationController : NucleusController(), Schedulers.io()) val sourceMangas = manga.asSequence().filter { it.source == item.source.id }.map { it.id!! }.toList() withContext(Dispatchers.Main) { - router.pushController(MigrationDesignController.create(sourceMangas).withFadeTransaction()) + router.pushController( + if (Injekt.get().skipPreMigration().getOrDefault()) { + MigrationListController.create( + MigrationProcedureConfig( sourceMangas, null) + ) + } + else { MigrationDesignController.create(sourceMangas) } + .withFadeTransaction()) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationBottomSheetDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationBottomSheetDialog.kt new file mode 100644 index 0000000000..57a07f973c --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationBottomSheetDialog.kt @@ -0,0 +1,136 @@ +package eu.kanade.tachiyomi.ui.migration.manga.design + +import android.app.Activity +import android.content.res.Configuration +import android.os.Bundle +import android.widget.CompoundButton +import android.widget.LinearLayout +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.Toast +import com.bluelinelabs.conductor.Controller +import com.f2prateek.rx.preferences.Preference +import com.google.android.material.bottomsheet.BottomSheetDialog +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.ui.migration.MigrationFlags +import eu.kanade.tachiyomi.util.gone +import eu.kanade.tachiyomi.util.toast +import eu.kanade.tachiyomi.util.visible +import kotlinx.android.synthetic.main.migration_bottom_sheet.* +import kotlinx.android.synthetic.main.migration_bottom_sheet.extra_search_param +import kotlinx.android.synthetic.main.migration_bottom_sheet.extra_search_param_text +import kotlinx.android.synthetic.main.migration_bottom_sheet.mig_categories +import kotlinx.android.synthetic.main.migration_bottom_sheet.mig_chapters +import kotlinx.android.synthetic.main.migration_bottom_sheet.mig_tracking +import kotlinx.android.synthetic.main.migration_bottom_sheet.use_smart_search +import uy.kohesive.injekt.injectLazy + +class MigrationBottomSheetDialog(activity: Activity, theme: Int, private val listener: +StartMigrationListener) : + BottomSheetDialog(activity, + theme) { + /** + * Preferences helper. + */ + private val preferences by injectLazy() + + init { + // Use activity theme for this layout + val view = activity.layoutInflater.inflate(R.layout.migration_bottom_sheet, null) + //val scroll = NestedScrollView(context) + // scroll.addView(view) + + setContentView(view) + if (activity.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) + sourceGroup.orientation = LinearLayout.HORIZONTAL + window?.setBackgroundDrawable(null) + } + + /** + * Called when the sheet is created. It initializes the listeners and values of the preferences. + */ + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + initPreferences() + + fab.setOnClickListener { + preferences.skipPreMigration().set(skip_step.isChecked) + listener.startMigration( + if (use_smart_search.isChecked && extra_search_param_text.text.isNotBlank()) + extra_search_param_text.text.toString() else null) + dismiss() + } + } + + /** + * Init general reader preferences. + */ + private fun initPreferences() { + val flags = preferences.migrateFlags().getOrDefault() + + mig_chapters.isChecked = MigrationFlags.hasChapters(flags) + mig_categories.isChecked = MigrationFlags.hasCategories(flags) + mig_tracking.isChecked = MigrationFlags.hasTracks(flags) + + mig_chapters.setOnCheckedChangeListener { _, _ -> setFlags() } + mig_categories.setOnCheckedChangeListener { _, _ -> setFlags() } + mig_tracking.setOnCheckedChangeListener { _, _ -> setFlags() } + + use_smart_search.bindToPreference(preferences.smartMigration()) + extra_search_param_text.gone() + extra_search_param.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + extra_search_param_text.visible() + } else { + extra_search_param_text.gone() + } + } + sourceGroup.bindToPreference(preferences.useSourceWithMost()) + + skip_step.isChecked = preferences.skipPreMigration().getOrDefault() + skip_step.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) + (listener as? Controller)?.activity?.toast(R.string.pre_migration_skip_toast, + Toast.LENGTH_LONG) + } + } + + private fun setFlags() { + var flags = 0 + if(mig_chapters.isChecked) flags = flags or MigrationFlags.CHAPTERS + if(mig_categories.isChecked) flags = flags or MigrationFlags.CATEGORIES + if(mig_categories.isChecked) flags = flags or MigrationFlags.TRACK + preferences.migrateFlags().set(flags) + } + + /** + * Binds a checkbox or switch view with a boolean preference. + */ + private fun CompoundButton.bindToPreference(pref: Preference) { + isChecked = pref.getOrDefault() + setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) } + } + + /** + * Binds a radio group with a boolean preference. + */ + private fun RadioGroup.bindToPreference(pref: Preference) { + (getChildAt(pref.getOrDefault().toInt()) as RadioButton).isChecked = true + setOnCheckedChangeListener { _, value -> + val index = indexOfChild(findViewById(value)) + pref.set(index == 1) + } + } + + private fun Boolean.toInt() = if (this) 1 else 0 + + + +} + +interface StartMigrationListener { + fun startMigration(extraParam:String?) +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationDesignController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationDesignController.kt index 15363dcd08..ddf9171a11 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationDesignController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationDesignController.kt @@ -4,7 +4,9 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout import androidx.recyclerview.widget.LinearLayoutManager +import com.google.android.material.bottomsheet.BottomSheetBehavior import eu.davidea.flexibleadapter.FlexibleAdapter import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper @@ -15,14 +17,22 @@ import eu.kanade.tachiyomi.ui.base.controller.BaseController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.migration.MigrationFlags import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController +import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener +import eu.kanade.tachiyomi.util.doOnApplyWindowInsets import eu.kanade.tachiyomi.util.gone +import eu.kanade.tachiyomi.util.marginBottom +import eu.kanade.tachiyomi.util.updateLayoutParams +import eu.kanade.tachiyomi.util.updatePaddingRelative import eu.kanade.tachiyomi.util.visible import exh.ui.migration.manga.process.MigrationProcedureConfig +import kotlinx.android.synthetic.main.chapters_controller.* import kotlinx.android.synthetic.main.migration_design_controller.* +import kotlinx.android.synthetic.main.migration_design_controller.fab +import kotlinx.android.synthetic.main.migration_design_controller.recycler import uy.kohesive.injekt.injectLazy class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle), FlexibleAdapter -.OnItemClickListener { +.OnItemClickListener, StartMigrationListener { private val sourceManager: SourceManager by injectLazy() private val prefs: PreferencesHelper by injectLazy() @@ -42,7 +52,7 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle) super.onViewCreated(view) val ourAdapter = adapter ?: MigrationSourceAdapter( - getEnabledSources().map { MigrationSourceItem(it, true) }, + getEnabledSources().map { MigrationSourceItem(it, isEnabled(it.id.toString())) }, this ) adapter = ourAdapter @@ -52,83 +62,42 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle) ourAdapter.itemTouchHelperCallback = null // Reset adapter touch adapter to fix drag after rotation ourAdapter.isHandleDragEnabled = true - migration_mode.setOnClickListener { - prioritize_chapter_count.toggle() - } + val fabBaseMarginBottom = fab?.marginBottom ?: 0 + recycler.doOnApplyWindowInsets { v, insets, padding -> - fuzzy_search.setOnClickListener { - use_smart_search.toggle() - } - - extra_search_param_desc.setOnClickListener { - extra_search_param.toggle() - } - - prioritize_chapter_count.setOnCheckedChangeListener { _, b -> - updatePrioritizeChapterCount(b) - } - - extra_search_param.setOnCheckedChangeListener { _, b -> - updateOptionsState() - } - - updatePrioritizeChapterCount(prioritize_chapter_count.isChecked) - - updateOptionsState() - - begin_migration_btn.setOnClickListener { - if(!showingOptions) { - showingOptions = true - updateOptionsState() - return@setOnClickListener + fab?.updateLayoutParams { + bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom } + // offset the recycler by the fab's inset + some inset on top + v.updatePaddingRelative(bottom = padding.bottom + (fab?.marginBottom ?: 0) + + fabBaseMarginBottom + (fab?.height ?: 0)) + } - var flags = 0 - if(mig_chapters.isChecked) flags = flags or MigrationFlags.CHAPTERS - if(mig_categories.isChecked) flags = flags or MigrationFlags.CATEGORIES - if(mig_categories.isChecked) flags = flags or MigrationFlags.TRACK + fab.setOnClickListener { + val dialog = MigrationBottomSheetDialog(activity!!, R.style.SheetDialog, this) + dialog.show() + val bottomSheet = + dialog.findViewById(com.google.android.material.R.id + .design_bottom_sheet) + val behavior: BottomSheetBehavior<*> = BottomSheetBehavior.from(bottomSheet) + behavior.state = BottomSheetBehavior.STATE_EXPANDED + behavior.skipCollapsed = true + } + } - router.replaceTopController( - MigrationListController.create( - MigrationProcedureConfig( - config.toList(), - ourAdapter.items.filter { - it.sourceEnabled - }.map { it.source.id }, - useSourceWithMostChapters = prioritize_chapter_count.isChecked, - enableLenientSearch = use_smart_search.isChecked, - migrationFlags = flags, - extraSearchParams = if(extra_search_param.isChecked && extra_search_param_text.text.isNotBlank()) { - extra_search_param_text.text.toString() - } else null - ) + override fun startMigration(extraParam:String?) { + val listOfSources = adapter?.items?.filter { + it.sourceEnabled + }?.joinToString("/") { it.source.id.toString() } + prefs.migrationSources().set(listOfSources) + + router.replaceTopController( + MigrationListController.create( + MigrationProcedureConfig( + config.toList(), + extraSearchParams = extraParam + ) ).withFadeTransaction()) - } - } - - fun updateOptionsState() { - if (showingOptions) { - begin_migration_btn.text = "Begin migration" - options_group.visible() - if(extra_search_param.isChecked) { - extra_search_param_text.visible() - } else { - extra_search_param_text.gone() - } - } else { - begin_migration_btn.text = "Next step" - options_group.gone() - extra_search_param_text.gone() - } - } - - override fun handleBack(): Boolean { - if(showingOptions) { - showingOptions = false - updateOptionsState() - return true - } - return super.handleBack() } override fun onSaveInstanceState(outState: Bundle) { @@ -142,13 +111,6 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle) adapter?.onRestoreInstanceState(savedInstanceState) } - private fun updatePrioritizeChapterCount(migrationMode: Boolean) { - migration_mode.text = if(migrationMode) { - "Currently using the source with the most chapters and the above list to break ties (slow with many sources or smart search)" - } else { - "Currently using the first source in the list that has the manga" - } - } override fun onItemClick(view: View, position: Int): Boolean { adapter?.getItem(position)?.let { @@ -165,13 +127,25 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle) */ private fun getEnabledSources(): List { val languages = prefs.enabledLanguages().getOrDefault() - val hiddenCatalogues = prefs.hiddenCatalogues().getOrDefault() + val sourcesSaved = prefs.migrationSources().getOrDefault().split("/") + var sources = sourceManager.getCatalogueSources() + .filterIsInstance() + .filter { it.lang in languages } + .sortedBy { "(${it.lang}) ${it.name}" } + sources = + sources.filter { isEnabled(it.id.toString()) }.sortedBy { sourcesSaved.indexOf(it.id + .toString() ) + } + + sources.filterNot { isEnabled(it.id.toString()) } - return sourceManager.getCatalogueSources() - .filterIsInstance() - .filter { it.lang in languages } - .filterNot { it.id.toString() in hiddenCatalogues } - .sortedBy { "(${it.lang}) ${it.name}" } + return sources + } + + fun isEnabled(id:String): Boolean { + val sourcesSaved = prefs.migrationSources().getOrDefault() + val hiddenCatalogues = prefs.hiddenCatalogues().getOrDefault() + return if (sourcesSaved.isEmpty()) id !in hiddenCatalogues + else sourcesSaved.split("/").contains(id) } companion object { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceAdapter.kt index 6d01c6aa15..12807fe1d0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceAdapter.kt @@ -5,7 +5,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter import eu.kanade.tachiyomi.source.SourceManager import uy.kohesive.injekt.injectLazy -class MigrationSourceAdapter(val items: List, +class MigrationSourceAdapter(var items: List, val controller: MigrationDesignController ): FlexibleAdapter( items, @@ -31,6 +31,10 @@ class MigrationSourceAdapter(val items: List, super.onRestoreInstanceState(savedInstanceState) } + fun updateItems() { + items = currentItems + } + companion object { private const val SELECTED_SOURCES_KEY = "selected_sources" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt index 209291dd3f..e26bd29623 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt @@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.util.getRound import kotlinx.android.synthetic.main.migration_source_item.* -class MigrationSourceHolder(view: View, val adapter: FlexibleAdapter): +class MigrationSourceHolder(view: View, val adapter: MigrationSourceAdapter): BaseFlexibleViewHolder(view, adapter) { init { setDragHandleView(reorder) @@ -34,6 +34,16 @@ class MigrationSourceHolder(view: View, val adapter: FlexibleAdapter - if(pager.currentItem >= adapter.count - 1) { - applicationContext?.toast("All migrations complete!") - router.popCurrentController() - } else { - adapter.migratingManga[pager.currentItem].migrationJob.cancel() - pager.setCurrentItem(pager.currentItem + 1, true) - launch(Dispatchers.Main) { - updateTitle() - } - } - } - }*/ - fun migrationFailure() { activity?.let { MaterialDialog.Builder(it) @@ -138,8 +123,13 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle), } suspend fun runMigrations(mangas: List) { - val sources = config?.targetSourceIds?.mapNotNull { sourceManager.get(it) as? CatalogueSource } ?: return + val useSourceWithMost = preferences.useSourceWithMost().getOrDefault() + val useSmartSearch = preferences.smartMigration().getOrDefault() + val sources = preferences.migrationSources().getOrDefault().split("/").mapNotNull { + val value = it.toLongOrNull() ?: return + sourceManager.get(value) as? CatalogueSource } + if (config == null) return for(manga in mangas) { if(!manga.searchResult.initialized && manga.migrationJob.isActive) { val mangaObj = manga.manga() @@ -156,7 +146,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle), val validSources = sources.filter { it.id != mangaSource.id } - if(config.useSourceWithMostChapters) { + if(useSourceWithMost) { val sourceSemaphore = Semaphore(3) val processedSources = AtomicInteger() @@ -164,7 +154,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle), async { sourceSemaphore.withPermit { try { - val searchResult = if (config.enableLenientSearch) { + val searchResult = if (useSmartSearch) { smartSearchEngine.smartSearch(source, mangaObj.title) } else { smartSearchEngine.normalSearch(source, mangaObj.title) @@ -194,7 +184,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle), } else { validSources.forEachIndexed { index, source -> val searchResult = try { - val searchResult = if (config.enableLenientSearch) { + val searchResult = if (useSmartSearch) { smartSearchEngine.smartSearch(source, mangaObj.title) } else { smartSearchEngine.normalSearch(source, mangaObj.title) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureAdapter.kt index 08df43f241..996f116981 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureAdapter.kt @@ -100,7 +100,7 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController, val config = controller.config ?: return //db.inTransaction { // Update chapters read - if (MigrationFlags.hasChapters(controller.config.migrationFlags)) { + /* if (MigrationFlags.hasChapters(controller.config.migrationFlags)) { val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking() val maxChapterRead = prevMangaChapters.filter { it.read } .maxBy { it.chapter_number }?.chapter_number @@ -139,7 +139,7 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController, // SearchPresenter#networkToLocalManga may have updated the manga title, so ensure db gets updated title db.updateMangaTitle(manga).executeAsBlocking() - //} + //}*/ } fun View.setupView(tag: ViewTag, migratingManga: MigratingManga) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureConfig.kt index f5235c06a5..a088b2f376 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureConfig.kt @@ -6,9 +6,5 @@ import kotlinx.android.parcel.Parcelize @Parcelize data class MigrationProcedureConfig( var mangaIds: List, - val targetSourceIds: List, - val useSourceWithMostChapters: Boolean, - val enableLenientSearch: Boolean, - val migrationFlags: Int, val extraSearchParams: String? ): Parcelable \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureController.kt index eed24715bb..34f264da8d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcedureController.kt @@ -123,7 +123,7 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseController(bund } suspend fun runMigrations(mangas: List) { - val sources = config?.targetSourceIds?.mapNotNull { sourceManager.get(it) as? + /* val sources = config?.targetSourceIds?.mapNotNull { sourceManager.get(it) as? CatalogueSource } ?: return for(manga in mangas) { @@ -231,7 +231,7 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseController(bund manga.searchResult.initialize(result?.id) } - } + }*/ } override fun onDestroy() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcessAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcessAdapter.kt index fae8e1c3f3..d362cec4ac 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcessAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationProcessAdapter.kt @@ -6,6 +6,8 @@ import eu.davidea.flexibleadapter.FlexibleAdapter import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.MangaCategory +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.migration.MigrationFlags import eu.kanade.tachiyomi.util.launchUI import kotlinx.coroutines.Dispatchers @@ -22,6 +24,7 @@ class MigrationProcessAdapter( private val db: DatabaseHelper by injectLazy() var items: List = emptyList() + val preferences:PreferencesHelper by injectLazy() val menuItemListener: MigrationProcessInterface = controller @@ -47,7 +50,7 @@ class MigrationProcessAdapter( .searchResult.content != null }) fun mangasSkipped() = (items.count { (!it.manga.searchResult.initialized || it.manga - .searchResult.content == null) && !it.manga.migrationJob.isActive }) + .searchResult.content == null) }) suspend fun performMigrations(copy: Boolean) { withContext(Dispatchers.IO) { @@ -94,9 +97,9 @@ class MigrationProcessAdapter( manga: Manga, replace: Boolean) { if (controller.config == null) return - //db.inTransaction { + val flags = preferences.migrateFlags().getOrDefault() // Update chapters read - if (MigrationFlags.hasChapters(controller.config.migrationFlags)) { + if (MigrationFlags.hasChapters(flags)) { val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking() val maxChapterRead = prevMangaChapters.filter { it.read } .maxBy { it.chapter_number }?.chapter_number @@ -111,13 +114,13 @@ class MigrationProcessAdapter( } } // Update categories - if (MigrationFlags.hasCategories(controller.config.migrationFlags)) { + if (MigrationFlags.hasCategories(flags)) { val categories = db.getCategoriesForManga(prevManga).executeAsBlocking() val mangaCategories = categories.map { MangaCategory.create(manga, it) } db.setMangaCategories(mangaCategories, listOf(manga)) } // Update track - if (MigrationFlags.hasTracks(controller.config.migrationFlags)) { + if (MigrationFlags.hasTracks(flags)) { val tracks = db.getTracks(prevManga).executeAsBlocking() for (track in tracks) { track.id = null diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt index 840f05596f..34f8006799 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt @@ -200,6 +200,16 @@ class SettingsGeneralController : SettingsController() { } } + if (preferences.skipPreMigration().getOrDefault() || preferences.migrationSources() + .getOrDefault().isNotEmpty()) { + switchPreference { + key = Keys.skipPreMigration + titleRes = R.string.pref_skip_pre_migration + summaryRes = R.string.pref_skip_pre_migration_summary + defaultValue = false + } + } + switchPreference { key = Keys.removeArticles titleRes = R.string.pref_remove_articles diff --git a/app/src/main/res/drawable/dialog_rounded_background.xml b/app/src/main/res/drawable/dialog_rounded_background.xml new file mode 100644 index 0000000000..3a54d1729a --- /dev/null +++ b/app/src/main/res/drawable/dialog_rounded_background.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/migration_bottom_sheet.xml b/app/src/main/res/layout/migration_bottom_sheet.xml new file mode 100644 index 0000000000..0efe8abe40 --- /dev/null +++ b/app/src/main/res/layout/migration_bottom_sheet.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/migration_design_controller.xml b/app/src/main/res/layout/migration_design_controller.xml index a97ce39e90..23834a74f3 100644 --- a/app/src/main/res/layout/migration_design_controller.xml +++ b/app/src/main/res/layout/migration_design_controller.xml @@ -2,6 +2,7 @@ @@ -10,174 +11,24 @@ android:id="@+id/recycler" android:layout_width="0dp" android:layout_height="0dp" - android:layout_marginBottom="8dp" - app:layout_constraintBottom_toTopOf="@+id/textView2" + android:clipToPadding="false" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:listitem="@layout/migration_source_item"> - - - - - - - - - - - - - - - - - - - - - - - - -