Browse Source

Move chapter filter/sort/display settings into a sheet

arkon 4 years ago
parent
commit
9278ca3f5e

+ 4 - 4
app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt

@@ -24,10 +24,6 @@ interface Manga : SManga {
         setFlags(order, SORT_MASK)
     }
 
-    private fun setFlags(flag: Int, mask: Int) {
-        chapter_flags = chapter_flags and mask.inv() or (flag and mask)
-    }
-
     fun sortDescending(): Boolean {
         return chapter_flags and SORT_MASK == SORT_DESC
     }
@@ -36,6 +32,10 @@ interface Manga : SManga {
         return genre?.split(", ")?.map { it.trim() }
     }
 
+    private fun setFlags(flag: Int, mask: Int) {
+        chapter_flags = chapter_flags and mask.inv() or (flag and mask)
+    }
+
     // Used to display the chapter's title one way or another
     var displayMode: Int
         get() = chapter_flags and DISPLAY_MASK

+ 26 - 100
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

@@ -13,7 +13,6 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.appcompat.app.AppCompatActivity
 import androidx.appcompat.view.ActionMode
-import androidx.core.graphics.drawable.DrawableCompat
 import androidx.recyclerview.widget.ConcatAdapter
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
@@ -51,6 +50,7 @@ import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
 import eu.kanade.tachiyomi.ui.manga.chapter.ChapterHolder
 import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
 import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter
+import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersSettingsSheet
 import eu.kanade.tachiyomi.ui.manga.chapter.DeleteChaptersDialog
 import eu.kanade.tachiyomi.ui.manga.chapter.DownloadCustomChaptersDialog
 import eu.kanade.tachiyomi.ui.manga.chapter.MangaChaptersHeaderAdapter
@@ -61,7 +61,6 @@ import eu.kanade.tachiyomi.ui.recent.history.HistoryController
 import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
 import eu.kanade.tachiyomi.ui.webview.WebViewActivity
 import eu.kanade.tachiyomi.util.hasCustomCover
-import eu.kanade.tachiyomi.util.system.getResourceColor
 import eu.kanade.tachiyomi.util.system.toast
 import eu.kanade.tachiyomi.util.view.getCoordinates
 import eu.kanade.tachiyomi.util.view.gone
@@ -124,6 +123,11 @@ class MangaController :
     private var chaptersHeaderAdapter: MangaChaptersHeaderAdapter? = null
     private var chaptersAdapter: ChaptersAdapter? = null
 
