mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 07:11:52 +01:00
Bottom action menu in library
This commit is contained in:
parent
316211372c
commit
af2ef36d68
@ -32,6 +32,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
|||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import eu.kanade.tachiyomi.ui.base.controller.BottomActionMenuController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
|
import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
|
||||||
@ -41,6 +42,7 @@ import eu.kanade.tachiyomi.ui.main.MainActivity
|
|||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.inflate
|
import eu.kanade.tachiyomi.util.view.inflate
|
||||||
|
import eu.kanade.tachiyomi.widget.BottomActionMenu
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import kotlinx.android.synthetic.main.library_controller.empty_view
|
import kotlinx.android.synthetic.main.library_controller.empty_view
|
||||||
import kotlinx.android.synthetic.main.library_controller.library_pager
|
import kotlinx.android.synthetic.main.library_controller.library_pager
|
||||||
@ -58,6 +60,7 @@ class LibraryController(
|
|||||||
RootController,
|
RootController,
|
||||||
TabbedController,
|
TabbedController,
|
||||||
SecondaryDrawerController,
|
SecondaryDrawerController,
|
||||||
|
BottomActionMenuController,
|
||||||
ActionMode.Callback,
|
ActionMode.Callback,
|
||||||
ChangeMangaCategoriesDialog.Listener,
|
ChangeMangaCategoriesDialog.Listener,
|
||||||
DeleteLibraryMangasDialog.Listener {
|
DeleteLibraryMangasDialog.Listener {
|
||||||
@ -72,6 +75,7 @@ class LibraryController(
|
|||||||
* Action mode for selections.
|
* Action mode for selections.
|
||||||
*/
|
*/
|
||||||
private var actionMode: ActionMode? = null
|
private var actionMode: ActionMode? = null
|
||||||
|
private var bottomActionMenu: BottomActionMenu? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Library search query.
|
* Library search query.
|
||||||
@ -179,9 +183,9 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
|
destroyActionModeIfNeeded()
|
||||||
adapter?.onDestroy()
|
adapter?.onDestroy()
|
||||||
adapter = null
|
adapter = null
|
||||||
actionMode = null
|
|
||||||
tabsVisibilitySubscription?.unsubscribe()
|
tabsVisibilitySubscription?.unsubscribe()
|
||||||
tabsVisibilitySubscription = null
|
tabsVisibilitySubscription = null
|
||||||
super.onDestroyView(view)
|
super.onDestroyView(view)
|
||||||
@ -320,7 +324,7 @@ class LibraryController(
|
|||||||
/**
|
/**
|
||||||
* Destroys the action mode.
|
* Destroys the action mode.
|
||||||
*/
|
*/
|
||||||
fun destroyActionModeIfNeeded() {
|
private fun destroyActionModeIfNeeded() {
|
||||||
actionMode?.finish()
|
actionMode?.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +418,7 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
mode.menuInflater.inflate(R.menu.library_selection, menu)
|
mode.menuInflater.inflate(R.menu.generic_selection, menu)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +429,9 @@ class LibraryController(
|
|||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
} else {
|
} else {
|
||||||
mode.title = count.toString()
|
mode.title = count.toString()
|
||||||
menu.findItem(R.id.action_edit_cover)?.isVisible = count == 1
|
|
||||||
|
bottomActionMenu?.show(mode.menuInflater)
|
||||||
|
bottomActionMenu?.findItem(R.id.action_edit_cover)?.isVisible = count == 1
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -445,12 +451,20 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||||
|
bottomActionMenu?.hide()
|
||||||
// Clear all the manga selections and notify child views.
|
// Clear all the manga selections and notify child views.
|
||||||
selectedMangas.clear()
|
selectedMangas.clear()
|
||||||
selectionRelay.call(LibrarySelectionEvent.Cleared())
|
selectionRelay.call(LibrarySelectionEvent.Cleared())
|
||||||
actionMode = null
|
actionMode = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun configureBottomActionMenu(bottomActionMenu: BottomActionMenu) {
|
||||||
|
this.bottomActionMenu = bottomActionMenu
|
||||||
|
bottomActionMenu.configure(
|
||||||
|
R.menu.library_selection
|
||||||
|
) { onActionItemClicked(actionMode!!, it!!) }
|
||||||
|
}
|
||||||
|
|
||||||
fun openManga(manga: Manga) {
|
fun openManga(manga: Manga) {
|
||||||
// Notify the presenter a manga is being opened.
|
// Notify the presenter a manga is being opened.
|
||||||
presenter.onOpenManga()
|
presenter.onOpenManga()
|
||||||
|
@ -107,8 +107,8 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
|
destroyActionModeIfNeeded()
|
||||||
adapter = null
|
adapter = null
|
||||||
actionMode = null
|
|
||||||
super.onDestroyView(view)
|
super.onDestroyView(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
* Returns selected chapters
|
* Returns selected chapters
|
||||||
* @return list of selected chapters
|
* @return list of selected chapters
|
||||||
*/
|
*/
|
||||||
fun getSelectedChapters(): List<UpdatesItem> {
|
private fun getSelectedChapters(): List<UpdatesItem> {
|
||||||
val adapter = adapter ?: return emptyList()
|
val adapter = adapter ?: return emptyList()
|
||||||
return adapter.selectedPositions.mapNotNull { adapter.getItem(it) as? UpdatesItem }
|
return adapter.selectedPositions.mapNotNull { adapter.getItem(it) as? UpdatesItem }
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
* Download selected items
|
* Download selected items
|
||||||
* @param chapters list of selected [UpdatesItem]s
|
* @param chapters list of selected [UpdatesItem]s
|
||||||
*/
|
*/
|
||||||
fun downloadChapters(chapters: List<UpdatesItem>) {
|
private fun downloadChapters(chapters: List<UpdatesItem>) {
|
||||||
presenter.downloadChapters(chapters)
|
presenter.downloadChapters(chapters)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,13 +216,21 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
* Mark chapter as read
|
* Mark chapter as read
|
||||||
* @param chapters list of chapters
|
* @param chapters list of chapters
|
||||||
*/
|
*/
|
||||||
fun markAsRead(chapters: List<UpdatesItem>) {
|
private fun markAsRead(chapters: List<UpdatesItem>) {
|
||||||
presenter.markChapterRead(chapters, true)
|
presenter.markChapterRead(chapters, true)
|
||||||
if (presenter.preferences.removeAfterMarkedAsRead()) {
|
if (presenter.preferences.removeAfterMarkedAsRead()) {
|
||||||
deleteChapters(chapters)
|
deleteChapters(chapters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark chapter as unread
|
||||||
|
* @param chapters list of selected [UpdatesItem]
|
||||||
|
*/
|
||||||
|
private fun markAsUnread(chapters: List<UpdatesItem>) {
|
||||||
|
presenter.markChapterRead(chapters, false)
|
||||||
|
}
|
||||||
|
|
||||||
override fun deleteChapters(chaptersToDelete: List<UpdatesItem>) {
|
override fun deleteChapters(chaptersToDelete: List<UpdatesItem>) {
|
||||||
DeletingChaptersDialog().showDialog(router)
|
DeletingChaptersDialog().showDialog(router)
|
||||||
presenter.deleteChapters(chaptersToDelete)
|
presenter.deleteChapters(chaptersToDelete)
|
||||||
@ -235,20 +243,12 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
actionMode?.finish()
|
actionMode?.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark chapter as unread
|
|
||||||
* @param chapters list of selected [UpdatesItem]
|
|
||||||
*/
|
|
||||||
fun markAsUnread(chapters: List<UpdatesItem>) {
|
|
||||||
presenter.markChapterRead(chapters, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCoverClick(position: Int) {
|
override fun onCoverClick(position: Int) {
|
||||||
val chapterClicked = adapter?.getItem(position) as? UpdatesItem ?: return
|
val chapterClicked = adapter?.getItem(position) as? UpdatesItem ?: return
|
||||||
openManga(chapterClicked)
|
openManga(chapterClicked)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openManga(chapter: UpdatesItem) {
|
private fun openManga(chapter: UpdatesItem) {
|
||||||
router.pushController(MangaController(chapter.manga).withFadeTransaction())
|
router.pushController(MangaController(chapter.manga).withFadeTransaction())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
/**
|
/**
|
||||||
* Called to dismiss deleting dialog
|
* Called to dismiss deleting dialog
|
||||||
*/
|
*/
|
||||||
fun dismissDeletingDialog() {
|
private fun dismissDeletingDialog() {
|
||||||
router.popControllerWithTag(DeletingChaptersDialog.TAG)
|
router.popControllerWithTag(DeletingChaptersDialog.TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +284,6 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
mode.menuInflater.inflate(R.menu.generic_selection, menu)
|
mode.menuInflater.inflate(R.menu.generic_selection, menu)
|
||||||
adapter?.mode = SelectableAdapter.Mode.MULTI
|
adapter?.mode = SelectableAdapter.Mode.MULTI
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,16 +330,16 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
actionMode = null
|
actionMode = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun selectAll() {
|
|
||||||
val adapter = adapter ?: return
|
|
||||||
adapter.selectAll()
|
|
||||||
actionMode?.invalidate()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun configureBottomActionMenu(bottomActionMenu: BottomActionMenu) {
|
override fun configureBottomActionMenu(bottomActionMenu: BottomActionMenu) {
|
||||||
this.bottomActionMenu = bottomActionMenu
|
this.bottomActionMenu = bottomActionMenu
|
||||||
bottomActionMenu.configure(
|
bottomActionMenu.configure(
|
||||||
R.menu.updates_chapter_selection
|
R.menu.updates_chapter_selection
|
||||||
) { onActionItemClicked(actionMode!!, it!!) }
|
) { onActionItemClicked(actionMode!!, it!!) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun selectAll() {
|
||||||
|
val adapter = adapter ?: return
|
||||||
|
adapter.selectAll()
|
||||||
|
actionMode?.invalidate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.view.MenuInflater
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import androidx.annotation.IdRes
|
||||||
import androidx.annotation.MenuRes
|
import androidx.annotation.MenuRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import kotlinx.android.synthetic.main.common_bottom_action_menu.view.bottom_menu
|
import kotlinx.android.synthetic.main.common_bottom_action_menu.view.bottom_menu
|
||||||
@ -31,6 +32,10 @@ class BottomActionMenu @JvmOverloads constructor(context: Context, attrs: Attrib
|
|||||||
bottom_menu.setOnMenuItemClickListener(null)
|
bottom_menu.setOnMenuItemClickListener(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun findItem(@IdRes itemId: Int): MenuItem? {
|
||||||
|
return bottom_menu.menu.findItem(itemId)
|
||||||
|
}
|
||||||
|
|
||||||
fun show(menuInflater: MenuInflater) {
|
fun show(menuInflater: MenuInflater) {
|
||||||
// Avoid re-inflating the menu
|
// Avoid re-inflating the menu
|
||||||
if (bottom_menu.menu.size() == 0) {
|
if (bottom_menu.menu.size() == 0) {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
@ -7,24 +6,18 @@
|
|||||||
android:id="@+id/action_edit_cover"
|
android:id="@+id/action_edit_cover"
|
||||||
android:icon="@drawable/ic_create_white_24dp"
|
android:icon="@drawable/ic_create_white_24dp"
|
||||||
android:title="@string/action_edit_cover"
|
android:title="@string/action_edit_cover"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="always" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_move_to_category"
|
android:id="@+id/action_move_to_category"
|
||||||
android:icon="@drawable/ic_label_white_24dp"
|
android:icon="@drawable/ic_label_white_24dp"
|
||||||
android:title="@string/action_move_category"
|
android:title="@string/action_move_category"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="always" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_delete"
|
android:id="@+id/action_delete"
|
||||||
android:icon="@drawable/ic_delete_white_24dp"
|
android:icon="@drawable/ic_delete_white_24dp"
|
||||||
android:title="@string/action_delete"
|
android:title="@string/action_delete"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="always" />
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_select_all"
|
|
||||||
android:icon="@drawable/ic_select_all_white_24dp"
|
|
||||||
android:title="@string/action_select_all"
|
|
||||||
app:showAsAction="ifRoom" />
|
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
Loading…
Reference in New Issue
Block a user