mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 02:34:39 +00:00
chore: Rewriting getLibrary func
This commit is contained in:
parent
de48b52ec3
commit
893af9bd73
9 changed files with 159 additions and 24 deletions
|
@ -52,24 +52,16 @@ class CategoryPutResolver : DefaultPutResolver<Category>() {
|
|||
|
||||
class CategoryGetResolver : DefaultGetResolver<Category>() {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): Category = CategoryImpl().apply {
|
||||
id = cursor.getInt(cursor.getColumnIndex(COL_ID))
|
||||
name = cursor.getString(cursor.getColumnIndex(COL_NAME))
|
||||
order = cursor.getInt(cursor.getColumnIndex(COL_ORDER))
|
||||
flags = cursor.getInt(cursor.getColumnIndex(COL_FLAGS))
|
||||
override fun mapFromCursor(cursor: Cursor): Category = CategoryImpl().also {
|
||||
it.id = cursor.getInt(cursor.getColumnIndex(COL_ID))
|
||||
it.name = cursor.getString(cursor.getColumnIndex(COL_NAME))
|
||||
it.order = cursor.getInt(cursor.getColumnIndex(COL_ORDER))
|
||||
it.flags = cursor.getInt(cursor.getColumnIndex(COL_FLAGS))
|
||||
|
||||
val orderString = cursor.getString(cursor.getColumnIndex(COL_MANGA_ORDER))
|
||||
when {
|
||||
orderString.isNullOrBlank() -> {
|
||||
mangaSort = 'a'
|
||||
mangaOrder = emptyList()
|
||||
}
|
||||
orderString.firstOrNull()?.isLetter() == true -> {
|
||||
mangaSort = orderString.first()
|
||||
mangaOrder = emptyList()
|
||||
}
|
||||
else -> mangaOrder = orderString.split("/").mapNotNull { it.toLongOrNull() }
|
||||
}
|
||||
val (sort, order) = Category.mangaOrderFromString(orderString)
|
||||
if (sort != null) it.mangaSort = sort
|
||||
it.mangaOrder = order
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ interface Category : Serializable {
|
|||
|
||||
var langId: String?
|
||||
|
||||
var isSystem: Boolean
|
||||
|
||||
fun isAscending(): Boolean {
|
||||
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
|
||||
}
|
||||
|
@ -61,6 +63,7 @@ interface Category : Serializable {
|
|||
fun createDefault(context: Context): Category =
|
||||
create(context.getString(R.string.default_value)).apply {
|
||||
id = 0
|
||||
isSystem = true
|
||||
}
|
||||
|
||||
fun createCustom(name: String, libSort: Int, ascending: Boolean): Category =
|
||||
|
@ -78,6 +81,36 @@ interface Category : Serializable {
|
|||
id = -1
|
||||
order = -1
|
||||
isAlone = true
|
||||
isSystem = true
|
||||
}
|
||||
|
||||
fun mangaOrderFromString(orderString: String?): Pair<Char?, List<Long>> {
|
||||
return when {
|
||||
orderString.isNullOrBlank() -> {
|
||||
Pair('a', emptyList())
|
||||
}
|
||||
orderString.firstOrNull()?.isLetter() == true -> {
|
||||
Pair(orderString.first(), emptyList())
|
||||
}
|
||||
else -> Pair(null, orderString.split("/").mapNotNull { it.toLongOrNull() })
|
||||
}
|
||||
}
|
||||
|
||||
fun mapper(
|
||||
id: Long,
|
||||
name: String,
|
||||
sort: Long,
|
||||
flags: Long,
|
||||
orderString: String,
|
||||
) = create(name).also {
|
||||
it.id = id.toInt()
|
||||
it.name = name
|
||||
it.order = sort.toInt()
|
||||
it.flags = flags.toInt()
|
||||
|
||||
val (mangaSort, order) = mangaOrderFromString(orderString)
|
||||
if (mangaSort != null) it.mangaSort = mangaSort
|
||||
it.mangaOrder = order
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ class CategoryImpl : Category {
|
|||
|
||||
override var langId: String? = null
|
||||
|
||||
override var isSystem: Boolean = false
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
|
|
@ -49,12 +49,15 @@ import eu.kanade.tachiyomi.util.system.launchUI
|
|||
import eu.kanade.tachiyomi.util.system.withIOContext
|
||||
import eu.kanade.tachiyomi.util.system.withUIContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import yokai.domain.category.interactor.GetCategories
|
||||
import yokai.domain.chapter.interactor.GetChapters
|
||||
import yokai.domain.manga.interactor.GetLibraryManga
|
||||
import yokai.util.isLewd
|
||||
|
@ -63,6 +66,11 @@ import java.util.concurrent.*
|
|||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Typealias for the library manga, using the category as keys, and list of manga as values.
|
||||
*/
|
||||
typealias LibraryMap = Map<Category, List<LibraryItem>>
|
||||
|
||||
/**
|
||||
* Presenter of [LibraryController].
|
||||
*/
|
||||
|
@ -75,6 +83,7 @@ class LibraryPresenter(
|
|||
private val chapterFilter: ChapterFilter = Injekt.get(),
|
||||
private val trackManager: TrackManager = Injekt.get(),
|
||||
) : BaseCoroutinePresenter<LibraryController>(), DownloadQueue.DownloadListener {
|
||||
private val getCategories: GetCategories by injectLazy()
|
||||
private val getLibraryManga: GetLibraryManga by injectLazy()
|
||||
private val getChapters: GetChapters by injectLazy()
|
||||
|
||||
|
@ -189,14 +198,15 @@ class LibraryPresenter(
|
|||
|
||||
/** Get favorited manga for library and sort and filter it */
|
||||
fun getLibrary() {
|
||||
if (categories.isEmpty()) {
|
||||
val dbCategories = db.getCategories().executeAsBlocking()
|
||||
if ((dbCategories + Category.createDefault(context)).distinctBy { it.order }.size != dbCategories.size + 1) {
|
||||
reorderCategories(dbCategories)
|
||||
}
|
||||
categories = lastCategories ?: db.getCategories().executeAsBlocking().toMutableList()
|
||||
}
|
||||
presenterScope.launch {
|
||||
if (categories.isEmpty()) {
|
||||
val dbCategories = getCategories.await()
|
||||
if ((dbCategories + Category.createDefault(context)).distinctBy { it.order }.size != dbCategories.size + 1) {
|
||||
reorderCategories(dbCategories)
|
||||
}
|
||||
categories = lastCategories ?: getCategories.await().toMutableList()
|
||||
}
|
||||
|
||||
val (library, hiddenItems) = withIOContext { getLibraryFromDB() }
|
||||
setDownloadCount(library)
|
||||
setUnreadBadge(library)
|
||||
|
@ -700,6 +710,54 @@ class LibraryPresenter(
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Migrate getCategories to SQLDelight
|
||||
/*
|
||||
private fun getPreferencesFlow() = combine(
|
||||
) {
|
||||
ItemPreferences(
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
||||
private fun getLibraryFlow(): Flow<LibraryMap> {
|
||||
return combine(
|
||||
getCategories.subscribe(),
|
||||
getLibraryManga.subscribe(),
|
||||
) { categories, libraryMangaList ->
|
||||
val categoryAll = Category.createAll(
|
||||
context,
|
||||
preferences.librarySortingMode().get(),
|
||||
preferences.librarySortingAscending().get(),
|
||||
)
|
||||
val catItemAll = LibraryHeaderItem({ categoryAll }, -1)
|
||||
val categorySet = mutableSetOf<Int>()
|
||||
val headerItems = (
|
||||
categories.mapNotNull { category ->
|
||||
val id = category.id
|
||||
if (id == null) {
|
||||
null
|
||||
} else {
|
||||
id to LibraryHeaderItem({ getCategory(id) }, id)
|
||||
}
|
||||
} + (-1 to catItemAll) + (0 to LibraryHeaderItem({ getCategory(0) }, 0))
|
||||
).toMap()
|
||||
|
||||
val libraryManga = libraryMangaList.mapNotNull {
|
||||
val headerItem = (
|
||||
if (!libraryIsGrouped) {
|
||||
catItemAll
|
||||
} else {
|
||||
headerItems[it.category]
|
||||
}
|
||||
) ?: return@mapNotNull null
|
||||
categorySet.add(it.category)
|
||||
LibraryItem(it, headerItem, viewContext)
|
||||
}.groupBy { it.manga.category }
|
||||
|
||||
categories.associateWith { libraryManga[it.id].orEmpty() }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the categories and all its manga from the database.
|
||||
*
|
||||
|
@ -707,7 +765,7 @@ class LibraryPresenter(
|
|||
*/
|
||||
private suspend fun getLibraryFromDB(): Pair<List<LibraryItem>, List<LibraryItem>> {
|
||||
removeArticles = preferences.removeArticles().get()
|
||||
val categories = db.getCategories().executeAsBlocking().toMutableList()
|
||||
val categories = getCategories.await().toMutableList()
|
||||
var libraryManga = getLibraryManga.await()
|
||||
val showAll = showAllCategories
|
||||
if (groupType > BY_DEFAULT) {
|
||||
|
@ -1491,4 +1549,10 @@ class LibraryPresenter(
|
|||
view?.updateDownloadStatus(!downloadManager.isPaused())
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Immutable
|
||||
data class ItemPreferences(
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -5,10 +5,13 @@ import uy.kohesive.injekt.api.InjektRegistrar
|
|||
import uy.kohesive.injekt.api.addFactory
|
||||
import uy.kohesive.injekt.api.addSingletonFactory
|
||||
import uy.kohesive.injekt.api.get
|
||||
import yokai.data.category.CategoryRepositoryImpl
|
||||
import yokai.data.chapter.ChapterRepositoryImpl
|
||||
import yokai.data.extension.repo.ExtensionRepoRepositoryImpl
|
||||
import yokai.data.library.custom.CustomMangaRepositoryImpl
|
||||
import yokai.data.manga.MangaRepositoryImpl
|
||||
import yokai.domain.category.CategoryRepository
|
||||
import yokai.domain.category.interactor.GetCategories
|
||||
import yokai.domain.chapter.ChapterRepository
|
||||
import yokai.domain.chapter.interactor.GetAvailableScanlators
|
||||
import yokai.domain.chapter.interactor.GetChapters
|
||||
|
@ -52,5 +55,8 @@ class DomainModule : InjektModule {
|
|||
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
||||
addFactory { GetAvailableScanlators(get()) }
|
||||
addFactory { GetChapters(get()) }
|
||||
|
||||
addSingletonFactory<CategoryRepository> { CategoryRepositoryImpl(get()) }
|
||||
addFactory { GetCategories(get()) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package yokai.data.category
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import yokai.data.DatabaseHandler
|
||||
import yokai.domain.category.CategoryRepository
|
||||
|
||||
class CategoryRepositoryImpl(private val handler: DatabaseHandler) : CategoryRepository {
|
||||
override suspend fun getAll(): List<Category> =
|
||||
handler.awaitList { categoriesQueries.findAll(Category::mapper) }
|
||||
|
||||
override fun getAllAsFlow(): Flow<List<Category>> =
|
||||
handler.subscribeToList { categoriesQueries.findAll(Category::mapper) }
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package yokai.domain.category
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface CategoryRepository {
|
||||
suspend fun getAll(): List<Category>
|
||||
fun getAllAsFlow(): Flow<List<Category>>
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package yokai.domain.category.interactor
|
||||
|
||||
import yokai.domain.category.CategoryRepository
|
||||
|
||||
class GetCategories(
|
||||
val categoryRepository: CategoryRepository,
|
||||
) {
|
||||
suspend fun await() = categoryRepository.getAll()
|
||||
fun subscribe() = categoryRepository.getAllAsFlow()
|
||||
}
|
|
@ -5,3 +5,8 @@ CREATE TABLE categories(
|
|||
flags INTEGER NOT NULL,
|
||||
manga_order TEXT NOT NULL
|
||||
);
|
||||
|
||||
findAll:
|
||||
SELECT *
|
||||
FROM categories
|
||||
ORDER BY sort;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue