Migrate to more use of domain models

(cherry picked from commit 76c0ead1db3a93f859f00ce6bff69f38b8699bd6)

# Conflicts:
#	app/src/main/java/eu/kanade/domain/manga/model/Manga.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/CategoryTypeMapping.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaCategory.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/tables/CategoryTable.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceCompactGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
This commit is contained in:
arkon 2022-07-02 17:14:19 -04:00 committed by Jobobby04
parent cd2f26a7c9
commit 9205b568e8
32 changed files with 238 additions and 208 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
@ -15,6 +18,15 @@ data class Category(
// SY <-- // SY <--
) : 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(
@ -22,7 +34,7 @@ data class Category(
name = context.getString(R.string.default_category), name = context.getString(R.string.default_category),
order = 0, order = 0,
flags = 0, flags = 0,
mangaOrder = emptyList() mangaOrder = emptyList(),
) )
} }
} }

View File

@ -11,6 +11,7 @@ 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 uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
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(
@ -36,7 +37,7 @@ data class Manga(
// SY --> // SY -->
val filteredScanlators: List<String>?, val filteredScanlators: List<String>?,
// SY <-- // SY <--
) { ) : Serializable {
// SY --> // SY -->
private val customMangaInfo = if (favorite) { private val customMangaInfo = if (favorite) {

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 {
@ -26,16 +27,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 {
@ -46,3 +47,14 @@ 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(),
mangaOrder = mangaOrder,
)
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.data.database.models package eu.kanade.tachiyomi.data.database.models
import data.GetCategories import eu.kanade.domain.category.model.Category as DomainCategory
import eu.kanade.domain.manga.model.Manga as DomainManga
class MangaCategory { class MangaCategory {
@ -12,18 +13,18 @@ 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!!
mc.category_id = category.id!! mc.category_id = category.id!!
return mc return mc
} }
fun create(manga: Manga, category: GetCategories): MangaCategory {
val mc = MangaCategory()
mc.manga_id = manga.id!!
mc.category_id = category.id.toInt()
return mc
}
} }
} }

View File

@ -150,7 +150,6 @@ fun getHistoryByMangaId() =
ON ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID} ON ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
WHERE ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = ? AND ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID} WHERE ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = ? AND ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
""" """
// SY <--
/** /**
* Query to get the categories for a manga. * Query to get the categories for a manga.
@ -162,3 +161,5 @@ fun getCategoriesForMangaQuery() =
${MangaCategory.TABLE}.${MangaCategory.COL_CATEGORY_ID} ${MangaCategory.TABLE}.${MangaCategory.COL_CATEGORY_ID}
WHERE ${MangaCategory.COL_MANGA_ID} = ? WHERE ${MangaCategory.COL_MANGA_ID} = ?
""" """
// SY <--

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
@ -23,7 +24,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
@ -262,7 +262,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, -1)
val group = intent.getIntExtra(KEY_GROUP, LibraryGroup.BY_DEFAULT) val group = intent.getIntExtra(KEY_GROUP, LibraryGroup.BY_DEFAULT)
val groupExtra = intent.getStringExtra(KEY_GROUP_EXTRA) val groupExtra = intent.getStringExtra(KEY_GROUP_EXTRA)
addMangaToQueue(categoryId, group, groupExtra) addMangaToQueue(categoryId, group, groupExtra)
@ -294,14 +294,14 @@ 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, group: Int, groupExtra: String?) { fun addMangaToQueue(categoryId: Long, group: Int, groupExtra: String?) {
val libraryManga = db.getLibraryMangas().executeAsBlocking() val libraryManga = db.getLibraryMangas().executeAsBlocking()
// SY --> // SY -->
val groupLibraryUpdateType = preferences.groupLibraryUpdateType().get() val groupLibraryUpdateType = preferences.groupLibraryUpdateType().get()
// SY <-- // SY <--
val listToUpdate = if (categoryId != -1) { val listToUpdate = if (categoryId != -1L) {
libraryManga.filter { it.category == categoryId } libraryManga.filter { it.category.toLong() == categoryId }
// SY --> // SY -->
} else if ( } else if (
group == LibraryGroup.BY_DEFAULT || group == LibraryGroup.BY_DEFAULT ||

View File

@ -3,6 +3,7 @@ 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 androidx.core.os.bundleOf import androidx.core.os.bundleOf
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
@ -31,7 +32,7 @@ class SourceSearchController(
val migrationListController = targetController as? MigrationListController ?: return false val migrationListController = targetController as? MigrationListController ?: return false
val sourceManager = Injekt.get<SourceManager>() val sourceManager = Injekt.get<SourceManager>()
val source = sourceManager.get(manga.source) ?: return false val source = sourceManager.get(manga.source) ?: return false
migrationListController.useMangaForMigration(manga, source) migrationListController.useMangaForMigration(manga.toDbManga(), source)
router.popCurrentController() router.popCurrentController()
router.popCurrentController() router.popCurrentController()
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
@ -724,7 +724,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<*>
} }
} }
@ -760,7 +760,7 @@ open class BrowseSourceController(bundle: Bundle) :
val item = adapter?.getItem(position) as? SourceItem ?: return false val item = adapter?.getItem(position) as? SourceItem ?: return false
router.pushController( router.pushController(
MangaController( MangaController(
item.manga.id!!, item.manga.id,
true, true,
args.getParcelable(MangaController.SMART_SEARCH_CONFIG_EXTRA), args.getParcelable(MangaController.SMART_SEARCH_CONFIG_EXTRA),
), ),
@ -790,7 +790,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))
} }
@ -825,18 +825,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))
} }
@ -852,7 +852,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)
} }
} }
@ -869,8 +869,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

@ -5,6 +5,7 @@ import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.data.DatabaseHandler import eu.kanade.data.DatabaseHandler
import eu.kanade.data.exh.savedSearchMapper import eu.kanade.data.exh.savedSearchMapper
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
@ -13,9 +14,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
@ -77,6 +78,7 @@ import uy.kohesive.injekt.api.get
import xyz.nulldev.ts.api.http.serializer.FilterSerializer import xyz.nulldev.ts.api.http.serializer.FilterSerializer
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,
@ -220,7 +222,7 @@ open class BrowseSourcePresenter(
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
// SY --> // SY -->
.map { (page, mangas, metadata) -> .map { (page, mangas, metadata) ->
Triple(page, mangas.map { networkToLocalManga(it, sourceId) }, metadata) Triple(page, mangas.map { networkToLocalManga(it, sourceId).toDomainManga()!! }, metadata)
} }
// SY <-- // SY <--
.doOnNext { initializeMangas(it.second) } .doOnNext { initializeMangas(it.second) }
@ -296,15 +298,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) }
@ -451,8 +453,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)
} }
/** /**
@ -461,9 +463,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()
} }
/** /**
@ -472,8 +475,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))
} }
@ -483,7 +486,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))
} }
@ -493,7 +496,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,9 +3,9 @@ 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.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.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.util.view.loadAutoPause import eu.kanade.tachiyomi.util.view.loadAutoPause
import exh.metadata.metadata.MangaDexSearchMetadata import exh.metadata.metadata.MangaDexSearchMetadata

View File

@ -3,9 +3,9 @@ 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.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.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.util.view.loadAutoPause import eu.kanade.tachiyomi.util.view.loadAutoPause
import exh.metadata.metadata.MangaDexSearchMetadata import exh.metadata.metadata.MangaDexSearchMetadata

View File

@ -4,9 +4,9 @@ import android.view.View
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.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.SourceEnhancedEhentaiListItemBinding import eu.kanade.tachiyomi.databinding.SourceEnhancedEhentaiListItemBinding
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
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
import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata
/** /**

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.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding

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
import exh.metadata.metadata.MangaDexSearchMetadata import exh.metadata.metadata.MangaDexSearchMetadata
@ -68,7 +68,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

@ -10,10 +10,10 @@ 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.interactor.UpdateCategory import eu.kanade.domain.category.interactor.UpdateCategory
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.CategoryUpdate import eu.kanade.domain.category.model.CategoryUpdate
import eu.kanade.domain.category.model.toDbCategory
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
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.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferenceValues
@ -60,8 +60,6 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
private val preferences: PreferencesHelper by injectLazy() private val preferences: PreferencesHelper by injectLazy()
private val db: DatabaseHelper by injectLazy()
/** /**
* The fragment containing this view. * The fragment containing this view.
*/ */
@ -264,20 +262,21 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
// SY --> // SY -->
adapter.isLongPressDragEnabled = adapter.canDrag() adapter.isLongPressDragEnabled = adapter.canDrag()
var mangaForCategory = event.getMangaForCategory(category).orEmpty() var mangaForCategory = event.getMangaForCategory(category).orEmpty()
if (preferences.categorizedDisplaySettings().get() && category.id != 0) { var mangaOrder = category.mangaOrder
if (preferences.categorizedDisplaySettings().get() && category.id != 0L) {
if (SortModeSetting.fromFlag(category.sortMode) == SortModeSetting.DRAG_AND_DROP) { if (SortModeSetting.fromFlag(category.sortMode) == SortModeSetting.DRAG_AND_DROP) {
mangaForCategory = mangaForCategory.sortedBy { mangaForCategory = mangaForCategory.sortedBy {
category.mangaOrder.indexOf(it.manga.id) mangaOrder.indexOf(it.manga.id)
} }
} }
} else if (preferences.librarySortingMode().get() == SortModeSetting.DRAG_AND_DROP) { } else if (preferences.librarySortingMode().get() == SortModeSetting.DRAG_AND_DROP) {
if (category.id == 0) { if (category.id == 0L) {
category.mangaOrder = preferences.defaultMangaOrder().get() mangaOrder = preferences.defaultMangaOrder().get()
.split("/") .split("/")
.mapNotNull { it.toLongOrNull() } .mapNotNull { it.toLongOrNull() }
} }
mangaForCategory = mangaForCategory.sortedBy { mangaForCategory = mangaForCategory.sortedBy {
category.mangaOrder.indexOf(it.manga.id) mangaOrder.indexOf(it.manga.id)
} }
} }
// SY <-- // SY <--
@ -433,23 +432,23 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
if (fromPosition == toPosition) return if (fromPosition == toPosition) return
controller.invalidateActionMode() controller.invalidateActionMode()
val mangaIds = adapter.currentItems.mapNotNull { it.manga.id } val mangaIds = adapter.currentItems.mapNotNull { it.manga.id }
category.mangaOrder = mangaIds if (category.id == 0L) {
if (category.id == 0) {
preferences.defaultMangaOrder().set(mangaIds.joinToString("/")) preferences.defaultMangaOrder().set(mangaIds.joinToString("/"))
} else { } else {
scope.launch { scope.launch {
updateCategory.await(CategoryUpdate(category.id!!.toLong(), mangaOrder = mangaIds)) updateCategory.await(CategoryUpdate(category.id.toLong(), mangaOrder = mangaIds))
} }
} }
if (preferences.categorizedDisplaySettings().get() && category.id != 0) { if (preferences.categorizedDisplaySettings().get() && category.id != 0L) {
if (SortModeSetting.fromFlag(category.sortMode) != SortModeSetting.DRAG_AND_DROP) { if (SortModeSetting.fromFlag(category.sortMode) != SortModeSetting.DRAG_AND_DROP) {
category.sortMode = SortModeSetting.DRAG_AND_DROP.flag val dbCategory = category.toDbCategory()
category.sortDirection = SortDirectionSetting.ASCENDING.flag dbCategory.sortMode = SortModeSetting.DRAG_AND_DROP.flag.toInt()
dbCategory.sortDirection = SortDirectionSetting.ASCENDING.flag.toInt()
scope.launch { scope.launch {
updateCategory.await( updateCategory.await(
CategoryUpdate( CategoryUpdate(
id = category.id!!.toLong(), id = category.id,
flags = category.flags.toLong(), flags = dbCategory.flags.toLong(),
mangaOrder = mangaIds, mangaOrder = mangaIds,
), ),
) )

View File

@ -6,6 +6,7 @@ import coil.dispose
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.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.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.util.view.loadAutoPause import eu.kanade.tachiyomi.util.view.loadAutoPause
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -85,7 +86,7 @@ class LibraryComfortableGridHolder(
// SY --> // SY -->
private fun playButtonClicked() { private fun playButtonClicked() {
if (adapter !is LibraryCategoryAdapter) return if (adapter !is LibraryCategoryAdapter) return
adapter.controller.startReading(manga ?: return, adapter) adapter.controller.startReading(manga?.toDomainManga() ?: return, adapter)
} }
// SY <-- // SY <--
} }

View File

@ -6,6 +6,7 @@ import androidx.core.view.updateLayoutParams
import coil.dispose import coil.dispose
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
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.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.util.view.loadAutoPause import eu.kanade.tachiyomi.util.view.loadAutoPause
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -117,7 +118,7 @@ class LibraryCompactGridHolder(
// SY --> // SY -->
private fun playButtonClicked() { private fun playButtonClicked() {
if (adapter !is LibraryCategoryAdapter) return if (adapter !is LibraryCategoryAdapter) return
adapter.controller.startReading(manga ?: return, adapter) adapter.controller.startReading(manga?.toDomainManga() ?: return, adapter)
} }
// SY <-- // SY <--
} }

View File

@ -19,9 +19,12 @@ 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.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.category.model.toDbCategory
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toDbManga
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.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
@ -72,6 +75,7 @@ import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
class LibraryController( class LibraryController(
bundle: Bundle? = null, bundle: Bundle? = null,
@ -97,7 +101,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.
@ -117,12 +121,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.
@ -303,14 +307,14 @@ class LibraryController(
fun showSettingsSheet() { fun showSettingsSheet() {
if (adapter?.categories?.isNotEmpty() == true) { if (adapter?.categories?.isNotEmpty() == true) {
adapter?.categories?.getOrNull(binding.libraryPager.currentItem)?.let { category -> adapter?.categories?.getOrNull(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
@ -395,7 +399,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()
} }
@ -585,7 +589,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()
@ -598,7 +602,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))
@ -615,7 +619,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)) {
@ -642,7 +646,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)
@ -656,7 +660,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)
} }
} }
@ -703,7 +707,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()
} }
@ -866,12 +870,12 @@ class LibraryController(
fun startReading(manga: Manga, adapter: LibraryCategoryAdapter) { fun startReading(manga: Manga, adapter: LibraryCategoryAdapter) {
if (adapter.mode == SelectableAdapter.Mode.MULTI) { if (adapter.mode == SelectableAdapter.Mode.MULTI) {
toggleSelection(manga) toggleSelection(manga.toDbManga())
return return
} }
val activity = activity ?: return val activity = activity ?: return
val chapter = presenter.getFirstUnread(manga) ?: return val chapter = presenter.getFirstUnread(manga) ?: return
val intent = ReaderActivity.newIntent(activity, manga.id!!, chapter.id!!) val intent = ReaderActivity.newIntent(activity, manga.id, chapter.id!!)
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
startActivity(intent) startActivity(intent)
} }

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

@ -7,7 +7,7 @@ import eu.kanade.data.AndroidDatabaseHandler
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.GetMergedChapterByMangaId import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId
import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.interactor.UpdateChapter
@ -15,14 +15,13 @@ 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.GetMergedMangaById import eu.kanade.domain.manga.interactor.GetMergedMangaById
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.manga.model.toDbManga import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
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.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.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.library.CustomMangaManager import eu.kanade.tachiyomi.data.library.CustomMangaManager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
@ -48,7 +47,6 @@ import exh.source.MERGED_SOURCE_ID
import exh.source.isEhBasedManga import exh.source.isEhBasedManga
import exh.util.isLewd import exh.util.isLewd
import exh.util.nullIfBlank import exh.util.nullIfBlank
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
@ -59,6 +57,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.
@ -68,7 +67,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].
@ -403,12 +402,12 @@ class LibraryPresenter(
val defaultSortingMode = SortModeSetting.get(preferences, null) val defaultSortingMode = SortModeSetting.get(preferences, null)
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 defaultSortDirection = SortDirectionSetting.get(preferences, null) val defaultSortDirection = SortDirectionSetting.get(preferences, null)
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()
@ -417,12 +416,12 @@ class LibraryPresenter(
} }
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
val sortingMode = if (groupType == LibraryGroup.BY_DEFAULT) { val sortingMode = if (groupType == LibraryGroup.BY_DEFAULT) {
sortingModes[i1.manga.category] ?: defaultSortingMode sortingModes[i1.manga.category.toLong()] ?: defaultSortingMode
} else { } else {
defaultSortingMode defaultSortingMode
} }
val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) { val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) {
sortDirections[i1.manga.category] ?: defaultSortDirection sortDirections[i1.manga.category.toLong()] ?: defaultSortDirection
} else { } else {
defaultSortDirection defaultSortDirection
} == SortDirectionSetting.ASCENDING } == SortDirectionSetting.ASCENDING
@ -480,7 +479,7 @@ class LibraryPresenter(
return map.mapValues { entry -> return map.mapValues { entry ->
val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) { val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) {
sortDirections[entry.key] ?: defaultSortDirection sortDirections[entry.key.toLong()] ?: defaultSortDirection
} else { } else {
defaultSortDirection defaultSortDirection
} == SortDirectionSetting.ASCENDING } == SortDirectionSetting.ASCENDING
@ -503,13 +502,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
} }
@ -527,9 +526,9 @@ class LibraryPresenter(
val items = if (groupType == LibraryGroup.BY_DEFAULT) { val items = if (groupType == LibraryGroup.BY_DEFAULT) {
map map
} else if (!libraryIsGrouped) { } else if (!libraryIsGrouped) {
editedCategories = listOf(Category.create("All").apply { this.id = 0 }) editedCategories = listOf(Category(0, "All", 0, 0, emptyList()))
mapOf( mapOf(
0 to map.values.flatten().distinctBy { it.manga.id }, 0L to map.values.flatten().distinctBy { it.manga.id },
) )
} else { } else {
val (items, customCategories) = getGroupedMangaItems( val (items, customCategories) = getGroupedMangaItems(
@ -549,7 +548,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()
} }
/** /**
@ -603,7 +602,7 @@ class LibraryPresenter(
shouldSetFromCategory, shouldSetFromCategory,
defaultLibraryDisplayMode, defaultLibraryDisplayMode,
) )
}.groupBy { it.manga.category } }.groupBy { it.manga.category.toLong() }
} }
} }
@ -688,10 +687,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() }
} }
@ -700,9 +699,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()
} }
@ -712,7 +711,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 {
if (manga.source == MERGED_SOURCE_ID) { if (manga.source == MERGED_SOURCE_ID) {
@ -742,7 +741,7 @@ class LibraryPresenter(
} }
// SY --> // SY -->
fun cleanTitles(mangas: List<Manga>) { fun cleanTitles(mangas: List<DbManga>) {
mangas.forEach { manga -> mangas.forEach { manga ->
val editedTitle = manga.title.replace("\\[.*?]".toRegex(), "").trim().replace("\\(.*?\\)".toRegex(), "").trim().replace("\\{.*?\\}".toRegex(), "").trim().let { val editedTitle = manga.title.replace("\\[.*?]".toRegex(), "").trim().replace("\\(.*?\\)".toRegex(), "").trim().replace("\\{.*?\\}".toRegex(), "").trim().let {
if (it.contains("|")) { if (it.contains("|")) {
@ -769,7 +768,7 @@ class LibraryPresenter(
} }
} }
fun syncMangaToDex(mangaList: List<Manga>) { fun syncMangaToDex(mangaList: List<DbManga>) {
launchIO { launchIO {
MdUtil.getEnabledMangaDex(preferences, sourceManager)?.let { mdex -> MdUtil.getEnabledMangaDex(preferences, sourceManager)?.let { mdex ->
mangaList.forEach { mangaList.forEach {
@ -785,7 +784,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 = if (manga.source == MERGED_SOURCE_ID) getMergedChaptersByMangaId.await(manga.id!!) else getChapterByMangaId.await(manga.id!!) val chapters = if (manga.source == MERGED_SOURCE_ID) getMergedChaptersByMangaId.await(manga.id!!) else getChapterByMangaId.await(manga.id!!)
@ -807,7 +806,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 ->
// SY --> // SY -->
if (source is MergedSource) { if (source is MergedSource) {
@ -829,7 +828,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 }
@ -872,12 +871,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)
} }
} }
} }
@ -886,8 +884,8 @@ class LibraryPresenter(
/** Returns first unread chapter of a manga */ /** Returns first unread chapter of a manga */
fun getFirstUnread(manga: Manga): Chapter? { fun getFirstUnread(manga: Manga): Chapter? {
val chapters = if (manga.source == MERGED_SOURCE_ID) { val chapters = if (manga.source == MERGED_SOURCE_ID) {
(sourceManager.get(MERGED_SOURCE_ID) as MergedSource).getChaptersAsBlockingAsDbChapter(manga.id!!) (sourceManager.get(MERGED_SOURCE_ID) as MergedSource).getChaptersAsBlockingAsDbChapter(manga.id)
} else runBlocking { getChapterByMangaId.await(manga.id!!) }.map { it.toDbChapter() } } else runBlocking { getChapterByMangaId.await(manga.id) }.map { it.toDbChapter() }
return if (manga.isEhBasedManga()) { return if (manga.isEhBasedManga()) {
val chapter = chapters.sortedBy { it.source_order }.getOrNull(0) val chapter = chapters.sortedBy { it.source_order }.getOrNull(0)
if (chapter?.read == false) chapter else null if (chapter?.read == false) chapter else null
@ -897,19 +895,19 @@ class LibraryPresenter(
} }
private fun getGroupedMangaItems(libraryManga: List<LibraryItem>): Pair<LibraryMap, List<Category>> { private fun getGroupedMangaItems(libraryManga: List<LibraryItem>): Pair<LibraryMap, List<Category>> {
val grouping: MutableMap<Number, Pair<Int, String>> = mutableMapOf() val grouping: MutableMap<Number, Pair<Long, String>> = mutableMapOf()
when (groupType) { when (groupType) {
LibraryGroup.BY_STATUS -> { LibraryGroup.BY_STATUS -> {
grouping.putAll( grouping.putAll(
listOf( listOf(
SManga.ONGOING to context.getString(R.string.ongoing), SManga.ONGOING.toLong() to context.getString(R.string.ongoing),
SManga.LICENSED to context.getString(R.string.licensed), SManga.LICENSED.toLong() to context.getString(R.string.licensed),
SManga.CANCELLED to context.getString(R.string.cancelled), SManga.CANCELLED.toLong() to context.getString(R.string.cancelled),
SManga.ON_HIATUS to context.getString(R.string.on_hiatus), SManga.ON_HIATUS.toLong() to context.getString(R.string.on_hiatus),
SManga.PUBLISHING_FINISHED to context.getString(R.string.publishing_finished), SManga.PUBLISHING_FINISHED.toLong() to context.getString(R.string.publishing_finished),
SManga.COMPLETED to context.getString(R.string.completed), SManga.COMPLETED.toLong() to context.getString(R.string.completed),
SManga.UNKNOWN to context.getString(R.string.unknown), SManga.UNKNOWN.toLong() to context.getString(R.string.unknown),
).associateBy(Pair<Int, *>::first), ).associateBy(Pair<Long, *>::first),
) )
} }
LibraryGroup.BY_SOURCE -> LibraryGroup.BY_SOURCE ->
@ -917,19 +915,19 @@ class LibraryPresenter(
.map { it.manga.source } .map { it.manga.source }
.distinct() .distinct()
.sorted() .sorted()
.mapIndexed { index, sourceLong -> .map { sourceId ->
sourceLong to (index to sourceManager.getOrStub(sourceLong).name) sourceId to (sourceId to sourceManager.getOrStub(sourceId).name)
} }
.let(grouping::putAll) .let(grouping::putAll)
LibraryGroup.BY_TRACK_STATUS -> { LibraryGroup.BY_TRACK_STATUS -> {
grouping.putAll( grouping.putAll(
TrackStatus.values() TrackStatus.values()
.map { it.int to context.getString(it.res) } .map { it.int.toLong() to context.getString(it.res) }
.associateBy(Pair<Int, *>::first), .associateBy(Pair<Long, *>::first),
) )
} }
} }
val map: MutableMap<Int, MutableList<LibraryItem>> = mutableMapOf() val map: MutableMap<Long, MutableList<LibraryItem>> = mutableMapOf()
when (groupType) { when (groupType) {
LibraryGroup.BY_TRACK_STATUS -> { LibraryGroup.BY_TRACK_STATUS -> {
@ -939,7 +937,7 @@ class LibraryPresenter(
TrackStatus.parseTrackerStatus(track.syncId, track.status.toInt()) TrackStatus.parseTrackerStatus(track.syncId, track.status.toInt())
} ?: TrackStatus.OTHER } ?: TrackStatus.OTHER
map.getOrPut(status.int) { mutableListOf() } += libraryItem map.getOrPut(status.int.toLong()) { mutableListOf() } += libraryItem
} }
} }
LibraryGroup.BY_SOURCE -> { LibraryGroup.BY_SOURCE -> {
@ -949,9 +947,9 @@ class LibraryPresenter(
map.getOrPut(group.first) { mutableListOf() } += libraryItem map.getOrPut(group.first) { mutableListOf() } += libraryItem
} else { } else {
grouping.getOrPut(Int.MAX_VALUE) { grouping.getOrPut(Int.MAX_VALUE) {
Int.MAX_VALUE to context.getString(R.string.unknown) Long.MAX_VALUE to context.getString(R.string.unknown)
} }
map.getOrPut(Int.MAX_VALUE) { mutableListOf() } += libraryItem map.getOrPut(Long.MAX_VALUE) { mutableListOf() } += libraryItem
} }
} }
} }
@ -962,9 +960,9 @@ class LibraryPresenter(
map.getOrPut(group.first) { mutableListOf() } += libraryItem map.getOrPut(group.first) { mutableListOf() } += libraryItem
} else { } else {
grouping.getOrPut(Int.MAX_VALUE) { grouping.getOrPut(Int.MAX_VALUE) {
Int.MAX_VALUE to context.getString(R.string.unknown) Long.MAX_VALUE to context.getString(R.string.unknown)
} }
map.getOrPut(Int.MAX_VALUE) { mutableListOf() } += libraryItem map.getOrPut(Long.MAX_VALUE) { mutableListOf() } += libraryItem
} }
} }
} }
@ -975,7 +973,7 @@ class LibraryPresenter(
LibraryGroup.BY_TRACK_STATUS, LibraryGroup.BY_STATUS -> grouping.values.filter { it.first in map.keys } LibraryGroup.BY_TRACK_STATUS, LibraryGroup.BY_STATUS -> grouping.values.filter { it.first in map.keys }
else -> grouping.values else -> grouping.values
}.map { (id, name) -> }.map { (id, name) ->
Category.create(name).also { it.id = id } Category(id, name, 0, 0, emptyList())
} }
return map to categories return map to categories

