From 6533689539e52e38c0c4882f713c7991362dd2db Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 13 Apr 2020 00:46:01 -0400 Subject: [PATCH] Recents can now be filtered for only history or updates --- .../data/preference/PreferencesHelper.kt | 2 +- .../kanade/tachiyomi/ui/main/MainActivity.kt | 11 +- .../tachiyomi/ui/recent_updates/DateItem.kt | 7 +- .../ui/recently_read/RemoveHistoryDialog.kt | 16 ++- .../tachiyomi/ui/recents/RecentMangaHolder.kt | 26 +++- .../tachiyomi/ui/recents/RecentMangaItem.kt | 13 +- .../tachiyomi/ui/recents/RecentsController.kt | 60 +++++++-- .../tachiyomi/ui/recents/RecentsPresenter.kt | 119 ++++++++++++++---- app/src/main/res/menu/bottom_navigation.xml | 2 +- app/src/main/res/menu/recents.xml | 28 ++++- app/src/main/res/values/strings.xml | 13 +- 11 files changed, 231 insertions(+), 66 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 2a52a9ace6..29282ba4cd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 886a443676..9e53893e48 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -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 = diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/DateItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/DateItem.kt index e621eec2c3..78ab104281 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/DateItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/DateItem.kt @@ -11,7 +11,8 @@ import eu.davidea.viewholders.FlexibleViewHolder import eu.kanade.tachiyomi.R import java.util.Date -class DateItem(val date: Date) : AbstractHeaderItem() { +class DateItem(val date: Date, val addedString: Boolean = false) : AbstractHeaderItem() { override fun getLayoutRes(): Int { return R.layout.recent_chapters_section_item @@ -44,7 +45,9 @@ class DateItem(val date: Date) : AbstractHeaderItem() { 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 } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RemoveHistoryDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RemoveHistoryDialog.kt index 2b9e51d20d..c6546dc45c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RemoveHistoryDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RemoveHistoryDialog.kt @@ -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(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()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt index 187a74c2e4..1485cdb0b8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt @@ -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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt index 163a2836e9..060820c6ee 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt @@ -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(chapter, header) { + BaseChapterItem>(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? ) { - 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) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt index 66b6b5d185..915adcdd57 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt @@ -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) { 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() } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsPresenter.kt index 2757d1c9f6..58f39ff26b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsPresenter.kt @@ -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> { 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>> { + 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? = null } } diff --git a/app/src/main/res/menu/bottom_navigation.xml b/app/src/main/res/menu/bottom_navigation.xml index 57e4dbc97a..f813dbba17 100644 --- a/app/src/main/res/menu/bottom_navigation.xml +++ b/app/src/main/res/menu/bottom_navigation.xml @@ -11,7 +11,7 @@ android:icon="@drawable/recent_read_selector_24dp" android:title="@string/recents" /> diff --git a/app/src/main/res/menu/recents.xml b/app/src/main/res/menu/recents.xml index c94ad70479..d2431b4811 100644 --- a/app/src/main/res/menu/recents.xml +++ b/app/src/main/res/menu/recents.xml @@ -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" /> - + android:id="@+id/action_filter" + android:icon="@drawable/ic_filter_list_white_24dp" + android:title="@string/group_all" + app:showAsAction="ifRoom"> + + + + + + + + + History Recently read Recent updates - This will remove the read date of this chapter. Are you sure? + This will remove the read date of + \"%1$s\". Are you sure? + This will remove the read date of this + chapter. Are you sure? Reset all chapters for this %1$s %1$s - Ch.%2$s Last read %1$s @@ -190,8 +193,12 @@ Search recents… No recent chapters No recently read manga - Group recents - Ungroup recents + Group all + Ungroup all + Only history + Only updates + Reset chapter? + Press and hold to reset chapter history Search filters