Merge branch 'devel' into feature/nextgen

This commit is contained in:
Koitharu
2022-07-04 15:40:49 +03:00
14 changed files with 375 additions and 119 deletions

View File

@@ -17,6 +17,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseActivity
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.databinding.ActivitySearchMultiBinding
import org.koitharu.kotatsu.details.ui.DetailsActivity
@@ -32,14 +33,14 @@ import org.koitharu.kotatsu.search.ui.multi.adapter.MultiSearchAdapter
import org.koitharu.kotatsu.utils.ShareHelper
import org.koitharu.kotatsu.utils.ext.findViewsByType
class MultiSearchActivity : BaseActivity<ActivitySearchMultiBinding>(), MangaListListener, ActionMode.Callback {
class MultiSearchActivity : BaseActivity<ActivitySearchMultiBinding>(), MangaListListener,
ListSelectionController.Callback {
private val viewModel by viewModel<MultiSearchViewModel> {
parametersOf(intent.getStringExtra(EXTRA_QUERY).orEmpty())
}
private lateinit var adapter: MultiSearchAdapter
private lateinit var selectionDecoration: MangaSelectionDecoration
private var actionMode: ActionMode? = null
private lateinit var selectionController: ListSelectionController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -51,7 +52,13 @@ class MultiSearchActivity : BaseActivity<ActivitySearchMultiBinding>(), MangaLis
}
}
val sizeResolver = ItemSizeResolver(resources, get())
selectionDecoration = MangaSelectionDecoration(this)
val selectionDecoration = MangaSelectionDecoration(this)
selectionController = ListSelectionController(
activity = this,
decoration = selectionDecoration,
registryOwner = this,
callback = this,
)
adapter = MultiSearchAdapter(
lifecycleOwner = this,
coil = get(),
@@ -90,29 +97,14 @@ class MultiSearchActivity : BaseActivity<ActivitySearchMultiBinding>(), MangaLis
}
override fun onItemClick(item: Manga, view: View) {
if (selectionDecoration.checkedItemsCount != 0) {
selectionDecoration.toggleItemChecked(item.id)
if (selectionDecoration.checkedItemsCount == 0) {
actionMode?.finish()
} else {
actionMode?.invalidate()
invalidateItemDecorations()
}
return
if (!selectionController.onItemClick(item.id)) {
val intent = DetailsActivity.newIntent(this, item)
startActivity(intent)
}
val intent = DetailsActivity.newIntent(this, item)
startActivity(intent)
}
override fun onItemLongClick(item: Manga, view: View): Boolean {
if (actionMode == null) {
actionMode = startSupportActionMode(this)
}
return actionMode?.also {
selectionDecoration.setItemIsChecked(item.id, true)
invalidateItemDecorations()
it.invalidate()
} != null
return selectionController.onItemLongClick(item.id)
}
override fun onRetryClick(error: Throwable) {
@@ -131,7 +123,7 @@ class MultiSearchActivity : BaseActivity<ActivitySearchMultiBinding>(), MangaLis
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
mode.title = selectionDecoration.checkedItemsCount.toString()
mode.title = selectionController.count.toString()
return true
}
@@ -156,22 +148,16 @@ class MultiSearchActivity : BaseActivity<ActivitySearchMultiBinding>(), MangaLis
}
}
override fun onDestroyActionMode(mode: ActionMode) {
selectionDecoration.clearSelection()
invalidateItemDecorations()
actionMode = null
}
private fun collectSelectedItems(): Set<Manga> {
return viewModel.getItems(selectionDecoration.checkedItemsIds)
}
private fun invalidateItemDecorations() {
override fun onSelectionChanged(count: Int) {
binding.recyclerView.findViewsByType(RecyclerView::class.java).forEach {
it.invalidateItemDecorations()
}
}
private fun collectSelectedItems(): Set<Manga> {
return viewModel.getItems(selectionController.peekCheckedIds())
}
companion object {
private const val EXTRA_QUERY = "query"

View File

@@ -6,6 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
class MultiSearchListModel(
val source: MangaSource,
val hasMore: Boolean,
val list: List<MangaItemModel>,
) : ListModel {
@@ -16,6 +17,7 @@ class MultiSearchListModel(
other as MultiSearchListModel
if (source != other.source) return false
if (hasMore != other.hasMore) return false
if (list != other.list) return false
return true
@@ -23,6 +25,7 @@ class MultiSearchListModel(
override fun hashCode(): Int {
var result = source.hashCode()
result = 31 * result + hasMore.hashCode()
result = 31 * result + list.hashCode()
return result
}

View File

@@ -19,6 +19,7 @@ import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
private const val MAX_PARALLELISM = 4
private const val MIN_HAS_MORE_ITEMS = 8
class MultiSearchViewModel(
initialQuery: String,
@@ -98,7 +99,7 @@ class MultiSearchViewModel(
val list = MangaRepository(source).getList(offset = 0, query = q)
.toUi(ListMode.GRID)
if (list.isNotEmpty()) {
MultiSearchListModel(source, list)
MultiSearchListModel(source, list.size > MIN_HAS_MORE_ITEMS, list)
} else {
null
}

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.search.ui.multi.adapter
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import coil.ImageLoader
@@ -38,11 +39,12 @@ fun searchResultsAD(
val spacing = context.resources.getDimensionPixelOffset(R.dimen.grid_spacing)
binding.recyclerView.addItemDecoration(SpacingItemDecoration(spacing))
val eventListener = AdapterDelegateClickListenerAdapter(this, itemClickListener)
itemView.setOnClickListener(eventListener)
binding.buttonMore.setOnClickListener(eventListener)
bind {
binding.textViewTitle.text = item.source.title
adapter.items = item.list
binding.buttonMore.isVisible = item.hasMore
adapter.notifyDataSetChanged()
adapter.items = item.list
}
}