mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2025-01-11 12:09:09 +01:00
Steps to optimize recents loading
especially those with insanely large libraries
This commit is contained in:
parent
2ec4db3c10
commit
2f09ac8cb5
@ -56,5 +56,7 @@ open class DatabaseHelper(context: Context) :
|
|||||||
|
|
||||||
inline fun inTransaction(block: () -> Unit) = db.inTransaction(block)
|
inline fun inTransaction(block: () -> Unit) = db.inTransaction(block)
|
||||||
|
|
||||||
|
inline fun <T> inTransactionReturn(block: () -> T): T = db.inTransactionReturn(block)
|
||||||
|
|
||||||
fun lowLevel() = db.lowLevel()
|
fun lowLevel() = db.lowLevel()
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterGetResolver
|
|||||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver
|
||||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||||
import eu.kanade.tachiyomi.util.lang.sqLite
|
import eu.kanade.tachiyomi.util.lang.sqLite
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
interface ChapterQueries : DbProvider {
|
interface ChapterQueries : DbProvider {
|
||||||
|
|
||||||
@ -32,14 +31,12 @@ interface ChapterQueries : DbProvider {
|
|||||||
)
|
)
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
fun getRecentChapters(date: Date) = getRecentChapters(Date(), date)
|
fun getRecentChapters(search: String = "", offset: Int, isResuming: Boolean) = db.get()
|
||||||
|
|
||||||
fun getRecentChapters(startDate: Date, date: Date, search: String = "") = db.get()
|
|
||||||
.listOfObjects(MangaChapter::class.java)
|
.listOfObjects(MangaChapter::class.java)
|
||||||
.withQuery(
|
.withQuery(
|
||||||
RawQuery.builder()
|
RawQuery.builder()
|
||||||
.query(getRecentsQuery(search.sqLite))
|
.query(getRecentsQuery(search.sqLite, offset, isResuming))
|
||||||
.args(date.time, startDate.time)
|
// .args(date.time, startDate.time)
|
||||||
.observesTables(ChapterTable.TABLE)
|
.observesTables(ChapterTable.TABLE)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
@ -51,15 +48,12 @@ interface ChapterQueries : DbProvider {
|
|||||||
* @param date recent date range
|
* @param date recent date range
|
||||||
* @offset offset the db by
|
* @offset offset the db by
|
||||||
*/
|
*/
|
||||||
fun getUpdatedManga(date: Date, search: String = "", endless: Boolean) =
|
fun getUpdatedManga(search: String = "", endless: Boolean, offset: Int, isResuming: Boolean) = db.get()
|
||||||
getUpdatedManga(Date(), date, search, endless)
|
|
||||||
|
|
||||||
fun getUpdatedManga(startDate: Date, date: Date, search: String = "", endless: Boolean) = db.get()
|
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
.listOfObjects(MangaChapterHistory::class.java)
|
||||||
.withQuery(
|
.withQuery(
|
||||||
RawQuery.builder()
|
RawQuery.builder()
|
||||||
.query(getRecentsQueryDistinct(search.sqLite, endless))
|
.query(getRecentsQueryDistinct(search.sqLite, endless, offset, isResuming))
|
||||||
.args(date.time, startDate.time)
|
// .args(date.time, startDate.time)
|
||||||
.observesTables(ChapterTable.TABLE)
|
.observesTables(ChapterTable.TABLE)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
@ -10,7 +10,6 @@ import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolve
|
|||||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||||
import eu.kanade.tachiyomi.util.lang.sqLite
|
import eu.kanade.tachiyomi.util.lang.sqLite
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
interface HistoryQueries : DbProvider {
|
interface HistoryQueries : DbProvider {
|
||||||
|
|
||||||
@ -18,36 +17,36 @@ interface HistoryQueries : DbProvider {
|
|||||||
* Insert history into database
|
* Insert history into database
|
||||||
* @param history object containing history information
|
* @param history object containing history information
|
||||||
*/
|
*/
|
||||||
fun insertHistory(history: History) = db.put().`object`(history).prepare()
|
// fun insertHistory(history: History) = db.put().`object`(history).prepare()
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Returns history of recent manga containing last read chapter in 25s
|
||||||
|
// * @param date recent date range
|
||||||
|
// * @offset offset the db by
|
||||||
|
// */
|
||||||
|
// fun getRecentManga(date: Date, offset: Int = 0, search: String = "") = db.get()
|
||||||
|
// .listOfObjects(MangaChapterHistory::class.java)
|
||||||
|
// .withQuery(
|
||||||
|
// RawQuery.builder()
|
||||||
|
// .query(getRecentMangasQuery(offset, search.sqLite))
|
||||||
|
// .args(date.time)
|
||||||
|
// .observesTables(HistoryTable.TABLE)
|
||||||
|
// .build()
|
||||||
|
// )
|
||||||
|
// .withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
||||||
|
// .prepare()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns history of recent manga containing last read chapter in 25s
|
* Returns history of recent manga containing last read chapter in 25s
|
||||||
* @param date recent date range
|
* @param date recent date range
|
||||||
* @offset offset the db by
|
* @offset offset the db by
|
||||||
*/
|
*/
|
||||||
fun getRecentManga(date: Date, offset: Int = 0, search: String = "") = db.get()
|
fun getRecentlyAdded(search: String = "", endless: Boolean, offset: Int, isResuming: Boolean) = db.get()
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
.listOfObjects(MangaChapterHistory::class.java)
|
||||||
.withQuery(
|
.withQuery(
|
||||||
RawQuery.builder()
|
RawQuery.builder()
|
||||||
.query(getRecentMangasQuery(offset, search.sqLite))
|
.query(getRecentAdditionsQuery(search.sqLite, endless, offset, isResuming))
|
||||||
.args(date.time)
|
// .args(date.time, startDate.time)
|
||||||
.observesTables(HistoryTable.TABLE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.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 getRecentlyAdded(startDate: Date, date: Date, search: String = "", endless: Boolean) = db.get()
|
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
|
||||||
.withQuery(
|
|
||||||
RawQuery.builder()
|
|
||||||
.query(getRecentAdditionsQuery(search.sqLite, endless))
|
|
||||||
.args(date.time, startDate.time)
|
|
||||||
.observesTables(MangaTable.TABLE)
|
.observesTables(MangaTable.TABLE)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
@ -59,20 +58,12 @@ interface HistoryQueries : DbProvider {
|
|||||||
* @param date recent date range
|
* @param date recent date range
|
||||||
* @offset offset the db by
|
* @offset offset the db by
|
||||||
*/
|
*/
|
||||||
fun getRecentMangaLimit(date: Date, limit: Int = 0, search: String = "") =
|
fun getRecentMangaLimit(search: String = "", endless: Boolean, offset: Int, isResuming: Boolean) = db.get()
|
||||||
getRecentMangaLimit(Date(), date, limit, search)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns history of recent manga containing last read chapter in 25s
|
|
||||||
* @param date recent date range
|
|
||||||
* @offset offset the db by
|
|
||||||
*/
|
|
||||||
fun getRecentMangaLimit(startDate: Date, date: Date, limit: Int = 0, search: String = "") = db.get()
|
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
.listOfObjects(MangaChapterHistory::class.java)
|
||||||
.withQuery(
|
.withQuery(
|
||||||
RawQuery.builder()
|
RawQuery.builder()
|
||||||
.query(getRecentMangasLimitQuery(limit, search.sqLite))
|
.query(getRecentMangasLimitQuery(search.sqLite, endless, offset, isResuming))
|
||||||
.args(date.time, startDate.time)
|
// .args(date.time, startDate.time)
|
||||||
.observesTables(HistoryTable.TABLE)
|
.observesTables(HistoryTable.TABLE)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
@ -84,29 +75,20 @@ interface HistoryQueries : DbProvider {
|
|||||||
* @param date recent date range
|
* @param date recent date range
|
||||||
* @offset offset the db by
|
* @offset offset the db by
|
||||||
*/
|
*/
|
||||||
fun getRecentsWithUnread(startDate: Date, date: Date, search: String = "", endless: Boolean) = db.get()
|
fun getAllRecents(search: String = "", includeRead: Boolean, endless: Boolean, offset: Int, isResuming: Boolean) = db.get()
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
.listOfObjects(MangaChapterHistory::class.java)
|
||||||
.withQuery(
|
.withQuery(
|
||||||
RawQuery.builder()
|
RawQuery.builder()
|
||||||
.query(getRecentReadWithUnreadChapters(search.sqLite, endless))
|
.query(
|
||||||
.args(date.time, startDate.time)
|
getRecentRead(
|
||||||
.observesTables(HistoryTable.TABLE)
|
search.sqLite,
|
||||||
.build()
|
includeRead,
|
||||||
|
endless,
|
||||||
|
offset,
|
||||||
|
isResuming
|
||||||
)
|
)
|
||||||
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
)
|
||||||
.prepare()
|
// .args(date.time, startDate.time)
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns history of recent manga containing last read chapter in 25s
|
|
||||||
* @param date recent date range
|
|
||||||
* @offset offset the db by
|
|
||||||
*/
|
|
||||||
fun getAllRecents(startDate: Date, date: Date, search: String = "", endless: Boolean) = db.get()
|
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
|
||||||
.withQuery(
|
|
||||||
RawQuery.builder()
|
|
||||||
.query(getRecentRead(search.sqLite, endless))
|
|
||||||
.args(date.time, startDate.time)
|
|
||||||
.observesTables(HistoryTable.TABLE)
|
.observesTables(HistoryTable.TABLE)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.data.database.queries
|
package eu.kanade.tachiyomi.data.database.queries
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.ui.recents.RecentsPresenter
|
||||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable as Category
|
import eu.kanade.tachiyomi.data.database.tables.CategoryTable as Category
|
||||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable as Chapter
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable as Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable as History
|
import eu.kanade.tachiyomi.data.database.tables.HistoryTable as History
|
||||||
@ -41,36 +42,41 @@ val libraryQuery =
|
|||||||
/**
|
/**
|
||||||
* Query to get the recent chapters of manga from the library up to a date.
|
* Query to get the recent chapters of manga from the library up to a date.
|
||||||
*/
|
*/
|
||||||
fun getRecentsQuery(search: String) =
|
fun getRecentsQuery(search: String, offset: Int, isResuming: Boolean) =
|
||||||
"""
|
"""
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, * FROM ${Manga.TABLE} JOIN ${Chapter.TABLE}
|
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, * FROM ${Manga.TABLE} JOIN ${Chapter.TABLE}
|
||||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${Manga.COL_FAVORITE} = 1
|
WHERE ${Manga.COL_FAVORITE} = 1
|
||||||
AND ${Chapter.COL_DATE_FETCH} > ?
|
|
||||||
AND ${Chapter.COL_DATE_FETCH} < ?
|
|
||||||
AND ${Chapter.COL_DATE_FETCH} > ${Manga.COL_DATE_ADDED}
|
AND ${Chapter.COL_DATE_FETCH} > ${Manga.COL_DATE_ADDED}
|
||||||
AND lower(${Manga.COL_TITLE}) LIKE '%$search%'
|
AND lower(${Manga.COL_TITLE}) LIKE '%$search%'
|
||||||
ORDER BY ${Chapter.COL_DATE_UPLOAD} DESC
|
ORDER BY ${Chapter.COL_DATE_FETCH} DESC
|
||||||
|
${limitAndOffset(true, isResuming, offset)}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to get the recently added manga
|
* Query to get the recently added manga
|
||||||
*/
|
*/
|
||||||
fun getRecentAdditionsQuery(search: String, endless: Boolean) =
|
fun getRecentAdditionsQuery(search: String, endless: Boolean, offset: Int, isResuming: Boolean) =
|
||||||
"""
|
"""
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, * FROM ${Manga.TABLE}
|
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, * FROM ${Manga.TABLE}
|
||||||
WHERE ${Manga.COL_FAVORITE} = 1
|
WHERE ${Manga.COL_FAVORITE} = 1
|
||||||
AND ${Manga.COL_DATE_ADDED} > ?
|
|
||||||
AND ${Manga.COL_DATE_ADDED} < ?
|
|
||||||
AND lower(${Manga.COL_TITLE}) LIKE '%$search%'
|
AND lower(${Manga.COL_TITLE}) LIKE '%$search%'
|
||||||
ORDER BY ${Manga.COL_DATE_ADDED} DESC
|
ORDER BY ${Manga.COL_DATE_ADDED} DESC
|
||||||
${if (endless) "" else "LIMIT 8"}
|
${limitAndOffset(endless, isResuming, offset)}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
fun limitAndOffset(endless: Boolean, isResuming: Boolean, offset: Int): String {
|
||||||
|
return when {
|
||||||
|
isResuming && endless -> "LIMIT $offset"
|
||||||
|
endless -> "LIMIT ${RecentsPresenter.ENDLESS_LIMIT}\nOFFSET $offset"
|
||||||
|
else -> "LIMIT 8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to get the manga with recently uploaded chapters
|
* Query to get the manga with recently uploaded chapters
|
||||||
*/
|
*/
|
||||||
fun getRecentsQueryDistinct(search: String, endless: Boolean) =
|
fun getRecentsQueryDistinct(search: String, endless: Boolean, offset: Int = 0, isResuming: Boolean) =
|
||||||
"""
|
"""
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*
|
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*
|
||||||
FROM ${Manga.TABLE}
|
FROM ${Manga.TABLE}
|
||||||
@ -80,17 +86,15 @@ fun getRecentsQueryDistinct(search: String, endless: Boolean) =
|
|||||||
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID},${Chapter.TABLE}.${Chapter.COL_ID} as ${History.COL_CHAPTER_ID},MAX(${Chapter.TABLE}.${Chapter.COL_DATE_UPLOAD})
|
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID},${Chapter.TABLE}.${Chapter.COL_ID} as ${History.COL_CHAPTER_ID},MAX(${Chapter.TABLE}.${Chapter.COL_DATE_UPLOAD})
|
||||||
FROM ${Chapter.TABLE} JOIN ${Manga.TABLE}
|
FROM ${Chapter.TABLE} JOIN ${Manga.TABLE}
|
||||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${Chapter.COL_DATE_FETCH} > ?
|
WHERE ${Chapter.COL_READ} = 0
|
||||||
AND ${Chapter.COL_DATE_FETCH} < ?
|
|
||||||
AND ${Chapter.COL_READ} = 0
|
|
||||||
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS newest_chapter
|
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS newest_chapter
|
||||||
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = newest_chapter.${Chapter.COL_MANGA_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = newest_chapter.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${Manga.COL_FAVORITE} = 1
|
WHERE ${Manga.COL_FAVORITE} = 1
|
||||||
AND newest_chapter.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
|
AND newest_chapter.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
|
||||||
AND ${Chapter.COL_DATE_FETCH} > ${Manga.COL_DATE_ADDED}
|
AND ${Chapter.COL_DATE_FETCH} > ${Manga.COL_DATE_ADDED}
|
||||||
AND lower(${Manga.COL_TITLE}) LIKE '%$search%'
|
AND lower(${Manga.COL_TITLE}) LIKE '%$search%'
|
||||||
ORDER BY ${Chapter.COL_DATE_UPLOAD} DESC
|
ORDER BY ${Chapter.COL_DATE_FETCH} DESC
|
||||||
${if (endless) "" else "LIMIT 8"}
|
${limitAndOffset(endless, isResuming, offset)}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,9 +102,13 @@ fun getRecentsQueryDistinct(search: String, endless: Boolean) =
|
|||||||
* The max_last_read table contains the most recent chapters grouped by manga
|
* 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
|
* 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
|
* and are read after the given time period
|
||||||
* @return return limit is 25
|
|
||||||
*/
|
*/
|
||||||
fun getRecentMangasQuery(offset: Int = 0, search: String = "") =
|
fun getRecentMangasLimitQuery(
|
||||||
|
search: String = "",
|
||||||
|
endless: Boolean,
|
||||||
|
offset: Int = 0,
|
||||||
|
isResuming: Boolean
|
||||||
|
) =
|
||||||
"""
|
"""
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
||||||
FROM ${Manga.TABLE}
|
FROM ${Manga.TABLE}
|
||||||
@ -114,39 +122,10 @@ fun getRecentMangasQuery(offset: Int = 0, search: String = "") =
|
|||||||
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
|
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}
|
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 max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
|
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
|
||||||
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
||||||
LIMIT 25 OFFSET $offset
|
${limitAndOffset(endless, isResuming, 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 = "") =
|
|
||||||
"""
|
|
||||||
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 ${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 $limit
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,7 +135,13 @@ fun getRecentMangasLimitQuery(limit: Int = 25, search: String = "") =
|
|||||||
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
|
* 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
|
* and are read after the given time period
|
||||||
*/
|
*/
|
||||||
fun getRecentReadWithUnreadChapters(search: String = "", endless: Boolean) =
|
fun getRecentRead(
|
||||||
|
search: String = "",
|
||||||
|
includeRead: Boolean,
|
||||||
|
endless: Boolean,
|
||||||
|
offset: Int = 0,
|
||||||
|
isResuming: Boolean
|
||||||
|
) =
|
||||||
"""
|
"""
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
||||||
FROM (
|
FROM (
|
||||||
@ -165,11 +150,10 @@ fun getRecentReadWithUnreadChapters(search: String = "", endless: Boolean) =
|
|||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS unread
|
SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS unread
|
||||||
FROM ${Chapter.TABLE}
|
FROM ${Chapter.TABLE}
|
||||||
WHERE ${Chapter.COL_READ} = 0
|
|
||||||
GROUP BY ${Chapter.COL_MANGA_ID}
|
GROUP BY ${Chapter.COL_MANGA_ID}
|
||||||
) AS C
|
) AS C
|
||||||
ON ${Manga.COL_ID} = C.${Chapter.COL_MANGA_ID}
|
ON ${Manga.COL_ID} = C.${Chapter.COL_MANGA_ID}
|
||||||
WHERE C.unread > 0
|
${if (includeRead) "" else "WHERE C.unread > 0"}
|
||||||
GROUP BY ${Manga.COL_ID}
|
GROUP BY ${Manga.COL_ID}
|
||||||
ORDER BY ${Manga.COL_TITLE}
|
ORDER BY ${Manga.COL_TITLE}
|
||||||
) AS ${Manga.TABLE}
|
) AS ${Manga.TABLE}
|
||||||
@ -183,53 +167,10 @@ fun getRecentReadWithUnreadChapters(search: String = "", endless: Boolean) =
|
|||||||
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
|
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}
|
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ?
|
|
||||||
AND ${History.TABLE}.${History.COL_LAST_READ} < ?
|
|
||||||
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
|
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
|
||||||
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
||||||
${if (endless) "" else "LIMIT 8"}
|
${limitAndOffset(endless, isResuming, offset)}
|
||||||
"""
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query to get the recently read manga that has more chapters to read
|
|
||||||
* The first from checks that there's an unread chapter
|
|
||||||
* 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 getRecentRead(search: String = "", endless: Boolean) =
|
|
||||||
"""
|
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
|
||||||
FROM (
|
|
||||||
SELECT ${Manga.TABLE}.*
|
|
||||||
FROM ${Manga.TABLE}
|
|
||||||
LEFT JOIN (
|
|
||||||
SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS unread
|
|
||||||
FROM ${Chapter.TABLE}
|
|
||||||
GROUP BY ${Chapter.COL_MANGA_ID}
|
|
||||||
) AS C
|
|
||||||
ON ${Manga.COL_ID} = C.${Chapter.COL_MANGA_ID}
|
|
||||||
WHERE C.unread > 0
|
|
||||||
GROUP BY ${Manga.COL_ID}
|
|
||||||
ORDER BY ${Manga.COL_TITLE}
|
|
||||||
) AS ${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 ${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
|
|
||||||
${if (endless) "" else "LIMIT 8"}
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
fun getHistoryByMangaId() =
|
fun getHistoryByMangaId() =
|
||||||
|
@ -181,6 +181,8 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
presenter.onCreate()
|
presenter.onCreate()
|
||||||
|
binding.swipeRefresh.isRefreshing = true
|
||||||
|
|
||||||
if (presenter.recentItems.isNotEmpty()) {
|
if (presenter.recentItems.isNotEmpty()) {
|
||||||
adapter.updateDataSet(presenter.recentItems)
|
adapter.updateDataSet(presenter.recentItems)
|
||||||
}
|
}
|
||||||
@ -345,7 +347,9 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
override fun onActivityResumed(activity: Activity) {
|
override fun onActivityResumed(activity: Activity) {
|
||||||
super.onActivityResumed(activity)
|
super.onActivityResumed(activity)
|
||||||
if (!isBindingInitialized) return
|
if (!isBindingInitialized) return
|
||||||
|
if (!presenter.isLoading) {
|
||||||
refresh()
|
refresh()
|
||||||
|
}
|
||||||
setBottomPadding()
|
setBottomPadding()
|
||||||
binding.downloadBottomSheet.dlBottomSheet.update()
|
binding.downloadBottomSheet.dlBottomSheet.update()
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import eu.kanade.tachiyomi.data.library.LibraryServiceListener
|
|||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -46,7 +45,7 @@ class RecentsPresenter(
|
|||||||
var query = ""
|
var query = ""
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
page = 0
|
resetOffsets()
|
||||||
}
|
}
|
||||||
private val newAdditionsHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEWLY_ADDED)
|
private val newAdditionsHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEWLY_ADDED)
|
||||||
private val newChaptersHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEW_CHAPTERS)
|
private val newChaptersHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEW_CHAPTERS)
|
||||||
@ -55,23 +54,37 @@ class RecentsPresenter(
|
|||||||
.CONTINUE_READING
|
.CONTINUE_READING
|
||||||
)
|
)
|
||||||
var finished = false
|
var finished = false
|
||||||
var shouldMoveToTop = false
|
var heldItems: HashMap<Int, List<RecentMangaItem>> = hashMapOf()
|
||||||
|
private var shouldMoveToTop = false
|
||||||
var viewType: Int = preferences.recentsViewType().get()
|
var viewType: Int = preferences.recentsViewType().get()
|
||||||
private var page = 0
|
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
if (value == 0) {
|
ENDLESS_LIMIT = if (value == VIEW_TYPE_UNGROUP_ALL) 25 else 50
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetOffsets() {
|
||||||
finished = false
|
finished = false
|
||||||
shouldMoveToTop = true
|
shouldMoveToTop = true
|
||||||
|
updatesOffset = 0
|
||||||
|
historyOffset = 0
|
||||||
|
additionsOffset = 0
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private var updatesOffset = 0
|
||||||
|
private var historyOffset = 0
|
||||||
|
private var additionsOffset = 0
|
||||||
|
var isLoading = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val isOnFirstPage: Boolean
|
||||||
|
get() = additionsOffset + historyOffset + updatesOffset == 0
|
||||||
|
|
||||||
init {
|
init {
|
||||||
preferences.showReadInAllRecents()
|
preferences.showReadInAllRecents()
|
||||||
.asFlow()
|
.asFlow()
|
||||||
.drop(1)
|
.drop(1)
|
||||||
.onEach {
|
.onEach {
|
||||||
page = 0
|
resetOffsets()
|
||||||
getRecents()
|
getRecents()
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(scope)
|
||||||
@ -97,97 +110,107 @@ class RecentsPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun runRecents(oldQuery: String = "", updatePageCount: Boolean = false, retryCount: Int = 0, itemCount: Int = 0, limit: Boolean = false) {
|
private suspend fun runRecents(
|
||||||
|
oldQuery: String = "",
|
||||||
|
updatePageCount: Boolean = false,
|
||||||
|
retryCount: Int = 0,
|
||||||
|
itemCount: Int = 0,
|
||||||
|
limit: Boolean = false,
|
||||||
|
customViewType: Int? = null
|
||||||
|
) {
|
||||||
if (retryCount > 15) {
|
if (retryCount > 15) {
|
||||||
finished = true
|
finished = true
|
||||||
setDownloadedChapters(recentItems)
|
setDownloadedChapters(recentItems)
|
||||||
withContext(Dispatchers.Main) { controller?.showLists(recentItems, false) }
|
if (customViewType == null) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
controller?.showLists(recentItems, false)
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
val viewType = customViewType ?: viewType
|
||||||
|
|
||||||
|
// Timber.d("starting up items new page: $updatePageCount")
|
||||||
val showRead = preferences.showReadInAllRecents().get() && !limit
|
val showRead = preferences.showReadInAllRecents().get() && !limit
|
||||||
if (updatePageCount) {
|
|
||||||
page++
|
|
||||||
}
|
|
||||||
|
|
||||||
val isUngrouped = viewType > VIEW_TYPE_GROUP_ALL && query.isEmpty()
|
val isUngrouped = viewType > VIEW_TYPE_GROUP_ALL && query.isEmpty()
|
||||||
val cal = Calendar.getInstance().apply {
|
|
||||||
time = Date()
|
|
||||||
when {
|
|
||||||
query.isNotEmpty() -> add(Calendar.YEAR, -50)
|
|
||||||
isUngrouped -> add(Calendar.MONTH, -(page + 1))
|
|
||||||
else -> add(Calendar.MONTH, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val startCal = Calendar.getInstance().apply {
|
|
||||||
time = Date()
|
|
||||||
when {
|
|
||||||
query.isNotEmpty() -> {}
|
|
||||||
isUngrouped && !updatePageCount -> {}
|
|
||||||
isUngrouped -> add(Calendar.MONTH, -page)
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val calWeek = Calendar.getInstance().apply {
|
|
||||||
time = Date()
|
|
||||||
when {
|
|
||||||
query.isNotEmpty() -> add(Calendar.YEAR, -50)
|
|
||||||
isUngrouped -> add(Calendar.MONTH, -(page + 1))
|
|
||||||
else -> add(Calendar.WEEK_OF_YEAR, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val calDay = Calendar.getInstance().apply {
|
|
||||||
time = Date()
|
|
||||||
when {
|
|
||||||
query.isNotEmpty() -> add(Calendar.YEAR, -50)
|
|
||||||
isUngrouped -> add(Calendar.MONTH, -(page + 1))
|
|
||||||
else -> add(Calendar.DAY_OF_YEAR, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
val isCustom = customViewType != null
|
||||||
|
val isEndless = isUngrouped && !limit
|
||||||
|
// Timber.d("set up cal items")
|
||||||
|
val (cReading, rUpdates, nAdditions) = db.inTransactionReturn {
|
||||||
val cReading = if (viewType != VIEW_TYPE_ONLY_UPDATES) {
|
val cReading = if (viewType != VIEW_TYPE_ONLY_UPDATES) {
|
||||||
if (query.isEmpty() && viewType != VIEW_TYPE_ONLY_HISTORY) {
|
if (query.isEmpty() && viewType != VIEW_TYPE_ONLY_HISTORY) {
|
||||||
if (showRead) {
|
db.getAllRecents(
|
||||||
db.getAllRecents(startCal.time, cal.time, query, isUngrouped && !limit)
|
query,
|
||||||
.executeOnIO()
|
showRead,
|
||||||
|
isEndless,
|
||||||
|
if (isCustom) ENDLESS_LIMIT else historyOffset,
|
||||||
|
!updatePageCount && !isOnFirstPage
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
db.getRecentsWithUnread(startCal.time, cal.time, query, isUngrouped && !limit)
|
db.getRecentMangaLimit(
|
||||||
.executeOnIO()
|
query,
|
||||||
}
|
isEndless,
|
||||||
} else db.getRecentMangaLimit(
|
if (isCustom) ENDLESS_LIMIT else historyOffset,
|
||||||
startCal.time,
|
!updatePageCount && !isOnFirstPage
|
||||||
cal.time,
|
)
|
||||||
if (viewType == VIEW_TYPE_ONLY_HISTORY) 200 else 8,
|
}.executeAsBlocking()
|
||||||
query
|
|
||||||
).executeOnIO()
|
|
||||||
} else emptyList()
|
} else emptyList()
|
||||||
|
// Timber.d("set up cReader items: ${cReading.size}")
|
||||||
val rUpdates = when {
|
val rUpdates = when {
|
||||||
viewType == VIEW_TYPE_ONLY_UPDATES -> db.getRecentChapters(startCal.time, calWeek.time, query).executeOnIO().map {
|
viewType == VIEW_TYPE_ONLY_UPDATES -> db.getRecentChapters(
|
||||||
|
query,
|
||||||
|
if (isCustom) ENDLESS_LIMIT else updatesOffset,
|
||||||
|
!updatePageCount && !isOnFirstPage
|
||||||
|
).executeAsBlocking().map {
|
||||||
MangaChapterHistory(it.manga, it.chapter, HistoryImpl())
|
MangaChapterHistory(it.manga, it.chapter, HistoryImpl())
|
||||||
}
|
}
|
||||||
viewType != VIEW_TYPE_ONLY_HISTORY -> db.getUpdatedManga(startCal.time, calWeek.time, query, isUngrouped && !limit).executeOnIO()
|
viewType != VIEW_TYPE_ONLY_HISTORY -> db.getUpdatedManga(
|
||||||
|
query,
|
||||||
|
isEndless,
|
||||||
|
if (isCustom) ENDLESS_LIMIT else updatesOffset,
|
||||||
|
!updatePageCount && !isOnFirstPage
|
||||||
|
).executeAsBlocking()
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
rUpdates.forEach {
|
rUpdates.forEach {
|
||||||
it.history.last_read = it.chapter.date_fetch
|
it.history.last_read = it.chapter.date_fetch
|
||||||
}
|
}
|
||||||
|
// Timber.d("set up rUpdates items: ${rUpdates.size}")
|
||||||
val nAdditions = if (viewType < VIEW_TYPE_ONLY_HISTORY) {
|
val nAdditions = if (viewType < VIEW_TYPE_ONLY_HISTORY) {
|
||||||
db.getRecentlyAdded(startCal.time, calDay.time, query, isUngrouped && !limit).executeOnIO()
|
db.getRecentlyAdded(
|
||||||
|
query,
|
||||||
|
isEndless,
|
||||||
|
if (isCustom) ENDLESS_LIMIT else additionsOffset,
|
||||||
|
!updatePageCount && !isOnFirstPage
|
||||||
|
).executeAsBlocking()
|
||||||
} else emptyList()
|
} else emptyList()
|
||||||
nAdditions.forEach {
|
nAdditions.forEach {
|
||||||
it.history.last_read = it.manga.date_added
|
it.history.last_read = it.manga.date_added
|
||||||
}
|
}
|
||||||
|
// Timber.d("set up nAdditons items: ${nAdditions.size}")
|
||||||
|
Triple(cReading, rUpdates, nAdditions)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isCustom &&
|
||||||
|
(historyOffset + updatesOffset + additionsOffset == 0 || updatePageCount)
|
||||||
|
) {
|
||||||
|
additionsOffset += nAdditions.size
|
||||||
|
historyOffset += cReading.size
|
||||||
|
updatesOffset += rUpdates.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timber.d("loaded items: ")
|
||||||
if (query != oldQuery) return
|
if (query != oldQuery) return
|
||||||
|
// Timber.d("query matches items: ")
|
||||||
val mangaList = (cReading + rUpdates + nAdditions).sortedByDescending {
|
val mangaList = (cReading + rUpdates + nAdditions).sortedByDescending {
|
||||||
it.history.last_read
|
it.history.last_read
|
||||||
}.distinctBy {
|
}.distinctBy {
|
||||||
if (query.isEmpty() && viewType != VIEW_TYPE_ONLY_HISTORY) it.manga.id else it.chapter.id
|
if (query.isEmpty() && viewType != VIEW_TYPE_ONLY_HISTORY && viewType != VIEW_TYPE_ONLY_UPDATES) it.manga.id else it.chapter.id
|
||||||
}.filter { mch ->
|
}.filter { mch ->
|
||||||
if (updatePageCount && page > 0 && query.isEmpty()) {
|
if (updatePageCount && !isOnFirstPage && query.isEmpty()) {
|
||||||
if (viewType != VIEW_TYPE_ONLY_HISTORY) {
|
if (viewType != VIEW_TYPE_ONLY_HISTORY && viewType != VIEW_TYPE_ONLY_UPDATES) {
|
||||||
recentItems.none { mch.manga.id == it.mch.manga.id }
|
recentItems.none { mch.manga.id == it.mch.manga.id }
|
||||||
} else {
|
} else {
|
||||||
recentItems.none { mch.chapter.id == it.mch.chapter.id }
|
recentItems.none { mch.chapter.id == it.mch.chapter.id }
|
||||||
@ -209,9 +232,11 @@ class RecentsPresenter(
|
|||||||
else null
|
else null
|
||||||
else Pair(it, chapter)
|
else Pair(it, chapter)
|
||||||
}
|
}
|
||||||
|
// Timber.d("setting new items")
|
||||||
val newItems = if (query.isEmpty() && !isUngrouped) {
|
val newItems = if (query.isEmpty() && !isUngrouped) {
|
||||||
val nChaptersItems =
|
val nChaptersItems =
|
||||||
pairs.asSequence().filter { it.first.history.id == null && it.first.chapter.id != null }
|
pairs.asSequence()
|
||||||
|
.filter { it.first.history.id == null && it.first.chapter.id != null }
|
||||||
.sortedWith { f1, f2 ->
|
.sortedWith { f1, f2 ->
|
||||||
if (abs(f1.second.date_fetch - f2.second.date_fetch) <=
|
if (abs(f1.second.date_fetch - f2.second.date_fetch) <=
|
||||||
TimeUnit.HOURS.toMillis(12)
|
TimeUnit.HOURS.toMillis(12)
|
||||||
@ -249,8 +274,8 @@ class RecentsPresenter(
|
|||||||
}.flatten()
|
}.flatten()
|
||||||
} else {
|
} else {
|
||||||
if (viewType == VIEW_TYPE_ONLY_UPDATES) {
|
if (viewType == VIEW_TYPE_ONLY_UPDATES) {
|
||||||
val map = TreeMap<Date, MutableList<Pair<MangaChapterHistory, Chapter>>> {
|
val map =
|
||||||
d1, d2 ->
|
TreeMap<Date, MutableList<Pair<MangaChapterHistory, Chapter>>> { d1, d2 ->
|
||||||
d2
|
d2
|
||||||
.compareTo(d1)
|
.compareTo(d1)
|
||||||
}
|
}
|
||||||
@ -264,24 +289,41 @@ class RecentsPresenter(
|
|||||||
}
|
}
|
||||||
} else pairs.map { RecentMangaItem(it.first, it.second, null) }
|
} else pairs.map { RecentMangaItem(it.first, it.second, null) }
|
||||||
}
|
}
|
||||||
recentItems = if (page == 0 || !updatePageCount) {
|
// Timber.d("setting some items")
|
||||||
|
if (customViewType == null) {
|
||||||
|
recentItems = if (isOnFirstPage || !updatePageCount) {
|
||||||
newItems
|
newItems
|
||||||
} else {
|
} else {
|
||||||
recentItems + newItems
|
recentItems + newItems
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
heldItems[customViewType] = newItems
|
||||||
|
}
|
||||||
val newCount = itemCount + newItems.size
|
val newCount = itemCount + newItems.size
|
||||||
val hasNewItems = newItems.isNotEmpty()
|
val hasNewItems = newItems.isNotEmpty()
|
||||||
if (updatePageCount && newCount < 25 && viewType != VIEW_TYPE_GROUP_ALL && query.isEmpty() && !limit) {
|
if (updatePageCount && newCount < 25 && viewType != VIEW_TYPE_GROUP_ALL && query.isEmpty() && !limit) {
|
||||||
page++
|
// Timber.d("needs to retry. has New items: $hasNewItems, offset: $subUpdatesOffset")
|
||||||
runRecents(oldQuery, true, retryCount + (if (hasNewItems) 0 else 1), newCount)
|
runRecents(oldQuery, true, retryCount + (if (hasNewItems) 0 else 1), newCount)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!limit) {
|
if (!limit) {
|
||||||
setDownloadedChapters(recentItems)
|
setDownloadedChapters(recentItems)
|
||||||
|
if (customViewType == null) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
controller?.showLists(recentItems, hasNewItems, shouldMoveToTop)
|
controller?.showLists(recentItems, hasNewItems, shouldMoveToTop)
|
||||||
|
isLoading = false
|
||||||
shouldMoveToTop = false
|
shouldMoveToTop = false
|
||||||
}
|
}
|
||||||
|
// scope.launchIO {
|
||||||
|
// (0..3).map {
|
||||||
|
// async {
|
||||||
|
// if (this@RecentsPresenter.viewType != it) {
|
||||||
|
// runRecents(oldQuery, customViewType = it)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }.awaitAll()
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +354,7 @@ class RecentsPresenter(
|
|||||||
preferences.recentsViewType().set(pref)
|
preferences.recentsViewType().set(pref)
|
||||||
}
|
}
|
||||||
viewType = pref
|
viewType = pref
|
||||||
page = 0
|
resetOffsets()
|
||||||
getRecents()
|
getRecents()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,8 +494,11 @@ class RecentsPresenter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun requestNext() {
|
fun requestNext() {
|
||||||
|
if (!isLoading) {
|
||||||
|
isLoading = true
|
||||||
getRecents(true)
|
getRecents(true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var lastRecents: List<RecentMangaItem>? = null
|
private var lastRecents: List<RecentMangaItem>? = null
|
||||||
@ -462,6 +507,7 @@ class RecentsPresenter(
|
|||||||
const val VIEW_TYPE_UNGROUP_ALL = 1
|
const val VIEW_TYPE_UNGROUP_ALL = 1
|
||||||
const val VIEW_TYPE_ONLY_HISTORY = 2
|
const val VIEW_TYPE_ONLY_HISTORY = 2
|
||||||
const val VIEW_TYPE_ONLY_UPDATES = 3
|
const val VIEW_TYPE_ONLY_UPDATES = 3
|
||||||
|
var ENDLESS_LIMIT = 50
|
||||||
|
|
||||||
suspend fun getRecentManga(): List<Pair<Manga, Long>> {
|
suspend fun getRecentManga(): List<Pair<Manga, Long>> {
|
||||||
val presenter = RecentsPresenter(null)
|
val presenter = RecentsPresenter(null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user