Part 2 of Auto-Migration Done
(cherry picked from commit c4321e3adfff1bdfdcd8ba209dd20549348be217)
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+137
@@ -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<PreferencesHelper>()
|
||||
|
||||
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<Boolean>) {
|
||||
isChecked = pref.getOrDefault()
|
||||
setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a radio group with a boolean preference.
|
||||
*/
|
||||
private fun RadioGroup.bindToPreference(pref: Preference<Boolean>) {
|
||||
(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?)
|
||||
}
|
||||
+58
-102
@@ -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<ViewGroup.MarginLayoutParams> {
|
||||
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<FrameLayout>(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<HttpSource> {
|
||||
val languages = prefs.enabledLanguages().getOrDefault()
|
||||
val hiddenCatalogues = prefs.hiddenCatalogues().getOrDefault()
|
||||
val sourcesSaved = prefs.migrationSources().getOrDefault().split("/")
|
||||
var sources = sourceManager.getCatalogueSources()
|
||||
.filterIsInstance<HttpSource>()
|
||||
.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<HttpSource>()
|
||||
.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 {
|
||||
|
||||
+5
-1
@@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class MigrationSourceAdapter(
|
||||
val items: List<MigrationSourceItem>,
|
||||
var items: List<MigrationSourceItem>,
|
||||
val controller: MigrationDesignController
|
||||
) : FlexibleAdapter<MigrationSourceItem>(
|
||||
items,
|
||||
@@ -32,6 +32,10 @@ class MigrationSourceAdapter(
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
}
|
||||
|
||||
fun updateItems() {
|
||||
items = currentItems
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SELECTED_SOURCES_KEY = "selected_sources"
|
||||
}
|
||||
|
||||
+12
-22
@@ -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<MigratingManga>) {
|
||||
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)
|
||||
|
||||
+2
-4
@@ -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) {
|
||||
|
||||
-4
@@ -6,9 +6,5 @@ import kotlinx.android.parcel.Parcelize
|
||||
@Parcelize
|
||||
data class MigrationProcedureConfig(
|
||||
var mangaIds: List<Long>,
|
||||
val targetSourceIds: List<Long>,
|
||||
val useSourceWithMostChapters: Boolean,
|
||||
val enableLenientSearch: Boolean,
|
||||
val migrationFlags: Int,
|
||||
val extraSearchParams: String?
|
||||
) : Parcelable
|
||||
|
||||
+2
-13
@@ -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<MigratingManga>) {
|
||||
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() {
|
||||
|
||||
+8
-5
@@ -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<MigrationProcessItem> = 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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user