mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-09 20:15:05 +01:00
Fixed being able to drag n drop the a manga into a category that already has it
Sometimes you have to save users from themselves Added checkbox to also default switching category sorting when moving manga
This commit is contained in:
parent
3044dca9bb
commit
c3a10692a1
@ -137,6 +137,8 @@ object PreferenceKeys {
|
||||
|
||||
const val refreshCoversToo = "refresh_covers_too"
|
||||
|
||||
const val keepCatSort = "keep_cat_sort"
|
||||
|
||||
@Deprecated("Use the preferences of the source")
|
||||
fun sourceUsername(sourceId: Long) = "pref_source_username_$sourceId"
|
||||
|
||||
|
@ -239,6 +239,8 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
fun unreadBadgeType() = rxPrefs.getInteger("unread_badge_type", 1)
|
||||
|
||||
fun keepCatSort() = rxPrefs.getInteger(Keys.keepCatSort, 0)
|
||||
|
||||
fun upgradeFilters() {
|
||||
val filterDl = rxPrefs.getBoolean(Keys.filterDownloaded, false).getOrDefault()
|
||||
val filterUn = rxPrefs.getBoolean(Keys.filterUnread, false).getOrDefault()
|
||||
|
@ -67,6 +67,17 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
||||
else false }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in the adapter for the given manga.
|
||||
*
|
||||
* @param manga the manga to find.
|
||||
*/
|
||||
fun allIndexOf(manga: Manga): List<Int> {
|
||||
return currentItems.mapIndexedNotNull { index, it ->
|
||||
if (it is LibraryItem && it.manga.id == manga.id) index
|
||||
else null }
|
||||
}
|
||||
|
||||
fun performFilter() {
|
||||
val s = getFilter(String::class.java)
|
||||
if (s.isNullOrBlank()) {
|
||||
@ -161,6 +172,6 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
||||
fun onItemReleased(position: Int)
|
||||
fun canDrag(): Boolean
|
||||
fun updateCategory(catId: Int): Boolean
|
||||
fun sortCategory(catId: Int, sortBy: Int): String
|
||||
fun sortCategory(catId: Int, sortBy: Int)
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
val position = adapter.indexOf(manga)
|
||||
if (position != -1 && !adapter.isSelected(position)) {
|
||||
adapter.toggleSelection(position)
|
||||
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation()
|
||||
(recycler.findViewHolderForAdapterPosition(position) as? LibraryHolder)?.toggleActivation()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -272,7 +272,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
val position = adapter.indexOf(manga)
|
||||
if (position != -1) {
|
||||
adapter.toggleSelection(position)
|
||||
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation()
|
||||
(recycler.findViewHolderForAdapterPosition(position) as? LibraryHolder)?.toggleActivation()
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,9 +320,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
lastClickPosition = position
|
||||
}
|
||||
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
|
||||
}
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) { }
|
||||
|
||||
override fun onItemReleased(position: Int) {
|
||||
if (adapter.selectedItemCount == 0) saveDragSort()
|
||||
@ -395,8 +393,5 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
return true
|
||||
}
|
||||
|
||||
override fun sortCategory(catId: Int, sortBy: Int): String {
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun sortCategory(catId: Int, sortBy: Int) { }
|
||||
}
|
||||
|
@ -446,7 +446,7 @@ open class LibraryController(
|
||||
/**
|
||||
* Destroys the action mode.
|
||||
*/
|
||||
private fun destroyActionModeIfNeeded() {
|
||||
protected fun destroyActionModeIfNeeded() {
|
||||
actionMode?.finish()
|
||||
}
|
||||
|
||||
|
@ -131,12 +131,12 @@ class LibraryItem(val manga: LibraryManga,
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is LibraryItem) {
|
||||
return manga.id == other.manga.id
|
||||
return manga.id == other.manga.id && manga.category == other.manga.category
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return manga.id!!.hashCode()
|
||||
return (manga.id!! + (manga.category shl 50).toLong()).hashCode() //!!.hashCode()
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,13 @@ import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.checkbox.checkBoxPrompt
|
||||
import com.afollestad.materialdialogs.checkbox.isCheckPromptChecked
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
@ -58,6 +61,9 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
|
||||
private var spinnerAdapter: SpinnerAdapter? = null
|
||||
|
||||
private var lastItemPostion:Int? = null
|
||||
private var lastItem:IFlexible<*>? = null
|
||||
|
||||
/**
|
||||
* Recycler view of the list of manga.
|
||||
*/
|
||||
@ -261,7 +267,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
override fun setSelection(manga: Manga, selected: Boolean) {
|
||||
if (selected) {
|
||||
if (selectedMangas.add(manga)) {
|
||||
val position = adapter.indexOf(manga)
|
||||
val positions = adapter.allIndexOf(manga)
|
||||
if (adapter.mode != SelectableAdapter.Mode.MULTI) {
|
||||
adapter.mode = SelectableAdapter.Mode.MULTI
|
||||
}
|
||||
@ -269,19 +275,23 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
delay(100)
|
||||
adapter.isLongPressDragEnabled = false
|
||||
}
|
||||
adapter.toggleSelection(position)
|
||||
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation()
|
||||
positions.forEach { position ->
|
||||
adapter.addSelection(position)
|
||||
(recycler.findViewHolderForAdapterPosition(position) as? LibraryHolder)?.toggleActivation()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (selectedMangas.remove(manga)) {
|
||||
val position = adapter.indexOf(manga)
|
||||
val positions = adapter.allIndexOf(manga)
|
||||
lastClickPosition = -1
|
||||
if (selectedMangas.isEmpty()) {
|
||||
adapter.mode = SelectableAdapter.Mode.SINGLE
|
||||
adapter.isLongPressDragEnabled = canDrag()
|
||||
}
|
||||
adapter.toggleSelection(position)
|
||||
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation()
|
||||
positions.forEach { position ->
|
||||
adapter.removeSelection(position)
|
||||
(recycler.findViewHolderForAdapterPosition(position) as? LibraryHolder)?.toggleActivation()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -358,7 +368,20 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
|
||||
override fun onActionStateChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
|
||||
val position = viewHolder?.adapterPosition ?: return
|
||||
if (actionState == 2) onItemLongClick(position)
|
||||
if (actionState == 2) {
|
||||
if (lastItemPostion != null && position != lastItemPostion
|
||||
&& lastItem == adapter.getItem(position)) {
|
||||
// because for whatever reason you can re
|
||||
adapter.removeSelection(position)
|
||||
(recycler.findViewHolderForAdapterPosition(position) as? LibraryHolder)?.toggleActivation()
|
||||
adapter.moveItem(position, lastItemPostion!!)
|
||||
}
|
||||
else {
|
||||
lastItem = adapter.getItem(position)
|
||||
lastItemPostion = position
|
||||
onItemLongClick(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUpdateManga(manga: LibraryManga) {
|
||||
@ -378,10 +401,17 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
invalidateActionMode()
|
||||
}
|
||||
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) { }
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
if (lastItemPostion == toPosition)
|
||||
lastItemPostion = null
|
||||
}
|
||||
|
||||
override fun onItemReleased(position: Int) {
|
||||
if (adapter.selectedItemCount > 0) return
|
||||
if (adapter.selectedItemCount > 0) {
|
||||
lastItemPostion = null
|
||||
return
|
||||
}
|
||||
destroyActionModeIfNeeded()
|
||||
val item = adapter.getItem(position) as? LibraryItem ?: return
|
||||
val newHeader = adapter.getSectionHeader(position) as? LibraryHeaderItem
|
||||
val libraryItems = adapter.getSectionItems(adapter.getSectionHeader(position))
|
||||
@ -390,35 +420,58 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
if (newHeader?.category?.id == item.manga.category) {
|
||||
presenter.rearrangeCategory(item.manga.category, mangaIds)
|
||||
} else {
|
||||
if (presenter.mangaIsInCategory(item.manga, newHeader?.category?.id)) {
|
||||
adapter.moveItem(position, lastItemPostion!!)
|
||||
snack = snackbar_layout?.snack(R.string.already_in_category)
|
||||
return
|
||||
}
|
||||
if (newHeader?.category?.mangaSort == null) {
|
||||
presenter.moveMangaToCategory(item, newHeader?.category?.id, mangaIds, true)
|
||||
} else {
|
||||
MaterialDialog(activity!!).message(R.string.switch_to_dnd)
|
||||
.positiveButton(R.string.action_switch) {
|
||||
presenter.moveMangaToCategory(item, newHeader.category.id, mangaIds, true)
|
||||
}.negativeButton(
|
||||
text = resources?.getString(
|
||||
R.string.keep_current_sort,
|
||||
resources!!.getString(newHeader.category.sortRes()).toLowerCase
|
||||
(Locale.getDefault())
|
||||
)
|
||||
) {
|
||||
presenter.moveMangaToCategory(
|
||||
item, newHeader.category.id, mangaIds, false
|
||||
)
|
||||
}
|
||||
.cancelOnTouchOutside(false)
|
||||
.show()
|
||||
val keepCatSort = preferences.keepCatSort().getOrDefault()
|
||||
if (keepCatSort == 0) {
|
||||
MaterialDialog(activity!!).message(R.string.switch_to_dnd)
|
||||
.positiveButton(R.string.action_switch) {
|
||||
presenter.moveMangaToCategory(
|
||||
item, newHeader.category.id, mangaIds, true
|
||||
)
|
||||
if (it.isCheckPromptChecked()) preferences.keepCatSort().set(2)
|
||||
}
|
||||
.checkBoxPrompt(R.string.remember_choice) {}
|
||||
.negativeButton(
|
||||
text = resources?.getString(
|
||||
R.string.keep_current_sort,
|
||||
resources!!.getString(newHeader.category.sortRes()).toLowerCase(
|
||||
Locale.getDefault()
|
||||
)
|
||||
)
|
||||
) {
|
||||
presenter.moveMangaToCategory(
|
||||
item, newHeader.category.id, mangaIds, false
|
||||
)
|
||||
if (it.isCheckPromptChecked()) preferences.keepCatSort().set(1)
|
||||
}.cancelOnTouchOutside(false).show()
|
||||
}
|
||||
else {
|
||||
presenter.moveMangaToCategory(
|
||||
item, newHeader.category.id, mangaIds, keepCatSort == 2
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
lastItemPostion = null
|
||||
}
|
||||
|
||||
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
|
||||
if (adapter.selectedItemCount > 1)
|
||||
return false
|
||||
//if (adapter.selectedItemCount > 1)
|
||||
// return false
|
||||
if (adapter.isSelected(fromPosition))
|
||||
toggleSelection(fromPosition)
|
||||
return true
|
||||
val item = adapter.getItem(fromPosition) as? LibraryItem ?: return false
|
||||
val newHeader = adapter.getSectionHeader(toPosition) as? LibraryHeaderItem
|
||||
//if (adapter.getItem(toPosition) is LibraryHeaderItem) return false
|
||||
return newHeader?.category?.id == item.manga.category ||
|
||||
!presenter.mangaIsInCategory(item.manga, newHeader?.category?.id)
|
||||
}
|
||||
|
||||
override fun updateCategory(catId: Int): Boolean {
|
||||
@ -438,8 +491,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
return true
|
||||
}
|
||||
|
||||
override fun sortCategory(catId: Int, sortBy: Int): String {
|
||||
override fun sortCategory(catId: Int, sortBy: Int) {
|
||||
presenter.sortCategory(catId, sortBy)
|
||||
return ""
|
||||
}
|
||||
}
|
@ -843,6 +843,11 @@ class LibraryPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
fun mangaIsInCategory(manga: LibraryManga, catId: Int?): Boolean {
|
||||
val categories = db.getCategoriesForManga(manga).executeAsBlocking().map { it.id }
|
||||
return catId in categories
|
||||
}
|
||||
|
||||
private companion object {
|
||||
var currentLibrary:Library? = null
|
||||
}
|
||||
|
@ -1,9 +1,18 @@
|
||||
package eu.kanade.tachiyomi.ui.setting
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.preference.*
|
||||
import androidx.preference.CheckBoxPreference
|
||||
import androidx.preference.DialogPreference
|
||||
import androidx.preference.DropDownPreference
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceGroup
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import eu.kanade.tachiyomi.widget.preference.ExtensionPreference
|
||||
import eu.kanade.tachiyomi.widget.preference.IntListMatPreference
|
||||
import eu.kanade.tachiyomi.widget.preference.ListMatPreference
|
||||
@ -38,6 +47,11 @@ inline fun PreferenceGroup.editTextPreference(block: (@DSL EditTextPreference).(
|
||||
return initThenAdd(EditTextPreference(context), block).also(::initDialog)
|
||||
}
|
||||
|
||||
inline fun PreferenceGroup.dropDownPreference(block: (@DSL DropDownPreference).() -> Unit):
|
||||
DropDownPreference {
|
||||
return initThenAdd(DropDownPreference(context), block).also(::initDialog)
|
||||
}
|
||||
|
||||
inline fun PreferenceGroup.listPreference(activity: Activity?, block: (@DSL ListMatPreference).()
|
||||
-> Unit):
|
||||
ListMatPreference {
|
||||
|
@ -182,6 +182,18 @@ class SettingsLibraryController : SettingsController() {
|
||||
true
|
||||
}
|
||||
}
|
||||
intListPreference(activity) {
|
||||
titleRes = R.string.pref_keep_category_sorting
|
||||
key = Keys.keepCatSort
|
||||
summaryRes = R.string.pref_keep_category_sorting_summary
|
||||
entries = listOf(
|
||||
context.getString(R.string.always_ask),
|
||||
context.getString(R.string.option_keep_category_sort),
|
||||
context.getString(R.string.option_switch_to_dnd)
|
||||
)
|
||||
entryRange = 0..2
|
||||
defaultValue = 0
|
||||
}
|
||||
}
|
||||
if (preferences.skipPreMigration().getOrDefault() || preferences.migrationSources().getOrDefault().isNotEmpty()) {
|
||||
preferenceCategory {
|
||||
|
@ -3,15 +3,9 @@ package eu.kanade.tachiyomi.widget.preference
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.preference.Preference
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.callbacks.onDismiss
|
||||
import com.afollestad.materialdialogs.list.listItemsSingleChoice
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.setting.defaultValue
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class IntListMatPreference @JvmOverloads constructor(activity: Activity?, context: Context,
|
||||
attrs:
|
||||
@ -33,6 +27,7 @@ AttributeSet? =
|
||||
defValue = defaultValue as? Int ?: defValue
|
||||
}
|
||||
override fun getSummary(): CharSequence {
|
||||
if (key == null || useCustomSummary) return super.getSummary()
|
||||
val index = entryValues.indexOf(prefs.getInt(key, defValue).getOrDefault())
|
||||
return if (entries.isEmpty() || index == -1) ""
|
||||
else entries[index]
|
||||
@ -46,7 +41,8 @@ AttributeSet? =
|
||||
initialSelection = default) {
|
||||
_, pos, _ ->
|
||||
val value = entryValues[pos]
|
||||
prefs.getInt(key, defValue).set(value)
|
||||
if (key != null)
|
||||
prefs.getInt(key, defValue).set(value)
|
||||
callChangeListener(value)
|
||||
this@IntListMatPreference.summary = this@IntListMatPreference.summary
|
||||
dismiss()
|
||||
|
@ -6,9 +6,7 @@ import android.util.AttributeSet
|
||||
import androidx.preference.Preference
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.callbacks.onDismiss
|
||||
import com.afollestad.materialdialogs.list.listItemsSingleChoice
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
@ -18,9 +16,19 @@ open class MatPreference @JvmOverloads constructor(val activity: Activity?, cont
|
||||
null) :
|
||||
Preference(context, attrs) {
|
||||
|
||||
protected var useCustomSummary = false
|
||||
protected val prefs: PreferencesHelper = Injekt.get()
|
||||
private var isShowing = false
|
||||
|
||||
override fun setSummary(summaryResId: Int) {
|
||||
useCustomSummary = true
|
||||
super.setSummary(summaryResId)
|
||||
}
|
||||
|
||||
override fun setSummary(summary: CharSequence?) {
|
||||
useCustomSummary = true
|
||||
super.setSummary(summary)
|
||||
}
|
||||
override fun onClick() {
|
||||
if (!isShowing)
|
||||
dialog().apply {
|
||||
|
@ -226,6 +226,13 @@
|
||||
when updating library (overwrites local covers)</string>
|
||||
|
||||
<string name="pref_category_library_migration">Migration</string>
|
||||
<string name="pref_keep_category_sorting">Change category sorting when moving</string>
|
||||
<string name="pref_keep_category_sorting_summary">In single list mode, should dragging and
|
||||
dropping an entry into a new category change the category\'s sorting to drag &
|
||||
drop?</string>
|
||||
<string name="always_ask">Always ask</string>
|
||||
<string name="option_keep_category_sort">Keep current sorting method</string>
|
||||
<string name="option_switch_to_dnd">Switch to Drag & Drop</string>
|
||||
|
||||
|
||||
<!-- Extension section -->
|
||||
@ -430,6 +437,8 @@
|
||||
<item quantity="one">1 downloaded</item>
|
||||
<item quantity="other">%d downloaded</item>
|
||||
</plurals>
|
||||
<string name="remember_choice">Remember this choice</string>
|
||||
<string name="already_in_category">Manga already in category</string>
|
||||
|
||||
<!-- Catalogue fragment -->
|
||||
<string name="source_search_options">Search filters</string>
|
||||
|
Loading…
Reference in New Issue
Block a user