Merge branch 'master' into Failed-Updates-feature-added
This commit is contained in:
commit
9d77b6e2b5
16 changed files with 71 additions and 127 deletions
|
@ -3,6 +3,7 @@ package eu.kanade.presentation.util
|
|||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.network.HttpException
|
||||
import eu.kanade.tachiyomi.source.online.LicensedMangaChaptersException
|
||||
import tachiyomi.data.source.NoResultsException
|
||||
import tachiyomi.domain.source.model.SourceNotInstalledException
|
||||
|
||||
|
@ -13,6 +14,7 @@ val Throwable.formattedMessage: String
|
|||
is NoResultsException -> return getString(R.string.no_results_found)
|
||||
is SourceNotInstalledException -> return getString(R.string.loader_not_implemented_error)
|
||||
is HttpException -> return "$message: ${getString(R.string.http_error_hint)}"
|
||||
is LicensedMangaChaptersException -> return getString(R.string.licensed_manga_chapters_error)
|
||||
}
|
||||
return when (val className = this::class.simpleName) {
|
||||
"Exception", "IOException" -> message ?: className
|
||||
|
|
|
@ -106,10 +106,10 @@ class BackupManager(
|
|||
UniFile.fromUri(context, uri)
|
||||
}
|
||||
)
|
||||
?: throw Exception("Couldn't create backup file")
|
||||
?: throw Exception(context.getString(R.string.create_backup_file_error))
|
||||
|
||||
if (!file.isFile) {
|
||||
throw IllegalStateException("Failed to get handle on file")
|
||||
throw IllegalStateException("Failed to get handle on a backup file")
|
||||
}
|
||||
|
||||
val byteArray = parser.encodeToByteArray(BackupSerializer, backup)
|
||||
|
|
|
@ -382,11 +382,14 @@ class ReaderActivity : BaseActivity() {
|
|||
|
||||
binding.pageNumber.setComposeContent {
|
||||
val state by viewModel.state.collectAsState()
|
||||
val showPageNumber by viewModel.readerPreferences.showPageNumber().collectAsState()
|
||||
|
||||
PageIndicatorText(
|
||||
currentPage = state.currentPage,
|
||||
totalPages = state.totalPages,
|
||||
)
|
||||
if (!state.menuVisible && showPageNumber) {
|
||||
PageIndicatorText(
|
||||
currentPage = state.currentPage,
|
||||
totalPages = state.totalPages,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
binding.dialogRoot.setComposeContent {
|
||||
|
@ -554,10 +557,6 @@ class ReaderActivity : BaseActivity() {
|
|||
bottomAnimation.applySystemAnimatorScale(this)
|
||||
binding.readerMenuBottom.startAnimation(bottomAnimation)
|
||||
}
|
||||
|
||||
if (readerPreferences.showPageNumber().get()) {
|
||||
config?.setPageNumberVisibility(false)
|
||||
}
|
||||
} else {
|
||||
if (readerPreferences.fullscreen().get()) {
|
||||
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||
|
@ -580,10 +579,6 @@ class ReaderActivity : BaseActivity() {
|
|||
bottomAnimation.applySystemAnimatorScale(this)
|
||||
binding.readerMenuBottom.startAnimation(bottomAnimation)
|
||||
}
|
||||
|
||||
if (readerPreferences.showPageNumber().get()) {
|
||||
config?.setPageNumberVisibility(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -636,9 +631,8 @@ class ReaderActivity : BaseActivity() {
|
|||
|
||||
private fun showReadingModeToast(mode: Int) {
|
||||
try {
|
||||
val strings = resources.getStringArray(R.array.viewers_selector)
|
||||
readingModeToast?.cancel()
|
||||
readingModeToast = toast(strings[mode])
|
||||
readingModeToast = toast(ReadingModeType.fromPreference(mode).stringRes)
|
||||
} catch (e: ArrayIndexOutOfBoundsException) {
|
||||
logcat(LogPriority.ERROR) { "Unknown reading mode: $mode" }
|
||||
}
|
||||
|
@ -892,10 +886,6 @@ class ReaderActivity : BaseActivity() {
|
|||
}
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
readerPreferences.showPageNumber().changes()
|
||||
.onEach(::setPageNumberVisibility)
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
readerPreferences.trueColor().changes()
|
||||
.onEach(::setTrueColor)
|
||||
.launchIn(lifecycleScope)
|
||||
|
@ -945,13 +935,6 @@ class ReaderActivity : BaseActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of the bottom page indicator according to [visible].
|
||||
*/
|
||||
fun setPageNumberVisibility(visible: Boolean) {
|
||||
binding.pageNumber.isVisible = visible
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 32-bit color mode according to [enabled].
|
||||
*/
|
||||
|
|
|
@ -61,7 +61,7 @@ class ReaderNavigationOverlayView(context: Context, attributeSet: AttributeSet)
|
|||
override fun onDraw(canvas: Canvas) {
|
||||
if (navigation == null) return
|
||||
|
||||
navigation?.regions?.forEach { region ->
|
||||
navigation?.getRegions()?.forEach { region ->
|
||||
val rect = region.rectF
|
||||
|
||||
// Scale rect from 1f,1f to screen width and height
|
||||
|
|
|
@ -5,14 +5,14 @@ import androidx.annotation.DrawableRes
|
|||
import androidx.annotation.StringRes
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
enum class OrientationType(val prefValue: Int, val flag: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int, val flagValue: Int) {
|
||||
DEFAULT(0, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.label_default, R.drawable.ic_screen_rotation_24dp, 0x00000000),
|
||||
FREE(1, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.rotation_free, R.drawable.ic_screen_rotation_24dp, 0x00000008),
|
||||
PORTRAIT(2, ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT, R.string.rotation_portrait, R.drawable.ic_stay_current_portrait_24dp, 0x00000010),
|
||||
LANDSCAPE(3, ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE, R.string.rotation_landscape, R.drawable.ic_stay_current_landscape_24dp, 0x00000018),
|
||||
LOCKED_PORTRAIT(4, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, R.string.rotation_force_portrait, R.drawable.ic_screen_lock_portrait_24dp, 0x00000020),
|
||||
LOCKED_LANDSCAPE(5, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, R.string.rotation_force_landscape, R.drawable.ic_screen_lock_landscape_24dp, 0x00000028),
|
||||
REVERSE_PORTRAIT(6, ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, R.string.rotation_reverse_portrait, R.drawable.ic_stay_current_portrait_24dp, 0x00000030),
|
||||
enum class OrientationType(val flag: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int, val flagValue: Int) {
|
||||
DEFAULT(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.label_default, R.drawable.ic_screen_rotation_24dp, 0x00000000),
|
||||
FREE(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.rotation_free, R.drawable.ic_screen_rotation_24dp, 0x00000008),
|
||||
PORTRAIT(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT, R.string.rotation_portrait, R.drawable.ic_stay_current_portrait_24dp, 0x00000010),
|
||||
LANDSCAPE(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE, R.string.rotation_landscape, R.drawable.ic_stay_current_landscape_24dp, 0x00000018),
|
||||
LOCKED_PORTRAIT(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, R.string.rotation_force_portrait, R.drawable.ic_screen_lock_portrait_24dp, 0x00000020),
|
||||
LOCKED_LANDSCAPE(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, R.string.rotation_force_landscape, R.drawable.ic_screen_lock_landscape_24dp, 0x00000028),
|
||||
REVERSE_PORTRAIT(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, R.string.rotation_reverse_portrait, R.drawable.ic_stay_current_portrait_24dp, 0x00000030),
|
||||
;
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -10,13 +10,13 @@ import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
|
|||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.VerticalPagerViewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
|
||||
|
||||
enum class ReadingModeType(val prefValue: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int, val flagValue: Int) {
|
||||
DEFAULT(0, R.string.label_default, R.drawable.ic_reader_default_24dp, 0x00000000),
|
||||
LEFT_TO_RIGHT(1, R.string.left_to_right_viewer, R.drawable.ic_reader_ltr_24dp, 0x00000001),
|
||||
RIGHT_TO_LEFT(2, R.string.right_to_left_viewer, R.drawable.ic_reader_rtl_24dp, 0x00000002),
|
||||
VERTICAL(3, R.string.vertical_viewer, R.drawable.ic_reader_vertical_24dp, 0x00000003),
|
||||
WEBTOON(4, R.string.webtoon_viewer, R.drawable.ic_reader_webtoon_24dp, 0x00000004),
|
||||
CONTINUOUS_VERTICAL(5, R.string.vertical_plus_viewer, R.drawable.ic_reader_continuous_vertical_24dp, 0x00000005),
|
||||
enum class ReadingModeType(@StringRes val stringRes: Int, @DrawableRes val iconRes: Int, val flagValue: Int) {
|
||||
DEFAULT(R.string.label_default, R.drawable.ic_reader_default_24dp, 0x00000000),
|
||||
LEFT_TO_RIGHT(R.string.left_to_right_viewer, R.drawable.ic_reader_ltr_24dp, 0x00000001),
|
||||
RIGHT_TO_LEFT(R.string.right_to_left_viewer, R.drawable.ic_reader_rtl_24dp, 0x00000002),
|
||||
VERTICAL(R.string.vertical_viewer, R.drawable.ic_reader_vertical_24dp, 0x00000003),
|
||||
WEBTOON(R.string.webtoon_viewer, R.drawable.ic_reader_webtoon_24dp, 0x00000004),
|
||||
CONTINUOUS_VERTICAL(R.string.vertical_plus_viewer, R.drawable.ic_reader_continuous_vertical_24dp, 0x00000005),
|
||||
;
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -32,15 +32,19 @@ abstract class ViewerNavigation {
|
|||
|
||||
private var constantMenuRegion: RectF = RectF(0f, 0f, 1f, 0.05f)
|
||||
|
||||
abstract var regions: List<Region>
|
||||
|
||||
var invertMode: ReaderPreferences.TappingInvertMode = ReaderPreferences.TappingInvertMode.NONE
|
||||
|
||||
protected abstract var regionList: List<Region>
|
||||
|
||||
/** Returns regions with applied inversion. */
|
||||
fun getRegions(): List<Region> {
|
||||
return regionList.map { it.invert(invertMode) }
|
||||
}
|
||||
|
||||
fun getAction(pos: PointF): NavigationRegion {
|
||||
val x = pos.x
|
||||
val y = pos.y
|
||||
val region = regions.map { it.invert(invertMode) }
|
||||
.find { it.rectF.contains(x, y) }
|
||||
val region = getRegions().find { it.rectF.contains(x, y) }
|
||||
return when {
|
||||
region != null -> region.type
|
||||
constantMenuRegion.contains(x, y) -> NavigationRegion.MENU
|
||||
|
|
|
@ -14,5 +14,5 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
|||
*/
|
||||
class DisabledNavigation : ViewerNavigation() {
|
||||
|
||||
override var regions: List<Region> = emptyList()
|
||||
override var regionList: List<Region> = emptyList()
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
|||
*/
|
||||
class EdgeNavigation : ViewerNavigation() {
|
||||
|
||||
override var regions: List<Region> = listOf(
|
||||
override var regionList: List<Region> = listOf(
|
||||
Region(
|
||||
rectF = RectF(0f, 0f, 0.33f, 1f),
|
||||
type = NavigationRegion.NEXT,
|
||||
|
|
|
@ -15,7 +15,7 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
|||
*/
|
||||
class KindlishNavigation : ViewerNavigation() {
|
||||
|
||||
override var regions: List<Region> = listOf(
|
||||
override var regionList: List<Region> = listOf(
|
||||
Region(
|
||||
rectF = RectF(0.33f, 0.33f, 1f, 1f),
|
||||
type = NavigationRegion.NEXT,
|
||||
|
|
|
@ -15,7 +15,7 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
|||
*/
|
||||
open class LNavigation : ViewerNavigation() {
|
||||
|
||||
override var regions: List<Region> = listOf(
|
||||
override var regionList: List<Region> = listOf(
|
||||
Region(
|
||||
rectF = RectF(0f, 0.33f, 0.33f, 0.66f),
|
||||
type = NavigationRegion.PREV,
|
||||
|
|
|
@ -15,7 +15,7 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
|||
*/
|
||||
class RightAndLeftNavigation : ViewerNavigation() {
|
||||
|
||||
override var regions: List<Region> = listOf(
|
||||
override var regionList: List<Region> = listOf(
|
||||
Region(
|
||||
rectF = RectF(0f, 0f, 0.33f, 1f),
|
||||
type = NavigationRegion.LEFT,
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="viewers_selector">
|
||||
<item>@string/label_default</item>
|
||||
<item>@string/left_to_right_viewer</item>
|
||||
<item>@string/right_to_left_viewer</item>
|
||||
<item>@string/vertical_viewer</item>
|
||||
<item>@string/webtoon_viewer</item>
|
||||
<item>@string/vertical_plus_viewer</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="rotation_type">
|
||||
<item>@string/label_default</item>
|
||||
<item>@string/rotation_free</item>
|
||||
<item>@string/rotation_portrait</item>
|
||||
<item>@string/rotation_landscape</item>
|
||||
<item>@string/rotation_force_portrait</item>
|
||||
<item>@string/rotation_force_landscape</item>
|
||||
<item>@string/rotation_reverse_portrait</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -6,8 +6,10 @@ import org.junit.jupiter.api.Test
|
|||
import org.junit.jupiter.api.parallel.Execution
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode
|
||||
import tachiyomi.domain.chapter.model.Chapter
|
||||
import java.time.Duration
|
||||
import java.time.ZonedDateTime
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.toJavaDuration
|
||||
|
||||
@Execution(ExecutionMode.CONCURRENT)
|
||||
class SetFetchIntervalTest {
|
||||
|
@ -22,49 +24,34 @@ class SetFetchIntervalTest {
|
|||
|
||||
@Test
|
||||
fun `calculateInterval returns default of 7 days when less than 3 distinct days`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..1).forEach {
|
||||
val duration = Duration.ofHours(10)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..2).map {
|
||||
chapterWithTime(chapter, 10.hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 7
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calculateInterval returns 7 when 5 chapters in 1 day`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(10)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..5).map {
|
||||
chapterWithTime(chapter, 10.hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 7
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calculateInterval returns 7 when 7 chapters in 48 hours, 2 day`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..2).forEach {
|
||||
val duration = Duration.ofHours(24L)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
}
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(48L)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..2).map {
|
||||
chapterWithTime(chapter, 24.hours)
|
||||
} + (1..5).map {
|
||||
chapterWithTime(chapter, 48.hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 7
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calculateInterval returns default of 1 day when interval less than 1`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(15L * it)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..5).map {
|
||||
chapterWithTime(chapter, (15 * it).hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1
|
||||
}
|
||||
|
@ -72,61 +59,46 @@ class SetFetchIntervalTest {
|
|||
// Normal interval calculation
|
||||
@Test
|
||||
fun `calculateInterval returns 1 when 5 chapters in 120 hours, 5 days`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(24L * it)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..5).map {
|
||||
chapterWithTime(chapter, (24 * it).hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calculateInterval returns 2 when 5 chapters in 240 hours, 10 days`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(48L * it)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..5).map {
|
||||
chapterWithTime(chapter, (48 * it).hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 2
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calculateInterval returns floored value when interval is decimal`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(25L * it)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..5).map {
|
||||
chapterWithTime(chapter, (25 * it).hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calculateInterval returns 1 when 5 chapters in 215 hours, 5 days`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(43L * it)
|
||||
val newChapter = chapterAddTime(chapter, duration)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..5).map {
|
||||
chapterWithTime(chapter, (43 * it).hours)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calculateInterval returns interval based on fetch time if upload time not available`() {
|
||||
val chapters = mutableListOf<Chapter>()
|
||||
(1..5).forEach {
|
||||
val duration = Duration.ofHours(25L * it)
|
||||
val newChapter = chapterAddTime(chapter, duration).copy(dateUpload = 0L)
|
||||
chapters.add(newChapter)
|
||||
val chapters = (1..5).map {
|
||||
chapterWithTime(chapter, (25 * it).hours).copy(dateUpload = 0L)
|
||||
}
|
||||
setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1
|
||||
}
|
||||
|
||||
private fun chapterAddTime(chapter: Chapter, duration: Duration): Chapter {
|
||||
val newTime = testTime.plus(duration).toEpochSecond() * 1000
|
||||
private fun chapterWithTime(chapter: Chapter, duration: Duration): Chapter {
|
||||
val newTime = testTime.plus(duration.toJavaDuration()).toEpochSecond() * 1000
|
||||
return chapter.copy(dateFetch = newTime, dateUpload = newTime)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -507,6 +507,7 @@
|
|||
<string name="creating_backup_error">Backup failed</string>
|
||||
<string name="missing_storage_permission">Storage permissions not granted</string>
|
||||
<string name="empty_backup_error">No library entries to back up</string>
|
||||
<string name="create_backup_file_error">Couldn\'t create a backup file</string>
|
||||
<string name="restore_miui_warning">Backup/restore may not function properly if MIUI Optimization is disabled.</string>
|
||||
<string name="restore_in_progress">Restore is already in progress</string>
|
||||
<string name="restoring_backup">Restoring backup</string>
|
||||
|
@ -620,6 +621,7 @@
|
|||
<string name="no_results_found">No results found</string>
|
||||
<!-- Do not translate "WebView" -->
|
||||
<string name="http_error_hint">Check website in WebView</string>
|
||||
<string name="licensed_manga_chapters_error">Licensed - No chapters to show</string>
|
||||
<string name="local_source">Local source</string>
|
||||
<string name="other_source">Other</string>
|
||||
<string name="last_used_source">Last used</string>
|
||||
|
|
|
@ -215,7 +215,7 @@ abstract class HttpSource : CatalogueSource {
|
|||
chapterListParse(response)
|
||||
}
|
||||
} else {
|
||||
Observable.error(Exception("Licensed - No chapters to show"))
|
||||
Observable.error(LicensedMangaChaptersException())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,3 +404,5 @@ abstract class HttpSource : CatalogueSource {
|
|||
*/
|
||||
override fun getFilterList() = FilterList()
|
||||
}
|
||||
|
||||
class LicensedMangaChaptersException : Exception("Licensed - No chapters to show")
|
||||
|
|
Reference in a new issue