refactor(reader): Use SQLDelight to load chapter url

This commit is contained in:
Ahmad Ansori Palembani 2024-08-16 19:59:27 +07:00
parent a6ef46a90f
commit ce94bd2ad6
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
6 changed files with 34 additions and 11 deletions

View file

@ -67,8 +67,6 @@ interface ChapterQueries : DbProvider {
)
.prepare()
fun insertChapter(chapter: Chapter) = db.put().`object`(chapter).prepare()
fun insertChapters(chapters: List<Chapter>) = db.put().objects(chapters).prepare()
fun updateKnownChaptersBackup(chapters: List<Chapter>) = db.put()

View file

@ -48,12 +48,13 @@ import eu.kanade.tachiyomi.util.isLocal
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.e
import eu.kanade.tachiyomi.util.system.executeOnIO
import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.launchNonCancellableIO
import eu.kanade.tachiyomi.util.system.localeContext
import eu.kanade.tachiyomi.util.system.withIOContext
import eu.kanade.tachiyomi.util.system.withUIContext
import java.util.Date
import java.util.concurrent.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -76,14 +77,15 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.chapter.interactor.InsertChapter
import yokai.domain.download.DownloadPreferences
import yokai.domain.manga.interactor.GetManga
import yokai.domain.manga.interactor.InsertManga
import yokai.domain.manga.interactor.UpdateManga
import yokai.domain.manga.models.MangaUpdate
import yokai.domain.storage.StorageManager
import yokai.i18n.MR
import yokai.util.lang.getString
import java.util.*
import java.util.concurrent.*
/**
* Presenter used by the activity to perform background operations.
@ -100,6 +102,9 @@ class ReaderViewModel(
private val downloadPreferences: DownloadPreferences = Injekt.get(),
) : ViewModel() {
private val getChapter: GetChapter by injectLazy()
private val insertChapter: InsertChapter by injectLazy()
private val getManga: GetManga by injectLazy()
private val insertManga: InsertManga by injectLazy()
private val updateManga: UpdateManga by injectLazy()
private val mutableState = MutableStateFlow(State())
@ -310,8 +315,8 @@ class ReaderViewModel(
context.getString(MR.strings.source_not_installed),
)
if (chapterUrl != null) {
val dbChapter = db.getChapters(chapterUrl).executeOnIO().find {
val source = db.getManga(it.manga_id!!).executeOnIO()?.source ?: return@find false
val dbChapter = getChapter.awaitAllByUrl(chapterUrl, false).find {
val source = getManga.awaitById(it.manga_id!!)?.source ?: return@find false
if (source == sourceId) {
true
} else {
@ -327,11 +332,11 @@ class ReaderViewModel(
val info = delegatedSource.fetchMangaFromChapterUrl(url)
if (info != null) {
val (chapter, manga, chapters) = info
val id = db.insertManga(manga).executeOnIO().insertedId()
val id = insertManga.await(manga)
manga.id = id ?: manga.id
chapter.manga_id = manga.id
val matchingChapterId =
db.getChapters(manga).executeOnIO().find { it.url == chapter.url }?.id
getChapter.awaitAll(manga.id!!, false).find { it.url == chapter.url }?.id
if (matchingChapterId != null) {
withContext(Dispatchers.Main) {
this@ReaderViewModel.init(manga.id!!, matchingChapterId)
@ -348,7 +353,7 @@ class ReaderViewModel(
?: error(context.getString(MR.strings.chapter_not_found))
} else {
chapter.date_fetch = Date().time
chapterId = db.insertChapter(chapter).executeOnIO().insertedId() ?: error(
chapterId = insertChapter.await(chapter) ?: error(
context.getString(MR.strings.unknown_error),
)
}

View file

@ -16,6 +16,9 @@ class ChapterRepositoryImpl(private val handler: DatabaseHandler) : ChapterRepos
override fun getChaptersAsFlow(mangaId: Long, filterScanlators: Boolean): Flow<List<Chapter>> =
handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, filterScanlators.toInt().toLong(), Chapter::mapper) }
override suspend fun getChaptersByUrl(url: String, filterScanlators: Boolean): List<Chapter> =
handler.awaitList { chaptersQueries.getChaptersByUrl(url, filterScanlators.toInt().toLong(), Chapter::mapper) }
override suspend fun getRecents(filterScanlators: Boolean, search: String, limit: Long, offset: Long): List<MangaChapter> =
handler.awaitList { chaptersQueries.getRecents(search, filterScanlators.toInt().toLong(), limit, offset, MangaChapter::mapper) }

View file

@ -9,6 +9,8 @@ interface ChapterRepository {
suspend fun getChapters(mangaId: Long, filterScanlators: Boolean): List<Chapter>
fun getChaptersAsFlow(mangaId: Long, filterScanlators: Boolean): Flow<List<Chapter>>
suspend fun getChaptersByUrl(url: String, filterScanlators: Boolean): List<Chapter>
suspend fun getRecents(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapter>
suspend fun getScanlatorsByChapter(mangaId: Long): List<String>

View file

@ -6,9 +6,13 @@ import yokai.domain.chapter.ChapterRepository
class GetChapter(
private val chapterRepository: ChapterRepository,
) {
suspend fun awaitAll(mangaId: Long, filterScanlators: Boolean) = chapterRepository.getChapters(mangaId, filterScanlators)
suspend fun awaitAll(mangaId: Long, filterScanlators: Boolean) =
chapterRepository.getChapters(mangaId, filterScanlators)
suspend fun awaitAll(manga: Manga, filterScanlators: Boolean? = null) =
awaitAll(manga.id!!, filterScanlators ?: (manga.filtered_scanlators?.isNotEmpty() == true))
suspend fun awaitAllByUrl(chapterUrl: String, filterScanlators: Boolean) =
chapterRepository.getChaptersByUrl(chapterUrl, filterScanlators)
fun subscribeAll(mangaId: Long, filterScanlators: Boolean) = chapterRepository.getChaptersAsFlow(mangaId, filterScanlators)
}

View file

@ -32,6 +32,17 @@ AND (
:apply_filter = 0 OR S.name IS NULL
);
getChaptersByUrl:
SELECT C.*
FROM chapters AS C
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 C.url = :url
AND (
:apply_filter = 0 OR S.name IS NULL
);
getRecents:
SELECT
M.*,