Przeglądaj źródła

Migrate some categories SQL calls to SQLDelight

arkon 2 lat temu
rodzic
commit
a7decdb62d

+ 7 - 0
app/src/main/java/eu/kanade/domain/category/model/Category.kt

@@ -1,6 +1,7 @@
 package eu.kanade.domain.category.model
 
 import java.io.Serializable
+import eu.kanade.tachiyomi.data.database.models.Category as DbCategory
 
 data class Category(
     val id: Long,
@@ -8,3 +9,9 @@ data class Category(
     val order: Long,
     val flags: Long,
 ) : Serializable
+
+fun Category.toDbCategory(): DbCategory = DbCategory.create(name).also {
+    it.id = id.toInt()
+    it.order = order.toInt()
+    it.flags = flags.toInt()
+}

+ 4 - 1
app/src/main/java/eu/kanade/domain/manga/interactor/GetDuplicateLibraryManga.kt

@@ -3,7 +3,10 @@ package eu.kanade.domain.manga.interactor
 import eu.kanade.domain.manga.model.Manga
 import eu.kanade.domain.manga.repository.MangaRepository
 
-class GetDuplicateLibraryManga(private val mangaRepository: MangaRepository) {
+class GetDuplicateLibraryManga(
+    private val mangaRepository: MangaRepository,
+) {
+
     suspend fun await(title: String, sourceId: Long): Manga? {
         return mangaRepository.getDuplicateLibraryManga(title.lowercase(), sourceId)
     }

+ 1 - 0
app/src/main/java/eu/kanade/domain/manga/interactor/ResetViewerFlags.kt

@@ -5,6 +5,7 @@ import eu.kanade.domain.manga.repository.MangaRepository
 class ResetViewerFlags(
     private val mangaRepository: MangaRepository,
 ) {
+
     suspend fun await(): Boolean {
         return mangaRepository.resetViewerFlags()
     }

+ 36 - 31
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt

@@ -20,6 +20,7 @@ import com.google.android.material.snackbar.Snackbar
 import dev.chrisbanes.insetter.applyInsetter
 import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.items.IFlexible
+import eu.kanade.domain.category.model.toDbCategory
 import eu.kanade.domain.source.model.Source
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Category
@@ -627,42 +628,46 @@ open class BrowseSourceController(bundle: Bundle) :
 
     private fun addToLibrary(newManga: Manga, position: Int) {
         val activity = activity ?: return
-        val categories = presenter.getCategories()
-        val defaultCategoryId = preferences.defaultCategory()
-        val defaultCategory = categories.find { it.id == defaultCategoryId }
-
-        when {
-            // Default category set
-            defaultCategory != null -> {
-                presenter.moveMangaToCategory(newManga, defaultCategory)
-
-                presenter.changeMangaFavorite(newManga)
-                adapter?.notifyItemChanged(position)
-                activity.toast(activity.getString(R.string.manga_added_library))
-            }
+        launchIO {
+            val categories = presenter.getCategories()
+            val defaultCategoryId = preferences.defaultCategory()
+            val defaultCategory = categories.find { it.id == defaultCategoryId.toLong() }
 
-            // Automatic 'Default' or no categories
-            defaultCategoryId == 0 || categories.isEmpty() -> {
-                presenter.moveMangaToCategory(newManga, null)
+            withUIContext {
+                when {
+                    // Default category set
+                    defaultCategory != null -> {
+                        presenter.moveMangaToCategory(newManga, defaultCategory.toDbCategory())
+
+                        presenter.changeMangaFavorite(newManga)
+                        adapter?.notifyItemChanged(position)
+                        activity.toast(activity.getString(R.string.manga_added_library))
+                    }
 
-                presenter.changeMangaFavorite(newManga)
-                adapter?.notifyItemChanged(position)
-                activity.toast(activity.getString(R.string.manga_added_library))
-            }
+                    // Automatic 'Default' or no categories
+                    defaultCategoryId == 0 || categories.isEmpty() -> {
+                        presenter.moveMangaToCategory(newManga, null)
 
-            // Choose a category
-            else -> {
-                val ids = presenter.getMangaCategoryIds(newManga)
-                val preselected = categories.map {
-                    if (it.id in ids) {
-                        QuadStateTextView.State.CHECKED.ordinal
-                    } else {
-                        QuadStateTextView.State.UNCHECKED.ordinal
+                        presenter.changeMangaFavorite(newManga)
+                        adapter?.notifyItemChanged(position)
+                        activity.toast(activity.getString(R.string.manga_added_library))
                     }
-                }.toTypedArray()
 
-                ChangeMangaCategoriesDialog(this, listOf(newManga), categories, preselected)
-                    .showDialog(router)
+                    // Choose a category
+                    else -> {
+                        val ids = presenter.getMangaCategoryIds(newManga)
+                        val preselected = categories.map {
+                            if (it.id in ids) {
+                                QuadStateTextView.State.CHECKED.ordinal
+                            } else {
+                                QuadStateTextView.State.UNCHECKED.ordinal
+                            }
+                        }.toTypedArray()
+
+                        ChangeMangaCategoriesDialog(this@BrowseSourceController, listOf(newManga), categories.map { it.toDbCategory() }, preselected)
+                            .showDialog(router)
+                    }
+                }
             }
         }
     }

+ 8 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt

@@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
 
 import android.os.Bundle
 import eu.davidea.flexibleadapter.items.IFlexible
+import eu.kanade.domain.category.interactor.GetCategories
 import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
 import eu.kanade.domain.manga.model.toDbManga
 import eu.kanade.tachiyomi.data.cache.CoverCache
@@ -45,6 +46,7 @@ import kotlinx.coroutines.flow.asFlow
 import kotlinx.coroutines.flow.catch
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import logcat.LogPriority
@@ -54,6 +56,7 @@ import rx.schedulers.Schedulers
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import java.util.Date
+import eu.kanade.domain.category.model.Category as DomainCategory
 
 open class BrowseSourcePresenter(
     private val sourceId: Long,
@@ -63,6 +66,7 @@ open class BrowseSourcePresenter(
     private val prefs: PreferencesHelper = Injekt.get(),
     private val coverCache: CoverCache = Injekt.get(),
     private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
+    private val getCategories: GetCategories = Injekt.get(),
 ) : BasePresenter<BrowseSourceController>() {
 
     /**
@@ -347,8 +351,8 @@ open class BrowseSourcePresenter(
      *
      * @return List of categories, not including the default category
      */
-    fun getCategories(): List<Category> {
-        return db.getCategories().executeAsBlocking()
+    suspend fun getCategories(): List<DomainCategory> {
+        return getCategories.subscribe().firstOrNull() ?: emptyList()
     }
 
     suspend fun getDuplicateLibraryManga(manga: Manga): Manga? {
@@ -361,9 +365,9 @@ open class BrowseSourcePresenter(
      * @param manga the manga to get categories from.
      * @return Array of category ids the manga is in, if none returns default id
      */
-    fun getMangaCategoryIds(manga: Manga): Array<Int?> {
+    fun getMangaCategoryIds(manga: Manga): Array<Long?> {
         val categories = db.getCategoriesForManga(manga).executeAsBlocking()
-        return categories.mapNotNull { it.id }.toTypedArray()
+        return categories.mapNotNull { it?.id?.toLong() }.toTypedArray()
     }
 
     /**

+ 68 - 46
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

@@ -34,6 +34,7 @@ import dev.chrisbanes.insetter.applyInsetter
 import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.SelectableAdapter
 import eu.kanade.data.chapter.NoChaptersException
+import eu.kanade.domain.category.model.toDbCategory
 import eu.kanade.domain.history.model.HistoryWithRelations
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.cache.CoverCache
@@ -97,6 +98,7 @@ import eu.kanade.tachiyomi.widget.ActionModeWithToolbar
 import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.runBlocking
 import logcat.LogPriority
 import reactivecircus.flowbinding.recyclerview.scrollStateChanges
 import reactivecircus.flowbinding.swiperefreshlayout.refreshes
@@ -397,13 +399,16 @@ class MangaController :
     }
 
     override fun onPrepareOptionsMenu(menu: Menu) {
-        // Hide options for local manga
-        menu.findItem(R.id.action_share).isVisible = !isLocalSource
-        menu.findItem(R.id.download_group).isVisible = !isLocalSource
-
-        // Hide options for non-library manga
-        menu.findItem(R.id.action_edit_categories).isVisible = presenter.manga.favorite && presenter.getCategories().isNotEmpty()
-        menu.findItem(R.id.action_migrate).isVisible = presenter.manga.favorite
+        runBlocking {
+            // Hide options for local manga
+            menu.findItem(R.id.action_share).isVisible = !isLocalSource
+            menu.findItem(R.id.download_group).isVisible = !isLocalSource
+
+            // Hide options for non-library manga
+            menu.findItem(R.id.action_edit_categories).isVisible =
+                presenter.manga.favorite && presenter.getCategories().isNotEmpty()
+            menu.findItem(R.id.action_migrate).isVisible = presenter.manga.favorite
+        }
     }
 
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
@@ -533,39 +538,47 @@ class MangaController :
     }
 
     private fun addToLibrary(newManga: Manga) {
-        val categories = presenter.getCategories()
-        val defaultCategoryId = preferences.defaultCategory()
-        val defaultCategory = categories.find { it.id == defaultCategoryId }
+        launchIO {
+            val categories = presenter.getCategories()
+            val defaultCategoryId = preferences.defaultCategory()
+            val defaultCategory = categories.find { it.id == defaultCategoryId.toLong() }
+
+            withUIContext {
+                when {
+                    // Default category set
+                    defaultCategory != null -> {
+                        toggleFavorite()
+                        presenter.moveMangaToCategory(newManga, defaultCategory.toDbCategory())
+                        activity?.toast(activity?.getString(R.string.manga_added_library))
+                        activity?.invalidateOptionsMenu()
+                    }
 
-        when {
-            // Default category set
-            defaultCategory != null -> {
-                toggleFavorite()
-                presenter.moveMangaToCategory(newManga, defaultCategory)
-                activity?.toast(activity?.getString(R.string.manga_added_library))
-                activity?.invalidateOptionsMenu()
-            }
+                    // Automatic 'Default' or no categories
+                    defaultCategoryId == 0 || categories.isEmpty() -> {
+                        toggleFavorite()
+                        presenter.moveMangaToCategory(newManga, null)
+                        activity?.toast(activity?.getString(R.string.manga_added_library))
+                        activity?.invalidateOptionsMenu()
+                    }
 
-            // Automatic 'Default' or no categories
-            defaultCategoryId == 0 || categories.isEmpty() -> {
-                toggleFavorite()
-                presenter.moveMangaToCategory(newManga, null)
-                activity?.toast(activity?.getString(R.string.manga_added_library))
-                activity?.invalidateOptionsMenu()
-            }
+                    // Choose a category
+                    else -> {
+                        val ids = presenter.getMangaCategoryIds(newManga)
+                        val preselected = categories.map {
+                            if (it.id in ids) {
+                                QuadStateTextView.State.CHECKED.ordinal
+                            } else {
+                                QuadStateTextView.State.UNCHECKED.ordinal
+                            }
+                        }.toTypedArray()
 
-            // Choose a category
-            else -> {
-                val ids = presenter.getMangaCategoryIds(newManga)
-                val preselected = categories.map {
-                    if (it.id in ids) {
-                        QuadStateTextView.State.CHECKED.ordinal
-                    } else {
-                        QuadStateTextView.State.UNCHECKED.ordinal
+                        showChangeCategoryDialog(
+                            newManga,
+                            categories.map { it.toDbCategory() },
+                            preselected,
+                        )
                     }
-                }.toTypedArray()
-
-                showChangeCategoryDialog(newManga, categories, preselected)
+                }
             }
         }
 
@@ -609,18 +622,27 @@ class MangaController :
     }
 
     fun onCategoriesClick() {
-        val manga = presenter.manga
-        val categories = presenter.getCategories()
+        launchIO {
+            val manga = presenter.manga
+            val categories = presenter.getCategories()
 
-        val ids = presenter.getMangaCategoryIds(manga)
-        val preselected = categories.map {
-            if (it.id in ids) {
-                QuadStateTextView.State.CHECKED.ordinal
-            } else {
-                QuadStateTextView.State.UNCHECKED.ordinal
+            if (categories.isEmpty()) {
+                return@launchIO
             }
-        }.toTypedArray()
-        showChangeCategoryDialog(manga, categories, preselected)
+
+            val ids = presenter.getMangaCategoryIds(manga)
+            val preselected = categories.map {
+                if (it.id in ids) {
+                    QuadStateTextView.State.CHECKED.ordinal
+                } else {
+                    QuadStateTextView.State.UNCHECKED.ordinal
+                }
+            }.toTypedArray()
+
+            withUIContext {
+                showChangeCategoryDialog(manga, categories.map { it.toDbCategory() }, preselected)
+            }
+        }
     }
 
     private fun showChangeCategoryDialog(manga: Manga, categories: List<Category>, preselected: Array<Int>) {

+ 12 - 8
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt

@@ -4,6 +4,7 @@ import android.content.Context
 import android.net.Uri
 import android.os.Bundle
 import com.jakewharton.rxrelay.PublishRelay
+import eu.kanade.domain.category.interactor.GetCategories
 import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
 import eu.kanade.domain.chapter.model.toDbChapter
 import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
@@ -51,6 +52,7 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.async
 import kotlinx.coroutines.awaitAll
 import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.supervisorScope
 import logcat.LogPriority
 import rx.Observable
@@ -61,6 +63,7 @@ import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import uy.kohesive.injekt.injectLazy
 import java.util.Date
+import eu.kanade.domain.category.model.Category as DomainCategory
 
 class MangaPresenter(
     val manga: Manga,
@@ -72,6 +75,7 @@ class MangaPresenter(
     private val coverCache: CoverCache = Injekt.get(),
     private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
     private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
+    private val getCategories: GetCategories = Injekt.get(),
 ) : BasePresenter<MangaController>() {
 
     /**
@@ -255,8 +259,8 @@ class MangaPresenter(
      *
      * @return List of categories, not including the default category
      */
-    fun getCategories(): List<Category> {
-        return db.getCategories().executeAsBlocking()
+    suspend fun getCategories(): List<DomainCategory> {
+        return getCategories.subscribe().firstOrNull() ?: emptyList()
     }
 
     /**
@@ -265,9 +269,9 @@ class MangaPresenter(
      * @param manga the manga to get categories from.
      * @return Array of category ids the manga is in, if none returns default id
      */
-    fun getMangaCategoryIds(manga: Manga): Array<Int> {
+    fun getMangaCategoryIds(manga: Manga): Array<Long> {
         val categories = db.getCategoriesForManga(manga).executeAsBlocking()
-        return categories.mapNotNull { it.id }.toTypedArray()
+        return categories.mapNotNull { it?.id?.toLong() }.toTypedArray()
     }
 
     /**
@@ -654,14 +658,14 @@ class MangaPresenter(
     /**
      * Whether downloaded only mode is enabled.
      */
-    fun forceDownloaded(): Boolean {
+    private fun forceDownloaded(): Boolean {
         return manga.favorite && preferences.downloadedOnly().get()
     }
 
     /**
      * Whether the display only downloaded filter is enabled.
      */
-    fun onlyDownloaded(): State {
+    private fun onlyDownloaded(): State {
         if (forceDownloaded()) {
             return State.INCLUDE
         }
@@ -675,7 +679,7 @@ class MangaPresenter(
     /**
      * Whether the display only downloaded filter is enabled.
      */
-    fun onlyBookmarked(): State {
+    private fun onlyBookmarked(): State {
         return when (manga.bookmarkedFilter) {
             Manga.CHAPTER_SHOW_BOOKMARKED -> State.INCLUDE
             Manga.CHAPTER_SHOW_NOT_BOOKMARKED -> State.EXCLUDE
@@ -686,7 +690,7 @@ class MangaPresenter(
     /**
      * Whether the display only unread filter is enabled.
      */
-    fun onlyUnread(): State {
+    private fun onlyUnread(): State {
         return when (manga.readFilter) {
             Manga.CHAPTER_SHOW_UNREAD -> State.INCLUDE
             Manga.CHAPTER_SHOW_READ -> State.EXCLUDE

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt

@@ -100,7 +100,7 @@ class MangaInfoHeaderAdapter(
                 .onEach { controller.onFavoriteClick() }
                 .launchIn(controller.viewScope)
 
-            if (controller.presenter.manga.favorite && controller.presenter.getCategories().isNotEmpty()) {
+            if (controller.presenter.manga.favorite) {
                 binding.btnFavorite.longClicks()
                     .onEach { controller.onCategoriesClick() }
                     .launchIn(controller.viewScope)