mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
refactor(recents): Fully migrate recents to use SQLDelight
This commit is contained in:
parent
79929b395e
commit
354ed7ce8a
10 changed files with 354 additions and 86 deletions
|
@ -39,16 +39,18 @@ interface History : Serializable {
|
||||||
this.chapter_id = chapter.id!!
|
this.chapter_id = chapter.id!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun create(): History = HistoryImpl()
|
||||||
|
|
||||||
fun mapper(
|
fun mapper(
|
||||||
id: Long,
|
id: Long,
|
||||||
chapterId: Long,
|
chapterId: Long,
|
||||||
lastRead: Long,
|
lastRead: Long?,
|
||||||
timeRead: Long
|
timeRead: Long?,
|
||||||
) = HistoryImpl().apply {
|
): History = HistoryImpl().apply {
|
||||||
this.id = id
|
this.id = id
|
||||||
this.chapter_id = chapterId
|
this.chapter_id = chapterId
|
||||||
this.last_read = lastRead
|
this.last_read = lastRead ?: 0L
|
||||||
this.time_read = timeRead
|
this.time_read = timeRead ?: 0L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,100 @@ data class MangaChapterHistory(val manga: Manga, val chapter: Chapter, val histo
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createBlank() = MangaChapterHistory(MangaImpl(), ChapterImpl(), HistoryImpl())
|
fun createBlank() = MangaChapterHistory(MangaImpl(), ChapterImpl(), HistoryImpl())
|
||||||
|
|
||||||
|
fun mapper(
|
||||||
|
// manga
|
||||||
|
mangaId: Long,
|
||||||
|
source: Long,
|
||||||
|
mangaUrl: String,
|
||||||
|
artist: String?,
|
||||||
|
author: String?,
|
||||||
|
description: String?,
|
||||||
|
genre: String?,
|
||||||
|
title: String,
|
||||||
|
status: Long,
|
||||||
|
thumbnailUrl: String?,
|
||||||
|
favorite: Boolean,
|
||||||
|
lastUpdate: Long?,
|
||||||
|
initialized: Boolean,
|
||||||
|
viewer: Long,
|
||||||
|
hideTitle: Boolean,
|
||||||
|
chapterFlags: Long,
|
||||||
|
dateAdded: Long?,
|
||||||
|
filteredScanlators: String?,
|
||||||
|
updateStrategy: Long,
|
||||||
|
coverLastModified: Long,
|
||||||
|
// chapter
|
||||||
|
chapterId: Long?,
|
||||||
|
_mangaId: Long?,
|
||||||
|
chapterUrl: String?,
|
||||||
|
name: String?,
|
||||||
|
scanlator: String?,
|
||||||
|
read: Boolean?,
|
||||||
|
bookmark: Boolean?,
|
||||||
|
lastPageRead: Long?,
|
||||||
|
pagesLeft: Long?,
|
||||||
|
chapterNumber: Double?,
|
||||||
|
sourceOrder: Long?,
|
||||||
|
dateFetch: Long?,
|
||||||
|
dateUpload: Long?,
|
||||||
|
// history
|
||||||
|
historyId: Long?,
|
||||||
|
historyChapterId: Long?,
|
||||||
|
historyLastRead: Long?,
|
||||||
|
historyTimeRead: Long?,
|
||||||
|
) = MangaChapterHistory(
|
||||||
|
Manga.mapper(
|
||||||
|
id = mangaId,
|
||||||
|
source = source,
|
||||||
|
url = mangaUrl,
|
||||||
|
artist = artist,
|
||||||
|
author = author,
|
||||||
|
description = description,
|
||||||
|
genre = genre,
|
||||||
|
title = title,
|
||||||
|
status = status,
|
||||||
|
thumbnailUrl = thumbnailUrl,
|
||||||
|
favorite = favorite,
|
||||||
|
lastUpdate = lastUpdate,
|
||||||
|
initialized = initialized,
|
||||||
|
viewerFlags = viewer,
|
||||||
|
hideTitle = hideTitle,
|
||||||
|
chapterFlags = chapterFlags,
|
||||||
|
dateAdded = dateAdded,
|
||||||
|
filteredScanlators = filteredScanlators,
|
||||||
|
updateStrategy = updateStrategy,
|
||||||
|
coverLastModified = coverLastModified,
|
||||||
|
),
|
||||||
|
chapterId?.let {
|
||||||
|
Chapter.mapper(
|
||||||
|
id = chapterId,
|
||||||
|
mangaId = _mangaId!!,
|
||||||
|
url = chapterUrl!!,
|
||||||
|
name = name!!,
|
||||||
|
scanlator = scanlator!!,
|
||||||
|
read = read!!,
|
||||||
|
bookmark = bookmark!!,
|
||||||
|
lastPageRead = lastPageRead!!,
|
||||||
|
pagesLeft = pagesLeft!!,
|
||||||
|
chapterNumber = chapterNumber!!,
|
||||||
|
sourceOrder = sourceOrder!!,
|
||||||
|
dateFetch = dateFetch!!,
|
||||||
|
dateUpload = dateUpload!!,
|
||||||
|
)
|
||||||
|
} ?: Chapter.create(),
|
||||||
|
historyId?.let {
|
||||||
|
History.mapper(
|
||||||
|
id = historyId,
|
||||||
|
chapterId = historyChapterId!!,
|
||||||
|
lastRead = historyLastRead,
|
||||||
|
timeRead = historyTimeRead,
|
||||||
|
)
|
||||||
|
} ?: History.create().apply {
|
||||||
|
historyLastRead?.let { last_read = it }
|
||||||
|
historyTimeRead?.let { time_read = it }
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,22 +52,6 @@ interface HistoryQueries : DbProvider {
|
||||||
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns history of recent manga containing last read chapter in 25s
|
|
||||||
* @param date recent date range
|
|
||||||
* @offset offset the db by
|
|
||||||
*/
|
|
||||||
fun getRecentMangaLimit(search: String = "", offset: Int, isResuming: Boolean) = db.get()
|
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
|
||||||
.withQuery(
|
|
||||||
RawQuery.builder()
|
|
||||||
.query(getRecentMangasLimitQuery(search.sqLite, offset, isResuming))
|
|
||||||
.observesTables(HistoryTable.TABLE)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
|
||||||
.prepare()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns history of manga read during period
|
* Returns history of manga read during period
|
||||||
* @param startDate start date of the period
|
* @param startDate start date of the period
|
||||||
|
@ -85,37 +69,6 @@ interface HistoryQueries : DbProvider {
|
||||||
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns history of recent manga containing last read chapter in 25s
|
|
||||||
* @param date recent date range
|
|
||||||
* @offset offset the db by
|
|
||||||
*/
|
|
||||||
fun getAllRecentsTypes(
|
|
||||||
search: String = "",
|
|
||||||
includeRead: Boolean,
|
|
||||||
endless: Boolean,
|
|
||||||
offset: Int,
|
|
||||||
isResuming: Boolean,
|
|
||||||
) = db.get()
|
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
|
||||||
.withQuery(
|
|
||||||
RawQuery.builder()
|
|
||||||
.query(
|
|
||||||
getAllRecentsType(
|
|
||||||
search.sqLite,
|
|
||||||
includeRead,
|
|
||||||
endless,
|
|
||||||
offset,
|
|
||||||
isResuming,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
// .args(date.time, startDate.time)
|
|
||||||
.observesTables(HistoryTable.TABLE)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
|
|
||||||
.prepare()
|
|
||||||
|
|
||||||
fun getHistoryByMangaId(mangaId: Long) = db.get()
|
fun getHistoryByMangaId(mangaId: Long) = db.get()
|
||||||
.listOfObjects(History::class.java)
|
.listOfObjects(History::class.java)
|
||||||
.withQuery(
|
.withQuery(
|
||||||
|
|
|
@ -17,7 +17,6 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter
|
||||||
import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
||||||
import eu.kanade.tachiyomi.util.chapter.ChapterSort
|
import eu.kanade.tachiyomi.util.chapter.ChapterSort
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
|
||||||
import eu.kanade.tachiyomi.util.system.launchIO
|
import eu.kanade.tachiyomi.util.system.launchIO
|
||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
@ -41,9 +40,9 @@ import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import yokai.domain.chapter.interactor.GetChapter
|
import yokai.domain.chapter.interactor.GetChapter
|
||||||
import yokai.domain.chapter.interactor.RecentChapter
|
|
||||||
import yokai.domain.chapter.interactor.UpdateChapter
|
import yokai.domain.chapter.interactor.UpdateChapter
|
||||||
import yokai.domain.recents.RecentsPreferences
|
import yokai.domain.recents.RecentsPreferences
|
||||||
|
import yokai.domain.recents.interactor.GetRecents
|
||||||
import yokai.domain.ui.UiPreferences
|
import yokai.domain.ui.UiPreferences
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ class RecentsPresenter(
|
||||||
private val chapterFilter: ChapterFilter = Injekt.get(),
|
private val chapterFilter: ChapterFilter = Injekt.get(),
|
||||||
) : BaseCoroutinePresenter<RecentsController>(), DownloadQueue.DownloadListener {
|
) : BaseCoroutinePresenter<RecentsController>(), DownloadQueue.DownloadListener {
|
||||||
private val getChapter: GetChapter by injectLazy()
|
private val getChapter: GetChapter by injectLazy()
|
||||||
private val recentChapter: RecentChapter by injectLazy()
|
private val getRecents: GetRecents by injectLazy()
|
||||||
private val updateChapter: UpdateChapter by injectLazy()
|
private val updateChapter: UpdateChapter by injectLazy()
|
||||||
|
|
||||||
private var recentsJob: Job? = null
|
private var recentsJob: Job? = null
|
||||||
|
@ -172,26 +171,29 @@ class RecentsPresenter(
|
||||||
var extraCount = 0
|
var extraCount = 0
|
||||||
val cReading: List<MangaChapterHistory> = when (viewType) {
|
val cReading: List<MangaChapterHistory> = when (viewType) {
|
||||||
RecentsViewType.GroupedAll, RecentsViewType.UngroupedAll -> {
|
RecentsViewType.GroupedAll, RecentsViewType.UngroupedAll -> {
|
||||||
db.getAllRecentsTypes(
|
getRecents.awaitAll(
|
||||||
query,
|
|
||||||
showRead,
|
showRead,
|
||||||
|
true,
|
||||||
isEndless,
|
isEndless,
|
||||||
if (isCustom) ENDLESS_LIMIT else pageOffset,
|
|
||||||
!updatePageCount && !isOnFirstPage,
|
!updatePageCount && !isOnFirstPage,
|
||||||
).executeOnIO()
|
query,
|
||||||
|
(if (isCustom) ENDLESS_LIMIT else pageOffset).toLong(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
RecentsViewType.History -> {
|
RecentsViewType.History -> {
|
||||||
val items = if (groupChaptersHistory == GroupType.BySeries) {
|
val items = if (groupChaptersHistory == GroupType.BySeries) {
|
||||||
db.getRecentMangaLimit(
|
getRecents.awaitBySeries(
|
||||||
query,
|
true,
|
||||||
if (isCustom) ENDLESS_LIMIT else pageOffset,
|
|
||||||
!updatePageCount && !isOnFirstPage,
|
!updatePageCount && !isOnFirstPage,
|
||||||
|
query,
|
||||||
|
(if (isCustom) ENDLESS_LIMIT else pageOffset).toLong(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
db.getHistoryUngrouped(
|
getRecents.awaitUngrouped(
|
||||||
query,
|
true,
|
||||||
if (isCustom) ENDLESS_LIMIT else pageOffset,
|
|
||||||
!updatePageCount && !isOnFirstPage,
|
!updatePageCount && !isOnFirstPage,
|
||||||
|
query,
|
||||||
|
(if (isCustom) ENDLESS_LIMIT else pageOffset).toLong(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (groupChaptersHistory.isByTime) {
|
if (groupChaptersHistory.isByTime) {
|
||||||
|
@ -203,7 +205,7 @@ class RecentsPresenter(
|
||||||
)
|
)
|
||||||
val dayOfWeek = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) % 7 + 1
|
val dayOfWeek = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) % 7 + 1
|
||||||
dateFormat.calendar.firstDayOfWeek = dayOfWeek
|
dateFormat.calendar.firstDayOfWeek = dayOfWeek
|
||||||
items.executeOnIO().groupBy {
|
items.groupBy {
|
||||||
val date = it.history.last_read
|
val date = it.history.last_read
|
||||||
it.manga.id to if (date <= 0L) "-1" else dateFormat.format(Date(date))
|
it.manga.id to if (date <= 0L) "-1" else dateFormat.format(Date(date))
|
||||||
}
|
}
|
||||||
|
@ -235,14 +237,14 @@ class RecentsPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
items.executeOnIO()
|
items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecentsViewType.Updates -> {
|
RecentsViewType.Updates -> {
|
||||||
dateFormat.applyPattern("yyyy-MM-dd")
|
dateFormat.applyPattern("yyyy-MM-dd")
|
||||||
dateFormat.calendar.firstDayOfWeek =
|
dateFormat.calendar.firstDayOfWeek =
|
||||||
Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
|
Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
|
||||||
recentChapter.await(
|
getRecents.awaitUpdates(
|
||||||
true,
|
true,
|
||||||
!updatePageCount && !isOnFirstPage,
|
!updatePageCount && !isOnFirstPage,
|
||||||
query,
|
query,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import uy.kohesive.injekt.api.get
|
||||||
import yokai.data.category.CategoryRepositoryImpl
|
import yokai.data.category.CategoryRepositoryImpl
|
||||||
import yokai.data.chapter.ChapterRepositoryImpl
|
import yokai.data.chapter.ChapterRepositoryImpl
|
||||||
import yokai.data.extension.repo.ExtensionRepoRepositoryImpl
|
import yokai.data.extension.repo.ExtensionRepoRepositoryImpl
|
||||||
|
import yokai.data.history.HistoryRepositoryImpl
|
||||||
import yokai.data.library.custom.CustomMangaRepositoryImpl
|
import yokai.data.library.custom.CustomMangaRepositoryImpl
|
||||||
import yokai.data.manga.MangaRepositoryImpl
|
import yokai.data.manga.MangaRepositoryImpl
|
||||||
import yokai.domain.category.CategoryRepository
|
import yokai.domain.category.CategoryRepository
|
||||||
|
@ -17,7 +18,7 @@ import yokai.domain.chapter.interactor.DeleteChapter
|
||||||
import yokai.domain.chapter.interactor.GetAvailableScanlators
|
import yokai.domain.chapter.interactor.GetAvailableScanlators
|
||||||
import yokai.domain.chapter.interactor.GetChapter
|
import yokai.domain.chapter.interactor.GetChapter
|
||||||
import yokai.domain.chapter.interactor.InsertChapter
|
import yokai.domain.chapter.interactor.InsertChapter
|
||||||
import yokai.domain.chapter.interactor.RecentChapter
|
import yokai.domain.recents.interactor.GetRecents
|
||||||
import yokai.domain.chapter.interactor.UpdateChapter
|
import yokai.domain.chapter.interactor.UpdateChapter
|
||||||
import yokai.domain.extension.interactor.TrustExtension
|
import yokai.domain.extension.interactor.TrustExtension
|
||||||
import yokai.domain.extension.repo.ExtensionRepoRepository
|
import yokai.domain.extension.repo.ExtensionRepoRepository
|
||||||
|
@ -27,6 +28,7 @@ import yokai.domain.extension.repo.interactor.GetExtensionRepo
|
||||||
import yokai.domain.extension.repo.interactor.GetExtensionRepoCount
|
import yokai.domain.extension.repo.interactor.GetExtensionRepoCount
|
||||||
import yokai.domain.extension.repo.interactor.ReplaceExtensionRepo
|
import yokai.domain.extension.repo.interactor.ReplaceExtensionRepo
|
||||||
import yokai.domain.extension.repo.interactor.UpdateExtensionRepo
|
import yokai.domain.extension.repo.interactor.UpdateExtensionRepo
|
||||||
|
import yokai.domain.history.HistoryRepository
|
||||||
import yokai.domain.library.custom.CustomMangaRepository
|
import yokai.domain.library.custom.CustomMangaRepository
|
||||||
import yokai.domain.library.custom.interactor.CreateCustomManga
|
import yokai.domain.library.custom.interactor.CreateCustomManga
|
||||||
import yokai.domain.library.custom.interactor.DeleteCustomManga
|
import yokai.domain.library.custom.interactor.DeleteCustomManga
|
||||||
|
@ -67,9 +69,12 @@ class DomainModule : InjektModule {
|
||||||
addFactory { GetAvailableScanlators(get()) }
|
addFactory { GetAvailableScanlators(get()) }
|
||||||
addFactory { GetChapter(get()) }
|
addFactory { GetChapter(get()) }
|
||||||
addFactory { InsertChapter(get()) }
|
addFactory { InsertChapter(get()) }
|
||||||
addFactory { RecentChapter(get()) }
|
|
||||||
addFactory { UpdateChapter(get()) }
|
addFactory { UpdateChapter(get()) }
|
||||||
|
|
||||||
|
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
|
||||||
|
|
||||||
|
addFactory { GetRecents(get(), get()) }
|
||||||
|
|
||||||
addSingletonFactory<CategoryRepository> { CategoryRepositoryImpl(get()) }
|
addSingletonFactory<CategoryRepository> { CategoryRepositoryImpl(get()) }
|
||||||
addFactory { GetCategories(get()) }
|
addFactory { GetCategories(get()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package yokai.data.history
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
||||||
|
import eu.kanade.tachiyomi.util.system.toInt
|
||||||
|
import yokai.data.DatabaseHandler
|
||||||
|
import yokai.domain.history.HistoryRepository
|
||||||
|
|
||||||
|
class HistoryRepositoryImpl(private val handler: DatabaseHandler) : HistoryRepository {
|
||||||
|
override suspend fun getRecentsUngrouped(
|
||||||
|
filterScanlators: Boolean,
|
||||||
|
search: String,
|
||||||
|
limit: Long,
|
||||||
|
offset: Long,
|
||||||
|
): List<MangaChapterHistory> =
|
||||||
|
handler.awaitList { historyQueries.getRecentsUngrouped(search, filterScanlators.toInt().toLong(), limit, offset, MangaChapterHistory::mapper) }
|
||||||
|
|
||||||
|
override suspend fun getRecentsBySeries(
|
||||||
|
filterScanlators: Boolean,
|
||||||
|
search: String,
|
||||||
|
limit: Long,
|
||||||
|
offset: Long,
|
||||||
|
): List<MangaChapterHistory> =
|
||||||
|
handler.awaitList { historyQueries.getRecentsBySeries(search, filterScanlators.toInt().toLong(), limit, offset, MangaChapterHistory::mapper) }
|
||||||
|
|
||||||
|
override suspend fun getRecentsAll(
|
||||||
|
includeRead: Boolean,
|
||||||
|
filterScanlators: Boolean,
|
||||||
|
search: String,
|
||||||
|
limit: Long,
|
||||||
|
offset: Long
|
||||||
|
): List<MangaChapterHistory> =
|
||||||
|
handler.awaitList { historyQueries.getRecentsAll(includeRead.toInt().toLong(), search, filterScanlators.toInt().toLong(), limit, offset, MangaChapterHistory::mapper) }
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
package yokai.domain.chapter.interactor
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaChapter
|
|
||||||
import yokai.domain.chapter.ChapterRepository
|
|
||||||
import yokai.util.limitAndOffset
|
|
||||||
|
|
||||||
class RecentChapter(
|
|
||||||
private val chapterRepository: ChapterRepository,
|
|
||||||
) {
|
|
||||||
suspend fun await(filterScanlators: Boolean, isResuming: Boolean, search: String = "", offset: Long = 0L): List<MangaChapter> {
|
|
||||||
val (limit, actualOffset) = limitAndOffset(true, isResuming, offset)
|
|
||||||
|
|
||||||
return chapterRepository.getRecents(filterScanlators, search, limit, actualOffset)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package yokai.domain.history
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
||||||
|
|
||||||
|
interface HistoryRepository {
|
||||||
|
suspend fun getRecentsUngrouped(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapterHistory>
|
||||||
|
suspend fun getRecentsBySeries(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapterHistory>
|
||||||
|
suspend fun getRecentsAll(includeRead: Boolean, filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapterHistory>
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package yokai.domain.recents.interactor
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapter
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
||||||
|
import yokai.domain.chapter.ChapterRepository
|
||||||
|
import yokai.domain.history.HistoryRepository
|
||||||
|
import yokai.util.limitAndOffset
|
||||||
|
|
||||||
|
class GetRecents(
|
||||||
|
private val chapterRepository: ChapterRepository,
|
||||||
|
private val historyRepository: HistoryRepository,
|
||||||
|
) {
|
||||||
|
suspend fun awaitUpdates(
|
||||||
|
filterScanlators: Boolean,
|
||||||
|
isResuming: Boolean,
|
||||||
|
search: String = "",
|
||||||
|
offset: Long = 0L,
|
||||||
|
): List<MangaChapter> {
|
||||||
|
val (limit, actualOffset) = limitAndOffset(true, isResuming, offset)
|
||||||
|
|
||||||
|
return chapterRepository.getRecents(filterScanlators, search, limit, actualOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun awaitUngrouped(
|
||||||
|
filterScanlators: Boolean,
|
||||||
|
isResuming: Boolean,
|
||||||
|
search: String = "",
|
||||||
|
offset: Long = 0L,
|
||||||
|
): List<MangaChapterHistory> {
|
||||||
|
val (limit, actualOffset) = limitAndOffset(true, isResuming, offset)
|
||||||
|
|
||||||
|
return historyRepository.getRecentsUngrouped(filterScanlators, search, limit, actualOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun awaitBySeries(
|
||||||
|
filterScanlators: Boolean,
|
||||||
|
isResuming: Boolean,
|
||||||
|
search: String = "",
|
||||||
|
offset: Long = 0L,
|
||||||
|
): List<MangaChapterHistory> {
|
||||||
|
val (limit, actualOffset) = limitAndOffset(true, isResuming, offset)
|
||||||
|
|
||||||
|
return historyRepository.getRecentsBySeries(filterScanlators, search, limit, actualOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun awaitAll(
|
||||||
|
includeRead: Boolean,
|
||||||
|
filterScanlators: Boolean,
|
||||||
|
isEndless: Boolean,
|
||||||
|
isResuming: Boolean,
|
||||||
|
search: String = "",
|
||||||
|
offset: Long = 0L,
|
||||||
|
): List<MangaChapterHistory> {
|
||||||
|
val (limit, actualOffset) = limitAndOffset(isEndless, isResuming, offset)
|
||||||
|
|
||||||
|
return historyRepository.getRecentsAll(includeRead, filterScanlators, search, limit, actualOffset)
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,6 @@ LIMIT :limit OFFSET :offset;
|
||||||
|
|
||||||
getRecentsBySeries:
|
getRecentsBySeries:
|
||||||
SELECT
|
SELECT
|
||||||
M.url AS mangaUrl,
|
|
||||||
M.*,
|
M.*,
|
||||||
C.*,
|
C.*,
|
||||||
H.*
|
H.*
|
||||||
|
@ -62,3 +61,131 @@ AND (
|
||||||
)
|
)
|
||||||
ORDER BY max_last_read.history_last_read DESC
|
ORDER BY max_last_read.history_last_read DESC
|
||||||
LIMIT :limit OFFSET :offset;
|
LIMIT :limit OFFSET :offset;
|
||||||
|
|
||||||
|
getRecentsAll: -- AKA insanity
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
M.*,
|
||||||
|
C.*,
|
||||||
|
H.*
|
||||||
|
FROM (
|
||||||
|
SELECT mangas.*
|
||||||
|
FROM mangas
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT manga_id, COUNT(*) AS unread
|
||||||
|
FROM chapters
|
||||||
|
WHERE read = 0
|
||||||
|
GROUP BY manga_id
|
||||||
|
) AS C
|
||||||
|
ON _id = C.manga_id
|
||||||
|
WHERE (
|
||||||
|
:include_read = 0 OR C.unread > 0
|
||||||
|
)
|
||||||
|
GROUP BY _id
|
||||||
|
ORDER BY title
|
||||||
|
) AS M
|
||||||
|
JOIN chapters AS C
|
||||||
|
ON M._id = C.manga_id
|
||||||
|
JOIN history AS H
|
||||||
|
ON C._id = H.history_chapter_id
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
chapters.manga_id AS manga_id,
|
||||||
|
chapters._id AS history_chapter_id,
|
||||||
|
MAX(history.history_last_read) AS history_last_read
|
||||||
|
FROM chapters JOIN history
|
||||||
|
ON chapters._id = history.history_chapter_id
|
||||||
|
GROUP BY chapters.manga_id
|
||||||
|
) AS max_last_read
|
||||||
|
ON C.manga_id = max_last_read.manga_id
|
||||||
|
AND max_last_read.history_chapter_id = H.history_chapter_id
|
||||||
|
AND max_last_read.history_last_read > 0
|
||||||
|
LEFT JOIN scanlators_view AS S
|
||||||
|
ON C.manga_id = S.manga_id
|
||||||
|
AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '/<INVALID>/') -- I assume if it's N/A it shouldn't be filtered
|
||||||
|
WHERE lower(M.title) LIKE '%' || :search || '%'
|
||||||
|
AND (
|
||||||
|
:apply_filter = 0 OR S.name IS NULL
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
UNION --
|
||||||
|
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
M.*,
|
||||||
|
C.*,
|
||||||
|
NULL AS history_id,
|
||||||
|
NULL AS history_chapter_id,
|
||||||
|
C.date_fetch AS history_last_read,
|
||||||
|
NULL AS history_time_read
|
||||||
|
FROM (
|
||||||
|
SELECT mangas.*
|
||||||
|
FROM mangas
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT manga_id, COUNT(*) AS unread
|
||||||
|
FROM chapters
|
||||||
|
WHERE read = 0
|
||||||
|
GROUP BY manga_id
|
||||||
|
) AS C2
|
||||||
|
ON _id = C2.manga_id
|
||||||
|
WHERE (
|
||||||
|
:include_read = 0 OR C2.unread > 0
|
||||||
|
)
|
||||||
|
GROUP BY _id
|
||||||
|
ORDER BY title
|
||||||
|
) AS M
|
||||||
|
JOIN chapters AS C
|
||||||
|
ON M._id = C.manga_id
|
||||||
|
JOIN history AS H
|
||||||
|
ON C._id = H.history_chapter_id
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
chapters.manga_id,
|
||||||
|
chapters._id AS history_chapter_id,
|
||||||
|
max(chapters.date_upload)
|
||||||
|
FROM chapters JOIN mangas
|
||||||
|
ON mangas._id = chapters.manga_id
|
||||||
|
WHERE chapters.read = 0
|
||||||
|
GROUP BY chapters.manga_id
|
||||||
|
) AS newest_chapter
|
||||||
|
LEFT JOIN scanlators_view AS S
|
||||||
|
ON C.manga_id = S.manga_id
|
||||||
|
AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '/<INVALID>/') -- I assume if it's N/A it shouldn't be filtered
|
||||||
|
WHERE M.favorite = 1
|
||||||
|
AND newest_chapter.history_chapter_id = H.history_chapter_id
|
||||||
|
AND C.date_fetch > M.date_added
|
||||||
|
AND lower(M.title) LIKE '%' || :search || '%'
|
||||||
|
AND (
|
||||||
|
:apply_filter = 0 OR S.name IS NULL
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
UNION --
|
||||||
|
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
M.*,
|
||||||
|
NULL AS _id,
|
||||||
|
NULL AS manga_id,
|
||||||
|
NULL AS url,
|
||||||
|
NULL AS name,
|
||||||
|
NULL AS read,
|
||||||
|
NULL AS scanlator,
|
||||||
|
NULL AS bookmark,
|
||||||
|
NULL AS date_fetch,
|
||||||
|
NULL AS date_upload,
|
||||||
|
NULL AS last_page_read,
|
||||||
|
NULL AS pages_left,
|
||||||
|
NULL AS chapter_number,
|
||||||
|
NULL AS source_order,
|
||||||
|
NULL AS history_id,
|
||||||
|
NULL AS history_chapter_id,
|
||||||
|
M.date_added AS history_last_read,
|
||||||
|
NULL AS history_time_read
|
||||||
|
FROM mangas AS M
|
||||||
|
WHERE M.favorite = 1
|
||||||
|
AND lower(M.title) LIKE '%' || :search || '%'
|
||||||
|
)
|
||||||
|
ORDER BY history_last_read DESC
|
||||||
|
LIMIT :limit OFFSET :offset;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue