From 3680eb0bf567064d6014d622aa3ad0e9453a288e Mon Sep 17 00:00:00 2001 From: len Date: Sun, 3 Jul 2016 17:58:39 +0200 Subject: [PATCH] Recently read improvements: Open next chapter if read, local date formatting --- .../data/database/queries/HistoryQueries.kt | 10 ++ .../ui/recently_read/RecentlyReadFragment.kt | 36 ++++--- .../ui/recently_read/RecentlyReadHolder.kt | 13 ++- .../ui/recently_read/RecentlyReadPresenter.kt | 96 ++++++++++++------- 4 files changed, 103 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt index 6b51775df..ec404bad2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt @@ -50,4 +50,14 @@ interface HistoryQueries : DbProvider { .`object`(history) .withPutResolver(HistoryLastReadPutResolver()) .prepare() + + /** + * Updates the history last read. + * Inserts history object if not yet in database + * @param historyList history object list + */ + fun updateHistoryLastRead(historyList: List) = db.put() + .objects(historyList) + .withPutResolver(HistoryLastReadPutResolver()) + .prepare() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadFragment.kt index 6264cdd51..3930570a4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadFragment.kt @@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.manga.MangaActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.toast import kotlinx.android.synthetic.main.fragment_recently_read.* import nucleus.factory.RequiresPresenter @@ -85,7 +86,6 @@ class RecentlyReadFragment : BaseRxFragment() { */ fun removeFromHistory(history: History) { presenter.removeFromHistory(history) - adapter.notifyDataSetChanged() } /** @@ -94,7 +94,6 @@ class RecentlyReadFragment : BaseRxFragment() { */ fun removeAllFromHistory(mangaId: Long) { presenter.removeAllFromHistory(mangaId) - adapter.notifyDataSetChanged() } /** @@ -103,8 +102,29 @@ class RecentlyReadFragment : BaseRxFragment() { * @param manga manga belonging to chapter */ fun openChapter(chapter: Chapter, manga: Manga) { - val intent = ReaderActivity.newIntent(activity, manga, chapter) - startActivity(intent) + if (!chapter.read) { + val intent = ReaderActivity.newIntent(activity, manga, chapter) + startActivity(intent) + } else { + presenter.openNextChapter(chapter, manga) + } + } + + /** + * Called from the presenter when wanting to open the next chapter of the current one. + * @param chapter the next chapter or null if it doesn't exist. + * @param manga the manga of the chapter. + */ + fun onOpenNextChapter(chapter: Chapter?, manga: Manga) { + if (chapter == null) { + context.toast(R.string.no_next_chapter) + } + // Avoid crashes if the fragment isn't resumed, the event will be ignored but it's unlikely + // to happen. + else if (isResumed) { + val intent = ReaderActivity.newIntent(activity, manga, chapter) + startActivity(intent) + } } /** @@ -116,12 +136,4 @@ class RecentlyReadFragment : BaseRxFragment() { startActivity(intent) } - /** - * Returns the timestamp of last read - * @param history history containing time of last read - */ - fun getLastRead(history: History): String? { - return presenter.getLastRead(history) - } - } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadHolder.kt index 7d4f9774b..07e18bfb5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadHolder.kt @@ -10,8 +10,11 @@ import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory import eu.kanade.tachiyomi.data.source.SourceManager import kotlinx.android.synthetic.main.dialog_remove_recently.view.* import kotlinx.android.synthetic.main.item_recently_read.view.* +import uy.kohesive.injekt.injectLazy +import java.text.DateFormat import java.text.DecimalFormat import java.text.DecimalFormatSymbols +import java.util.* /** * Holder that contains recent manga item @@ -30,6 +33,10 @@ class RecentlyReadHolder(view: View, private val adapter: RecentlyReadAdapter) */ private val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols().apply { decimalSeparator = '.' }) + private val sourceManager by injectLazy() + + private val df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT) + /** * Set values of view * @@ -47,10 +54,10 @@ class RecentlyReadHolder(view: View, private val adapter: RecentlyReadAdapter) // Set source + chapter title val formattedNumber = decimalFormat.format(chapter.chapter_number.toDouble()) itemView.manga_source.text = itemView.context.getString(R.string.recent_manga_source) - .format(SourceManager(adapter.fragment.context).get(manga.source)?.name, formattedNumber) + .format(sourceManager.get(manga.source)?.name, formattedNumber) // Set last read timestamp title - itemView.last_read.text = adapter.fragment.getLastRead(history) + itemView.last_read.text = df.format(Date(history.last_read)) // Set cover if (!manga.thumbnail_url.isNullOrEmpty()) { @@ -79,7 +86,7 @@ class RecentlyReadHolder(view: View, private val adapter: RecentlyReadAdapter) .onNegative { materialDialog, dialogAction -> materialDialog.dismiss() } - .show(); + .show() } // Set continue reading clickListener diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadPresenter.kt index ca77ca336..bcae72c1a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadPresenter.kt @@ -2,15 +2,15 @@ package eu.kanade.tachiyomi.ui.recently_read import android.os.Bundle 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.Manga import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import rx.Observable import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers import timber.log.Timber import uy.kohesive.injekt.injectLazy -import java.text.SimpleDateFormat import java.util.* /** @@ -20,13 +20,6 @@ import java.util.* */ class RecentlyReadPresenter : BasePresenter() { - companion object { - /** - * The id of the restartable. - */ - const private val GET_RECENT_MANGA = 1 - } - /** * Used to connect to database */ @@ -35,26 +28,18 @@ class RecentlyReadPresenter : BasePresenter() { override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) - // Used to get recent manga - restartableLatestCache(GET_RECENT_MANGA, - { getRecentMangaObservable() }, - { view, manga -> - // Update adapter to show recent manga's - view.onNextManga(manga) - } - ) - - if (savedState == null) { - // Start fetching recent manga - start(GET_RECENT_MANGA) - } + // Used to get a list of recently read manga + getRecentMangaObservable() + .subscribeLatestCache({ view, historyList -> + view.onNextManga(historyList) + }) } /** * Get recent manga observable * @return list of history */ - fun getRecentMangaObservable(): Observable> { + fun getRecentMangaObservable(): Observable> { // Set date for recent manga val cal = Calendar.getInstance() cal.time = Date() @@ -71,30 +56,67 @@ class RecentlyReadPresenter : BasePresenter() { fun removeFromHistory(history: History) { history.last_read = 0L db.updateHistoryLastRead(history).asRxObservable() - .doOnError { Timber.e(it.message) }.subscribe() + .subscribe() } /** - * Removes all chapters belonging to manga from library + * Removes all chapters belonging to manga from history. * @param mangaId id of manga */ fun removeAllFromHistory(mangaId: Long) { - db.getHistoryByMangaId(mangaId).asRxObservable() - .take(1) - .flatMapIterable { it } - .doOnError { Timber.e(it.message) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ result -> removeFromHistory(result) }) + db.getHistoryByMangaId(mangaId).asRxSingle() + .map { list -> + list.forEach { it.last_read = 0L } + db.updateHistoryLastRead(list).executeAsBlocking() + } + .subscribe() } /** - * Returns the timestamp of last read - * @param history history containing time of last read + * Open the next chapter instead of the current one. + * @param chapter the chapter of the history object. + * @param manga the manga of the chapter. */ - fun getLastRead(history: History): String? { - return SimpleDateFormat("dd-MM-yyyy HH:mm", - Locale.getDefault()).format(Date(history.last_read)) + fun openNextChapter(chapter: Chapter, manga: Manga) { + val sortFunction: (Chapter, Chapter) -> Int = when (manga.sorting) { + Manga.SORTING_SOURCE -> { c1, c2 -> c2.source_order.compareTo(c1.source_order) } + Manga.SORTING_NUMBER -> { c1, c2 -> c1.chapter_number.compareTo(c2.chapter_number) } + else -> throw NotImplementedError("Unknown sorting method") + } + + db.getChapters(manga).asRxSingle() + .map { it.sortedWith(Comparator { c1, c2 -> sortFunction(c1, c2) }) } + .map { chapters -> + val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id } + when (manga.sorting) { + Manga.SORTING_SOURCE -> { + chapters.getOrNull(currChapterIndex + 1) + } + Manga.SORTING_NUMBER -> { + val chapterNumber = chapter.chapter_number + + var nextChapter: Chapter? = null + for (i in (currChapterIndex + 1) until chapters.size) { + val c = chapters[i] + if (c.chapter_number > chapterNumber && + c.chapter_number <= chapterNumber + 1) { + + nextChapter = c + break + } + } + nextChapter + } + else -> throw NotImplementedError("Unknown sorting method") + } + } + .toObservable() + .observeOn(AndroidSchedulers.mainThread()) + .subscribeFirst({ view, chapter -> + view.onOpenNextChapter(chapter, manga) + }, { view, error -> + Timber.e(error, error.message) + }) } }