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)
.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<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.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<RecentlyReadPresenter>() {
*/
fun removeFromHistory(history: History) {
presenter.removeFromHistory(history)
adapter.notifyDataSetChanged()
}
/**
@ -94,7 +94,6 @@ class RecentlyReadFragment : BaseRxFragment<RecentlyReadPresenter>() {
*/
fun removeAllFromHistory(mangaId: Long) {
presenter.removeAllFromHistory(mangaId)
adapter.notifyDataSetChanged()
}
/**
@ -103,8 +102,29 @@ class RecentlyReadFragment : BaseRxFragment<RecentlyReadPresenter>() {
* @param manga manga belonging to chapter
*/
fun openChapter(chapter: Chapter, manga: Manga) {
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<RecentlyReadPresenter>() {
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 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<SourceManager>()
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

View File

@ -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<RecentlyReadFragment>() {
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<RecentlyReadFragment>() {
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<MutableList<MangaChapterHistory>> {
fun getRecentMangaObservable(): Observable<List<MangaChapterHistory>> {
// Set date for recent manga
val cal = Calendar.getInstance()
cal.time = Date()
@ -71,30 +56,67 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadFragment>() {
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<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)
})
}
}