diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt index 7378b5acf..23ec29339 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt @@ -45,7 +45,7 @@ abstract class BaseBottomSheet : BottomSheetDialogFragment() { requireContext().displayCompat?.let { val metrics = DisplayMetrics() it.getRealMetrics(metrics) - behavior?.peekHeight = metrics.heightPixels / 2 + behavior?.peekHeight = (metrics.heightPixels * 0.4).toInt() } return binding.root diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt index 5f1f0cd5e..c0d9c8c53 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt @@ -16,10 +16,7 @@ class WindowInsetsDelegate( private var lastInsets: Insets? = null - override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat?): WindowInsetsCompat? { - if (insets == null) { - return null - } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { val handledInsets = interceptingWindowInsetsListener?.onApplyWindowInsets(v, insets) ?: insets val newInsets = if (handleImeInsets) { Insets.max( @@ -49,7 +46,7 @@ class WindowInsetsDelegate( ) { view.removeOnLayoutChangeListener(this) if (lastInsets == null) { // Listener may not be called - onApplyWindowInsets(view, ViewCompat.getRootWindowInsets(view)) + onApplyWindowInsets(view, ViewCompat.getRootWindowInsets(view) ?: return) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index a9a57e30e..283a141d3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.view.ActionMode import androidx.appcompat.widget.SearchView import androidx.core.graphics.Insets +import androidx.core.view.MenuProvider import androidx.core.view.isVisible import androidx.core.view.updatePadding import com.google.android.material.snackbar.Snackbar @@ -27,6 +28,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback +import org.koitharu.kotatsu.utils.ext.addMenuProvider import kotlin.math.roundToInt class ChaptersFragment : @@ -43,11 +45,6 @@ class ChaptersFragment : private var actionMode: ActionMode? = null private var selectionDecoration: ChaptersSelectionDecoration? = null - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - override fun onInflateView( inflater: LayoutInflater, container: ViewGroup? @@ -72,6 +69,7 @@ class ChaptersFragment : binding.textViewHolder.isVisible = it activity?.invalidateOptionsMenu() } + addMenuProvider(ChaptersMenuProvider()) } override fun onDestroyView() { @@ -81,31 +79,6 @@ class ChaptersFragment : super.onDestroyView() } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.opt_chapters, menu) - val searchMenuItem = menu.findItem(R.id.action_search) - searchMenuItem.setOnActionExpandListener(this) - val searchView = searchMenuItem.actionView as SearchView - searchView.setOnQueryTextListener(this) - searchView.setIconifiedByDefault(false) - searchView.queryHint = searchMenuItem.title - } - - override fun onPrepareOptionsMenu(menu: Menu) { - super.onPrepareOptionsMenu(menu) - menu.findItem(R.id.action_reversed).isChecked = viewModel.isChaptersReversed.value == true - menu.findItem(R.id.action_search).isVisible = viewModel.isChaptersEmpty.value == false - } - - override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { - R.id.action_reversed -> { - viewModel.setChaptersReversed(!item.isChecked) - true - } - else -> super.onOptionsItemSelected(item) - } - override fun onItemClick(item: ChapterListItem, view: View) { if (selectionDecoration?.checkedItemsCount != 0) { selectionDecoration?.toggleItemChecked(item.chapter.id) @@ -268,4 +241,30 @@ class ChaptersFragment : private fun onLoadingStateChanged(isLoading: Boolean) { binding.progressBar.isVisible = isLoading } + + private inner class ChaptersMenuProvider : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_chapters, menu) + val searchMenuItem = menu.findItem(R.id.action_search) + searchMenuItem.setOnActionExpandListener(this@ChaptersFragment) + val searchView = searchMenuItem.actionView as SearchView + searchView.setOnQueryTextListener(this@ChaptersFragment) + searchView.setIconifiedByDefault(false) + searchView.queryHint = searchMenuItem.title + } + + override fun onPrepareMenu(menu: Menu) { + menu.findItem(R.id.action_reversed).isChecked = viewModel.isChaptersReversed.value == true + menu.findItem(R.id.action_search).isVisible = viewModel.isChaptersEmpty.value == false + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { + R.id.action_reversed -> { + viewModel.setChaptersReversed(!menuItem.isChecked) + true + } + else -> false + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index ec4b8e499..dc5e6a513 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -15,8 +15,6 @@ import android.widget.Toast import androidx.appcompat.view.ActionMode import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.Insets -import androidx.core.net.toFile -import androidx.core.net.toUri import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding @@ -45,7 +43,6 @@ import org.koitharu.kotatsu.parsers.util.mapNotNullToSet import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.search.ui.multi.MultiSearchActivity -import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.getDisplayMessage class DetailsActivity : @@ -166,16 +163,6 @@ class DetailsActivity : } override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { - R.id.action_share -> { - viewModel.manga.value?.let { - if (it.source == MangaSource.LOCAL) { - ShareHelper(this).shareCbz(listOf(it.url.toUri().toFile())) - } else { - ShareHelper(this).shareMangaLink(it) - } - } - true - } R.id.action_delete -> { val title = viewModel.manga.value?.title.orEmpty() MaterialAlertDialogBuilder(this) diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index 54ae95a5b..dfc427d99 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -8,8 +8,10 @@ import android.view.* import androidx.appcompat.widget.PopupMenu import androidx.core.content.ContextCompat import androidx.core.graphics.Insets +import androidx.core.net.toFile import androidx.core.net.toUri import androidx.core.text.parseAsHtml +import androidx.core.view.MenuProvider import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.view.updatePadding @@ -40,6 +42,7 @@ import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.search.ui.MangaListActivity import org.koitharu.kotatsu.search.ui.SearchActivity import org.koitharu.kotatsu.utils.FileSize +import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.* class DetailsFragment : @@ -52,11 +55,6 @@ class DetailsFragment : private val viewModel by sharedViewModel() private val coil by inject(mode = LazyThreadSafetyMode.NONE) - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - override fun onInflateView( inflater: LayoutInflater, container: ViewGroup?, @@ -76,11 +74,7 @@ class DetailsFragment : viewModel.favouriteCategories.observe(viewLifecycleOwner, ::onFavouriteChanged) viewModel.readingHistory.observe(viewLifecycleOwner, ::onHistoryChanged) viewModel.bookmarks.observe(viewLifecycleOwner, ::onBookmarksChanged) - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.opt_details_info, menu) + addMenuProvider(DetailsMenuProvider()) } override fun onItemClick(item: Bookmark, view: View) { @@ -329,4 +323,26 @@ class DetailsFragment : } ?: request.fallback(R.drawable.ic_placeholder) request.enqueueWith(coil) } + + private inner class DetailsMenuProvider : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_details_info, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { + R.id.action_share -> { + viewModel.manga.value?.let { + val context = requireContext() + if (it.source == MangaSource.LOCAL) { + ShareHelper(context).shareCbz(listOf(it.url.toUri().toFile())) + } else { + ShareHelper(context).shareMangaLink(it) + } + } + true + } + else -> false + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt index 8e9d945a0..22939d9d9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt @@ -1,7 +1,9 @@ package org.koitharu.kotatsu.favourites.ui import android.os.Bundle -import android.view.* +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import androidx.appcompat.view.ActionMode import androidx.appcompat.widget.PopupMenu import androidx.core.graphics.Insets @@ -19,12 +21,12 @@ import org.koitharu.kotatsu.base.ui.util.ActionModeListener import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.databinding.FragmentFavouritesBinding import org.koitharu.kotatsu.databinding.ItemEmptyStateBinding -import org.koitharu.kotatsu.favourites.ui.categories.CategoriesActivity import org.koitharu.kotatsu.favourites.ui.categories.CategoriesEditDelegate import org.koitharu.kotatsu.favourites.ui.categories.FavouritesCategoriesViewModel import org.koitharu.kotatsu.favourites.ui.categories.adapter.CategoryListModel import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity import org.koitharu.kotatsu.main.ui.AppBarOwner +import org.koitharu.kotatsu.utils.ext.addMenuProvider import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.measureHeight import org.koitharu.kotatsu.utils.ext.resolveDp @@ -43,11 +45,6 @@ class FavouritesContainerFragment : private var pagerAdapter: FavouritesPagerAdapter? = null private var stubBinding: ItemEmptyStateBinding? = null - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - override fun onInflateView( inflater: LayoutInflater, container: ViewGroup? @@ -61,6 +58,7 @@ class FavouritesContainerFragment : pagerAdapter = adapter TabLayoutMediator(binding.tabs, binding.pager, adapter).attach() actionModeDelegate.addListener(this, viewLifecycleOwner) + addMenuProvider(FavouritesContainerMenuProvider(view.context)) viewModel.visibleCategories.observe(viewLifecycleOwner, ::onCategoriesChanged) viewModel.onError.observe(viewLifecycleOwner, ::onError) @@ -115,21 +113,6 @@ class FavouritesContainerFragment : } } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.opt_favourites, menu) - super.onCreateOptionsMenu(menu, inflater) - } - - override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { - R.id.action_categories -> { - context?.let { - startActivity(CategoriesActivity.newIntent(it)) - } - true - } - else -> super.onOptionsItemSelected(item) - } - private fun onError(e: Throwable) { Snackbar.make(binding.pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show() } diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerMenuProvider.kt new file mode 100644 index 000000000..1b07f535d --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerMenuProvider.kt @@ -0,0 +1,28 @@ +package org.koitharu.kotatsu.favourites.ui + +import android.content.Context +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.favourites.ui.categories.CategoriesActivity + +class FavouritesContainerMenuProvider( + private val context: Context, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_favourites, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when (menuItem.itemId) { + R.id.action_categories -> { + context.startActivity(CategoriesActivity.newIntent(context)) + true + } + else -> false + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt index 8d4b9e419..4d55137a2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt @@ -2,18 +2,15 @@ package org.koitharu.kotatsu.favourites.ui.list import android.os.Bundle import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import android.view.View import androidx.appcompat.view.ActionMode -import androidx.core.view.iterator import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.ui.titleRes -import org.koitharu.kotatsu.favourites.ui.categories.CategoriesActivity import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.utils.ext.addMenuProvider import org.koitharu.kotatsu.utils.ext.withArgs class FavouritesListFragment : MangaListFragment() { @@ -30,46 +27,13 @@ class FavouritesListFragment : MangaListFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.sortOrder.observe(viewLifecycleOwner) { activity?.invalidateOptionsMenu() } - } - - override fun onScrolledToEnd() = Unit - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) if (categoryId != NO_ID) { - inflater.inflate(R.menu.opt_favourites_list, menu) - menu.findItem(R.id.action_order)?.subMenu?.let { submenu -> - for ((i, item) in CategoriesActivity.SORT_ORDERS.withIndex()) { - val menuItem = submenu.add(R.id.group_order, Menu.NONE, i, item.titleRes) - menuItem.isCheckable = true - } - submenu.setGroupCheckable(R.id.group_order, true, true) - } + addMenuProvider(FavouritesListMenuProvider(viewModel)) } } - override fun onPrepareOptionsMenu(menu: Menu) { - super.onPrepareOptionsMenu(menu) - menu.findItem(R.id.action_order)?.subMenu?.let { submenu -> - val selectedOrder = viewModel.sortOrder.value - for (item in submenu) { - val order = CategoriesActivity.SORT_ORDERS.getOrNull(item.order) - item.isChecked = order == selectedOrder - } - } - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when { - item.itemId == R.id.action_order -> false - item.groupId == R.id.group_order -> { - val order = CategoriesActivity.SORT_ORDERS.getOrNull(item.order) ?: return false - viewModel.setSortOrder(order) - true - } - else -> super.onOptionsItemSelected(item) - } - } + override fun onScrolledToEnd() = Unit override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { mode.menuInflater.inflate(R.menu.mode_favourites, menu) diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListMenuProvider.kt new file mode 100644 index 000000000..2a1b08876 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListMenuProvider.kt @@ -0,0 +1,48 @@ +package org.koitharu.kotatsu.favourites.ui.list + +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import androidx.core.view.iterator +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.ui.titleRes +import org.koitharu.kotatsu.favourites.ui.categories.CategoriesActivity + +class FavouritesListMenuProvider( + private val viewModel: FavouritesListViewModel, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_favourites_list, menu) + menu.findItem(R.id.action_order)?.subMenu?.let { submenu -> + for ((i, item) in CategoriesActivity.SORT_ORDERS.withIndex()) { + val menuItem = submenu.add(R.id.group_order, Menu.NONE, i, item.titleRes) + menuItem.isCheckable = true + } + submenu.setGroupCheckable(R.id.group_order, true, true) + } + } + + override fun onPrepareMenu(menu: Menu) { + menu.findItem(R.id.action_order)?.subMenu?.let { submenu -> + val selectedOrder = viewModel.sortOrder.value + for (item in submenu) { + val order = CategoriesActivity.SORT_ORDERS.getOrNull(item.order) + item.isChecked = order == selectedOrder + } + } + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when { + menuItem.itemId == R.id.action_order -> false + menuItem.groupId == R.id.group_order -> { + val order = CategoriesActivity.SORT_ORDERS.getOrNull(menuItem.order) ?: return false + viewModel.setSortOrder(order) + true + } + else -> false + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt index 27f4a86ca..b68f247aa 100644 --- a/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt @@ -2,11 +2,9 @@ package org.koitharu.kotatsu.history.ui import android.os.Bundle import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import android.view.View import androidx.appcompat.view.ActionMode -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R @@ -14,6 +12,7 @@ import org.koitharu.kotatsu.base.domain.ReversibleHandle import org.koitharu.kotatsu.base.domain.reverseAsync import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.utils.ext.addMenuProvider class HistoryListFragment : MangaListFragment() { @@ -22,6 +21,7 @@ class HistoryListFragment : MangaListFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + addMenuProvider(HistoryListMenuProvider(view.context, viewModel)) viewModel.isGroupingEnabled.observe(viewLifecycleOwner) { activity?.invalidateOptionsMenu() } @@ -30,37 +30,6 @@ class HistoryListFragment : MangaListFragment() { override fun onScrolledToEnd() = Unit - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.opt_history, menu) - super.onCreateOptionsMenu(menu, inflater) - } - - override fun onPrepareOptionsMenu(menu: Menu) { - super.onPrepareOptionsMenu(menu) - menu.findItem(R.id.action_history_grouping)?.isChecked = - viewModel.isGroupingEnabled.value == true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.action_clear_history -> { - MaterialAlertDialogBuilder(context ?: return false) - .setTitle(R.string.clear_history) - .setMessage(R.string.text_clear_history_prompt) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(R.string.clear) { _, _ -> - viewModel.clearHistory() - }.show() - true - } - R.id.action_history_grouping -> { - viewModel.setGrouping(!item.isChecked) - true - } - else -> super.onOptionsItemSelected(item) - } - } - override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { mode.menuInflater.inflate(R.menu.mode_history, menu) return super.onCreateActionMode(mode, menu) diff --git a/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListMenuProvider.kt new file mode 100644 index 000000000..b27629ce6 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListMenuProvider.kt @@ -0,0 +1,41 @@ +package org.koitharu.kotatsu.history.ui + +import android.content.Context +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.koitharu.kotatsu.R + +class HistoryListMenuProvider( + private val context: Context, + private val viewModel: HistoryListViewModel, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_history, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { + R.id.action_clear_history -> { + MaterialAlertDialogBuilder(context) + .setTitle(R.string.clear_history) + .setMessage(R.string.text_clear_history_prompt) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(R.string.clear) { _, _ -> + viewModel.clearHistory() + }.show() + true + } + R.id.action_history_grouping -> { + viewModel.setGrouping(!menuItem.isChecked) + true + } + else -> false + } + + override fun onPrepareMenu(menu: Menu) { + menu.findItem(R.id.action_history_grouping).isChecked = viewModel.isGroupingEnabled.value == true + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index ad7e3ab70..28556ac48 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -9,6 +9,7 @@ import androidx.collection.ArraySet import androidx.core.graphics.Insets import androidx.core.view.isNotEmpty import androidx.core.view.updatePadding +import androidx.lifecycle.Lifecycle import androidx.recyclerview.widget.GridLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.snackbar.Snackbar @@ -67,11 +68,6 @@ abstract class MangaListFragment : protected val selectedItems: Set get() = collectSelectedItems() - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - override fun onInflateView( inflater: LayoutInflater, container: ViewGroup? @@ -98,6 +94,7 @@ abstract class MangaListFragment : setOnRefreshListener(this@MangaListFragment) isEnabled = isSwipeRefreshEnabled } + addMenuProvider(MangaListMenuProvider(childFragmentManager)) viewModel.listMode.observe(viewLifecycleOwner, ::onListModeChanged) viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) @@ -114,19 +111,6 @@ abstract class MangaListFragment : super.onDestroyView() } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.opt_list, menu) - super.onCreateOptionsMenu(menu, inflater) - } - - override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { - R.id.action_list_mode -> { - ListModeSelectDialog.show(childFragmentManager) - true - } - else -> super.onOptionsItemSelected(item) - } - override fun onItemClick(item: Manga, view: View) { if (selectionDecoration?.checkedItemsCount != 0) { selectionDecoration?.toggleItemChecked(item.id) diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListMenuProvider.kt new file mode 100644 index 000000000..5950cd546 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListMenuProvider.kt @@ -0,0 +1,25 @@ +package org.koitharu.kotatsu.list.ui + +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import androidx.fragment.app.FragmentManager +import org.koitharu.kotatsu.R + +class MangaListMenuProvider( + private val fragmentManager: FragmentManager, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_list, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { + R.id.action_list_mode -> { + ListModeSelectDialog.show(fragmentManager) + true + } + else -> false + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt index fc2dbad03..4fff18ac6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt @@ -4,7 +4,6 @@ import android.content.* import android.net.Uri import android.os.Bundle import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import android.view.View import androidx.activity.result.ActivityResultCallback @@ -19,6 +18,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.download.ui.service.DownloadService import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.utils.ShareHelper +import org.koitharu.kotatsu.utils.ext.addMenuProvider import org.koitharu.kotatsu.utils.ext.printStackTraceDebug import org.koitharu.kotatsu.utils.progress.Progress @@ -48,6 +48,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback { - onEmptyActionClick() - true - } - else -> super.onOptionsItemSelected(item) - } - } - override fun onActivityResult(result: List<@JvmSuppressWildcards Uri>) { if (result.isEmpty()) return viewModel.importFiles(result) diff --git a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListMenuProvider.kt new file mode 100644 index 000000000..ce9941293 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListMenuProvider.kt @@ -0,0 +1,26 @@ +package org.koitharu.kotatsu.local.ui + +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import org.koitharu.kotatsu.R + +class LocalListMenuProvider( + private val onImportClick: Function0, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_local, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when (menuItem.itemId) { + R.id.action_import -> { + onImportClick() + true + } + else -> false + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/PageSaveContract.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/PageSaveContract.kt index 556a03cac..406fbbd63 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/PageSaveContract.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/PageSaveContract.kt @@ -9,7 +9,7 @@ import android.webkit.MimeTypeMap import androidx.activity.result.contract.ActivityResultContracts import androidx.core.net.toUri -class PageSaveContract : ActivityResultContracts.CreateDocument() { +class PageSaveContract : ActivityResultContracts.CreateDocument("image/*") { override fun createIntent(context: Context, input: String): Intent { val intent = super.createIntent(context, input) diff --git a/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt index 16a3b16a6..6dcd26b0f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt @@ -1,9 +1,12 @@ package org.koitharu.kotatsu.remotelist.ui +import android.os.Bundle import android.view.Menu import android.view.MenuInflater import android.view.MenuItem +import android.view.View import androidx.appcompat.view.ActionMode +import androidx.core.view.MenuProvider import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R @@ -11,6 +14,7 @@ import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.list.ui.filter.FilterBottomSheet import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.settings.SettingsActivity +import org.koitharu.kotatsu.utils.ext.addMenuProvider import org.koitharu.kotatsu.utils.ext.serializableArgument import org.koitharu.kotatsu.utils.ext.withArgs @@ -22,29 +26,13 @@ class RemoteListFragment : MangaListFragment() { private val source by serializableArgument(ARG_SOURCE) - override fun onScrolledToEnd() { - viewModel.loadNextPage() - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.opt_list_remote, menu) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + addMenuProvider(RemoteListMenuProvider()) } - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.action_source_settings -> { - startActivity( - SettingsActivity.newSourceSettingsIntent(context ?: return false, source) - ) - true - } - R.id.action_filter -> { - onFilterClick() - true - } - else -> super.onOptionsItemSelected(item) - } + override fun onScrolledToEnd() { + viewModel.loadNextPage() } override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { @@ -60,6 +48,25 @@ class RemoteListFragment : MangaListFragment() { viewModel.resetFilter() } + private inner class RemoteListMenuProvider: MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_list_remote, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { + R.id.action_source_settings -> { + startActivity(SettingsActivity.newSourceSettingsIntent(requireContext(), source)) + true + } + R.id.action_filter -> { + onFilterClick() + true + } + else -> false + } + } + companion object { private const val ARG_SOURCE = "provider" diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt index 88f30c87b..b309a588b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt @@ -23,15 +23,16 @@ class BackupDialogFragment : AlertDialogFragment() { private val viewModel by viewModel() private var backup: File? = null - private val saveFileContract = - registerForActivityResult(ActivityResultContracts.CreateDocument()) { uri -> - val file = backup - if (uri != null && file != null) { - saveBackup(file, uri) - } else { - dismiss() - } + private val saveFileContract = registerForActivityResult( + ActivityResultContracts.CreateDocument("*/*") + ) { uri -> + val file = backup + if (uri != null && file != null) { + saveBackup(file, uri) + } else { + dismiss() } + } override fun onInflateView( inflater: LayoutInflater, diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt index e89e20173..e8044fdde 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.* import androidx.appcompat.widget.SearchView import androidx.core.graphics.Insets +import androidx.core.view.MenuProvider import androidx.core.view.updatePadding import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView @@ -20,12 +21,11 @@ import org.koitharu.kotatsu.settings.SourceSettingsFragment import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigAdapter import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigListener import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem +import org.koitharu.kotatsu.utils.ext.addMenuProvider class SourcesSettingsFragment : BaseFragment(), SourceConfigListener, - SearchView.OnQueryTextListener, - MenuItem.OnActionExpandListener, RecyclerViewOwner { private var reorderHelper: ItemTouchHelper? = null @@ -34,11 +34,6 @@ class SourcesSettingsFragment : override val recyclerView: RecyclerView get() = binding.recyclerView - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - override fun onInflateView( inflater: LayoutInflater, container: ViewGroup? @@ -62,6 +57,7 @@ class SourcesSettingsFragment : viewModel.items.observe(viewLifecycleOwner) { sourcesAdapter.items = it } + addMenuProvider(SourcesMenuProvider()) } override fun onDestroyView() { @@ -69,17 +65,6 @@ class SourcesSettingsFragment : super.onDestroyView() } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.opt_sources, menu) - val searchMenuItem = menu.findItem(R.id.action_search) - searchMenuItem.setOnActionExpandListener(this) - val searchView = searchMenuItem.actionView as SearchView - searchView.setOnQueryTextListener(this) - searchView.setIconifiedByDefault(false) - searchView.queryHint = searchMenuItem.title - } - override fun onWindowInsetsChanged(insets: Insets) { binding.recyclerView.updatePadding( bottom = insets.bottom, @@ -106,21 +91,39 @@ class SourcesSettingsFragment : viewModel.expandOrCollapse(header.localeId) } - override fun onQueryTextSubmit(query: String?): Boolean = false + private inner class SourcesMenuProvider : + MenuProvider, + MenuItem.OnActionExpandListener, + SearchView.OnQueryTextListener { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_sources, menu) + val searchMenuItem = menu.findItem(R.id.action_search) + searchMenuItem.setOnActionExpandListener(this) + val searchView = searchMenuItem.actionView as SearchView + searchView.setOnQueryTextListener(this) + searchView.setIconifiedByDefault(false) + searchView.queryHint = searchMenuItem.title + } - override fun onQueryTextChange(newText: String?): Boolean { - viewModel.performSearch(newText) - return true - } + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = false - override fun onMenuItemActionExpand(item: MenuItem?): Boolean { - (activity as? AppBarOwner)?.appBar?.setExpanded(false, true) - return true - } + override fun onMenuItemActionExpand(item: MenuItem?): Boolean { + (activity as? AppBarOwner)?.appBar?.setExpanded(false, true) + return true + } + + override fun onMenuItemActionCollapse(item: MenuItem): Boolean { + (item.actionView as SearchView).setQuery("", false) + return true + } + + override fun onQueryTextSubmit(query: String?): Boolean = false - override fun onMenuItemActionCollapse(item: MenuItem): Boolean { - (item.actionView as SearchView).setQuery("", false) - return true + override fun onQueryTextChange(newText: String?): Boolean { + viewModel.performSearch(newText) + return true + } } private inner class SourcesReorderCallback : ItemTouchHelper.SimpleCallback( diff --git a/app/src/main/java/org/koitharu/kotatsu/suggestions/ui/SuggestionsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/suggestions/ui/SuggestionsFragment.kt index ceb873f49..f1af41bf3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/suggestions/ui/SuggestionsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/suggestions/ui/SuggestionsFragment.kt @@ -4,30 +4,40 @@ import android.os.Bundle import android.view.Menu import android.view.MenuInflater import android.view.MenuItem +import android.view.View import androidx.appcompat.view.ActionMode +import androidx.core.view.MenuProvider import com.google.android.material.snackbar.Snackbar import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.settings.SettingsActivity +import org.koitharu.kotatsu.utils.ext.addMenuProvider class SuggestionsFragment : MangaListFragment() { override val viewModel by viewModel() override val isSwipeRefreshEnabled = false - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + addMenuProvider(SuggestionMenuProvider()) } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.opt_suggestions, menu) + override fun onScrolledToEnd() = Unit + + override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { + mode.menuInflater.inflate(R.menu.mode_remote, menu) + return super.onCreateActionMode(mode, menu) } - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { + private inner class SuggestionMenuProvider : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_suggestions, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { R.id.action_update -> { SuggestionsWorker.startNow(requireContext()) Snackbar.make( @@ -41,17 +51,10 @@ class SuggestionsFragment : MangaListFragment() { startActivity(SettingsActivity.newSuggestionsSettingsIntent(requireContext())) true } - else -> super.onOptionsItemSelected(item) + else -> false } } - override fun onScrolledToEnd() = Unit - - override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { - mode.menuInflater.inflate(R.menu.mode_remote, menu) - return super.onCreateActionMode(mode, menu) - } - companion object { fun newInstance() = SuggestionsFragment() diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt index 584e2a4ff..32120ea94 100644 --- a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt @@ -1,10 +1,11 @@ package org.koitharu.kotatsu.tracker.ui import android.os.Bundle -import android.view.* +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import androidx.core.graphics.Insets import androidx.core.view.updatePadding -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import org.koin.android.ext.android.get import org.koin.androidx.viewmodel.ext.android.viewModel @@ -21,6 +22,7 @@ import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.tracker.ui.adapter.FeedAdapter import org.koitharu.kotatsu.tracker.work.TrackWorker +import org.koitharu.kotatsu.utils.ext.addMenuProvider import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.measureHeight import org.koitharu.kotatsu.utils.progress.Progress @@ -37,11 +39,6 @@ class FeedFragment : private var paddingVertical = 0 private var paddingHorizontal = 0 - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - override fun onInflateView( inflater: LayoutInflater, container: ViewGroup? @@ -63,6 +60,7 @@ class FeedFragment : ) addItemDecoration(decoration) } + addMenuProvider(FeedMenuProvider(binding.recyclerView, viewModel)) viewModel.content.observe(viewLifecycleOwner, this::onListChanged) viewModel.onError.observe(viewLifecycleOwner, this::onError) @@ -73,36 +71,6 @@ class FeedFragment : .observe(viewLifecycleOwner, this::onUpdateProgressChanged) } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.opt_feed, menu) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.action_update -> { - TrackWorker.startNow(requireContext()) - Snackbar.make( - binding.recyclerView, - R.string.feed_will_update_soon, - Snackbar.LENGTH_LONG, - ).show() - true - } - R.id.action_clear_feed -> { - MaterialAlertDialogBuilder(context ?: return false) - .setTitle(R.string.clear_updates_feed) - .setMessage(R.string.text_clear_updates_feed_prompt) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(R.string.clear) { _, _ -> - viewModel.clearFeed() - }.show() - true - } - else -> super.onOptionsItemSelected(item) - } - } - override fun onDestroyView() { feedAdapter = null updateStatusSnackbar = null diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedMenuProvider.kt new file mode 100644 index 000000000..6787ff7da --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedMenuProvider.kt @@ -0,0 +1,48 @@ +package org.koitharu.kotatsu.tracker.ui + +import android.content.Context +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import androidx.core.view.MenuProvider +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.tracker.work.TrackWorker + +class FeedMenuProvider( + private val snackbarHost: View, + private val viewModel: FeedViewModel, +) : MenuProvider { + + private val context: Context + get() = snackbarHost.context + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_feed, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { + R.id.action_update -> { + TrackWorker.startNow(context) + Snackbar.make( + snackbarHost, + R.string.feed_will_update_soon, + Snackbar.LENGTH_LONG, + ).show() + true + } + R.id.action_clear_feed -> { + MaterialAlertDialogBuilder(context) + .setTitle(R.string.clear_updates_feed) + .setMessage(R.string.text_clear_updates_feed_prompt) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(R.string.clear) { _, _ -> + viewModel.clearFeed() + }.show() + true + } + else -> false + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt index d881d3b1d..d37b579e7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt @@ -2,9 +2,11 @@ package org.koitharu.kotatsu.utils.ext import android.os.Bundle import android.os.Parcelable +import androidx.core.view.MenuProvider import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager +import androidx.lifecycle.Lifecycle import androidx.lifecycle.coroutineScope import java.io.Serializable @@ -43,4 +45,8 @@ fun DialogFragment.showAllowStateLoss(manager: FragmentManager, tag: String?) { if (!manager.isStateSaved) { show(manager, tag) } +} + +fun Fragment.addMenuProvider(provider: MenuProvider) { + requireActivity().addMenuProvider(provider, viewLifecycleOwner, Lifecycle.State.RESUMED) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/LocaleExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/LocaleExt.kt index b07b0c41d..ac878b538 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/LocaleExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/LocaleExt.kt @@ -3,12 +3,14 @@ package org.koitharu.kotatsu.utils.ext import androidx.core.os.LocaleListCompat import java.util.* -fun LocaleListCompat.toList(): List = createList(size()) { i -> get(i) } +fun LocaleListCompat.getOrThrow(index: Int) = get(index) ?: throw kotlin.NoSuchElementException() + +fun LocaleListCompat.toList(): List = createList(size()) { i -> getOrThrow(i) } operator fun LocaleListCompat.iterator() = object : Iterator { private var index = 0 override fun hasNext(): Boolean = index < size() - override fun next(): Locale = get(index++) + override fun next(): Locale = getOrThrow(index++) } inline fun > LocaleListCompat.mapTo( @@ -17,7 +19,7 @@ inline fun > LocaleListCompat.mapTo( ): C { val len = size() for (i in 0 until len) { - val item = get(i) + val item = get(i) ?: continue destination.add(block(item)) } return destination