diff --git a/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreAdapter.kt b/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreAdapter.kt index 1432e00da..e7746f489 100644 --- a/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreAdapter.kt +++ b/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreAdapter.kt @@ -35,8 +35,16 @@ class ExploreAdapter(context: Context, val callBack: CallBack) : RecyclerAdapter(context) { private val recycler = arrayListOf() - private var exIndex = -1 - private var scrollTo = -1 + private var expandedId: String? = null + private var scrollToId: String? = null + + init { + setHasStableIds(true) + } + + override fun getItemId(position: Int): Long { + return getItem(position)?.bookSourceUrl.hashCode().toLong() + } override fun getViewBinding(parent: ViewGroup): ItemFindBookBinding { return ItemFindBookBinding.inflate(inflater, parent, false) @@ -53,12 +61,16 @@ class ExploreAdapter(context: Context, val callBack: CallBack) : tvName.text = item.bookSourceName } - if (exIndex == holder.layoutPosition) { + val isExpanded = (item.bookSourceUrl == expandedId) + + if (isExpanded) { ivStatus.icon = ContextCompat.getDrawable(context, R.drawable.ic_arrow_right) ivStatus.rotation = 90f - if (scrollTo >= 0) { - callBack.scrollTo(scrollTo) + if (scrollToId == item.bookSourceUrl) { + val pos = holder.bindingAdapterPosition + if (pos >= 0) callBack.scrollTo(pos) + scrollToId = null } Coroutine.async(callBack.scope) { @@ -102,7 +114,6 @@ class ExploreAdapter(context: Context, val callBack: CallBack) : } } - @Synchronized private fun getFlexboxChild(flexbox: FlexboxLayout): MaterialCardView { return if (recycler.isEmpty()) { @@ -121,33 +132,43 @@ class ExploreAdapter(context: Context, val callBack: CallBack) : override fun registerListener(holder: ItemViewHolder, binding: ItemFindBookBinding) { binding.apply { llTitle.setOnClickListener { - val position = holder.layoutPosition - val oldEx = exIndex - exIndex = if (exIndex == position) -1 else position - notifyItemChanged(oldEx, false) - if (exIndex != -1) { - scrollTo = position - callBack.scrollTo(position) - notifyItemChanged(position, false) + val item = getItem(holder.bindingAdapterPosition) ?: return@setOnClickListener + val oldId = expandedId + expandedId = if (expandedId == item.bookSourceUrl) null else item.bookSourceUrl + notifyItemChangedById(oldId) + notifyItemChangedById(expandedId) + + if (expandedId != null) { + scrollToId = expandedId + callBack.scrollTo(holder.bindingAdapterPosition) } } llTitle.onLongClick { - showMenu(llTitle, holder.layoutPosition) + showMenu(llTitle, holder.bindingAdapterPosition) } } } fun compressExplore(): Boolean { - return if (exIndex < 0) { + return if (expandedId == null) { false } else { - val oldExIndex = exIndex - exIndex = -1 - notifyItemChanged(oldExIndex) + val oldId = expandedId + expandedId = null + notifyItemChangedById(oldId) true } } - + private fun notifyItemChangedById(id: String?) { + id ?: return + for (pos in 0 until itemCount) { + val item = getItem(pos) ?: continue + if (item.bookSourceUrl == id) { + notifyItemChanged(pos) + break + } + } + } private fun showMenu(view: View, position: Int) { val source = getItem(position) ?: return val popupMenu = PopupMenu(context, view) @@ -162,13 +183,11 @@ class ExploreAdapter(context: Context, val callBack: CallBack) : putExtra("type", "bookSource") putExtra("key", source.bookSourceUrl) } - R.id.menu_refresh -> Coroutine.async(callBack.scope) { source.clearExploreKindsCache() }.onSuccess { notifyItemChanged(position) } - R.id.menu_del -> callBack.deleteSource(source) } true diff --git a/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreFragment.kt b/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreFragment.kt index 1a58e921f..e3e9ffdf2 100644 --- a/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreFragment.kt +++ b/app/src/main/java/io/legato/kazusa/ui/main/explore/ExploreFragment.kt @@ -188,11 +188,13 @@ class ExploreFragment() : VMBaseFragment(R.layout.fragment_exp private fun upGroupsMenu() = groupsMenu?.transaction { subMenu -> subMenu.removeGroup(R.id.menu_group_text) + subMenu.add(R.id.menu_group_text, Menu.NONE, Menu.NONE, getString(R.string.all)) groups.forEach { subMenu.add(R.id.menu_group_text, Menu.NONE, Menu.NONE, it) } } + override val scope: CoroutineScope get() = viewLifecycleOwner.lifecycleScope @@ -205,16 +207,23 @@ class ExploreFragment() : VMBaseFragment(R.layout.fragment_exp override fun onCompatOptionsItemSelected(item: MenuItem) { super.onCompatOptionsItemSelected(item) if (item.groupId == R.id.menu_group_text) { - val query = "group:${item.title}" - searchView.setText(query) - upExploreData(query) - }else if (item.itemId == R.id.menu_exp_search) { + val title = item.title.toString() + if (title == getString(R.string.all)) { + searchView.setText("") + upExploreData(null) + } else { + val query = "group:$title" + searchView.setText(query) + upExploreData(query) + } + } else if (item.itemId == R.id.menu_exp_search) { TransitionManager.beginDelayedTransition(binding.rootView) binding.searchBar.visibility = if (binding.searchBar.isVisible) View.GONE else View.VISIBLE } } + override fun scrollTo(pos: Int) { (binding.rvFind.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(pos, 0) }