Fix chapters selections
parent
6b786084cf
commit
d588e8d941
@ -0,0 +1,12 @@
|
|||||||
|
package org.koitharu.kotatsu.core.ui.list
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
||||||
|
abstract class BaseListSelectionCallback(
|
||||||
|
protected val recyclerView: RecyclerView,
|
||||||
|
) : ListSelectionController.Callback {
|
||||||
|
|
||||||
|
override fun onSelectionChanged(controller: ListSelectionController, count: Int) {
|
||||||
|
recyclerView.invalidateItemDecorations()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,122 @@
|
|||||||
|
package org.koitharu.kotatsu.details.ui.pager.chapters
|
||||||
|
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.appcompat.view.ActionMode
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.model.LocalMangaSource
|
||||||
|
import org.koitharu.kotatsu.core.ui.list.BaseListSelectionCallback
|
||||||
|
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.toCollection
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.toSet
|
||||||
|
import org.koitharu.kotatsu.details.ui.DetailsViewModel
|
||||||
|
import org.koitharu.kotatsu.local.ui.LocalChaptersRemoveService
|
||||||
|
|
||||||
|
class ChaptersSelectionCallback(
|
||||||
|
private val viewModel: DetailsViewModel,
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
) : BaseListSelectionCallback(recyclerView) {
|
||||||
|
|
||||||
|
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||||
|
mode.menuInflater.inflate(R.menu.mode_chapters, menu)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
|
||||||
|
val selectedIds = controller.peekCheckedIds()
|
||||||
|
val allItems = viewModel.chapters.value
|
||||||
|
val items = allItems.withIndex().filter { it.value.chapter.id in selectedIds }
|
||||||
|
var canSave = true
|
||||||
|
var canDelete = true
|
||||||
|
items.forEach { (_, x) ->
|
||||||
|
val isLocal = x.isDownloaded || x.chapter.source == LocalMangaSource
|
||||||
|
if (isLocal) canSave = false else canDelete = false
|
||||||
|
}
|
||||||
|
menu.findItem(R.id.action_save).isVisible = canSave
|
||||||
|
menu.findItem(R.id.action_delete).isVisible = canDelete
|
||||||
|
menu.findItem(R.id.action_select_all).isVisible = items.size < allItems.size
|
||||||
|
menu.findItem(R.id.action_mark_current).isVisible = items.size == 1
|
||||||
|
mode.title = items.size.toString()
|
||||||
|
var hasGap = false
|
||||||
|
for (i in 0 until items.size - 1) {
|
||||||
|
if (items[i].index + 1 != items[i + 1].index) {
|
||||||
|
hasGap = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu.findItem(R.id.action_select_range).isVisible = hasGap
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
|
R.id.action_save -> {
|
||||||
|
viewModel.download(controller.snapshot())
|
||||||
|
mode.finish()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.action_delete -> {
|
||||||
|
val ids = controller.peekCheckedIds()
|
||||||
|
val manga = viewModel.manga.value
|
||||||
|
when {
|
||||||
|
ids.isEmpty() || manga == null -> Unit
|
||||||
|
ids.size == manga.chapters?.size -> viewModel.deleteLocal()
|
||||||
|
else -> {
|
||||||
|
LocalChaptersRemoveService.start(recyclerView.context, manga, ids.toSet())
|
||||||
|
Snackbar.make(
|
||||||
|
recyclerView,
|
||||||
|
R.string.chapters_will_removed_background,
|
||||||
|
Snackbar.LENGTH_LONG,
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mode.finish()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.action_select_range -> {
|
||||||
|
val items = viewModel.chapters.value
|
||||||
|
val ids = controller.peekCheckedIds().toCollection(HashSet())
|
||||||
|
val buffer = HashSet<Long>()
|
||||||
|
var isAdding = false
|
||||||
|
for (x in items) {
|
||||||
|
if (x.chapter.id in ids) {
|
||||||
|
isAdding = true
|
||||||
|
if (buffer.isNotEmpty()) {
|
||||||
|
ids.addAll(buffer)
|
||||||
|
buffer.clear()
|
||||||
|
}
|
||||||
|
} else if (isAdding) {
|
||||||
|
buffer.add(x.chapter.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
controller.addAll(ids)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.action_select_all -> {
|
||||||
|
val ids = viewModel.chapters.value.map {
|
||||||
|
it.chapter.id
|
||||||
|
}
|
||||||
|
controller.addAll(ids)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.action_mark_current -> {
|
||||||
|
val ids = controller.peekCheckedIds()
|
||||||
|
if (ids.size == 1) {
|
||||||
|
viewModel.markChapterAsCurrent(ids.first())
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mode.finish()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M2.39,1.73L1.11,3L3.19,5.08C2.45,6 2,7.19 2,8.5C2,12.27 5.4,15.36 10.55,20.03L12,21.35L13.45,20.03C14.32,19.24 15.14,18.5 15.9,17.79L20,22L21.27,20.73M12.1,18.55L12,18.65L11.89,18.55C7.14,14.24 4,11.39 4,8.5C4,7.74 4.22,7.06 4.61,6.5L14.5,16.37C13.74,17.06 12.95,17.78 12.1,18.55M8.3,5.1L6.33,3.13C6.7,3.05 7.1,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,10.84 20.69,12.92 18.47,15.27L17.06,13.86C18.91,11.88 20,10.2 20,8.5C20,6.5 18.5,5 16.5,5C15.1,5 13.74,5.83 13.11,7H10.89C10.38,6.06 9.39,5.34 8.3,5.1Z" />
|
||||||
|
</vector>
|
||||||
Loading…
Reference in New Issue