Rewrite migration, split it up into 2 controllers and reorganize the classes
Everything is under the hood, so on top only the back button was fixed in the selct manga screen
This commit is contained in:
parent
75bddd5105
commit
04e8f0d77f
@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import java.io.Serializable
|
||||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
@ -12,7 +13,7 @@ import uy.kohesive.injekt.api.get
|
||||
/**
|
||||
* A basic interface for creating a source. It could be an online source, a local source, etc...
|
||||
*/
|
||||
interface Source {
|
||||
interface Source : Serializable {
|
||||
|
||||
/**
|
||||
* Id for the source. Must be unique.
|
||||
|
@ -20,7 +20,7 @@ import eu.kanade.tachiyomi.ui.base.controller.RootController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.RxController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
||||
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrationSourcesController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.SourceController
|
||||
import kotlinx.android.synthetic.main.main_activity.tabs
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
@ -126,7 +126,7 @@ class BrowseController :
|
||||
val controller: Controller = when (position) {
|
||||
SOURCES_CONTROLLER -> SourceController()
|
||||
EXTENSIONS_CONTROLLER -> ExtensionController()
|
||||
MIGRATION_CONTROLLER -> MigrationController()
|
||||
MIGRATION_CONTROLLER -> MigrationSourcesController()
|
||||
else -> error("Wrong position $position")
|
||||
}
|
||||
router.setRoot(RouterTransaction.with(controller))
|
||||
|
@ -1,17 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
|
||||
class MangaAdapter(controller: MigrationController) :
|
||||
FlexibleAdapter<IFlexible<*>>(null, controller) {
|
||||
|
||||
private var items: List<IFlexible<*>>? = null
|
||||
|
||||
override fun updateDataSet(items: MutableList<IFlexible<*>>?) {
|
||||
if (this.items !== items) {
|
||||
this.items = items
|
||||
super.updateDataSet(items)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.MigrationControllerBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import exh.util.RecyclerWindowInsetsListener
|
||||
import exh.util.applyWindowInsetsForController
|
||||
import exh.util.await
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import rx.schedulers.Schedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class MigrationController :
|
||||
NucleusController<MigrationControllerBinding, MigrationPresenter>(),
|
||||
FlexibleAdapter.OnItemClickListener,
|
||||
SourceAdapter.OnAllClickListener,
|
||||
MigrationInterface {
|
||||
|
||||
private var adapter: FlexibleAdapter<IFlexible<*>>? = null
|
||||
|
||||
private var title: String? = null
|
||||
set(value) {
|
||||
field = value
|
||||
setTitle()
|
||||
}
|
||||
|
||||
override fun createPresenter(): MigrationPresenter {
|
||||
return MigrationPresenter()
|
||||
}
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||
binding = MigrationControllerBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
fun searchController(manga: Manga): SearchController {
|
||||
val controller = SearchController(manga)
|
||||
controller.targetController = this
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View) {
|
||||
super.onViewCreated(view)
|
||||
view.applyWindowInsetsForController()
|
||||
|
||||
adapter = FlexibleAdapter(null, this)
|
||||
binding.recycler.layoutManager =
|
||||
androidx.recyclerview.widget.LinearLayoutManager(view.context)
|
||||
binding.recycler.adapter = adapter
|
||||
binding.recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
||||
}
|
||||
|
||||
override fun onDestroyView(view: View) {
|
||||
adapter = null
|
||||
super.onDestroyView(view)
|
||||
}
|
||||
|
||||
override fun getTitle(): String? {
|
||||
return title
|
||||
}
|
||||
|
||||
override fun handleBack(): Boolean {
|
||||
return if (presenter.state.selectedSource != null) {
|
||||
presenter.deselectSource()
|
||||
true
|
||||
} else {
|
||||
super.handleBack()
|
||||
}
|
||||
}
|
||||
|
||||
fun render(state: ViewState) {
|
||||
if (state.selectedSource == null) {
|
||||
title = resources?.getString(R.string.source_migration)
|
||||
if (adapter !is SourceAdapter) {
|
||||
adapter = SourceAdapter(this)
|
||||
binding.recycler.adapter = adapter
|
||||
adapter?.fastScroller = binding.fastScroller
|
||||
}
|
||||
adapter?.updateDataSet(state.sourcesWithManga)
|
||||
} else {
|
||||
// val switching = title == resources?.getString(R.string.source_migration)
|
||||
title = state.selectedSource.toString()
|
||||
if (adapter !is MangaAdapter) {
|
||||
adapter = MangaAdapter(this)
|
||||
binding.recycler.adapter = adapter
|
||||
adapter?.fastScroller = binding.fastScroller
|
||||
}
|
||||
adapter?.updateDataSet(state.mangaForSource, true)
|
||||
/*if (switching) launchUI {
|
||||
migration_recycler.alpha = 0f
|
||||
migration_recycler.animate().alpha(1f).setStartDelay(100).setDuration(200).start()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemClick(view: View?, position: Int): Boolean {
|
||||
val item = adapter?.getItem(position) ?: return false
|
||||
|
||||
if (item is MangaItem) {
|
||||
PreMigrationController.navigateToMigration(
|
||||
Injekt.get<PreferencesHelper>().skipPreMigration().get(),
|
||||
parentController!!.router,
|
||||
listOf(item.manga.id!!)
|
||||
)
|
||||
} else if (item is SourceItem) {
|
||||
presenter.setSelectedSource(item.source)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onAllClick(position: Int) {
|
||||
val item = adapter?.getItem(position) as? SourceItem ?: return
|
||||
|
||||
launchUI {
|
||||
val manga = Injekt.get<DatabaseHelper>().getFavoriteMangas().asRxSingle().await(
|
||||
Schedulers.io()
|
||||
)
|
||||
val sourceMangas =
|
||||
manga.asSequence().filter { it.source == item.source.id }.map { it.id!! }.toList()
|
||||
withContext(Dispatchers.Main) {
|
||||
PreMigrationController.navigateToMigration(
|
||||
Injekt.get<PreferencesHelper>().skipPreMigration().get(),
|
||||
parentController!!.router,
|
||||
sourceMangas
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean): Manga? {
|
||||
presenter.migrateManga(prevManga, manga, replace)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
interface MigrationInterface {
|
||||
fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean): Manga?
|
||||
}
|
@ -6,7 +6,7 @@ import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListController
|
||||
|
||||
class MigrationMangaDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
|
||||
where T : Controller {
|
||||
|
@ -1,10 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
|
||||
data class ViewState(
|
||||
val selectedSource: Source? = null,
|
||||
val mangaForSource: List<MangaItem> = emptyList(),
|
||||
val sourcesWithManga: List<SourceItem> = emptyList(),
|
||||
val isReplacingManga: Boolean = false
|
||||
)
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.design
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.res.Configuration
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.design
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.design
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design
|
||||
|
||||
import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
|
||||
import android.view.View
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.design
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design
|
||||
|
||||
import android.os.Parcelable
|
||||
import android.view.View
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.design
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@ -20,8 +20,8 @@ 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.browse.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.process.MigrationProcedureConfig
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationProcedureConfig
|
||||
import exh.util.doOnApplyWindowInsets
|
||||
import exh.util.marginBottom
|
||||
import exh.util.updateLayoutParams
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.process
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.process
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.graphics.Color
|
||||
@ -27,8 +27,8 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationMangaDialog
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.SearchController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.search.SearchController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
@ -349,7 +349,11 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
} else {
|
||||
sources.filter { it.id != manga.source }
|
||||
}
|
||||
val searchController = SearchController(manga, validSources)
|
||||
val searchController =
|
||||
SearchController(
|
||||
manga,
|
||||
validSources
|
||||
)
|
||||
searchController.targetController = this@MigrationListController
|
||||
router.pushController(searchController.withFadeTransaction())
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.process
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.android.parcel.Parcelize
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.process
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import android.view.MenuItem
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.process
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import android.view.View
|
||||
import android.widget.PopupMenu
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga.process
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga
|
||||
|
||||
import android.view.View
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
@ -1,5 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga
|
||||
|
||||
import android.os.Parcelable
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
@ -7,15 +8,20 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
class MangaItem(val manga: Manga) : AbstractFlexibleItem<MangaHolder>() {
|
||||
@Parcelize
|
||||
class MangaItem(val manga: Manga) : AbstractFlexibleItem<MangaHolder>(), Parcelable {
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return R.layout.source_list_item
|
||||
}
|
||||
|
||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHolder {
|
||||
return MangaHolder(view, adapter)
|
||||
return MangaHolder(
|
||||
view,
|
||||
adapter
|
||||
)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(
|
@ -0,0 +1,95 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.MigrationControllerBinding
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.SourceDividerItemDecoration
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class MigrationMangaController :
|
||||
NucleusController<MigrationControllerBinding, MigrationMangaPresenter>,
|
||||
FlexibleAdapter.OnItemClickListener,
|
||||
MigrationInterface {
|
||||
|
||||
private var adapter: FlexibleAdapter<IFlexible<*>>? = null
|
||||
|
||||
constructor(source: Source) : super(
|
||||
Bundle().apply {
|
||||
putSerializable(SOURCE_EXTRA, source)
|
||||
}
|
||||
)
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(bundle: Bundle) : this(bundle.getSerializable(SOURCE_EXTRA) as Source)
|
||||
|
||||
private val source: Source = args.getSerializable(SOURCE_EXTRA) as Source
|
||||
|
||||
override fun getTitle(): String? {
|
||||
return source.name
|
||||
}
|
||||
|
||||
override fun createPresenter(): MigrationMangaPresenter {
|
||||
return MigrationMangaPresenter(
|
||||
source.id
|
||||
)
|
||||
}
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||
binding = MigrationControllerBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View) {
|
||||
super.onViewCreated(view)
|
||||
|
||||
adapter = FlexibleAdapter<IFlexible<*>>(null, this)
|
||||
binding.recycler.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.recycler.adapter = adapter
|
||||
binding.recycler.addItemDecoration(SourceDividerItemDecoration(view.context))
|
||||
adapter?.fastScroller = binding.fastScroller
|
||||
}
|
||||
|
||||
override fun onDestroyView(view: View) {
|
||||
adapter = null
|
||||
super.onDestroyView(view)
|
||||
}
|
||||
|
||||
fun setManga(manga: List<MangaItem>) {
|
||||
adapter?.updateDataSet(manga)
|
||||
}
|
||||
|
||||
override fun onItemClick(view: View, position: Int): Boolean {
|
||||
val item = adapter?.getItem(position) as? MangaItem
|
||||
?: return false
|
||||
PreMigrationController.navigateToMigration(
|
||||
Injekt.get<PreferencesHelper>().skipPreMigration().get(),
|
||||
router,
|
||||
listOf(item.manga.id!!)
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean): Manga? {
|
||||
presenter.migrateManga(prevManga, manga, replace)
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SOURCE_EXTRA = "source_id_extra"
|
||||
}
|
||||
}
|
||||
|
||||
interface MigrationInterface {
|
||||
fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean): Manga?
|
||||
}
|
@ -1,37 +1,26 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.manga
|
||||
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
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.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.lang.combineLatest
|
||||
import exh.debug.DebugFunctions.sourceManager
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class MigrationPresenter(
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val preferences: PreferencesHelper = Injekt.get()
|
||||
) : BasePresenter<MigrationController>() {
|
||||
|
||||
var state = ViewState()
|
||||
private set(value) {
|
||||
field = value
|
||||
stateRelay.call(value)
|
||||
}
|
||||
|
||||
private val stateRelay = BehaviorRelay.create(state)
|
||||
class MigrationMangaPresenter(
|
||||
private val sourceId: Long,
|
||||
private val db: DatabaseHelper = Injekt.get()
|
||||
) : BasePresenter<MigrationMangaController>() {
|
||||
|
||||
override fun onCreate(savedState: Bundle?) {
|
||||
super.onCreate(savedState)
|
||||
@ -39,54 +28,24 @@ class MigrationPresenter(
|
||||
db.getFavoriteMangas()
|
||||
.asRxObservable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext { state = state.copy(sourcesWithManga = findSourcesWithManga(it)) }
|
||||
.combineLatest(
|
||||
stateRelay.map { it.selectedSource }
|
||||
.distinctUntilChanged()
|
||||
) { library, source -> library to source }
|
||||
.filter { (_, source) -> source != null }
|
||||
.observeOn(Schedulers.io())
|
||||
.map { (library, source) -> libraryToMigrationItem(library, source!!.id) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext { state = state.copy(mangaForSource = it) }
|
||||
.subscribe()
|
||||
|
||||
stateRelay
|
||||
// Render the view when any field other than isReplacingManga changes
|
||||
.distinctUntilChanged { t1, t2 -> t1.isReplacingManga != t2.isReplacingManga }
|
||||
.subscribeLatestCache(MigrationController::render)
|
||||
.map { libraryToMigrationItem(it) }
|
||||
.subscribeLatestCache(MigrationMangaController::setManga)
|
||||
}
|
||||
|
||||
fun setSelectedSource(source: Source) {
|
||||
state = state.copy(selectedSource = source, mangaForSource = emptyList())
|
||||
}
|
||||
|
||||
fun deselectSource() {
|
||||
state = state.copy(selectedSource = null, mangaForSource = emptyList())
|
||||
}
|
||||
|
||||
private fun findSourcesWithManga(library: List<Manga>): List<SourceItem> {
|
||||
val header = SelectionHeader()
|
||||
return library.map { it.source }.toSet()
|
||||
.mapNotNull { if (it != LocalSource.ID) sourceManager.getOrStub(it) else null }
|
||||
.sortedBy { it.name }
|
||||
.map { SourceItem(it, header) }
|
||||
}
|
||||
|
||||
private fun libraryToMigrationItem(library: List<Manga>, sourceId: Long): List<MangaItem> {
|
||||
return library.filter { it.source == sourceId }.map(::MangaItem)
|
||||
private fun libraryToMigrationItem(library: List<Manga>): List<MangaItem> {
|
||||
return library.filter { it.source == sourceId }
|
||||
.sortedBy { it.title }
|
||||
.map { MangaItem(it) }
|
||||
}
|
||||
|
||||
fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean) {
|
||||
val source = sourceManager.get(manga.source) ?: return
|
||||
|
||||
state = state.copy(isReplacingManga = true)
|
||||
|
||||
Observable.defer { source.fetchChapterList(manga) }.onErrorReturn { emptyList() }
|
||||
.doOnNext { migrateMangaInternal(source, it, prevManga, manga, replace) }
|
||||
.onErrorReturn { emptyList() }.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnUnsubscribe { state = state.copy(isReplacingManga = false) }.subscribe()
|
||||
.subscribe()
|
||||
}
|
||||
|
||||
private fun migrateMangaInternal(
|
||||
@ -96,10 +55,19 @@ class MigrationPresenter(
|
||||
manga: Manga,
|
||||
replace: Boolean
|
||||
) {
|
||||
val flags = preferences.migrateFlags().get()
|
||||
val migrateChapters = MigrationFlags.hasChapters(flags)
|
||||
val migrateCategories = MigrationFlags.hasCategories(flags)
|
||||
val migrateTracks = MigrationFlags.hasTracks(flags)
|
||||
val flags = Injekt.get<PreferencesHelper>().migrateFlags().get()
|
||||
val migrateChapters =
|
||||
MigrationFlags.hasChapters(
|
||||
flags
|
||||
)
|
||||
val migrateCategories =
|
||||
MigrationFlags.hasCategories(
|
||||
flags
|
||||
)
|
||||
val migrateTracks =
|
||||
MigrationFlags.hasTracks(
|
||||
flags
|
||||
)
|
||||
|
||||
db.inTransaction {
|
||||
// Update chapters read
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.search
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
@ -15,7 +15,9 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrationInterface
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchPresenter
|
||||
import kotlinx.coroutines.flow.filter
|
||||
@ -50,7 +52,11 @@ class SearchController(
|
||||
}
|
||||
|
||||
override fun createPresenter(): GlobalSearchPresenter {
|
||||
return SearchPresenter(initialQuery, manga!!, sources = sources)
|
||||
return SearchPresenter(
|
||||
initialQuery,
|
||||
manga!!,
|
||||
sources = sources
|
||||
)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
@ -85,7 +91,8 @@ class SearchController(
|
||||
}*/
|
||||
|
||||
fun migrateManga() {
|
||||
val target = targetController as? MigrationInterface ?: return
|
||||
val target = targetController as? MigrationInterface
|
||||
?: return
|
||||
val manga = manga ?: return
|
||||
val newManga = newManga ?: return
|
||||
|
||||
@ -94,7 +101,8 @@ class SearchController(
|
||||
}
|
||||
|
||||
fun copyManga() {
|
||||
val target = targetController as? MigrationInterface ?: return
|
||||
val target = targetController as? MigrationInterface
|
||||
?: return
|
||||
val manga = manga ?: return
|
||||
val newManga = newManga ?: return
|
||||
|
||||
@ -105,7 +113,10 @@ class SearchController(
|
||||
private fun replaceWithNewSearchController(manga: Manga?) {
|
||||
if (manga != null) {
|
||||
// router.popCurrentController()
|
||||
val searchController = SearchController(manga)
|
||||
val searchController =
|
||||
SearchController(
|
||||
manga
|
||||
)
|
||||
searchController.targetController = targetController
|
||||
searchController.progress = progress + 1
|
||||
searchController.totalProgress = totalProgress
|
||||
@ -123,7 +134,8 @@ class SearchController(
|
||||
return
|
||||
}
|
||||
newManga = manga
|
||||
val dialog = MigrationDialog()
|
||||
val dialog =
|
||||
MigrationDialog()
|
||||
dialog.targetController = this
|
||||
dialog.showDialog(router)
|
||||
}
|
||||
@ -140,7 +152,10 @@ class SearchController(
|
||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||
val prefValue = preferences.migrateFlags().get()
|
||||
|
||||
val preselected = MigrationFlags.getEnabledFlagsPositions(prefValue)
|
||||
val preselected =
|
||||
MigrationFlags.getEnabledFlagsPositions(
|
||||
prefValue
|
||||
)
|
||||
|
||||
return MaterialDialog(activity!!)
|
||||
.message(R.string.data_to_include_in_migration)
|
||||
@ -149,7 +164,10 @@ class SearchController(
|
||||
{ resources?.getString(it) as CharSequence },
|
||||
initialSelection = preselected.toIntArray()
|
||||
) { _, positions, _ ->
|
||||
val newValue = MigrationFlags.getFlagsFromPositions(positions.toTypedArray())
|
||||
val newValue =
|
||||
MigrationFlags.getFlagsFromPositions(
|
||||
positions.toTypedArray()
|
||||
)
|
||||
preferences.migrateFlags().set(newValue)
|
||||
}
|
||||
.positiveButton(R.string.migrate) {
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.search
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
@ -0,0 +1,95 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.MigrationControllerBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrationMangaController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.SourceDividerItemDecoration
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import exh.util.await
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import rx.schedulers.Schedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class MigrationSourcesController :
|
||||
NucleusController<MigrationControllerBinding, MigrationSourcesPresenter>(),
|
||||
FlexibleAdapter.OnItemClickListener,
|
||||
SourceAdapter.OnAllClickListener {
|
||||
|
||||
private var adapter: SourceAdapter? = null
|
||||
|
||||
override fun createPresenter(): MigrationSourcesPresenter {
|
||||
return MigrationSourcesPresenter()
|
||||
}
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||
binding = MigrationControllerBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View) {
|
||||
super.onViewCreated(view)
|
||||
|
||||
adapter =
|
||||
SourceAdapter(this)
|
||||
binding.recycler.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.recycler.adapter = adapter
|
||||
binding.recycler.addItemDecoration(SourceDividerItemDecoration(view.context))
|
||||
adapter?.fastScroller = binding.fastScroller
|
||||
}
|
||||
|
||||
override fun onDestroyView(view: View) {
|
||||
adapter = null
|
||||
super.onDestroyView(view)
|
||||
}
|
||||
|
||||
fun setSources(sourcesWithManga: List<SourceItem>) {
|
||||
adapter?.updateDataSet(sourcesWithManga)
|
||||
}
|
||||
|
||||
override fun getTitle(): String? {
|
||||
return resources?.getString(R.string.source_migration)
|
||||
}
|
||||
|
||||
override fun onItemClick(view: View?, position: Int): Boolean {
|
||||
val item = adapter?.getItem(position) as? SourceItem
|
||||
?: return false
|
||||
val controller =
|
||||
MigrationMangaController(
|
||||
item.source
|
||||
)
|
||||
parentController!!.router.pushController(controller.withFadeTransaction())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onAllClick(position: Int) {
|
||||
val item = adapter?.getItem(position) as? SourceItem
|
||||
?: return
|
||||
|
||||
launchUI {
|
||||
val manga = Injekt.get<DatabaseHelper>().getFavoriteMangas().asRxSingle().await(
|
||||
Schedulers.io()
|
||||
)
|
||||
val sourceMangas =
|
||||
manga.asSequence().filter { it.source == item.source.id }.map { it.id!! }.toList()
|
||||
withContext(Dispatchers.Main) {
|
||||
PreMigrationController.navigateToMigration(
|
||||
Injekt.get<PreferencesHelper>().skipPreMigration().get(),
|
||||
parentController!!.router,
|
||||
sourceMangas
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||
|
||||
import android.os.Bundle
|
||||
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.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.MangaItem
|
||||
import exh.MERGED_SOURCE_ID
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class MigrationSourcesPresenter(
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val preferences: PreferencesHelper = Injekt.get()
|
||||
) : BasePresenter<MigrationSourcesController>() {
|
||||
|
||||
override fun onCreate(savedState: Bundle?) {
|
||||
super.onCreate(savedState)
|
||||
|
||||
db.getFavoriteMangas()
|
||||
.asRxObservable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.map { findSourcesWithManga(it) }
|
||||
.subscribeLatestCache(MigrationSourcesController::setSources)
|
||||
}
|
||||
|
||||
private fun findSourcesWithManga(library: List<Manga>): List<SourceItem> {
|
||||
val header =
|
||||
SelectionHeader()
|
||||
return library.map { it.source }.toSet()
|
||||
.mapNotNull { if (it != LocalSource.ID && it != MERGED_SOURCE_ID) sourceManager.getOrStub(it) else null }
|
||||
.sortedBy { it.name }
|
||||
.map {
|
||||
SourceItem(
|
||||
it,
|
||||
header
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun libraryToMigrationItem(library: List<Manga>, sourceId: Long): List<MangaItem> {
|
||||
return library.filter { it.source == sourceId }.map(::MangaItem)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -25,7 +25,10 @@ class SelectionHeader : AbstractHeaderItem<SelectionHeader.Holder>() {
|
||||
* Creates a new view holder for this item.
|
||||
*/
|
||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): Holder {
|
||||
return Holder(view, adapter)
|
||||
return Holder(
|
||||
view,
|
||||
adapter
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
@ -8,15 +8,13 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
/**
|
||||
* Adapter that holds the catalogue cards.
|
||||
*
|
||||
* @param controller instance of [MigrationController].
|
||||
* @param controller instance of [MigrationSourcesController].
|
||||
*/
|
||||
class SourceAdapter(val controller: MigrationController) :
|
||||
class SourceAdapter(val controller: MigrationSourcesController) :
|
||||
FlexibleAdapter<IFlexible<*>>(null, controller, true) {
|
||||
|
||||
val cardBackground = controller.activity!!.getResourceColor(R.attr.colorSurface)
|
||||
|
||||
private var items: List<IFlexible<*>>? = null
|
||||
|
||||
init {
|
||||
setDisplayHeadersAtStartUp(true)
|
||||
}
|
||||
@ -32,11 +30,4 @@ class SourceAdapter(val controller: MigrationController) :
|
||||
interface OnAllClickListener {
|
||||
fun onAllClick(position: Int)
|
||||
}
|
||||
|
||||
override fun updateDataSet(items: MutableList<IFlexible<*>>?) {
|
||||
if (this.items !== items) {
|
||||
this.items = items
|
||||
super.updateDataSet(items)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||
|
||||
import android.view.View
|
||||
import eu.kanade.tachiyomi.source.icon
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -14,7 +14,7 @@ import eu.kanade.tachiyomi.source.Source
|
||||
* @param source Instance of [Source] containing source information.
|
||||
* @param header The header for this item.
|
||||
*/
|
||||
data class SourceItem(val source: Source, val header: SelectionHeader? = null) :
|
||||
data class SourceItem(val source: Source, val header: SelectionHeader) :
|
||||
AbstractSectionableItem<SourceHolder, SelectionHeader>(header) {
|
||||
|
||||
/**
|
||||
@ -28,7 +28,10 @@ data class SourceItem(val source: Source, val header: SelectionHeader? = null) :
|
||||
* Creates a new view holder for this item.
|
||||
*/
|
||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): SourceHolder {
|
||||
return SourceHolder(view, adapter as SourceAdapter)
|
||||
return SourceHolder(
|
||||
view,
|
||||
adapter as SourceAdapter
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
@ -34,8 +34,8 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrationSourcesController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController
|
||||
@ -429,7 +429,10 @@ class LibraryController(
|
||||
}
|
||||
}
|
||||
R.id.action_source_migration -> {
|
||||
router.pushController(MigrationController().withFadeTransaction())
|
||||
router.pushController(
|
||||
MigrationSourcesController()
|
||||
.withFadeTransaction()
|
||||
)
|
||||
}
|
||||
// --> EXH
|
||||
R.id.action_sync_favorites -> {
|
||||
|
@ -32,7 +32,7 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.SourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||
|
@ -24,7 +24,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.all.MergedSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.SourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||
|
Loading…
x
Reference in New Issue
Block a user