Recently read improvements: Open next chapter if read, local date formatting

This commit is contained in:
len 2016-07-03 17:58:39 +02:00
parent 3dbdc495e7
commit 3680eb0bf5
4 changed files with 103 additions and 52 deletions

View File

@ -50,4 +50,14 @@ interface HistoryQueries : DbProvider {
.`object`(history) .`object`(history)
.withPutResolver(HistoryLastReadPutResolver()) .withPutResolver(HistoryLastReadPutResolver())
.prepare() .prepare()
/**
* Updates the history last read.
* Inserts history object if not yet in database
* @param historyList history object list
*/
fun updateHistoryLastRead(historyList: List<History>) = db.put()
.objects(historyList)
.withPutResolver(HistoryLastReadPutResolver())
.prepare()
} }

View File

@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaActivity import eu.kanade.tachiyomi.ui.manga.MangaActivity
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.fragment_recently_read.* import kotlinx.android.synthetic.main.fragment_recently_read.*
import nucleus.factory.RequiresPresenter import nucleus.factory.RequiresPresenter
@ -85,7 +86,6 @@ class RecentlyReadFragment : BaseRxFragment<RecentlyReadPresenter>() {
*/ */
fun removeFromHistory(history: History) { fun removeFromHistory(history: History) {
presenter.removeFromHistory(history) presenter.removeFromHistory(history)
adapter.notifyDataSetChanged()
} }
/** /**
@ -94,7 +94,6 @@ class RecentlyReadFragment : BaseRxFragment<RecentlyReadPresenter>() {
*/ */
fun removeAllFromHistory(mangaId: Long) { fun removeAllFromHistory(mangaId: Long) {
presenter.removeAllFromHistory(mangaId) presenter.removeAllFromHistory(mangaId)
adapter.notifyDataSetChanged()
} }
/** /**
@ -103,8 +102,29 @@ class RecentlyReadFragment : BaseRxFragment<RecentlyReadPresenter>() {
* @param manga manga belonging to chapter * @param manga manga belonging to chapter
*/ */
fun openChapter(chapter: Chapter, manga: Manga) { fun openChapter(chapter: Chapter, manga: Manga) {
if (!chapter.read) {
val intent = ReaderActivity.newIntent(activity, manga, chapter) val intent = ReaderActivity.newIntent(activity, manga, chapter)
startActivity(intent) 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<RecentlyReadPresenter>() {
startActivity(intent) 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)
}
} }

View File

@ -10,8 +10,11 @@ import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
import eu.kanade.tachiyomi.data.source.SourceManager import eu.kanade.tachiyomi.data.source.SourceManager
import kotlinx.android.synthetic.main.dialog_remove_recently.view.* import kotlinx.android.synthetic.main.dialog_remove_recently.view.*
import kotlinx.android.synthetic.main.item_recently_read.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.DecimalFormat
import java.text.DecimalFormatSymbols import java.text.DecimalFormatSymbols
import java.util.*
/** /**
* Holder that contains recent manga item * 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 decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols().apply { decimalSeparator = '.' })
private val sourceManager by injectLazy<SourceManager>()
private val df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT)
/** /**
* Set values of view * Set values of view
* *
@ -47,10 +54,10 @@ class RecentlyReadHolder(view: View, private val adapter: RecentlyReadAdapter)
// Set source + chapter title // Set source + chapter title
val formattedNumber = decimalFormat.format(chapter.chapter_number.toDouble()) val formattedNumber = decimalFormat.format(chapter.chapter_number.toDouble())
itemView.manga_source.text = itemView.context.getString(R.string.recent_manga_source) 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 // 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 // Set cover
if (!manga.thumbnail_url.isNullOrEmpty()) { if (!manga.thumbnail_url.isNullOrEmpty()) {
@ -79,7 +86,7 @@ class RecentlyReadHolder(view: View, private val adapter: RecentlyReadAdapter)
.onNegative { materialDialog, dialogAction -> .onNegative { materialDialog, dialogAction ->
materialDialog.dismiss() materialDialog.dismiss()
} }
.show(); .show()
} }
// Set continue reading clickListener // Set continue reading clickListener

View File

@ -2,15 +2,15 @@ package eu.kanade.tachiyomi.ui.recently_read
import android.os.Bundle import android.os.Bundle
import eu.kanade.tachiyomi.data.database.DatabaseHelper 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.History
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import timber.log.Timber import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.text.SimpleDateFormat
import java.util.* import java.util.*
/** /**
@ -20,13 +20,6 @@ import java.util.*
*/ */
class RecentlyReadPresenter : BasePresenter<RecentlyReadFragment>() { class RecentlyReadPresenter : BasePresenter<RecentlyReadFragment>() {
companion object {
/**
* The id of the restartable.
*/
const private val GET_RECENT_MANGA = 1
}
/** /**
* Used to connect to database * Used to connect to database
*/ */
@ -35,26 +28,18 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadFragment>() {
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
// Used to get recent manga // Used to get a list of recently read manga
restartableLatestCache(GET_RECENT_MANGA, getRecentMangaObservable()
{ getRecentMangaObservable() }, .subscribeLatestCache({ view, historyList ->
{ view, manga -> view.onNextManga(historyList)
// Update adapter to show recent manga's })
view.onNextManga(manga)
}
)
if (savedState == null) {
// Start fetching recent manga
start(GET_RECENT_MANGA)
}
} }
/** /**
* Get recent manga observable * Get recent manga observable
* @return list of history * @return list of history
*/ */
fun getRecentMangaObservable(): Observable<MutableList<MangaChapterHistory>> { fun getRecentMangaObservable(): Observable<List<MangaChapterHistory>> {
// Set date for recent manga // Set date for recent manga
val cal = Calendar.getInstance() val cal = Calendar.getInstance()
cal.time = Date() cal.time = Date()
@ -71,30 +56,67 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadFragment>() {
fun removeFromHistory(history: History) { fun removeFromHistory(history: History) {
history.last_read = 0L history.last_read = 0L
db.updateHistoryLastRead(history).asRxObservable() 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 * @param mangaId id of manga
*/ */
fun removeAllFromHistory(mangaId: Long) { fun removeAllFromHistory(mangaId: Long) {
db.getHistoryByMangaId(mangaId).asRxObservable() db.getHistoryByMangaId(mangaId).asRxSingle()
.take(1) .map { list ->
.flatMapIterable { it } list.forEach { it.last_read = 0L }
.doOnError { Timber.e(it.message) } db.updateHistoryLastRead(list).executeAsBlocking()
.subscribeOn(Schedulers.io()) }
.observeOn(AndroidSchedulers.mainThread()) .subscribe()
.subscribe({ result -> removeFromHistory(result) })
} }
/** /**
* Returns the timestamp of last read * Open the next chapter instead of the current one.
* @param history history containing time of last read * @param chapter the chapter of the history object.
* @param manga the manga of the chapter.
*/ */
fun getLastRead(history: History): String? { fun openNextChapter(chapter: Chapter, manga: Manga) {
return SimpleDateFormat("dd-MM-yyyy HH:mm", val sortFunction: (Chapter, Chapter) -> Int = when (manga.sorting) {
Locale.getDefault()).format(Date(history.last_read)) 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<Chapter> { 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)
})
} }
} }