+    /**
+     * Sheet containing filter/sort/display items.
+     */
+    private var settingsSheet: ChaptersSettingsSheet? = null
+
     private var actionFabScrollListener: RecyclerView.OnScrollListener? = null
 
     /**
@@ -178,7 +182,7 @@ class MangaController :
 
         // Init RecyclerView and adapter
         mangaInfoAdapter = MangaInfoHeaderAdapter(this, fromSource)
-        chaptersHeaderAdapter = MangaChaptersHeaderAdapter()
+        chaptersHeaderAdapter = MangaChaptersHeaderAdapter(this)
         chaptersAdapter = ChaptersAdapter(this, view.context)
 
         binding.recycler.adapter = ConcatAdapter(mangaInfoAdapter, chaptersHeaderAdapter, chaptersAdapter)
@@ -205,6 +209,19 @@ class MangaController :
             .launchIn(scope)
 
         binding.actionToolbar.offsetAppbarHeight(activity!!)
+
+        settingsSheet = ChaptersSettingsSheet(activity!!, presenter) { group ->
+            if (group is ChaptersSettingsSheet.Filter.FilterGroup) {
+                updateFilterIconState()
+                chaptersAdapter?.notifyDataSetChanged()
+            }
+        }
+
+        updateFilterIconState()
+    }
+
+    private fun updateFilterIconState() {
+        chaptersHeaderAdapter?.setHasActiveFilters(settingsSheet?.filters?.hasActiveFilters() == true)
     }
 
     override fun configureFab(fab: ExtendedFloatingActionButton) {
@@ -249,6 +266,7 @@ class MangaController :
         mangaInfoAdapter = null
         chaptersHeaderAdapter = null
         chaptersAdapter = null
+        settingsSheet = null
         super.onDestroyView(view)
     }
 
@@ -266,50 +284,10 @@ class MangaController :
     }
 
     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
-        inflater.inflate(R.menu.chapters, menu)
+        inflater.inflate(R.menu.manga, menu)
     }
 
     override fun onPrepareOptionsMenu(menu: Menu) {
-        // Initialize menu items.
-        val menuFilterRead = menu.findItem(R.id.action_filter_read) ?: return
-        val menuFilterUnread = menu.findItem(R.id.action_filter_unread)
-        val menuFilterDownloaded = menu.findItem(R.id.action_filter_downloaded)
-        val menuFilterBookmarked = menu.findItem(R.id.action_filter_bookmarked)
-        val menuFilterEmpty = menu.findItem(R.id.action_filter_empty)
-
-        // Set correct checkbox values.
-        menuFilterRead.isChecked = presenter.onlyRead()
-        menuFilterUnread.isChecked = presenter.onlyUnread()
-        menuFilterDownloaded.isChecked = presenter.onlyDownloaded()
-        menuFilterDownloaded.isEnabled = !presenter.forceDownloaded()
-        menuFilterBookmarked.isChecked = presenter.onlyBookmarked()
-
-        val filterSet = presenter.onlyRead() || presenter.onlyUnread() || presenter.onlyDownloaded() || presenter.onlyBookmarked()
-        if (filterSet) {
-            val filterColor = activity!!.getResourceColor(R.attr.colorFilterActive)
-            DrawableCompat.setTint(menu.findItem(R.id.action_filter).icon, filterColor)
-        }
-
-        // Only show remove filter option if there's a filter set.
-        menuFilterEmpty.isVisible = filterSet
-
-        // Display mode submenu
-        if (presenter.manga.displayMode == Manga.DISPLAY_NAME) {
-            menu.findItem(R.id.display_title).isChecked = true
-        } else {
-            menu.findItem(R.id.display_chapter_number).isChecked = true
-        }
-
-        // Sorting mode submenu
-        val sortingItem = when (presenter.manga.sorting) {
-            Manga.SORTING_SOURCE -> R.id.sort_by_source
-            Manga.SORTING_NUMBER -> R.id.sort_by_number
-            Manga.SORTING_UPLOAD_DATE -> R.id.sort_by_upload_date
-            else -> throw NotImplementedError("Unimplemented sorting method")
-        }
-        menu.findItem(sortingItem).isChecked = true
-        menu.findItem(R.id.action_sort_descending).isChecked = presenter.manga.sortDescending()
-
         // Hide download options for local manga
         menu.findItem(R.id.download_group).isVisible = !isLocalSource
 
@@ -321,61 +299,10 @@ class MangaController :
 
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
         when (item.itemId) {
-            R.id.display_title -> {
-                item.isChecked = true
-                setDisplayMode(Manga.DISPLAY_NAME)
-            }
-            R.id.display_chapter_number -> {
-                item.isChecked = true
-                setDisplayMode(Manga.DISPLAY_NUMBER)
-            }
-
-            R.id.sort_by_source -> {
-                item.isChecked = true
-                presenter.setSorting(Manga.SORTING_SOURCE)
-            }
-            R.id.sort_by_number -> {
-                item.isChecked = true
-                presenter.setSorting(Manga.SORTING_NUMBER)
-            }
-            R.id.sort_by_upload_date -> {
-                item.isChecked = true
-                presenter.setSorting(Manga.SORTING_UPLOAD_DATE)
-            }
-            R.id.action_sort_descending -> {
-                presenter.reverseSortOrder()
-                activity?.invalidateOptionsMenu()
-            }
-
             R.id.download_next, R.id.download_next_5, R.id.download_next_10,
             R.id.download_custom, R.id.download_unread, R.id.download_all
             -> downloadChapters(item.itemId)
 
-            R.id.action_filter_unread -> {
-                item.isChecked = !item.isChecked
-                presenter.setUnreadFilter(item.isChecked)
-                activity?.invalidateOptionsMenu()
-            }
-            R.id.action_filter_read -> {
-                item.isChecked = !item.isChecked
-                presenter.setReadFilter(item.isChecked)
-                activity?.invalidateOptionsMenu()
-            }
-            R.id.action_filter_downloaded -> {
-                item.isChecked = !item.isChecked
-                presenter.setDownloadedFilter(item.isChecked)
-                activity?.invalidateOptionsMenu()
-            }
-            R.id.action_filter_bookmarked -> {
-                item.isChecked = !item.isChecked
-                presenter.setBookmarkedFilter(item.isChecked)
-                activity?.invalidateOptionsMenu()
-            }
-            R.id.action_filter_empty -> {
-                presenter.removeFilters()
-                activity?.invalidateOptionsMenu()
-            }
-
             R.id.action_edit_categories -> onCategoriesClick()
             R.id.action_edit_cover -> handleChangeCover()
             R.id.action_migrate -> migrateManga()
@@ -756,6 +683,10 @@ class MangaController :
         chaptersAdapter?.notifyDataSetChanged()
     }
 
+    fun showSettingsSheet() {
+        settingsSheet?.show()
+    }
+
     // SELECTIONS & ACTION MODE
 
     private fun toggleSelection(position: Int) {
@@ -958,11 +889,6 @@ class MangaController :
 
     // OVERFLOW MENU DIALOGS
 
-    private fun setDisplayMode(id: Int) {
-        presenter.setDisplayMode(id)
-        chaptersAdapter?.notifyDataSetChanged()
-    }
-
     private fun getUnreadChaptersSorted() = presenter.chapters
         .filter { !it.read && it.status == Download.NOT_DOWNLOADED }
         .distinctBy { it.name }

+ 0 - 11
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt

@@ -531,17 +531,6 @@ class MangaPresenter(
         refreshChapters()
     }
 
-    /**
-     * Removes all filters and requests an UI update.
-     */
-    fun removeFilters() {
-        manga.readFilter = Manga.SHOW_ALL
-        manga.downloadedFilter = Manga.SHOW_ALL
-        manga.bookmarkedFilter = Manga.SHOW_ALL
-        db.updateFlags(manga).executeAsBlocking()
-        refreshChapters()
-    }
-
     /**
      * Sets the active display mode.
      * @param mode the mode to set.

+ 239 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSettingsSheet.kt

@@ -0,0 +1,239 @@
+package eu.kanade.tachiyomi.ui.manga.chapter
+
+import android.app.Activity
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.data.database.models.Manga
+import eu.kanade.tachiyomi.ui.manga.MangaPresenter
+import eu.kanade.tachiyomi.widget.ExtendedNavigationView
+import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
+
+class ChaptersSettingsSheet(
+    activity: Activity,
+    private val presenter: MangaPresenter,
+    onGroupClickListener: (ExtendedNavigationView.Group) -> Unit
+) : TabbedBottomSheetDialog(activity) {
+
+    val filters: Filter
+    private val sort: Sort
+    private val display: Display
+
+    init {
+        filters = Filter(activity)
+        filters.onGroupClicked = onGroupClickListener
+
+        sort = Sort(activity)
+        sort.onGroupClicked = onGroupClickListener
+
+        display = Display(activity)
+        display.onGroupClicked = onGroupClickListener
+    }
+
+    override fun getTabViews(): List<View> = listOf(
+        filters,
+        sort,
+        display
+    )
+
+    override fun getTabTitles(): List<Int> = listOf(
+        R.string.action_filter,
+        R.string.action_sort,
+        R.string.action_display
+    )
+
+    /**
+     * Filters group (unread, downloaded, ...).
+     */
+    inner class Filter @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+        Settings(context, attrs) {
+
+        private val filterGroup = FilterGroup()
+
+        init {
+            setGroups(listOf(filterGroup))
+        }
+
+        /**
+         * Returns true if there's at least one filter from [FilterGroup] active.
+         */
+        fun hasActiveFilters(): Boolean {
+            return filterGroup.items.any { it.checked }
+        }
+
+        inner class FilterGroup : Group {
+
+            private val read = Item.CheckboxGroup(R.string.action_filter_read, this)
+            private val unread = Item.CheckboxGroup(R.string.action_filter_unread, this)
+            private val downloaded = Item.CheckboxGroup(R.string.action_filter_downloaded, this)
+            private val bookmarked = Item.CheckboxGroup(R.string.action_filter_bookmarked, this)
+
+            override val header = null
+            override val items = listOf(read, unread, downloaded, bookmarked)
+            override val footer = null
+
+            override fun initModels() {
+                read.checked = presenter.onlyRead()
+                unread.checked = presenter.onlyUnread()
+                downloaded.checked = presenter.onlyDownloaded()
+                downloaded.enabled = !presenter.forceDownloaded()
+                bookmarked.checked = presenter.onlyBookmarked()
+            }
+
+            override fun onItemClicked(item: Item) {
+                item as Item.CheckboxGroup
+                item.checked = !item.checked
+                when (item) {
+                    read -> presenter.setReadFilter(item.checked)
+                    unread -> presenter.setUnreadFilter(item.checked)
+                    downloaded -> presenter.setDownloadedFilter(item.checked)
+                    bookmarked -> presenter.setBookmarkedFilter(item.checked)
+                }
+
+                initModels()
+                item.group.items.forEach { adapter.notifyItemChanged(it) }
+            }
+        }
+    }
+
+    /**
+     * Sorting group (alphabetically, by last read, ...) and ascending or descending.
+     */
+    inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+        Settings(context, attrs) {
+
+        init {
+            setGroups(listOf(SortGroup()))
+        }
+
+        inner class SortGroup : Group {
+
+            private val source = Item.MultiSort(R.string.sort_by_source, this)
+            private val chapterNum = Item.MultiSort(R.string.sort_by_number, this)
+            private val uploadDate = Item.MultiSort(R.string.sort_by_upload_date, this)
+
+            override val header = null
+            override val items = listOf(source, uploadDate, chapterNum)
+            override val footer = null
+
+            override fun initModels() {
+                val sorting = presenter.manga.sorting
+                val order = if (presenter.manga.sortDescending()) {
+                    Item.MultiSort.SORT_DESC
+                } else {
+                    Item.MultiSort.SORT_ASC
+                }
+
+                source.state =
+                    if (sorting == Manga.SORTING_SOURCE) order else Item.MultiSort.SORT_NONE
+                chapterNum.state =
+                    if (sorting == Manga.SORTING_NUMBER) order else Item.MultiSort.SORT_NONE
+                uploadDate.state =
+                    if (sorting == Manga.SORTING_UPLOAD_DATE) order else Item.MultiSort.SORT_NONE
+            }
+
+            override fun onItemClicked(item: Item) {
+                item as Item.MultiStateGroup
+                val prevState = item.state
+
+                item.group.items.forEach {
+                    (it as Item.MultiStateGroup).state =
+                        Item.MultiSort.SORT_NONE
+                }
+                item.state = when (prevState) {
+                    Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
+                    Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
+                    Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
+                    else -> throw Exception("Unknown state")
+                }
+
+                when (item) {
+                    source -> presenter.setSorting(Manga.SORTING_SOURCE)
+                    chapterNum -> presenter.setSorting(Manga.SORTING_NUMBER)
+                    uploadDate -> presenter.setSorting(Manga.SORTING_UPLOAD_DATE)
+                    else -> throw Exception("Unknown sorting")
+                }
+
+                presenter.reverseSortOrder()
+
+                item.group.items.forEach { adapter.notifyItemChanged(it) }
+            }
+        }
+    }
+
+    /**
+     * Display group, to show the library as a list or a grid.
+     */
+    inner class Display @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+        Settings(context, attrs) {
+
+        init {
+            setGroups(listOf(DisplayGroup()))
+        }
+
+        inner class DisplayGroup : Group {
+
+            private val displayTitle = Item.Radio(R.string.show_title, this)
+            private val displayChapterNum = Item.Radio(R.string.show_chapter_number, this)
+
+            override val header = null
+            override val items = listOf(displayTitle, displayChapterNum)
+            override val footer = null
+
+            override fun initModels() {
+                val mode = presenter.manga.displayMode
+                displayTitle.checked = mode == Manga.DISPLAY_NAME
+                displayChapterNum.checked = mode == Manga.DISPLAY_NUMBER
+            }
+
+            override fun onItemClicked(item: Item) {
+                item as Item.Radio
+                if (item.checked) return
+
+                item.group.items.forEach { (it as Item.Radio).checked = false }
+                item.checked = true
+
+                when (item) {
+                    displayTitle -> presenter.setDisplayMode(Manga.DISPLAY_NAME)
+                    displayChapterNum -> presenter.setDisplayMode(Manga.DISPLAY_NUMBER)
+                    else -> throw NotImplementedError("Unknown display mode")
+                }
+
+                item.group.items.forEach { adapter.notifyItemChanged(it) }
+            }
+        }
+    }
+
+    open inner class Settings(context: Context, attrs: AttributeSet?) :
+        ExtendedNavigationView(context, attrs) {
+
+        lateinit var adapter: Adapter
+
+        /**
+         * Click listener to notify the parent fragment when an item from a group is clicked.
+         */
+        var onGroupClicked: (Group) -> Unit = {}
+
+        fun setGroups(groups: List<Group>) {
+            adapter = Adapter(groups.map { it.createItems() }.flatten())
+            recycler.adapter = adapter
+
+            groups.forEach { it.initModels() }
+            addView(recycler)
+        }
+
+        /**
+         * Adapter of the recycler view.
+         */
+        inner class Adapter(items: List<Item>) : ExtendedNavigationView.Adapter(items) {
+
+            override fun onItemClicked(item: Item) {
+                if (item is GroupedItem) {
+                    item.group.onItemClicked(item)
+                    onGroupClicked(item.group)
+                }
+            }
+        }
+    }
+}

