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.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import java.io.Serializable
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
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...
|
* 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.
|
* 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.RxController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
||||||
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionController
|
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 eu.kanade.tachiyomi.ui.browse.source.SourceController
|
||||||
import kotlinx.android.synthetic.main.main_activity.tabs
|
import kotlinx.android.synthetic.main.main_activity.tabs
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
@ -126,7 +126,7 @@ class BrowseController :
|
|||||||
val controller: Controller = when (position) {
|
val controller: Controller = when (position) {
|
||||||
SOURCES_CONTROLLER -> SourceController()
|
SOURCES_CONTROLLER -> SourceController()
|
||||||
EXTENSIONS_CONTROLLER -> ExtensionController()
|
EXTENSIONS_CONTROLLER -> ExtensionController()
|
||||||
MIGRATION_CONTROLLER -> MigrationController()
|
MIGRATION_CONTROLLER -> MigrationSourcesController()
|
||||||
else -> error("Wrong position $position")
|
else -> error("Wrong position $position")
|
||||||
}
|
}
|
||||||
router.setRoot(RouterTransaction.with(controller))
|
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 com.bluelinelabs.conductor.Controller
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
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)
|
class MigrationMangaDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
|
||||||
where T : Controller {
|
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.app.Activity
|
||||||
import android.content.res.Configuration
|
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 android.os.Bundle
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
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.graphics.Paint.STRIKE_THRU_TEXT_FLAG
|
||||||
import android.view.View
|
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.os.Parcelable
|
||||||
import android.view.View
|
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.os.Bundle
|
||||||
import android.view.LayoutInflater
|
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.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
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.browse.migration.manga.process.MigrationListController
|
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListController
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.process.MigrationProcedureConfig
|
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationProcedureConfig
|
||||||
import exh.util.doOnApplyWindowInsets
|
import exh.util.doOnApplyWindowInsets
|
||||||
import exh.util.marginBottom
|
import exh.util.marginBottom
|
||||||
import exh.util.updateLayoutParams
|
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.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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.content.pm.ActivityInfo
|
||||||
import android.graphics.Color
|
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.BaseController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationMangaDialog
|
import eu.kanade.tachiyomi.ui.browse.migration.MigrationMangaDialog
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.SearchController
|
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.design.PreMigrationController
|
import eu.kanade.tachiyomi.ui.browse.migration.search.SearchController
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController
|
import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
@ -349,7 +349,11 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
} else {
|
} else {
|
||||||
sources.filter { it.id != manga.source }
|
sources.filter { it.id != manga.source }
|
||||||
}
|
}
|
||||||
val searchController = SearchController(manga, validSources)
|
val searchController =
|
||||||
|
SearchController(
|
||||||
|
manga,
|
||||||
|
validSources
|
||||||
|
)
|
||||||
searchController.targetController = this@MigrationListController
|
searchController.targetController = this@MigrationListController
|
||||||
router.pushController(searchController.withFadeTransaction())
|
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 android.os.Parcelable
|
||||||
import kotlinx.android.parcel.Parcelize
|
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 android.view.MenuItem
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
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.view.View
|
||||||
import android.widget.PopupMenu
|
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 android.view.View
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
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 android.view.View
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
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 android.view.View
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
@ -7,15 +8,20 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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 {
|
override fun getLayoutRes(): Int {
|
||||||
return R.layout.source_list_item
|
return R.layout.source_list_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHolder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHolder {
|
||||||
return MangaHolder(view, adapter)
|
return MangaHolder(
|
||||||
|
view,
|
||||||
|
adapter
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(
|
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 android.os.Bundle
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
|
||||||
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.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
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.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.lang.combineLatest
|
import exh.debug.DebugFunctions.sourceManager
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
import rx.schedulers.Schedulers
|
import rx.schedulers.Schedulers
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class MigrationPresenter(
|
class MigrationMangaPresenter(
|
||||||
private val sourceManager: SourceManager = Injekt.get(),
|
private val sourceId: Long,
|
||||||
private val db: DatabaseHelper = Injekt.get(),
|
private val db: DatabaseHelper = Injekt.get()
|
||||||
private val preferences: PreferencesHelper = Injekt.get()
|
) : BasePresenter<MigrationMangaController>() {
|
||||||
) : BasePresenter<MigrationController>() {
|
|
||||||
|
|
||||||
var state = ViewState()
|
|
||||||
private set(value) {
|
|
||||||
field = value
|
|
||||||
stateRelay.call(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val stateRelay = BehaviorRelay.create(state)
|
|
||||||
|
|
||||||
override fun onCreate(savedState: Bundle?) {
|
override fun onCreate(savedState: Bundle?) {
|
||||||
super.onCreate(savedState)
|
super.onCreate(savedState)
|
||||||
@ -39,54 +28,24 @@ class MigrationPresenter(
|
|||||||
db.getFavoriteMangas()
|
db.getFavoriteMangas()
|
||||||
.asRxObservable()
|
.asRxObservable()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnNext { state = state.copy(sourcesWithManga = findSourcesWithManga(it)) }
|
.map { libraryToMigrationItem(it) }
|
||||||
.combineLatest(
|
.subscribeLatestCache(MigrationMangaController::setManga)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSelectedSource(source: Source) {
|
private fun libraryToMigrationItem(library: List<Manga>): List<MangaItem> {
|
||||||
state = state.copy(selectedSource = source, mangaForSource = emptyList())
|
return library.filter { it.source == sourceId }
|
||||||
}
|
.sortedBy { it.title }
|
||||||
|
.map { MangaItem(it) }
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean) {
|
fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean) {
|
||||||
val source = sourceManager.get(manga.source) ?: return
|
val source = sourceManager.get(manga.source) ?: return
|
||||||
|
|
||||||
state = state.copy(isReplacingManga = true)
|
|
||||||
|
|
||||||
Observable.defer { source.fetchChapterList(manga) }.onErrorReturn { emptyList() }
|
Observable.defer { source.fetchChapterList(manga) }.onErrorReturn { emptyList() }
|
||||||
.doOnNext { migrateMangaInternal(source, it, prevManga, manga, replace) }
|
.doOnNext { migrateMangaInternal(source, it, prevManga, manga, replace) }
|
||||||
.onErrorReturn { emptyList() }.subscribeOn(Schedulers.io())
|
.onErrorReturn { emptyList() }.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnUnsubscribe { state = state.copy(isReplacingManga = false) }.subscribe()
|
.subscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun migrateMangaInternal(
|
private fun migrateMangaInternal(
|
||||||
@ -96,10 +55,19 @@ class MigrationPresenter(
|
|||||||
manga: Manga,
|
manga: Manga,
|
||||||
replace: Boolean
|
replace: Boolean
|
||||||
) {
|
) {
|
||||||
val flags = preferences.migrateFlags().get()
|
val flags = Injekt.get<PreferencesHelper>().migrateFlags().get()
|
||||||
val migrateChapters = MigrationFlags.hasChapters(flags)
|
val migrateChapters =
|
||||||
val migrateCategories = MigrationFlags.hasCategories(flags)
|
MigrationFlags.hasChapters(
|
||||||
val migrateTracks = MigrationFlags.hasTracks(flags)
|
flags
|
||||||
|
)
|
||||||
|
val migrateCategories =
|
||||||
|
MigrationFlags.hasCategories(
|
||||||
|
flags
|
||||||
|
)
|
||||||
|
val migrateTracks =
|
||||||
|
MigrationFlags.hasTracks(
|
||||||
|
flags
|
||||||
|
)
|
||||||
|
|
||||||
db.inTransaction {
|
db.inTransaction {
|
||||||
// Update chapters read
|
// 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.app.Dialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -15,7 +15,9 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
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.GlobalSearchController
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchPresenter
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchPresenter
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
@ -50,7 +52,11 @@ class SearchController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createPresenter(): GlobalSearchPresenter {
|
override fun createPresenter(): GlobalSearchPresenter {
|
||||||
return SearchPresenter(initialQuery, manga!!, sources = sources)
|
return SearchPresenter(
|
||||||
|
initialQuery,
|
||||||
|
manga!!,
|
||||||
|
sources = sources
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
@ -85,7 +91,8 @@ class SearchController(
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
fun migrateManga() {
|
fun migrateManga() {
|
||||||
val target = targetController as? MigrationInterface ?: return
|
val target = targetController as? MigrationInterface
|
||||||
|
?: return
|
||||||
val manga = manga ?: return
|
val manga = manga ?: return
|
||||||
val newManga = newManga ?: return
|
val newManga = newManga ?: return
|
||||||
|
|
||||||
@ -94,7 +101,8 @@ class SearchController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copyManga() {
|
fun copyManga() {
|
||||||
val target = targetController as? MigrationInterface ?: return
|
val target = targetController as? MigrationInterface
|
||||||
|
?: return
|
||||||
val manga = manga ?: return
|
val manga = manga ?: return
|
||||||
val newManga = newManga ?: return
|
val newManga = newManga ?: return
|
||||||
|
|
||||||
@ -105,7 +113,10 @@ class SearchController(
|
|||||||
private fun replaceWithNewSearchController(manga: Manga?) {
|
private fun replaceWithNewSearchController(manga: Manga?) {
|
||||||
if (manga != null) {
|
if (manga != null) {
|
||||||
// router.popCurrentController()
|
// router.popCurrentController()
|
||||||
val searchController = SearchController(manga)
|
val searchController =
|
||||||
|
SearchController(
|
||||||
|
manga
|
||||||
|
)
|
||||||
searchController.targetController = targetController
|
searchController.targetController = targetController
|
||||||
searchController.progress = progress + 1
|
searchController.progress = progress + 1
|
||||||
searchController.totalProgress = totalProgress
|
searchController.totalProgress = totalProgress
|
||||||
@ -123,7 +134,8 @@ class SearchController(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
newManga = manga
|
newManga = manga
|
||||||
val dialog = MigrationDialog()
|
val dialog =
|
||||||
|
MigrationDialog()
|
||||||
dialog.targetController = this
|
dialog.targetController = this
|
||||||
dialog.showDialog(router)
|
dialog.showDialog(router)
|
||||||
}
|
}
|
||||||
@ -140,7 +152,10 @@ class SearchController(
|
|||||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||||
val prefValue = preferences.migrateFlags().get()
|
val prefValue = preferences.migrateFlags().get()
|
||||||
|
|
||||||
val preselected = MigrationFlags.getEnabledFlagsPositions(prefValue)
|
val preselected =
|
||||||
|
MigrationFlags.getEnabledFlagsPositions(
|
||||||
|
prefValue
|
||||||
|
)
|
||||||
|
|
||||||
return MaterialDialog(activity!!)
|
return MaterialDialog(activity!!)
|
||||||
.message(R.string.data_to_include_in_migration)
|
.message(R.string.data_to_include_in_migration)
|
||||||
@ -149,7 +164,10 @@ class SearchController(
|
|||||||
{ resources?.getString(it) as CharSequence },
|
{ resources?.getString(it) as CharSequence },
|
||||||
initialSelection = preselected.toIntArray()
|
initialSelection = preselected.toIntArray()
|
||||||
) { _, positions, _ ->
|
) { _, positions, _ ->
|
||||||
val newValue = MigrationFlags.getFlagsFromPositions(positions.toTypedArray())
|
val newValue =
|
||||||
|
MigrationFlags.getFlagsFromPositions(
|
||||||
|
positions.toTypedArray()
|
||||||
|
)
|
||||||
preferences.migrateFlags().set(newValue)
|
preferences.migrateFlags().set(newValue)
|
||||||
}
|
}
|
||||||
.positiveButton(R.string.migrate) {
|
.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.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
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 android.view.View
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@ -25,7 +25,10 @@ class SelectionHeader : AbstractHeaderItem<SelectionHeader.Holder>() {
|
|||||||
* Creates a new view holder for this item.
|
* Creates a new view holder for this item.
|
||||||
*/
|
*/
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): Holder {
|
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.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
@ -8,15 +8,13 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
|
|||||||
/**
|
/**
|
||||||
* Adapter that holds the catalogue cards.
|
* 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) {
|
FlexibleAdapter<IFlexible<*>>(null, controller, true) {
|
||||||
|
|
||||||
val cardBackground = controller.activity!!.getResourceColor(R.attr.colorSurface)
|
val cardBackground = controller.activity!!.getResourceColor(R.attr.colorSurface)
|
||||||
|
|
||||||
private var items: List<IFlexible<*>>? = null
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDisplayHeadersAtStartUp(true)
|
setDisplayHeadersAtStartUp(true)
|
||||||
}
|
}
|
||||||
@ -32,11 +30,4 @@ class SourceAdapter(val controller: MigrationController) :
|
|||||||
interface OnAllClickListener {
|
interface OnAllClickListener {
|
||||||
fun onAllClick(position: Int)
|
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 android.view.View
|
||||||
import eu.kanade.tachiyomi.source.icon
|
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 android.view.View
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@ -14,7 +14,7 @@ import eu.kanade.tachiyomi.source.Source
|
|||||||
* @param source Instance of [Source] containing source information.
|
* @param source Instance of [Source] containing source information.
|
||||||
* @param header The header for this item.
|
* @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) {
|
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.
|
* Creates a new view holder for this item.
|
||||||
*/
|
*/
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): SourceHolder {
|
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.RootController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationController
|
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.design.PreMigrationController
|
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrationSourcesController
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
|
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController
|
import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController
|
||||||
@ -429,7 +429,10 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
R.id.action_source_migration -> {
|
R.id.action_source_migration -> {
|
||||||
router.pushController(MigrationController().withFadeTransaction())
|
router.pushController(
|
||||||
|
MigrationSourcesController()
|
||||||
|
.withFadeTransaction()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
// --> EXH
|
// --> EXH
|
||||||
R.id.action_sync_favorites -> {
|
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.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
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.SourceController
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
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.source.online.all.MergedSource
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
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.SourceController
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||||
|
Loading…
x
Reference in New Issue
Block a user