mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 03:41:50 +01:00
Recently read improvements: Open next chapter if read, local date formatting
This commit is contained in:
parent
3dbdc495e7
commit
3680eb0bf5
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user