+ 30 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/MangaChaptersHeaderAdapter.kt

@@ -3,17 +3,28 @@ package eu.kanade.tachiyomi.ui.manga.chapter
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import androidx.core.graphics.drawable.DrawableCompat
 import androidx.recyclerview.widget.RecyclerView
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.databinding.MangaChaptersHeaderBinding
+import eu.kanade.tachiyomi.ui.manga.MangaController
+import eu.kanade.tachiyomi.util.system.getResourceColor
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
+import reactivecircus.flowbinding.android.view.clicks
 
-class MangaChaptersHeaderAdapter :
+class MangaChaptersHeaderAdapter(
+    private val controller: MangaController
+) :
     RecyclerView.Adapter<MangaChaptersHeaderAdapter.HeaderViewHolder>() {
 
     private var numChapters: Int? = null
+    private var hasActiveFilters: Boolean = false
 
     private val scope = CoroutineScope(Job() + Dispatchers.Main)
     private lateinit var binding: MangaChaptersHeaderBinding
@@ -35,13 +46,31 @@ class MangaChaptersHeaderAdapter :
         notifyDataSetChanged()
     }
 
+    fun setHasActiveFilters(hasActiveFilters: Boolean) {
+        this.hasActiveFilters = hasActiveFilters
+
+        notifyDataSetChanged()
+    }
+
     inner class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