View File

@ -9,6 +9,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
@ -226,8 +227,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
@ -290,12 +291,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 {
@ -303,7 +304,7 @@ class LibrarySettingsSheet(
} }
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) { if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
currentCategory?.sortDirection = flag.flag currentCategory?.sortDirection = flag.flag.toInt()
sheetScope.launchIO { sheetScope.launchIO {
updateCategory.await( updateCategory.await(
CategoryUpdate( CategoryUpdate(
@ -335,7 +336,7 @@ class LibrarySettingsSheet(
} }
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) { if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
currentCategory?.sortMode = flag.flag currentCategory?.sortMode = flag.flag.toInt()
sheetScope.launchIO { sheetScope.launchIO {
updateCategory.await( updateCategory.await(
CategoryUpdate( CategoryUpdate(
@ -386,7 +387,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 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) { return if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
DisplayModeSetting.fromFlag(currentCategory?.displayMode) DisplayModeSetting.fromFlag(currentCategory?.displayMode?.toLong())
} else { } else {
preferences.libraryDisplayMode().get() preferences.libraryDisplayMode().get()
} }
@ -438,7 +439,7 @@ class LibrarySettingsSheet(
} }
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) { if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0 /* SY --> */ && preferences.groupLibraryBy().get() == LibraryGroup.BY_DEFAULT /* SY <-- */) {
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),
@ -27,14 +27,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.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
@ -68,6 +68,7 @@ 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.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
@ -302,7 +303,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)
} }
@ -316,7 +317,7 @@ class MangaController :
QuadStateTextView.State.UNCHECKED.ordinal QuadStateTextView.State.UNCHECKED.ordinal
} }
}.toTypedArray() }.toTypedArray()
showChangeCategoryDialog(manga.toDbManga(), categories, preselected) showChangeCategoryDialog(manga, categories, preselected)
}, },
) )
} }
@ -404,10 +405,6 @@ class MangaController :
} }
// AZ <-- // AZ <--
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
@ -421,8 +418,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

