Migrate to more use of domain models

This commit is contained in:
arkon 2022-07-02 17:14:19 -04:00
parent 2674570792
commit 76c0ead1db
32 changed files with 184 additions and 235 deletions

View File

@ -2,6 +2,9 @@ package eu.kanade.domain.category.model
import android.content.Context import android.content.Context
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import java.io.Serializable import java.io.Serializable
import eu.kanade.tachiyomi.data.database.models.Category as DbCategory import eu.kanade.tachiyomi.data.database.models.Category as DbCategory
@ -12,6 +15,15 @@ data class Category(
val flags: Long, val flags: Long,
) : Serializable { ) : Serializable {
val displayMode: Long
get() = flags and DisplayModeSetting.MASK
val sortMode: Long
get() = flags and SortModeSetting.MASK
val sortDirection: Long
get() = flags and SortDirectionSetting.MASK
companion object { companion object {
val default = { context: Context -> val default = { context: Context ->
Category( Category(

View File

@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import tachiyomi.source.model.MangaInfo import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.Serializable
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
data class Manga( data class Manga(
@ -29,7 +30,7 @@ data class Manga(
val status: Long, val status: Long,
val thumbnailUrl: String?, val thumbnailUrl: String?,
val initialized: Boolean, val initialized: Boolean,
) { ) : Serializable {
fun toSManga(): SManga { fun toSManga(): SManga {
return SManga.create().also { return SManga.create().also {

View File

@ -2,11 +2,9 @@ package eu.kanade.tachiyomi.data.database
import androidx.sqlite.db.SupportSQLiteOpenHelper import androidx.sqlite.db.SupportSQLiteOpenHelper
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite
import eu.kanade.tachiyomi.data.database.mappers.CategoryTypeMapping
import eu.kanade.tachiyomi.data.database.mappers.ChapterTypeMapping import eu.kanade.tachiyomi.data.database.mappers.ChapterTypeMapping
import eu.kanade.tachiyomi.data.database.mappers.MangaCategoryTypeMapping import eu.kanade.tachiyomi.data.database.mappers.MangaCategoryTypeMapping
import eu.kanade.tachiyomi.data.database.mappers.MangaTypeMapping import eu.kanade.tachiyomi.data.database.mappers.MangaTypeMapping
import eu.kanade.tachiyomi.data.database.models.Category
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.database.models.MangaCategory import eu.kanade.tachiyomi.data.database.models.MangaCategory
@ -26,7 +24,6 @@ class DatabaseHelper(
.sqliteOpenHelper(openHelper) .sqliteOpenHelper(openHelper)
.addTypeMapping(Manga::class.java, MangaTypeMapping()) .addTypeMapping(Manga::class.java, MangaTypeMapping())
.addTypeMapping(Chapter::class.java, ChapterTypeMapping()) .addTypeMapping(Chapter::class.java, ChapterTypeMapping())
.addTypeMapping(Category::class.java, CategoryTypeMapping())
.addTypeMapping(MangaCategory::class.java, MangaCategoryTypeMapping()) .addTypeMapping(MangaCategory::class.java, MangaCategoryTypeMapping())
.build() .build()
} }

View File

@ -1,64 +0,0 @@
package eu.kanade.tachiyomi.data.database.mappers
import android.database.Cursor
import androidx.core.content.contentValuesOf
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_FLAGS
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_ID
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_NAME
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_ORDER
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.TABLE
class CategoryTypeMapping : SQLiteTypeMapping<Category>(
CategoryPutResolver(),
CategoryGetResolver(),
CategoryDeleteResolver(),
)
class CategoryPutResolver : DefaultPutResolver<Category>() {
override fun mapToInsertQuery(obj: Category) = InsertQuery.builder()
.table(TABLE)
.build()
override fun mapToUpdateQuery(obj: Category) = UpdateQuery.builder()
.table(TABLE)
.where("$COL_ID = ?")
.whereArgs(obj.id)
.build()
override fun mapToContentValues(obj: Category) =
contentValuesOf(
COL_ID to obj.id,
COL_NAME to obj.name,
COL_ORDER to obj.order,
COL_FLAGS to obj.flags,
)
}
class CategoryGetResolver : DefaultGetResolver<Category>() {
override fun mapFromCursor(cursor: Cursor): Category = CategoryImpl().apply {
id = cursor.getInt(cursor.getColumnIndexOrThrow(COL_ID))
name = cursor.getString(cursor.getColumnIndexOrThrow(COL_NAME))
order = cursor.getInt(cursor.getColumnIndexOrThrow(COL_ORDER))
flags = cursor.getInt(cursor.getColumnIndexOrThrow(COL_FLAGS))
}
}
class CategoryDeleteResolver : DefaultDeleteResolver<Category>() {
override fun mapToDeleteQuery(obj: Category) = DeleteQuery.builder()
.table(TABLE)
.where("$COL_ID = ?")
.whereArgs(obj.id)
.build()
}

View File

@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting
import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import java.io.Serializable import java.io.Serializable
import eu.kanade.domain.category.model.Category as DomainCategory
interface Category : Serializable { interface Category : Serializable {
@ -22,16 +23,16 @@ interface Category : Serializable {
} }
var displayMode: Int var displayMode: Int
get() = flags and DisplayModeSetting.MASK get() = flags and DisplayModeSetting.MASK.toInt()
set(mode) = setFlags(mode, DisplayModeSetting.MASK) set(mode) = setFlags(mode, DisplayModeSetting.MASK.toInt())
var sortMode: Int var sortMode: Int
get() = flags and SortModeSetting.MASK get() = flags and SortModeSetting.MASK.toInt()
set(mode) = setFlags(mode, SortModeSetting.MASK) set(mode) = setFlags(mode, SortModeSetting.MASK.toInt())
var sortDirection: Int var sortDirection: Int
get() = flags and SortDirectionSetting.MASK get() = flags and SortDirectionSetting.MASK.toInt()
set(mode) = setFlags(mode, SortDirectionSetting.MASK) set(mode) = setFlags(mode, SortDirectionSetting.MASK.toInt())
companion object { companion object {
@ -42,3 +43,13 @@ interface Category : Serializable {
fun createDefault(context: Context): Category = create(context.getString(R.string.label_default)).apply { id = 0 } fun createDefault(context: Context): Category = create(context.getString(R.string.label_default)).apply { id = 0 }
} }
} }
fun Category.toDomainCategory(): DomainCategory? {
val categoryId = id ?: return null
return DomainCategory(
id = categoryId.toLong(),
name = this.name,
order = this.order.toLong(),
flags = this.flags.toLong(),
)
}

View File

@ -1,5 +1,8 @@
package eu.kanade.tachiyomi.data.database.models package eu.kanade.tachiyomi.data.database.models
import eu.kanade.domain.category.model.Category as DomainCategory
import eu.kanade.domain.manga.model.Manga as DomainManga
class MangaCategory { class MangaCategory {
var id: Long? = null var id: Long? = null
@ -10,6 +13,13 @@ class MangaCategory {
companion object { companion object {
fun create(manga: DomainManga, category: DomainCategory): MangaCategory {
val mc = MangaCategory()
mc.manga_id = manga.id
mc.category_id = category.id.toInt()
return mc
}
fun create(manga: Manga, category: Category): MangaCategory { fun create(manga: Manga, category: Category): MangaCategory {
val mc = MangaCategory() val mc = MangaCategory()
mc.manga_id = manga.id!! mc.manga_id = manga.id!!

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.data.database.queries package eu.kanade.tachiyomi.data.database.queries
import eu.kanade.tachiyomi.data.database.tables.CategoryTable as Category
import eu.kanade.tachiyomi.data.database.tables.ChapterTable as Chapter import eu.kanade.tachiyomi.data.database.tables.ChapterTable as Chapter
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable as MangaCategory import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable as MangaCategory
import eu.kanade.tachiyomi.data.database.tables.MangaTable as Manga import eu.kanade.tachiyomi.data.database.tables.MangaTable as Manga
@ -36,14 +35,3 @@ val libraryQuery =
SELECT * FROM ${MangaCategory.TABLE}) AS MC SELECT * FROM ${MangaCategory.TABLE}) AS MC
ON MC.${MangaCategory.COL_MANGA_ID} = M.${Manga.COL_ID} ON MC.${MangaCategory.COL_MANGA_ID} = M.${Manga.COL_ID}
""" """
/**
* Query to get the categories for a manga.
*/
fun getCategoriesForMangaQuery() =
"""
SELECT ${Category.TABLE}.* FROM ${Category.TABLE}
JOIN ${MangaCategory.TABLE} ON ${Category.TABLE}.${Category.COL_ID} =
${MangaCategory.TABLE}.${MangaCategory.COL_CATEGORY_ID}
WHERE ${MangaCategory.COL_MANGA_ID} = ?
"""

View File

@ -3,12 +3,4 @@ package eu.kanade.tachiyomi.data.database.tables
object CategoryTable { object CategoryTable {
const val TABLE = "categories" const val TABLE = "categories"
const val COL_ID = "_id"
const val COL_NAME = "name"
const val COL_ORDER = "sort"
const val COL_FLAGS = "flags"
} }

View File

@ -8,6 +8,7 @@ import android.os.PowerManager
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import eu.kanade.data.chapter.NoChaptersException import eu.kanade.data.chapter.NoChaptersException
import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
@ -22,7 +23,6 @@ import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
@ -228,7 +228,7 @@ class LibraryUpdateService(
ioScope?.cancel() ioScope?.cancel()
// Update favorite manga // Update favorite manga
val categoryId = intent.getIntExtra(KEY_CATEGORY, -1) val categoryId = intent.getLongExtra(KEY_CATEGORY, -1L)
addMangaToQueue(categoryId) addMangaToQueue(categoryId)
// Destroy service when completed or in case of an error. // Destroy service when completed or in case of an error.
@ -254,11 +254,11 @@ class LibraryUpdateService(
* *
* @param categoryId the ID of the category to update, or -1 if no category specified. * @param categoryId the ID of the category to update, or -1 if no category specified.
*/ */
fun addMangaToQueue(categoryId: Int) { fun addMangaToQueue(categoryId: Long) {
val libraryManga = db.getLibraryMangas().executeAsBlocking() val libraryManga = db.getLibraryMangas().executeAsBlocking()
val listToUpdate = if (categoryId != -1) { val listToUpdate = if (categoryId != -1L) {
libraryManga.filter { it.category == categoryId } libraryManga.filter { it.category.toLong() == categoryId }
} else { } else {
val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt) val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt)
val listToInclude = if (categoriesToUpdate.isNotEmpty()) { val listToInclude = if (categoriesToUpdate.isNotEmpty()) {

View File

@ -9,6 +9,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
@ -149,6 +150,6 @@ class SearchController(
override fun onTitleClick(source: CatalogueSource) { override fun onTitleClick(source: CatalogueSource) {
presenter.preferences.lastUsedSource().set(source.id) presenter.preferences.lastUsedSource().set(source.id)
router.pushController(SourceSearchController(manga, source, presenter.query)) router.pushController(SourceSearchController(manga?.toDomainManga(), source, presenter.query))
} }
} }

View File

@ -2,7 +2,8 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
import eu.kanade.tachiyomi.ui.browse.source.browse.SourceItem import eu.kanade.tachiyomi.ui.browse.source.browse.SourceItem
@ -28,7 +29,7 @@ class SourceSearchController(
newManga = item.manga newManga = item.manga
val searchController = router.backstack.findLast { it.controller.javaClass == SearchController::class.java }?.controller as SearchController? val searchController = router.backstack.findLast { it.controller.javaClass == SearchController::class.java }?.controller as SearchController?
val dialog = val dialog =
SearchController.MigrationDialog(oldManga, newManga, this) SearchController.MigrationDialog(oldManga?.toDbManga(), newManga?.toDbManga(), this)
dialog.targetController = searchController dialog.targetController = searchController
dialog.showDialog(router) dialog.showDialog(router)
return true return true

View File

@ -20,11 +20,11 @@ import com.google.android.material.snackbar.Snackbar
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.domain.category.model.toDbCategory import eu.kanade.domain.category.model.Category
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.source.model.Source import eu.kanade.domain.source.model.Source
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.SourceControllerBinding import eu.kanade.tachiyomi.databinding.SourceControllerBinding
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
@ -541,7 +541,7 @@ open class BrowseSourceController(bundle: Bundle) :
adapter.allBoundViewHolders.forEach { holder -> adapter.allBoundViewHolders.forEach { holder ->
val item = adapter.getItem(holder.bindingAdapterPosition) as? SourceItem val item = adapter.getItem(holder.bindingAdapterPosition) as? SourceItem
if (item != null && item.manga.id!! == manga.id!!) { if (item != null && item.manga.id == manga.id) {
return holder as SourceHolder<*> return holder as SourceHolder<*>
} }
} }
@ -575,7 +575,7 @@ open class BrowseSourceController(bundle: Bundle) :
*/ */
override fun onItemClick(view: View, position: Int): Boolean { override fun onItemClick(view: View, position: Int): Boolean {
val item = adapter?.getItem(position) as? SourceItem ?: return false val item = adapter?.getItem(position) as? SourceItem ?: return false
router.pushController(MangaController(item.manga.id!!, true)) router.pushController(MangaController(item.manga.id, true))
return false return false
} }
@ -602,7 +602,7 @@ open class BrowseSourceController(bundle: Bundle) :
.setItems(arrayOf(activity.getString(R.string.remove_from_library))) { _, which -> .setItems(arrayOf(activity.getString(R.string.remove_from_library))) { _, which ->
when (which) { when (which) {
0 -> { 0 -> {
presenter.changeMangaFavorite(manga) presenter.changeMangaFavorite(manga.toDbManga())
adapter?.notifyItemChanged(position) adapter?.notifyItemChanged(position)
activity.toast(activity.getString(R.string.manga_removed_library)) activity.toast(activity.getString(R.string.manga_removed_library))
} }
@ -637,18 +637,18 @@ open class BrowseSourceController(bundle: Bundle) :
when { when {
// Default category set // Default category set
defaultCategory != null -> { defaultCategory != null -> {
presenter.moveMangaToCategory(newManga, defaultCategory.toDbCategory()) presenter.moveMangaToCategory(newManga.toDbManga(), defaultCategory)
presenter.changeMangaFavorite(newManga) presenter.changeMangaFavorite(newManga.toDbManga())
adapter?.notifyItemChanged(position) adapter?.notifyItemChanged(position)
activity.toast(activity.getString(R.string.manga_added_library)) activity.toast(activity.getString(R.string.manga_added_library))
} }
// Automatic 'Default' or no categories // Automatic 'Default' or no categories
defaultCategoryId == 0 || categories.isEmpty() -> { defaultCategoryId == 0 || categories.isEmpty() -> {
presenter.moveMangaToCategory(newManga, null) presenter.moveMangaToCategory(newManga.toDbManga(), null)
presenter.changeMangaFavorite(newManga) presenter.changeMangaFavorite(newManga.toDbManga())
adapter?.notifyItemChanged(position) adapter?.notifyItemChanged(position)
activity.toast(activity.getString(R.string.manga_added_library)) activity.toast(activity.getString(R.string.manga_added_library))
} }
@ -664,7 +664,7 @@ open class BrowseSourceController(bundle: Bundle) :
} }
}.toTypedArray() }.toTypedArray()
ChangeMangaCategoriesDialog(this@BrowseSourceController, listOf(newManga), categories.map { it.toDbCategory() }, preselected) ChangeMangaCategoriesDialog(this@BrowseSourceController, listOf(newManga), categories, preselected)
.showDialog(router) .showDialog(router)
} }
} }
@ -681,8 +681,8 @@ open class BrowseSourceController(bundle: Bundle) :
override fun updateCategoriesForMangas(mangas: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) { override fun updateCategoriesForMangas(mangas: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) {
val manga = mangas.firstOrNull() ?: return val manga = mangas.firstOrNull() ?: return
presenter.changeMangaFavorite(manga) presenter.changeMangaFavorite(manga.toDbManga())
presenter.updateMangaCategories(manga, addCategories) presenter.updateMangaCategories(manga.toDbManga(), addCategories)
val position = adapter?.currentItems?.indexOfFirst { it -> (it as SourceItem).manga.id == manga.id } val position = adapter?.currentItems?.indexOfFirst { it -> (it as SourceItem).manga.id == manga.id }
if (position != null) { if (position != null) {

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
import android.os.Bundle import android.os.Bundle
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.model.toDbCategory
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
@ -11,9 +12,9 @@ import eu.kanade.domain.track.interactor.InsertTrack
import eu.kanade.domain.track.model.toDomainTrack import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.database.models.toMangaInfo import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService import eu.kanade.tachiyomi.data.track.EnhancedTrackService
@ -52,6 +53,7 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
import logcat.LogPriority import logcat.LogPriority
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
@ -60,6 +62,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date import java.util.Date
import eu.kanade.domain.category.model.Category as DomainCategory import eu.kanade.domain.category.model.Category as DomainCategory
import eu.kanade.domain.manga.model.Manga as DomainManga
open class BrowseSourcePresenter( open class BrowseSourcePresenter(
private val sourceId: Long, private val sourceId: Long,
@ -157,7 +160,7 @@ open class BrowseSourcePresenter(
pagerSubscription?.let { remove(it) } pagerSubscription?.let { remove(it) }
pagerSubscription = pager.results() pagerSubscription = pager.results()
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.map { (first, second) -> first to second.map { networkToLocalManga(it, sourceId) } } .map { (first, second) -> first to second.map { networkToLocalManga(it, sourceId).toDomainManga()!! } }
.doOnNext { initializeMangas(it.second) } .doOnNext { initializeMangas(it.second) }
.map { (first, second) -> first to second.map { SourceItem(it, sourceDisplayMode) } } .map { (first, second) -> first to second.map { SourceItem(it, sourceDisplayMode) } }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
@ -225,15 +228,15 @@ open class BrowseSourcePresenter(
* *
* @param mangas the list of manga to initialize. * @param mangas the list of manga to initialize.
*/ */
fun initializeMangas(mangas: List<Manga>) { fun initializeMangas(mangas: List<DomainManga>) {
presenterScope.launchIO { presenterScope.launchIO {
mangas.asFlow() mangas.asFlow()
.filter { it.thumbnail_url == null && !it.initialized } .filter { it.thumbnailUrl == null && !it.initialized }
.map { getMangaDetails(it) } .map { getMangaDetails(it.toDbManga()) }
.onEach { .onEach {
withUIContext { withUIContext {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
view?.onMangaInitialized(it) view?.onMangaInitialized(it.toDomainManga()!!)
} }
} }
.catch { e -> logcat(LogPriority.ERROR, e) } .catch { e -> logcat(LogPriority.ERROR, e) }
@ -362,8 +365,8 @@ open class BrowseSourcePresenter(
return getCategories.subscribe().firstOrNull() ?: emptyList() return getCategories.subscribe().firstOrNull() ?: emptyList()
} }
suspend fun getDuplicateLibraryManga(manga: Manga): Manga? { suspend fun getDuplicateLibraryManga(manga: DomainManga): DomainManga? {
return getDuplicateLibraryManga.await(manga.title, manga.source)?.toDbManga() return getDuplicateLibraryManga.await(manga.title, manga.source)
} }
/** /**
@ -372,9 +375,10 @@ open class BrowseSourcePresenter(
* @param manga the manga to get categories from. * @param manga the manga to get categories from.
* @return Array of category ids the manga is in, if none returns default id * @return Array of category ids the manga is in, if none returns default id
*/ */
suspend fun getMangaCategoryIds(manga: Manga): Array<Long?> { fun getMangaCategoryIds(manga: DomainManga): Array<Long?> {
val categories = getCategories.await(manga.id!!) return runBlocking { getCategories.await(manga.id) }
return categories.map { it.id }.toTypedArray() .map { it.id }
.toTypedArray()
} }
/** /**
@ -383,8 +387,8 @@ open class BrowseSourcePresenter(
* @param categories the selected categories. * @param categories the selected categories.
* @param manga the manga to move. * @param manga the manga to move.
*/ */
private fun moveMangaToCategories(manga: Manga, categories: List<Category>) { private fun moveMangaToCategories(manga: Manga, categories: List<DomainCategory>) {
val mc = categories.filter { it.id != 0 }.map { MangaCategory.create(manga, it) } val mc = categories.filter { it.id != 0L }.map { MangaCategory.create(manga, it.toDbCategory()) }
db.setMangaCategories(mc, listOf(manga)) db.setMangaCategories(mc, listOf(manga))
} }
@ -394,7 +398,7 @@ open class BrowseSourcePresenter(
* @param category the selected category. * @param category the selected category.
* @param manga the manga to move. * @param manga the manga to move.
*/ */
fun moveMangaToCategory(manga: Manga, category: Category?) { fun moveMangaToCategory(manga: Manga, category: DomainCategory?) {
moveMangaToCategories(manga, listOfNotNull(category)) moveMangaToCategories(manga, listOfNotNull(category))
} }
@ -404,7 +408,7 @@ open class BrowseSourcePresenter(
* @param manga needed to change * @param manga needed to change
* @param selectedCategories selected categories * @param selectedCategories selected categories
*/ */
fun updateMangaCategories(manga: Manga, selectedCategories: List<Category>) { fun updateMangaCategories(manga: Manga, selectedCategories: List<DomainCategory>) {
if (!manga.favorite) { if (!manga.favorite) {
changeMangaFavorite(manga) changeMangaFavorite(manga)
} }

View File

@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
import androidx.core.view.isVisible import androidx.core.view.isVisible
import coil.dispose import coil.dispose
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.util.view.loadAutoPause import eu.kanade.tachiyomi.util.view.loadAutoPause

View File

@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
import androidx.core.view.isVisible import androidx.core.view.isVisible
import coil.dispose import coil.dispose
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.util.view.loadAutoPause import eu.kanade.tachiyomi.util.view.loadAutoPause

View File

@ -4,7 +4,7 @@ import android.view.View
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.domain.manga.model.Manga
/** /**
* Generic class used to hold the displayed data of a manga in the catalogue. * Generic class used to hold the displayed data of a manga in the catalogue.

View File

@ -6,8 +6,8 @@ import com.fredporciuncula.flow.preferences.Preference
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting

View File

@ -5,9 +5,9 @@ import androidx.core.view.isVisible
import coil.dispose import coil.dispose
import coil.load import coil.load
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.databinding.SourceListItemBinding import eu.kanade.tachiyomi.databinding.SourceListItemBinding
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
@ -51,7 +51,7 @@ class SourceListHolder(private val view: View, adapter: FlexibleAdapter<*>) :
override fun setImage(manga: Manga) { override fun setImage(manga: Manga) {
binding.thumbnail.dispose() binding.thumbnail.dispose()
if (!manga.thumbnail_url.isNullOrEmpty()) { if (!manga.thumbnailUrl.isNullOrEmpty()) {
binding.thumbnail.load(manga) { binding.thumbnail.load(manga) {
setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false)
} }

View File

@ -4,9 +4,9 @@ import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.pushController import eu.kanade.tachiyomi.ui.base.controller.pushController
import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.category.CategoryController

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.library
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.domain.category.model.Category
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
@ -153,7 +153,7 @@ class LibraryAdapter(
override fun getViewType(position: Int): Int { override fun getViewType(position: Int): Int {
val category = categories.getOrNull(position) val category = categories.getOrNull(position)
return if (isPerCategory && category?.id != 0) { return if (isPerCategory && category?.id != 0L) {
if (DisplayModeSetting.fromFlag(category?.displayMode) == DisplayModeSetting.LIST) { if (DisplayModeSetting.fromFlag(category?.displayMode) == DisplayModeSetting.LIST) {
LIST_DISPLAY_MODE LIST_DISPLAY_MODE
} else { } else {

View File

@ -8,8 +8,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
import eu.kanade.domain.category.model.Category
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding

View File

@ -15,9 +15,11 @@ import com.fredporciuncula.flow.preferences.Preference
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.PublishRelay import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.toDbCategory
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.LibraryControllerBinding import eu.kanade.tachiyomi.databinding.LibraryControllerBinding
@ -50,6 +52,7 @@ import rx.android.schedulers.AndroidSchedulers
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
class LibraryController( class LibraryController(
bundle: Bundle? = null, bundle: Bundle? = null,
@ -74,7 +77,7 @@ class LibraryController(
/** /**
* Currently selected mangas. * Currently selected mangas.
*/ */
val selectedMangas = mutableSetOf<Manga>() val selectedMangas = mutableSetOf<DbManga>()
/** /**
* Relay to notify the UI of selection updates. * Relay to notify the UI of selection updates.
@ -94,12 +97,12 @@ class LibraryController(
/** /**
* Relay to notify the library's viewpager to select all manga * Relay to notify the library's viewpager to select all manga
*/ */
val selectAllRelay: PublishRelay<Int> = PublishRelay.create() val selectAllRelay: PublishRelay<Long> = PublishRelay.create()
/** /**
* Relay to notify the library's viewpager to select the inverse * Relay to notify the library's viewpager to select the inverse
*/ */
val selectInverseRelay: PublishRelay<Int> = PublishRelay.create() val selectInverseRelay: PublishRelay<Long> = PublishRelay.create()
/** /**
* Number of manga per row in grid mode. * Number of manga per row in grid mode.
@ -262,14 +265,14 @@ class LibraryController(
fun showSettingsSheet() { fun showSettingsSheet() {
if (adapter?.categories?.isNotEmpty() == true) { if (adapter?.categories?.isNotEmpty() == true) {
adapter?.categories?.get(binding.libraryPager.currentItem)?.let { category -> adapter?.categories?.get(binding.libraryPager.currentItem)?.let { category ->
settingsSheet?.show(category) settingsSheet?.show(category.toDbCategory())
} }
} else { } else {
settingsSheet?.show() settingsSheet?.show()
} }
} }
fun onNextLibraryUpdate(categories: List<Category>, mangaMap: Map<Int, List<LibraryItem>>) { fun onNextLibraryUpdate(categories: List<Category>, mangaMap: LibraryMap) {
val view = view ?: return val view = view ?: return
val adapter = adapter ?: return val adapter = adapter ?: return
@ -344,7 +347,7 @@ class LibraryController(
if (!firstLaunch) { if (!firstLaunch) {
mangaCountVisibilityRelay.call(preferences.categoryNumberOfItems().get()) mangaCountVisibilityRelay.call(preferences.categoryNumberOfItems().get())
} }
tabsVisibilityRelay.call(preferences.categoryTabs().get() && adapter?.categories?.size ?: 0 > 1) tabsVisibilityRelay.call(preferences.categoryTabs().get() && (adapter?.categories?.size ?: 0) > 1)
updateTitle() updateTitle()
} }
@ -493,7 +496,7 @@ class LibraryController(
actionMode = null actionMode = null
} }
fun openManga(manga: Manga) { fun openManga(manga: DbManga) {
// Notify the presenter a manga is being opened. // Notify the presenter a manga is being opened.
presenter.onOpenManga() presenter.onOpenManga()
@ -506,7 +509,7 @@ class LibraryController(
* @param manga the manga whose selection has changed. * @param manga the manga whose selection has changed.
* @param selected whether it's now selected or not. * @param selected whether it's now selected or not.
*/ */
fun setSelection(manga: Manga, selected: Boolean) { fun setSelection(manga: DbManga, selected: Boolean) {
if (selected) { if (selected) {
if (selectedMangas.add(manga)) { if (selectedMangas.add(manga)) {
selectionRelay.call(LibrarySelectionEvent.Selected(manga)) selectionRelay.call(LibrarySelectionEvent.Selected(manga))
@ -523,7 +526,7 @@ class LibraryController(
* *
* @param manga the manga whose selection to change. * @param manga the manga whose selection to change.
*/ */
fun toggleSelection(manga: Manga) { fun toggleSelection(manga: DbManga) {
if (selectedMangas.add(manga)) { if (selectedMangas.add(manga)) {
selectionRelay.call(LibrarySelectionEvent.Selected(manga)) selectionRelay.call(LibrarySelectionEvent.Selected(manga))
} else if (selectedMangas.remove(manga)) { } else if (selectedMangas.remove(manga)) {
@ -550,7 +553,7 @@ class LibraryController(
val mangas = selectedMangas.toList() val mangas = selectedMangas.toList()
// Hide the default category because it has a different behavior than the ones from db. // Hide the default category because it has a different behavior than the ones from db.
val categories = presenter.categories.filter { it.id != 0 } val categories = presenter.categories.filter { it.id != 0L }
// Get indexes of the common categories to preselect. // Get indexes of the common categories to preselect.
val common = presenter.getCommonCategories(mangas) val common = presenter.getCommonCategories(mangas)
@ -564,7 +567,7 @@ class LibraryController(
} }
}.toTypedArray() }.toTypedArray()
launchUI { launchUI {
ChangeMangaCategoriesDialog(this@LibraryController, mangas, categories, preselected) ChangeMangaCategoriesDialog(this@LibraryController, mangas.map { it.toDomainManga()!! }, categories, preselected)
.showDialog(router) .showDialog(router)
} }
} }
@ -591,7 +594,7 @@ class LibraryController(
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
} }
override fun deleteMangas(mangas: List<Manga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) { override fun deleteMangas(mangas: List<DbManga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) {
presenter.removeMangas(mangas, deleteFromLibrary, deleteChapters) presenter.removeMangas(mangas, deleteFromLibrary, deleteChapters)
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
} }

View File

@ -25,7 +25,7 @@ class LibraryItem(
private val sourceManager: SourceManager = Injekt.get() private val sourceManager: SourceManager = Injekt.get()
var displayMode: Int = -1 var displayMode: Long = -1
var downloadCount = -1 var downloadCount = -1
var unreadCount = -1 var unreadCount = -1
var isLocal = false var isLocal = false

View File

@ -1,8 +1,8 @@
package eu.kanade.tachiyomi.ui.library package eu.kanade.tachiyomi.ui.library
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.domain.category.model.Category
class LibraryMangaEvent(val mangas: Map<Int, List<LibraryItem>>) { class LibraryMangaEvent(val mangas: LibraryMap) {
fun getMangaForCategory(category: Category): List<LibraryItem>? { fun getMangaForCategory(category: Category): List<LibraryItem>? {
return mangas[category.id] return mangas[category.id]

View File

@ -6,19 +6,18 @@ import eu.kanade.core.util.asObservable
import eu.kanade.data.DatabaseHandler import eu.kanade.data.DatabaseHandler
import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.interactor.SetMangaCategories import eu.kanade.domain.category.interactor.SetMangaCategories
import eu.kanade.domain.category.model.toDbCategory import eu.kanade.domain.category.model.Category
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId 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.chapter.model.toDbChapter
import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.MangaUpdate import eu.kanade.domain.manga.model.MangaUpdate
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
@ -34,7 +33,6 @@ import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.removeCovers import eu.kanade.tachiyomi.util.removeCovers
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
@ -45,6 +43,7 @@ import uy.kohesive.injekt.api.get
import java.text.Collator import java.text.Collator
import java.util.Collections import java.util.Collections
import java.util.Locale import java.util.Locale
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
/** /**
* Class containing library information. * Class containing library information.
@ -54,7 +53,7 @@ private data class Library(val categories: List<Category>, val mangaMap: Library
/** /**
* Typealias for the library manga, using the category as keys, and list of manga as values. * Typealias for the library manga, using the category as keys, and list of manga as values.
*/ */
private typealias LibraryMap = Map<Int, List<LibraryItem>> typealias LibraryMap = Map<Long, List<LibraryItem>>
/** /**
* Presenter of [LibraryController]. * Presenter of [LibraryController].
@ -299,11 +298,11 @@ class LibraryPresenter(
} }
val sortingModes = categories.associate { category -> val sortingModes = categories.associate { category ->
(category.id ?: 0) to SortModeSetting.get(preferences, category) category.id to SortModeSetting.get(preferences, category)
} }
val sortDirections = categories.associate { category -> val sortDirections = categories.associate { category ->
(category.id ?: 0) to SortDirectionSetting.get(preferences, category) category.id to SortDirectionSetting.get(preferences, category)
} }
val locale = Locale.getDefault() val locale = Locale.getDefault()
@ -311,8 +310,8 @@ class LibraryPresenter(
strength = Collator.PRIMARY strength = Collator.PRIMARY
} }
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
val sortingMode = sortingModes[i1.manga.category]!! val sortingMode = sortingModes[i1.manga.category.toLong()]!!
val sortAscending = sortDirections[i1.manga.category]!! == SortDirectionSetting.ASCENDING val sortAscending = sortDirections[i1.manga.category.toLong()]!! == SortDirectionSetting.ASCENDING
when (sortingMode) { when (sortingMode) {
SortModeSetting.ALPHABETICAL -> { SortModeSetting.ALPHABETICAL -> {
collator.compare(i1.manga.title.lowercase(locale), i2.manga.title.lowercase(locale)) collator.compare(i1.manga.title.lowercase(locale), i2.manga.title.lowercase(locale))
@ -355,7 +354,7 @@ class LibraryPresenter(
} }
return map.mapValues { entry -> return map.mapValues { entry ->
val sortAscending = sortDirections[entry.key]!! == SortDirectionSetting.ASCENDING val sortAscending = sortDirections[entry.key.toLong()]!! == SortDirectionSetting.ASCENDING
val comparator = if (sortAscending) { val comparator = if (sortAscending) {
Comparator(sortFn) Comparator(sortFn)
@ -375,13 +374,13 @@ class LibraryPresenter(
private fun getLibraryObservable(): Observable<Library> { private fun getLibraryObservable(): Observable<Library> {
return Observable.combineLatest(getCategoriesObservable(), getLibraryMangasObservable()) { dbCategories, libraryManga -> return Observable.combineLatest(getCategoriesObservable(), getLibraryMangasObservable()) { dbCategories, libraryManga ->
val categories = if (libraryManga.containsKey(0)) { val categories = if (libraryManga.containsKey(0)) {
arrayListOf(Category.createDefault(context)) + dbCategories arrayListOf(Category.default(context)) + dbCategories
} else { } else {
dbCategories dbCategories
} }
libraryManga.forEach { (categoryId, libraryManga) -> libraryManga.forEach { (categoryId, libraryManga) ->
val category = categories.first { category -> category.id == categoryId } val category = categories.first { category -> category.id == categoryId.toLong() }
libraryManga.forEach { libraryItem -> libraryManga.forEach { libraryItem ->
libraryItem.displayMode = category.displayMode libraryItem.displayMode = category.displayMode
} }
@ -398,7 +397,7 @@ class LibraryPresenter(
* @return an observable of the categories. * @return an observable of the categories.
*/ */
private fun getCategoriesObservable(): Observable<List<Category>> { private fun getCategoriesObservable(): Observable<List<Category>> {
return getCategories.subscribe().map { it.map { it.toDbCategory() } }.asObservable() return getCategories.subscribe().asObservable()
} }
/** /**
@ -448,7 +447,7 @@ class LibraryPresenter(
shouldSetFromCategory, shouldSetFromCategory,
defaultLibraryDisplayMode, defaultLibraryDisplayMode,
) )
}.groupBy { it.manga.category } }.groupBy { it.manga.category.toLong() }
} }
} }
@ -516,10 +515,10 @@ class LibraryPresenter(
* *
* @param mangas the list of manga. * @param mangas the list of manga.
*/ */
suspend fun getCommonCategories(mangas: List<Manga>): Collection<Category> { suspend fun getCommonCategories(mangas: List<DbManga>): Collection<Category> {
if (mangas.isEmpty()) return emptyList() if (mangas.isEmpty()) return emptyList()
return mangas.toSet() return mangas.toSet()
.map { getCategories.await(it.id!!).map { it.toDbCategory() } } .map { getCategories.await(it.id!!) }
.reduce { set1, set2 -> set1.intersect(set2).toMutableList() } .reduce { set1, set2 -> set1.intersect(set2).toMutableList() }
} }
@ -528,9 +527,9 @@ class LibraryPresenter(
* *
* @param mangas the list of manga. * @param mangas the list of manga.
*/ */
suspend fun getMixCategories(mangas: List<Manga>): Collection<Category> { suspend fun getMixCategories(mangas: List<DbManga>): Collection<Category> {
if (mangas.isEmpty()) return emptyList() if (mangas.isEmpty()) return emptyList()
val mangaCategories = mangas.toSet().map { getCategories.await(it.id!!).map { it.toDbCategory() } } val mangaCategories = mangas.toSet().map { getCategories.await(it.id!!) }
val common = mangaCategories.reduce { set1, set2 -> set1.intersect(set2).toMutableList() } val common = mangaCategories.reduce { set1, set2 -> set1.intersect(set2).toMutableList() }
return mangaCategories.flatten().distinct().subtract(common).toMutableList() return mangaCategories.flatten().distinct().subtract(common).toMutableList()
} }
@ -540,7 +539,7 @@ class LibraryPresenter(
* *
* @param mangas the list of manga. * @param mangas the list of manga.
*/ */
fun downloadUnreadChapters(mangas: List<Manga>) { fun downloadUnreadChapters(mangas: List<DbManga>) {
mangas.forEach { manga -> mangas.forEach { manga ->
launchIO { launchIO {
val chapters = getChapterByMangaId.await(manga.id!!) val chapters = getChapterByMangaId.await(manga.id!!)
@ -557,7 +556,7 @@ class LibraryPresenter(
* *
* @param mangas the list of manga. * @param mangas the list of manga.
*/ */
fun markReadStatus(mangas: List<Manga>, read: Boolean) { fun markReadStatus(mangas: List<DbManga>, read: Boolean) {
mangas.forEach { manga -> mangas.forEach { manga ->
launchIO { launchIO {
val chapters = getChapterByMangaId.await(manga.id!!) val chapters = getChapterByMangaId.await(manga.id!!)
@ -579,7 +578,7 @@ class LibraryPresenter(
} }
} }
private fun deleteChapters(manga: Manga, chapters: List<Chapter>) { private fun deleteChapters(manga: DbManga, chapters: List<Chapter>) {
sourceManager.get(manga.source)?.let { source -> sourceManager.get(manga.source)?.let { source ->
downloadManager.deleteChapters(chapters, manga, source) downloadManager.deleteChapters(chapters, manga, source)
} }
@ -592,7 +591,7 @@ class LibraryPresenter(
* @param deleteFromLibrary whether to delete manga from library. * @param deleteFromLibrary whether to delete manga from library.
* @param deleteChapters whether to delete downloaded chapters. * @param deleteChapters whether to delete downloaded chapters.
*/ */
fun removeMangas(mangaList: List<Manga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) { fun removeMangas(mangaList: List<DbManga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) {
launchIO { launchIO {
val mangaToDelete = mangaList.distinctBy { it.id } val mangaToDelete = mangaList.distinctBy { it.id }
@ -628,12 +627,11 @@ class LibraryPresenter(
fun setMangaCategories(mangaList: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) { fun setMangaCategories(mangaList: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) {
presenterScope.launchIO { presenterScope.launchIO {
mangaList.map { manga -> mangaList.map { manga ->
val categoryIds = getCategories.await(manga.id!!) val categoryIds = getCategories.await(manga.id)
.map { it.toDbCategory() }
.subtract(removeCategories) .subtract(removeCategories)
.plus(addCategories) .plus(addCategories)
.mapNotNull { it.id?.toLong() } .map { it.id }
setMangaCategories.await(manga.id!!, categoryIds) setMangaCategories.await(manga.id, categoryIds)
} }
} }
} }

View File

@ -8,6 +8,7 @@ import eu.kanade.domain.category.interactor.UpdateCategory
import eu.kanade.domain.category.model.CategoryUpdate import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.toDomainCategory
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
@ -201,8 +202,8 @@ class LibrarySettingsSheet(
override val footer = null override val footer = null
override fun initModels() { override fun initModels() {
val sorting = SortModeSetting.get(preferences, currentCategory) val sorting = SortModeSetting.get(preferences, currentCategory?.toDomainCategory())
val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) { val order = if (SortDirectionSetting.get(preferences, currentCategory?.toDomainCategory()) == SortDirectionSetting.ASCENDING) {
Item.MultiSort.SORT_ASC Item.MultiSort.SORT_ASC
} else { } else {
Item.MultiSort.SORT_DESC Item.MultiSort.SORT_DESC
@ -243,12 +244,12 @@ class LibrarySettingsSheet(
setSortModePreference(item) setSortModePreference(item)
setSortDirectionPrefernece(item) setSortDirectionPreference(item)
item.group.items.forEach { adapter.notifyItemChanged(it) } item.group.items.forEach { adapter.notifyItemChanged(it) }
} }
private fun setSortDirectionPrefernece(item: Item.MultiStateGroup) { private fun setSortDirectionPreference(item: Item.MultiStateGroup) {
val flag = if (item.state == Item.MultiSort.SORT_ASC) { val flag = if (item.state == Item.MultiSort.SORT_ASC) {
SortDirectionSetting.ASCENDING SortDirectionSetting.ASCENDING
} else { } else {
@ -256,7 +257,7 @@ class LibrarySettingsSheet(
} }
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
currentCategory?.sortDirection = flag.flag currentCategory?.sortDirection = flag.flag.toInt()
sheetScope.launchIO { sheetScope.launchIO {
updateCategory.await( updateCategory.await(
CategoryUpdate( CategoryUpdate(
@ -284,7 +285,7 @@ class LibrarySettingsSheet(
} }
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
currentCategory?.sortMode = flag.flag currentCategory?.sortMode = flag.flag.toInt()
sheetScope.launchIO { sheetScope.launchIO {
updateCategory.await( updateCategory.await(
CategoryUpdate( CategoryUpdate(
@ -327,7 +328,7 @@ class LibrarySettingsSheet(
// Gets user preference of currently selected display mode at current category // Gets user preference of currently selected display mode at current category
private fun getDisplayModePreference(): DisplayModeSetting { private fun getDisplayModePreference(): DisplayModeSetting {
return if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { return if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
DisplayModeSetting.fromFlag(currentCategory?.displayMode) DisplayModeSetting.fromFlag(currentCategory?.displayMode?.toLong())
} else { } else {
preferences.libraryDisplayMode().get() preferences.libraryDisplayMode().get()
} }
@ -379,7 +380,7 @@ class LibrarySettingsSheet(
} }
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
currentCategory?.displayMode = flag.flag currentCategory?.displayMode = flag.flag.toInt()
sheetScope.launchIO { sheetScope.launchIO {
updateCategory.await( updateCategory.await(
CategoryUpdate( CategoryUpdate(

View File

@ -1,15 +1,15 @@
package eu.kanade.tachiyomi.ui.library.setting package eu.kanade.tachiyomi.ui.library.setting
enum class DisplayModeSetting(val flag: Int) { enum class DisplayModeSetting(val flag: Long) {
COMPACT_GRID(0b00000000), COMPACT_GRID(0b00000000),
COMFORTABLE_GRID(0b00000001), COMFORTABLE_GRID(0b00000001),
LIST(0b00000010), LIST(0b00000010),
COVER_ONLY_GRID(0b00000011); COVER_ONLY_GRID(0b00000011);
companion object { companion object {
const val MASK = 0b00000011 const val MASK = 0b00000011L
fun fromFlag(flag: Int?): DisplayModeSetting { fun fromFlag(flag: Long?): DisplayModeSetting {
return values() return values()
.find { mode -> mode.flag == flag } ?: COMPACT_GRID .find { mode -> mode.flag == flag } ?: COMPACT_GRID
} }

View File

@ -1,21 +1,21 @@
package eu.kanade.tachiyomi.ui.library.setting package eu.kanade.tachiyomi.ui.library.setting
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.domain.category.model.Category
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
enum class SortDirectionSetting(val flag: Int) { enum class SortDirectionSetting(val flag: Long) {
ASCENDING(0b01000000), ASCENDING(0b01000000),
DESCENDING(0b00000000); DESCENDING(0b00000000);
companion object { companion object {
const val MASK = 0b01000000 const val MASK = 0b01000000L
fun fromFlag(flag: Int?): SortDirectionSetting { fun fromFlag(flag: Long?): SortDirectionSetting {
return values().find { mode -> mode.flag == flag } ?: ASCENDING return values().find { mode -> mode.flag == flag } ?: ASCENDING
} }
fun get(preferences: PreferencesHelper, category: Category?): SortDirectionSetting { fun get(preferences: PreferencesHelper, category: Category?): SortDirectionSetting {
return if (preferences.categorizedDisplaySettings().get() && category != null && category.id != 0) { return if (preferences.categorizedDisplaySettings().get() && category != null && category.id != 0L) {
fromFlag(category.sortDirection) fromFlag(category.sortDirection)
} else { } else {
preferences.librarySortingAscending().get() preferences.librarySortingAscending().get()

View File

@ -1,9 +1,9 @@
package eu.kanade.tachiyomi.ui.library.setting package eu.kanade.tachiyomi.ui.library.setting
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.domain.category.model.Category
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
enum class SortModeSetting(val flag: Int) { enum class SortModeSetting(val flag: Long) {
ALPHABETICAL(0b00000000), ALPHABETICAL(0b00000000),
LAST_READ(0b00000100), LAST_READ(0b00000100),
LAST_MANGA_UPDATE(0b00001000), LAST_MANGA_UPDATE(0b00001000),
@ -25,14 +25,14 @@ enum class SortModeSetting(val flag: Int) {
companion object { companion object {
// Mask supports for more sorting flags if necessary // Mask supports for more sorting flags if necessary
const val MASK = 0b00111100 const val MASK = 0b00111100L
fun fromFlag(flag: Int?): SortModeSetting { fun fromFlag(flag: Long?): SortModeSetting {
return values().find { mode -> mode.flag == flag } ?: ALPHABETICAL return values().find { mode -> mode.flag == flag } ?: ALPHABETICAL
} }
fun get(preferences: PreferencesHelper, category: Category?): SortModeSetting { fun get(preferences: PreferencesHelper, category: Category?): SortModeSetting {
return if (preferences.categorizedDisplaySettings().get() && category != null && category.id != 0) { return if (preferences.categorizedDisplaySettings().get() && category != null && category.id != 0L) {
fromFlag(category.sortMode) fromFlag(category.sortMode)
} else { } else {
preferences.librarySortingMode().get() preferences.librarySortingMode().get()

View File

@ -4,8 +4,8 @@ import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.pushController import eu.kanade.tachiyomi.ui.base.controller.pushController

View File

@ -24,14 +24,14 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.data.chapter.NoChaptersException import eu.kanade.data.chapter.NoChaptersException
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toDbManga import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.presentation.manga.ChapterDownloadAction import eu.kanade.presentation.manga.ChapterDownloadAction
import eu.kanade.presentation.manga.DownloadAction import eu.kanade.presentation.manga.DownloadAction
import eu.kanade.presentation.manga.MangaScreen import eu.kanade.presentation.manga.MangaScreen
import eu.kanade.presentation.util.calculateWindowWidthSizeClass import eu.kanade.presentation.util.calculateWindowWidthSizeClass
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
@ -59,7 +59,7 @@ import eu.kanade.tachiyomi.ui.recent.history.HistoryController
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
import eu.kanade.tachiyomi.ui.webview.WebViewActivity import eu.kanade.tachiyomi.ui.webview.WebViewActivity
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.withUIContext
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
@ -211,7 +211,7 @@ class MangaController :
{ {
AddDuplicateMangaDialog( AddDuplicateMangaDialog(
target = this, target = this,
libraryManga = it.toDbManga(), libraryManga = it,
onAddToLibrary = { onFavoriteClick(checkDuplicate = false) }, onAddToLibrary = { onFavoriteClick(checkDuplicate = false) },
).showDialog(router) ).showDialog(router)
} }
@ -225,7 +225,7 @@ class MangaController :
QuadStateTextView.State.UNCHECKED.ordinal QuadStateTextView.State.UNCHECKED.ordinal
} }
}.toTypedArray() }.toTypedArray()
showChangeCategoryDialog(manga.toDbManga(), categories, preselected) showChangeCategoryDialog(manga, categories, preselected)
}, },
) )
} }
@ -246,10 +246,6 @@ class MangaController :
} }
} }
fun onTrackingClick() {
trackSheet.show()
}
private fun onCategoriesClick() { private fun onCategoriesClick() {
viewScope.launchIO { viewScope.launchIO {
val manga = presenter.manga ?: return@launchIO val manga = presenter.manga ?: return@launchIO
@ -263,8 +259,9 @@ class MangaController :
QuadStateTextView.State.UNCHECKED.ordinal QuadStateTextView.State.UNCHECKED.ordinal
} }
}.toTypedArray() }.toTypedArray()
launchUI {
showChangeCategoryDialog(manga.toDbManga(), categories, preselected) withUIContext {
showChangeCategoryDialog(manga, categories, preselected)
} }
} }
} }

View File

@ -4,7 +4,7 @@ import android.os.Bundle
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.interactor.SetMangaCategories import eu.kanade.domain.category.interactor.SetMangaCategories
import eu.kanade.domain.category.model.toDbCategory import eu.kanade.domain.category.model.Category
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.interactor.UpdateChapter
@ -23,9 +23,7 @@ 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
import eu.kanade.domain.track.model.toDomainTrack import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.database.models.Category
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.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.database.models.toDomainChapter import eu.kanade.tachiyomi.data.database.models.toDomainChapter
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
@ -258,22 +256,22 @@ class MangaPresenter(
// Now check if user previously set categories, when available // Now check if user previously set categories, when available
val categories = getCategories() val categories = getCategories()
val defaultCategoryId = preferences.defaultCategory() val defaultCategoryId = preferences.defaultCategory().toLong()
val defaultCategory = categories.find { it.id == defaultCategoryId } val defaultCategory = categories.find { it.id == defaultCategoryId }
when { when {
// Default category set // Default category set
defaultCategory != null -> { defaultCategory != null -> {
val result = updateManga.awaitUpdateFavorite(manga.id, true) val result = updateManga.awaitUpdateFavorite(manga.id, true)
if (!result) return@launchIO if (!result) return@launchIO
moveMangaToCategory(manga.toDbManga(), defaultCategory) moveMangaToCategory(defaultCategory)
launchUI { onAdded() } launchUI { onAdded() }
} }
// Automatic 'Default' or no categories // Automatic 'Default' or no categories
defaultCategoryId == 0 || categories.isEmpty() -> { defaultCategoryId == 0L || categories.isEmpty() -> {
val result = updateManga.awaitUpdateFavorite(manga.id, true) val result = updateManga.awaitUpdateFavorite(manga.id, true)
if (!result) return@launchIO if (!result) return@launchIO
moveMangaToCategory(manga.toDbManga(), null) moveMangaToCategory(null)
launchUI { onAdded() } launchUI { onAdded() }
} }
@ -326,7 +324,7 @@ class MangaPresenter(
* @return List of categories, not including the default category * @return List of categories, not including the default category
*/ */
suspend fun getCategories(): List<Category> { suspend fun getCategories(): List<Category> {
return getCategories.await().map { it.toDbCategory() } return getCategories.await()
} }
/** /**
@ -335,15 +333,15 @@ class MangaPresenter(
* @param manga the manga to get categories from. * @param manga the manga to get categories from.
* @return Array of category ids the manga is in, if none returns default id * @return Array of category ids the manga is in, if none returns default id
*/ */
fun getMangaCategoryIds(manga: DomainManga): Array<Int> { fun getMangaCategoryIds(manga: DomainManga): Array<Long> {
val categories = runBlocking { getCategories.await(manga.id) } val categories = runBlocking { getCategories.await(manga.id) }
return categories.map { it.id.toInt() }.toTypedArray() return categories.map { it.id }.toTypedArray()
} }
fun moveMangaToCategoriesAndAddToLibrary(manga: Manga, categories: List<Category>) { fun moveMangaToCategoriesAndAddToLibrary(manga: DomainManga, categories: List<Category>) {
moveMangaToCategories(manga, categories) moveMangaToCategories(categories)
presenterScope.launchIO { presenterScope.launchIO {
updateManga.awaitUpdateFavorite(manga.id!!, true) updateManga.awaitUpdateFavorite(manga.id, true)
} }
} }
@ -353,9 +351,8 @@ class MangaPresenter(
* @param manga the manga to move. * @param manga the manga to move.
* @param categories the selected categories. * @param categories the selected categories.
*/ */
private fun moveMangaToCategories(manga: Manga, categories: List<Category>) { private fun moveMangaToCategories(categories: List<Category>) {
val mangaId = manga.id ?: return val categoryIds = categories.map { it.id }
val categoryIds = categories.mapNotNull { it.id?.toLong() }
presenterScope.launchIO { presenterScope.launchIO {
setMangaCategories.await(mangaId, categoryIds) setMangaCategories.await(mangaId, categoryIds)
} }
@ -367,8 +364,8 @@ class MangaPresenter(
* @param manga the manga to move. * @param manga the manga to move.
* @param category the selected category, or null for default category. * @param category the selected category, or null for default category.
*/ */
private fun moveMangaToCategory(manga: Manga, category: Category?) { private fun moveMangaToCategory(category: Category?) {
moveMangaToCategories(manga, listOfNotNull(category)) moveMangaToCategories(listOfNotNull(category))
} }
private fun observeTrackingCount() { private fun observeTrackingCount() {