diff --git a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt index 9058eac34..f9ecbf735 100644 --- a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt @@ -26,6 +26,10 @@ class MangaRepositoryImpl( return handler.subscribeToOne { mangasQueries.getMangaById(id, mangaMapper) } } + override suspend fun getFavorites(): List { + return handler.awaitList { mangasQueries.getFavorites(mangaMapper) } + } + override fun getFavoritesBySourceId(sourceId: Long): Flow> { return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) } } diff --git a/app/src/main/java/eu/kanade/domain/DomainModule.kt b/app/src/main/java/eu/kanade/domain/DomainModule.kt index 622060862..971bde777 100644 --- a/app/src/main/java/eu/kanade/domain/DomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/DomainModule.kt @@ -31,7 +31,7 @@ import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId import eu.kanade.domain.history.interactor.UpsertHistory import eu.kanade.domain.history.repository.HistoryRepository 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.GetMangaWithChapters import eu.kanade.domain.manga.interactor.ResetViewerFlags @@ -70,7 +70,7 @@ class DomainModule : InjektModule { addSingletonFactory { MangaRepositoryImpl(get()) } addFactory { GetDuplicateLibraryManga(get()) } - addFactory { GetFavoritesBySourceId(get()) } + addFactory { GetFavorites(get()) } addFactory { GetMangaWithChapters(get(), get()) } addFactory { GetMangaById(get()) } addFactory { GetNextChapter(get()) } diff --git a/app/src/main/java/eu/kanade/domain/manga/interactor/GetFavoritesBySourceId.kt b/app/src/main/java/eu/kanade/domain/manga/interactor/GetFavorites.kt similarity index 76% rename from app/src/main/java/eu/kanade/domain/manga/interactor/GetFavoritesBySourceId.kt rename to app/src/main/java/eu/kanade/domain/manga/interactor/GetFavorites.kt index 8489d4d57..6365d86be 100644 --- a/app/src/main/java/eu/kanade/domain/manga/interactor/GetFavoritesBySourceId.kt +++ b/app/src/main/java/eu/kanade/domain/manga/interactor/GetFavorites.kt @@ -4,10 +4,14 @@ import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.repository.MangaRepository import kotlinx.coroutines.flow.Flow -class GetFavoritesBySourceId( +class GetFavorites( private val mangaRepository: MangaRepository, ) { + suspend fun await(): List { + return mangaRepository.getFavorites() + } + fun subscribe(sourceId: Long): Flow> { return mangaRepository.getFavoritesBySourceId(sourceId) } diff --git a/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt b/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt index 577868b90..054edc69f 100644 --- a/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt +++ b/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt @@ -31,9 +31,6 @@ data class Manga( val initialized: Boolean, ) { - val sorting: Long - get() = chapterFlags and CHAPTER_SORTING_MASK - fun toSManga(): SManga { return SManga.create().also { it.url = url @@ -48,6 +45,9 @@ data class Manga( } } + val sorting: Long + get() = chapterFlags and CHAPTER_SORTING_MASK + val displayMode: Long get() = chapterFlags and CHAPTER_DISPLAY_MASK diff --git a/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt b/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt index d5d282832..97c35de42 100644 --- a/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt +++ b/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt @@ -12,6 +12,8 @@ interface MangaRepository { suspend fun getMangaByIdAsFlow(id: Long): Flow + suspend fun getFavorites(): List + fun getFavoritesBySourceId(sourceId: Long): Flow> suspend fun getDuplicateLibraryManga(title: String, sourceId: Long): Manga? diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt index 60e792b41..cc7f8f07f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupManager.kt @@ -4,6 +4,7 @@ import android.content.Context import android.net.Uri import eu.kanade.data.DatabaseHandler import eu.kanade.data.toLong +import eu.kanade.domain.manga.interactor.GetFavorites import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.toMangaInfo @@ -16,6 +17,7 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import data.Mangas as DbManga +import eu.kanade.domain.manga.model.Manga as DomainManga abstract class AbstractBackupManager(protected val context: Context) { @@ -24,6 +26,7 @@ abstract class AbstractBackupManager(protected val context: Context) { internal val sourceManager: SourceManager = Injekt.get() internal val trackManager: TrackManager = Injekt.get() protected val preferences: PreferencesHelper = Injekt.get() + private val getFavorites: GetFavorites = Injekt.get() abstract suspend fun createBackup(uri: Uri, flags: Int, isAutoBackup: Boolean): String @@ -60,8 +63,8 @@ abstract class AbstractBackupManager(protected val context: Context) { * * @return [Manga] from library */ - protected suspend fun getFavoriteManga(): List { - return handler.awaitList { mangasQueries.getFavorites() } + protected suspend fun getFavoriteManga(): List { + return getFavorites.await() } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt index 7fc7309ca..652f276f2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt @@ -38,6 +38,7 @@ import okio.sink import java.io.FileOutputStream import java.util.Date import kotlin.math.max +import eu.kanade.domain.manga.model.Manga as DomainManga class FullBackupManager(context: Context) : AbstractBackupManager(context) { @@ -113,13 +114,13 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { } } - private suspend fun backupManga(mangas: List, flags: Int): List { + private suspend fun backupManga(mangas: List, flags: Int): List { return mangas.map { backupMangaObject(it, flags) } } - private fun backupExtensionInfo(mangas: List): List { + private fun backupExtensionInfo(mangas: List): List { return mangas .asSequence() .map { it.source } @@ -150,14 +151,14 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { * @param options options for the backup * @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 val mangaObject = BackupManga.copyFrom(manga) // Check if user wants chapter information in backup if (options and BACKUP_CHAPTER_MASK == BACKUP_CHAPTER) { // 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()) { mangaObject.chapters = chapters } @@ -166,7 +167,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { // Check if user wants category information in backup if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) { // Backup categories for this manga - val categoriesForManga = handler.awaitList { categoriesQueries.getCategoriesByMangaId(manga._id) } + val categoriesForManga = handler.awaitList { categoriesQueries.getCategoriesByMangaId(manga.id) } if (categoriesForManga.isNotEmpty()) { mangaObject.categories = categoriesForManga.map { it.order } } @@ -174,7 +175,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { // Check if user wants track information in backup 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()) { mangaObject.tracking = tracks } @@ -182,7 +183,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { // Check if user wants history information in backup 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()) { val history = historyByMangaId.map { history -> val chapter = handler.awaitOne { chaptersQueries.getChapterById(history.chapter_id) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupManga.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupManga.kt index 86496dc8a..3569d534a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupManga.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupManga.kt @@ -1,6 +1,6 @@ package eu.kanade.tachiyomi.data.backup.full.models -import data.Mangas +import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.data.database.models.ChapterImpl import eu.kanade.tachiyomi.data.database.models.MangaImpl import eu.kanade.tachiyomi.data.database.models.TrackImpl @@ -69,7 +69,7 @@ data class BackupManga( } companion object { - fun copyFrom(manga: Mangas): BackupManga { + fun copyFrom(manga: Manga): BackupManga { return BackupManga( url = manga.url, title = manga.title, @@ -78,13 +78,13 @@ data class BackupManga( description = manga.description, genre = manga.genre ?: emptyList(), status = manga.status.toInt(), - thumbnailUrl = manga.thumbnail_url, + thumbnailUrl = manga.thumbnailUrl, favorite = manga.favorite, source = manga.source, - dateAdded = manga.date_added, - viewer = (manga.viewer.toInt() and ReadingModeType.MASK), - viewer_flags = manga.viewer.toInt(), - chapterFlags = manga.chapter_flags.toInt(), + dateAdded = manga.dateAdded, + viewer = (manga.viewerFlags.toInt() and ReadingModeType.MASK), + viewer_flags = manga.viewerFlags.toInt(), + chapterFlags = manga.chapterFlags.toInt(), ) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt index 35b7bcfe8..22ae7af18 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt @@ -8,17 +8,6 @@ import eu.kanade.tachiyomi.data.database.tables.ChapterTable interface ChapterQueries : DbProvider { - fun getChapters(mangaId: Long) = db.get() - .listOfObjects(Chapter::class.java) - .withQuery( - Query.builder() - .table(ChapterTable.TABLE) - .where("${ChapterTable.COL_MANGA_ID} = ?") - .whereArgs(mangaId) - .build(), - ) - .prepare() - fun getChapter(id: Long) = db.get() .`object`(Chapter::class.java) .withQuery( diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt index 7fc7415c8..887c0ae4b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt @@ -173,7 +173,7 @@ class NotificationReceiver : BroadcastReceiver() { val manga = db.getManga(mangaId).executeAsBlocking() val chapter = db.getChapter(chapterId).executeAsBlocking() 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 } context.startActivity(intent) @@ -440,7 +440,7 @@ class NotificationReceiver : BroadcastReceiver() { * @param chapter chapter that needs to be opened */ 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) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt index cc8dd804e..4e1bbbc29 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.manga 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.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.util.lang.launchIO @@ -16,7 +16,7 @@ import uy.kohesive.injekt.api.get class MigrationMangaPresenter( private val sourceId: Long, - private val getFavoritesBySourceId: GetFavoritesBySourceId = Injekt.get(), + private val getFavorites: GetFavorites = Injekt.get(), ) : BasePresenter() { private val _state: MutableStateFlow = MutableStateFlow(MigrateMangaState.Loading) @@ -25,7 +25,7 @@ class MigrationMangaPresenter( override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) presenterScope.launchIO { - getFavoritesBySourceId + getFavorites .subscribe(sourceId) .catch { exception -> _state.value = MigrateMangaState.Error(exception) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index d6f2cd450..a1b672533 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -46,7 +46,6 @@ import com.google.android.material.transition.platform.MaterialContainerTransfor import dev.chrisbanes.insetter.applyInsetter import eu.kanade.tachiyomi.BuildConfig 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.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.Notifications @@ -106,10 +105,6 @@ class ReaderActivity : BaseRxActivity() { } } - fun newIntent(context: Context, manga: Manga, chapter: Chapter): Intent { - return newIntent(context, manga.id, chapter.id) - } - private const val ENABLED_BUTTON_IMAGE_ALPHA = 255 private const val DISABLED_BUTTON_IMAGE_ALPHA = 64 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index cf4315f76..ef197ea25 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -5,11 +5,15 @@ import android.content.Context import android.net.Uri import android.os.Bundle import com.jakewharton.rxrelay.BehaviorRelay +import eu.kanade.domain.chapter.interactor.GetChapterByMangaId import eu.kanade.domain.chapter.interactor.UpdateChapter 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.model.HistoryUpdate +import eu.kanade.domain.manga.interactor.GetMangaById 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.InsertTrack import eu.kanade.domain.track.model.toDbTrack @@ -41,6 +45,7 @@ import eu.kanade.tachiyomi.util.lang.byteSize import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchUI 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.cacheImageDir import eu.kanade.tachiyomi.util.system.isOnline @@ -68,6 +73,8 @@ class ReaderPresenter( private val downloadManager: DownloadManager = Injekt.get(), private val preferences: PreferencesHelper = 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 insertTrack: InsertTrack = Injekt.get(), private val upsertHistory: UpsertHistory = Injekt.get(), @@ -118,14 +125,14 @@ class ReaderPresenter( */ private val chapterList by lazy { val manga = manga!! - val dbChapters = db.getChapters(manga.id!!).executeAsBlocking() + val chapters = runBlocking { 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") val chaptersForReader = when { (preferences.skipRead() || preferences.skipFiltered()) -> { - val filteredChapters = dbChapters.filterNot { + val filteredChapters = chapters.filterNot { when { preferences.skipRead() && it.read -> true preferences.skipFiltered() -> { @@ -146,10 +153,11 @@ class ReaderPresenter( filteredChapters + listOf(selectedChapter) } } - else -> dbChapters + else -> chapters } chaptersForReader + .map { it.toDbChapter() } .sortedWith(getChapterSort(manga, sortDescending = false)) .map(::ReaderChapter) } @@ -232,16 +240,16 @@ class ReaderPresenter( fun init(mangaId: Long, initialChapterId: Long) { if (!needsInit()) return - db.getManga(mangaId).asRxObservable() - .first() - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext { init(it, initialChapterId) } - .subscribeFirst( - { _, _ -> - // Ignore onNext event - }, - ReaderActivity::setInitialChapterError, - ) + launchIO { + try { + val manga = getMangaById.await(mangaId) + withUIContext { + manga?.let { init(it.toDbManga(), initialChapterId) } + } + } catch (e: Throwable) { + view?.setInitialChapterError(e) + } + } } /**