From 4f3fef3bfed9b47515a5ed7265b6facbbfcfb2be Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 25 May 2022 10:04:06 +0300 Subject: [PATCH] Update parsers --- app/build.gradle | 9 ++++- .../kotatsu/core/parser/DummyParser.kt | 4 ++- .../kotatsu/core/model/MangaSource.kt | 10 ++++++ .../kotatsu/core/parser/MangaRepository.kt | 13 +++---- .../core/parser/RemoteMangaRepository.kt | 13 +++---- .../local/domain/LocalMangaRepository.kt | 35 ++++++++++-------- .../kotatsu/local/ui/LocalListViewModel.kt | 4 +-- .../search/domain/MangaSearchRepository.kt | 4 +-- .../newsources/NewSourcesViewModel.kt | 3 +- .../sources/SourcesSettingsViewModel.kt | 7 ++-- .../adapter/SourceConfigAdapterDelegates.kt | 15 ++++---- .../main/res/layout/item_source_config.xml | 36 ++++++++++++++----- app/src/main/res/layout/navigation_header.xml | 4 ++- 13 files changed, 103 insertions(+), 54 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt diff --git a/app/build.gradle b/app/build.gradle index e1c007038..108f28f92 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,9 +64,16 @@ android { unitTests.returnDefaultValues = false } } +afterEvaluate { + compileDebugKotlin { + kotlinOptions { + freeCompilerArgs += ['-opt-in=kotlin.RequiresOptIn'] + } + } +} dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) - implementation('com.github.nv95:kotatsu-parsers:f46c5add46') { + implementation('com.github.nv95:kotatsu-parsers:ab87a50e9b') { exclude group: 'org.json', module: 'json' } diff --git a/app/src/debug/java/org/koitharu/kotatsu/core/parser/DummyParser.kt b/app/src/debug/java/org/koitharu/kotatsu/core/parser/DummyParser.kt index 4323e3a5f..479ada3ec 100644 --- a/app/src/debug/java/org/koitharu/kotatsu/core/parser/DummyParser.kt +++ b/app/src/debug/java/org/koitharu/kotatsu/core/parser/DummyParser.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.core.parser import java.util.* +import org.koitharu.kotatsu.parsers.InternalParsersApi import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey @@ -9,6 +10,7 @@ import org.koitharu.kotatsu.parsers.model.* /** * This parser is just for parser development, it should not be used in releases */ +@OptIn(InternalParsersApi::class) class DummyParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.DUMMY) { override val configKeyDomain: ConfigKey.Domain @@ -25,7 +27,7 @@ class DummyParser(override val context: MangaLoaderContext) : MangaParser(MangaS offset: Int, query: String?, tags: Set?, - sortOrder: SortOrder? + sortOrder: SortOrder, ): List { TODO("Not yet implemented") } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt new file mode 100644 index 000000000..9bd4ef5cf --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.core.model + +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.util.toTitleCase +import java.util.* + +fun MangaSource.getLocaleTitle(): String? { + val lc = Locale(locale ?: return null) + return lc.getDisplayLanguage(lc).toTitleCase(lc) +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt index ca4cc495b..812fc9e81 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt @@ -1,11 +1,11 @@ package org.koitharu.kotatsu.core.parser -import java.lang.ref.WeakReference -import java.util.* import org.koin.core.component.KoinComponent import org.koin.core.component.get import org.koitharu.kotatsu.local.domain.LocalMangaRepository import org.koitharu.kotatsu.parsers.model.* +import java.lang.ref.WeakReference +import java.util.* interface MangaRepository { @@ -13,12 +13,9 @@ interface MangaRepository { val sortOrders: Set - suspend fun getList( - offset: Int, - query: String? = null, - tags: Set? = null, - sortOrder: SortOrder? = null, - ): List + suspend fun getList(offset: Int, query: String?): List + + suspend fun getList(offset: Int, tags: Set?, sortOrder: SortOrder?): List suspend fun getDetails(manga: Manga): Manga diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt index 14a113e24..358bd2645 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt @@ -20,12 +20,13 @@ class RemoteMangaRepository(private val parser: MangaParser) : MangaRepository { getConfig().defaultSortOrder = value } - override suspend fun getList( - offset: Int, - query: String?, - tags: Set?, - sortOrder: SortOrder?, - ): List = parser.getList(offset, query, tags, sortOrder) + override suspend fun getList(offset: Int, query: String?): List { + return parser.getList(offset, query) + } + + override suspend fun getList(offset: Int, tags: Set?, sortOrder: SortOrder?): List { + return parser.getList(offset, tags, sortOrder) + } override suspend fun getDetails(manga: Manga): Manga = parser.getDetails(manga) diff --git a/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt index 2c0b37298..6eef24c86 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt @@ -37,28 +37,25 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma private val filenameFilter = CbzFilter() private val locks = CompositeMutex() - override suspend fun getList( - offset: Int, - query: String?, - tags: Set?, - sortOrder: SortOrder? - ): List { + override suspend fun getList(offset: Int, query: String?): List { if (offset > 0) { return emptyList() } - val files = getAllFiles() - val list = coroutineScope { - val dispatcher = Dispatchers.IO.limitedParallelism(MAX_PARALLELISM) - files.map { file -> - getFromFileAsync(file, dispatcher) - }.awaitAll() - }.filterNotNullTo(ArrayList(files.size)) + val list = getRawList() if (!query.isNullOrEmpty()) { list.retainAll { x -> x.title.contains(query, ignoreCase = true) || x.altTitle?.contains(query, ignoreCase = true) == true } } + return list + } + + override suspend fun getList(offset: Int, tags: Set?, sortOrder: SortOrder?): List { + if (offset > 0) { + return emptyList() + } + val list = getRawList() if (!tags.isNullOrEmpty()) { list.retainAll { x -> x.tags.containsAll(tags) @@ -244,7 +241,7 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma } } - override val sortOrders = emptySet() + override val sortOrders = setOf(SortOrder.ALPHABETICAL) override suspend fun getPageUrl(page: MangaPage) = page.url @@ -295,6 +292,16 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma locks.unlock(id) } + private suspend fun getRawList(): ArrayList { + val files = getAllFiles() + return coroutineScope { + val dispatcher = Dispatchers.IO.limitedParallelism(MAX_PARALLELISM) + files.map { file -> + getFromFileAsync(file, dispatcher) + }.awaitAll() + }.filterNotNullTo(ArrayList(files.size)) + } + private suspend fun getAllFiles() = storageManager.getReadableDirs().flatMap { dir -> dir.listFiles(filenameFilter)?.toList().orEmpty() } diff --git a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt index 7ca7e8249..375e03997 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.local.ui import android.net.Uri import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope -import java.io.IOException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow @@ -24,6 +23,7 @@ import org.koitharu.kotatsu.utils.SingleLiveEvent import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct import org.koitharu.kotatsu.utils.ext.printStackTraceDebug import org.koitharu.kotatsu.utils.progress.Progress +import java.io.IOException class LocalListViewModel( private val repository: LocalMangaRepository, @@ -115,7 +115,7 @@ class LocalListViewModel( private suspend fun doRefresh() { try { listError.value = null - mangaList.value = repository.getList(0) + mangaList.value = repository.getList(0, null, null) } catch (e: Throwable) { listError.value = e } diff --git a/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt b/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt index 270238553..2c95fb632 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt @@ -17,7 +17,6 @@ import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaTag -import org.koitharu.kotatsu.parsers.model.SortOrder import org.koitharu.kotatsu.parsers.util.levenshteinDistance import org.koitharu.kotatsu.search.ui.MangaSuggestionsProvider @@ -35,7 +34,6 @@ class MangaSearchRepository( MangaRepository(source).getList( offset = 0, query = query, - sortOrder = SortOrder.POPULARITY ) }.getOrElse { emptyList() @@ -141,4 +139,4 @@ class MangaSearchRepository( return false } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/newsources/NewSourcesViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/settings/newsources/NewSourcesViewModel.kt index 530851d46..08ef96c49 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/newsources/NewSourcesViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/newsources/NewSourcesViewModel.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.settings.newsources import androidx.lifecycle.MutableLiveData import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.core.model.getLocaleTitle import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem @@ -33,7 +34,7 @@ class NewSourcesViewModel( sources.value = initialList.map { SourceConfigItem.SourceItem( source = it, - summary = null, + summary = it.getLocaleTitle(), isEnabled = it.name !in hidden, isDraggable = false, ) diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsViewModel.kt index 2f53c15fc..da3eba14f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsViewModel.kt @@ -4,6 +4,7 @@ import androidx.core.os.LocaleListCompat import androidx.lifecycle.MutableLiveData import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.core.model.getLocaleTitle import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.toTitleCase @@ -82,7 +83,7 @@ class SourcesSettingsViewModel( } SourceConfigItem.SourceItem( source = it, - summary = null, + summary = it.getLocaleTitle(), isEnabled = it.name !in hiddenSources, isDraggable = false, ) @@ -105,7 +106,7 @@ class SourcesSettingsViewModel( enabledSources.mapTo(result) { SourceConfigItem.SourceItem( source = it, - summary = getLocaleTitle(it.locale), + summary = it.getLocaleTitle(), isEnabled = true, isDraggable = true, ) @@ -162,4 +163,4 @@ class SourcesSettingsViewModel( } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt index 752e3d33e..775da0f6e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt @@ -17,15 +17,17 @@ import org.koitharu.kotatsu.databinding.ItemSourceConfigBinding import org.koitharu.kotatsu.databinding.ItemSourceConfigDraggableBinding import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem import org.koitharu.kotatsu.utils.ext.enqueueWith +import org.koitharu.kotatsu.utils.ext.textAndVisible -fun sourceConfigHeaderDelegate() = adapterDelegateViewBinding( - { layoutInflater, parent -> ItemFilterHeaderBinding.inflate(layoutInflater, parent, false) } -) { +fun sourceConfigHeaderDelegate() = + adapterDelegateViewBinding( + { layoutInflater, parent -> ItemFilterHeaderBinding.inflate(layoutInflater, parent, false) } + ) { - bind { - binding.textViewTitle.setText(item.titleResId) + bind { + binding.textViewTitle.setText(item.titleResId) + } } -} fun sourceConfigGroupDelegate( listener: SourceConfigListener, @@ -61,6 +63,7 @@ fun sourceConfigItemDelegate( bind { binding.textViewTitle.text = item.source.title binding.switchToggle.isChecked = item.isEnabled + binding.textViewDescription.textAndVisible = item.summary imageRequest = ImageRequest.Builder(context) .data(item.faviconUrl) .error(R.drawable.ic_favicon_fallback) diff --git a/app/src/main/res/layout/item_source_config.xml b/app/src/main/res/layout/item_source_config.xml index a0620433a..859105c96 100644 --- a/app/src/main/res/layout/item_source_config.xml +++ b/app/src/main/res/layout/item_source_config.xml @@ -3,8 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="?android:listPreferredItemHeightSmall" + android:layout_height="wrap_content" android:gravity="center_vertical" + android:minHeight="?android:listPreferredItemHeightSmall" android:orientation="horizontal"> - + android:orientation="vertical"> + + + + + + + android:src="@drawable/ic_totoro" + app:tint="?colorPrimary" />