+        @ExperimentalCoroutinesApi
         fun bind() {
             binding.chaptersLabel.text = if (numChapters == null) {
                 view.context.getString(R.string.chapters)
             } else {
                 view.context.resources.getQuantityString(R.plurals.manga_num_chapters, numChapters!!, numChapters)
             }
+
+            val filterColor = if (hasActiveFilters) {
+                view.context.getResourceColor(R.attr.colorFilterActive)
+            } else {
+                view.context.getResourceColor(R.attr.colorOnPrimary)
+            }
+            DrawableCompat.setTint(binding.btnChaptersFilter.icon, filterColor)
+
+            merge(view.clicks(), binding.btnChaptersFilter.clicks())
+                .onEach { controller.showSettingsSheet() }
+                .launchIn(scope)
         }
     }
 }

+ 24 - 6
app/src/main/res/layout/manga_chapters_header.xml

@@ -1,20 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:background="?attr/selectableItemBackground"
     android:paddingStart="16dp"
-    android:paddingTop="16dp"
+    android:paddingTop="4dp"
     android:paddingEnd="16dp"
-    android:paddingBottom="8dp"
+    android:paddingBottom="4dp"
     tools:context=".ui.browse.source.browse.BrowseSourceController">
 
     <TextView
         android:id="@+id/chapters_label"
         style="@style/TextAppearance.Regular.SubHeading"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:text="@string/chapters"
