Migrate to more use of domain models

This commit is contained in:
arkon
2022-07-02 17:14:19 -04:00
parent 2674570792
commit 76c0ead1db
32 changed files with 184 additions and 235 deletions
@@ -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()