From 95a4bf41d244344cf3ad991403bd2bfa9fda2b3c Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 2 Nov 2020 19:54:43 +0200 Subject: [PATCH] Popup menu on favourite tabs --- .../favourites/FavouritesContainerFragment.kt | 36 ++++++++++- .../list/favourites/FavouritesPagerAdapter.kt | 15 ++++- .../FavouritesTabLongClickListener.kt | 9 +++ .../categories/CategoriesActivity.kt | 51 ++++------------ .../categories/CategoriesEditDelegate.kt | 61 +++++++++++++++++++ .../FavouriteCategoriesPresenter.kt | 1 - .../org/koitharu/kotatsu/utils/ext/ViewExt.kt | 22 +++---- .../main/res/menu/popup_category_empty.xml | 9 +++ app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 10 files changed, 148 insertions(+), 58 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesTabLongClickListener.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesEditDelegate.kt create mode 100644 app/src/main/res/menu/popup_category_empty.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesContainerFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesContainerFragment.kt index 8cad00353..3bc872ec4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesContainerFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesContainerFragment.kt @@ -15,16 +15,21 @@ import org.koitharu.kotatsu.domain.favourites.FavouritesRepository import org.koitharu.kotatsu.domain.favourites.OnFavouritesChangeListener import org.koitharu.kotatsu.ui.base.BaseFragment import org.koitharu.kotatsu.ui.list.favourites.categories.CategoriesActivity +import org.koitharu.kotatsu.ui.list.favourites.categories.CategoriesEditDelegate import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesPresenter import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesView +import org.koitharu.kotatsu.utils.ext.showPopupMenu import java.util.* import kotlin.collections.ArrayList class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), - FavouriteCategoriesView, - OnFavouritesChangeListener { + FavouriteCategoriesView, OnFavouritesChangeListener, FavouritesTabLongClickListener, + CategoriesEditDelegate.CategoriesEditCallback { private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter) + private val editDelegate by lazy(LazyThreadSafetyMode.NONE) { + CategoriesEditDelegate(requireContext(), this) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -33,7 +38,7 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val adapter = FavouritesPagerAdapter(this) + val adapter = FavouritesPagerAdapter(this, this) pager.adapter = adapter TabLayoutMediator(tabs, pager, adapter).attach() FavouritesRepository.subscribe(this) @@ -82,6 +87,31 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), presenter.loadAllCategories() } + override fun onTabLongClick(tabView: View, category: FavouriteCategory): Boolean { + val menuRes = if (category.id == 0L) R.menu.popup_category_empty else R.menu.popup_category + tabView.showPopupMenu(menuRes) { + when (it.itemId) { + R.id.action_remove -> editDelegate.deleteCategory(category) + R.id.action_rename -> editDelegate.renameCategory(category) + R.id.action_create -> editDelegate.createCategory() + } + true + } + return true + } + + override fun onDeleteCategory(category: FavouriteCategory) { + presenter.deleteCategory(category.id) + } + + override fun onRenameCategory(category: FavouriteCategory, newName: String) { + presenter.renameCategory(category.id, newName) + } + + override fun onCreateCategory(name: String) { + presenter.createCategory(name) + } + companion object { fun newInstance() = FavouritesContainerFragment() diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesPagerAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesPagerAdapter.kt index 7c7f1ffb4..f8db9be9c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesPagerAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesPagerAdapter.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.ui.list.favourites +import android.view.View import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayout @@ -8,8 +9,11 @@ import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.ui.base.list.AdapterUpdater import org.koitharu.kotatsu.utils.ext.replaceWith -class FavouritesPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment), - TabLayoutMediator.TabConfigurationStrategy { +class FavouritesPagerAdapter( + fragment: Fragment, + private val longClickListener: FavouritesTabLongClickListener +) : FragmentStateAdapter(fragment), + TabLayoutMediator.TabConfigurationStrategy, View.OnLongClickListener { private val dataSet = ArrayList() @@ -23,6 +27,8 @@ class FavouritesPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment override fun onConfigureTab(tab: TabLayout.Tab, position: Int) { val item = dataSet[position] tab.text = item.title + tab.view.tag = item + tab.view.setOnLongClickListener(this) } fun replaceData(data: List) { @@ -30,4 +36,9 @@ class FavouritesPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment dataSet.replaceWith(data) updater(this) } + + override fun onLongClick(v: View): Boolean { + val item = v.tag as? FavouriteCategory ?: return false + return longClickListener.onTabLongClick(v, item) + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesTabLongClickListener.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesTabLongClickListener.kt new file mode 100644 index 000000000..63709f134 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesTabLongClickListener.kt @@ -0,0 +1,9 @@ +package org.koitharu.kotatsu.ui.list.favourites + +import android.view.View +import org.koitharu.kotatsu.core.model.FavouriteCategory + +fun interface FavouritesTabLongClickListener { + + fun onTabLongClick(tabView: View, category: FavouriteCategory): Boolean +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesActivity.kt index d7dee74c7..2ba84ce7d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesActivity.kt @@ -5,31 +5,29 @@ import android.content.Intent import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle -import android.text.InputType import android.view.View import androidx.core.view.isVisible import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_categories.* import moxy.ktx.moxyPresenter import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.ui.base.BaseActivity -import org.koitharu.kotatsu.ui.base.dialog.TextInputDialog import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.showPopupMenu class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener, - FavouriteCategoriesView, View.OnClickListener { + FavouriteCategoriesView, View.OnClickListener, CategoriesEditDelegate.CategoriesEditCallback { private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter) private lateinit var adapter: CategoriesAdapter private lateinit var reorderHelper: ItemTouchHelper + private lateinit var editDelegate: CategoriesEditDelegate override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -37,6 +35,7 @@ class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener createCategory() + R.id.fab_add -> editDelegate.createCategory() } } override fun onItemClick(item: FavouriteCategory, position: Int, view: View) { view.showPopupMenu(R.menu.popup_category) { when (it.itemId) { - R.id.action_remove -> deleteCategory(item) - R.id.action_rename -> renameCategory(item) + R.id.action_remove -> editDelegate.deleteCategory(item) + R.id.action_rename -> editDelegate.renameCategory(item) } true } @@ -79,42 +78,16 @@ class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener - presenter.deleteCategory(category.id) - }.create() - .show() + override fun onDeleteCategory(category: FavouriteCategory) { + presenter.deleteCategory(category.id) } - private fun renameCategory(category: FavouriteCategory) { - TextInputDialog.Builder(this) - .setTitle(R.string.rename) - .setText(category.title) - .setHint(R.string.enter_category_name) - .setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) - .setNegativeButton(android.R.string.cancel) - .setMaxLength(12, false) - .setPositiveButton(R.string.rename) { _, name -> - presenter.renameCategory(category.id, name) - }.create() - .show() + override fun onRenameCategory(category: FavouriteCategory, newName: String) { + presenter.renameCategory(category.id, newName) } - private fun createCategory() { - TextInputDialog.Builder(this) - .setTitle(R.string.add_new_category) - .setHint(R.string.enter_category_name) - .setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) - .setNegativeButton(android.R.string.cancel) - .setMaxLength(12, false) - .setPositiveButton(R.string.add) { _, name -> - presenter.createCategory(name) - }.create() - .show() + override fun onCreateCategory(name: String) { + presenter.createCategory(name) } private inner class ReorderHelperCallback : ItemTouchHelper.SimpleCallback( diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesEditDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesEditDelegate.kt new file mode 100644 index 000000000..1401e2213 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesEditDelegate.kt @@ -0,0 +1,61 @@ +package org.koitharu.kotatsu.ui.list.favourites.categories + +import android.content.Context +import android.text.InputType +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.ui.base.dialog.TextInputDialog + +class CategoriesEditDelegate( + private val context: Context, + private val callback: CategoriesEditCallback +) { + + fun deleteCategory(category: FavouriteCategory) { + MaterialAlertDialogBuilder(context) + .setMessage(context.getString(R.string.category_delete_confirm, category.title)) + .setTitle(R.string.remove_category) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(R.string.remove) { _, _ -> + callback.onDeleteCategory(category) + }.create() + .show() + } + + fun renameCategory(category: FavouriteCategory) { + TextInputDialog.Builder(context) + .setTitle(R.string.rename) + .setText(category.title) + .setHint(R.string.enter_category_name) + .setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) + .setNegativeButton(android.R.string.cancel) + .setMaxLength(12, false) + .setPositiveButton(R.string.rename) { _, name -> + callback.onRenameCategory(category, name) + }.create() + .show() + } + + fun createCategory() { + TextInputDialog.Builder(context) + .setTitle(R.string.add_new_category) + .setHint(R.string.enter_category_name) + .setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) + .setNegativeButton(android.R.string.cancel) + .setMaxLength(12, false) + .setPositiveButton(R.string.add) { _, name -> + callback.onCreateCategory(name) + }.create() + .show() + } + + interface CategoriesEditCallback { + + fun onDeleteCategory(category: FavouriteCategory) + + fun onRenameCategory(category: FavouriteCategory, newName: String) + + fun onCreateCategory(name: String) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt index 7a9795095..02a966f3d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt @@ -45,7 +45,6 @@ class FavouriteCategoriesPresenter : BasePresenter() { fun renameCategory(id: Long, name: String) { launchJob { repository.renameCategory(id, name) - } } diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt index f9f502383..da85fc752 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt @@ -3,7 +3,10 @@ package org.koitharu.kotatsu.utils.ext import android.app.Activity import android.graphics.Rect import android.util.Log -import android.view.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.View +import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.TextView import androidx.annotation.LayoutRes @@ -14,7 +17,6 @@ import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.view.postDelayed import androidx.drawerlayout.widget.DrawerLayout -import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 @@ -35,13 +37,6 @@ fun View.showKeyboard() { inline fun ViewGroup.inflate(@LayoutRes resId: Int) = LayoutInflater.from(context).inflate(resId, this, false) as T -fun RecyclerView.lookupSpanSize(callback: (Int) -> Int) { - (layoutManager as? GridLayoutManager)?.spanSizeLookup = - object : GridLayoutManager.SpanSizeLookup() { - override fun getSpanSize(position: Int) = callback(position) - } -} - val RecyclerView.hasItems: Boolean get() = (adapter?.itemCount ?: 0) > 0 @@ -82,14 +77,15 @@ fun View.disableFor(timeInMillis: Long) { } } -fun View.showPopupMenu( - @MenuRes menuRes: Int, onPrepare: ((Menu) -> Unit)? = null, - onItemClick: (MenuItem) -> Boolean +inline fun View.showPopupMenu( + @MenuRes menuRes: Int, + onPrepare: (Menu) -> Unit = {}, + onItemClick: PopupMenu.OnMenuItemClickListener ) { val menu = PopupMenu(context, this) menu.inflate(menuRes) menu.setOnMenuItemClickListener(onItemClick) - onPrepare?.invoke(menu.menu) + onPrepare(menu.menu) menu.show() } diff --git a/app/src/main/res/menu/popup_category_empty.xml b/app/src/main/res/menu/popup_category_empty.xml new file mode 100644 index 000000000..740312ef1 --- /dev/null +++ b/app/src/main/res/menu/popup_category_empty.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 2cfc33a41..07453c1cf 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -162,4 +162,5 @@ Справа налево Предпочитать режим Справа налево Вы можете настроить режим чтения для каждой манги отдельно + Создать категорию \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e30893499..6d346b2a1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -163,4 +163,5 @@ Right to left Prefer Right to left reader You can set up the reading mode for each manga separately + New category \ No newline at end of file