-        android:textIsSelectable="false" />
+        android:textIsSelectable="false"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/btn_chapters_filter"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/btn_chapters_filter"
+        style="@style/Theme.Widget.Button.Icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/action_filter"
+        app:icon="@drawable/ic_filter_list_24dp"
+        app:iconTint="?attr/colorOnPrimary"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
 
-</RelativeLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 0 - 114
app/src/main/res/menu/chapters.xml

@@ -1,114 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <item
-        android:id="@+id/action_filter"
-        android:icon="@drawable/ic_filter_list_24dp"
-        android:title="@string/action_filter"
-        app:iconTint="?attr/colorOnPrimary"
-        app:showAsAction="ifRoom">
-        <menu>
-            <item
-                android:id="@+id/action_filter_read"
-                android:checkable="true"
-                android:title="@string/action_filter_read" />
-            <item
-                android:id="@+id/action_filter_unread"
-                android:checkable="true"
-                android:title="@string/action_filter_unread" />
-            <item
-                android:id="@+id/action_filter_downloaded"
-                android:checkable="true"
-                android:title="@string/action_filter_downloaded" />
-            <item
-                android:id="@+id/action_filter_bookmarked"
-                android:checkable="true"
-                android:title="@string/action_filter_bookmarked" />
-            <item
-                android:id="@+id/action_filter_empty"
-                android:title="@string/action_filter_empty" />
-        </menu>
-    </item>
-
-    <item
-        android:icon="@drawable/ic_sort_24dp"
-        android:title="@string/sorting_mode"
-        app:iconTint="?attr/colorOnPrimary"
-        app:showAsAction="ifRoom">
-        <menu>
-            <group android:checkableBehavior="single">
-                <item
-                    android:id="@+id/sort_by_source"
-                    android:title="@string/sort_by_source" />
-                <item
-                    android:id="@+id/sort_by_number"
-                    android:title="@string/sort_by_number" />
-                <item
-                    android:id="@+id/sort_by_upload_date"
-                    android:title="@string/sort_by_upload_date" />
-            </group>
-
-            <item
-                android:id="@+id/action_sort_descending"
-                android:checkable="true"
-                android:title="@string/action_sort_descending" />
-        </menu>
-    </item>
-
-    <item
-        android:title="@string/action_display_mode"
-        app:showAsAction="never">
-        <menu>
-            <group android:checkableBehavior="single">
-                <item
-                    android:id="@+id/display_title"
-                    android:title="@string/show_title" />
-                <item
-                    android:id="@+id/display_chapter_number"
-                    android:title="@string/show_chapter_number" />
-            </group>
-        </menu>
-    </item>
-
-    <item
-        android:id="@+id/download_group"
-        android:title="@string/manga_download"
-        app:showAsAction="never">
-        <menu>
-            <item
-                android:id="@+id/download_next"
-                android:title="@string/download_1" />
-            <item
-                android:id="@+id/download_next_5"
-                android:title="@string/download_5" />
-            <item
-                android:id="@+id/download_next_10"
-                android:title="@string/download_10" />
-            <item
-                android:id="@+id/download_custom"
-                android:title="@string/download_custom" />
-            <item
-                android:id="@+id/download_unread"
-                android:title="@string/download_unread" />
-            <item
-                android:id="@+id/download_all"
-                android:title="@string/download_all" />
-        </menu>
-    </item>
-
-    <item
-        android:id="@+id/action_edit_categories"
-        android:title="@string/action_edit_categories"
-        app:showAsAction="never" />
-
-    <item
-        android:id="@+id/action_edit_cover"
-        android:title="@string/action_edit_cover"
-        app:showAsAction="never" />
-
-    <item
-        android:id="@+id/action_migrate"
-        android:title="@string/action_migrate"
-        app:showAsAction="never" />
-</menu>

