mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-15 05:27:28 +01:00
Use SQLDelight on Library screen (#7432)
- Uses the new `asObservable` function to change the database calls to use SQLDelight, which should make the impact minimal when it comes to bugs. - Use interactors where they already exist - The todos are for the Compose rewrite - Removed unused StorIO methods/queries - Tested loading library, move manga to new category, unfavorite multiple manga, move multiple manga from one category to another, change filter, sort and display settings (with and without per category settings), (un)mark chapters, start/delete downloads Thank Syer for asObservable Co-authored-by: jobobby04 <17078382+jobobby04@users.noreply.github.com> Co-authored-by: jobobby04 <17078382+jobobby04@users.noreply.github.com>
This commit is contained in:
@@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.interactor.MoveMangaToCategories
|
||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||
@@ -48,7 +48,7 @@ class SearchPresenter(
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val getTracks: GetTracks = Injekt.get(),
|
||||
private val insertTrack: InsertTrack = Injekt.get(),
|
||||
private val moveMangaToCategories: MoveMangaToCategories = Injekt.get(),
|
||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||
) : GlobalSearchPresenter(initialQuery) {
|
||||
|
||||
private val replacingMangaRelay = BehaviorRelay.create<Pair<Boolean, Manga?>>()
|
||||
@@ -164,7 +164,7 @@ class SearchPresenter(
|
||||
// Update categories
|
||||
if (migrateCategories) {
|
||||
val categoryIds = getCategories.await(prevDomainManga.id).map { it.id }
|
||||
moveMangaToCategories.await(domainManga.id, categoryIds)
|
||||
setMangaCategories.await(domainManga.id, categoryIds)
|
||||
}
|
||||
|
||||
// Update track
|
||||
|
||||
@@ -29,6 +29,8 @@ import eu.kanade.tachiyomi.ui.base.controller.pushController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.preference.asImmediateFlow
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||
@@ -36,6 +38,7 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.widget.ActionModeWithToolbar
|
||||
import eu.kanade.tachiyomi.widget.EmptyView
|
||||
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -226,6 +229,7 @@ class LibraryController(
|
||||
destroyActionModeIfNeeded()
|
||||
adapter?.onDestroy()
|
||||
adapter = null
|
||||
settingsSheet?.sheetScope?.cancel()
|
||||
settingsSheet = null
|
||||
tabsVisibilitySubscription?.unsubscribe()
|
||||
tabsVisibilitySubscription = null
|
||||
@@ -541,25 +545,29 @@ class LibraryController(
|
||||
* Move the selected manga to a list of categories.
|
||||
*/
|
||||
private fun showMangaCategoriesDialog() {
|
||||
// Create a copy of selected manga
|
||||
val mangas = selectedMangas.toList()
|
||||
viewScope.launchIO {
|
||||
// Create a copy of selected manga
|
||||
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 }
|
||||
// Hide the default category because it has a different behavior than the ones from db.
|
||||
val categories = presenter.categories.filter { it.id != 0 }
|
||||
|
||||
// Get indexes of the common categories to preselect.
|
||||
val common = presenter.getCommonCategories(mangas)
|
||||
// Get indexes of the mix categories to preselect.
|
||||
val mix = presenter.getMixCategories(mangas)
|
||||
val preselected = categories.map {
|
||||
when (it) {
|
||||
in common -> QuadStateTextView.State.CHECKED.ordinal
|
||||
in mix -> QuadStateTextView.State.INDETERMINATE.ordinal
|
||||
else -> QuadStateTextView.State.UNCHECKED.ordinal
|
||||
// Get indexes of the common categories to preselect.
|
||||
val common = presenter.getCommonCategories(mangas)
|
||||
// Get indexes of the mix categories to preselect.
|
||||
val mix = presenter.getMixCategories(mangas)
|
||||
val preselected = categories.map {
|
||||
when (it) {
|
||||
in common -> QuadStateTextView.State.CHECKED.ordinal
|
||||
in mix -> QuadStateTextView.State.INDETERMINATE.ordinal
|
||||
else -> QuadStateTextView.State.UNCHECKED.ordinal
|
||||
}
|
||||
}.toTypedArray()
|
||||
launchUI {
|
||||
ChangeMangaCategoriesDialog(this@LibraryController, mangas, categories, preselected)
|
||||
.showDialog(router)
|
||||
}
|
||||
}.toTypedArray()
|
||||
ChangeMangaCategoriesDialog(this, mangas, categories, preselected)
|
||||
.showDialog(router)
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadUnreadChapters() {
|
||||
@@ -579,7 +587,7 @@ class LibraryController(
|
||||
}
|
||||
|
||||
override fun updateCategoriesForMangas(mangas: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) {
|
||||
presenter.updateMangasToCategories(mangas, addCategories, removeCategories)
|
||||
presenter.setMangaCategories(mangas, addCategories, removeCategories)
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,23 @@ package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
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.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.MangaUpdate
|
||||
import eu.kanade.domain.track.interactor.GetTracks
|
||||
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
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
@@ -23,6 +34,8 @@ 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
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
@@ -47,7 +60,13 @@ private typealias LibraryMap = Map<Int, List<LibraryItem>>
|
||||
* Presenter of [LibraryController].
|
||||
*/
|
||||
class LibraryPresenter(
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val handler: DatabaseHandler = Injekt.get(),
|
||||
private val getTracks: GetTracks = Injekt.get(),
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||
private val preferences: PreferencesHelper = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
@@ -92,6 +111,7 @@ class LibraryPresenter(
|
||||
* Subscribes to library if needed.
|
||||
*/
|
||||
fun subscribeLibrary() {
|
||||
// TODO: Move this to a coroutine world
|
||||
if (librarySubscription.isNullOrUnsubscribed()) {
|
||||
librarySubscription = getLibraryObservable()
|
||||
.combineLatest(badgeTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
||||
@@ -115,7 +135,7 @@ class LibraryPresenter(
|
||||
*
|
||||
* @param map the map to filter.
|
||||
*/
|
||||
private fun applyFilters(map: LibraryMap, trackMap: Map<Long, Map<Int, Boolean>>): LibraryMap {
|
||||
private fun applyFilters(map: LibraryMap, trackMap: Map<Long, Map<Long, Boolean>>): LibraryMap {
|
||||
val downloadedOnly = preferences.downloadedOnly().get()
|
||||
val filterDownloaded = preferences.filterDownloaded().get()
|
||||
val filterUnread = preferences.filterUnread().get()
|
||||
@@ -252,18 +272,30 @@ class LibraryPresenter(
|
||||
private fun applySort(categories: List<Category>, map: LibraryMap): LibraryMap {
|
||||
val lastReadManga by lazy {
|
||||
var counter = 0
|
||||
// Result comes as newest to oldest so it's reversed
|
||||
db.getLastReadManga().executeAsBlocking().reversed().associate { it.id!! to counter++ }
|
||||
// TODO: Make [applySort] a suspended function
|
||||
runBlocking {
|
||||
handler.awaitList {
|
||||
mangasQueries.getLastRead()
|
||||
}.associate { it._id to counter++ }
|
||||
}
|
||||
}
|
||||
val latestChapterManga by lazy {
|
||||
var counter = 0
|
||||
// Result comes as newest to oldest so it's reversed
|
||||
db.getLatestChapterManga().executeAsBlocking().reversed().associate { it.id!! to counter++ }
|
||||
// TODO: Make [applySort] a suspended function
|
||||
runBlocking {
|
||||
handler.awaitList {
|
||||
mangasQueries.getLatestByChapterUploadDate()
|
||||
}.associate { it._id to counter++ }
|
||||
}
|
||||
}
|
||||
val chapterFetchDateManga by lazy {
|
||||
var counter = 0
|
||||
// Result comes as newest to oldest so it's reversed
|
||||
db.getChapterFetchDateManga().executeAsBlocking().reversed().associate { it.id!! to counter++ }
|
||||
// TODO: Make [applySort] a suspended function
|
||||
runBlocking {
|
||||
handler.awaitList {
|
||||
mangasQueries.getLatestByChapterFetchDate()
|
||||
}.associate { it._id to counter++ }
|
||||
}
|
||||
}
|
||||
|
||||
val sortingModes = categories.associate { category ->
|
||||
@@ -366,7 +398,7 @@ class LibraryPresenter(
|
||||
* @return an observable of the categories.
|
||||
*/
|
||||
private fun getCategoriesObservable(): Observable<List<Category>> {
|
||||
return db.getCategories().asRxObservable()
|
||||
return getCategories.subscribe().map { it.map { it.toDbCategory() } }.asObservable()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,7 +410,36 @@ class LibraryPresenter(
|
||||
private fun getLibraryMangasObservable(): Observable<LibraryMap> {
|
||||
val defaultLibraryDisplayMode = preferences.libraryDisplayMode()
|
||||
val shouldSetFromCategory = preferences.categorizedDisplaySettings()
|
||||
return db.getLibraryMangas().asRxObservable()
|
||||
|
||||
// TODO: Move this to domain/data layer
|
||||
return handler
|
||||
.subscribeToList {
|
||||
mangasQueries.getLibrary { _id: Long, source: Long, url: String, artist: String?, author: String?, description: String?, genre: List<String>?, title: String, status: Long, thumbnail_url: String?, favorite: Boolean, last_update: Long?, next_update: Long?, initialized: Boolean, viewer: Long, chapter_flags: Long, cover_last_modified: Long, date_added: Long, unread_count: Long, read_count: Long, category: Long ->
|
||||
LibraryManga().apply {
|
||||
this.id = _id
|
||||
this.source = source
|
||||
this.url = url
|
||||
this.artist = artist
|
||||
this.author = author
|
||||
this.description = description
|
||||
this.genre = genre?.joinToString()
|
||||
this.title = title
|
||||
this.status = status.toInt()
|
||||
this.thumbnail_url = thumbnail_url
|
||||
this.favorite = favorite
|
||||
this.last_update = last_update ?: 0
|
||||
this.initialized = initialized
|
||||
this.viewer_flags = viewer.toInt()
|
||||
this.chapter_flags = chapter_flags.toInt()
|
||||
this.cover_last_modified = cover_last_modified
|
||||
this.date_added = date_added
|
||||
this.unreadCount = unread_count.toInt()
|
||||
this.readCount = read_count.toInt()
|
||||
this.category = category.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
.asObservable()
|
||||
.map { list ->
|
||||
list.map { libraryManga ->
|
||||
// Display mode based on user preference: take it from global library setting or category
|
||||
@@ -396,7 +457,7 @@ class LibraryPresenter(
|
||||
*
|
||||
* @return an observable of tracked manga.
|
||||
*/
|
||||
private fun getFilterObservable(): Observable<Map<Long, Map<Int, Boolean>>> {
|
||||
private fun getFilterObservable(): Observable<Map<Long, Map<Long, Boolean>>> {
|
||||
return getTracksObservable().combineLatest(filterTriggerRelay.observeOn(Schedulers.io())) { tracks, _ -> tracks }
|
||||
}
|
||||
|
||||
@@ -405,16 +466,20 @@ class LibraryPresenter(
|
||||
*
|
||||
* @return an observable of tracked manga.
|
||||
*/
|
||||
private fun getTracksObservable(): Observable<Map<Long, Map<Int, Boolean>>> {
|
||||
return db.getTracks().asRxObservable().map { tracks ->
|
||||
tracks.groupBy { it.manga_id }
|
||||
.mapValues { tracksForMangaId ->
|
||||
// Check if any of the trackers is logged in for the current manga id
|
||||
tracksForMangaId.value.associate {
|
||||
Pair(it.sync_id, trackManager.getService(it.sync_id.toLong())?.isLogged ?: false)
|
||||
private fun getTracksObservable(): Observable<Map<Long, Map<Long, Boolean>>> {
|
||||
// TODO: Move this to domain/data layer
|
||||
return getTracks.subscribe()
|
||||
.asObservable().map { tracks ->
|
||||
tracks
|
||||
.groupBy { it.mangaId }
|
||||
.mapValues { tracksForMangaId ->
|
||||
// Check if any of the trackers is logged in for the current manga id
|
||||
tracksForMangaId.value.associate {
|
||||
Pair(it.syncId, trackManager.getService(it.syncId)?.isLogged ?: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.observeOn(Schedulers.io())
|
||||
}
|
||||
.observeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -451,11 +516,11 @@ class LibraryPresenter(
|
||||
*
|
||||
* @param mangas the list of manga.
|
||||
*/
|
||||
fun getCommonCategories(mangas: List<Manga>): Collection<Category> {
|
||||
suspend fun getCommonCategories(mangas: List<Manga>): Collection<Category> {
|
||||
if (mangas.isEmpty()) return emptyList()
|
||||
return mangas.toSet()
|
||||
.map { db.getCategoriesForManga(it).executeAsBlocking() }
|
||||
.reduce { set1: Iterable<Category>, set2 -> set1.intersect(set2).toMutableList() }
|
||||
.map { getCategories.await(it.id!!).map { it.toDbCategory() } }
|
||||
.reduce { set1, set2 -> set1.intersect(set2).toMutableList() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,9 +528,9 @@ class LibraryPresenter(
|
||||
*
|
||||
* @param mangas the list of manga.
|
||||
*/
|
||||
fun getMixCategories(mangas: List<Manga>): Collection<Category> {
|
||||
suspend fun getMixCategories(mangas: List<Manga>): Collection<Category> {
|
||||
if (mangas.isEmpty()) return emptyList()
|
||||
val mangaCategories = mangas.toSet().map { db.getCategoriesForManga(it).executeAsBlocking() }
|
||||
val mangaCategories = mangas.toSet().map { getCategories.await(it.id!!).map { it.toDbCategory() } }
|
||||
val common = mangaCategories.reduce { set1, set2 -> set1.intersect(set2).toMutableList() }
|
||||
return mangaCategories.flatten().distinct().subtract(common).toMutableList()
|
||||
}
|
||||
@@ -478,8 +543,9 @@ class LibraryPresenter(
|
||||
fun downloadUnreadChapters(mangas: List<Manga>) {
|
||||
mangas.forEach { manga ->
|
||||
launchIO {
|
||||
val chapters = db.getChapters(manga).executeAsBlocking()
|
||||
val chapters = getChapterByMangaId.await(manga.id!!)
|
||||
.filter { !it.read }
|
||||
.map { it.toDbChapter() }
|
||||
|
||||
downloadManager.downloadChapters(manga, chapters)
|
||||
}
|
||||
@@ -494,17 +560,20 @@ class LibraryPresenter(
|
||||
fun markReadStatus(mangas: List<Manga>, read: Boolean) {
|
||||
mangas.forEach { manga ->
|
||||
launchIO {
|
||||
val chapters = db.getChapters(manga).executeAsBlocking()
|
||||
chapters.forEach {
|
||||
it.read = read
|
||||
if (!read) {
|
||||
it.last_page_read = 0
|
||||
val chapters = getChapterByMangaId.await(manga.id!!)
|
||||
|
||||
val toUpdate = chapters
|
||||
.map { chapter ->
|
||||
ChapterUpdate(
|
||||
read = read,
|
||||
lastPageRead = if (read) 0 else null,
|
||||
id = chapter.id,
|
||||
)
|
||||
}
|
||||
}
|
||||
db.updateChaptersProgress(chapters).executeAsBlocking()
|
||||
updateChapter.awaitAll(toUpdate)
|
||||
|
||||
if (read && preferences.removeAfterMarkedAsRead()) {
|
||||
deleteChapters(manga, chapters)
|
||||
deleteChapters(manga, chapters.map { it.toDbChapter() })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,20 +588,23 @@ class LibraryPresenter(
|
||||
/**
|
||||
* Remove the selected manga.
|
||||
*
|
||||
* @param mangas the list of manga to delete.
|
||||
* @param mangaList the list of manga to delete.
|
||||
* @param deleteFromLibrary whether to delete manga from library.
|
||||
* @param deleteChapters whether to delete downloaded chapters.
|
||||
*/
|
||||
fun removeMangas(mangas: List<Manga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) {
|
||||
fun removeMangas(mangaList: List<Manga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) {
|
||||
launchIO {
|
||||
val mangaToDelete = mangas.distinctBy { it.id }
|
||||
val mangaToDelete = mangaList.distinctBy { it.id }
|
||||
|
||||
if (deleteFromLibrary) {
|
||||
mangaToDelete.forEach {
|
||||
it.favorite = false
|
||||
val toDelete = mangaToDelete.map {
|
||||
it.removeCovers(coverCache)
|
||||
MangaUpdate(
|
||||
favorite = false,
|
||||
id = it.id!!,
|
||||
)
|
||||
}
|
||||
db.insertMangas(mangaToDelete).executeAsBlocking()
|
||||
updateManga.awaitAll(toDelete)
|
||||
}
|
||||
|
||||
if (deleteChapters) {
|
||||
@@ -547,35 +619,22 @@ class LibraryPresenter(
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the given list of manga to categories.
|
||||
* Bulk update categories of manga using old and new common categories.
|
||||
*
|
||||
* @param categories the selected categories.
|
||||
* @param mangas the list of manga to move.
|
||||
*/
|
||||
fun moveMangasToCategories(categories: List<Category>, mangas: List<Manga>) {
|
||||
val mc = mutableListOf<MangaCategory>()
|
||||
|
||||
for (manga in mangas) {
|
||||
categories.mapTo(mc) { MangaCategory.create(manga, it) }
|
||||
}
|
||||
|
||||
db.setMangaCategories(mc, mangas)
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk update categories of mangas using old and new common categories.
|
||||
*
|
||||
* @param mangas the list of manga to move.
|
||||
* @param mangaList the list of manga to move.
|
||||
* @param addCategories the categories to add for all mangas.
|
||||
* @param removeCategories the categories to remove in all mangas.
|
||||
*/
|
||||
fun updateMangasToCategories(mangas: List<Manga>, addCategories: List<Category>, removeCategories: List<Category>) {
|
||||
val mangaCategories = mangas.map { manga ->
|
||||
val categories = db.getCategoriesForManga(manga).executeAsBlocking()
|
||||
.subtract(removeCategories).plus(addCategories).distinct()
|
||||
categories.map { MangaCategory.create(manga, it) }
|
||||
}.flatten()
|
||||
|
||||
db.setMangaCategories(mangaCategories, mangas)
|
||||
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() }
|
||||
.subtract(removeCategories)
|
||||
.plus(addCategories)
|
||||
.mapNotNull { it.id?.toLong() }
|
||||
setMangaCategories.await(manga.id!!, categoryIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@ import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import com.bluelinelabs.conductor.Router
|
||||
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.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
@@ -13,9 +14,13 @@ import eu.kanade.tachiyomi.data.track.TrackService
|
||||
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 eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
|
||||
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
@@ -23,13 +28,15 @@ import uy.kohesive.injekt.injectLazy
|
||||
class LibrarySettingsSheet(
|
||||
router: Router,
|
||||
private val trackManager: TrackManager = Injekt.get(),
|
||||
private val updateCategory: UpdateCategory = Injekt.get(),
|
||||
onGroupClickListener: (ExtendedNavigationView.Group) -> Unit,
|
||||
) : TabbedBottomSheetDialog(router.activity!!) {
|
||||
|
||||
val filters: Filter
|
||||
private val sort: Sort
|
||||
private val display: Display
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
|
||||
val sheetScope = CoroutineScope(Job() + Dispatchers.IO)
|
||||
|
||||
init {
|
||||
filters = Filter(router.activity!!)
|
||||
@@ -250,8 +257,14 @@ class LibrarySettingsSheet(
|
||||
|
||||
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.sortDirection = flag.flag
|
||||
|
||||
db.insertCategory(currentCategory!!).executeAsBlocking()
|
||||
sheetScope.launchIO {
|
||||
updateCategory.await(
|
||||
CategoryUpdate(
|
||||
id = currentCategory!!.id?.toLong()!!,
|
||||
flags = currentCategory!!.flags.toLong(),
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferences.librarySortingAscending().set(flag)
|
||||
}
|
||||
@@ -272,8 +285,14 @@ class LibrarySettingsSheet(
|
||||
|
||||
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.sortMode = flag.flag
|
||||
|
||||
db.insertCategory(currentCategory!!).executeAsBlocking()
|
||||
sheetScope.launchIO {
|
||||
updateCategory.await(
|
||||
CategoryUpdate(
|
||||
id = currentCategory!!.id?.toLong()!!,
|
||||
flags = currentCategory!!.flags.toLong(),
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferences.librarySortingMode().set(flag)
|
||||
}
|
||||
@@ -361,8 +380,14 @@ class LibrarySettingsSheet(
|
||||
|
||||
if (preferences.categorizedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||
currentCategory?.displayMode = flag.flag
|
||||
|
||||
db.insertCategory(currentCategory!!).executeAsBlocking()
|
||||
sheetScope.launchIO {
|
||||
updateCategory.await(
|
||||
CategoryUpdate(
|
||||
id = currentCategory!!.id?.toLong()!!,
|
||||
flags = currentCategory!!.flags.toLong(),
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferences.libraryDisplayMode().set(flag)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.manga
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Immutable
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.interactor.MoveMangaToCategories
|
||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||
@@ -90,7 +90,7 @@ class MangaPresenter(
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val deleteTrack: DeleteTrack = Injekt.get(),
|
||||
private val getTracks: GetTracks = Injekt.get(),
|
||||
private val moveMangaToCategories: MoveMangaToCategories = Injekt.get(),
|
||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||
private val insertTrack: InsertTrack = Injekt.get(),
|
||||
private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay = Injekt.get(),
|
||||
) : BasePresenter<MangaController>() {
|
||||
@@ -358,7 +358,7 @@ class MangaPresenter(
|
||||
val mangaId = manga.id ?: return
|
||||
val categoryIds = categories.mapNotNull { it.id?.toLong() }
|
||||
presenterScope.launchIO {
|
||||
moveMangaToCategories.await(mangaId, categoryIds)
|
||||
setMangaCategories.await(mangaId, categoryIds)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user