More SQLDelight migrations

(cherry picked from commit 21771e62aa0dc7e1393b27ea8eb146de277cebd9)

# Conflicts:
#	app/src/main/java/eu/kanade/domain/manga/model/Manga.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupManga.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt
This commit is contained in:
arkon 2022-07-02 15:19:52 -04:00 committed by Jobobby04
parent 2c87a8fd02
commit 85898df703
21 changed files with 142 additions and 84 deletions

View File

@ -11,6 +11,14 @@ class MangaMergeRepositoryImpl(
private val handler: DatabaseHandler, private val handler: DatabaseHandler,
) : MangaMergeRepository { ) : MangaMergeRepository {
override suspend fun getMergedManga(): List<Manga> {
return handler.awaitList { mergedQueries.selectAllMergedMangas(mangaMapper) }
}
override suspend fun subscribeMergedManga(): Flow<List<Manga>> {
return handler.subscribeToList { mergedQueries.selectAllMergedMangas(mangaMapper) }
}
override suspend fun getMergedMangaById(id: Long): List<Manga> { override suspend fun getMergedMangaById(id: Long): List<Manga> {
return handler.awaitList { mergedQueries.selectMergedMangasById(id, mangaMapper) } return handler.awaitList { mergedQueries.selectMergedMangasById(id, mangaMapper) }
} }

View File

@ -27,6 +27,10 @@ class MangaRepositoryImpl(
return handler.subscribeToOne { mangasQueries.getMangaById(id, mangaMapper) } return handler.subscribeToOne { mangasQueries.getMangaById(id, mangaMapper) }
} }
override suspend fun getFavorites(): List<Manga> {
return handler.awaitList { mangasQueries.getFavorites(mangaMapper) }
}
override fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>> { override fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>> {
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) } return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) }
} }

View File

@ -31,7 +31,7 @@ import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId
import eu.kanade.domain.history.interactor.UpsertHistory import eu.kanade.domain.history.interactor.UpsertHistory
import eu.kanade.domain.history.repository.HistoryRepository import eu.kanade.domain.history.repository.HistoryRepository
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId import eu.kanade.domain.manga.interactor.GetFavorites
import eu.kanade.domain.manga.interactor.GetMangaById import eu.kanade.domain.manga.interactor.GetMangaById
import eu.kanade.domain.manga.interactor.GetMangaWithChapters import eu.kanade.domain.manga.interactor.GetMangaWithChapters
import eu.kanade.domain.manga.interactor.ResetViewerFlags import eu.kanade.domain.manga.interactor.ResetViewerFlags
@ -70,7 +70,7 @@ class DomainModule : InjektModule {
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) } addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
addFactory { GetDuplicateLibraryManga(get()) } addFactory { GetDuplicateLibraryManga(get()) }
addFactory { GetFavoritesBySourceId(get()) } addFactory { GetFavorites(get()) }
addFactory { GetMangaWithChapters(get(), get()) } addFactory { GetMangaWithChapters(get(), get()) }
addFactory { GetMangaById(get()) } addFactory { GetMangaById(get()) }
addFactory { GetNextChapter(get()) } addFactory { GetNextChapter(get()) }

View File

