Migrate to LongSet in selection controller
This commit is contained in:
@@ -95,7 +95,7 @@ dependencies {
|
||||
implementation 'androidx.activity:activity-ktx:1.9.0'
|
||||
implementation 'androidx.fragment:fragment-ktx:1.8.1'
|
||||
implementation 'androidx.transition:transition-ktx:1.5.0'
|
||||
implementation 'androidx.collection:collection-ktx:1.4.0'
|
||||
implementation 'androidx.collection:collection-ktx:1.4.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3'
|
||||
implementation 'androidx.lifecycle:lifecycle-service:2.8.3'
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.8.3'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package org.koitharu.kotatsu.core.ui.list
|
||||
|
||||
import android.app.Notification.Action
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.collection.LongSet
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
@@ -14,6 +14,8 @@ import androidx.savedstate.SavedStateRegistry
|
||||
import androidx.savedstate.SavedStateRegistryOwner
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.AbstractSelectionItemDecoration
|
||||
import org.koitharu.kotatsu.core.util.ext.toLongArray
|
||||
import org.koitharu.kotatsu.core.util.ext.toSet
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
private const val KEY_SELECTION = "selection"
|
||||
@@ -35,11 +37,9 @@ class ListSelectionController(
|
||||
registryOwner.lifecycle.addObserver(StateEventObserver())
|
||||
}
|
||||
|
||||
fun snapshot(): Set<Long> {
|
||||
return peekCheckedIds().toSet()
|
||||
}
|
||||
fun snapshot(): Set<Long> = peekCheckedIds().toSet()
|
||||
|
||||
fun peekCheckedIds(): Set<Long> {
|
||||
fun peekCheckedIds(): LongSet {
|
||||
return decoration.checkedItemsIds
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.graphics.Canvas
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.view.View
|
||||
import androidx.collection.LongSet
|
||||
import androidx.collection.MutableLongSet
|
||||
import androidx.core.view.children
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.NO_ID
|
||||
@@ -12,7 +14,7 @@ abstract class AbstractSelectionItemDecoration : RecyclerView.ItemDecoration() {
|
||||
|
||||
private val bounds = Rect()
|
||||
private val boundsF = RectF()
|
||||
protected val selection = HashSet<Long>() // TODO MutableLongSet
|
||||
protected val selection = MutableLongSet()
|
||||
|
||||
protected var hasBackground: Boolean = true
|
||||
protected var hasForeground: Boolean = false
|
||||
@@ -21,7 +23,7 @@ abstract class AbstractSelectionItemDecoration : RecyclerView.ItemDecoration() {
|
||||
val checkedItemsCount: Int
|
||||
get() = selection.size
|
||||
|
||||
val checkedItemsIds: Set<Long>
|
||||
val checkedItemsIds: LongSet
|
||||
get() = selection
|
||||
|
||||
fun toggleItemChecked(id: Long) {
|
||||
@@ -39,7 +41,9 @@ abstract class AbstractSelectionItemDecoration : RecyclerView.ItemDecoration() {
|
||||
}
|
||||
|
||||
fun checkAll(ids: Collection<Long>) {
|
||||
selection.addAll(ids)
|
||||
for (id in ids) {
|
||||
selection.add(id)
|
||||
}
|
||||
}
|
||||
|
||||
fun clearSelection() {
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.util.ext
|
||||
|
||||
import androidx.collection.ArrayMap
|
||||
import androidx.collection.ArraySet
|
||||
import androidx.collection.LongSet
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import java.util.Collections
|
||||
import java.util.EnumSet
|
||||
@@ -77,3 +78,16 @@ inline fun <T, reified R> Collection<T>.mapToArray(transform: (T) -> R): Array<R
|
||||
forEachIndexed { index, t -> result[index] = transform(t) }
|
||||
return result as Array<R>
|
||||
}
|
||||
|
||||
fun LongSet.toLongArray(): LongArray {
|
||||
val result = LongArray(size)
|
||||
var i = 0
|
||||
forEach { result[i++] = it }
|
||||
return result
|
||||
}
|
||||
|
||||
fun LongSet.toSet(): Set<Long> = toCollection(ArraySet<Long>(size))
|
||||
|
||||
fun <R : MutableCollection<Long>> LongSet.toCollection(out: R): R = out.also { result ->
|
||||
forEach(result::add)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
|
||||
import org.koitharu.kotatsu.core.util.ext.findParentCallback
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
import org.koitharu.kotatsu.core.util.ext.toCollection
|
||||
import org.koitharu.kotatsu.core.util.ext.toSet
|
||||
import org.koitharu.kotatsu.databinding.FragmentChaptersBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsViewModel
|
||||
import org.koitharu.kotatsu.details.ui.adapter.ChaptersAdapter
|
||||
@@ -137,10 +139,10 @@ class ChaptersFragment :
|
||||
val ids = selectionController?.peekCheckedIds()
|
||||
val manga = viewModel.manga.value
|
||||
when {
|
||||
ids.isNullOrEmpty() || manga == null -> Unit
|
||||
ids == null || ids.isEmpty() || manga == null -> Unit
|
||||
ids.size == manga.chapters?.size -> viewModel.deleteLocal()
|
||||
else -> {
|
||||
LocalChaptersRemoveService.start(requireContext(), manga, ids)
|
||||
LocalChaptersRemoveService.start(requireContext(), manga, ids.toSet())
|
||||
Snackbar.make(
|
||||
requireViewBinding().recyclerViewChapters,
|
||||
R.string.chapters_will_removed_background,
|
||||
@@ -154,7 +156,7 @@ class ChaptersFragment :
|
||||
|
||||
R.id.action_select_range -> {
|
||||
val items = chaptersAdapter?.items ?: return false
|
||||
val ids = HashSet(controller.peekCheckedIds())
|
||||
val ids = controller.peekCheckedIds().toCollection(HashSet())
|
||||
val buffer = HashSet<Long>()
|
||||
var isAdding = false
|
||||
for (x in items) {
|
||||
@@ -188,8 +190,12 @@ class ChaptersFragment :
|
||||
}
|
||||
|
||||
R.id.action_mark_current -> {
|
||||
val id = controller.peekCheckedIds().singleOrNull() ?: return false
|
||||
viewModel.markChapterAsCurrent(id)
|
||||
val ids = controller.peekCheckedIds()
|
||||
if (ids.size == 1) {
|
||||
viewModel.markChapterAsCurrent(ids.first())
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.download.ui.list
|
||||
|
||||
import androidx.collection.ArrayMap
|
||||
import androidx.collection.LongSet
|
||||
import androidx.collection.LongSparseArray
|
||||
import androidx.collection.getOrElse
|
||||
import androidx.collection.set
|
||||
@@ -182,7 +183,7 @@ class DownloadsViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun snapshot(ids: Set<Long>): Collection<DownloadItemModel> {
|
||||
fun snapshot(ids: LongSet): Collection<DownloadItemModel> {
|
||||
return works.value?.filterTo(ArrayList(ids.size)) { x -> x.id.mostSignificantBits in ids }.orEmpty()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.explore.ui
|
||||
|
||||
import androidx.collection.LongSet
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -126,7 +127,7 @@ class ExploreViewModel @Inject constructor(
|
||||
settings.closeTip(TIP_SUGGESTIONS)
|
||||
}
|
||||
|
||||
fun sourcesSnapshot(ids: Set<Long>): List<MangaSourceInfo> {
|
||||
fun sourcesSnapshot(ids: LongSet): List<MangaSourceInfo> {
|
||||
return content.value.mapNotNull {
|
||||
(it as? MangaSourceItem)?.takeIf { x -> x.id in ids }?.source
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.favourites.ui.categories
|
||||
|
||||
import androidx.collection.LongSet
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -76,7 +77,7 @@ class FavouritesCategoriesViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun getCategories(ids: Set<Long>): ArrayList<FavouriteCategory> {
|
||||
fun getCategories(ids: LongSet): ArrayList<FavouriteCategory> {
|
||||
val items = content.requireValue()
|
||||
return items.mapNotNullTo(ArrayList(ids.size)) { item ->
|
||||
(item as? CategoryListModel)?.category?.takeIf { it.id in ids }
|
||||
|
||||
@@ -14,7 +14,11 @@ import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga
|
||||
class ScrobblerMangaSelectionDecoration(context: Context) : MangaSelectionDecoration(context) {
|
||||
|
||||
var checkedItemId: Long
|
||||
get() = selection.singleOrNull() ?: NO_ID
|
||||
get() = if (selection.size == 1) {
|
||||
selection.first()
|
||||
} else {
|
||||
NO_ID
|
||||
}
|
||||
set(value) {
|
||||
clearSelection()
|
||||
if (value != NO_ID) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.search.ui.multi
|
||||
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.collection.LongSet
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@@ -81,7 +82,7 @@ class MultiSearchViewModel @Inject constructor(
|
||||
}
|
||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, listOf(LoadingState))
|
||||
|
||||
fun getItems(ids: Set<Long>): Set<Manga> {
|
||||
fun getItems(ids: LongSet): Set<Manga> {
|
||||
val snapshot = listData.value ?: return emptySet()
|
||||
val result = HashSet<Manga>(ids.size)
|
||||
snapshot.forEach { x ->
|
||||
|
||||
Reference in New Issue
Block a user