Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5053b7820 | ||
|
|
e4df81495d | ||
|
|
295c5bed9f | ||
|
|
5fd1cbadcd | ||
|
|
9dd86f57e6 | ||
|
|
bce6d71743 | ||
|
|
6367c06f49 | ||
|
|
3aa8e9d6d3 | ||
|
|
ac2b367312 | ||
|
|
5cd9b02159 | ||
|
|
0bd62c6925 | ||
|
|
d657216a69 | ||
|
|
39f91464dc | ||
|
|
05422b95a1 | ||
|
|
554e3c1b61 | ||
|
|
56ece80f2a | ||
|
|
3ebde0284d | ||
|
|
c993488fe7 | ||
|
|
e65a3b43f6 |
@@ -18,8 +18,8 @@ android {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
versionCode = 690
|
||||
versionName = '7.7-beta2'
|
||||
versionCode = 692
|
||||
versionName = '7.7'
|
||||
generatedDensities = []
|
||||
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
|
||||
ksp {
|
||||
|
||||
@@ -402,7 +402,7 @@
|
||||
android:value="@bool/com_samsung_android_icon_container_has_icon_container" />
|
||||
|
||||
<activity-alias
|
||||
android:name="org.koitharu.kotatsu.details.ui.DetailsBYLinkActivity"
|
||||
android:name="org.koitharu.kotatsu.details.ui.DetailsByLinkActivity"
|
||||
android:exported="true"
|
||||
android:targetActivity="org.koitharu.kotatsu.details.ui.DetailsActivity">
|
||||
|
||||
|
||||
@@ -78,6 +78,9 @@ open class BaseApp : Application(), Configuration.Provider {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (ACRA.isACRASenderServiceProcess()) {
|
||||
return
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(settings.theme)
|
||||
AppCompatDelegate.setApplicationLocales(settings.appLocales)
|
||||
// TLS 1.3 support for Android < 10
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package org.koitharu.kotatsu.core.exceptions
|
||||
|
||||
class CaughtException(cause: Throwable, override val message: String?) : RuntimeException(cause)
|
||||
class CaughtException(cause: Throwable) : RuntimeException("${cause.javaClass.simpleName}(${cause.message})", cause)
|
||||
|
||||
@@ -85,7 +85,7 @@ class DoHManager(
|
||||
).build()
|
||||
|
||||
DoHProvider.ZERO_MS -> DnsOverHttps.Builder().client(bootstrapClient)
|
||||
.url("https://2ca4h4crra.cloudflare-gateway.com/dns-query".toHttpUrl())
|
||||
.url("https://0ms.dev/dns-query".toHttpUrl())
|
||||
.resolvePublicAddresses(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -79,7 +79,9 @@ class ParserMangaRepository(
|
||||
}
|
||||
|
||||
override suspend fun getPageUrl(page: MangaPage): String = mirrorSwitchInterceptor.withMirrorSwitching {
|
||||
parser.getPageUrl(page)
|
||||
parser.getPageUrl(page).also { result ->
|
||||
check(result.isNotEmpty()) { "Page url is empty" }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getFilterOptions(): MangaListFilterOptions = filterOptionsLazy.get()
|
||||
|
||||
@@ -727,6 +727,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
const val KEY_LINK_MANUAL = "about_help"
|
||||
const val KEY_PROXY_TEST = "proxy_test"
|
||||
const val KEY_OPEN_BROWSER = "open_browser"
|
||||
const val KEY_HANDLE_LINKS = "handle_links"
|
||||
|
||||
// old keys are for migration only
|
||||
private const val KEY_IMAGES_PROXY_OLD = "images_proxy"
|
||||
|
||||
@@ -58,7 +58,7 @@ class ErrorDetailsDialog : AlertDialogFragment<DialogErrorDetailsBinding>() {
|
||||
if (exception.isReportable()) {
|
||||
builder.setPositiveButton(R.string.report) { _, _ ->
|
||||
dismiss()
|
||||
exception.report()
|
||||
exception.report(silent = true)
|
||||
}
|
||||
}
|
||||
return builder
|
||||
|
||||
@@ -9,6 +9,7 @@ import okhttp3.Response
|
||||
import okio.FileNotFoundException
|
||||
import okio.IOException
|
||||
import okio.ProtocolException
|
||||
import org.acra.ktx.sendSilentlyWithAcra
|
||||
import org.acra.ktx.sendWithAcra
|
||||
import org.jsoup.HttpStatusException
|
||||
import org.koitharu.kotatsu.R
|
||||
@@ -37,9 +38,9 @@ import org.koitharu.kotatsu.parsers.exception.NotFoundException
|
||||
import org.koitharu.kotatsu.parsers.exception.ParseException
|
||||
import org.koitharu.kotatsu.parsers.exception.TooManyRequestExceptions
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.ScrobblerAuthRequiredException
|
||||
import java.io.ObjectOutputStream
|
||||
import java.net.ConnectException
|
||||
import java.net.NoRouteToHostException
|
||||
import java.io.ObjectOutputStream
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.UnknownHostException
|
||||
import java.util.Locale
|
||||
@@ -57,7 +58,7 @@ private fun Throwable.getDisplayMessageOrNull(resources: Resources): String? = w
|
||||
)
|
||||
|
||||
is AuthRequiredException -> resources.getString(R.string.auth_required)
|
||||
is CloudFlareProtectedException -> resources.getString(R.string.captcha_required)
|
||||
is CloudFlareProtectedException -> resources.getString(R.string.captcha_required_message)
|
||||
is CloudFlareBlockedException -> resources.getString(R.string.blocked_by_server_message)
|
||||
is ActivityNotFoundException,
|
||||
is UnsupportedOperationException,
|
||||
@@ -193,9 +194,13 @@ fun Throwable.isNetworkError(): Boolean {
|
||||
return this is UnknownHostException || this is SocketTimeoutException
|
||||
}
|
||||
|
||||
fun Throwable.report() {
|
||||
val exception = CaughtException(this, "${javaClass.simpleName}($message)")
|
||||
exception.sendWithAcra()
|
||||
fun Throwable.report(silent: Boolean = false) {
|
||||
val exception = CaughtException(this)
|
||||
if (silent) {
|
||||
exception.sendSilentlyWithAcra()
|
||||
} else {
|
||||
exception.sendWithAcra()
|
||||
}
|
||||
}
|
||||
|
||||
fun Throwable.isWebViewUnavailable(): Boolean {
|
||||
|
||||
@@ -60,7 +60,7 @@ class ScrobblingSelectorSheet :
|
||||
lateinit var coil: ImageLoader
|
||||
|
||||
private var collapsibleActionViewCallback: CollapseActionViewCallback? = null
|
||||
|
||||
private var paginationScrollListener: PaginationScrollListener? = null
|
||||
private val viewModel by viewModels<ScrobblingSelectorViewModel>()
|
||||
|
||||
override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): SheetScrobblingSelectorBinding {
|
||||
@@ -77,7 +77,11 @@ class ScrobblingSelectorSheet :
|
||||
adapter = listAdapter
|
||||
addItemDecoration(decoration)
|
||||
addItemDecoration(TypedListSpacingDecoration(context, false))
|
||||
addOnScrollListener(PaginationScrollListener(4, this@ScrobblingSelectorSheet))
|
||||
addOnScrollListener(
|
||||
PaginationScrollListener(4, this@ScrobblingSelectorSheet).also {
|
||||
paginationScrollListener = it
|
||||
},
|
||||
)
|
||||
}
|
||||
binding.buttonDone.setOnClickListener(this)
|
||||
initOptionsMenu()
|
||||
@@ -112,6 +116,7 @@ class ScrobblingSelectorSheet :
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
collapsibleActionViewCallback = null
|
||||
paginationScrollListener = null
|
||||
}
|
||||
|
||||
override fun onCurrentListChanged(previousList: MutableList<ListModel>, currentList: MutableList<ListModel>) {
|
||||
@@ -124,6 +129,7 @@ class ScrobblingSelectorSheet :
|
||||
currentList.indexOfFirst { it is ScrobblerManga && it.id == selectedId }.coerceAtLeast(0)
|
||||
}
|
||||
rv.post(RecyclerViewScrollCallback(rv, target, if (target == 0) 0 else rv.height / 3))
|
||||
paginationScrollListener?.postInvalidate(rv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.plus
|
||||
import org.koitharu.kotatsu.R
|
||||
@@ -59,7 +58,7 @@ class ScrobblingSelectorViewModel @Inject constructor(
|
||||
get() = availableScrobblers[selectedScrobblerIndex.requireValue()]
|
||||
|
||||
val content: StateFlow<List<ListModel>> = combine(
|
||||
scrobblerMangaList.map { it.distinctBy { x -> x.id } },
|
||||
scrobblerMangaList,
|
||||
listError,
|
||||
hasNextPage,
|
||||
) { list, error, isHasNextPage ->
|
||||
@@ -127,14 +126,17 @@ class ScrobblingSelectorViewModel @Inject constructor(
|
||||
runCatchingCancellable {
|
||||
currentScrobbler.findManga(checkNotNull(searchQuery.value), offset)
|
||||
}.onSuccess { list ->
|
||||
if (!append) {
|
||||
scrobblerMangaList.value = list
|
||||
} else if (list.isNotEmpty()) {
|
||||
scrobblerMangaList.value += list
|
||||
}
|
||||
hasNextPage.value = list.isNotEmpty()
|
||||
val newList = (if (append) {
|
||||
scrobblerMangaList.value + list
|
||||
} else {
|
||||
list
|
||||
}).distinctBy { x -> x.id }
|
||||
val changed = newList != scrobblerMangaList.value
|
||||
scrobblerMangaList.value = newList
|
||||
hasNextPage.value = changed && newList.isNotEmpty()
|
||||
}.onFailure { error ->
|
||||
error.printStackTraceDebug()
|
||||
hasNextPage.value = false
|
||||
listError.value = error
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
package org.koitharu.kotatsu.scrobbling.kitsu.data
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.Response
|
||||
import okhttp3.internal.closeQuietly
|
||||
import okio.IOException
|
||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
||||
import org.koitharu.kotatsu.parsers.util.mimeType
|
||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.ScrobblerAuthRequiredException
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
|
||||
@@ -23,13 +29,23 @@ class KitsuInterceptor(private val storage: ScrobblerStorage) : Interceptor {
|
||||
}
|
||||
val response = chain.proceed(request.build())
|
||||
if (!isAuthRequest && response.code == HttpURLConnection.HTTP_UNAUTHORIZED) {
|
||||
response.closeQuietly()
|
||||
throw ScrobblerAuthRequiredException(ScrobblerService.KITSU)
|
||||
}
|
||||
if (response.mimeType?.toMediaTypeOrNull()?.subtype == SUBTYPE_HTML) {
|
||||
val message = runCatchingCancellable {
|
||||
response.parseHtml().title().takeUnless { it.isEmpty() }
|
||||
}.onFailure {
|
||||
response.closeQuietly()
|
||||
}.getOrNull() ?: "Invalid response (${response.code})"
|
||||
throw IOException(message)
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val VND_JSON = "application/vnd.api+json"
|
||||
const val SUBTYPE_HTML = "html"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.view.View
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.TwoStatePreference
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
@@ -50,6 +51,11 @@ class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources)
|
||||
}
|
||||
}
|
||||
}
|
||||
findPreference<TwoStatePreference>(AppSettings.KEY_HANDLE_LINKS)?.let { pref ->
|
||||
viewModel.isLinksEnabled.observe(viewLifecycleOwner) {
|
||||
pref.isChecked = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceTreeClick(preference: Preference): Boolean = when (preference.key) {
|
||||
@@ -58,6 +64,11 @@ class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources)
|
||||
true
|
||||
}
|
||||
|
||||
AppSettings.KEY_HANDLE_LINKS -> {
|
||||
viewModel.setLinksEnabled((preference as TwoStatePreference).isChecked)
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
package org.koitharu.kotatsu.settings.sources
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|
||||
import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
||||
import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.plus
|
||||
@@ -13,8 +21,11 @@ import javax.inject.Inject
|
||||
@HiltViewModel
|
||||
class SourcesSettingsViewModel @Inject constructor(
|
||||
sourcesRepository: MangaSourcesRepository,
|
||||
@ApplicationContext private val context: Context,
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val linksHandlerActivity = ComponentName(context, "org.koitharu.kotatsu.details.ui.DetailsByLinkActivity")
|
||||
|
||||
val enabledSourcesCount = sourcesRepository.observeEnabledSourcesCount()
|
||||
.withErrorHandling()
|
||||
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, -1)
|
||||
@@ -22,4 +33,20 @@ class SourcesSettingsViewModel @Inject constructor(
|
||||
val availableSourcesCount = sourcesRepository.observeAvailableSourcesCount()
|
||||
.withErrorHandling()
|
||||
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, -1)
|
||||
|
||||
val isLinksEnabled = MutableStateFlow(isLinksEnabled())
|
||||
|
||||
fun setLinksEnabled(isEnabled: Boolean) {
|
||||
context.packageManager.setComponentEnabledSetting(
|
||||
linksHandlerActivity,
|
||||
if (isEnabled) COMPONENT_ENABLED_STATE_ENABLED else COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP,
|
||||
)
|
||||
isLinksEnabled.value = isLinksEnabled()
|
||||
}
|
||||
|
||||
private fun isLinksEnabled(): Boolean {
|
||||
val state = context.packageManager.getComponentEnabledSetting(linksHandlerActivity)
|
||||
return state == COMPONENT_ENABLED_STATE_ENABLED || state == COMPONENT_ENABLED_STATE_DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints="emailAddress"
|
||||
android:hint="@string/email"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textEmailAddress"
|
||||
android:maxLength="512"
|
||||
android:singleLine="true"
|
||||
android:textSize="16sp"
|
||||
tools:hint="Email" />
|
||||
android:textSize="16sp" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
@@ -83,12 +83,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints="password"
|
||||
android:hint="@string/password"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textPassword"
|
||||
android:maxLength="512"
|
||||
android:singleLine="true"
|
||||
android:textSize="16sp"
|
||||
tools:hint="Password" />
|
||||
android:textSize="16sp" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
@@ -749,4 +749,7 @@
|
||||
<string name="pages_saved">Páginas guardadas</string>
|
||||
<string name="delete_old_backups_summary">Elimina automáticamente los archivos de copia de seguridad antiguos para ahorrar espacio de almacenamiento</string>
|
||||
<string name="delete_old_backups">Eliminar copias de seguridad antiguas</string>
|
||||
<string name="email">Correo electrónico</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>
|
||||
</resources>
|
||||
@@ -746,4 +746,10 @@
|
||||
<string name="error_not_image">Imbalidong pormat: inaasahang larawan ngunit nakakuha ng %s</string>
|
||||
<string name="access_denied_403">Tinanggihan ang pag-access (403)</string>
|
||||
<string name="max_backups_count">Pinakamataas na bilang ng mga backup</string>
|
||||
<string name="pages_saved">Na-save na mga pahina</string>
|
||||
<string name="delete_old_backups">Tanggalin ang mga lumang backup</string>
|
||||
<string name="delete_old_backups_summary">Awtomatikong tanggalin ang mga lumang backup file upang makatipid ng storage space</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="email">Ang email</string>
|
||||
</resources>
|
||||
@@ -746,4 +746,7 @@
|
||||
<string name="pages_saved">Pages sauvegardées</string>
|
||||
<string name="delete_old_backups_summary">Suppression automatique des anciens fichiers de sauvegarde pour économiser de l\'espace de stockage</string>
|
||||
<string name="delete_old_backups">Supprimer les anciennes sauvegardes</string>
|
||||
<string name="handle_links">Gérer les liens</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>
|
||||
</resources>
|
||||
@@ -3,11 +3,11 @@
|
||||
<string name="read">Ler</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="favourites">Favoritas</string>
|
||||
<string name="favourites">Favoritos</string>
|
||||
<string name="history">Histórico</string>
|
||||
<string name="error_occurred">Ocorreu um erro</string>
|
||||
<string name="network_error">Erro de rede</string>
|
||||
<string name="details">Detalhado</string>
|
||||
<string name="details">Detalhes</string>
|
||||
<string name="chapters">Capítulos</string>
|
||||
<string name="list">Lista</string>
|
||||
<string name="detailed_list">Lista detalhada</string>
|
||||
@@ -32,7 +32,7 @@
|
||||
<string name="manga_downloading_">Baixando…</string>
|
||||
<string name="processing_">Processando…</string>
|
||||
<string name="download_complete">Baixado</string>
|
||||
<string name="downloads">Transferências</string>
|
||||
<string name="downloads">Baixados</string>
|
||||
<string name="computing_">Processando…</string>
|
||||
<string name="add_to_favourites">Favoritar obra</string>
|
||||
<string name="by_name">Nome</string>
|
||||
@@ -50,7 +50,7 @@
|
||||
<string name="remove">Remover</string>
|
||||
<string name="_s_deleted_from_local_storage">“%s” excluído do armazenamento local</string>
|
||||
<string name="save_page">Salvar página</string>
|
||||
<string name="page_saved">Salva</string>
|
||||
<string name="page_saved">Página salva</string>
|
||||
<string name="share_image">Compartilhar imagem</string>
|
||||
<string name="_import">Importar</string>
|
||||
<string name="delete">Deletar</string>
|
||||
@@ -73,7 +73,7 @@
|
||||
<string name="external_storage">Armazenamento externo</string>
|
||||
<string name="domain">Domínio</string>
|
||||
<string name="app_update_available">Uma nova versão do aplicativo está disponível</string>
|
||||
<string name="open_in_browser">Abrir no navegador da web</string>
|
||||
<string name="open_in_browser">Abrir no navegador</string>
|
||||
<string name="notifications">Notificações</string>
|
||||
<string name="new_chapters">Novos capítulos</string>
|
||||
<string name="download">Baixar</string>
|
||||
@@ -99,7 +99,7 @@
|
||||
<string name="favourites_category_empty">Categoria vazia</string>
|
||||
<string name="read_later">Ler depois</string>
|
||||
<string name="updates">Atualizações</string>
|
||||
<string name="search_results">Resultados encontrados</string>
|
||||
<string name="search_results">Resultados da busca</string>
|
||||
<string name="new_version_s">Nova versão: %s</string>
|
||||
<string name="size_s">Tamanho: %s</string>
|
||||
<string name="clear_updates_feed">Limpar o fluxo de atualizações</string>
|
||||
@@ -114,7 +114,7 @@
|
||||
<string name="repeat_password">Repita a senha</string>
|
||||
<string name="passwords_mismatch">Senhas incompatíveis</string>
|
||||
<string name="about">Sobre</string>
|
||||
<string name="backup_information">Você pode criar um backup do seu histórico e favoritas e restaurá-lo</string>
|
||||
<string name="backup_information">Você pode criar um backup do seu histórico e obras favoritas e restaurá-lo</string>
|
||||
<string name="just_now">Agora mesmo</string>
|
||||
<string name="yesterday">Ontem</string>
|
||||
<string name="long_ago">Há muito tempo</string>
|
||||
@@ -129,7 +129,7 @@
|
||||
<string name="cookies_cleared">Todos os cookies foram removidos</string>
|
||||
<string name="clear_feed">Limpar fluxo</string>
|
||||
<string name="text_clear_updates_feed_prompt">Limpar todo o histórico de atualizações permanentemente\?</string>
|
||||
<string name="check_for_new_chapters">Verificando se há novos capítulos</string>
|
||||
<string name="check_for_new_chapters">Verificar se há novos capítulos</string>
|
||||
<string name="reverse">Reverter</string>
|
||||
<string name="sign_in">Entrar</string>
|
||||
<string name="auth_required">Faça login para ver este conteúdo</string>
|
||||
@@ -180,7 +180,7 @@
|
||||
<string name="various_languages">Vários idiomas</string>
|
||||
<string name="operation_not_supported">Esta operação não é suportada</string>
|
||||
<string name="follow_system">Automático (segue o sistema)</string>
|
||||
<string name="enabled_d_of_d" tools:ignore="PluralsCandidate">%1$d de %2$d em</string>
|
||||
<string name="enabled_d_of_d" tools:ignore="PluralsCandidate">%1$d de %2$d habilitados</string>
|
||||
<string name="webtoon">Webtoon</string>
|
||||
<string name="switch_pages">Mudar páginas</string>
|
||||
<string name="clear_thumbs_cache">Limpar cache das miniaturas (capas, etc.)</string>
|
||||
@@ -192,8 +192,8 @@
|
||||
<string name="black_dark_theme_summary">Consome menos bateria em telas AMOLED</string>
|
||||
<string name="create_backup">Criar backup de dados</string>
|
||||
<string name="text_local_holder_secondary">Salve algo do catálogo online ou importe de um arquivo.</string>
|
||||
<string name="check_for_updates">Verificar se há atualização</string>
|
||||
<string name="text_feed_holder">Novos capítulos da(s) obra(s) que você tá lendo serão mostrados aqui</string>
|
||||
<string name="check_for_updates">Verificar se há atualizações</string>
|
||||
<string name="text_feed_holder">Novos capítulos da(s) obra(s) que você lê serão mostrados aqui</string>
|
||||
<string name="app_version">Versão %s</string>
|
||||
<string name="zoom_mode_fit_width">Ajustar à largura</string>
|
||||
<string name="preparing_">Preparando…</string>
|
||||
@@ -315,7 +315,7 @@
|
||||
<string name="import_completed_hint">Você pode excluir o arquivo original do armazenamento para economizar espaço</string>
|
||||
<string name="import_will_start_soon">A importação começará em breve</string>
|
||||
<string name="history_shortcuts">Mostrar atalhos de obras recentes</string>
|
||||
<string name="reader_control_ltr_summary">Tocar na borda direita ou pressionar a tecla direita sempre muda para a próxima página.</string>
|
||||
<string name="reader_control_ltr_summary">Não ajustar a direção da troca de páginas para o modo leitor, ex: pressionar a \"tecla\" direita sempre muda para a próxima página. Essa opção apenas afeta dispositivos de entrada hardware</string>
|
||||
<string name="reader_control_ltr">Controle de leitura ergonômico</string>
|
||||
<string name="color_correction">Correção de cor</string>
|
||||
<string name="brightness">Brilho</string>
|
||||
@@ -375,7 +375,7 @@
|
||||
<string name="more">Mais</string>
|
||||
<string name="enable">Permitir</string>
|
||||
<string name="no_thanks">Não, valeu</string>
|
||||
<string name="remove_completed_downloads_confirm">Seu histórico de baixados será excluído permanentemente</string>
|
||||
<string name="remove_completed_downloads_confirm">Seu histórico de baixados será excluído permanentemente. Nenhum arquivo baixado será afetado</string>
|
||||
<string name="text_downloads_list_holder">Você ainda não baixou nada</string>
|
||||
<string name="downloads_paused">\"Baixando foi pausado\"</string>
|
||||
<string name="downloads_removed">Os baixados foram removidos</string>
|
||||
@@ -696,11 +696,41 @@
|
||||
<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_replaced">Mangá “%1$s” (%2$s) substituído por “%3$s” (%4$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="text_empty_holder_secondary_filtered">Não foi possível encontrar Mangás com os filtros selecionado</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="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="sort_order_desc">Descendente</string>
|
||||
<string name="download_new_chapters">Baixar novos capítulos</string>
|
||||
<string name="retry">Retentativa</string>
|
||||
<string name="retry">Retentar</string>
|
||||
<string name="connection_ok">Conexão OK</string>
|
||||
<string name="too_many_requests_message_retry">Muitas solicitações. Tente novamente depois de %s</string>
|
||||
<string name="unstable_feature">Recurso instável</string>
|
||||
<string name="popular_in_hour">Popular no momento</string>
|
||||
<string name="updated_long_ago">Atualizado há muito tempo</string>
|
||||
<string name="downloads_background">Downloads em segundo plano</string>
|
||||
<string name="content_type_novel">Romance</string>
|
||||
<string name="content_type_manhua">Manhua</string>
|
||||
<string name="content_type_manhwa">Manhwa</string>
|
||||
<string name="seconds_short">%d s</string>
|
||||
<string name="minutes_seconds_short">%1$d m %2$d s</string>
|
||||
<string name="unpopular">Impopular</string>
|
||||
<string name="stuck">Preso</string>
|
||||
<string name="not_in_favorites">Não está nos favoritos</string>
|
||||
<string name="fixing_manga">Corrigindo o mangá</string>
|
||||
<string name="fixed">Corrigido</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="demographic_kodomo">Kodomo</string>
|
||||
<string name="content_type_one_shot">One shot</string>
|
||||
<string name="handle_links">Lidar com links</string>
|
||||
<string name="email">Email</string>
|
||||
<string name="demographics">Demografia</string>
|
||||
<string name="demographic_shounen">Shounen</string>
|
||||
<string name="demographic_shoujo">Shoujo</string>
|
||||
<string name="demographic_seinen">Seinen</string>
|
||||
<string name="demographic_josei">Josei</string>
|
||||
<string name="access_denied_403">Acesso negado (403)</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_summary">Automaticamente apagar backups antigos para liberar espaço</string>
|
||||
</resources>
|
||||
@@ -749,4 +749,7 @@
|
||||
<string name="access_denied_403">Приступ одбијен (403)</string>
|
||||
<string name="delete_old_backups">Избриши старе резервне копије</string>
|
||||
<string name="delete_old_backups_summary">Аутоматски избриши старе датотеке резервних копија да бис уштедео простор за складиштење</string>
|
||||
<string name="handle_links_summary">Руковање манга везама из спољних апликација (нпр. из прегледача). Можда ћеш морати да је омогућиш и ручно у системским поставкама апликације</string>
|
||||
<string name="handle_links">Руковање везама</string>
|
||||
<string name="email">Е-пошта</string>
|
||||
</resources>
|
||||
@@ -749,4 +749,7 @@
|
||||
<string name="pages_saved">Sayfalar kaydedildi</string>
|
||||
<string name="delete_old_backups">Eski yedekleri sil</string>
|
||||
<string name="delete_old_backups_summary">Depolama kullanımını azaltmak için eski yedek dosyalarını otomatik olarak sil</string>
|
||||
<string name="email">E-posta</string>
|
||||
<string name="handle_links">Bağlantıları aç</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>
|
||||
</resources>
|
||||
@@ -749,4 +749,7 @@
|
||||
<string name="pages_saved">Đã lưu trang</string>
|
||||
<string name="delete_old_backups">Xóa bản sao lưu cũ</string>
|
||||
<string name="delete_old_backups_summary">Tự động xóa các bản sao lưu cũ để tiết kiệm bộ nhớ của thiết bị</string>
|
||||
<string name="handle_links">Xử lí liên kết (Link)</string>
|
||||
<string name="handle_links_summary">Xử lý các liên kết (Link) manga từ các ứng dụng bên ngoài (Ví dụ: trình duyệt web,...). Có thể bạn cũng cần phải bật thủ công trong cài đặt hệ thống</string>
|
||||
<string name="email">E-mail</string>
|
||||
</resources>
|
||||
@@ -749,4 +749,7 @@
|
||||
<string name="pages_saved">图片已保存</string>
|
||||
<string name="delete_old_backups">删除旧备份文件</string>
|
||||
<string name="delete_old_backups_summary">自动删除旧备份文件以释放存储空间</string>
|
||||
<string name="handle_links">处理链接</string>
|
||||
<string name="handle_links_summary">处理来自外部程序的漫画链接(如 Web 浏览器), 可能需要在程序的系统设置中手动开启</string>
|
||||
<string name="email">电子邮箱</string>
|
||||
</resources>
|
||||
@@ -765,4 +765,8 @@
|
||||
<string name="max_backups_count">Max number of backups</string>
|
||||
<string name="delete_old_backups">Delete old backups</string>
|
||||
<string name="delete_old_backups_summary">Automatically delete old backup files to save storage space</string>
|
||||
<string name="handle_links">Handle links</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="captcha_required_message">This source requires solving a captcha to continue</string>
|
||||
</resources>
|
||||
|
||||
@@ -32,4 +32,11 @@
|
||||
android:summary="@string/disable_nsfw_summary"
|
||||
android:title="@string/disable_nsfw" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="handle_links"
|
||||
android:persistent="false"
|
||||
android:summary="@string/handle_links_summary"
|
||||
android:title="@string/handle_links"
|
||||
app:allowDividerAbove="true" />
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
||||
@@ -5,7 +5,7 @@ adapterdelegates = "4.3.2"
|
||||
appcompat = "1.7.0"
|
||||
avifDecoder = "1.1.1.14d8e3c4"
|
||||
biometric = "1.2.0-alpha05"
|
||||
coil = "3.0.3"
|
||||
coil = "3.0.4"
|
||||
collections = "1.4.5"
|
||||
conscrypt = "2.5.3"
|
||||
constraintlayout = "2.2.0"
|
||||
@@ -30,7 +30,7 @@ material = "1.12.0"
|
||||
moshi = "1.15.1"
|
||||
okhttp = "4.12.0"
|
||||
okio = "3.9.1"
|
||||
parsers = "8bc51b3b79"
|
||||
parsers = "1.5"
|
||||
preference = "1.2.1"
|
||||
recyclerview = "1.3.2"
|
||||
room = "2.6.1"
|
||||
|
||||
Reference in New Issue
Block a user