Using set categories sheet to bulk move in library

This commit is contained in:
Jays2Kings 2021-04-06 12:25:56 -04:00
parent 5868ca3197
commit 2d10680fd9
6 changed files with 55 additions and 81 deletions

View File

@ -28,20 +28,24 @@ import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.util.ArrayList
import java.util.Date
import java.util.Locale
import kotlin.math.max
class SetCategoriesSheet(
private val activity: Activity,
private val manga: Manga,
private val listManga: List<Manga>,
var categories: MutableList<Category>,
var preselected: Array<Int>,
val addingToLibrary: Boolean,
private val addingToLibrary: Boolean,
val onMangaAdded: (() -> Unit) = { }
) : BottomSheetDialog
(activity, R.style.BottomSheetDialogTheme) {
constructor(activity: Activity, manga: Manga, categories: MutableList<Category>, preselected: Array<Int>, addingToLibrary: Boolean, onMangaAdded: () -> Unit) :
this(activity, listOf(manga), categories, preselected, addingToLibrary, onMangaAdded)
private var sheetBehavior: BottomSheetBehavior<*>
private val fastAdapter: FastAdapter<AddCategoryItem>
@ -63,7 +67,11 @@ class SetCategoriesSheet(
} else {
R.string.move_x_to
},
manga.mangaType(context)
if (listManga.size == 1) {
listManga.first().mangaType(context)
} else {
context.getString(R.string.selection).lowercase(Locale.ROOT)
}
)
setOnShowListener {
@ -199,7 +207,8 @@ class SetCategoriesSheet(
}
private fun addMangaToCategories() {
if (!manga.favorite) {
if (listManga.size == 1 && !listManga.first().favorite) {
val manga = listManga.first()
manga.favorite = !manga.favorite
manga.date_added = Date().time
@ -207,9 +216,15 @@ class SetCategoriesSheet(
db.insertManga(manga).executeAsBlocking()
}
val mc = ArrayList<MangaCategory>()
val selectedCategories = selectExtension.selectedItems.map(AddCategoryItem::category)
val mc = selectedCategories.filter { it.id != 0 }.map { MangaCategory.create(manga, it) }
db.setMangaCategories(mc, listOf(manga))
for (manga in listManga) {
for (cat in selectedCategories) {
mc.add(MangaCategory.create(manga, cat))
}
}
db.setMangaCategories(mc, listManga)
onMangaAdded()
}
}

View File

@ -1,53 +0,0 @@
package eu.kanade.tachiyomi.ui.library
import android.app.Dialog
import android.os.Bundle
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsMultiChoice
import com.bluelinelabs.conductor.Controller
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.base.controller.DialogController
class ChangeMangaCategoriesDialog<T>(bundle: Bundle? = null) :
DialogController(bundle) where T : Controller, T : ChangeMangaCategoriesDialog.Listener {
private var mangas = emptyList<Manga>()
private var categories = emptyList<Category>()
private var preselected = emptyArray<Int>()
constructor(
target: T,
mangas: List<Manga>,
categories: List<Category>,
preselected: Array<Int>
) : this() {
this.mangas = mangas
this.categories = categories
this.preselected = preselected
targetController = target
}
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialDialog(activity!!)
.title(R.string.move_to_categories)
.listItemsMultiChoice(
items = categories.map { it.name },
initialSelection = preselected.toIntArray(),
allowEmptySelection = true
) { _, selections, _ ->
val newCategories = selections.map { categories[it] }
(targetController as? Listener)?.updateCategoriesForMangas(mangas, newCategories)
}
.positiveButton(android.R.string.ok)
.negativeButton(android.R.string.cancel)
}
interface Listener {
fun updateCategoriesForMangas(mangas: List<Manga>, categories: List<Category>)
}
}

View File

@ -73,6 +73,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
import eu.kanade.tachiyomi.util.moveCategories
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getBottomGestureInsets
import eu.kanade.tachiyomi.util.system.getResourceColor
@ -111,7 +112,6 @@ class LibraryController(
val preferences: PreferencesHelper = Injekt.get()
) : BaseController<LibraryControllerBinding>(bundle),
ActionMode.Callback,
ChangeMangaCategoriesDialog.Listener,
FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener,
FlexibleAdapter.OnItemMoveListener,
@ -1477,7 +1477,7 @@ class LibraryController(
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_move_to_category -> showChangeMangaCategoriesDialog()
R.id.action_move_to_category -> showChangeMangaCategoriesSheet()
R.id.action_share -> shareManga()
R.id.action_delete -> {
MaterialDialog(activity!!).message(R.string.remove_from_library_question)
@ -1551,27 +1551,14 @@ class LibraryController(
(activity as? MainActivity)?.setUndoSnackBar(snack)
}
override fun updateCategoriesForMangas(mangas: List<Manga>, categories: List<Category>) {
presenter.moveMangasToCategories(categories, mangas)
destroyActionModeIfNeeded()
}
/**
* Move the selected manga to a list of categories.
*/
private fun showChangeMangaCategoriesDialog() {
// Create a copy of selected manga
val mangas = selectedMangas.toList()
// Hide the default category because it has a different behavior than the ones from db.
val categories = presenter.allCategories.filter { it.id != 0 }
// Get indexes of the common categories to preselect.
val commonCategoriesIndexes =
presenter.getCommonCategories(mangas).map { categories.indexOf(it) }.toTypedArray()
ChangeMangaCategoriesDialog(this, mangas, categories, commonCategoriesIndexes).showDialog(
router
)
private fun showChangeMangaCategoriesSheet() {
val activity = activity ?: return
selectedMangas.toList().moveCategories(presenter.db, activity) {
presenter.getLibrary()
destroyActionModeIfNeeded()
}
}
}

View File

@ -44,7 +44,7 @@ import java.util.Locale
*/
class LibraryPresenter(
private val view: LibraryController,
private val db: DatabaseHelper = Injekt.get(),
val db: DatabaseHelper = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get(),
private val coverCache: CoverCache = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(),

View File

@ -6,6 +6,7 @@ import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
@ -54,6 +55,29 @@ fun Manga.moveCategories(
}.show()
}
fun List<Manga>.moveCategories(
db: DatabaseHelper,
activity: Activity,
onMangaMoved: () -> Unit
) {
if (this.isEmpty()) return
val commonCategories = this
.map { db.getCategoriesForManga(it).executeAsBlocking() }
.reduce { set1: Iterable<Category>, set2 -> set1.intersect(set2).toMutableList() }
.mapNotNull { it.id }
.toTypedArray()
val categories = db.getCategories().executeAsBlocking()
SetCategoriesSheet(
activity,
this,
categories.toMutableList(),
commonCategories,
false
) {
onMangaMoved()
}.show()
}
fun Manga.addOrRemoveToFavorites(
db: DatabaseHelper,
preferences: PreferencesHelper,

View File

@ -877,6 +877,7 @@
<string name="search">Search</string>
<string name="select_all">Select all</string>
<string name="select_none">Select none</string>
<string name="selection">Selection</string>
<string name="share">Share</string>
<string name="sort">Sort</string>
<string name="sort_and_filter">Sort &amp; Filter</string>