mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +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>() {
|
class CategoryGetResolver : DefaultGetResolver<Category>() {
|
||||||
|
|
||||||
override fun mapFromCursor(cursor: Cursor): Category = CategoryImpl().apply {
|
override fun mapFromCursor(cursor: Cursor): Category = CategoryImpl().also {
|
||||||
id = cursor.getInt(cursor.getColumnIndex(COL_ID))
|
it.id = cursor.getInt(cursor.getColumnIndex(COL_ID))
|
||||||
name = cursor.getString(cursor.getColumnIndex(COL_NAME))
|
it.name = cursor.getString(cursor.getColumnIndex(COL_NAME))
|
||||||
order = cursor.getInt(cursor.getColumnIndex(COL_ORDER))
|
it.order = cursor.getInt(cursor.getColumnIndex(COL_ORDER))
|
||||||
flags = cursor.getInt(cursor.getColumnIndex(COL_FLAGS))
|
it.flags = cursor.getInt(cursor.getColumnIndex(COL_FLAGS))
|
||||||
|
|
||||||
val orderString = cursor.getString(cursor.getColumnIndex(COL_MANGA_ORDER))
|
val orderString = cursor.getString(cursor.getColumnIndex(COL_MANGA_ORDER))
|
||||||
when {
|
val (sort, order) = Category.mangaOrderFromString(orderString)
|
||||||
orderString.isNullOrBlank() -> {
|
if (sort != null) it.mangaSort = sort
|
||||||
mangaSort = 'a'
|
it.mangaOrder = order
|
||||||
mangaOrder = emptyList()
|
|
||||||
}
|
|
||||||
orderString.firstOrNull()?.isLetter() == true -> {
|
|
||||||
mangaSort = orderString.first()
|
|
||||||
mangaOrder = emptyList()
|
|
||||||
}
|
|
||||||
else -> mangaOrder = orderString.split("/").mapNotNull { it.toLongOrNull() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ interface Category : Serializable {
|
||||||
|
|
||||||
var langId: String?
|
var langId: String?
|
||||||
|
|
||||||
|
var isSystem: Boolean
|
||||||
|
|
||||||
fun isAscending(): Boolean {
|
fun isAscending(): Boolean {
|
||||||
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
|
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
|
||||||
}
|
}
|
||||||
|
@ -61,6 +63,7 @@ interface Category : Serializable {
|
||||||
fun createDefault(context: Context): Category =
|
fun createDefault(context: Context): Category =
|
||||||
create(context.getString(R.string.default_value)).apply {
|
create(context.getString(R.string.default_value)).apply {
|
||||||
id = 0
|
id = 0
|
||||||
|
isSystem = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCustom(name: String, libSort: Int, ascending: Boolean): Category =
|
fun createCustom(name: String, libSort: Int, ascending: Boolean): Category =
|
||||||
|
@ -78,6 +81,36 @@ interface Category : Serializable {
|
||||||
id = -1
|
id = -1
|
||||||
order = -1
|
order = -1
|
||||||
isAlone = true
|
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 langId: String? = null
|
||||||
|
|
||||||
|
override var isSystem: Boolean = false
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other == null || javaClass != other.javaClass) return false
|
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.withIOContext
|
||||||
import eu.kanade.tachiyomi.util.system.withUIContext
|
import eu.kanade.tachiyomi.util.system.withUIContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import yokai.domain.category.interactor.GetCategories
|
||||||
import yokai.domain.chapter.interactor.GetChapters
|
import yokai.domain.chapter.interactor.GetChapters
|
||||||
import yokai.domain.manga.interactor.GetLibraryManga
|
import yokai.domain.manga.interactor.GetLibraryManga
|
||||||
import yokai.util.isLewd
|
import yokai.util.isLewd
|
||||||
|
@ -63,6 +66,11 @@ import java.util.concurrent.*
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.random.Random
|
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].
|
* Presenter of [LibraryController].
|
||||||
*/
|
*/
|
||||||
|
@ -75,6 +83,7 @@ class LibraryPresenter(
|
||||||
private val chapterFilter: ChapterFilter = Injekt.get(),
|
private val chapterFilter: ChapterFilter = Injekt.get(),
|
||||||
private val trackManager: TrackManager = Injekt.get(),
|
private val trackManager: TrackManager = Injekt.get(),
|
||||||
) : BaseCoroutinePresenter<LibraryController>(), DownloadQueue.DownloadListener {
|
) : BaseCoroutinePresenter<LibraryController>(), DownloadQueue.DownloadListener {
|
||||||
|
private val getCategories: GetCategories by injectLazy()
|
||||||
private val getLibraryManga: GetLibraryManga by injectLazy()
|
private val getLibraryManga: GetLibraryManga by injectLazy()
|
||||||
private val getChapters: GetChapters by injectLazy()
|
private val getChapters: GetChapters by injectLazy()
|
||||||
|
|
||||||
|
@ -189,14 +198,15 @@ class LibraryPresenter(
|
||||||
|
|
||||||
/** Get favorited manga for library and sort and filter it */
|
/** Get favorited manga for library and sort and filter it */
|
||||||
fun getLibrary() {
|
fun getLibrary() {
|
||||||
|
presenterScope.launch {
|
||||||
if (categories.isEmpty()) {
|
if (categories.isEmpty()) {
|
||||||
val dbCategories = db.getCategories().executeAsBlocking()
|
val dbCategories = getCategories.await()
|
||||||
if ((dbCategories + Category.createDefault(context)).distinctBy { it.order }.size != dbCategories.size + 1) {
|
if ((dbCategories + Category.createDefault(context)).distinctBy { it.order }.size != dbCategories.size + 1) {
|
||||||
reorderCategories(dbCategories)
|
reorderCategories(dbCategories)
|
||||||
}
|
}
|
||||||
categories = lastCategories ?: db.getCategories().executeAsBlocking().toMutableList()
|
categories = lastCategories ?: getCategories.await().toMutableList()
|
||||||
}
|
}
|
||||||
presenterScope.launch {
|
|
||||||
val (library, hiddenItems) = withIOContext { getLibraryFromDB() }
|
val (library, hiddenItems) = withIOContext { getLibraryFromDB() }
|
||||||
setDownloadCount(library)
|
setDownloadCount(library)
|
||||||
setUnreadBadge(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.
|
* 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>> {
|
private suspend fun getLibraryFromDB(): Pair<List<LibraryItem>, List<LibraryItem>> {
|
||||||
removeArticles = preferences.removeArticles().get()
|
removeArticles = preferences.removeArticles().get()
|
||||||
val categories = db.getCategories().executeAsBlocking().toMutableList()
|
val categories = getCategories.await().toMutableList()
|
||||||
var libraryManga = getLibraryManga.await()
|
var libraryManga = getLibraryManga.await()
|
||||||
val showAll = showAllCategories
|
val showAll = showAllCategories
|
||||||
if (groupType > BY_DEFAULT) {
|
if (groupType > BY_DEFAULT) {
|
||||||
|
@ -1491,4 +1549,10 @@ class LibraryPresenter(
|
||||||
view?.updateDownloadStatus(!downloadManager.isPaused())
|
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.addFactory
|
||||||
import uy.kohesive.injekt.api.addSingletonFactory
|
import uy.kohesive.injekt.api.addSingletonFactory
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
import yokai.data.category.CategoryRepositoryImpl
|
||||||
import yokai.data.chapter.ChapterRepositoryImpl
|
import yokai.data.chapter.ChapterRepositoryImpl
|
||||||
import yokai.data.extension.repo.ExtensionRepoRepositoryImpl
|
import yokai.data.extension.repo.ExtensionRepoRepositoryImpl
|
||||||
import yokai.data.library.custom.CustomMangaRepositoryImpl
|
import yokai.data.library.custom.CustomMangaRepositoryImpl
|
||||||
import yokai.data.manga.MangaRepositoryImpl
|
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.ChapterRepository
|
||||||
import yokai.domain.chapter.interactor.GetAvailableScanlators
|
import yokai.domain.chapter.interactor.GetAvailableScanlators
|
||||||
import yokai.domain.chapter.interactor.GetChapters
|
import yokai.domain.chapter.interactor.GetChapters
|
||||||
|
@ -52,5 +55,8 @@ class DomainModule : InjektModule {
|
||||||
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
||||||
addFactory { GetAvailableScanlators(get()) }
|
addFactory { GetAvailableScanlators(get()) }
|
||||||
addFactory { GetChapters(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,
|
flags INTEGER NOT NULL,
|
||||||
manga_order TEXT 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