@ -5,7 +5,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.GetMergedChapterByMangaId import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId
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
@ -34,9 +34,7 @@ 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.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.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.database.models.toDomainManga import eu.kanade.tachiyomi.data.database.models.toDomainManga
@ -111,6 +109,7 @@ import uy.kohesive.injekt.injectLazy
import java.text.DateFormat import java.text.DateFormat
import eu.kanade.domain.chapter.model.Chapter as DomainChapter import eu.kanade.domain.chapter.model.Chapter as DomainChapter
import eu.kanade.domain.manga.model.Manga as DomainManga import eu.kanade.domain.manga.model.Manga as DomainManga
import eu.kanade.tachiyomi.data.database.models.Manga.Companion as DbManga
class MangaPresenter( class MangaPresenter(
val mangaId: Long, val mangaId: Long,
@ -404,8 +403,8 @@ class MangaPresenter(
artist = newArtist, artist = newArtist,
description = newDesc, description = newDesc,
genre = tags, genre = tags,
status = status status = status,
) ),
) )
} }
} else { } else {
@ -481,13 +480,13 @@ class MangaPresenter(
return originalManga return originalManga
} else { } else {
val mergedManga = Manga.create(originalManga.url, originalManga.title, MERGED_SOURCE_ID).apply { val mergedManga = DbManga.create(originalManga.url, originalManga.title, MERGED_SOURCE_ID).apply {
copyFrom(originalManga.toSManga()) copyFrom(originalManga.toSManga())
favorite = true favorite = true
last_update = originalManga.lastUpdate last_update = originalManga.lastUpdate
viewer_flags = originalManga.viewerFlags.toInt() viewer_flags = originalManga.viewerFlags.toInt()
chapter_flags = originalManga.chapterFlags.toInt() chapter_flags = originalManga.chapterFlags.toInt()
sorting = Manga.CHAPTER_SORTING_NUMBER sorting = DbManga.CHAPTER_SORTING_NUMBER
date_added = System.currentTimeMillis() date_added = System.currentTimeMillis()
} }
@ -515,7 +514,6 @@ class MangaPresenter(
setMangaCategories.await(mergedManga.id!!, it.map { it.id }) setMangaCategories.await(mergedManga.id!!, it.map { it.id })
} }
val originalMangaReference = MergedMangaReference( val originalMangaReference = MergedMangaReference(
id = null, id = null,
isInfoManga = true, isInfoManga = true,
@ -617,22 +615,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() }
} }
@ -691,7 +689,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()
} }
/** /**
@ -700,15 +698,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)
} }
} }
@ -718,9 +716,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)
} }
@ -732,8 +729,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() {

View File

@ -45,7 +45,7 @@ class RecommendsController(bundle: Bundle) : BrowseSourceController(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
openSmartSearch(item.manga.originalTitle) openSmartSearch(item.manga.ogTitle)
return true return true
} }