mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-22 14:31:52 +01:00
Migrate to more use of domain models
This commit is contained in:
parent
2674570792
commit
76c0ead1db
@ -2,6 +2,9 @@ package eu.kanade.domain.category.model
|
||||
|
||||
import android.content.Context
|
||||
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 eu.kanade.tachiyomi.data.database.models.Category as DbCategory
|
||||
|
||||
@ -12,6 +15,15 @@ data class Category(
|
||||
val flags: Long,
|
||||
) : 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 {
|
||||
val default = { context: Context ->
|
||||
Category(
|
||||
|
@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||
import tachiyomi.source.model.MangaInfo
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.Serializable
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
|
||||
|
||||
data class Manga(
|
||||
@ -29,7 +30,7 @@ data class Manga(
|
||||
val status: Long,
|
||||
val thumbnailUrl: String?,
|
||||
val initialized: Boolean,
|
||||
) {
|
||||
) : Serializable {
|
||||
|
||||
fun toSManga(): SManga {
|
||||
return SManga.create().also {
|
||||
|
@ -2,11 +2,9 @@ package eu.kanade.tachiyomi.data.database
|
||||
|
||||
import androidx.sqlite.db.SupportSQLiteOpenHelper
|
||||
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.MangaCategoryTypeMapping
|
||||
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.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
@ -26,7 +24,6 @@ class DatabaseHelper(
|
||||
.sqliteOpenHelper(openHelper)
|
||||
.addTypeMapping(Manga::class.java, MangaTypeMapping())
|
||||
.addTypeMapping(Chapter::class.java, ChapterTypeMapping())
|
||||
.addTypeMapping(Category::class.java, CategoryTypeMapping())
|
||||
.addTypeMapping(MangaCategory::class.java, MangaCategoryTypeMapping())
|
||||
.build()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
@ -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.SortModeSetting
|
||||
import java.io.Serializable
|
||||
import eu.kanade.domain.category.model.Category as DomainCategory
|
||||
|
||||
interface Category : Serializable {
|
||||
|
||||
@ -22,16 +23,16 @@ interface Category : Serializable {
|
||||
}
|
||||
|
||||
var displayMode: Int
|
||||
get() = flags and DisplayModeSetting.MASK
|
||||
set(mode) = setFlags(mode, DisplayModeSetting.MASK)
|
||||
get() = flags and DisplayModeSetting.MASK.toInt()
|
||||
set(mode) = setFlags(mode, DisplayModeSetting.MASK.toInt())
|
||||
|
||||
var sortMode: Int
|
||||
get() = flags and SortModeSetting.MASK
|
||||
set(mode) = setFlags(mode, SortModeSetting.MASK)
|
||||
get() = flags and SortModeSetting.MASK.toInt()
|
||||
set(mode) = setFlags(mode, SortModeSetting.MASK.toInt())
|
||||
|
||||
var sortDirection: Int
|
||||
get() = flags and SortDirectionSetting.MASK
|
||||
set(mode) = setFlags(mode, SortDirectionSetting.MASK)
|
||||
get() = flags and SortDirectionSetting.MASK.toInt()
|
||||
set(mode) = setFlags(mode, SortDirectionSetting.MASK.toInt())
|
||||
|
||||
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 Category.toDomainCategory(): DomainCategory? {
|
||||
val categoryId = id ?: return null
|
||||
return DomainCategory(
|
||||
id = categoryId.toLong(),
|
||||
name = this.name,
|
||||
order = this.order.toLong(),
|
||||
flags = this.flags.toLong(),
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
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 {
|
||||
|
||||
var id: Long? = null
|
||||
@ -10,6 +13,13 @@ class MangaCategory {
|
||||
|
||||
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 {
|
||||
val mc = MangaCategory()
|
||||
mc.manga_id = manga.id!!
|
||||
|
@ -1,6 +1,5 @@
|
||||
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.MangaCategoryTable as MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable as Manga
|
||||
@ -36,14 +35,3 @@ val libraryQuery =
|
||||
SELECT * FROM ${MangaCategory.TABLE}) AS MC
|
||||
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} = ?
|
||||
"""
|
||||
|
@ -3,12 +3,4 @@ package eu.kanade.tachiyomi.data.database.tables
|
||||
object CategoryTable {
|
||||
|
||||
const val TABLE = "categories"
|
||||
|
||||
const val COL_ID = "_id"
|
||||
|
||||
const val COL_NAME = "name"
|
||||
|
||||
const val COL_ORDER = "sort"
|
||||
|
||||
const val COL_FLAGS = "flags"
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import android.os.PowerManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import eu.kanade.data.chapter.NoChaptersException
|
||||
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.SyncChaptersWithSource
|
||||
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.data.cache.CoverCache
|
||||
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.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
@ -228,7 +228,7 @@ class LibraryUpdateService(
|
||||
ioScope?.cancel()
|
||||
|
||||
// Update favorite manga
|
||||
val categoryId = intent.getIntExtra(KEY_CATEGORY, -1)
|
||||
val categoryId = intent.getLongExtra(KEY_CATEGORY, -1L)
|
||||
addMangaToQueue(categoryId)
|
||||
|
||||
// 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.
|
||||
*/
|
||||
fun addMangaToQueue(categoryId: Int) {
|
||||
fun addMangaToQueue(categoryId: Long) {
|
||||
val libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||
|
||||
val listToUpdate = if (categoryId != -1) {
|
||||
libraryManga.filter { it.category == categoryId }
|
||||
val listToUpdate = if (categoryId != -1L) {
|
||||
libraryManga.filter { it.category.toLong() == categoryId }
|
||||
} else {
|
||||
val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt)
|
||||
val listToInclude = if (categoriesToUpdate.isNotEmpty()) {
|
||||
|
@ -9,6 +9,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
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.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
@ -149,6 +150,6 @@ class SearchController(
|
||||
override fun onTitleClick(source: CatalogueSource) {
|
||||
presenter.preferences.lastUsedSource().set(source.id)
|
||||
|
||||
router.pushController(SourceSearchController(manga, source, presenter.query))
|
||||
router.pushController(SourceSearchController(manga?.toDomainManga(), source, presenter.query))
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
|
||||
|
||||
import android.os.Bundle
|
||||
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.ui.browse.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.SourceItem
|
||||
@ -28,7 +29,7 @@ class SourceSearchController(
|
||||
newManga = item.manga
|
||||
val searchController = router.backstack.findLast { it.controller.javaClass == SearchController::class.java }?.controller as SearchController?
|
||||
val dialog =
|
||||
SearchController.MigrationDialog(oldManga, newManga, this)
|
||||
SearchController.MigrationDialog(oldManga?.toDbManga(), newManga?.toDbManga(), this)
|
||||
dialog.targetController = searchController
|
||||
dialog.showDialog(router)
|
||||
return true
|
||||
|
@ -20,11 +20,11 @@ import com.google.android.material.snackbar.Snackbar
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.domain.category.model.toDbCategory
|
||||
import eu.kanade.domain.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.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.databinding.SourceControllerBinding
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
@ -541,7 +541,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
|
||||
adapter.allBoundViewHolders.forEach { holder ->
|
||||
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<*>
|
||||
}
|
||||
}
|
||||
@ -575,7 +575,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
*/
|
||||
override fun onItemClick(view: View, position: Int): Boolean {
|
||||
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
|
||||
}
|
||||
@ -602,7 +602,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
.setItems(arrayOf(activity.getString(R.string.remove_from_library))) { _, which ->
|
||||
when (which) {
|
||||
0 -> {
|
||||
presenter.changeMangaFavorite(manga)
|
||||
presenter.changeMangaFavorite(manga.toDbManga())
|
||||
adapter?.notifyItemChanged(position)
|
||||
activity.toast(activity.getString(R.string.manga_removed_library))
|
||||
}
|
||||
@ -637,18 +637,18 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
when {
|
||||
// Default category set
|
||||
defaultCategory != null -> {
|
||||
presenter.moveMangaToCategory(newManga, defaultCategory.toDbCategory())
|
||||
presenter.moveMangaToCategory(newManga.toDbManga(), defaultCategory)
|
||||
|
||||
presenter.changeMangaFavorite(newManga)
|
||||
presenter.changeMangaFavorite(newManga.toDbManga())
|
||||
adapter?.notifyItemChanged(position)
|
||||
activity.toast(activity.getString(R.string.manga_added_library))
|
||||
}
|
||||
|
||||
// Automatic 'Default' or no categories
|
||||
defaultCategoryId == 0 || categories.isEmpty() -> {
|
||||
presenter.moveMangaToCategory(newManga, null)
|
||||
presenter.moveMangaToCategory(newManga.toDbManga(), null)
|
||||
|
||||
presenter.changeMangaFavorite(newManga)
|
||||
presenter.changeMangaFavorite(newManga.toDbManga())
|
||||
adapter?.notifyItemChanged(position)
|
||||
activity.toast(activity.getString(R.string.manga_added_library))
|
||||
}
|
||||
@ -664,7 +664,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
}
|
||||
}.toTypedArray()
|
||||
|
||||
ChangeMangaCategoriesDialog(this@BrowseSourceController, listOf(newManga), categories.map { it.toDbCategory() }, preselected)
|
||||
ChangeMangaCategoriesDialog(this@BrowseSourceController, listOf(newManga), categories, preselected)
|
||||
.showDialog(router)
|
||||
}
|
||||
}
|
||||
@ -681,8 +681,8 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
override fun updateCategoriesForMangas(mangas: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) {
|
||||
val manga = mangas.firstOrNull() ?: return
|
||||
|
||||
presenter.changeMangaFavorite(manga)
|
||||
presenter.updateMangaCategories(manga, addCategories)
|
||||
presenter.changeMangaFavorite(manga.toDbManga())
|
||||
presenter.updateMangaCategories(manga.toDbManga(), addCategories)
|
||||
|
||||
val position = adapter?.currentItems?.indexOfFirst { it -> (it as SourceItem).manga.id == manga.id }
|
||||
if (position != null) {
|
||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||
import android.os.Bundle
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.model.toDbCategory
|
||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
||||
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.tachiyomi.data.cache.CoverCache
|
||||
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.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
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.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import logcat.LogPriority
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
@ -60,6 +62,7 @@ import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.Date
|
||||
import eu.kanade.domain.category.model.Category as DomainCategory
|
||||
import eu.kanade.domain.manga.model.Manga as DomainManga
|
||||
|
||||
open class BrowseSourcePresenter(
|
||||
private val sourceId: Long,
|
||||
@ -157,7 +160,7 @@ open class BrowseSourcePresenter(
|
||||
pagerSubscription?.let { remove(it) }
|
||||
pagerSubscription = pager.results()
|
||||
.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) }
|
||||
.map { (first, second) -> first to second.map { SourceItem(it, sourceDisplayMode) } }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -225,15 +228,15 @@ open class BrowseSourcePresenter(
|
||||
*
|
||||
* @param mangas the list of manga to initialize.
|
||||
*/
|
||||
fun initializeMangas(mangas: List<Manga>) {
|
||||
fun initializeMangas(mangas: List<DomainManga>) {
|
||||
presenterScope.launchIO {
|
||||
mangas.asFlow()
|
||||
.filter { it.thumbnail_url == null && !it.initialized }
|
||||
.map { getMangaDetails(it) }
|
||||
.filter { it.thumbnailUrl == null && !it.initialized }
|
||||
.map { getMangaDetails(it.toDbManga()) }
|
||||
.onEach {
|
||||
withUIContext {
|
||||
@Suppress("DEPRECATION")
|
||||
view?.onMangaInitialized(it)
|
||||
view?.onMangaInitialized(it.toDomainManga()!!)
|
||||
}
|
||||
}
|
||||
.catch { e -> logcat(LogPriority.ERROR, e) }
|
||||
@ -362,8 +365,8 @@ open class BrowseSourcePresenter(
|
||||
return getCategories.subscribe().firstOrNull() ?: emptyList()
|
||||
}
|
||||
|
||||
suspend fun getDuplicateLibraryManga(manga: Manga): Manga? {
|
||||
return getDuplicateLibraryManga.await(manga.title, manga.source)?.toDbManga()
|
||||
suspend fun getDuplicateLibraryManga(manga: DomainManga): DomainManga? {
|
||||
return getDuplicateLibraryManga.await(manga.title, manga.source)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -372,9 +375,10 @@ open class BrowseSourcePresenter(
|
||||
* @param manga the manga to get categories from.
|
||||
* @return Array of category ids the manga is in, if none returns default id
|
||||
*/
|
||||
suspend fun getMangaCategoryIds(manga: Manga): Array<Long?> {
|
||||
val categories = getCategories.await(manga.id!!)
|
||||
return categories.map { it.id }.toTypedArray()
|
||||
fun getMangaCategoryIds(manga: DomainManga): Array<Long?> {
|
||||
return runBlocking { getCategories.await(manga.id) }
|
||||
.map { it.id }
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -383,8 +387,8 @@ open class BrowseSourcePresenter(
|
||||
* @param categories the selected categories.
|
||||
* @param manga the manga to move.
|
||||
*/
|
||||
private fun moveMangaToCategories(manga: Manga, categories: List<Category>) {
|
||||
val mc = categories.filter { it.id != 0 }.map { MangaCategory.create(manga, it) }
|
||||
private fun moveMangaToCategories(manga: Manga, categories: List<DomainCategory>) {
|
||||
val mc = categories.filter { it.id != 0L }.map { MangaCategory.create(manga, it.toDbCategory()) }
|
||||
db.setMangaCategories(mc, listOf(manga))
|
||||
}
|
||||
|
||||
@ -394,7 +398,7 @@ open class BrowseSourcePresenter(
|
||||
* @param category the selected category.
|
||||
* @param manga the manga to move.
|
||||
*/
|
||||
fun moveMangaToCategory(manga: Manga, category: Category?) {
|
||||
fun moveMangaToCategory(manga: Manga, category: DomainCategory?) {
|
||||
moveMangaToCategories(manga, listOfNotNull(category))
|
||||
}
|
||||
|
||||
@ -404,7 +408,7 @@ open class BrowseSourcePresenter(
|
||||
* @param manga needed to change
|
||||
* @param selectedCategories selected categories
|
||||
*/
|
||||
fun updateMangaCategories(manga: Manga, selectedCategories: List<Category>) {
|
||||
fun updateMangaCategories(manga: Manga, selectedCategories: List<DomainCategory>) {
|
||||
if (!manga.favorite) {
|
||||
changeMangaFavorite(manga)
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||
import androidx.core.view.isVisible
|
||||
import coil.dispose
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
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.util.view.loadAutoPause
|
||||
|
||||
|
@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||
import androidx.core.view.isVisible
|
||||
import coil.dispose
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
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.util.view.loadAutoPause
|
||||
|
||||
|
@ -4,7 +4,7 @@ import android.view.View
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
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.
|
||||
|
@ -6,8 +6,8 @@ import com.fredporciuncula.flow.preferences.Preference
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
|
||||
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
||||
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||
|
@ -5,9 +5,9 @@ import androidx.core.view.isVisible
|
||||
import coil.dispose
|
||||
import coil.load
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.R
|
||||
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.util.system.getResourceColor
|
||||
|
||||
@ -51,7 +51,7 @@ class SourceListHolder(private val view: View, adapter: FlexibleAdapter<*>) :
|
||||
|
||||
override fun setImage(manga: Manga) {
|
||||
binding.thumbnail.dispose()
|
||||
if (!manga.thumbnail_url.isNullOrEmpty()) {
|
||||
if (!manga.thumbnailUrl.isNullOrEmpty()) {
|
||||
binding.thumbnail.load(manga) {
|
||||
setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false)
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
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.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.pushController
|
||||
import eu.kanade.tachiyomi.ui.category.CategoryController
|
||||
|
@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.library
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
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.databinding.LibraryCategoryBinding
|
||||
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||
@ -153,7 +153,7 @@ class LibraryAdapter(
|
||||
|
||||
override fun getViewType(position: Int): Int {
|
||||
val category = categories.getOrNull(position)
|
||||
return if (isPerCategory && category?.id != 0) {
|
||||
return if (isPerCategory && category?.id != 0L) {
|
||||
if (DisplayModeSetting.fromFlag(category?.displayMode) == DisplayModeSetting.LIST) {
|
||||
LIST_DISPLAY_MODE
|
||||
} else {
|
||||
|
@ -8,8 +8,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.kanade.domain.category.model.Category
|
||||
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.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
|
||||
|
@ -15,9 +15,11 @@ import com.fredporciuncula.flow.preferences.Preference
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
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.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.LibraryControllerBinding
|
||||
@ -50,6 +52,7 @@ import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.concurrent.TimeUnit
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
|
||||
|
||||
class LibraryController(
|
||||
bundle: Bundle? = null,
|
||||
@ -74,7 +77,7 @@ class LibraryController(
|
||||
/**
|
||||
* Currently selected mangas.
|
||||
*/
|
||||
val selectedMangas = mutableSetOf<Manga>()
|
||||
val selectedMangas = mutableSetOf<DbManga>()
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
val selectAllRelay: PublishRelay<Int> = PublishRelay.create()
|
||||
val selectAllRelay: PublishRelay<Long> = PublishRelay.create()
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -262,14 +265,14 @@ class LibraryController(
|
||||
fun showSettingsSheet() {
|
||||
if (adapter?.categories?.isNotEmpty() == true) {
|
||||
adapter?.categories?.get(binding.libraryPager.currentItem)?.let { category ->
|
||||
settingsSheet?.show(category)
|
||||
settingsSheet?.show(category.toDbCategory())
|
||||
}
|
||||
} else {
|
||||
settingsSheet?.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun onNextLibraryUpdate(categories: List<Category>, mangaMap: Map<Int, List<LibraryItem>>) {
|
||||
fun onNextLibraryUpdate(categories: List<Category>, mangaMap: LibraryMap) {
|
||||
val view = view ?: return
|
||||
val adapter = adapter ?: return
|
||||
|
||||
@ -344,7 +347,7 @@ class LibraryController(
|
||||
if (!firstLaunch) {
|
||||
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()
|
||||
}
|
||||
|
||||
@ -493,7 +496,7 @@ class LibraryController(
|
||||
actionMode = null
|
||||
}
|
||||
|
||||
fun openManga(manga: Manga) {
|
||||
fun openManga(manga: DbManga) {
|
||||
// Notify the presenter a manga is being opened.
|
||||
presenter.onOpenManga()
|
||||
|
||||
@ -506,7 +509,7 @@ class LibraryController(
|
||||
* @param manga the manga whose selection has changed.
|
||||
* @param selected whether it's now selected or not.
|
||||
*/
|
||||
fun setSelection(manga: Manga, selected: Boolean) {
|
||||
fun setSelection(manga: DbManga, selected: Boolean) {
|
||||
if (selected) {
|
||||
if (selectedMangas.add(manga)) {
|
||||
selectionRelay.call(LibrarySelectionEvent.Selected(manga))
|
||||
@ -523,7 +526,7 @@ class LibraryController(
|
||||
*
|
||||
* @param manga the manga whose selection to change.
|
||||
*/
|
||||
fun toggleSelection(manga: Manga) {
|
||||
fun toggleSelection(manga: DbManga) {
|
||||
if (selectedMangas.add(manga)) {
|
||||
selectionRelay.call(LibrarySelectionEvent.Selected(manga))
|
||||
} else if (selectedMangas.remove(manga)) {
|
||||
@ -550,7 +553,7 @@ class LibraryController(
|
||||
val mangas = selectedMangas.toList()
|
||||
|
||||
// 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.
|
||||
val common = presenter.getCommonCategories(mangas)
|
||||
@ -564,7 +567,7 @@ class LibraryController(
|
||||
}
|
||||
}.toTypedArray()
|
||||
launchUI {
|
||||
ChangeMangaCategoriesDialog(this@LibraryController, mangas, categories, preselected)
|
||||
ChangeMangaCategoriesDialog(this@LibraryController, mangas.map { it.toDomainManga()!! }, categories, preselected)
|
||||
.showDialog(router)
|
||||
}
|
||||
}
|
||||
@ -591,7 +594,7 @@ class LibraryController(
|
||||
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)
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class LibraryItem(
|
||||
|
||||
private val sourceManager: SourceManager = Injekt.get()
|
||||
|
||||
var displayMode: Int = -1
|
||||
var displayMode: Long = -1
|
||||
var downloadCount = -1
|
||||
var unreadCount = -1
|
||||
var isLocal = false
|
||||
|
@ -1,8 +1,8 @@
|
||||
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>? {
|
||||
return mangas[category.id]
|
||||
|
@ -6,19 +6,18 @@ import eu.kanade.core.util.asObservable
|
||||
import eu.kanade.data.DatabaseHandler
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
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.UpdateChapter
|
||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
||||
import eu.kanade.domain.chapter.model.toDbChapter
|
||||
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.track.interactor.GetTracks
|
||||
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.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
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.removeCovers
|
||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
@ -45,6 +43,7 @@ import uy.kohesive.injekt.api.get
|
||||
import java.text.Collator
|
||||
import java.util.Collections
|
||||
import java.util.Locale
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private typealias LibraryMap = Map<Int, List<LibraryItem>>
|
||||
typealias LibraryMap = Map<Long, List<LibraryItem>>
|
||||
|
||||
/**
|
||||
* Presenter of [LibraryController].
|
||||
@ -299,11 +298,11 @@ class LibraryPresenter(
|
||||
}
|
||||
|
||||
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 ->
|
||||
(category.id ?: 0) to SortDirectionSetting.get(preferences, category)
|
||||
category.id to SortDirectionSetting.get(preferences, category)
|
||||
}
|
||||
|
||||
val locale = Locale.getDefault()
|
||||
@ -311,8 +310,8 @@ class LibraryPresenter(
|
||||
strength = Collator.PRIMARY
|
||||
}
|
||||
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
|
||||
val sortingMode = sortingModes[i1.manga.category]!!
|
||||
val sortAscending = sortDirections[i1.manga.category]!! == SortDirectionSetting.ASCENDING
|
||||
val sortingMode = sortingModes[i1.manga.category.toLong()]!!
|
||||
val sortAscending = sortDirections[i1.manga.category.toLong()]!! == SortDirectionSetting.ASCENDING
|
||||
when (sortingMode) {
|
||||
SortModeSetting.ALPHABETICAL -> {
|
||||
collator.compare(i1.manga.title.lowercase(locale), i2.manga.title.lowercase(locale))
|
||||
@ -355,7 +354,7 @@ class LibraryPresenter(
|
||||
}
|
||||
|
||||
return map.mapValues { entry ->
|
||||
val sortAscending = sortDirections[entry.key]!! == SortDirectionSetting.ASCENDING
|
||||
val sortAscending = sortDirections[entry.key.toLong()]!! == SortDirectionSetting.ASCENDING
|
||||
|
||||
val comparator = if (sortAscending) {
|
||||
Comparator(sortFn)
|
||||
@ -375,13 +374,13 @@ class LibraryPresenter(
|
||||
private fun getLibraryObservable(): Observable<Library> {
|
||||
return Observable.combineLatest(getCategoriesObservable(), getLibraryMangasObservable()) { dbCategories, libraryManga ->
|
||||
val categories = if (libraryManga.containsKey(0)) {
|
||||
arrayListOf(Category.createDefault(context)) + dbCategories
|
||||
arrayListOf(Category.default(context)) + dbCategories
|
||||
} else {
|
||||
dbCategories
|
||||
}
|
||||
|
||||
libraryManga.forEach { (categoryId, libraryManga) ->
|
||||
val category = categories.first { category -> category.id == categoryId }
|
||||
val category = categories.first { category -> category.id == categoryId.toLong() }
|
||||
libraryManga.forEach { libraryItem ->
|
||||
libraryItem.displayMode = category.displayMode
|
||||
}
|
||||
@ -398,7 +397,7 @@ class LibraryPresenter(
|
||||
* @return an observable of the categories.
|
||||
*/
|
||||
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,
|
||||
defaultLibraryDisplayMode,
|
||||
)
|
||||
}.groupBy { it.manga.category }
|
||||
}.groupBy { it.manga.category.toLong() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,10 +515,10 @@ class LibraryPresenter(
|
||||
*
|
||||
* @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()
|
||||
return mangas.toSet()
|
||||
.map { getCategories.await(it.id!!).map { it.toDbCategory() } }
|
||||
.map { getCategories.await(it.id!!) }
|
||||
.reduce { set1, set2 -> set1.intersect(set2).toMutableList() }
|
||||
}
|
||||
|
||||
@ -528,9 +527,9 @@ class LibraryPresenter(
|
||||
*
|
||||
* @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()
|
||||
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() }
|
||||
return mangaCategories.flatten().distinct().subtract(common).toMutableList()
|
||||
}
|
||||
@ -540,7 +539,7 @@ class LibraryPresenter(
|
||||
*
|
||||
* @param mangas the list of manga.
|
||||
*/
|
||||
fun downloadUnreadChapters(mangas: List<Manga>) {
|
||||
fun downloadUnreadChapters(mangas: List<DbManga>) {
|
||||
mangas.forEach { manga ->
|
||||
launchIO {
|
||||
val chapters = getChapterByMangaId.await(manga.id!!)
|
||||
@ -557,7 +556,7 @@ class LibraryPresenter(
|
||||
*
|
||||
* @param mangas the list of manga.
|
||||
*/
|
||||
fun markReadStatus(mangas: List<Manga>, read: Boolean) {
|
||||
fun markReadStatus(mangas: List<DbManga>, read: Boolean) {
|
||||
mangas.forEach { manga ->
|
||||
launchIO {
|
||||
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 ->
|
||||
downloadManager.deleteChapters(chapters, manga, source)
|
||||
}
|
||||
@ -592,7 +591,7 @@ class LibraryPresenter(
|
||||
* @param deleteFromLibrary whether to delete manga from library.
|
||||
* @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 {
|
||||
val mangaToDelete = mangaList.distinctBy { it.id }
|
||||
|
||||
@ -628,12 +627,11 @@ class LibraryPresenter(
|
||||
fun setMangaCategories(mangaList: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) {
|
||||
presenterScope.launchIO {
|
||||
mangaList.map { manga ->
|
||||
val categoryIds = getCategories.await(manga.id!!)
|
||||
.map { it.toDbCategory() }
|
||||
val categoryIds = getCategories.await(manga.id)
|
||||
.subtract(removeCategories)
|
||||
.plus(addCategories)
|
||||
.mapNotNull { it.id?.toLong() }
|
||||
setMangaCategories.await(manga.id!!, categoryIds)
|
||||
.map { it.id }
|
||||
setMangaCategories.await(manga.id, categoryIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import eu.kanade.domain.category.interactor.UpdateCategory
|
||||
import eu.kanade.domain.category.model.CategoryUpdate
|
||||
import eu.kanade.tachiyomi.R
|
||||
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.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
@ -201,8 +202,8 @@ class LibrarySettingsSheet(
|
||||
override val footer = null
|
||||
|
||||
override fun initModels() {
|
||||
val sorting = SortModeSetting.get(preferences, currentCategory)
|
||||
val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) {
|
||||
val sorting = SortModeSetting.get(preferences, currentCategory?.toDomainCategory())
|
||||
val order = if (SortDirectionSetting.get(preferences, currentCategory?.toDomainCategory()) == SortDirectionSetting.ASCENDING) {
|
||||
Item.MultiSort.SORT_ASC
|
||||
} else {
|
||||
Item.MultiSort.SORT_DESC
|
||||
@ -243,12 +244,12 @@ class LibrarySettingsSheet(
|
||||
|
||||
setSortModePreference(item)
|
||||
|
||||
setSortDirectionPrefernece(item)
|
||||
setSortDirectionPreference(item)
|
||||
|
||||
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) {
|
||||
SortDirectionSetting.ASCENDING
|
||||
} else {
|
||||
@ -256,7 +257,7 @@ class LibrarySettingsSheet(
|
||||
}
|
||||
|
||||
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.sortDirection = flag.flag
|
||||
currentCategory?.sortDirection = flag.flag.toInt()
|
||||
sheetScope.launchIO {
|
||||
updateCategory.await(
|
||||
CategoryUpdate(
|
||||
@ -284,7 +285,7 @@ class LibrarySettingsSheet(
|
||||
}
|
||||
|
||||
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.sortMode = flag.flag
|
||||
currentCategory?.sortMode = flag.flag.toInt()
|
||||
sheetScope.launchIO {
|
||||
updateCategory.await(
|
||||
CategoryUpdate(
|
||||
@ -327,7 +328,7 @@ class LibrarySettingsSheet(
|
||||
// Gets user preference of currently selected display mode at current category
|
||||
private fun getDisplayModePreference(): DisplayModeSetting {
|
||||
return if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
DisplayModeSetting.fromFlag(currentCategory?.displayMode)
|
||||
DisplayModeSetting.fromFlag(currentCategory?.displayMode?.toLong())
|
||||
} else {
|
||||
preferences.libraryDisplayMode().get()
|
||||
}
|
||||
@ -379,7 +380,7 @@ class LibrarySettingsSheet(
|
||||
}
|
||||
|
||||
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.displayMode = flag.flag
|
||||
currentCategory?.displayMode = flag.flag.toInt()
|
||||
sheetScope.launchIO {
|
||||
updateCategory.await(
|
||||
CategoryUpdate(
|
||||
|
@ -1,15 +1,15 @@
|
||||
package eu.kanade.tachiyomi.ui.library.setting
|
||||
|
||||
enum class DisplayModeSetting(val flag: Int) {
|
||||
enum class DisplayModeSetting(val flag: Long) {
|
||||
COMPACT_GRID(0b00000000),
|
||||
COMFORTABLE_GRID(0b00000001),
|
||||
LIST(0b00000010),
|
||||
COVER_ONLY_GRID(0b00000011);
|
||||
|
||||
companion object {
|
||||
const val MASK = 0b00000011
|
||||
const val MASK = 0b00000011L
|
||||
|
||||
fun fromFlag(flag: Int?): DisplayModeSetting {
|
||||
fun fromFlag(flag: Long?): DisplayModeSetting {
|
||||
return values()
|
||||
.find { mode -> mode.flag == flag } ?: COMPACT_GRID
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
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
|
||||
|
||||
enum class SortDirectionSetting(val flag: Int) {
|
||||
enum class SortDirectionSetting(val flag: Long) {
|
||||
ASCENDING(0b01000000),
|
||||
DESCENDING(0b00000000);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
} else {
|
||||
preferences.librarySortingAscending().get()
|
||||
|
@ -1,9 +1,9 @@
|
||||
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
|
||||
|
||||
enum class SortModeSetting(val flag: Int) {
|
||||
enum class SortModeSetting(val flag: Long) {
|
||||
ALPHABETICAL(0b00000000),
|
||||
LAST_READ(0b00000100),
|
||||
LAST_MANGA_UPDATE(0b00001000),
|
||||
@ -25,14 +25,14 @@ enum class SortModeSetting(val flag: Int) {
|
||||
|
||||
companion object {
|
||||
// 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
|
||||
}
|
||||
|
||||
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)
|
||||
} else {
|
||||
preferences.librarySortingMode().get()
|
||||
|
@ -4,8 +4,8 @@ import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.pushController
|
||||
|
@ -24,14 +24,14 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
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.presentation.manga.ChapterDownloadAction
|
||||
import eu.kanade.presentation.manga.DownloadAction
|
||||
import eu.kanade.presentation.manga.MangaScreen
|
||||
import eu.kanade.presentation.util.calculateWindowWidthSizeClass
|
||||
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.model.Download
|
||||
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.webview.WebViewActivity
|
||||
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.toast
|
||||
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
|
||||
@ -211,7 +211,7 @@ class MangaController :
|
||||
{
|
||||
AddDuplicateMangaDialog(
|
||||
target = this,
|
||||
libraryManga = it.toDbManga(),
|
||||
libraryManga = it,
|
||||
onAddToLibrary = { onFavoriteClick(checkDuplicate = false) },
|
||||
).showDialog(router)
|
||||
}
|
||||
@ -225,7 +225,7 @@ class MangaController :
|
||||
QuadStateTextView.State.UNCHECKED.ordinal
|
||||
}
|
||||
}.toTypedArray()
|
||||
showChangeCategoryDialog(manga.toDbManga(), categories, preselected)
|
||||
showChangeCategoryDialog(manga, categories, preselected)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -246,10 +246,6 @@ class MangaController :
|
||||
}
|
||||
}
|
||||
|
||||
fun onTrackingClick() {
|
||||
trackSheet.show()
|
||||
}
|
||||
|
||||
private fun onCategoriesClick() {
|
||||
viewScope.launchIO {
|
||||
val manga = presenter.manga ?: return@launchIO
|
||||
@ -263,8 +259,9 @@ class MangaController :
|
||||
QuadStateTextView.State.UNCHECKED.ordinal
|
||||
}
|
||||
}.toTypedArray()
|
||||
launchUI {
|
||||
showChangeCategoryDialog(manga.toDbManga(), categories, preselected)
|
||||
|
||||
withUIContext {
|
||||
showChangeCategoryDialog(manga, categories, preselected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import android.os.Bundle
|
||||
import androidx.compose.runtime.Immutable
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
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.SyncChaptersWithTrackServiceTwoWay
|
||||
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.model.toDbTrack
|
||||
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.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainChapter
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
@ -258,22 +256,22 @@ class MangaPresenter(
|
||||
|
||||
// Now check if user previously set categories, when available
|
||||
val categories = getCategories()
|
||||
val defaultCategoryId = preferences.defaultCategory()
|
||||
val defaultCategoryId = preferences.defaultCategory().toLong()
|
||||
val defaultCategory = categories.find { it.id == defaultCategoryId }
|
||||
when {
|
||||
// Default category set
|
||||
defaultCategory != null -> {
|
||||
val result = updateManga.awaitUpdateFavorite(manga.id, true)
|
||||
if (!result) return@launchIO
|
||||
moveMangaToCategory(manga.toDbManga(), defaultCategory)
|
||||
moveMangaToCategory(defaultCategory)
|
||||
launchUI { onAdded() }
|
||||
}
|
||||
|
||||
// Automatic 'Default' or no categories
|
||||
defaultCategoryId == 0 || categories.isEmpty() -> {
|
||||
defaultCategoryId == 0L || categories.isEmpty() -> {
|
||||
val result = updateManga.awaitUpdateFavorite(manga.id, true)
|
||||
if (!result) return@launchIO
|
||||
moveMangaToCategory(manga.toDbManga(), null)
|
||||
moveMangaToCategory(null)
|
||||
launchUI { onAdded() }
|
||||
}
|
||||
|
||||
@ -326,7 +324,7 @@ class MangaPresenter(
|
||||
* @return List of categories, not including the default 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.
|
||||
* @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) }
|
||||
return categories.map { it.id.toInt() }.toTypedArray()
|
||||
return categories.map { it.id }.toTypedArray()
|
||||
}
|
||||
|
||||
fun moveMangaToCategoriesAndAddToLibrary(manga: Manga, categories: List<Category>) {
|
||||
moveMangaToCategories(manga, categories)
|
||||
fun moveMangaToCategoriesAndAddToLibrary(manga: DomainManga, categories: List<Category>) {
|
||||
moveMangaToCategories(categories)
|
||||
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 categories the selected categories.
|
||||
*/
|
||||
private fun moveMangaToCategories(manga: Manga, categories: List<Category>) {
|
||||
val mangaId = manga.id ?: return
|
||||
val categoryIds = categories.mapNotNull { it.id?.toLong() }
|
||||
private fun moveMangaToCategories(categories: List<Category>) {
|
||||
val categoryIds = categories.map { it.id }
|
||||
presenterScope.launchIO {
|
||||
setMangaCategories.await(mangaId, categoryIds)
|
||||
}
|
||||
@ -367,8 +364,8 @@ class MangaPresenter(
|
||||
* @param manga the manga to move.
|
||||
* @param category the selected category, or null for default category.
|
||||
*/
|
||||
private fun moveMangaToCategory(manga: Manga, category: Category?) {
|
||||
moveMangaToCategories(manga, listOfNotNull(category))
|
||||
private fun moveMangaToCategory(category: Category?) {
|
||||
moveMangaToCategories(listOfNotNull(category))
|
||||
}
|
||||
|
||||
private fun observeTrackingCount() {
|
||||
|
Loading…
Reference in New Issue
Block a user