@ -4,6 +4,7 @@ import eu.kanade.data.manga.MangaMergeRepositoryImpl
import eu.kanade.data.manga.MangaMetadataRepositoryImpl import eu.kanade.data.manga.MangaMetadataRepositoryImpl
import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId
import eu.kanade.domain.manga.interactor.GetFlatMetadataById import eu.kanade.domain.manga.interactor.GetFlatMetadataById
import eu.kanade.domain.manga.interactor.GetMergedManga
import eu.kanade.domain.manga.interactor.GetMergedMangaById import eu.kanade.domain.manga.interactor.GetMergedMangaById
import eu.kanade.domain.manga.interactor.GetMergedReferencesById import eu.kanade.domain.manga.interactor.GetMergedReferencesById
import eu.kanade.domain.manga.interactor.SetMangaFilteredScanlators import eu.kanade.domain.manga.interactor.SetMangaFilteredScanlators
@ -34,6 +35,7 @@ class SYDomainModule : InjektModule {
addFactory { GetFlatMetadataById(get()) } addFactory { GetFlatMetadataById(get()) }
addSingletonFactory<MangaMergeRepository> { MangaMergeRepositoryImpl(get()) } addSingletonFactory<MangaMergeRepository> { MangaMergeRepositoryImpl(get()) }
addFactory { GetMergedManga(get()) }
addFactory { GetMergedMangaById(get()) } addFactory { GetMergedMangaById(get()) }
addFactory { GetMergedReferencesById(get()) } addFactory { GetMergedReferencesById(get()) }
addFactory { GetMergedChapterByMangaId(get()) } addFactory { GetMergedChapterByMangaId(get()) }

View File

@ -4,10 +4,14 @@ import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.repository.MangaRepository import eu.kanade.domain.manga.repository.MangaRepository
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
class GetFavoritesBySourceId( class GetFavorites(
private val mangaRepository: MangaRepository, private val mangaRepository: MangaRepository,
) { ) {
suspend fun await(): List<Manga> {
return mangaRepository.getFavorites()
}
fun subscribe(sourceId: Long): Flow<List<Manga>> { fun subscribe(sourceId: Long): Flow<List<Manga>> {
return mangaRepository.getFavoritesBySourceId(sourceId) return mangaRepository.getFavoritesBySourceId(sourceId)
} }

View File

@ -0,0 +1,25 @@
package eu.kanade.domain.manga.interactor
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.repository.MangaMergeRepository
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
class GetMergedManga(
private val mangaMergeRepository: MangaMergeRepository,
) {
suspend fun await(): List<Manga> {
return try {
mangaMergeRepository.getMergedManga()
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
emptyList()
}
}
suspend fun subscribe(): Flow<List<Manga>> {
return mangaMergeRepository.subscribeMergedManga()
}
}

View File

@ -62,9 +62,6 @@ data class Manga(
get() = customMangaInfo?.statusLong ?: ogStatus get() = customMangaInfo?.statusLong ?: ogStatus
// SY <-- // SY <--
val sorting: Long
get() = chapterFlags and CHAPTER_SORTING_MASK
fun toSManga(): SManga { fun toSManga(): SManga {
return SManga.create().also { return SManga.create().also {
it.url = url it.url = url
@ -79,6 +76,9 @@ data class Manga(
} }
} }
val sorting: Long
get() = chapterFlags and CHAPTER_SORTING_MASK
val displayMode: Long val displayMode: Long
get() = chapterFlags and CHAPTER_DISPLAY_MASK get() = chapterFlags and CHAPTER_DISPLAY_MASK

View File

@ -5,6 +5,10 @@ import exh.merged.sql.models.MergedMangaReference
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface MangaMergeRepository { interface MangaMergeRepository {
suspend fun getMergedManga(): List<Manga>
suspend fun subscribeMergedManga(): Flow<List<Manga>>
suspend fun getMergedMangaById(id: Long): List<Manga> suspend fun getMergedMangaById(id: Long): List<Manga>
suspend fun subscribeMergedMangaById(id: Long): Flow<List<Manga>> suspend fun subscribeMergedMangaById(id: Long): Flow<List<Manga>>

View File

@ -12,6 +12,8 @@ interface MangaRepository {
suspend fun getMangaByIdAsFlow(id: Long): Flow<Manga> suspend fun getMangaByIdAsFlow(id: Long): Flow<Manga>
suspend fun getFavorites(): List<Manga>
fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>> fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
suspend fun getDuplicateLibraryManga(title: String, sourceId: Long): Manga? suspend fun getDuplicateLibraryManga(title: String, sourceId: Long): Manga?

View File

@ -3,7 +3,10 @@ package eu.kanade.tachiyomi.data.backup
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import eu.kanade.data.DatabaseHandler import eu.kanade.data.DatabaseHandler
import eu.kanade.data.manga.mangaMapper
import eu.kanade.data.toLong import eu.kanade.data.toLong
import eu.kanade.domain.manga.interactor.GetFavorites
import eu.kanade.domain.manga.interactor.GetMergedManga
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.library.CustomMangaManager import eu.kanade.tachiyomi.data.library.CustomMangaManager
@ -13,6 +16,7 @@ import eu.kanade.tachiyomi.source.SourceManager
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import data.Mangas as DbManga import data.Mangas as DbManga
import eu.kanade.domain.manga.model.Manga as DomainManga
abstract class AbstractBackupManager(protected val context: Context) { abstract class AbstractBackupManager(protected val context: Context) {
@ -21,8 +25,10 @@ abstract class AbstractBackupManager(protected val context: Context) {
internal val sourceManager: SourceManager = Injekt.get() internal val sourceManager: SourceManager = Injekt.get()
internal val trackManager: TrackManager = Injekt.get() internal val trackManager: TrackManager = Injekt.get()
protected val preferences: PreferencesHelper = Injekt.get() protected val preferences: PreferencesHelper = Injekt.get()
private val getFavorites: GetFavorites = Injekt.get()
// SY --> // SY -->
private val getMergedManga: GetMergedManga = Injekt.get()
protected val customMangaManager: CustomMangaManager = Injekt.get() protected val customMangaManager: CustomMangaManager = Injekt.get()
// SY <-- // SY <--
@ -42,13 +48,13 @@ abstract class AbstractBackupManager(protected val context: Context) {
* *
* @return [Manga] from library * @return [Manga] from library
*/ */
protected suspend fun getFavoriteManga(): List<DbManga> { protected suspend fun getFavoriteManga(): List<DomainManga> {
return handler.awaitList { mangasQueries.getFavorites() } return getFavorites.await()
} }
// SY --> // SY -->
protected suspend fun getReadManga(): List<DbManga> { protected suspend fun getReadManga(): List<DomainManga> {
return handler.awaitList { mangasQueries.getReadMangaNotInLibrary() } return handler.awaitList { mangasQueries.getReadMangaNotInLibrary(mangaMapper) }
} }
/** /**
@ -56,8 +62,8 @@ abstract class AbstractBackupManager(protected val context: Context) {
* *
* @return merged [Manga] that are possibly not in the library * @return merged [Manga] that are possibly not in the library
*/ */
protected suspend fun getMergedManga(): List<DbManga> { protected suspend fun getMergedManga(): List<DomainManga> {
return handler.awaitList { mergedQueries.selectAllMergedMangas() } return getMergedManga.await()
} }
// SY <-- // SY <--

View File

@ -56,6 +56,7 @@ import okio.sink
import java.io.FileOutputStream import java.io.FileOutputStream
import java.util.Date import java.util.Date
import kotlin.math.max import kotlin.math.max
import eu.kanade.domain.manga.model.Manga as DomainManga
class FullBackupManager(context: Context) : AbstractBackupManager(context) { class FullBackupManager(context: Context) : AbstractBackupManager(context) {
@ -138,13 +139,13 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
} }
} }
private suspend fun backupManga(mangas: List<Mangas>, flags: Int): List<BackupManga> { private suspend fun backupManga(mangas: List<DomainManga>, flags: Int): List<BackupManga> {
return mangas.map { return mangas.map {
backupMangaObject(it, flags) backupMangaObject(it, flags)
} }
} }
private fun backupExtensionInfo(mangas: List<Mangas>): List<BackupSource> { private fun backupExtensionInfo(mangas: List<DomainManga>): List<BackupSource> {
return mangas return mangas
.asSequence() .asSequence()
.map { it.source } .map { it.source }
@ -186,21 +187,19 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
* @param options options for the backup * @param options options for the backup
* @return [BackupManga] containing manga in a serializable form * @return [BackupManga] containing manga in a serializable form
*/ */
private suspend fun backupMangaObject(manga: Mangas, options: Int): BackupManga { private suspend fun backupMangaObject(manga: DomainManga, options: Int): BackupManga {
// Entry for this manga // Entry for this manga
val mangaObject = BackupManga.copyFrom(manga /* SY --> */, if (options and BACKUP_CUSTOM_INFO_MASK == BACKUP_CUSTOM_INFO) customMangaManager else null /* SY <-- */) val mangaObject = BackupManga.copyFrom(manga /* SY --> */, if (options and BACKUP_CUSTOM_INFO_MASK == BACKUP_CUSTOM_INFO) customMangaManager else null /* SY <-- */)
// SY --> // SY -->
if (manga.source == MERGED_SOURCE_ID) { if (manga.source == MERGED_SOURCE_ID) {
mangaObject.mergedMangaReferences = handler.awaitList { mergedQueries.selectByMergeId(manga._id, backupMergedMangaReferenceMapper) } mangaObject.mergedMangaReferences = handler.awaitList { mergedQueries.selectByMergeId(manga.id, backupMergedMangaReferenceMapper) }
} }
val source = sourceManager.get(manga.source)?.getMainSource<MetadataSource<*, *>>() val source = sourceManager.get(manga.source)?.getMainSource<MetadataSource<*, *>>()
if (source != null) { if (source != null) {
manga._id.let { mangaId -> handler.getFlatMetadataForManga(manga.id)?.let { flatMetadata ->
handler.getFlatMetadataForManga(mangaId)?.let { flatMetadata -> mangaObject.flatMetadata = BackupFlatMetadata.copyFrom(flatMetadata)
mangaObject.flatMetadata = BackupFlatMetadata.copyFrom(flatMetadata)
}
} }
} }
// SY <-- // SY <--
@ -208,7 +207,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
// Check if user wants chapter information in backup // Check if user wants chapter information in backup
if (options and BACKUP_CHAPTER_MASK == BACKUP_CHAPTER) { if (options and BACKUP_CHAPTER_MASK == BACKUP_CHAPTER) {
// Backup all the chapters // Backup all the chapters
val chapters = handler.awaitList { chaptersQueries.getChaptersByMangaId(manga._id, backupChapterMapper) } val chapters = handler.awaitList { chaptersQueries.getChaptersByMangaId(manga.id, backupChapterMapper) }
if (chapters.isNotEmpty()) { if (chapters.isNotEmpty()) {
mangaObject.chapters = chapters mangaObject.chapters = chapters
} }
@ -217,7 +216,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
// Check if user wants category information in backup // Check if user wants category information in backup
if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) { if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) {
// Backup categories for this manga // Backup categories for this manga
val categoriesForManga = handler.awaitList { categoriesQueries.getCategoriesByMangaId(manga._id) } val categoriesForManga = handler.awaitList { categoriesQueries.getCategoriesByMangaId(manga.id) }
if (categoriesForManga.isNotEmpty()) { if (categoriesForManga.isNotEmpty()) {
mangaObject.categories = categoriesForManga.map { it.order } mangaObject.categories = categoriesForManga.map { it.order }
} }
@ -225,7 +224,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
// Check if user wants track information in backup // Check if user wants track information in backup
if (options and BACKUP_TRACK_MASK == BACKUP_TRACK) { if (options and BACKUP_TRACK_MASK == BACKUP_TRACK) {
val tracks = handler.awaitList { manga_syncQueries.getTracksByMangaId(manga._id, backupTrackMapper) } val tracks = handler.awaitList { manga_syncQueries.getTracksByMangaId(manga.id, backupTrackMapper) }
if (tracks.isNotEmpty()) { if (tracks.isNotEmpty()) {
mangaObject.tracking = tracks mangaObject.tracking = tracks
} }
@ -233,7 +232,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
// Check if user wants history information in backup // Check if user wants history information in backup
if (options and BACKUP_HISTORY_MASK == BACKUP_HISTORY) { if (options and BACKUP_HISTORY_MASK == BACKUP_HISTORY) {
val historyByMangaId = handler.awaitList(true) { historyQueries.getHistoryByMangaId(manga._id) } val historyByMangaId = handler.awaitList(true) { historyQueries.getHistoryByMangaId(manga.id) }
if (historyByMangaId.isNotEmpty()) { if (historyByMangaId.isNotEmpty()) {
val history = historyByMangaId.map { history -> val history = historyByMangaId.map { history ->
val chapter = handler.awaitOne { chaptersQueries.getChapterById(history.chapter_id) } val chapter = handler.awaitOne { chaptersQueries.getChapterById(history.chapter_id) }

View File

@ -1,13 +1,12 @@
package eu.kanade.tachiyomi.data.backup.full.models package eu.kanade.tachiyomi.data.backup.full.models
import data.Mangas
import eu.kanade.data.listOfStringsAndAdapter import eu.kanade.data.listOfStringsAndAdapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.database.models.ChapterImpl import eu.kanade.tachiyomi.data.database.models.ChapterImpl
import eu.kanade.tachiyomi.data.database.models.MangaImpl import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.database.models.TrackImpl import eu.kanade.tachiyomi.data.database.models.TrackImpl
import eu.kanade.tachiyomi.data.library.CustomMangaManager import eu.kanade.tachiyomi.data.library.CustomMangaManager
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import exh.util.nullIfBlank
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
@ -112,28 +111,28 @@ data class BackupManga(
} }
companion object { companion object {
fun copyFrom(manga: Mangas /* SY --> */, customMangaManager: CustomMangaManager?/* SY <-- */): BackupManga { fun copyFrom(manga: Manga /* SY --> */, customMangaManager: CustomMangaManager?/* SY <-- */): BackupManga {
return BackupManga( return BackupManga(
url = manga.url, url = manga.url,
// SY --> // SY -->
title = manga.title, title = manga.ogTitle,
artist = manga.artist, artist = manga.ogArtist,
author = manga.author, author = manga.ogAuthor,
description = manga.description, description = manga.ogDescription,
genre = manga.genre ?: emptyList(), genre = manga.ogGenre ?: emptyList(),
status = manga.status.toInt(), status = manga.ogStatus.toInt(),
// SY <-- // SY <--
thumbnailUrl = manga.thumbnail_url, thumbnailUrl = manga.thumbnailUrl,
favorite = manga.favorite, favorite = manga.favorite,
source = manga.source, source = manga.source,
dateAdded = manga.date_added, dateAdded = manga.dateAdded,
viewer = (manga.viewer.toInt() and ReadingModeType.MASK), viewer = (manga.viewerFlags.toInt() and ReadingModeType.MASK),
viewer_flags = manga.viewer.toInt(), viewer_flags = manga.viewerFlags.toInt(),
chapterFlags = manga.chapter_flags.toInt(), chapterFlags = manga.chapterFlags.toInt(),
filtered_scanlators = manga.filtered_scanlators?.let(listOfStringsAndAdapter::encode).nullIfBlank(),
// SY --> // SY -->
filtered_scanlators = manga.filteredScanlators?.let(listOfStringsAndAdapter::encode),
).also { backupManga -> ).also { backupManga ->
customMangaManager?.getManga(manga._id)?.let { customMangaManager?.getManga(manga.id)?.let {
backupManga.customTitle = it.title backupManga.customTitle = it.title
backupManga.customArtist = it.artist backupManga.customArtist = it.artist
backupManga.customAuthor = it.author backupManga.customAuthor = it.author

View File

@ -173,7 +173,7 @@ class NotificationReceiver : BroadcastReceiver() {
val manga = db.getManga(mangaId).executeAsBlocking() val manga = db.getManga(mangaId).executeAsBlocking()
val chapter = db.getChapter(chapterId).executeAsBlocking() val chapter = db.getChapter(chapterId).executeAsBlocking()
if (manga != null && chapter != null) { if (manga != null && chapter != null) {
val intent = ReaderActivity.newIntent(context, manga, chapter).apply { val intent = ReaderActivity.newIntent(context, manga.id, chapter.id).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
} }
context.startActivity(intent) context.startActivity(intent)
@ -440,7 +440,7 @@ class NotificationReceiver : BroadcastReceiver() {
* @param chapter chapter that needs to be opened * @param chapter chapter that needs to be opened
*/ */
internal fun openChapterPendingActivity(context: Context, manga: Manga, chapter: Chapter): PendingIntent { internal fun openChapterPendingActivity(context: Context, manga: Manga, chapter: Chapter): PendingIntent {
val newIntent = ReaderActivity.newIntent(context, manga, chapter) val newIntent = ReaderActivity.newIntent(context, manga.id, chapter.id)
return PendingIntent.getActivity(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) return PendingIntent.getActivity(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
} }

View File

@ -121,9 +121,12 @@ class MergedSource : HttpSource() {
return if (dedupe) dedupeChapterList(mangaReferences, chapters) else chapters return if (dedupe) dedupeChapterList(mangaReferences, chapters) else chapters
} }
fun getChaptersAsBlocking(mangaId: Long, editScanlators: Boolean = false, dedupe: Boolean = true): List<Chapter> { fun getChaptersAsBlockingAsDbChapter(mangaId: Long, editScanlators: Boolean = false, dedupe: Boolean = true): List<Chapter> {
return getChaptersAsBlocking(mangaId, editScanlators, dedupe).map(DomainChapter::toDbChapter)
}
fun getChaptersAsBlocking(mangaId: Long, editScanlators: Boolean = false, dedupe: Boolean = true): List<DomainChapter> {
return transformMergedChapters(mangaId, runBlocking { getMergedChaptersByMangaId.await(mangaId) }, editScanlators, dedupe) return transformMergedChapters(mangaId, runBlocking { getMergedChaptersByMangaId.await(mangaId) }, editScanlators, dedupe)
.map(DomainChapter::toDbChapter)
} }
private fun dedupeChapterList(mangaReferences: List<MergedMangaReference>, chapterList: List<DomainChapter>): List<DomainChapter> { private fun dedupeChapterList(mangaReferences: List<MergedMangaReference>, chapterList: List<DomainChapter>): List<DomainChapter> {
@ -155,7 +158,7 @@ class MergedSource : HttpSource() {
suspend fun fetchChaptersForMergedManga(manga: DomainManga, downloadChapters: Boolean = true, editScanlators: Boolean = false, dedupe: Boolean = true): List<Chapter> { suspend fun fetchChaptersForMergedManga(manga: DomainManga, downloadChapters: Boolean = true, editScanlators: Boolean = false, dedupe: Boolean = true): List<Chapter> {
return withIOContext { return withIOContext {
fetchChaptersAndSync(manga, downloadChapters) fetchChaptersAndSync(manga, downloadChapters)
getChaptersAsBlocking(manga.id, editScanlators, dedupe) getChaptersAsBlockingAsDbChapter(manga.id, editScanlators, dedupe)
} }
} }

View File

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.ui.browse.migration.manga package eu.kanade.tachiyomi.ui.browse.migration.manga
import android.os.Bundle import android.os.Bundle
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId import eu.kanade.domain.manga.interactor.GetFavorites
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
@ -16,7 +16,7 @@ import uy.kohesive.injekt.api.get
class MigrationMangaPresenter( class MigrationMangaPresenter(
private val sourceId: Long, private val sourceId: Long,
private val getFavoritesBySourceId: GetFavoritesBySourceId = Injekt.get(), private val getFavorites: GetFavorites = Injekt.get(),
) : BasePresenter<MigrationMangaController>() { ) : BasePresenter<MigrationMangaController>() {
private val _state: MutableStateFlow<MigrateMangaState> = MutableStateFlow(MigrateMangaState.Loading) private val _state: MutableStateFlow<MigrateMangaState> = MutableStateFlow(MigrateMangaState.Loading)
val state: StateFlow<MigrateMangaState> = _state.asStateFlow() val state: StateFlow<MigrateMangaState> = _state.asStateFlow()
@ -24,7 +24,7 @@ class MigrationMangaPresenter(
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
presenterScope.launchIO { presenterScope.launchIO {
getFavoritesBySourceId getFavorites
.subscribe(sourceId) .subscribe(sourceId)
.catch { exception -> .catch { exception ->
_state.value = MigrateMangaState.Error(exception) _state.value = MigrateMangaState.Error(exception)

View File

@ -871,7 +871,7 @@ class LibraryController(
} }
val activity = activity ?: return val activity = activity ?: return
val chapter = presenter.getFirstUnread(manga) ?: return val chapter = presenter.getFirstUnread(manga) ?: return
val intent = ReaderActivity.newIntent(activity, manga, chapter) val intent = ReaderActivity.newIntent(activity, manga.id!!, chapter.id!!)
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
startActivity(intent) startActivity(intent)
} }

View File

@ -719,7 +719,7 @@ class LibraryPresenter(
val mergedSource = sourceManager.get(MERGED_SOURCE_ID) as MergedSource val mergedSource = sourceManager.get(MERGED_SOURCE_ID) as MergedSource
val mergedMangas = getMergedMangaById.await(manga.id!!) val mergedMangas = getMergedMangaById.await(manga.id!!)
mergedSource mergedSource
.getChaptersAsBlocking(manga.id!!) .getChaptersAsBlockingAsDbChapter(manga.id!!)
.filter { !it.read } .filter { !it.read }
.groupBy { it.manga_id!! } .groupBy { it.manga_id!! }
.forEach ab@{ (mangaId, chapters) -> .forEach ab@{ (mangaId, chapters) ->
@ -886,7 +886,7 @@ class LibraryPresenter(
/** Returns first unread chapter of a manga */ /** Returns first unread chapter of a manga */
fun getFirstUnread(manga: Manga): Chapter? { fun getFirstUnread(manga: Manga): Chapter? {
val chapters = if (manga.source == MERGED_SOURCE_ID) { val chapters = if (manga.source == MERGED_SOURCE_ID) {
(sourceManager.get(MERGED_SOURCE_ID) as MergedSource).getChaptersAsBlocking(manga.id!!) (sourceManager.get(MERGED_SOURCE_ID) as MergedSource).getChaptersAsBlockingAsDbChapter(manga.id!!)
} else runBlocking { getChapterByMangaId.await(manga.id!!) }.map { it.toDbChapter() } } else runBlocking { getChapterByMangaId.await(manga.id!!) }.map { it.toDbChapter() }
return if (manga.isEhBasedManga()) { return if (manga.isEhBasedManga()) {
val chapter = chapters.sortedBy { it.source_order }.getOrNull(0) val chapter = chapters.sortedBy { it.source_order }.getOrNull(0)

View File

@ -51,7 +51,6 @@ import com.google.android.material.transition.platform.MaterialContainerTransfor
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
@ -136,10 +135,6 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
} }
} }
fun newIntent(context: Context, manga: Manga, chapter: Chapter): Intent {
return newIntent(context, manga.id, chapter.id)
}
const val SHIFT_DOUBLE_PAGES = "shiftingDoublePages" const val SHIFT_DOUBLE_PAGES = "shiftingDoublePages"
const val SHIFTED_PAGE_INDEX = "shiftedPageIndex" const val SHIFTED_PAGE_INDEX = "shiftedPageIndex"
const val SHIFTED_CHAP_INDEX = "shiftedChapterIndex" const val SHIFTED_CHAP_INDEX = "shiftedChapterIndex"

View File

@ -6,11 +6,16 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.model.ChapterUpdate import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.history.interactor.UpsertHistory import eu.kanade.domain.history.interactor.UpsertHistory
import eu.kanade.domain.history.model.HistoryUpdate import eu.kanade.domain.history.model.HistoryUpdate
import eu.kanade.domain.manga.interactor.GetFlatMetadataById
import eu.kanade.domain.manga.interactor.GetMangaById
import eu.kanade.domain.manga.model.isLocal import eu.kanade.domain.manga.model.isLocal
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.interactor.InsertTrack
import eu.kanade.domain.track.model.toDbTrack import eu.kanade.domain.track.model.toDbTrack
@ -46,6 +51,7 @@ import eu.kanade.tachiyomi.util.lang.byteSize
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.lang.takeBytes import eu.kanade.tachiyomi.util.lang.takeBytes
import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.cacheImageDir import eu.kanade.tachiyomi.util.storage.cacheImageDir
import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.ImageUtil
@ -54,7 +60,6 @@ import eu.kanade.tachiyomi.util.system.logcat
import exh.md.utils.FollowStatus import exh.md.utils.FollowStatus
import exh.md.utils.MdUtil import exh.md.utils.MdUtil
import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.source.MERGED_SOURCE_ID import exh.source.MERGED_SOURCE_ID
import exh.source.getMainSource import exh.source.getMainSource
import exh.source.isEhBasedManga import exh.source.isEhBasedManga
@ -86,10 +91,15 @@ class ReaderPresenter(
private val downloadManager: DownloadManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get(), private val preferences: PreferencesHelper = Injekt.get(),
private val delayedTrackingStore: DelayedTrackingStore = Injekt.get(), private val delayedTrackingStore: DelayedTrackingStore = Injekt.get(),
private val getMangaById: GetMangaById = Injekt.get(),
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
private val getTracks: GetTracks = Injekt.get(), private val getTracks: GetTracks = Injekt.get(),
private val insertTrack: InsertTrack = Injekt.get(), private val insertTrack: InsertTrack = Injekt.get(),
private val upsertHistory: UpsertHistory = Injekt.get(), private val upsertHistory: UpsertHistory = Injekt.get(),
private val updateChapter: UpdateChapter = Injekt.get(), private val updateChapter: UpdateChapter = Injekt.get(),
// SY -->
private val getFlatMetadataById: GetFlatMetadataById,
// SY <--
) : BasePresenter<ReaderActivity>() { ) : BasePresenter<ReaderActivity>() {
/** /**
@ -147,17 +157,19 @@ class ReaderPresenter(
// SY --> // SY -->
val filteredScanlators = manga.filtered_scanlators?.let { MdUtil.getScanlators(it) } val filteredScanlators = manga.filtered_scanlators?.let { MdUtil.getScanlators(it) }
// SY <-- // SY <--
val dbChapters = /* SY --> */ if (manga.source == MERGED_SOURCE_ID) { val chapters = runBlocking {
(sourceManager.get(MERGED_SOURCE_ID) as MergedSource) /* SY --> */ if (manga.source == MERGED_SOURCE_ID) {
.getChaptersAsBlocking(manga.id!!) (sourceManager.get(MERGED_SOURCE_ID) as MergedSource)
} else /* SY <-- */ db.getChapters(manga).executeAsBlocking() .getChaptersAsBlocking(manga.id!!)
} else /* SY <-- */ getChapterByMangaId.await(manga.id!!)
}
val selectedChapter = dbChapters.find { it.id == chapterId } val selectedChapter = chapters.find { it.id == chapterId }
?: error("Requested chapter of id $chapterId not found in chapter list") ?: error("Requested chapter of id $chapterId not found in chapter list")
val chaptersForReader = when { val chaptersForReader = when {
(preferences.skipRead() || preferences.skipFiltered()) -> { (preferences.skipRead() || preferences.skipFiltered()) -> {
val filteredChapters = dbChapters.filterNot { val filteredChapters = chapters.filterNot {
when { when {
preferences.skipRead() && it.read -> true preferences.skipRead() && it.read -> true
preferences.skipFiltered() -> { preferences.skipFiltered() -> {
@ -180,10 +192,11 @@ class ReaderPresenter(
filteredChapters + listOf(selectedChapter) filteredChapters + listOf(selectedChapter)
} }
} }
else -> dbChapters else -> chapters
} }
chaptersForReader chaptersForReader
.map { it.toDbChapter() }
.sortedWith(getChapterSort(manga, sortDescending = false)) .sortedWith(getChapterSort(manga, sortDescending = false))
.map(::ReaderChapter) .map(::ReaderChapter)
} }
@ -266,28 +279,22 @@ class ReaderPresenter(
fun init(mangaId: Long, initialChapterId: Long) { fun init(mangaId: Long, initialChapterId: Long) {
if (!needsInit()) return if (!needsInit()) return
db.getManga(mangaId).asRxObservable() launchIO {
.first() try {
.observeOn(AndroidSchedulers.mainThread()) // SY -->
// SY --> val manga = getMangaById.await(mangaId) ?: return@launchIO
.flatMap { manga ->
val source = sourceManager.get(manga.source)?.getMainSource<MetadataSource<*, *>>() val source = sourceManager.get(manga.source)?.getMainSource<MetadataSource<*, *>>()
if (manga.initialized && source != null) { val metadata = if (source != null) {
db.getFlatMetadataForManga(mangaId).asRxSingle().map { getFlatMetadataById.await(mangaId)?.raise(source.metaClass)
manga to it?.raise(source.metaClass) } else null
}.toObservable() withUIContext {
} else { init(manga.toDbManga(), initialChapterId, metadata)
Observable.just(manga to null)
} }
// SY <--
} catch (e: Throwable) {
view?.setInitialChapterError(e)
} }
.doOnNext { init(it.first, initialChapterId, it.second) } }
// SY <--
.subscribeFirst(
{ _, _ ->
// Ignore onNext event
},
ReaderActivity::setInitialChapterError,
)
} }
/** /**

View File

@ -70,7 +70,7 @@ class InterceptActivity : BaseActivity() {
onBackPressed() onBackPressed()
startActivity( startActivity(
if (it.chapter != null) { if (it.chapter != null) {
ReaderActivity.newIntent(this, it.manga, it.chapter) ReaderActivity.newIntent(this, it.manga.id!!, it.chapter.id!!)
} else { } else {
Intent(this, MainActivity::class.java) Intent(this, MainActivity::class.java)
.setAction(MainActivity.SHORTCUT_MANGA) .setAction(MainActivity.SHORTCUT_MANGA)