From a6f0e7f9b999104c0ebc51e0fdc292127801f1e5 Mon Sep 17 00:00:00 2001 From: jobobby04 Date: Thu, 16 Apr 2020 23:45:05 -0400 Subject: [PATCH] Part 2 of Auto-Migration Done (cherry picked from commit c4321e3adfff1bdfdcd8ba209dd20549348be217) --- .../data/preference/PreferencesHelper.kt | 8 + .../tachiyomi/ui/library/LibraryController.kt | 41 +++-- .../design/MigrationBottomSheetDialog.kt | 137 ++++++++++++++ .../manga/design/MigrationDesignController.kt | 160 ++++++---------- .../manga/design/MigrationSourceAdapter.kt | 6 +- .../manga/process/MigrationListController.kt | 34 ++-- .../process/MigrationProcedureAdapter.kt | 6 +- .../manga/process/MigrationProcedureConfig.kt | 4 - .../process/MigrationProcedureController.kt | 15 +- .../manga/process/MigrationProcessAdapter.kt | 13 +- .../ui/setting/SettingsGeneralController.kt | 11 ++ .../drawable/dialog_rounded_background.xml | 9 + .../res/layout/migration_bottom_sheet.xml | 164 +++++++++++++++++ .../layout/migration_design_controller.xml | 171 ++---------------- app/src/main/res/values/strings.xml | 12 +- app/src/main/res/values/styles.xml | 21 +++ 16 files changed, 481 insertions(+), 331 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationBottomSheetDialog.kt create mode 100644 app/src/main/res/drawable/dialog_rounded_background.xml create mode 100644 app/src/main/res/layout/migration_bottom_sheet.xml 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 ba1de70a0..d56c9ebf6 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -260,6 +260,14 @@ class PreferencesHelper(val context: Context) { fun skipPreMigration() = flowPrefs.getBoolean(Keys.skipPreMigration, false) + 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 a94fb0adb..46a931e9e 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 @@ -11,6 +11,8 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import android.view.WindowInsets +import android.view.WindowManager import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.view.ActionMode import androidx.appcompat.widget.SearchView @@ -36,8 +38,9 @@ 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.SearchController import eu.kanade.tachiyomi.ui.migration.manga.design.MigrationDesignController +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 @@ -484,9 +487,15 @@ class LibraryController( R.id.action_select_inverse -> selectInverseCategoryManga() 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() } else -> return false @@ -503,18 +512,6 @@ class LibraryController( return nextManga } - private fun startMangaMigration() { - migratingMangas.clear() - migratingMangas.addAll(selectedMangas) - 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() @@ -788,3 +785,15 @@ class LibraryController( const val REQUEST_IMAGE_OPEN = 101 } } + +object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener { + override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { + val topInset = insets.systemWindowInsetTop + v.setPadding(0, topInset, 0, 0) + if (v.layoutParams.height != topInset) { + v.layoutParams.height = topInset + v.requestLayout() + } + return insets + } +} 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 000000000..e993e31cc --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationBottomSheetDialog.kt @@ -0,0 +1,137 @@ +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.system.toast +import eu.kanade.tachiyomi.util.view.gone +import eu.kanade.tachiyomi.util.view.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?) +} 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 89be89b55..d749e2c3c 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 @@ -13,27 +15,18 @@ import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.online.HttpSource 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.ui.migration.manga.process.MigrationProcedureConfig -import eu.kanade.tachiyomi.util.view.gone -import eu.kanade.tachiyomi.util.view.visible -import kotlinx.android.synthetic.main.migration_design_controller.begin_migration_btn -import kotlinx.android.synthetic.main.migration_design_controller.extra_search_param -import kotlinx.android.synthetic.main.migration_design_controller.extra_search_param_desc -import kotlinx.android.synthetic.main.migration_design_controller.extra_search_param_text -import kotlinx.android.synthetic.main.migration_design_controller.fuzzy_search -import kotlinx.android.synthetic.main.migration_design_controller.mig_categories -import kotlinx.android.synthetic.main.migration_design_controller.mig_chapters -import kotlinx.android.synthetic.main.migration_design_controller.migration_mode -import kotlinx.android.synthetic.main.migration_design_controller.options_group -import kotlinx.android.synthetic.main.migration_design_controller.prioritize_chapter_count +import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets +import eu.kanade.tachiyomi.util.view.marginBottom +import eu.kanade.tachiyomi.util.view.updateLayoutParams +import eu.kanade.tachiyomi.util.view.updatePaddingRelative +import kotlinx.android.synthetic.main.migration_design_controller.fab import kotlinx.android.synthetic.main.migration_design_controller.recycler -import kotlinx.android.synthetic.main.migration_design_controller.use_smart_search 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() @@ -53,7 +46,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 @@ -63,83 +56,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) { @@ -153,14 +105,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 { it.sourceEnabled = !it.sourceEnabled @@ -176,13 +120,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.getVisibleCatalogueSources() - .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 9f771f6c5..35e253792 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 @@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.source.SourceManager import uy.kohesive.injekt.injectLazy class MigrationSourceAdapter( - val items: List, + var items: List, val controller: MigrationDesignController ) : FlexibleAdapter( items, @@ -32,6 +32,10 @@ class MigrationSourceAdapter( 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/process/MigrationListController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationListController.kt index 16ab4f351..8bd8b3c7b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationListController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/process/MigrationListController.kt @@ -16,6 +16,8 @@ import com.afollestad.materialdialogs.MaterialDialog 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.smartsearch.SmartSearchEngine import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.Source @@ -62,6 +64,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle), val config: MigrationProcedureConfig? = args.getParcelable(CONFIG_EXTRA) private val db: DatabaseHelper by injectLazy() + private val preferences: PreferencesHelper by injectLazy() private val sourceManager: SourceManager by injectLazy() private val smartSearchEngine = SmartSearchEngine(coroutineContext, config?.extraSearchParams) @@ -95,11 +98,8 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle), recycler.adapter = adapter recycler.layoutManager = LinearLayoutManager(view.context) - // recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration - // .VERTICAL)) recycler.setHasFixedSize(true) recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) - // recycler.isEnabled = false adapter?.updateDataSet(newMigratingManga.map { it.toModal() }) @@ -110,21 +110,6 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle), } } - /*fun nextMigration() { - adapter?.let { adapter -> - 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) @@ -136,8 +121,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() @@ -154,7 +144,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() @@ -162,7 +152,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) @@ -192,7 +182,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 0a4b4781c..fb9e69e70 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 @@ -8,7 +8,6 @@ import com.google.gson.Gson 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.database.models.MangaCategory import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager @@ -16,7 +15,6 @@ import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.manga.MangaController -import eu.kanade.tachiyomi.ui.migration.MigrationFlags import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.inflate import eu.kanade.tachiyomi.util.view.visible @@ -123,7 +121,7 @@ class MigrationProcedureAdapter( 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 @@ -162,7 +160,7 @@ class MigrationProcedureAdapter( // 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 d3bf84a89..1c26143d2 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 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 f31797935..92a5f7841 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 @@ -9,27 +9,16 @@ import com.afollestad.materialdialogs.MaterialDialog import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.smartsearch.SmartSearchEngine -import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.ui.base.controller.BaseController -import eu.kanade.tachiyomi.util.await -import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource import eu.kanade.tachiyomi.util.system.toast -import java.util.concurrent.atomic.AtomicInteger import kotlin.coroutines.CoroutineContext import kotlinx.android.synthetic.main.migration_process.pager -import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job -import kotlinx.coroutines.async import kotlinx.coroutines.cancel -import kotlinx.coroutines.isActive import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit -import kotlinx.coroutines.withContext -import rx.schedulers.Schedulers import uy.kohesive.injekt.injectLazy // TODO Will probably implode if activity is fully destroyed @@ -121,7 +110,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) { @@ -229,7 +218,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 11f912355..79a9635f9 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.lang.launchUI import kotlinx.coroutines.Dispatchers @@ -21,6 +23,7 @@ class MigrationProcessAdapter( private val db: DatabaseHelper by injectLazy() var items: List = emptyList() + val preferences: PreferencesHelper by injectLazy() val menuItemListener: MigrationProcessInterface = controller @@ -46,7 +49,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) { @@ -95,9 +98,9 @@ class MigrationProcessAdapter( 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 @@ -112,13 +115,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 1b0b39c84..522537566 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 @@ -16,6 +16,7 @@ import eu.kanade.tachiyomi.util.preference.onChange import eu.kanade.tachiyomi.util.preference.onClick import eu.kanade.tachiyomi.util.preference.preference import eu.kanade.tachiyomi.util.preference.preferenceCategory +import eu.kanade.tachiyomi.util.preference.summaryRes import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.system.LocaleHelper @@ -191,6 +192,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 + } + } + // --> EXH switchPreference { key = Keys.eh_expandFilters 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 000000000..7acf406ff --- /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 000000000..8c7e5f3ac --- /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 5469f761d..e7ce5509f 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"> - - - - - - - - - - - - - - - - - - - - - - - - -