+ 47 - 0
app/src/main/res/menu/manga.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/download_group"
+        android:icon="@drawable/ic_get_app_24dp"
+        android:title="@string/manga_download"
+        app:iconTint="?attr/colorOnPrimary"
+        app:showAsAction="ifRoom">
+        <menu>
+            <item
+                android:id="@+id/download_next"
+                android:title="@string/download_1" />
+            <item
+                android:id="@+id/download_next_5"
+                android:title="@string/download_5" />
+            <item
+                android:id="@+id/download_next_10"
+                android:title="@string/download_10" />
+            <item
+                android:id="@+id/download_custom"
+                android:title="@string/download_custom" />
+            <item
+                android:id="@+id/download_unread"
+                android:title="@string/download_unread" />
+            <item
+                android:id="@+id/download_all"
+                android:title="@string/download_all" />
+        </menu>
+    </item>
+
+    <item
+        android:id="@+id/action_edit_categories"
+        android:title="@string/action_edit_categories"
+        app:showAsAction="never" />
+
+    <item
+        android:id="@+id/action_edit_cover"
+        android:title="@string/action_edit_cover"
+        app:showAsAction="never" />
+
+    <item
+        android:id="@+id/action_migrate"
+        android:title="@string/action_migrate"
+        app:showAsAction="never" />
+</menu>