Part 2 of Auto-Migration Done
This commit is contained in:
parent
e10caecc9a
commit
c4321e3adf
20 changed files with 487 additions and 308 deletions
|
@ -127,6 +127,8 @@ object PreferenceKeys {
|
||||||
|
|
||||||
const val removeArticles = "remove_articles"
|
const val removeArticles = "remove_articles"
|
||||||
|
|
||||||
|
const val skipPreMigration = "skip_pre_migration"
|
||||||
|
|
||||||
@Deprecated("Use the preferences of the source")
|
@Deprecated("Use the preferences of the source")
|
||||||
fun sourceUsername(sourceId: Long) = "pref_source_username_$sourceId"
|
fun sourceUsername(sourceId: Long) = "pref_source_username_$sourceId"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.data.preference
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.f2prateek.rx.preferences.Preference
|
import com.f2prateek.rx.preferences.Preference
|
||||||
import com.f2prateek.rx.preferences.RxSharedPreferences
|
import com.f2prateek.rx.preferences.RxSharedPreferences
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
@ -190,6 +190,14 @@ class PreferencesHelper(val context: Context) {
|
||||||
|
|
||||||
fun trustedSignatures() = rxPrefs.getStringSet("trusted_signatures", emptySet())
|
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() {
|
fun upgradeFilters() {
|
||||||
val filterDl = rxPrefs.getBoolean(Keys.filterDownloaded, false).getOrDefault()
|
val filterDl = rxPrefs.getBoolean(Keys.filterDownloaded, false).getOrDefault()
|
||||||
val filterUn = rxPrefs.getBoolean(Keys.filterUnread, false).getOrDefault()
|
val filterUn = rxPrefs.getBoolean(Keys.filterUnread, false).getOrDefault()
|
||||||
|
|
|
@ -46,6 +46,7 @@ import eu.kanade.tachiyomi.ui.migration.MigrationController
|
||||||
import eu.kanade.tachiyomi.ui.migration.MigrationInterface
|
import eu.kanade.tachiyomi.ui.migration.MigrationInterface
|
||||||
import eu.kanade.tachiyomi.ui.migration.SearchController
|
import eu.kanade.tachiyomi.ui.migration.SearchController
|
||||||
import eu.kanade.tachiyomi.ui.migration.manga.design.MigrationDesignController
|
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.doOnApplyWindowInsets
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
import eu.kanade.tachiyomi.util.inflate
|
||||||
import eu.kanade.tachiyomi.util.marginBottom
|
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.snack
|
||||||
import eu.kanade.tachiyomi.util.toast
|
import eu.kanade.tachiyomi.util.toast
|
||||||
import eu.kanade.tachiyomi.util.updatePaddingRelative
|
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.library_controller.*
|
||||||
import kotlinx.android.synthetic.main.main_activity.*
|
import kotlinx.android.synthetic.main.main_activity.*
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
|
@ -470,11 +472,18 @@ class LibraryController(
|
||||||
}
|
}
|
||||||
R.id.action_migrate -> {
|
R.id.action_migrate -> {
|
||||||
router.pushController(
|
router.pushController(
|
||||||
MigrationDesignController.create(
|
if (preferences.skipPreMigration().getOrDefault()) {
|
||||||
selectedMangas.mapNotNull { it.id }
|
MigrationListController.create(
|
||||||
).withFadeTransaction())
|
MigrationProcedureConfig(
|
||||||
|
selectedMangas.mapNotNull { it.id },null)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MigrationDesignController.create( selectedMangas.mapNotNull { it.id } )
|
||||||
|
}
|
||||||
|
.withFadeTransaction())
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
} //startMangaMigration()
|
}
|
||||||
R.id.action_hide_title -> {
|
R.id.action_hide_title -> {
|
||||||
val showAll = (selectedMangas.filter { (it as? LibraryManga)?.hide_title == true }
|
val showAll = (selectedMangas.filter { (it as? LibraryManga)?.hide_title == true }
|
||||||
).size == selectedMangas.size
|
).size == selectedMangas.size
|
||||||
|
@ -495,17 +504,6 @@ class LibraryController(
|
||||||
return 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?) {
|
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||||
// Clear all the manga selections and notify child views.
|
// Clear all the manga selections and notify child views.
|
||||||
selectedMangas.clear()
|
selectedMangas.clear()
|
||||||
|
|
|
@ -6,7 +6,6 @@ import android.text.Html
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
@ -18,8 +17,6 @@ class MetadataFetchDialog {
|
||||||
|
|
||||||
val sourceManager: SourceManager by injectLazy()
|
val sourceManager: SourceManager by injectLazy()
|
||||||
|
|
||||||
val preferenceHelper: PreferencesHelper by injectLazy()
|
|
||||||
|
|
||||||
fun show(context: Activity) {
|
fun show(context: Activity) {
|
||||||
//Too lazy to actually deal with orientation changes
|
//Too lazy to actually deal with orientation changes
|
||||||
context.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
context.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
||||||
|
|
|
@ -11,14 +11,18 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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.DialogController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag
|
import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.migration.manga.design.MigrationDesignController
|
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.RecyclerWindowInsetsListener
|
||||||
import eu.kanade.tachiyomi.util.await
|
import eu.kanade.tachiyomi.util.await
|
||||||
import eu.kanade.tachiyomi.util.launchUI
|
import eu.kanade.tachiyomi.util.launchUI
|
||||||
|
import exh.ui.migration.manga.process.MigrationProcedureConfig
|
||||||
import kotlinx.android.synthetic.main.migration_controller.*
|
import kotlinx.android.synthetic.main.migration_controller.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -137,7 +141,14 @@ class MigrationController : NucleusController<MigrationPresenter>(),
|
||||||
Schedulers.io())
|
Schedulers.io())
|
||||||
val sourceMangas = manga.asSequence().filter { it.source == item.source.id }.map { it.id!! }.toList()
|
val sourceMangas = manga.asSequence().filter { it.source == item.source.id }.map { it.id!! }.toList()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
router.pushController(MigrationDesignController.create(sourceMangas).withFadeTransaction())
|
router.pushController(
|
||||||
|
if (Injekt.get<PreferencesHelper>().skipPreMigration().getOrDefault()) {
|
||||||
|
MigrationListController.create(
|
||||||
|
MigrationProcedureConfig( sourceMangas, null)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else { MigrationDesignController.create(sourceMangas) }
|
||||||
|
.withFadeTransaction())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<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?)
|
||||||
|
}
|
|
@ -4,7 +4,9 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
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.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.migration.MigrationFlags
|
import eu.kanade.tachiyomi.ui.migration.MigrationFlags
|
||||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
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.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 eu.kanade.tachiyomi.util.visible
|
||||||
import exh.ui.migration.manga.process.MigrationProcedureConfig
|
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.*
|
||||||
|
import kotlinx.android.synthetic.main.migration_design_controller.fab
|
||||||
|
import kotlinx.android.synthetic.main.migration_design_controller.recycler
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle), FlexibleAdapter
|
class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle), FlexibleAdapter
|
||||||
.OnItemClickListener {
|
.OnItemClickListener, StartMigrationListener {
|
||||||
private val sourceManager: SourceManager by injectLazy()
|
private val sourceManager: SourceManager by injectLazy()
|
||||||
private val prefs: PreferencesHelper by injectLazy()
|
private val prefs: PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
|
@ -42,7 +52,7 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle)
|
||||||
super.onViewCreated(view)
|
super.onViewCreated(view)
|
||||||
|
|
||||||
val ourAdapter = adapter ?: MigrationSourceAdapter(
|
val ourAdapter = adapter ?: MigrationSourceAdapter(
|
||||||
getEnabledSources().map { MigrationSourceItem(it, true) },
|
getEnabledSources().map { MigrationSourceItem(it, isEnabled(it.id.toString())) },
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
adapter = ourAdapter
|
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.itemTouchHelperCallback = null // Reset adapter touch adapter to fix drag after rotation
|
||||||
ourAdapter.isHandleDragEnabled = true
|
ourAdapter.isHandleDragEnabled = true
|
||||||
|
|
||||||
migration_mode.setOnClickListener {
|
val fabBaseMarginBottom = fab?.marginBottom ?: 0
|
||||||
prioritize_chapter_count.toggle()
|
recycler.doOnApplyWindowInsets { v, insets, padding ->
|
||||||
}
|
|
||||||
|
|
||||||
fuzzy_search.setOnClickListener {
|
fab?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
use_smart_search.toggle()
|
bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
// 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
|
fab.setOnClickListener {
|
||||||
if(mig_chapters.isChecked) flags = flags or MigrationFlags.CHAPTERS
|
val dialog = MigrationBottomSheetDialog(activity!!, R.style.SheetDialog, this)
|
||||||
if(mig_categories.isChecked) flags = flags or MigrationFlags.CATEGORIES
|
dialog.show()
|
||||||
if(mig_categories.isChecked) flags = flags or MigrationFlags.TRACK
|
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(
|
override fun startMigration(extraParam:String?) {
|
||||||
MigrationListController.create(
|
val listOfSources = adapter?.items?.filter {
|
||||||
MigrationProcedureConfig(
|
it.sourceEnabled
|
||||||
config.toList(),
|
}?.joinToString("/") { it.source.id.toString() }
|
||||||
ourAdapter.items.filter {
|
prefs.migrationSources().set(listOfSources)
|
||||||
it.sourceEnabled
|
|
||||||
}.map { it.source.id },
|
router.replaceTopController(
|
||||||
useSourceWithMostChapters = prioritize_chapter_count.isChecked,
|
MigrationListController.create(
|
||||||
enableLenientSearch = use_smart_search.isChecked,
|
MigrationProcedureConfig(
|
||||||
migrationFlags = flags,
|
config.toList(),
|
||||||
extraSearchParams = if(extra_search_param.isChecked && extra_search_param_text.text.isNotBlank()) {
|
extraSearchParams = extraParam
|
||||||
extra_search_param_text.text.toString()
|
)
|
||||||
} else null
|
|
||||||
)
|
|
||||||
).withFadeTransaction())
|
).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) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
@ -142,13 +111,6 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle)
|
||||||
adapter?.onRestoreInstanceState(savedInstanceState)
|
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 {
|
override fun onItemClick(view: View, position: Int): Boolean {
|
||||||
adapter?.getItem(position)?.let {
|
adapter?.getItem(position)?.let {
|
||||||
|
@ -165,13 +127,25 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseController(bundle)
|
||||||
*/
|
*/
|
||||||
private fun getEnabledSources(): List<HttpSource> {
|
private fun getEnabledSources(): List<HttpSource> {
|
||||||
val languages = prefs.enabledLanguages().getOrDefault()
|
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.getCatalogueSources()
|
return sources
|
||||||
.filterIsInstance<HttpSource>()
|
}
|
||||||
.filter { it.lang in languages }
|
|
||||||
.filterNot { it.id.toString() in hiddenCatalogues }
|
fun isEnabled(id:String): Boolean {
|
||||||
.sortedBy { "(${it.lang}) ${it.name}" }
|
val sourcesSaved = prefs.migrationSources().getOrDefault()
|
||||||
|
val hiddenCatalogues = prefs.hiddenCatalogues().getOrDefault()
|
||||||
|
return if (sourcesSaved.isEmpty()) id !in hiddenCatalogues
|
||||||
|
else sourcesSaved.split("/").contains(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class MigrationSourceAdapter(val items: List<MigrationSourceItem>,
|
class MigrationSourceAdapter(var items: List<MigrationSourceItem>,
|
||||||
val controller: MigrationDesignController
|
val controller: MigrationDesignController
|
||||||
): FlexibleAdapter<MigrationSourceItem>(
|
): FlexibleAdapter<MigrationSourceItem>(
|
||||||
items,
|
items,
|
||||||
|
@ -31,6 +31,10 @@ class MigrationSourceAdapter(val items: List<MigrationSourceItem>,
|
||||||
super.onRestoreInstanceState(savedInstanceState)
|
super.onRestoreInstanceState(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateItems() {
|
||||||
|
items = currentItems
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val SELECTED_SOURCES_KEY = "selected_sources"
|
private const val SELECTED_SOURCES_KEY = "selected_sources"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.util.getRound
|
import eu.kanade.tachiyomi.util.getRound
|
||||||
import kotlinx.android.synthetic.main.migration_source_item.*
|
import kotlinx.android.synthetic.main.migration_source_item.*
|
||||||
|
|
||||||
class MigrationSourceHolder(view: View, val adapter: FlexibleAdapter<MigrationSourceItem>):
|
class MigrationSourceHolder(view: View, val adapter: MigrationSourceAdapter):
|
||||||
BaseFlexibleViewHolder(view, adapter) {
|
BaseFlexibleViewHolder(view, adapter) {
|
||||||
init {
|
init {
|
||||||
setDragHandleView(reorder)
|
setDragHandleView(reorder)
|
||||||
|
@ -34,6 +34,16 @@ class MigrationSourceHolder(view: View, val adapter: FlexibleAdapter<MigrationSo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an item is released.
|
||||||
|
*
|
||||||
|
* @param position The position of the released item.
|
||||||
|
*/
|
||||||
|
override fun onItemReleased(position: Int) {
|
||||||
|
super.onItemReleased(position)
|
||||||
|
adapter.updateItems()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DISABLED_ALPHA = 0.3f
|
private const val DISABLED_ALPHA = 0.3f
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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.smartsearch.SmartSearchEngine
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
@ -64,6 +66,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||||
val config: MigrationProcedureConfig? = args.getParcelable(CONFIG_EXTRA)
|
val config: MigrationProcedureConfig? = args.getParcelable(CONFIG_EXTRA)
|
||||||
|
|
||||||
private val db: DatabaseHelper by injectLazy()
|
private val db: DatabaseHelper by injectLazy()
|
||||||
|
private val preferences: PreferencesHelper by injectLazy()
|
||||||
private val sourceManager: SourceManager by injectLazy()
|
private val sourceManager: SourceManager by injectLazy()
|
||||||
|
|
||||||
private val smartSearchEngine = SmartSearchEngine(coroutineContext, config?.extraSearchParams)
|
private val smartSearchEngine = SmartSearchEngine(coroutineContext, config?.extraSearchParams)
|
||||||
|
@ -97,11 +100,8 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||||
|
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
recycler.layoutManager = LinearLayoutManager(view.context)
|
recycler.layoutManager = LinearLayoutManager(view.context)
|
||||||
//recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration
|
|
||||||
// .VERTICAL))
|
|
||||||
recycler.setHasFixedSize(true)
|
recycler.setHasFixedSize(true)
|
||||||
recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
||||||
//recycler.isEnabled = false
|
|
||||||
|
|
||||||
adapter?.updateDataSet(newMigratingManga.map { it.toModal() } )
|
adapter?.updateDataSet(newMigratingManga.map { it.toModal() } )
|
||||||
|
|
||||||
|
@ -112,21 +112,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() {
|
fun migrationFailure() {
|
||||||
activity?.let {
|
activity?.let {
|
||||||
MaterialDialog.Builder(it)
|
MaterialDialog.Builder(it)
|
||||||
|
@ -138,8 +123,13 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun runMigrations(mangas: List<MigratingManga>) {
|
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) {
|
for(manga in mangas) {
|
||||||
if(!manga.searchResult.initialized && manga.migrationJob.isActive) {
|
if(!manga.searchResult.initialized && manga.migrationJob.isActive) {
|
||||||
val mangaObj = manga.manga()
|
val mangaObj = manga.manga()
|
||||||
|
@ -156,7 +146,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||||
val validSources = sources.filter {
|
val validSources = sources.filter {
|
||||||
it.id != mangaSource.id
|
it.id != mangaSource.id
|
||||||
}
|
}
|
||||||
if(config.useSourceWithMostChapters) {
|
if(useSourceWithMost) {
|
||||||
val sourceSemaphore = Semaphore(3)
|
val sourceSemaphore = Semaphore(3)
|
||||||
val processedSources = AtomicInteger()
|
val processedSources = AtomicInteger()
|
||||||
|
|
||||||
|
@ -164,7 +154,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||||
async {
|
async {
|
||||||
sourceSemaphore.withPermit {
|
sourceSemaphore.withPermit {
|
||||||
try {
|
try {
|
||||||
val searchResult = if (config.enableLenientSearch) {
|
val searchResult = if (useSmartSearch) {
|
||||||
smartSearchEngine.smartSearch(source, mangaObj.title)
|
smartSearchEngine.smartSearch(source, mangaObj.title)
|
||||||
} else {
|
} else {
|
||||||
smartSearchEngine.normalSearch(source, mangaObj.title)
|
smartSearchEngine.normalSearch(source, mangaObj.title)
|
||||||
|
@ -194,7 +184,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||||
} else {
|
} else {
|
||||||
validSources.forEachIndexed { index, source ->
|
validSources.forEachIndexed { index, source ->
|
||||||
val searchResult = try {
|
val searchResult = try {
|
||||||
val searchResult = if (config.enableLenientSearch) {
|
val searchResult = if (useSmartSearch) {
|
||||||
smartSearchEngine.smartSearch(source, mangaObj.title)
|
smartSearchEngine.smartSearch(source, mangaObj.title)
|
||||||
} else {
|
} else {
|
||||||
smartSearchEngine.normalSearch(source, mangaObj.title)
|
smartSearchEngine.normalSearch(source, mangaObj.title)
|
||||||
|
|
|
@ -100,7 +100,7 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController,
|
||||||
val config = controller.config ?: return
|
val config = controller.config ?: return
|
||||||
//db.inTransaction {
|
//db.inTransaction {
|
||||||
// Update chapters read
|
// Update chapters read
|
||||||
if (MigrationFlags.hasChapters(controller.config.migrationFlags)) {
|
/* if (MigrationFlags.hasChapters(controller.config.migrationFlags)) {
|
||||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||||
val maxChapterRead = prevMangaChapters.filter { it.read }
|
val maxChapterRead = prevMangaChapters.filter { it.read }
|
||||||
.maxBy { it.chapter_number }?.chapter_number
|
.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
|
// SearchPresenter#networkToLocalManga may have updated the manga title, so ensure db gets updated title
|
||||||
db.updateMangaTitle(manga).executeAsBlocking()
|
db.updateMangaTitle(manga).executeAsBlocking()
|
||||||
//}
|
//}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fun View.setupView(tag: ViewTag, migratingManga: MigratingManga) {
|
fun View.setupView(tag: ViewTag, migratingManga: MigratingManga) {
|
||||||
|
|
|
@ -6,9 +6,5 @@ import kotlinx.android.parcel.Parcelize
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class MigrationProcedureConfig(
|
data class MigrationProcedureConfig(
|
||||||
var mangaIds: List<Long>,
|
var mangaIds: List<Long>,
|
||||||
val targetSourceIds: List<Long>,
|
|
||||||
val useSourceWithMostChapters: Boolean,
|
|
||||||
val enableLenientSearch: Boolean,
|
|
||||||
val migrationFlags: Int,
|
|
||||||
val extraSearchParams: String?
|
val extraSearchParams: String?
|
||||||
): Parcelable
|
): Parcelable
|
|
@ -123,7 +123,7 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseController(bund
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun runMigrations(mangas: List<MigratingManga>) {
|
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
|
CatalogueSource } ?: return
|
||||||
|
|
||||||
for(manga in mangas) {
|
for(manga in mangas) {
|
||||||
|
@ -231,7 +231,7 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseController(bund
|
||||||
|
|
||||||
manga.searchResult.initialize(result?.id)
|
manga.searchResult.initialize(result?.id)
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
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.ui.migration.MigrationFlags
|
||||||
import eu.kanade.tachiyomi.util.launchUI
|
import eu.kanade.tachiyomi.util.launchUI
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -22,6 +24,7 @@ class MigrationProcessAdapter(
|
||||||
|
|
||||||
private val db: DatabaseHelper by injectLazy()
|
private val db: DatabaseHelper by injectLazy()
|
||||||
var items: List<MigrationProcessItem> = emptyList()
|
var items: List<MigrationProcessItem> = emptyList()
|
||||||
|
val preferences:PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
val menuItemListener: MigrationProcessInterface = controller
|
val menuItemListener: MigrationProcessInterface = controller
|
||||||
|
|
||||||
|
@ -47,7 +50,7 @@ class MigrationProcessAdapter(
|
||||||
.searchResult.content != null })
|
.searchResult.content != null })
|
||||||
|
|
||||||
fun mangasSkipped() = (items.count { (!it.manga.searchResult.initialized || it.manga
|
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) {
|
suspend fun performMigrations(copy: Boolean) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
|
@ -94,9 +97,9 @@ class MigrationProcessAdapter(
|
||||||
manga: Manga,
|
manga: Manga,
|
||||||
replace: Boolean) {
|
replace: Boolean) {
|
||||||
if (controller.config == null) return
|
if (controller.config == null) return
|
||||||
//db.inTransaction {
|
val flags = preferences.migrateFlags().getOrDefault()
|
||||||
// Update chapters read
|
// Update chapters read
|
||||||
if (MigrationFlags.hasChapters(controller.config.migrationFlags)) {
|
if (MigrationFlags.hasChapters(flags)) {
|
||||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||||
val maxChapterRead = prevMangaChapters.filter { it.read }
|
val maxChapterRead = prevMangaChapters.filter { it.read }
|
||||||
.maxBy { it.chapter_number }?.chapter_number
|
.maxBy { it.chapter_number }?.chapter_number
|
||||||
|
@ -111,13 +114,13 @@ class MigrationProcessAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update categories
|
// Update categories
|
||||||
if (MigrationFlags.hasCategories(controller.config.migrationFlags)) {
|
if (MigrationFlags.hasCategories(flags)) {
|
||||||
val categories = db.getCategoriesForManga(prevManga).executeAsBlocking()
|
val categories = db.getCategoriesForManga(prevManga).executeAsBlocking()
|
||||||
val mangaCategories = categories.map { MangaCategory.create(manga, it) }
|
val mangaCategories = categories.map { MangaCategory.create(manga, it) }
|
||||||
db.setMangaCategories(mangaCategories, listOf(manga))
|
db.setMangaCategories(mangaCategories, listOf(manga))
|
||||||
}
|
}
|
||||||
// Update track
|
// Update track
|
||||||
if (MigrationFlags.hasTracks(controller.config.migrationFlags)) {
|
if (MigrationFlags.hasTracks(flags)) {
|
||||||
val tracks = db.getTracks(prevManga).executeAsBlocking()
|
val tracks = db.getTracks(prevManga).executeAsBlocking()
|
||||||
for (track in tracks) {
|
for (track in tracks) {
|
||||||
track.id = null
|
track.id = null
|
||||||
|
|
|
@ -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 {
|
switchPreference {
|
||||||
key = Keys.removeArticles
|
key = Keys.removeArticles
|
||||||
titleRes = R.string.pref_remove_articles
|
titleRes = R.string.pref_remove_articles
|
||||||
|
|
9
app/src/main/res/drawable/dialog_rounded_background.xml
Normal file
9
app/src/main/res/drawable/dialog_rounded_background.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle" >
|
||||||
|
|
||||||
|
<solid android:color="@color/cardBackground" />
|
||||||
|
|
||||||
|
<corners android:radius="10dip" />
|
||||||
|
|
||||||
|
</shape>
|
164
app/src/main/res/layout/migration_bottom_sheet.xml
Normal file
164
app/src/main/res/layout/migration_bottom_sheet.xml
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:background="@drawable/dialog_rounded_background"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.0">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/data_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/data_to_include_in_migration"
|
||||||
|
android:textAppearance="@style/TextAppearance.Medium.Body2"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/mig_chapters"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/chapters"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/data_label"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/data_label" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/mig_categories"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/categories"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/mig_chapters"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/mig_chapters"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/mig_chapters" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/mig_tracking"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/track"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/mig_categories"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/mig_categories"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/mig_categories" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/options_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/options"
|
||||||
|
android:textAppearance="@style/TextAppearance.Medium.Body2"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/mig_chapters"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/mig_chapters" />
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/sourceGroup"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/options_label"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/options_label">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radioButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:text="@string/use_first_source" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radioButton2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/use_most_chapters" />
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
|
android:id="@+id/use_smart_search"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/use_intelligent_search"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/sourceGroup"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/sourceGroup"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/sourceGroup" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
|
android:id="@+id/extra_search_param"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/include_extra_search_parameter"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/use_smart_search"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/use_smart_search"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/use_smart_search" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/extra_search_param_text"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="@string/search_parameter"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/extra_search_param"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/extra_search_param" />
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/skip_step"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:text="@string/skip_this_step_next_time"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/extra_search_param"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/extra_search_param"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/extra_search_param_text" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:src="@drawable/baseline_arrow_forward_white_24"
|
||||||
|
app:layout_anchor="@id/constraintLayout"
|
||||||
|
app:layout_anchorGravity="bottom|end"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -2,6 +2,7 @@
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/frameLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:animateLayoutChanges="true">
|
android:animateLayoutChanges="true">
|
||||||
|
@ -10,174 +11,24 @@
|
||||||
android:id="@+id/recycler"
|
android:id="@+id/recycler"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:clipToPadding="false"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/textView2"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:listitem="@layout/migration_source_item">
|
tools:listitem="@layout/migration_source_item">
|
||||||
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/textView2"
|
android:id="@+id/fab"
|
||||||
android:layout_width="wrap_content"
|
style="@style/Theme.Widget.FABFixed"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:text="@string/data_to_include_in_migration"
|
|
||||||
android:textAppearance="@style/TextAppearance.Medium.Body2"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/mig_chapters"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/textView" />
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/mig_chapters"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:checked="true"
|
|
||||||
android:text="@string/chapters"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/textView"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/textView2" />
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/mig_categories"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:checked="true"
|
|
||||||
android:text="@string/categories"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/mig_chapters"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/mig_chapters" />
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/mig_tracking"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:checked="true"
|
|
||||||
android:text="@string/track"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/mig_categories"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/mig_categories" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:text="@string/options"
|
|
||||||
android:textAppearance="@style/TextAppearance.Medium.Body2"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/prioritize_chapter_count"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/prioritize_chapter_count"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/textView"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/migration_mode" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/migration_mode"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/fuzzy_search"
|
android:focusable="true"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:src="@drawable/baseline_arrow_forward_white_24"
|
||||||
app:layout_constraintStart_toEndOf="@+id/prioritize_chapter_count"
|
app:layout_anchor="@id/recycler"
|
||||||
android:focusable="true" />
|
app:layout_anchorGravity="bottom|right|end"
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/use_smart_search"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/textView"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/fuzzy_search" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fuzzy_search"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:text="@string/use_intelligent_search"
|
|
||||||
android:clickable="true"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/extra_search_param"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/prioritize_chapter_count"
|
|
||||||
android:focusable="true" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/extra_search_param"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/textView"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/extra_search_param_desc" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/extra_search_param_desc"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:text="@string/include_extra_search_parameter"
|
|
||||||
android:clickable="true"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/extra_search_param_text"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/prioritize_chapter_count"
|
|
||||||
android:focusable="true" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/extra_search_param_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:ems="10"
|
|
||||||
android:hint="@string/search_parameter"
|
|
||||||
android:inputType="textPersonName"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/begin_migration_btn"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
android:importantForAutofill="no" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/begin_migration_btn"
|
|
||||||
style="@style/Theme.Widget.Button.Colored"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:text="@string/begin_migration"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Group
|
|
||||||
android:id="@+id/options_group"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:constraint_referenced_ids="migration_mode,use_smart_search,fuzzy_search,action_copy_manga,extra_search_param_desc,mig_tracking,textView,mig_chapters,copy_manga_desc,textView2,prioritize_chapter_count,mig_categories,extra_search_param" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -156,6 +156,9 @@
|
||||||
<string name="pref_remove_articles">Sort by ignoring articles</string>
|
<string name="pref_remove_articles">Sort by ignoring articles</string>
|
||||||
<string name="pref_remove_articles_summary">When sorting alphabetically, sort ignoring
|
<string name="pref_remove_articles_summary">When sorting alphabetically, sort ignoring
|
||||||
articles (a, an, the) at the start of manga titles</string>
|
articles (a, an, the) at the start of manga titles</string>
|
||||||
|
<string name="pref_skip_pre_migration">Skip pre-migration</string>
|
||||||
|
<string name="pref_skip_pre_migration_summary">Use last saved pre-migration preferences
|
||||||
|
and sources to mass migrate</string>
|
||||||
<string name="pref_theme">Application theme</string>
|
<string name="pref_theme">Application theme</string>
|
||||||
<string name="light_theme">Main theme</string>
|
<string name="light_theme">Main theme</string>
|
||||||
<string name="dark_theme">Dark theme</string>
|
<string name="dark_theme">Dark theme</string>
|
||||||
|
@ -559,12 +562,15 @@
|
||||||
<string name="channel_ext_updates">Extension Updates</string>
|
<string name="channel_ext_updates">Extension Updates</string>
|
||||||
<string name="channel_library_updates">Updating Library</string>
|
<string name="channel_library_updates">Updating Library</string>
|
||||||
<string name="channel_new_chapters">New Chapters</string>
|
<string name="channel_new_chapters">New Chapters</string>
|
||||||
|
|
||||||
<string name="data_to_include_in_migration">Data to include in migration</string>
|
<string name="data_to_include_in_migration">Data to include in migration</string>
|
||||||
<string name="search_parameter">Search parameter (e.g. language:english)</string>
|
<string name="search_parameter">Search parameter (e.g. language:english)</string>
|
||||||
<string name="include_extra_search_parameter">Include extra search parameter when searching</string>
|
<string name="include_extra_search_parameter">Include extra search parameter when searching</string>
|
||||||
<string name="keep_old_manga">Keep old manga</string>
|
<string name="use_intelligent_search">Search title + keywords of title</string>
|
||||||
<string name="use_intelligent_search">Use intelligent search algorithm</string>
|
|
||||||
<string name="begin_migration">Begin migration</string>
|
|
||||||
<string name="migrating_to">migrating to</string>
|
<string name="migrating_to">migrating to</string>
|
||||||
|
<string name="use_most_chapters">Use source with the most chapters (slower)</string>
|
||||||
|
<string name="use_first_source">Use first source with alternative</string>
|
||||||
|
<string name="skip_this_step_next_time">Skip this step next time</string>
|
||||||
|
<string name="pre_migration_skip_toast">To show this screen again, go to Settings -> General.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -268,5 +268,15 @@
|
||||||
<item name="android:windowExitAnimation">@anim/exit_to_left</item>
|
<item name="android:windowExitAnimation">@anim/exit_to_left</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="SheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
|
||||||
|
<!--<item name="android:windowCloseOnTouchOutside">false</item>-->
|
||||||
|
<item name="android:windowIsTranslucent">true</item>
|
||||||
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
|
<item name="android:colorBackground"> @android:color/transparent</item>
|
||||||
|
<item name="android:backgroundDimEnabled">true</item>
|
||||||
|
<item name="android:backgroundDimAmount">0.3</item>
|
||||||
|
<item name="android:windowFrame">@null</item>
|
||||||
|
<item name="android:windowIsFloating">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Reference in a new issue