Match infinite history and search history from preview (#3827)

* Add infinite history and search history

* Cleanup code

(cherry picked from commit 9d2adcd512c28872c9e958e9fcdcbccbd11b3b35)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryPresenter.kt
This commit is contained in:
jobobby04 2020-09-27 18:17:14 -04:00 committed by Jobobby04
parent 8acd834783
commit 9c76f1fd8f
4 changed files with 32 additions and 94 deletions

View File

@ -18,16 +18,18 @@ interface HistoryQueries : DbProvider {
*/
fun insertHistory(history: History) = db.put().`object`(history).prepare()
// SY -->
/**
* Returns history of recent manga containing last read chapter
* @param date recent date range
* @param limit the limit of manga to grab
* @param offset offset the db by
* @param search what to search in the db history
*/
fun getRecentManga(date: Date, offset: Int = 0, search: String = "") = db.get()
fun getRecentManga(date: Date, limit: Int = 25, offset: Int = 0, search: String = "") = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(
RawQuery.builder()
.query(getRecentMangasQuery(offset, search))
.query(getRecentMangasQuery(limit, offset, search))
.args(date.time)
.observesTables(HistoryTable.TABLE)
.build()
@ -35,24 +37,6 @@ interface HistoryQueries : DbProvider {
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
.prepare()
/**
* Returns history of recent manga containing last read chapter in 25s
* @param date recent date range
* @offset offset the db by
*/
fun getRecentMangaLimit(date: Date, limit: Int = 0, search: String = "") = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(
RawQuery.builder()
.query(getRecentMangasLimitQuery(limit, search))
.args(date.time)
.observesTables(HistoryTable.TABLE)
.build()
)
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
.prepare()
// SY <--
fun getHistoryByMangaId(mangaId: Long) = db.get()
.listOfObjects(History::class.java)
.withQuery(

View File

@ -136,36 +136,8 @@ fun getRecentsQuery() =
* The max_last_read table contains the most recent chapters grouped by manga
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
* and are read after the given time period
* @return return limit is 25
*/
// SY -->
fun getRecentMangasQuery(offset: Int = 0, search: String = "") =
"""
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
FROM ${Manga.TABLE}
JOIN ${Chapter.TABLE}
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
JOIN ${History.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
JOIN (
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID},${Chapter.TABLE}.${Chapter.COL_ID} as ${History.COL_CHAPTER_ID}, MAX(${History.TABLE}.${History.COL_LAST_READ}) as ${History.COL_LAST_READ}
FROM ${Chapter.TABLE} JOIN ${History.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ? AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
LIMIT 25 OFFSET $offset
"""
/**
* Query to get the recently read chapters of manga from the library up to a date.
* The max_last_read table contains the most recent chapters grouped by manga
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
* and are read after the given time period
*/
fun getRecentMangasLimitQuery(limit: Int = 25, search: String = "") =
fun getRecentMangasQuery(limit: Int = 25, offset: Int = 0, search: String = "") =
"""
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
FROM ${Manga.TABLE}
@ -183,9 +155,8 @@ fun getRecentMangasLimitQuery(limit: Int = 25, search: String = "") =
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
LIMIT $limit
LIMIT $limit OFFSET $offset
"""
// SY <--
fun getHistoryByMangaId() =
"""

View File

@ -25,7 +25,6 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.appcompat.queryTextChanges
import uy.kohesive.injekt.api.get
/**
* Fragment that shows recently read manga.
@ -53,6 +52,10 @@ class HistoryController :
* Endless loading item.
*/
private var progressItem: ProgressItem? = null
/**
* Search query.
*/
private var query = ""
override fun getTitle(): String? {
@ -105,6 +108,9 @@ class HistoryController :
}
}
/**
* Safely error if next page load fails
*/
fun onAddPageError(error: Throwable) {
adapter?.onLoadMoreComplete(null)
adapter?.endlessTargetCount = 1

View File

@ -13,7 +13,6 @@ import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import uy.kohesive.injekt.injectLazy
import java.util.Calendar
import java.util.Comparator
import java.util.Date
import java.util.TreeMap
@ -28,8 +27,6 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
* Used to connect to database
*/
val db: DatabaseHelper by injectLazy()
var lastCount = 25
var lastSearch = ""
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
@ -39,9 +36,7 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
}
fun requestNext(offset: Int, search: String = "") {
lastCount = offset
lastSearch = search
getRecentMangaObservable((offset), search)
getRecentMangaObservable(offset = offset, search = search)
.subscribeLatestCache(
{ view, mangas ->
view.onNextManga(mangas)
@ -54,37 +49,14 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
* Get recent manga observable
* @return list of history
*/
fun getRecentMangaObservable(offset: Int = 0, search: String = ""): Observable<List<HistoryItem>> {
private fun getRecentMangaObservable(limit: Int = 25, offset: Int = 0, search: String = ""): Observable<List<HistoryItem>> {
// Set date limit for recent manga
val cal = Calendar.getInstance().apply {
time = Date()
add(Calendar.YEAR, -50)
}
return db.getRecentManga(cal.time, offset, search).asRxObservable()
.map { recents ->
val map = TreeMap<Date, MutableList<MangaChapterHistory>> { d1, d2 -> d2.compareTo(d1) }
val byDay = recents
.groupByTo(map, { it.history.last_read.toDateKey() })
byDay.flatMap { entry ->
val dateItem = DateSectionItem(entry.key)
entry.value.map { HistoryItem(it, dateItem) }
}
}
.observeOn(AndroidSchedulers.mainThread())
}
/**
* Get recent manga observable
* @return list of history
*/
private fun getRecentMangaLimitObservable(offset: Int = 0, search: String = ""): Observable<List<HistoryItem>> {
// Set limit for recent manga
val cal = Calendar.getInstance()
cal.time = Date()
cal.add(Calendar.YEAR, -50)
return db.getRecentMangaLimit(cal.time, lastCount, search).asRxObservable()
return db.getRecentManga(cal.time, limit, offset, search).asRxObservable()
.map { recents ->
val map = TreeMap<Date, MutableList<MangaChapterHistory>> { d1, d2 -> d2.compareTo(d1) }
val byDay = recents
@ -103,13 +75,16 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
*/
fun removeFromHistory(history: History) {
history.last_read = 0L
db.updateHistoryLastRead(history).executeAsBlocking()
updateList()
db.updateHistoryLastRead(history).asRxObservable()
.subscribe()
}
fun updateList(search: String? = null) {
lastSearch = search ?: lastSearch
getRecentMangaLimitObservable(lastCount, lastSearch).take(1)
/**
* Pull a list of history from the db
* @param search a search query to use for filtering
*/
fun updateList(search: String = "") {
getRecentMangaObservable(search = search).take(1)
.subscribeLatestCache(
{ view, mangas ->
view.onNextManga(mangas, true)
@ -123,10 +98,12 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
* @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()
updateList()
db.getHistoryByMangaId(mangaId).asRxSingle()
.map { list ->
list.forEach { it.last_read = 0L }
db.updateHistoryLastRead(list).executeAsBlocking()
}
.subscribe()
}
/**
@ -148,7 +125,7 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
}
val chapters = db.getChapters(manga).executeAsBlocking()
.sortedWith(Comparator { c1, c2 -> sortFunction(c1, c2) })
.sortedWith { c1, c2 -> sortFunction(c1, c2) }
val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id }
return when (manga.sorting) {