Recents can now be filtered for only history or updates

This commit is contained in:
Jay 2020-04-13 00:46:01 -04:00
parent cb6de21804
commit 6533689539
11 changed files with 231 additions and 66 deletions

View File

@ -245,7 +245,7 @@ class PreferencesHelper(val context: Context) {
fun extensionUpdatesCount() = rxPrefs.getInteger("ext_updates_count", 0)
fun groupRecents() = rxPrefs.getBoolean("group_recents", true)
fun recentsViewType() = rxPrefs.getInteger("recents_view_type", 0)
fun lastExtCheck() = rxPrefs.getLong("last_ext_check", 0)

View File

@ -145,7 +145,8 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}) return@setOnNavigationItemSelectedListener false
}
continueSwitchingTabs = false
preferences.lastTab().set(item.itemId)
if (item.itemId != R.id.nav_browse)
preferences.lastTab().set(item.itemId)
val currentRoot = router.backstack.firstOrNull()
if (currentRoot?.tag()?.toIntOrNull() != id) {
setRoot(when (id) {
@ -311,12 +312,12 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
private fun setExtensionsBadge() {
val updates = preferences.extensionUpdatesCount().getOrDefault()
if (updates > 0) {
val badge = bottom_nav.getOrCreateBadge(R.id.nav_catalogues)
val badge = bottom_nav.getOrCreateBadge(R.id.nav_browse)
badge.number = updates
badge.backgroundColor = getResourceColor(R.attr.badgeColor)
badge.badgeTextColor = Color.WHITE
} else {
bottom_nav.removeBadge(R.id.nav_catalogues)
bottom_nav.removeBadge(R.id.nav_browse)
}
}
@ -367,9 +368,9 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
router.pushController(controller.withFadeTransaction())
}
SHORTCUT_CATALOGUES -> bottom_nav.selectedItemId = R.id.nav_catalogues
SHORTCUT_CATALOGUES -> bottom_nav.selectedItemId = R.id.nav_browse
SHORTCUT_EXTENSIONS -> {
bottom_nav.selectedItemId = R.id.nav_catalogues
bottom_nav.selectedItemId = R.id.nav_browse
router.popToRoot()
bottom_nav.post {
val controller =

View File

@ -11,7 +11,8 @@ import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R
import java.util.Date
class DateItem(val date: Date) : AbstractHeaderItem<DateItem.Holder>() {
class DateItem(val date: Date, val addedString: Boolean = false) : AbstractHeaderItem<DateItem
.Holder>() {
override fun getLayoutRes(): Int {
return R.layout.recent_chapters_section_item
@ -44,7 +45,9 @@ class DateItem(val date: Date) : AbstractHeaderItem<DateItem.Holder>() {
val section_text: TextView = view.findViewById(R.id.section_text)
fun bind(item: DateItem) {
section_text.text = DateUtils.getRelativeTimeSpanString(item.date.time, now, DateUtils.DAY_IN_MILLIS)
val dateString = DateUtils.getRelativeTimeSpanString(item.date.time, now, DateUtils.DAY_IN_MILLIS)
section_text.text =
if (item.addedString) itemView.context.getString(R.string.added_, dateString) else dateString
}
}
}

View File

@ -7,6 +7,7 @@ import com.afollestad.materialdialogs.checkbox.checkBoxPrompt
import com.afollestad.materialdialogs.checkbox.isCheckPromptChecked
import com.bluelinelabs.conductor.Controller
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.base.controller.DialogController
@ -18,21 +19,28 @@ class RemoveHistoryDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
private var history: History? = null
constructor(target: T, manga: Manga, history: History) : this() {
private var chapter: Chapter? = null
constructor(target: T, manga: Manga, history: History, chapter: Chapter? = null) : this() {
this.manga = manga
this.history = history
this.chapter = chapter
targetController = target
}
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val activity = activity!!
return MaterialDialog(activity).title(R.string.remove)
.message(R.string.this_will_remove_the_read_date_question).checkBoxPrompt(
return MaterialDialog(activity).title(R.string.reset_chapter_question).message(
text = if (chapter?.name != null) activity.getString(
R.string.this_will_remove_the_read_date_for_x_question, chapter?.name ?: ""
)
else activity.getString(R.string.this_will_remove_the_read_date_question)
).checkBoxPrompt(
text = activity.getString(
R.string.reset_all_chapters_for_this_, manga!!.mangaType(activity)
)
) {}.negativeButton(android.R.string.cancel).positiveButton(R.string.remove) {
) {}.negativeButton(android.R.string.cancel).positiveButton(R.string.reset) {
onPositive(it.isCheckPromptChecked())
}
}

View File

@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterHolder
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.download_button.*
import kotlinx.android.synthetic.main.recent_manga_item.*
@ -37,9 +38,21 @@ class RecentMangaHolder(
fun bind(item: RecentMangaItem) {
download_button.visibleIf(item.mch.manga.source != LocalSource.ID)
subtitle.text = item.mch.manga.title
val isSearch = adapter.delegate.isSearching()
title.text = item.chapter.name
title.apply {
text = item.chapter.name
setTextColor(when {
item.chapter.bookmark -> context.getResourceColor(R.attr.colorAccent)
item.chapter.read -> context.getResourceColor(android.R.attr.textColorHint)
else -> context.getResourceColor(android.R.attr.textColorPrimary)
})
}
subtitle.apply {
text = item.mch.manga.title
setTextColor(when {
item.chapter.read -> context.getResourceColor(android.R.attr.textColorHint)
else -> context.getResourceColor(android.R.attr.textColorPrimary)
})
}
val notValidNum = item.mch.chapter.chapter_number <= 0
body.text = when {
item.mch.chapter.id == null -> body.context.getString(
@ -77,13 +90,18 @@ class RecentMangaHolder(
GlideApp.with(itemView.context).load(item.mch.manga).diskCacheStrategy(DiskCacheStrategy
.AUTOMATIC)
.signature(ObjectKey(MangaImpl.getLastCoverFetch(item.mch.manga.id!!).toString())).into(cover_thumbnail)
// adapter.delegate.setCover(item.mch.manga, cover_thumbnail)
notifyStatus(
if (adapter.isSelected(adapterPosition)) Download.CHECKED else item.status,
item.progress
)
}
override fun onLongClick(view: View?): Boolean {
super.onLongClick(view)
val item = adapter.getItem(adapterPosition) as? RecentMangaItem ?: return false
return item.mch.history.id != null
}
fun notifyStatus(status: Int, progress: Int) =
download_button.setDownloadStatus(status, progress)

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.recents
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
@ -13,10 +14,9 @@ import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterItem
class RecentMangaItem(
val mch: MangaChapterHistory = MangaChapterHistory.createBlank(),
chapter: Chapter = ChapterImpl(),
header:
RecentMangaHeaderItem?
header: AbstractHeaderItem<*>?
) :
BaseChapterItem<RecentMangaHolder, RecentMangaHeaderItem>(chapter, header) {
BaseChapterItem<RecentMangaHolder, AbstractHeaderItem<*>>(chapter, header) {
override fun getLayoutRes(): Int {
return if (mch.manga.id == null) R.layout.recents_footer_item
@ -37,14 +37,15 @@ class RecentMangaItem(
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other is RecentMangaItem) {
return if (mch.manga.id == null) header?.recentsType == other.header?.recentsType
return if (mch.manga.id == null) (header as? RecentMangaHeaderItem)?.recentsType ==
(other.header as? RecentMangaHeaderItem)?.recentsType
else chapter.id == other.chapter.id
}
return false
}
override fun hashCode(): Int {
return if (mch.manga.id == null) -(header?.recentsType ?: 0).hashCode()
return if (mch.manga.id == null) -((header as? RecentMangaHeaderItem)?.recentsType ?: 0).hashCode()
else (chapter.id ?: 0L).hashCode()
}
@ -54,7 +55,7 @@ class RecentMangaItem(
position: Int,
payloads: MutableList<Any?>?
) {
if (mch.manga.id == null) holder.bind(header?.recentsType ?: 0)
if (mch.manga.id == null) holder.bind((header as? RecentMangaHeaderItem)?.recentsType ?: 0)
else holder.bind(this)
}
}

View File

@ -8,6 +8,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.widget.SearchView
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
@ -20,6 +21,8 @@ import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
@ -32,7 +35,9 @@ import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController
import eu.kanade.tachiyomi.ui.recently_read.RemoveHistoryDialog
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForRootController
import eu.kanade.tachiyomi.util.view.scrollViewWith
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
@ -54,9 +59,11 @@ import kotlin.math.max
class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
RecentMangaAdapter.RecentsInterface,
FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener,
FlexibleAdapter.OnItemMoveListener,
RootSearchInterface,
BottomSheetController {
BottomSheetController,
RemoveHistoryDialog.Listener {
init {
setHasOptionsMenu(true)
@ -112,7 +119,10 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
}
presenter.onCreate()
if (presenter.recentItems.isNotEmpty()) adapter.updateDataSet(presenter.recentItems)
if (presenter.recentItems.isNotEmpty()) {
adapter.updateDataSet(presenter.recentItems)
adapter.addScrollableHeader(presenter.generalHeader)
}
dl_bottom_sheet.onCreate(this)
@ -173,6 +183,7 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
fun reEnableSwipe() {
swipe_refresh.isRefreshing = false
}
override fun onItemMove(fromPosition: Int, toPosition: Int) { }
override fun shouldMoveItem(fromPosition: Int, toPosition: Int) = true
@ -217,6 +228,9 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
fun showLists(recents: List<RecentMangaItem>) {
swipe_refresh.isRefreshing = LibraryUpdateService.isRunning()
adapter.updateDataSet(recents)
adapter.removeAllScrollableHeaders()
if (presenter.viewType > 0)
adapter.addScrollableHeader(presenter.generalHeader)
if (lastChapterId != null) {
refreshItem(lastChapterId ?: 0L)
lastChapterId = null
@ -286,6 +300,25 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
return true
}
override fun onItemLongClick(position: Int) {
val item = adapter.getItem(position) as? RecentMangaItem ?: return
val manga = item.mch.manga
val history = item.mch.history
val chapter = item.mch.chapter
if (history.id != null)
RemoveHistoryDialog(this, manga, history, chapter).showDialog(router)
}
override fun removeHistory(manga: Manga, history: History, all: Boolean) {
if (all) {
// Reset last read of chapter to 0L
presenter.removeAllFromHistory(manga.id!!)
} else {
// Remove all chapters belonging to manga from library
presenter.removeFromHistory(history)
}
}
override fun markAsRead(position: Int) {
val item = adapter.getItem(position) as? RecentMangaItem ?: return
val chapter = item.chapter
@ -323,10 +356,13 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
} else {
inflater.inflate(R.menu.recents, menu)
val viewItem = menu.findItem(R.id.action_view)
val endless = presenter.groupRecents
viewItem.setTitle(if (endless) R.string.group_recents else R.string.ungroup_recents)
viewItem.setIcon(if (endless) R.drawable.ic_view_stream_24dp else R.drawable.ic_view_headline_24dp)
when (presenter.viewType) {
0 -> menu.findItem(R.id.action_group_all)
1 -> menu.findItem(R.id.action_ungroup_all)
2 -> menu.findItem(R.id.action_only_history)
3 -> menu.findItem(R.id.action_only_updates)
else -> null
}?.isChecked = true
val searchItem = menu.findItem(R.id.action_search)
val searchView = searchItem.actionView as SearchView
@ -385,8 +421,16 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
if (showingDownloads)
return dl_bottom_sheet.onOptionsItemSelected(item)
when (item.itemId) {
R.id.action_view -> {
presenter.toggleGroupRecents()
R.id.action_group_all, R.id.action_ungroup_all, R.id.action_only_history,
R.id.action_only_updates -> {
presenter.toggleGroupRecents(when (item.itemId) {
R.id.action_ungroup_all -> 1
R.id.action_only_history -> 2
R.id.action_only_updates -> 3
else -> 0
})
if (item.itemId == R.id.action_only_history)
activity?.toast(R.string.press_and_hold_to_reset_history, Toast.LENGTH_LONG)
activity?.invalidateOptionsMenu()
}
}

View File

@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.ui.recents
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.HistoryImpl
import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
@ -13,6 +15,7 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.recent_updates.DateItem
import eu.kanade.tachiyomi.util.system.executeOnIO
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -24,6 +27,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Calendar
import java.util.Date
import java.util.TreeMap
import java.util.concurrent.TimeUnit
import kotlin.math.abs
@ -41,10 +45,10 @@ class RecentsPresenter(
var query = ""
private val newAdditionsHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEWLY_ADDED)
private val newChaptersHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEW_CHAPTERS)
private val endlessHeader = RecentMangaHeaderItem(-1)
val generalHeader = RecentMangaHeaderItem(-1)
private val continueReadingHeader = RecentMangaHeaderItem(RecentMangaHeaderItem
.CONTINUE_READING)
var groupRecents = preferences.groupRecents().getOrDefault()
var viewType: Int = preferences.recentsViewType().getOrDefault()
fun onCreate() {
downloadManager.addListener(this)
@ -60,12 +64,13 @@ class RecentsPresenter(
fun getRecents() {
val oldQuery = query
scope.launch {
val isEndless = groupRecents && query.isEmpty()
val isUngrouped = viewType > 0 && query.isEmpty()
// groupRecents && query.isEmpty()
val cal = Calendar.getInstance().apply {
time = Date()
when {
query.isNotEmpty() -> add(Calendar.YEAR, -50)
isEndless -> add(Calendar.MONTH, -1)
isUngrouped -> add(Calendar.MONTH, -1)
else -> add(Calendar.MONTH, -1)
}
}
@ -74,7 +79,7 @@ class RecentsPresenter(
time = Date()
when {
query.isNotEmpty() -> add(Calendar.YEAR, -50)
isEndless -> add(Calendar.MONTH, -1)
isUngrouped -> add(Calendar.MONTH, -1)
else -> add(Calendar.WEEK_OF_YEAR, -1)
}
}
@ -83,19 +88,30 @@ class RecentsPresenter(
time = Date()
when {
query.isNotEmpty() -> add(Calendar.YEAR, -50)
isEndless -> add(Calendar.MONTH, -1)
isUngrouped -> add(Calendar.MONTH, -1)
else -> add(Calendar.DAY_OF_YEAR, -1)
}
}
val cReading =
if (query.isEmpty()) db.getRecentsWithUnread(cal.time, query, isEndless).executeOnIO()
else db.getRecentMangaLimit(cal.time, 8, query).executeOnIO()
val rUpdates = db.getUpdatedManga(calWeek.time, query, isEndless).executeOnIO()
val cReading = if (viewType != 3)
if (query.isEmpty() && viewType != 2)
db.getRecentsWithUnread(cal.time, query, isUngrouped).executeOnIO()
else db.getRecentMangaLimit(
cal.time,
if (viewType == 2) 200 else 8,
query).executeOnIO() else emptyList()
val rUpdates = when {
viewType == 3 -> db.getRecentChapters(calWeek.time).executeOnIO().map {
MangaChapterHistory(it.manga, it.chapter, HistoryImpl())
}
viewType != 2 -> db.getUpdatedManga(calWeek.time, query, isUngrouped).executeOnIO()
else -> emptyList()
}
rUpdates.forEach {
it.history.last_read = it.chapter.date_fetch
}
val nAdditions = db.getRecentlyAdded(calDay.time, query, isEndless).executeOnIO()
val nAdditions = if (viewType < 2)
db.getRecentlyAdded(calDay.time, query, isUngrouped).executeOnIO() else emptyList()
nAdditions.forEach {
it.history.last_read = it.manga.date_added
}
@ -103,19 +119,21 @@ class RecentsPresenter(
val mangaList = (cReading + rUpdates + nAdditions).sortedByDescending {
it.history.last_read
}.distinctBy {
if (query.isEmpty()) it.manga.id else it.chapter.id
if (query.isEmpty() && viewType != 3) it.manga.id else it.chapter.id
}
val pairs = mangaList.mapNotNull {
val chapter = if (it.chapter.read || it.chapter.id == null) getNextChapter(it.manga)
else if (it.history.id == null) getFirstUpdatedChapter(it.manga, it.chapter)
else it.chapter
if (chapter == null) if (query.isNotEmpty() && it.chapter.id != null) Pair(
it, it.chapter
)
val chapter = when {
viewType == 3 -> it.chapter
it.chapter.read || it.chapter.id == null -> getNextChapter(it.manga)
it.history.id == null -> getFirstUpdatedChapter(it.manga, it.chapter)
else -> it.chapter
}
if (chapter == null) if ((query.isNotEmpty() || viewType > 1) &&
it.chapter.id != null) Pair(it, it.chapter)
else null
else Pair(it, chapter)
}
if (query.isEmpty() && !groupRecents) {
if (query.isEmpty() && !isUngrouped) {
val nChaptersItems =
pairs.filter { it.first.history.id == null && it.first.chapter.id != null }
.sortedWith(Comparator<Pair<MangaChapterHistory, Chapter>> { f1, f2 ->
@ -148,9 +166,20 @@ class RecentsPresenter(
it.firstOrNull()?.mch?.history?.last_read ?: 0L
}.flatten()
} else {
val header = if (isEndless) endlessHeader else null
recentItems = pairs.map { RecentMangaItem(it.first, it.second, header) }
if (isEndless && recentItems.isEmpty()) {
recentItems =
if (viewType == 3) {
val map = TreeMap<Date, MutableList<Pair<MangaChapterHistory, Chapter>>> {
d1, d2 -> d2
.compareTo(d1) }
val byDay =
pairs.groupByTo(map, { getMapKey(it.first.history.last_read) })
byDay.flatMap {
val dateItem = DateItem(it.key, true)
it.value.map { item ->
RecentMangaItem(item.first, item.second, dateItem) }
}
} else pairs.map { RecentMangaItem(it.first, it.second, null) }
if (isUngrouped && recentItems.isEmpty()) {
recentItems = listOf(
RecentMangaItem(header = newChaptersHeader),
RecentMangaItem(header = continueReadingHeader))
@ -183,9 +212,9 @@ class RecentsPresenter(
scope.cancel()
}
fun toggleGroupRecents() {
preferences.groupRecents().set(!groupRecents)
groupRecents = !groupRecents
fun toggleGroupRecents(pref: Int) {
preferences.recentsViewType().set(pref)
viewType = pref
getRecents()
}
@ -236,6 +265,22 @@ class RecentsPresenter(
}
}
/**
* Get date as time key
*
* @param date desired date
* @return date as time key
*/
private fun getMapKey(date: Long): Date {
val cal = Calendar.getInstance()
cal.time = Date(date)
cal[Calendar.HOUR_OF_DAY] = 0
cal[Calendar.MINUTE] = 0
cal[Calendar.SECOND] = 0
cal[Calendar.MILLISECOND] = 0
return cal.time
}
/**
* Downloads the given list of chapters with the manager.
* @param chapter the chapter to download.
@ -272,7 +317,29 @@ class RecentsPresenter(
}
}
private companion object {
// History
/**
* Reset last read of chapter to 0L
* @param history history belonging to chapter
*/
fun removeFromHistory(history: History) {
history.last_read = 0L
db.updateHistoryLastRead(history).executeAsBlocking()
getRecents()
}
/**
* Removes all chapters belonging to manga from history.
* @param mangaId id of manga
*/
fun removeAllFromHistory(mangaId: Long) {
val history = db.getHistoryByMangaId(mangaId).executeAsBlocking()
history.forEach { it.last_read = 0L }
db.updateHistoryLastRead(history).executeAsBlocking()
getRecents()
}
companion object {
var lastRecents: List<RecentMangaItem>? = null
}
}

View File

@ -11,7 +11,7 @@
android:icon="@drawable/recent_read_selector_24dp"
android:title="@string/recents" />
<item
android:id="@+id/nav_catalogues"
android:id="@+id/nav_browse"
android:icon="@drawable/browse_selector_24dp"
android:title="@string/browse" />
</group>

View File

@ -6,15 +6,31 @@
android:id="@+id/action_search"
android:icon="@drawable/ic_search_white_24dp"
android:title="@string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
android:visible="false"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView" />
<item
android:id="@+id/action_view"
android:icon="@drawable/ic_view_stream_24dp"
android:title="@string/group_recents"
app:showAsAction="ifRoom" />
android:id="@+id/action_filter"
android:icon="@drawable/ic_filter_list_white_24dp"
android:title="@string/group_all"
app:showAsAction="ifRoom">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/action_group_all"
android:title="@string/group_all" />
<item
android:id="@+id/action_ungroup_all"
android:title="@string/ungroup_all" />
<item
android:id="@+id/action_only_history"
android:title="@string/only_history" />
<item
android:id="@+id/action_only_updates"
android:title="@string/only_updates" />
</group>
</menu>
</item>
<item
android:id="@+id/action_settings"
android:icon="@drawable/ic_settings_white_24dp"

View File

@ -177,7 +177,10 @@
<string name="history">History</string>
<string name="recently_read">Recently read</string>
<string name="recent_updates">Recent updates</string>
<string name="this_will_remove_the_read_date_question">This will remove the read date of this chapter. Are you sure?</string>
<string name="this_will_remove_the_read_date_for_x_question">This will remove the read date of
\"%1$s\". Are you sure?</string>
<string name="this_will_remove_the_read_date_question">This will remove the read date of this
chapter. Are you sure?</string>
<string name="reset_all_chapters_for_this_">Reset all chapters for this %1$s</string>
<string name="source_dash_chapter_">%1$s - Ch.%2$s</string>
<string name="last_read_">Last read %1$s</string>
@ -190,8 +193,12 @@
<string name="search_recents">Search recents…</string>
<string name="no_recent_chapters">No recent chapters</string>
<string name="no_recently_read_manga">No recently read manga</string>
<string name="group_recents">Group recents</string>
<string name="ungroup_recents">Ungroup recents</string>
<string name="group_all">Group all</string>
<string name="ungroup_all">Ungroup all</string>
<string name="only_history">Only history</string>
<string name="only_updates">Only updates</string>
<string name="reset_chapter_question">Reset chapter?</string>
<string name="press_and_hold_to_reset_history">Press and hold to reset chapter history</string>
<!-- Browse -->
<string name="search_filters">Search filters</string>