Compare commits

...

20 Commits
v7.7 ... v7.7.3

Author SHA1 Message Date
Koitharu
0b8afe9c40 Fix checking for new chapters in some cases (#1212, #1195, #1190) 2024-12-18 18:26:27 +02:00
Koitharu
754ccc4197 Added url for NoDataReceivedException 2024-12-18 16:26:49 +02:00
Koitharu
ef691b1aed Update parsers 2024-12-18 15:48:57 +02:00
Koitharu
1bd916371a Update parsers 2024-12-14 09:36:50 +02:00
Koitharu
cd40dab8a4 Error handling fixes 2024-12-10 14:29:55 +02:00
Koitharu
d2ed8a1ace Update parsers 2024-12-07 15:18:18 +02:00
حيدر العراقي
024e3c11ee Translated using Weblate (Arabic)
Currently translated at 88.0% (668 of 759 strings)

Co-authored-by: حيدر العراقي <haiderdc12@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/ar/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
return_null
23ba302df8 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: return_null <demolang@dismail.de>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/zh_Hans/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
maryush
34e54e43e0 Translated using Weblate (Polish)
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: maryush <maryush@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/pl/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
Anon
07a8de6225 Translated using Weblate (Serbian)
Currently translated at 99.6% (756 of 759 strings)

Co-authored-by: Anon <anonymousprivate76@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/sr/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
gallegonovato
a3df6f799c Translated using Weblate (Spanish)
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/es/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
Maple Javora
d5722790ef Translated using Weblate (Czech)
Currently translated at 89.0% (676 of 759 strings)

Co-authored-by: Maple Javora <jindrous101@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/cs/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
johan
8bf540abbe Translated using Weblate (Czech)
Currently translated at 89.0% (676 of 759 strings)

Co-authored-by: johan <jqb4@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/cs/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
gekka
5241fa0d13 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: gekka <1778962971@qq.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/zh_Hans/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
Dragibus Noir
87e0c931a2 Translated using Weblate (French)
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: Dragibus Noir <dragibusnoir@pm.me>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/fr/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
Infy's Tagalog Translations
a51412801a Translated using Weblate (Filipino)
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/fil/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
TheOneWhoCares
a6c188d647 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: TheOneWhoCares <266nre4gw@mozmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/pt_BR/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
Frosted
831632cb8f Translated using Weblate (Turkish)
Currently translated at 100.0% (759 of 759 strings)

Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/tr/
Translation: Kotatsu/Strings
2024-12-07 15:17:34 +02:00
Koitharu
ad59bf50f4 Fix loading local manga without index #1192 2024-12-05 18:39:31 +02:00
Koitharu
6fe6c05327 Update parsers 2024-12-05 18:38:47 +02:00
29 changed files with 167 additions and 75 deletions

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@
.cxx .cxx
/.idea/deviceManager.xml /.idea/deviceManager.xml
/.kotlin/ /.kotlin/
/.idea/AndroidProjectSystem.xml

View File

@@ -18,8 +18,8 @@ android {
applicationId 'org.koitharu.kotatsu' applicationId 'org.koitharu.kotatsu'
minSdk = 21 minSdk = 21
targetSdk = 35 targetSdk = 35
versionCode = 692 versionCode = 695
versionName = '7.7' versionName = '7.7.3'
generatedDensities = [] generatedDensities = []
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner' testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
ksp { ksp {

View File

@@ -3,5 +3,5 @@ package org.koitharu.kotatsu.core.exceptions
import okio.IOException import okio.IOException
class NoDataReceivedException( class NoDataReceivedException(
url: String, val url: String,
) : IOException("No data has been received from $url") ) : IOException("No data has been received from $url")

View File

@@ -30,6 +30,7 @@ import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.parsers.util.find import org.koitharu.kotatsu.parsers.util.find
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.mapToSet
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.reader.domain.ReaderColorFilter import org.koitharu.kotatsu.reader.domain.ReaderColorFilter
import java.io.File import java.io.File
import java.net.Proxy import java.net.Proxy
@@ -412,10 +413,10 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
get() = prefs.getString(KEY_PROXY_PORT, null)?.toIntOrNull() ?: 0 get() = prefs.getString(KEY_PROXY_PORT, null)?.toIntOrNull() ?: 0
val proxyLogin: String? val proxyLogin: String?
get() = prefs.getString(KEY_PROXY_LOGIN, null)?.takeUnless { it.isEmpty() } get() = prefs.getString(KEY_PROXY_LOGIN, null)?.nullIfEmpty()
val proxyPassword: String? val proxyPassword: String?
get() = prefs.getString(KEY_PROXY_PASSWORD, null)?.takeUnless { it.isEmpty() } get() = prefs.getString(KEY_PROXY_PASSWORD, null)?.nullIfEmpty()
var localListOrder: SortOrder var localListOrder: SortOrder
get() = prefs.getEnumValue(KEY_LOCAL_LIST_ORDER, SortOrder.NEWEST) get() = prefs.getEnumValue(KEY_LOCAL_LIST_ORDER, SortOrder.NEWEST)

View File

@@ -11,6 +11,7 @@ import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.config.MangaSourceConfig import org.koitharu.kotatsu.parsers.config.MangaSourceConfig
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.SortOrder import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.settings.utils.validation.DomainValidator import org.koitharu.kotatsu.settings.utils.validation.DomainValidator
class SourceSettings(context: Context, source: MangaSource) : MangaSourceConfig { class SourceSettings(context: Context, source: MangaSource) : MangaSourceConfig {
@@ -38,7 +39,7 @@ class SourceSettings(context: Context, source: MangaSource) : MangaSourceConfig
is ConfigKey.ShowSuspiciousContent -> prefs.getBoolean(key.key, key.defaultValue) is ConfigKey.ShowSuspiciousContent -> prefs.getBoolean(key.key, key.defaultValue)
is ConfigKey.SplitByTranslations -> prefs.getBoolean(key.key, key.defaultValue) is ConfigKey.SplitByTranslations -> prefs.getBoolean(key.key, key.defaultValue)
is ConfigKey.PreferredImageServer -> prefs.getString(key.key, key.defaultValue)?.takeUnless(String::isEmpty) is ConfigKey.PreferredImageServer -> prefs.getString(key.key, key.defaultValue)?.nullIfEmpty()
} as T } as T
} }

View File

@@ -6,6 +6,7 @@ import android.net.Uri
import android.os.Build import android.os.Build
import android.os.storage.StorageManager import android.os.storage.StorageManager
import android.provider.DocumentsContract import android.provider.DocumentsContract
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.parsers.util.removeSuffix import org.koitharu.kotatsu.parsers.util.removeSuffix
import java.io.File import java.io.File
import java.lang.reflect.Array as ArrayReflect import java.lang.reflect.Array as ArrayReflect
@@ -80,7 +81,7 @@ private fun getVolumePathForAndroid11AndAbove(volumeId: String, context: Context
private fun getVolumeIdFromTreeUri(treeUri: Uri): String? { private fun getVolumeIdFromTreeUri(treeUri: Uri): String? {
val docId = DocumentsContract.getTreeDocumentId(treeUri) val docId = DocumentsContract.getTreeDocumentId(treeUri)
val split = docId.split(":".toRegex()) val split = docId.split(":".toRegex())
return split.firstOrNull()?.takeUnless { it.isEmpty() } return split.firstOrNull()?.nullIfEmpty()
} }
private fun getDocumentPathFromTreeUri(treeUri: Uri): String? { private fun getDocumentPathFromTreeUri(treeUri: Uri): String? {

View File

@@ -41,11 +41,13 @@ import org.koitharu.kotatsu.scrobbling.common.domain.ScrobblerAuthRequiredExcept
import java.io.ObjectOutputStream import java.io.ObjectOutputStream
import java.net.ConnectException import java.net.ConnectException
import java.net.NoRouteToHostException import java.net.NoRouteToHostException
import java.net.SocketException
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
import java.net.UnknownHostException import java.net.UnknownHostException
import java.util.Locale import java.util.Locale
private const val MSG_NO_SPACE_LEFT = "No space left on device" private const val MSG_NO_SPACE_LEFT = "No space left on device"
private const val MSG_CONNECTION_RESET = "Connection reset"
private const val IMAGE_FORMAT_NOT_SUPPORTED = "Image format not supported" private const val IMAGE_FORMAT_NOT_SUPPORTED = "Image format not supported"
fun Throwable.getDisplayMessage(resources: Resources): String = getDisplayMessageOrNull(resources) fun Throwable.getDisplayMessage(resources: Resources): String = getDisplayMessageOrNull(resources)
@@ -117,7 +119,7 @@ private fun Throwable.getDisplayMessageOrNull(resources: Resources): String? = w
is HttpException -> getHttpDisplayMessage(response.code, resources) is HttpException -> getHttpDisplayMessage(response.code, resources)
is HttpStatusException -> getHttpDisplayMessage(statusCode, resources) is HttpStatusException -> getHttpDisplayMessage(statusCode, resources)
else -> getDisplayMessage(message, resources) ?: message else -> mapDisplayMessage(message, resources) ?: message
}.takeUnless { it.isNullOrBlank() } }.takeUnless { it.isNullOrBlank() }
@DrawableRes @DrawableRes
@@ -140,6 +142,7 @@ fun Throwable.getCauseUrl(): String? = when (this) {
is NotFoundException -> url is NotFoundException -> url
is TooManyRequestExceptions -> url is TooManyRequestExceptions -> url
is CaughtException -> cause?.getCauseUrl() is CaughtException -> cause?.getCauseUrl()
is NoDataReceivedException -> url
is CloudFlareBlockedException -> url is CloudFlareBlockedException -> url
is CloudFlareProtectedException -> url is CloudFlareProtectedException -> url
is HttpStatusException -> url is HttpStatusException -> url
@@ -154,10 +157,11 @@ private fun getHttpDisplayMessage(statusCode: Int, resources: Resources): String
else -> null else -> null
} }
private fun getDisplayMessage(msg: String?, resources: Resources): String? = when { private fun mapDisplayMessage(msg: String?, resources: Resources): String? = when {
msg.isNullOrEmpty() -> null msg.isNullOrEmpty() -> null
msg.contains(MSG_NO_SPACE_LEFT) -> resources.getString(R.string.error_no_space_left) msg.contains(MSG_NO_SPACE_LEFT) -> resources.getString(R.string.error_no_space_left)
msg.contains(IMAGE_FORMAT_NOT_SUPPORTED) -> resources.getString(R.string.error_corrupted_file) msg.contains(IMAGE_FORMAT_NOT_SUPPORTED) -> resources.getString(R.string.error_corrupted_file)
msg == MSG_CONNECTION_RESET -> resources.getString(R.string.error_connection_reset)
msg == FILTER_MULTIPLE_GENRES_NOT_SUPPORTED -> resources.getString(R.string.error_multiple_genres_not_supported) msg == FILTER_MULTIPLE_GENRES_NOT_SUPPORTED -> resources.getString(R.string.error_multiple_genres_not_supported)
msg == FILTER_MULTIPLE_STATES_NOT_SUPPORTED -> resources.getString(R.string.error_multiple_states_not_supported) msg == FILTER_MULTIPLE_STATES_NOT_SUPPORTED -> resources.getString(R.string.error_multiple_states_not_supported)
msg == SEARCH_NOT_SUPPORTED -> resources.getString(R.string.error_search_not_supported) msg == SEARCH_NOT_SUPPORTED -> resources.getString(R.string.error_search_not_supported)
@@ -184,6 +188,7 @@ fun Throwable.isReportable(): Boolean {
|| this is WrongPasswordException || this is WrongPasswordException
|| this is TooManyRequestExceptions || this is TooManyRequestExceptions
|| this is HttpStatusException || this is HttpStatusException
|| this is SocketException
) { ) {
return false return false
} }

View File

@@ -17,6 +17,7 @@ import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.setTextColorAttr import org.koitharu.kotatsu.core.util.ext.setTextColorAttr
import org.koitharu.kotatsu.databinding.ItemPageThumbBinding import org.koitharu.kotatsu.databinding.ItemPageThumbBinding
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import com.google.android.material.R as materialR import com.google.android.material.R as materialR
fun pageThumbnailAD( fun pageThumbnailAD(
@@ -36,7 +37,7 @@ fun pageThumbnailAD(
AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView) AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView)
bind { bind {
val data: Any = item.page.preview?.takeUnless { it.isEmpty() } ?: item.page.toMangaPage() val data: Any = item.page.preview?.nullIfEmpty() ?: item.page.toMangaPage()
binding.imageViewThumb.newImageRequest(lifecycleOwner, data)?.run { binding.imageViewThumb.newImageRequest(lifecycleOwner, data)?.run {
defaultPlaceholders(context) defaultPlaceholders(context)
size(thumbSize) size(thumbSize)

View File

@@ -36,6 +36,7 @@ import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.parsers.model.SortOrder import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.parsers.model.YEAR_MIN import org.koitharu.kotatsu.parsers.model.YEAR_MIN
import org.koitharu.kotatsu.parsers.util.ifZero import org.koitharu.kotatsu.parsers.util.ifZero
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.parsers.util.suspendlazy.suspendLazy import org.koitharu.kotatsu.parsers.util.suspendlazy.suspendLazy
import org.koitharu.kotatsu.remotelist.ui.RemoteListFragment import org.koitharu.kotatsu.remotelist.ui.RemoteListFragment
import org.koitharu.kotatsu.search.domain.MangaSearchRepository import org.koitharu.kotatsu.search.domain.MangaSearchRepository
@@ -267,7 +268,7 @@ class FilterCoordinator @Inject constructor(
} }
fun setQuery(value: String?) { fun setQuery(value: String?) {
val newQuery = value?.trim()?.takeUnless { it.isEmpty() } val newQuery = value?.trim()?.nullIfEmpty()
currentListFilter.update { oldValue -> currentListFilter.update { oldValue ->
if (capabilities.isSearchWithFiltersSupported || newQuery == null) { if (capabilities.isSearchWithFiltersSupported || newQuery == null) {
oldValue.copy(query = newQuery) oldValue.copy(query = newQuery)

View File

@@ -10,6 +10,7 @@ import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils import com.google.android.material.badge.BadgeUtils
import com.google.android.material.badge.ExperimentalBadgeUtils import com.google.android.material.badge.ExperimentalBadgeUtils
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
@CheckResult @CheckResult
fun View.bindBadge(badge: BadgeDrawable?, counter: Int): BadgeDrawable? { fun View.bindBadge(badge: BadgeDrawable?, counter: Int): BadgeDrawable? {
@@ -34,7 +35,7 @@ private fun View.bindBadgeImpl(
if (counter > 0) { if (counter > 0) {
badgeDrawable.number = counter badgeDrawable.number = counter
} else { } else {
badgeDrawable.text = text?.takeUnless { it.isEmpty() } badgeDrawable.text = text?.nullIfEmpty()
} }
badgeDrawable.isVisible = true badgeDrawable.isVisible = true
badgeDrawable.align(this) badgeDrawable.align(this)

View File

@@ -26,6 +26,7 @@ import org.koitharu.kotatsu.core.util.ext.longHashCode
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.toListSorted import org.koitharu.kotatsu.core.util.ext.toListSorted
import org.koitharu.kotatsu.local.data.MangaIndex import org.koitharu.kotatsu.local.data.MangaIndex
import org.koitharu.kotatsu.local.data.hasZipExtension
import org.koitharu.kotatsu.local.data.isZipArchive import org.koitharu.kotatsu.local.data.isZipArchive
import org.koitharu.kotatsu.local.data.output.LocalMangaOutput.Companion.ENTRY_NAME_INDEX import org.koitharu.kotatsu.local.data.output.LocalMangaOutput.Companion.ENTRY_NAME_INDEX
import org.koitharu.kotatsu.local.domain.model.LocalManga import org.koitharu.kotatsu.local.domain.model.LocalManga
@@ -94,10 +95,12 @@ class LocalMangaParser(private val uri: Uri) {
chapters = if (withDetails) { chapters = if (withDetails) {
val chapters = fileSystem.listRecursively(rootPath) val chapters = fileSystem.listRecursively(rootPath)
.mapNotNullTo(HashSet()) { path -> .mapNotNullTo(HashSet()) { path ->
if (path != coverEntry && fileSystem.isRegularFile(path) && mimeTypeMap.isImage(path)) { when {
path.parent path == coverEntry -> null
} else { !fileSystem.isRegularFile(path) -> null
null mimeTypeMap.isImage(path) -> path.parent
hasZipExtension(path.name) -> path
else -> null
} }
}.sortedWith(compareBy(AlphanumComparator()) { x -> x.toString() }) }.sortedWith(compareBy(AlphanumComparator()) { x -> x.toString() })
chapters.mapIndexed { i, p -> chapters.mapIndexed { i, p ->

View File

@@ -38,6 +38,7 @@ import org.koitharu.kotatsu.databinding.ActivityColorFilterBinding
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.util.format import org.koitharu.kotatsu.parsers.util.format
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.reader.domain.ReaderColorFilter import org.koitharu.kotatsu.reader.domain.ReaderColorFilter
import javax.inject.Inject import javax.inject.Inject
import com.google.android.material.R as materialR import com.google.android.material.R as materialR
@@ -137,7 +138,7 @@ class ColorFilterConfigActivity :
} }
private fun loadPreview(page: MangaPage) { private fun loadPreview(page: MangaPage) {
val data: Any = page.preview?.takeUnless { it.isEmpty() } ?: page val data: Any = page.preview?.nullIfEmpty() ?: page
ImageRequest.Builder(this@ColorFilterConfigActivity) ImageRequest.Builder(this@ColorFilterConfigActivity)
.data(data) .data(data)
.scale(Scale.FILL) .scale(Scale.FILL)

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.scrobbling.common.data
import android.content.Context import android.content.Context
import androidx.core.content.edit import androidx.core.content.edit
import org.jsoup.internal.StringUtil.StringJoiner import org.jsoup.internal.StringUtil.StringJoiner
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerUser import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerUser
@@ -31,7 +32,7 @@ class ScrobblerStorage(context: Context, service: ScrobblerService) {
ScrobblerUser( ScrobblerUser(
id = lines[0].toLong(), id = lines[0].toLong(),
nickname = lines[1], nickname = lines[1],
avatar = lines[2].takeUnless(String::isEmpty), avatar = lines[2].nullIfEmpty(),
service = ScrobblerService.valueOf(lines[3]), service = ScrobblerService.valueOf(lines[3]),
) )
} }

View File

@@ -7,6 +7,7 @@ import okhttp3.internal.closeQuietly
import okio.IOException import okio.IOException
import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.network.CommonHeaders
import org.koitharu.kotatsu.parsers.util.mimeType import org.koitharu.kotatsu.parsers.util.mimeType
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.parseHtml
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage
@@ -34,7 +35,7 @@ class KitsuInterceptor(private val storage: ScrobblerStorage) : Interceptor {
} }
if (response.mimeType?.toMediaTypeOrNull()?.subtype == SUBTYPE_HTML) { if (response.mimeType?.toMediaTypeOrNull()?.subtype == SUBTYPE_HTML) {
val message = runCatchingCancellable { val message = runCatchingCancellable {
response.parseHtml().title().takeUnless { it.isEmpty() } response.parseHtml().title().nullIfEmpty()
}.onFailure { }.onFailure {
response.closeQuietly() response.closeQuietly()
}.getOrNull() ?: "Invalid response (${response.code})" }.getOrNull() ?: "Invalid response (${response.code})"

View File

@@ -1,6 +1,8 @@
package org.koitharu.kotatsu.tracker.domain package org.koitharu.kotatsu.tracker.domain
import android.util.Log
import coil3.request.CachePolicy import coil3.request.CachePolicy
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.core.model.getPreferredBranch import org.koitharu.kotatsu.core.model.getPreferredBranch
import org.koitharu.kotatsu.core.model.isLocal import org.koitharu.kotatsu.core.model.isLocal
import org.koitharu.kotatsu.core.parser.CachingMangaRepository import org.koitharu.kotatsu.core.parser.CachingMangaRepository
@@ -11,6 +13,7 @@ import org.koitharu.kotatsu.core.util.ext.toInstantOrNull
import org.koitharu.kotatsu.history.data.HistoryRepository import org.koitharu.kotatsu.history.data.HistoryRepository
import org.koitharu.kotatsu.local.data.LocalMangaRepository import org.koitharu.kotatsu.local.data.LocalMangaRepository
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.util.findById
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import org.koitharu.kotatsu.tracker.domain.model.MangaTracking import org.koitharu.kotatsu.tracker.domain.model.MangaTracking
import org.koitharu.kotatsu.tracker.domain.model.MangaUpdates import org.koitharu.kotatsu.tracker.domain.model.MangaUpdates
@@ -45,8 +48,9 @@ class CheckNewChaptersUseCase @Inject constructor(
runCatchingCancellable { runCatchingCancellable {
repository.updateTracks() repository.updateTracks()
val details = getFullManga(manga) val details = getFullManga(manga)
val chapters = details.chapters ?: return@withLock
val track = repository.getTrackOrNull(manga) ?: return@withLock val track = repository.getTrackOrNull(manga) ?: return@withLock
val branch = checkNotNull(details.chapters?.findById(currentChapterId)).branch
val chapters = details.getChapters(branch)
val chapterIndex = chapters.indexOfFirst { x -> x.id == currentChapterId } val chapterIndex = chapters.indexOfFirst { x -> x.id == currentChapterId }
val lastNewChapterIndex = chapters.size - track.newChapters val lastNewChapterIndex = chapters.size - track.newChapters
val lastChapter = chapters.lastOrNull() val lastChapter = chapters.lastOrNull()
@@ -70,7 +74,7 @@ class CheckNewChaptersUseCase @Inject constructor(
private suspend fun invokeImpl(track: MangaTracking): MangaUpdates = runCatchingCancellable { private suspend fun invokeImpl(track: MangaTracking): MangaUpdates = runCatchingCancellable {
val details = getFullManga(track.manga) val details = getFullManga(track.manga)
compare(track, details, getBranch(details)) compare(track, details, getBranch(details, track.lastChapterId))
}.getOrElse { error -> }.getOrElse { error ->
MangaUpdates.Failure( MangaUpdates.Failure(
manga = track.manga, manga = track.manga,
@@ -80,9 +84,17 @@ class CheckNewChaptersUseCase @Inject constructor(
repository.saveUpdates(updates) repository.saveUpdates(updates)
} }
private suspend fun getBranch(manga: Manga): String? { private suspend fun getBranch(manga: Manga, trackChapterId: Long): String? {
val history = historyRepository.getOne(manga) historyRepository.getOne(manga)?.let {
return manga.getPreferredBranch(history) manga.chapters?.findById(it.chapterId)
}?.let {
return it.branch
}
manga.chapters?.findById(trackChapterId)?.let {
return it.branch
}
// fallback
return manga.getPreferredBranch(null)
} }
private suspend fun getFullManga(manga: Manga): Manga = when { private suspend fun getFullManga(manga: Manga): Manga = when {
@@ -111,25 +123,29 @@ class CheckNewChaptersUseCase @Inject constructor(
private fun compare(track: MangaTracking, manga: Manga, branch: String?): MangaUpdates.Success { private fun compare(track: MangaTracking, manga: Manga, branch: String?): MangaUpdates.Success {
if (track.isEmpty()) { if (track.isEmpty()) {
// first check or manga was empty on last check // first check or manga was empty on last check
return MangaUpdates.Success(manga, emptyList(), isValid = false) return MangaUpdates.Success(manga, branch, emptyList(), isValid = false)
} }
val chapters = requireNotNull(manga.getChapters(branch)) val chapters = requireNotNull(manga.getChapters(branch))
if (BuildConfig.DEBUG && chapters.findById(track.lastChapterId) == null) {
Log.e("Tracker", "Chapter ${track.lastChapterId} not found")
}
val newChapters = chapters.takeLastWhile { x -> x.id != track.lastChapterId } val newChapters = chapters.takeLastWhile { x -> x.id != track.lastChapterId }
return when { return when {
newChapters.isEmpty() -> { newChapters.isEmpty() -> {
MangaUpdates.Success( MangaUpdates.Success(
manga = manga, manga = manga,
branch = branch,
newChapters = emptyList(), newChapters = emptyList(),
isValid = chapters.lastOrNull()?.id == track.lastChapterId, isValid = chapters.lastOrNull()?.id == track.lastChapterId,
) )
} }
newChapters.size == chapters.size -> { newChapters.size == chapters.size -> {
MangaUpdates.Success(manga, emptyList(), isValid = false) MangaUpdates.Success(manga, branch, emptyList(), isValid = false)
} }
else -> { else -> {
MangaUpdates.Success(manga, newChapters, isValid = true) MangaUpdates.Success(manga, branch, newChapters, isValid = true)
} }
} }
} }

View File

@@ -216,7 +216,6 @@ class TrackingRepository @Inject constructor(
} }
private fun TrackEntity.mergeWith(updates: MangaUpdates): TrackEntity { private fun TrackEntity.mergeWith(updates: MangaUpdates): TrackEntity {
val chapters = updates.manga.chapters.orEmpty()
return when (updates) { return when (updates) {
is MangaUpdates.Failure -> TrackEntity( is MangaUpdates.Failure -> TrackEntity(
mangaId = mangaId, mangaId = mangaId,
@@ -230,7 +229,7 @@ class TrackingRepository @Inject constructor(
is MangaUpdates.Success -> TrackEntity( is MangaUpdates.Success -> TrackEntity(
mangaId = mangaId, mangaId = mangaId,
lastChapterId = chapters.lastOrNull()?.id ?: NO_ID, lastChapterId = updates.manga.getChapters(updates.branch).lastOrNull()?.id ?: NO_ID,
newChapters = if (updates.isValid) newChapters + updates.newChapters.size else 0, newChapters = if (updates.isValid) newChapters + updates.newChapters.size else 0,
lastCheckTime = System.currentTimeMillis(), lastCheckTime = System.currentTimeMillis(),
lastChapterDate = updates.lastChapterDate().ifZero { lastChapterDate }, lastChapterDate = updates.lastChapterDate().ifZero { lastChapterDate },

View File

@@ -11,6 +11,7 @@ sealed interface MangaUpdates {
data class Success( data class Success(
override val manga: Manga, override val manga: Manga,
val branch: String?,
val newChapters: List<MangaChapter>, val newChapters: List<MangaChapter>,
val isValid: Boolean, val isValid: Boolean,
) : MangaUpdates { ) : MangaUpdates {

View File

@@ -659,4 +659,7 @@
<string name="external_source">خارجي/إضافي</string> <string name="external_source">خارجي/إضافي</string>
<string name="plugin_incompatible">مكون إضافي غير متوافق أو خطأ داخلي. تأكد من استخدام أحدث إصدار من المكون الإضافي وKotatsu</string> <string name="plugin_incompatible">مكون إضافي غير متوافق أو خطأ داخلي. تأكد من استخدام أحدث إصدار من المكون الإضافي وKotatsu</string>
<string name="invalid_server_address_message">mangatime.org</string> <string name="invalid_server_address_message">mangatime.org</string>
</resources> <string name="retry">حاول مجدداً</string>
<string name="pages_saved">الصفحات المحفوظة</string>
<string name="too_many_requests_message_retry">هنالك الكثير من الطلبات. حاول مرة أخرى بعد%s</string>
</resources>

View File

@@ -203,7 +203,7 @@
<string name="status_on_hold">Pozastaveno</string> <string name="status_on_hold">Pozastaveno</string>
<string name="status_dropped">Zahozeno</string> <string name="status_dropped">Zahozeno</string>
<string name="disable_all">Vypnout vše</string> <string name="disable_all">Vypnout vše</string>
<string name="use_fingerprint">Pokud lze, použijte otisk prstu</string> <string name="use_fingerprint">Pokud lze, použijte biometrii</string>
<string name="appwidget_shelf_description">Manga z vašich oblíbených</string> <string name="appwidget_shelf_description">Manga z vašich oblíbených</string>
<string name="appwidget_recent_description">Vaše nedávno čtená manga</string> <string name="appwidget_recent_description">Vaše nedávno čtená manga</string>
<string name="report">Hlášení</string> <string name="report">Hlášení</string>
@@ -251,7 +251,7 @@
<string name="manga_error_description_pattern">Podrobnosti chyby:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1. Zkuste &lt;a href=%2$s&gt;otveřít mangu v prohlížeči&lt;/a&gt; abyste se ujistili že je dostupná na zdroji&lt;br&gt;2. Ujistěte se že používáte &lt;a href=kotatsu://about&gt;nejnovější verzi Kotatsu&lt;/a&gt;&lt;br&gt;3. Pokud je dostupná, pošlete hlášení o chybě vývojářům.</string> <string name="manga_error_description_pattern">Podrobnosti chyby:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1. Zkuste &lt;a href=%2$s&gt;otveřít mangu v prohlížeči&lt;/a&gt; abyste se ujistili že je dostupná na zdroji&lt;br&gt;2. Ujistěte se že používáte &lt;a href=kotatsu://about&gt;nejnovější verzi Kotatsu&lt;/a&gt;&lt;br&gt;3. Pokud je dostupná, pošlete hlášení o chybě vývojářům.</string>
<string name="history_shortcuts">Zobrazovat zkratky nedávných mang</string> <string name="history_shortcuts">Zobrazovat zkratky nedávných mang</string>
<string name="history_shortcuts_summary">Udělejte nedávné mangy dostupné dlouhým kliknutím na ikonu aplikace</string> <string name="history_shortcuts_summary">Udělejte nedávné mangy dostupné dlouhým kliknutím na ikonu aplikace</string>
<string name="reader_control_ltr_summary">Kliknutí do pravého rohu nebo stisknutí pravého tlačítka vždy zobrazí následující stranu.</string> <string name="reader_control_ltr_summary">Neměň směr přepínání stránek v režimu čtení, například stisknutí pravé klávesy vždy přepne na další stránku. Tato volba ovlivňuje pouze hardwarová vstupní zařízení.</string>
<string name="reader_control_ltr">Ovládání ergonomické čtečky</string> <string name="reader_control_ltr">Ovládání ergonomické čtečky</string>
<string name="color_correction">Korekce barev</string> <string name="color_correction">Korekce barev</string>
<string name="brightness">Jas</string> <string name="brightness">Jas</string>
@@ -654,4 +654,21 @@
<string name="unpin">Odepnout</string> <string name="unpin">Odepnout</string>
<string name="too_many_requests_message_retry">Server přetížen. Zkuste to za %s</string> <string name="too_many_requests_message_retry">Server přetížen. Zkuste to za %s</string>
<string name="minutes_seconds_short">%1$d m %2$d s</string> <string name="minutes_seconds_short">%1$d m %2$d s</string>
<string name="invalid_proxy_configuration">Nesprávná proxy konfigurace</string>
<string name="plugin_incompatible_with_cause">Plugin error:%s\nUjisti se, že používáš poslední verzi Kotatsu a pluginu</string>
<string name="percent_left">Procent zbývá</string>
<string name="plugin_incompatible">Nekompatibilní plugin nebo vnitřní chyba. Ujistěte se, že používáte nejnovější verzi pluginu a aplikace Kotatsu.</string>
<string name="external_source">Externí zdroj/plugin</string>
<string name="retry">Opakovat</string>
<string name="connection_ok">Připojení je OK</string>
<string name="recent_sources">Nedávné zdroje</string>
<string name="image_server">Preferovaný server pro média</string>
<string name="crop_pages">Oříznout stránky</string>
<string name="show_quick_filters">Zobrazit rychlé filtry</string>
<string name="source_unpinned">Zdroj odepnut</string>
<string name="sources_unpinned">Zdroje odepnuty</string>
<string name="sources_pinned">Zdroje připnuty</string>
<string name="percent_read">Procenta přečtených</string>
<string name="chapters_read">Kapitol přečtených</string>
<string name="chapters_left">Kapitol zbývajících</string>
</resources> </resources>

View File

@@ -752,4 +752,5 @@
<string name="email">Correo electrónico</string> <string name="email">Correo electrónico</string>
<string name="handle_links">Gestionar enlaces</string> <string name="handle_links">Gestionar enlaces</string>
<string name="handle_links_summary">Gestionar enlaces de manga desde aplicaciones externas (por ejemplo, navegador web). También puede ser necesario habilitarlo manualmente en la configuración de la aplicación</string> <string name="handle_links_summary">Gestionar enlaces de manga desde aplicaciones externas (por ejemplo, navegador web). También puede ser necesario habilitarlo manualmente en la configuración de la aplicación</string>
<string name="captcha_required_message">Esta fuente requiere resolver un captcha para continuar</string>
</resources> </resources>

View File

@@ -752,4 +752,5 @@
<string name="handle_links">Pangasiwaan ang mga link</string> <string name="handle_links">Pangasiwaan ang mga link</string>
<string name="handle_links_summary">Pangasiwaan ang manga link mula sa mga panlabas na application (hal. web browser). Maaaring kailanganin mo rin itong manual na paganahin sa mga setting ng system ng aplikasyon</string> <string name="handle_links_summary">Pangasiwaan ang manga link mula sa mga panlabas na application (hal. web browser). Maaaring kailanganin mo rin itong manual na paganahin sa mga setting ng system ng aplikasyon</string>
<string name="email">Ang email</string> <string name="email">Ang email</string>
<string name="captcha_required_message">Ang source na ito ay kinakailang lutasin ang captcha para magpatuloy</string>
</resources> </resources>

View File

@@ -749,4 +749,5 @@
<string name="handle_links">Gérer les liens</string> <string name="handle_links">Gérer les liens</string>
<string name="email">Courriel</string> <string name="email">Courriel</string>
<string name="handle_links_summary">Gérer les liens vers des mangas à partir d\'applications externes (par exemple, un navigateur web). Il se peut que vous deviez également l\'activer manuellement dans les paramètres système de l\'application</string> <string name="handle_links_summary">Gérer les liens vers des mangas à partir d\'applications externes (par exemple, un navigateur web). Il se peut que vous deviez également l\'activer manuellement dans les paramètres système de l\'application</string>
<string name="captcha_required_message">Cette source nécessite la résolution d\'un captcha pour continuer</string>
</resources> </resources>

View File

@@ -50,7 +50,7 @@
<string name="processing_">Przetwarzanie…</string> <string name="processing_">Przetwarzanie…</string>
<string name="updated">Zaktualizowane</string> <string name="updated">Zaktualizowane</string>
<string name="save_page">Zapisz stronę</string> <string name="save_page">Zapisz stronę</string>
<string name="page_saved">Zapisano</string> <string name="page_saved">Zapisano stronę</string>
<string name="vibration">Wibracje</string> <string name="vibration">Wibracje</string>
<string name="manga_shelf">Biblioteka</string> <string name="manga_shelf">Biblioteka</string>
<string name="recent_manga">Ostatnie</string> <string name="recent_manga">Ostatnie</string>
@@ -739,4 +739,18 @@
<string name="allow_always">Zezwalaj zawsze</string> <string name="allow_always">Zezwalaj zawsze</string>
<string name="allow_once">Zezwól raz</string> <string name="allow_once">Zezwól raz</string>
<string name="ask_every_time">Pytaj za każdym razem</string> <string name="ask_every_time">Pytaj za każdym razem</string>
<string name="pages_saved">Zapisane strony</string>
<string name="portrait">Portret</string>
<string name="access_denied_403">Odmowa dostępu (403)</string>
<string name="captcha_required_message">To źródło wymaga rozwiązania captcha, aby kontynuować</string>
<string name="handle_links">Obsługa linków</string>
<string name="email">E-mail</string>
<string name="max_backups_count">Maksymalna liczba kopii zapasowych</string>
<string name="delete_old_backups">Usuń stare kopie zapasowe</string>
<string name="delete_old_backups_summary">Automatycznie usuwaj stare pliki kopii zapasowych, aby zaoszczędzić miejsce na dysku</string>
<string name="plugin_incompatible_with_cause">Błąd wtyczki: %s\nUpewnij się, że używasz najnowszej wersji wtyczki i Kotatsu</string>
<string name="error_not_image">Błędny format: oczekiwany obraz, ale pobrano %s</string>
<string name="screen_orientation">Orientacja ekranu</string>
<string name="landscape">Poziomo</string>
<string name="handle_links_summary">Obsługuj linki do mangi z zewnętrznych aplikacji (np. przeglądarki internetowej). Może być również konieczne ręczne włączenie go w ustawieniach systemowych aplikacji</string>
</resources> </resources>

View File

@@ -3,7 +3,7 @@
<string name="read">Ler</string> <string name="read">Ler</string>
<string name="you_have_not_favourites_yet">Você ainda não marcou alguma obra como favorita</string> <string name="you_have_not_favourites_yet">Você ainda não marcou alguma obra como favorita</string>
<string name="local_storage">Armazenamento local</string> <string name="local_storage">Armazenamento local</string>
<string name="favourites">Favoritos</string> <string name="favourites">Favoritas</string>
<string name="history">Histórico</string> <string name="history">Histórico</string>
<string name="error_occurred">Ocorreu um erro</string> <string name="error_occurred">Ocorreu um erro</string>
<string name="network_error">Erro de rede</string> <string name="network_error">Erro de rede</string>
@@ -61,8 +61,8 @@
<string name="standard">Padrão</string> <string name="standard">Padrão</string>
<string name="read_mode">Modo de leitura</string> <string name="read_mode">Modo de leitura</string>
<string name="grid_size">Tamanho da grade</string> <string name="grid_size">Tamanho da grade</string>
<string name="search_on_s">Pesquisar em %s</string> <string name="search_on_s">Procurar em %s</string>
<string name="delete_manga">Excluir mangá</string> <string name="delete_manga">Excluir obra</string>
<string name="text_delete_local_manga">Excluir “%s” do dispositivo permanentemente?</string> <string name="text_delete_local_manga">Excluir “%s” do dispositivo permanentemente?</string>
<string name="reader_settings">Configurações do leitor</string> <string name="reader_settings">Configurações do leitor</string>
<string name="_continue">Continuar</string> <string name="_continue">Continuar</string>
@@ -288,8 +288,7 @@
<string name="history_shortcuts_summary">Torne as obras recentes disponíveis ao pressionar e segurar o ícone do aplicativo</string> <string name="history_shortcuts_summary">Torne as obras recentes disponíveis ao pressionar e segurar o ícone do aplicativo</string>
<string name="no_manga_sources_text">Habilite fontes para ler obras online</string> <string name="no_manga_sources_text">Habilite fontes para ler obras online</string>
<string name="random">Aleatória</string> <string name="random">Aleatória</string>
<string name="categories_delete_confirm">Você tem certeza de que deseja excluir as categorias favoritas selecionadas? <string name="categories_delete_confirm">Você tem certeza de que deseja excluir as categorias favoritas selecionadas?\nTodas as obras nelas serão perdidas e isso não pode ser desfeito.</string>
\nTodas as obras nelas serão perdidas e isso não pode ser desfeito</string>
<string name="reorder">Reordenar</string> <string name="reorder">Reordenar</string>
<string name="empty">Vazio</string> <string name="empty">Vazio</string>
<string name="explore">Explorar</string> <string name="explore">Explorar</string>
@@ -393,7 +392,7 @@
<string name="network">Rede</string> <string name="network">Rede</string>
<string name="data_and_privacy">Dados e privacidade</string> <string name="data_and_privacy">Dados e privacidade</string>
<string name="restore_summary">Restaurar backup criado anteriormente</string> <string name="restore_summary">Restaurar backup criado anteriormente</string>
<string name="webtoon_zoom_summary">Permitir zoom no gesto no modo webtoon</string> <string name="webtoon_zoom_summary">Permitir zoom em gesto no modo webtoon</string>
<string name="reader_info_bar_summary">Mostrar a hora atual e o progresso da leitura na parte superior da tela</string> <string name="reader_info_bar_summary">Mostrar a hora atual e o progresso da leitura na parte superior da tela</string>
<string name="clear_source_cookies_summary">Limpar cookies apenas para o domínio especificado. Na maioria dos casos invalidará a autorização</string> <string name="clear_source_cookies_summary">Limpar cookies apenas para o domínio especificado. Na maioria dos casos invalidará a autorização</string>
<string name="download_option_all_chapters">Todos os capítulos com tradução %s</string> <string name="download_option_all_chapters">Todos os capítulos com tradução %s</string>
@@ -501,8 +500,7 @@
<string name="source_enabled">Fonte habilitada</string> <string name="source_enabled">Fonte habilitada</string>
<string name="disable_nsfw_summary">Desative as fontes NSFW e oculte as obras adultas da lista, se possível</string> <string name="disable_nsfw_summary">Desative as fontes NSFW e oculte as obras adultas da lista, se possível</string>
<string name="speed_value">x%.1f</string> <string name="speed_value">x%.1f</string>
<string name="no_manga_sources_catalog_text">Não há fontes disponíveis nesta seção, ou todas elas podem já ter sido habilitadas. <string name="no_manga_sources_catalog_text">Não há fontes disponíveis nesta seção, ou todas elas podem já ter sido habilitadas.\nFique atento</string>
\nFique atento</string>
<string name="available_d">Disponível: %1$d</string> <string name="available_d">Disponível: %1$d</string>
<string name="state">Situação</string> <string name="state">Situação</string>
<string name="state_paused">Pausada</string> <string name="state_paused">Pausada</string>
@@ -530,9 +528,7 @@
<string name="rating_adult">Adulta</string> <string name="rating_adult">Adulta</string>
<string name="default_tab">Aba padrão</string> <string name="default_tab">Aba padrão</string>
<string name="content_rating">Classificação do Conteúdo</string> <string name="content_rating">Classificação do Conteúdo</string>
<string name="mark_as_completed_prompt">Deseja marcar a obra selecionado como completa? <string name="mark_as_completed_prompt">Deseja marcar a obra selecionada como completa?\n\nAviso: o progresso de leitura atual será perdido.</string>
\n
\nAviso: o progresso de leitura atual será perdido.</string>
<string name="mark_as_completed">Marcar como completa</string> <string name="mark_as_completed">Marcar como completa</string>
<string name="category_hidden_done">Esta categoria foi ocultada da tela inicial e pode ser acessada novamente através de Menu → Gerenciar categorias</string> <string name="category_hidden_done">Esta categoria foi ocultada da tela inicial e pode ser acessada novamente através de Menu → Gerenciar categorias</string>
<string name="volume_">Volume %d</string> <string name="volume_">Volume %d</string>
@@ -557,7 +553,7 @@
<string name="use_two_pages_landscape">Usar layout de duas páginas na orientação paisagem (beta)</string> <string name="use_two_pages_landscape">Usar layout de duas páginas na orientação paisagem (beta)</string>
<string name="last_read">Última leitura</string> <string name="last_read">Última leitura</string>
<string name="none">Nenhum</string> <string name="none">Nenhum</string>
<string name="default_webtoon_zoom_out">Diminuir zoom padrão do webtoon</string> <string name="default_webtoon_zoom_out">Diminuir zoom padrão da webtoon</string>
<string name="fullscreen_mode">Modo tela cheia</string> <string name="fullscreen_mode">Modo tela cheia</string>
<string name="reader_fullscreen_summary">Ocultar a barra de status e navegação</string> <string name="reader_fullscreen_summary">Ocultar a barra de status e navegação</string>
<string name="remove_from_history">Remover do histórico</string> <string name="remove_from_history">Remover do histórico</string>
@@ -612,7 +608,7 @@
<string name="order_oldest">Mais velho</string> <string name="order_oldest">Mais velho</string>
<string name="long_ago_read">Lido há muito tempo atrás</string> <string name="long_ago_read">Lido há muito tempo atrás</string>
<string name="split_by_translations">Separar por traduções</string> <string name="split_by_translations">Separar por traduções</string>
<string name="fix">Fixar</string> <string name="fix">Corrigir</string>
<string name="error_no_data_received">Nenhum dado foi recebido do servidor</string> <string name="error_no_data_received">Nenhum dado foi recebido do servidor</string>
<string name="enable_source">Habilitar fonte</string> <string name="enable_source">Habilitar fonte</string>
<string name="unsupported_source">Esta fonte não é suportada</string> <string name="unsupported_source">Esta fonte não é suportada</string>
@@ -622,10 +618,10 @@
<string name="disable_connectivity_check">Desativar a verificação de conectividade</string> <string name="disable_connectivity_check">Desativar a verificação de conectividade</string>
<string name="disable_connectivity_check_summary">Ignore a verificação de conectividade caso tenha problemas com ela (por exemplo, entrar no modo off-line mesmo que a rede esteja conectada)</string> <string name="disable_connectivity_check_summary">Ignore a verificação de conectividade caso tenha problemas com ela (por exemplo, entrar no modo off-line mesmo que a rede esteja conectada)</string>
<string name="webtoon_gaps">Lacunas no modo webtoon</string> <string name="webtoon_gaps">Lacunas no modo webtoon</string>
<string name="webtoon_gaps_summary">Mostrar espaços verticais entre as páginas no modo webtoon</string> <string name="webtoon_gaps_summary">Mostrar lacunas verticais entre as páginas no modo webtoon</string>
<string name="authors">Autores</string> <string name="authors">Autores</string>
<string name="ignore_ssl_errors_summary">Você pode desativar a verificação de certificados SSL caso tenha problemas relacionados a SSL ao acessar recursos de rede. Isso pode afetar sua segurança. É necessário reiniciar o aplicativo após alterar essa configuração.</string> <string name="ignore_ssl_errors_summary">Você pode desativar a verificação de certificados SSL caso tenha problemas relacionados a SSL ao acessar recursos de rede. Isso pode afetar sua segurança. É necessário reiniciar o aplicativo após alterar essa configuração.</string>
<string name="search_suggestions">Sugestões de Pesquisa</string> <string name="search_suggestions">Sugestões de pesquisa</string>
<string name="recent_queries">Consultas recentes</string> <string name="recent_queries">Consultas recentes</string>
<string name="suggested_queries">Consultas sugeridas</string> <string name="suggested_queries">Consultas sugeridas</string>
<string name="disable">Desativar</string> <string name="disable">Desativar</string>
@@ -649,21 +645,21 @@
<string name="chapters_read">Capítulos lidos</string> <string name="chapters_read">Capítulos lidos</string>
<string name="chapters_left">Capítulos restantes</string> <string name="chapters_left">Capítulos restantes</string>
<string name="pin">Fixar</string> <string name="pin">Fixar</string>
<string name="unpin">Desfixar</string> <string name="unpin">Desafixar</string>
<string name="source_pinned">Fonte fixada</string> <string name="source_pinned">Fonte fixada</string>
<string name="source_unpinned">Fonte desfixada</string> <string name="source_unpinned">Fonte desafixada</string>
<string name="sources_pinned">Fontes fixadas</string> <string name="sources_pinned">Fontes fixadas</string>
<string name="recent_sources">Fontes recentes</string> <string name="recent_sources">Fontes recentes</string>
<string name="external_source">Plugin/Externo</string> <string name="external_source">Plugin/Externo</string>
<string name="sources_unpinned">Fontes desfixadas</string> <string name="sources_unpinned">Fontes desafixadas</string>
<string name="tracker_debug_info">Checando por novos logs de capítulos</string> <string name="tracker_debug_info">Checando por novos logs de capítulos</string>
<string name="tracker_debug_info_summary">Informações de Debug sobre a checagem de fundo para novos capítulos</string> <string name="tracker_debug_info_summary">Informações de Debug sobre a checagem de fundo para novos capítulos</string>
<string name="plugin_incompatible">Plugin incompatível ou erro interno. Certifique-se de que está usando a versão mais recente do plugin e do Kotatsu</string> <string name="plugin_incompatible">Plugin incompatível ou erro interno. Certifique-se de que está usando a versão mais recente do plugin e do Kotatsu</string>
<string name="show_quick_filters_summary">Habilitar filtros em todas as fontes compatíveis</string> <string name="show_quick_filters_summary">Habilitar filtros em todas as fontes compatíveis</string>
<string name="show_quick_filters">Mostrar filtros</string> <string name="show_quick_filters">Mostrar filtros</string>
<string name="scrobbler_auth_required">Faça login em %s para continuar</string> <string name="scrobbler_auth_required">Faça login em %s para continuar</string>
<string name="scrobbler_auth_intro">Faça login para configurar a integração com %s. Isso permitirá que você acompanhe o progresso e o status de sua leitura de mangás</string> <string name="scrobbler_auth_intro">Faça login para configurar a integração com %s. Isso permitirá que você acompanhe o progresso e o status de sua leitura</string>
<string name="unstable_feature_summary">Essa função é experimental. Certifique-se de que você tenha um backup para evitar a perda de dados</string> <string name="unstable_feature_summary">Essa função é experimental. Certifique-se de que você tenha um backup para evitar a perca de dados</string>
<string name="recently_added">Adicionado recentemente</string> <string name="recently_added">Adicionado recentemente</string>
<string name="added_long_ago">Adicionado há muito tempo</string> <string name="added_long_ago">Adicionado há muito tempo</string>
<string name="popular_today">Popular hoje</string> <string name="popular_today">Popular hoje</string>
@@ -674,31 +670,31 @@
<string name="low_rating">Classificação baixa</string> <string name="low_rating">Classificação baixa</string>
<string name="original_language">Idioma original</string> <string name="original_language">Idioma original</string>
<string name="year">Ano</string> <string name="year">Ano</string>
<string name="source_code">Códico fonte</string> <string name="source_code">Código fonte</string>
<string name="user_manual">Manual do Usuário</string> <string name="user_manual">Manual do usuário</string>
<string name="telegram_group">Grupo do Telegram</string> <string name="telegram_group">Grupo do Telegram</string>
<string name="skip_all">Pular Todos</string> <string name="skip_all">Pular todas</string>
<string name="by_date">Data</string> <string name="by_date">Data</string>
<string name="popularity">Popularidade</string> <string name="popularity">Popularidade</string>
<string name="popular_in_month">Popular neste mês</string> <string name="popular_in_month">Popular neste mês</string>
<string name="sort_order_asc">Ascendente</string> <string name="sort_order_asc">Ascendente</string>
<string name="years">Anos</string> <string name="years">Anos</string>
<string name="any">Todos</string> <string name="any">Qualquer</string>
<string name="filter_search_warning">Esta fonte não oferece suporte à pesquisa com filtros. Seus filtros foram limpos</string> <string name="filter_search_warning">Esta fonte não oferece suporte à pesquisa com filtros. Seus filtros foram limpos</string>
<string name="start_download">Iniciar download</string> <string name="start_download">Comecar a baixar</string>
<string name="save_manga_confirm">Salvar o mangá selecionado? Isso pode consumir dados e armazenamento</string> <string name="save_manga_confirm">Salvar a obra selecionada? Isso pode consumir dados e armazenamento</string>
<string name="save_manga">Salvar o mangá</string> <string name="save_manga">Salvar a obra</string>
<string name="genre">Gênero</string> <string name="genre">Gênero</string>
<string name="error_not_image">Formato inválido: esperava imagem, mas obteve %s</string> <string name="error_not_image">Formato inválido: esperava-se imagem, mas obtivemos %s</string>
<string name="invalid_proxy_configuration">Configuração de proxy inválida</string> <string name="invalid_proxy_configuration">Configuração de proxy inválida</string>
<string name="error_image_format">Formato de imagem não suportado: %s</string> <string name="error_image_format">Formato de imagem não suportado: %s</string>
<string name="manga_with_downloaded_chapters">Mangá com capítulos baixados</string> <string name="manga_with_downloaded_chapters">Obras com capítulos baixados</string>
<string name="manga_fix_prompt">Essa função encontrará fontes alternativas para o mangá selecionado. A tarefa levará algum tempo e será executada em segundo plano</string> <string name="manga_fix_prompt">Essa função encontrará fontes alternativas para a obra selecionada. A tarefa levará algum tempo e será executada em segundo plano</string>
<string name="manga_replaced">Mangá “%1$s” (%2$s) substituído por “%3$s” (%4$s)</string> <string name="manga_replaced">Obra “%1$s” (%2$s) substituída por “%3$s” (%4$s)</string>
<string name="no_alternatives_found">Não foi encontrado alternativas para “%s”</string> <string name="no_alternatives_found">Não foi encontrado alternativas para “%s”</string>
<string name="pages_saved">Páginas salvas</string> <string name="pages_saved">Páginas salvas</string>
<string name="text_empty_holder_secondary_filtered">Não existem obras que correspondam aos filtros selecionados</string> <string name="text_empty_holder_secondary_filtered">Não existem obras que correspondam aos filtros selecionados</string>
<string name="plugin_incompatible_with_cause">Plugin error: %s\n Verifique se você está usando a versão mais recente do plug-in e do Kotatsu</string> <string name="plugin_incompatible_with_cause">Erro de plugin: %s\n· Certifique-se de que você está usando a versão mais recente do plugin e Kotatsu</string>
<string name="sort_order_desc">Descendente</string> <string name="sort_order_desc">Descendente</string>
<string name="download_new_chapters">Baixar novos capítulos</string> <string name="download_new_chapters">Baixar novos capítulos</string>
<string name="retry">Retentar</string> <string name="retry">Retentar</string>
@@ -707,17 +703,17 @@
<string name="unstable_feature">Recurso instável</string> <string name="unstable_feature">Recurso instável</string>
<string name="popular_in_hour">Popular no momento</string> <string name="popular_in_hour">Popular no momento</string>
<string name="updated_long_ago">Atualizado há muito tempo</string> <string name="updated_long_ago">Atualizado há muito tempo</string>
<string name="downloads_background">Downloads em segundo plano</string> <string name="downloads_background">Baixando em segundo plano</string>
<string name="content_type_novel">Romance</string> <string name="content_type_novel">Novel</string>
<string name="content_type_manhua">Manhua</string> <string name="content_type_manhua">Manhua</string>
<string name="content_type_manhwa">Manhwa</string> <string name="content_type_manhwa">Manhwa</string>
<string name="seconds_short">%d s</string> <string name="seconds_short">%d s</string>
<string name="minutes_seconds_short">%1$d m %2$d s</string> <string name="minutes_seconds_short">%1$d min %2$d s</string>
<string name="unpopular">Impopular</string> <string name="unpopular">Impopular</string>
<string name="stuck">Preso</string> <string name="stuck">Preso</string>
<string name="not_in_favorites">Não está nos favoritos</string> <string name="not_in_favorites">Não está nas favoritas</string>
<string name="fixing_manga">Corrigindo o mangá</string> <string name="fixing_manga">Corrigindo a obra</string>
<string name="fixed">Corrigido</string> <string name="fixed">Corrigida</string>
<string name="no_fix_required">Nenhuma correção necessária para \"%s\"</string> <string name="no_fix_required">Nenhuma correção necessária para \"%s\"</string>
<string name="handle_links_summary">Lidar com links de mangá de aplicações externas (ex: navegador). Você talvez precise habilitar isso manualmente nas configurações da aplicação</string> <string name="handle_links_summary">Lidar com links de mangá de aplicações externas (ex: navegador). Você talvez precise habilitar isso manualmente nas configurações da aplicação</string>
<string name="demographic_kodomo">Kodomo</string> <string name="demographic_kodomo">Kodomo</string>
@@ -733,4 +729,24 @@
<string name="max_backups_count">Número máximo de backups</string> <string name="max_backups_count">Número máximo de backups</string>
<string name="delete_old_backups">Apagar backups antigos</string> <string name="delete_old_backups">Apagar backups antigos</string>
<string name="delete_old_backups_summary">Automaticamente apagar backups antigos para liberar espaço</string> <string name="delete_old_backups_summary">Automaticamente apagar backups antigos para liberar espaço</string>
<string name="screen_orientation">Orientação de tela</string>
<string name="portrait">Portrato</string>
<string name="landscape">Paisagem</string>
<string name="content_type_game_cg">Jogo CG</string>
<string name="captcha_required_message">Essa fonte requisita que você resolva um captcha para continuar</string>
<string name="content_type_image_set">Imagens</string>
<string name="content_type_doujinshi">Doujinshi</string>
<string name="debug">Depurar (para desenvolvedores)</string>
<string name="content_type_artist_cg">Artista CG</string>
<string name="more_options">Mais opções</string>
<string name="download_added">Baixando</string>
<string name="chapter_selection_hint">Você pode selecionar capítulos para baixar pressionando-os na lista de capítulos.</string>
<string name="destination_directory">Diretório de destinação</string>
<string name="chapters_all">Todos</string>
<string name="dont_allow">Não permitir</string>
<string name="allow_always">Permitir sempre</string>
<string name="allow_once">Permitir uma vez</string>
<string name="ask_every_time">Sempre pergunte</string>
<string name="download_over_cellular">Baixando pelos dados móveis</string>
<string name="download_cellular_confirm">Permitir baixar pelos dados móveis?</string>
</resources> </resources>

View File

@@ -752,4 +752,5 @@
<string name="handle_links_summary">Руковање манга везама из спољних апликација (нпр. из прегледача). Можда ћеш морати да је омогућиш и ручно у системским поставкама апликације</string> <string name="handle_links_summary">Руковање манга везама из спољних апликација (нпр. из прегледача). Можда ћеш морати да је омогућиш и ручно у системским поставкама апликације</string>
<string name="handle_links">Руковање везама</string> <string name="handle_links">Руковање везама</string>
<string name="email">Е-пошта</string> <string name="email">Е-пошта</string>
<string name="captcha_required_message">Овај извор захтева решавање CAPTCHA за наставак</string>
</resources> </resources>

View File

@@ -752,4 +752,5 @@
<string name="email">E-posta</string> <string name="email">E-posta</string>
<string name="handle_links">Bağlantıları</string> <string name="handle_links">Bağlantıları</string>
<string name="handle_links_summary">Harici uygulamalardaki (örn. web tarayıcısı) manga bağlantılarını uygulamada açın. Uygulamanın sistem ayarlarından bunu aktifleştirmeniz gerekebilir</string> <string name="handle_links_summary">Harici uygulamalardaki (örn. web tarayıcısı) manga bağlantılarını uygulamada açın. Uygulamanın sistem ayarlarından bunu aktifleştirmeniz gerekebilir</string>
<string name="captcha_required_message">Bu kaynağın kullanılabilmesi için bir captcha çözülmesi gerekiyor</string>
</resources> </resources>

View File

@@ -621,7 +621,7 @@
<string name="show_updated">显示更新</string> <string name="show_updated">显示更新</string>
<string name="webtoon_gaps_summary">在条漫模式下添加页与页之间的横向缝隙</string> <string name="webtoon_gaps_summary">在条漫模式下添加页与页之间的横向缝隙</string>
<string name="webtoon_gaps">缝隙条漫模式</string> <string name="webtoon_gaps">缝隙条漫模式</string>
<string name="pin_navigation_ui">置顶导航 UI</string> <string name="pin_navigation_ui">固定导航 UI</string>
<string name="frequency_of_check">自动检查更新频率</string> <string name="frequency_of_check">自动检查更新频率</string>
<string name="new_chapters_pattern">%1$s: %2$d</string> <string name="new_chapters_pattern">%1$s: %2$d</string>
<string name="pin_navigation_ui_summary">当上下滑动时不隐藏导航栏和搜索框</string> <string name="pin_navigation_ui_summary">当上下滑动时不隐藏导航栏和搜索框</string>
@@ -752,4 +752,5 @@
<string name="handle_links">处理链接</string> <string name="handle_links">处理链接</string>
<string name="handle_links_summary">处理来自外部程序的漫画链接(如 Web 浏览器), 可能需要在程序的系统设置中手动开启</string> <string name="handle_links_summary">处理来自外部程序的漫画链接(如 Web 浏览器), 可能需要在程序的系统设置中手动开启</string>
<string name="email">电子邮箱</string> <string name="email">电子邮箱</string>
<string name="captcha_required_message">此图源需要通过验证以继续操作</string>
</resources> </resources>

View File

@@ -769,4 +769,5 @@
<string name="handle_links_summary">Handle manga links from external applications (e.g. web browser). You may also need to enable it manually in the application\'s system settings</string> <string name="handle_links_summary">Handle manga links from external applications (e.g. web browser). You may also need to enable it manually in the application\'s system settings</string>
<string name="email">Email</string> <string name="email">Email</string>
<string name="captcha_required_message">This source requires solving a captcha to continue</string> <string name="captcha_required_message">This source requires solving a captcha to continue</string>
<string name="error_connection_reset">Connection reset by remote host</string>
</resources> </resources>

View File

@@ -7,7 +7,8 @@ avifDecoder = "1.1.1.14d8e3c4"
biometric = "1.2.0-alpha05" biometric = "1.2.0-alpha05"
coil = "3.0.4" coil = "3.0.4"
collections = "1.4.5" collections = "1.4.5"
conscrypt = "2.5.3" #noinspection GradleDependency - 2.5.3 cause crashes
conscrypt = "2.5.2"
constraintlayout = "2.2.0" constraintlayout = "2.2.0"
coreKtx = "1.15.0" coreKtx = "1.15.0"
coroutines = "1.9.0" coroutines = "1.9.0"
@@ -27,10 +28,10 @@ leakcanary = "3.0-alpha-8"
lifecycle = "2.8.7" lifecycle = "2.8.7"
markwon = "4.6.2" markwon = "4.6.2"
material = "1.12.0" material = "1.12.0"
moshi = "1.15.1" moshi = "1.15.2"
okhttp = "4.12.0" okhttp = "4.12.0"
okio = "3.9.1" okio = "3.9.1"
parsers = "1.5" parsers = "f86d31f811"
preference = "1.2.1" preference = "1.2.1"
recyclerview = "1.3.2" recyclerview = "1.3.2"
room = "2.6.1" room = "2.6.1"