Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
cf33cb66c6
|
|||
|
|
8010c5079b | ||
|
a87a77083e
|
|||
|
ca20422344
|
|||
|
c213b9d4b5
|
|||
|
95fbe496cb
|
|||
|
b9fd2e100d
|
|||
|
1242a88f8e
|
@@ -16,8 +16,8 @@ android {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 597
|
||||
versionName = '6.3.0'
|
||||
versionCode = 598
|
||||
versionName = '6.3.1'
|
||||
generatedDensities = []
|
||||
testInstrumentationRunner "org.koitharu.kotatsu.HiltTestRunner"
|
||||
ksp {
|
||||
@@ -82,7 +82,7 @@ afterEvaluate {
|
||||
}
|
||||
dependencies {
|
||||
//noinspection GradleDependency
|
||||
implementation('com.github.KotatsuApp:kotatsu-parsers:41eea1c420') {
|
||||
implementation('com.github.KotatsuApp:kotatsu-parsers:c3613f3ba4') {
|
||||
exclude group: 'org.json', module: 'json'
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.koitharu.kotatsu.parsers.MangaParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
@@ -19,19 +20,14 @@ class DummyParser(context: MangaLoaderContext) : MangaParser(context, MangaSourc
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("")
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.allOf(SortOrder::class.java)
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun getList(
|
||||
offset: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
override suspend fun getList(offset: Int, filter: MangaListFilter?): List<Manga> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
@@ -39,7 +35,7 @@ class DummyParser(context: MangaLoaderContext) : MangaParser(context, MangaSourc
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.runInterruptible
|
||||
import okio.IOException
|
||||
import org.koitharu.kotatsu.core.model.isLocal
|
||||
import org.koitharu.kotatsu.core.os.NetworkState
|
||||
import org.koitharu.kotatsu.core.parser.MangaDataRepository
|
||||
import org.koitharu.kotatsu.core.parser.MangaIntent
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
@@ -33,7 +33,6 @@ class DetailsLoadUseCase @Inject constructor(
|
||||
private val mangaRepositoryFactory: MangaRepository.Factory,
|
||||
private val recoverUseCase: RecoverMangaUseCase,
|
||||
private val imageGetter: Html.ImageGetter,
|
||||
private val networkState: NetworkState,
|
||||
) {
|
||||
|
||||
operator fun invoke(intent: MangaIntent): Flow<MangaDetails> = channelFlow {
|
||||
@@ -48,16 +47,15 @@ class DetailsLoadUseCase @Inject constructor(
|
||||
null
|
||||
}
|
||||
send(MangaDetails(manga, null, null, false))
|
||||
if (!networkState.value) {
|
||||
// try load offline instead
|
||||
local?.await()?.manga?.let { localManga ->
|
||||
try {
|
||||
val details = getDetails(manga)
|
||||
send(MangaDetails(details, local?.peek(), details.description?.parseAsHtml(withImages = false), false))
|
||||
send(MangaDetails(details, local?.await(), details.description?.parseAsHtml(withImages = true), true))
|
||||
} catch (e: IOException) {
|
||||
local?.await()?.manga?.also { localManga ->
|
||||
send(MangaDetails(localManga, null, localManga.description?.parseAsHtml(withImages = false), true))
|
||||
return@channelFlow
|
||||
}
|
||||
} ?: throw e
|
||||
}
|
||||
val details = getDetails(manga)
|
||||
send(MangaDetails(details, local?.peek(), details.description?.parseAsHtml(withImages = false), false))
|
||||
send(MangaDetails(details, local?.await(), details.description?.parseAsHtml(withImages = true), true))
|
||||
}
|
||||
|
||||
private suspend fun getDetails(seed: Manga) = runCatchingCancellable {
|
||||
|
||||
@@ -197,6 +197,11 @@ class DetailsFragment :
|
||||
drawableTop = ContextCompat.getDrawable(context, R.drawable.ic_state_abandoned)
|
||||
}
|
||||
|
||||
MangaState.PAUSED -> infoLayout.textViewState.apply {
|
||||
textAndVisible = resources.getString(R.string.state_paused)
|
||||
drawableTop = ContextCompat.getDrawable(context, R.drawable.ic_action_pause)
|
||||
}
|
||||
|
||||
null -> infoLayout.textViewState.isVisible = false
|
||||
}
|
||||
if (manga.source == MangaSource.LOCAL) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.plus
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.bookmarks.domain.Bookmark
|
||||
import org.koitharu.kotatsu.bookmarks.domain.BookmarksRepository
|
||||
@@ -119,9 +118,12 @@ class ReaderViewModel @Inject constructor(
|
||||
valueProducer = { isReaderKeepScreenOn },
|
||||
)
|
||||
|
||||
val isWebtoonZooEnabled = observeIsWebtoonZoomEnabled()
|
||||
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Lazily, false)
|
||||
|
||||
val isZoomControlsEnabled = getObserveIsZoomControlEnabled().flatMapLatest { zoom ->
|
||||
if (zoom) {
|
||||
combine(readerMode, observeIsWebtoonZoomEnabled()) { mode, ze -> ze || mode != ReaderMode.WEBTOON }
|
||||
combine(readerMode, isWebtoonZooEnabled) { mode, ze -> ze || mode != ReaderMode.WEBTOON }
|
||||
} else {
|
||||
flowOf(false)
|
||||
}
|
||||
@@ -260,8 +262,8 @@ class ReaderViewModel @Inject constructor(
|
||||
stateChangeJob = launchJob(Dispatchers.Default) {
|
||||
prevJob?.cancelAndJoin()
|
||||
loadingJob?.join()
|
||||
if (BuildConfig.DEBUG && pages.size != content.value.pages.size) {
|
||||
throw IllegalStateException("Concurrent pages modification")
|
||||
if (pages.size != content.value.pages.size) {
|
||||
return@launchJob // TODO
|
||||
}
|
||||
pages.getOrNull(position)?.let { page ->
|
||||
currentState.update { cs ->
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.os.NetworkState
|
||||
import org.koitharu.kotatsu.core.util.ext.findCenterViewPosition
|
||||
import org.koitharu.kotatsu.core.util.ext.firstVisibleItemPosition
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.databinding.FragmentReaderWebtoonBinding
|
||||
import org.koitharu.kotatsu.reader.domain.PageLoader
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderState
|
||||
@@ -44,6 +45,9 @@ class WebtoonReaderFragment : BaseReaderFragment<FragmentReaderWebtoonBinding>()
|
||||
adapter = readerAdapter
|
||||
addOnPageScrollListener(PageScrollListener())
|
||||
}
|
||||
viewModel.isWebtoonZooEnabled.observe(viewLifecycleOwner) {
|
||||
binding.frame.isZoomEnable = it
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
||||
@@ -51,7 +51,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
private val targetHitRect = Rect()
|
||||
private var animator: ValueAnimator? = null
|
||||
|
||||
var isZoomEnable = true
|
||||
var isZoomEnable = false
|
||||
set(value) {
|
||||
field = value
|
||||
if (scale != 1f) {
|
||||
|
||||
@@ -8,7 +8,8 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
sealed interface SourceCatalogItem : ListModel {
|
||||
|
||||
data class Source(
|
||||
val source: MangaSource
|
||||
val source: MangaSource,
|
||||
val showSummary: Boolean,
|
||||
) : SourceCatalogItem {
|
||||
|
||||
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import coil.ImageLoader
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.getSummary
|
||||
import org.koitharu.kotatsu.core.model.isNsfw
|
||||
import org.koitharu.kotatsu.core.parser.favicon.faviconUri
|
||||
import org.koitharu.kotatsu.core.ui.image.FaviconDrawable
|
||||
@@ -43,6 +44,12 @@ fun sourceCatalogItemSourceAD(
|
||||
} else {
|
||||
item.source.title
|
||||
}
|
||||
if (item.showSummary) {
|
||||
binding.textViewDescription.text = item.source.getSummary(context)
|
||||
binding.textViewDescription.isVisible = true
|
||||
} else {
|
||||
binding.textViewDescription.isVisible = false
|
||||
}
|
||||
val fallbackIcon = FaviconDrawable(context, R.style.FaviconDrawable_Small, item.source.name)
|
||||
binding.imageViewIcon.newImageRequest(lifecycleOwner, item.source.faviconUri())?.run {
|
||||
crossfade(context)
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package org.koitharu.kotatsu.settings.sources.catalog
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import coil.ImageLoader
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
@@ -28,7 +31,7 @@ import javax.inject.Inject
|
||||
class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
|
||||
TabLayout.OnTabSelectedListener,
|
||||
OnListItemClickListener<SourceCatalogItem.Source>,
|
||||
AppBarOwner {
|
||||
AppBarOwner, MenuItem.OnActionExpandListener {
|
||||
|
||||
@Inject
|
||||
lateinit var coil: ImageLoader
|
||||
@@ -56,7 +59,7 @@ class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
|
||||
viewModel.locale.observe(this) {
|
||||
supportActionBar?.subtitle = it.getLocaleDisplayName()
|
||||
}
|
||||
addMenuProvider(SourcesCatalogMenuProvider(this, viewModel))
|
||||
addMenuProvider(SourcesCatalogMenuProvider(this, viewModel, this))
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
@@ -83,6 +86,19 @@ class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
|
||||
viewBinding.recyclerView.firstVisibleItemPosition = 0
|
||||
}
|
||||
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
viewBinding.tabs.isVisible = false
|
||||
val sq = (item.actionView as? SearchView)?.query?.trim()?.toString().orEmpty()
|
||||
viewModel.performSearch(sq)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
viewBinding.tabs.isVisible = true
|
||||
viewModel.performSearch(null)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun initTabs() {
|
||||
val tabs = viewBinding.tabs
|
||||
for (type in ContentType.entries) {
|
||||
|
||||
@@ -28,7 +28,7 @@ class SourcesCatalogListProducer @AssistedInject constructor(
|
||||
) : InvalidationTracker.Observer(TABLE_SOURCES), RetainedLifecycle.OnClearedListener {
|
||||
|
||||
private val scope = lifecycle.lifecycleScope
|
||||
private var query: String = ""
|
||||
private var query: String? = null
|
||||
val list = MutableStateFlow(emptyList<SourceCatalogItem>())
|
||||
|
||||
private var job = scope.launch(Dispatchers.Default) {
|
||||
@@ -54,20 +54,21 @@ class SourcesCatalogListProducer @AssistedInject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun setQuery(value: String) {
|
||||
fun setQuery(value: String?) {
|
||||
this.query = value
|
||||
onInvalidated(emptySet())
|
||||
}
|
||||
|
||||
private suspend fun buildList(): List<SourceCatalogItem> {
|
||||
val sources = repository.getDisabledSources().toMutableList()
|
||||
sources.retainAll { it.contentType == contentType && it.locale == locale }
|
||||
if (query.isNotEmpty()) {
|
||||
sources.retainAll { it.title.contains(query, ignoreCase = true) }
|
||||
when (val q = query) {
|
||||
null -> sources.retainAll { it.contentType == contentType && it.locale == locale }
|
||||
"" -> return emptyList()
|
||||
else -> sources.retainAll { it.title.contains(q, ignoreCase = true) }
|
||||
}
|
||||
return if (sources.isEmpty()) {
|
||||
listOf(
|
||||
if (query.isEmpty()) {
|
||||
if (query == null) {
|
||||
SourceCatalogItem.Hint(
|
||||
icon = R.drawable.ic_empty_feed,
|
||||
title = R.string.no_manga_sources,
|
||||
@@ -86,6 +87,7 @@ class SourcesCatalogListProducer @AssistedInject constructor(
|
||||
sources.map {
|
||||
SourceCatalogItem.Source(
|
||||
source = it,
|
||||
showSummary = query != null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.koitharu.kotatsu.parsers.util.toTitleCase
|
||||
class SourcesCatalogMenuProvider(
|
||||
private val activity: Activity,
|
||||
private val viewModel: SourcesCatalogViewModel,
|
||||
private val expandListener: MenuItem.OnActionExpandListener,
|
||||
) : MenuProvider,
|
||||
MenuItem.OnActionExpandListener,
|
||||
SearchView.OnQueryTextListener {
|
||||
@@ -40,18 +41,18 @@ class SourcesCatalogMenuProvider(
|
||||
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
(activity as? AppBarOwner)?.appBar?.setExpanded(false, true)
|
||||
return true
|
||||
return expandListener.onMenuItemActionExpand(item)
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
(item.actionView as SearchView).setQuery("", false)
|
||||
return true
|
||||
return expandListener.onMenuItemActionCollapse(item)
|
||||
}
|
||||
|
||||
override fun onQueryTextSubmit(query: String?): Boolean = false
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
viewModel.performSearch(newText.orEmpty())
|
||||
viewModel.performSearch(newText?.trim().orEmpty())
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ import javax.inject.Inject
|
||||
class SourcesCatalogViewModel @Inject constructor(
|
||||
private val repository: MangaSourcesRepository,
|
||||
private val listProducerFactory: SourcesCatalogListProducer.Factory,
|
||||
private val settings: AppSettings,
|
||||
settings: AppSettings,
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val lifecycle = RetainedLifecycleImpl()
|
||||
private var searchQuery: String = ""
|
||||
private var searchQuery: String? = null
|
||||
val onActionDone = MutableEventFlow<ReversibleAction>()
|
||||
val contentType = MutableStateFlow(ContentType.entries.first())
|
||||
val locales = getLocalesImpl()
|
||||
@@ -59,7 +59,7 @@ class SourcesCatalogViewModel @Inject constructor(
|
||||
lifecycle.dispatchOnCleared()
|
||||
}
|
||||
|
||||
fun performSearch(query: String) {
|
||||
fun performSearch(query: String?) {
|
||||
searchQuery = query
|
||||
listProducer.value?.setQuery(query)
|
||||
}
|
||||
|
||||
@@ -23,17 +23,34 @@
|
||||
app:shapeAppearance="?shapeAppearanceCornerSmall"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="?android:listPreferredItemPaddingStart"
|
||||
android:layout_marginEnd="?android:listPreferredItemPaddingEnd"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?attr/textAppearanceTitleSmall"
|
||||
tools:text="@tools:sample/lorem[15]" />
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?attr/textAppearanceTitleSmall"
|
||||
tools:text="@tools:sample/lorem[15]" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||
tools:text="English" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView_add"
|
||||
|
||||
@@ -506,4 +506,18 @@
|
||||
<string name="backups_output_directory">Вывадны каталог рэзервовых копій</string>
|
||||
<string name="speed_value">x%.1f</string>
|
||||
<string name="lock_screen_rotation">Блакаванне павароту экрана</string>
|
||||
<string name="sources_catalog">Каталог крыніц</string>
|
||||
<string name="content_type_manga">Манга</string>
|
||||
<string name="source_summary_pattern">%1$s, %2$s</string>
|
||||
<string name="content_type_hentai">Хентай</string>
|
||||
<string name="content_type_comics">Коміксы</string>
|
||||
<string name="catalog">Каталог</string>
|
||||
<string name="manage_sources">Кіраванне крыніцамі</string>
|
||||
<string name="no_manga_sources_found">Па вашаму запыту не знойдзена даступных крыніц мангі</string>
|
||||
<string name="manual">Уручную</string>
|
||||
<string name="source_enabled">Крыніца ўключана</string>
|
||||
<string name="disable_nsfw_summary">Адключыць крыніцы NSFW і схавайць мангу для дарослых са спісу, калі гэта магчыма</string>
|
||||
<string name="no_manga_sources_catalog_text">У гэтым раздзеле пакуль няма даступных крыніц. Сачыце за абнаўленнямі</string>
|
||||
<string name="available_d">Даступна: %1$d</string>
|
||||
<string name="content_type_other">Іншае</string>
|
||||
</resources>
|
||||
@@ -519,4 +519,5 @@
|
||||
<string name="no_manga_sources_catalog_text">Пока что в данном разделе нет доступных источников. Следите за обновлениями</string>
|
||||
<string name="available_d">Доступно: %1$d</string>
|
||||
<string name="content_type_other">Другое</string>
|
||||
<string name="source_summary_pattern">%1$s, %2$s</string>
|
||||
</resources>
|
||||
@@ -506,4 +506,18 @@
|
||||
<string name="backups_output_directory">Вихідний каталог резервних копій</string>
|
||||
<string name="speed_value">x%.1f</string>
|
||||
<string name="lock_screen_rotation">Блокування повороту екрану</string>
|
||||
<string name="sources_catalog">Каталог джерел</string>
|
||||
<string name="content_type_manga">Манґа</string>
|
||||
<string name="source_summary_pattern">%1$s, %2$s</string>
|
||||
<string name="content_type_hentai">Хентай</string>
|
||||
<string name="content_type_comics">Комікси</string>
|
||||
<string name="catalog">Каталог</string>
|
||||
<string name="manage_sources">Кіравання джерелами</string>
|
||||
<string name="no_manga_sources_found">За вашим запитом не знайдено доступних джерел манґи</string>
|
||||
<string name="manual">Вручну</string>
|
||||
<string name="source_enabled">Джерело включено</string>
|
||||
<string name="disable_nsfw_summary">Вимкніть джерела NSFW і приховайте манґу для дорослих зі списку, якщо можливо</string>
|
||||
<string name="no_manga_sources_catalog_text">У цьому розділі ще немає доступних джерел. Слідкуйте за оновленнями</string>
|
||||
<string name="available_d">Доступно: %1$d</string>
|
||||
<string name="content_type_other">Інший</string>
|
||||
</resources>
|
||||
@@ -519,11 +519,12 @@
|
||||
<string name="source_summary_pattern">%1$s, %2$s</string>
|
||||
<string name="sources_catalog">Sources catalog</string>
|
||||
<string name="source_enabled">Source enabled</string>
|
||||
<string name="no_manga_sources_catalog_text">No available sources in this section yet. Stay tuned</string>
|
||||
<string name="no_manga_sources_catalog_text">There are no sources available in this section, or all of it might have been already added.\nStay tuned</string>
|
||||
<string name="no_manga_sources_found">No available manga sources found by your query</string>
|
||||
<string name="catalog">Catalog</string>
|
||||
<string name="manage_sources">Manage sources</string>
|
||||
<string name="manual">Manual</string>
|
||||
<string name="available_d">Available: %1$d</string>
|
||||
<string name="disable_nsfw_summary">Disable NSFW sources and hide adult manga from list if possible</string>
|
||||
<string name="state_paused">Paused</string>
|
||||
</resources>
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.exception.NotFoundException
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
@@ -17,21 +18,16 @@ class DummyParser(context: MangaLoaderContext) : MangaParser(context, MangaSourc
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("localhost")
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.allOf(SortOrder::class.java)
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = stub()
|
||||
|
||||
override suspend fun getList(
|
||||
offset: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> = stub()
|
||||
override suspend fun getList(offset: Int, filter: MangaListFilter?): List<Manga> = stub()
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> = stub()
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = stub()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = stub()
|
||||
|
||||
private fun stub(): Nothing {
|
||||
throw NotFoundException("Usage of Dummy parser in release build", "")
|
||||
|
||||
Reference in New Issue
Block a user