mirror of
https://github.com/mihonapp/mihon.git
synced 2025-06-26 19:17:51 +02:00
Compare commits
91 Commits
Author | SHA1 | Date | |
---|---|---|---|
26ddc6e3aa | |||
1dc4a52f61 | |||
473a4fec70 | |||
1919c2d925 | |||
71e31e6c03 | |||
c01df7f0a1 | |||
6024f6175b | |||
33500e5b69 | |||
17899a6d6d | |||
4c3eb68d3a | |||
29ced9642d | |||
af82591d85 | |||
5bc4a446ec | |||
83e93b254e | |||
49c7dd0cac | |||
96d2fb62e4 | |||
c76a136d3f | |||
940409a4c3 | |||
071dd88ef8 | |||
a58a4634e2 | |||
5979e72662 | |||
010436e797 | |||
980709cccb | |||
fe80356756 | |||
cecf532ffd | |||
6cb255e60a | |||
b46fb7d1e1 | |||
8874193927 | |||
a4515ad251 | |||
55b0b57699 | |||
aab7795b4c | |||
196a8e6829 | |||
972cd98d7b | |||
a16b5d241b | |||
bfa918140f | |||
0721de5b81 | |||
a409fde519 | |||
8e34a30dce | |||
ba43462041 | |||
c8ae936ce9 | |||
853f949140 | |||
615b01a006 | |||
0eb5a3176b | |||
867a5a3ea0 | |||
42eaaa497f | |||
96c894ce5b | |||
c0214103a9 | |||
2b76a97989 | |||
9d77052d9c | |||
b4981058a2 | |||
032aa64195 | |||
7c8e8317a8 | |||
eb1cfc4cd4 | |||
f1e5cccee7 | |||
bc2ed763bd | |||
a35995b898 | |||
b1f46ed830 | |||
6c1565a7d4 | |||
2ca6b655ad | |||
a83a481ac8 | |||
65a8b63b3b | |||
b20ca36db9 | |||
189f92d7e8 | |||
cdd4ec6233 | |||
ef1bb4e800 | |||
c475acd1ea | |||
7d50d7ff52 | |||
28522f4f90 | |||
ec3a227a02 | |||
89decf3474 | |||
0b2794e843 | |||
554dfb5874 | |||
9c30fa1da3 | |||
e81bd61e24 | |||
7a0b54bb38 | |||
f060daf8c4 | |||
c1976ef599 | |||
f16fb4e1e4 | |||
5da2c82f47 | |||
d443245d66 | |||
9be3eea5fd | |||
07a9fd061d | |||
2a070c0b1e | |||
7b5106d206 | |||
821d9cdb02 | |||
28575936d3 | |||
83a04da4a0 | |||
0894b1394f | |||
eb33d3c991 | |||
d7f01abf3a | |||
80635343ae |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@ -3,7 +3,7 @@
|
|||||||
I acknowledge that:
|
I acknowledge that:
|
||||||
|
|
||||||
- I have updated:
|
- I have updated:
|
||||||
- To the latest version of the app (stable is v0.13.2)
|
- To the latest version of the app (stable is v0.13.5)
|
||||||
- All extensions
|
- All extensions
|
||||||
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
|
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
|
||||||
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
|
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
|
||||||
|
4
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
4
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
@ -53,7 +53,7 @@ body:
|
|||||||
label: Tachiyomi version
|
label: Tachiyomi version
|
||||||
description: You can find your Tachiyomi version in **More → About**.
|
description: You can find your Tachiyomi version in **More → About**.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
Example: "0.13.2"
|
Example: "0.13.5"
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/).
|
- label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/).
|
||||||
required: true
|
required: true
|
||||||
- label: I have updated the app to version **[0.13.2](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
- label: I have updated the app to version **[0.13.5](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
||||||
required: true
|
required: true
|
||||||
- label: I have updated all installed extensions.
|
- label: I have updated all installed extensions.
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
2
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
@ -33,7 +33,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
|
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
|
||||||
required: true
|
required: true
|
||||||
- label: I have updated the app to version **[0.13.2](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
- label: I have updated the app to version **[0.13.5](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
||||||
required: true
|
required: true
|
||||||
- label: I will fill out all of the requested information in this form.
|
- label: I will fill out all of the requested information in this form.
|
||||||
required: true
|
required: true
|
||||||
|
11
.github/workflows/build_pull_request.yml
vendored
11
.github/workflows/build_pull_request.yml
vendored
@ -5,6 +5,9 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
- 'app/src/main/res/**/strings.xml'
|
- 'app/src/main/res/**/strings.xml'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build app
|
name: Build app
|
||||||
@ -12,15 +15,19 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repo
|
- name: Clone repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Validate Gradle Wrapper
|
- name: Validate Gradle Wrapper
|
||||||
uses: gradle/wrapper-validation-action@v1
|
uses: gradle/wrapper-validation-action@v1
|
||||||
|
|
||||||
|
- name: Dependency Review
|
||||||
|
uses: actions/dependency-review-action@v1
|
||||||
|
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
|
distribution: adopt
|
||||||
|
|
||||||
- name: Copy CI gradle.properties
|
- name: Copy CI gradle.properties
|
||||||
run: |
|
run: |
|
||||||
|
5
.github/workflows/build_push.yml
vendored
5
.github/workflows/build_push.yml
vendored
@ -19,15 +19,16 @@ jobs:
|
|||||||
all_but_latest: true
|
all_but_latest: true
|
||||||
|
|
||||||
- name: Clone repo
|
- name: Clone repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Validate Gradle Wrapper
|
- name: Validate Gradle Wrapper
|
||||||
uses: gradle/wrapper-validation-action@v1
|
uses: gradle/wrapper-validation-action@v1
|
||||||
|
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
|
distribution: adopt
|
||||||
|
|
||||||
- name: Copy CI gradle.properties
|
- name: Copy CI gradle.properties
|
||||||
run: |
|
run: |
|
||||||
|
@ -24,8 +24,8 @@ android {
|
|||||||
applicationId = "eu.kanade.tachiyomi"
|
applicationId = "eu.kanade.tachiyomi"
|
||||||
minSdk = AndroidConfig.minSdk
|
minSdk = AndroidConfig.minSdk
|
||||||
targetSdk = AndroidConfig.targetSdk
|
targetSdk = AndroidConfig.targetSdk
|
||||||
versionCode = 78
|
versionCode = 81
|
||||||
versionName = "0.13.2"
|
versionName = "0.13.5"
|
||||||
|
|
||||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||||
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
|
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
|
||||||
@ -155,7 +155,7 @@ dependencies {
|
|||||||
implementation(androidx.bundles.lifecycle)
|
implementation(androidx.bundles.lifecycle)
|
||||||
|
|
||||||
// Job scheduling
|
// Job scheduling
|
||||||
implementation(androidx.work.runtime)
|
implementation(androidx.bundles.workmanager)
|
||||||
|
|
||||||
// RX
|
// RX
|
||||||
implementation(libs.bundles.reactivex)
|
implementation(libs.bundles.reactivex)
|
||||||
@ -219,6 +219,7 @@ dependencies {
|
|||||||
exclude(group = "androidx.viewpager", module = "viewpager")
|
exclude(group = "androidx.viewpager", module = "viewpager")
|
||||||
}
|
}
|
||||||
implementation(libs.insetter)
|
implementation(libs.insetter)
|
||||||
|
implementation(libs.markwon)
|
||||||
|
|
||||||
// Conductor
|
// Conductor
|
||||||
implementation(libs.bundles.conductor)
|
implementation(libs.bundles.conductor)
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
android:name=".App"
|
android:name=".App"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:hasFragileUserData="true"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi
|
package eu.kanade.tachiyomi
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
@ -8,6 +9,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Looper
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
@ -34,6 +36,7 @@ import eu.kanade.tachiyomi.util.preference.asImmediateFlow
|
|||||||
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
|
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
|
||||||
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
||||||
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
||||||
|
import eu.kanade.tachiyomi.util.system.isDevFlavor
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.notification
|
import eu.kanade.tachiyomi.util.system.notification
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
@ -56,6 +59,7 @@ open class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
|
|||||||
|
|
||||||
private val disableIncognitoReceiver = DisableIncognitoReceiver()
|
private val disableIncognitoReceiver = DisableIncognitoReceiver()
|
||||||
|
|
||||||
|
@SuppressLint("LaunchActivityFromNotification")
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super<Application>.onCreate()
|
super<Application>.onCreate()
|
||||||
|
|
||||||
@ -150,27 +154,31 @@ open class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getPackageName(): String {
|
override fun getPackageName(): String {
|
||||||
try {
|
// This causes freezes in Android 6/7 for some reason
|
||||||
// Override the value passed as X-Requested-With in WebView requests
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val stackTrace = Thread.currentThread().stackTrace
|
try {
|
||||||
for (element in stackTrace) {
|
// Override the value passed as X-Requested-With in WebView requests
|
||||||
if ("org.chromium.base.BuildInfo".equals(element.className, ignoreCase = true)) {
|
val stackTrace = Looper.getMainLooper().thread.stackTrace
|
||||||
if ("getAll".equals(element.methodName, ignoreCase = true)) {
|
val chromiumElement = stackTrace.find {
|
||||||
return WebViewUtil.SPOOF_PACKAGE_NAME
|
it.className.equals(
|
||||||
}
|
"org.chromium.base.BuildInfo",
|
||||||
break
|
ignoreCase = true,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
if (chromiumElement?.methodName.equals("getAll", ignoreCase = true)) {
|
||||||
|
return WebViewUtil.SPOOF_PACKAGE_NAME
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
}
|
||||||
return super.getPackageName()
|
return super.getPackageName()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun setupAcra() {
|
protected open fun setupAcra() {
|
||||||
if (BuildConfig.FLAVOR != "dev") {
|
if (isDevFlavor.not()) {
|
||||||
initAcra {
|
initAcra {
|
||||||
buildConfigClass = BuildConfig::class.java
|
buildConfigClass = BuildConfig::class.java
|
||||||
excludeMatchingSharedPreferencesKeys = arrayOf(".*username.*", ".*password.*", ".*token.*")
|
excludeMatchingSharedPreferencesKeys = listOf(".*username.*", ".*password.*", ".*token.*")
|
||||||
|
|
||||||
httpSender {
|
httpSender {
|
||||||
uri = BuildConfig.ACRA_URI
|
uri = BuildConfig.ACRA_URI
|
||||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.backup.full
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
|
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY
|
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY_MASK
|
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY_MASK
|
||||||
@ -54,7 +55,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
|
|||||||
|
|
||||||
backup = Backup(
|
backup = Backup(
|
||||||
backupManga(databaseManga, flags),
|
backupManga(databaseManga, flags),
|
||||||
backupCategories(),
|
backupCategories(flags),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
backupExtensionInfo(databaseManga),
|
backupExtensionInfo(databaseManga),
|
||||||
)
|
)
|
||||||
@ -90,6 +91,10 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val byteArray = parser.encodeToByteArray(BackupSerializer, backup!!)
|
val byteArray = parser.encodeToByteArray(BackupSerializer, backup!!)
|
||||||
|
if (byteArray.isEmpty()) {
|
||||||
|
throw IllegalStateException(context.getString(R.string.empty_backup_error))
|
||||||
|
}
|
||||||
|
|
||||||
file.openOutputStream().also {
|
file.openOutputStream().also {
|
||||||
// Force overwrite old file
|
// Force overwrite old file
|
||||||
(it as? FileOutputStream)?.channel?.truncate(0)
|
(it as? FileOutputStream)?.channel?.truncate(0)
|
||||||
@ -128,10 +133,15 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
|
|||||||
*
|
*
|
||||||
* @return list of [BackupCategory] to be backed up
|
* @return list of [BackupCategory] to be backed up
|
||||||
*/
|
*/
|
||||||
private fun backupCategories(): List<BackupCategory> {
|
private fun backupCategories(options: Int): List<BackupCategory> {
|
||||||
return databaseHelper.getCategories()
|
// Check if user wants category information in backup
|
||||||
.executeAsBlocking()
|
return if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) {
|
||||||
.map { BackupCategory.copyFrom(it) }
|
databaseHelper.getCategories()
|
||||||
|
.executeAsBlocking()
|
||||||
|
.map { BackupCategory.copyFrom(it) }
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.data.download
|
package eu.kanade.tachiyomi.data.download
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
@ -184,8 +185,10 @@ internal class DownloadNotifier(private val context: Context) {
|
|||||||
* Called when the downloader receives a warning.
|
* Called when the downloader receives a warning.
|
||||||
*
|
*
|
||||||
* @param reason the text to show.
|
* @param reason the text to show.
|
||||||
|
* @param timeout duration after which to automatically dismiss the notification.
|
||||||
|
* Only works on Android 8+.
|
||||||
*/
|
*/
|
||||||
fun onWarning(reason: String) {
|
fun onWarning(reason: String, timeout: Long? = null, contentIntent: PendingIntent? = null) {
|
||||||
with(errorNotificationBuilder) {
|
with(errorNotificationBuilder) {
|
||||||
setContentTitle(context.getString(R.string.download_notifier_downloader_title))
|
setContentTitle(context.getString(R.string.download_notifier_downloader_title))
|
||||||
setStyle(NotificationCompat.BigTextStyle().bigText(reason))
|
setStyle(NotificationCompat.BigTextStyle().bigText(reason))
|
||||||
@ -194,6 +197,8 @@ internal class DownloadNotifier(private val context: Context) {
|
|||||||
clearActions()
|
clearActions()
|
||||||
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
|
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
|
||||||
setProgress(0, 0, false)
|
setProgress(0, 0, false)
|
||||||
|
timeout?.let { setTimeoutAfter(it) }
|
||||||
|
contentIntent?.let { setContentIntent(it) }
|
||||||
|
|
||||||
show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR)
|
show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
package eu.kanade.tachiyomi.data.download
|
package eu.kanade.tachiyomi.data.download
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.webkit.MimeTypeMap
|
|
||||||
import android.widget.Toast
|
|
||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
import com.jakewharton.rxrelay.PublishRelay
|
import com.jakewharton.rxrelay.PublishRelay
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
||||||
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
|
||||||
|
import eu.kanade.tachiyomi.data.notification.NotificationHandler
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.UnmeteredSource
|
import eu.kanade.tachiyomi.source.UnmeteredSource
|
||||||
@ -28,7 +27,6 @@ import eu.kanade.tachiyomi.util.storage.DiskUtil
|
|||||||
import eu.kanade.tachiyomi.util.storage.saveTo
|
import eu.kanade.tachiyomi.util.storage.saveTo
|
||||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
@ -275,14 +273,22 @@ class Downloader(
|
|||||||
|
|
||||||
// Start downloader if needed
|
// Start downloader if needed
|
||||||
if (autoStart && wasEmpty) {
|
if (autoStart && wasEmpty) {
|
||||||
|
val queuedDownloads = queue.filter { it.source !is UnmeteredSource }.count()
|
||||||
val maxDownloadsFromSource = queue
|
val maxDownloadsFromSource = queue
|
||||||
.groupBy { it.source }
|
.groupBy { it.source }
|
||||||
.filterKeys { it !is UnmeteredSource }
|
.filterKeys { it !is UnmeteredSource }
|
||||||
.maxOf { it.value.size }
|
.maxOfOrNull { it.value.size }
|
||||||
// TODO: show warnings in stable
|
?: 0
|
||||||
if (maxDownloadsFromSource > CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD && BuildConfig.FLAVOR != "stable") {
|
if (
|
||||||
|
queuedDownloads > DOWNLOADS_QUEUED_WARNING_THRESHOLD ||
|
||||||
|
maxDownloadsFromSource > CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD
|
||||||
|
) {
|
||||||
withUIContext {
|
withUIContext {
|
||||||
context.toast(R.string.download_queue_size_warning, Toast.LENGTH_LONG)
|
notifier.onWarning(
|
||||||
|
context.getString(R.string.download_queue_size_warning),
|
||||||
|
WARNING_NOTIF_TIMEOUT_MS,
|
||||||
|
NotificationHandler.openUrl(context, LibraryUpdateNotifier.HELP_WARNING_URL),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DownloadService.start(context)
|
DownloadService.start(context)
|
||||||
@ -465,7 +471,7 @@ class Downloader(
|
|||||||
// Else read magic numbers.
|
// Else read magic numbers.
|
||||||
?: ImageUtil.findImageType { file.openInputStream() }?.mime
|
?: ImageUtil.findImageType { file.openInputStream() }?.mime
|
||||||
|
|
||||||
return MimeTypeMap.getSingleton().getExtensionFromMimeType(mime) ?: "jpg"
|
return ImageUtil.getExtensionFromMimeType(mime)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -561,7 +567,9 @@ class Downloader(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TMP_DIR_SUFFIX = "_tmp"
|
const val TMP_DIR_SUFFIX = "_tmp"
|
||||||
|
const val WARNING_NOTIF_TIMEOUT_MS = 30_000L
|
||||||
const val CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 15
|
const val CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 15
|
||||||
|
private const val DOWNLOADS_QUEUED_WARNING_THRESHOLD = 30
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,7 @@ import androidx.work.PeriodicWorkRequestBuilder
|
|||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING
|
import eu.kanade.tachiyomi.data.preference.*
|
||||||
import eu.kanade.tachiyomi.data.preference.DEVICE_ONLY_ON_WIFI
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
|
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -21,8 +19,9 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
|
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
val preferences = Injekt.get<PreferencesHelper>()
|
val preferences = Injekt.get<PreferencesHelper>()
|
||||||
if (requiresWifiConnection(preferences) && !context.isConnectedToWifi()) {
|
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
|
||||||
Result.failure()
|
if ((DEVICE_ONLY_ON_WIFI in restrictions) && !context.isConnectedToWifi()) {
|
||||||
|
return Result.failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (LibraryUpdateService.start(context)) {
|
return if (LibraryUpdateService.start(context)) {
|
||||||
@ -41,8 +40,9 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
|
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
.setRequiredNetworkType(if (DEVICE_NETWORK_NOT_METERED in restrictions) { NetworkType.UNMETERED } else { NetworkType.CONNECTED })
|
||||||
.setRequiresCharging(DEVICE_CHARGING in restrictions)
|
.setRequiresCharging(DEVICE_CHARGING in restrictions)
|
||||||
|
.setRequiresBatteryNotLow(DEVICE_BATTERY_NOT_LOW in restrictions)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val request = PeriodicWorkRequestBuilder<LibraryUpdateJob>(
|
val request = PeriodicWorkRequestBuilder<LibraryUpdateJob>(
|
||||||
@ -60,10 +60,5 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
WorkManager.getInstance(context).cancelAllWorkByTag(TAG)
|
WorkManager.getInstance(context).cancelAllWorkByTag(TAG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requiresWifiConnection(preferences: PreferencesHelper): Boolean {
|
|
||||||
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
|
|
||||||
return DEVICE_ONLY_ON_WIFI in restrictions
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,21 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showQueueSizeWarningNotification() {
|
||||||
|
val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_LIBRARY_PROGRESS) {
|
||||||
|
setContentTitle(context.getString(R.string.label_warning))
|
||||||
|
setStyle(NotificationCompat.BigTextStyle().bigText(context.getString(R.string.notification_size_warning)))
|
||||||
|
setSmallIcon(R.drawable.ic_warning_white_24dp)
|
||||||
|
setTimeoutAfter(Downloader.WARNING_NOTIF_TIMEOUT_MS)
|
||||||
|
setContentIntent(NotificationHandler.openUrl(context, HELP_WARNING_URL))
|
||||||
|
}
|
||||||
|
|
||||||
|
context.notificationManager.notify(
|
||||||
|
Notifications.ID_LIBRARY_SIZE_WARNING,
|
||||||
|
notificationBuilder.build(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows notification containing update entries that failed with action to open full log.
|
* Shows notification containing update entries that failed with action to open full log.
|
||||||
*
|
*
|
||||||
@ -128,8 +143,9 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||||||
Notifications.ID_LIBRARY_SKIPPED,
|
Notifications.ID_LIBRARY_SKIPPED,
|
||||||
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_SKIPPED) {
|
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_SKIPPED) {
|
||||||
setContentTitle(context.resources.getString(R.string.notification_update_skipped, skipped))
|
setContentTitle(context.resources.getString(R.string.notification_update_skipped, skipped))
|
||||||
|
setContentText(context.getString(R.string.learn_more))
|
||||||
setSmallIcon(R.drawable.ic_tachi)
|
setSmallIcon(R.drawable.ic_tachi)
|
||||||
addAction(R.drawable.ic_help_24dp, context.getString(R.string.learn_more), NotificationHandler.openUrl(context, HELP_SKIPPED_URL))
|
setContentIntent(NotificationHandler.openUrl(context, HELP_SKIPPED_URL))
|
||||||
}
|
}
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
@ -325,6 +341,10 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||||||
}
|
}
|
||||||
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val HELP_WARNING_URL = "https://tachiyomi.org/help/faq/#why-does-the-app-warn-about-large-bulk-updates-and-downloads"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val NOTIF_MAX_CHAPTERS = 5
|
private const val NOTIF_MAX_CHAPTERS = 5
|
||||||
|
@ -5,9 +5,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
@ -43,7 +41,6 @@ import eu.kanade.tachiyomi.util.system.acquireWakeLock
|
|||||||
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
||||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -177,6 +174,8 @@ class LibraryUpdateService(
|
|||||||
*/
|
*/
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
updateJob?.cancel()
|
updateJob?.cancel()
|
||||||
|
// Despite what Android Studio
|
||||||
|
// states this can be null
|
||||||
ioScope?.cancel()
|
ioScope?.cancel()
|
||||||
if (wakeLock.isHeld) {
|
if (wakeLock.isHeld) {
|
||||||
wakeLock.release()
|
wakeLock.release()
|
||||||
@ -236,8 +235,7 @@ class LibraryUpdateService(
|
|||||||
/**
|
/**
|
||||||
* Adds list of manga to be updated.
|
* Adds list of manga to be updated.
|
||||||
*
|
*
|
||||||
* @param category the ID of the category to update, or -1 if no category specified.
|
* @param categoryId the ID of the category to update, or -1 if no category specified.
|
||||||
* @param target the target to update.
|
|
||||||
*/
|
*/
|
||||||
fun addMangaToQueue(categoryId: Int) {
|
fun addMangaToQueue(categoryId: Int) {
|
||||||
val libraryManga = db.getLibraryMangas().executeAsBlocking()
|
val libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||||
@ -271,19 +269,17 @@ class LibraryUpdateService(
|
|||||||
.groupBy { it.source }
|
.groupBy { it.source }
|
||||||
.filterKeys { sourceManager.get(it) !is UnmeteredSource }
|
.filterKeys { sourceManager.get(it) !is UnmeteredSource }
|
||||||
.maxOfOrNull { it.value.size } ?: 0
|
.maxOfOrNull { it.value.size } ?: 0
|
||||||
// TODO: show warnings in stable
|
if (maxUpdatesFromSource > MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD) {
|
||||||
if (maxUpdatesFromSource > MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD && BuildConfig.FLAVOR != "stable") {
|
notifier.showQueueSizeWarningNotification()
|
||||||
toast(R.string.notification_size_warning, Toast.LENGTH_LONG)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that updates the given list of manga. It's called in a background thread, so it's safe
|
* Method that updates manga in [mangaToUpdate]. It's called in a background thread, so it's safe
|
||||||
* to do heavy operations or network calls here.
|
* to do heavy operations or network calls here.
|
||||||
* For each manga it calls [updateManga] and updates the notification showing the current
|
* For each manga it calls [updateManga] and updates the notification showing the current
|
||||||
* progress.
|
* progress.
|
||||||
*
|
*
|
||||||
* @param mangaToUpdate the list to update
|
|
||||||
* @return an observable delivering the progress of each update.
|
* @return an observable delivering the progress of each update.
|
||||||
*/
|
*/
|
||||||
suspend fun updateChapterList() {
|
suspend fun updateChapterList() {
|
||||||
@ -309,35 +305,38 @@ class LibraryUpdateService(
|
|||||||
return@async
|
return@async
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't continue to update if manga not in library
|
||||||
|
db.getManga(manga.id!!).executeAsBlocking() ?: return@forEach
|
||||||
|
|
||||||
withUpdateNotification(
|
withUpdateNotification(
|
||||||
currentlyUpdatingManga,
|
currentlyUpdatingManga,
|
||||||
progressCount,
|
progressCount,
|
||||||
manga,
|
manga,
|
||||||
) { manga ->
|
) { mangaWithNotif ->
|
||||||
try {
|
try {
|
||||||
when {
|
when {
|
||||||
MANGA_NON_COMPLETED in restrictions && manga.status == SManga.COMPLETED -> {
|
MANGA_NON_COMPLETED in restrictions && mangaWithNotif.status == SManga.COMPLETED ->
|
||||||
skippedUpdates.add(manga to getString(R.string.skipped_reason_completed))
|
skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_completed))
|
||||||
}
|
|
||||||
MANGA_HAS_UNREAD in restrictions && manga.unreadCount != 0 -> {
|
MANGA_HAS_UNREAD in restrictions && mangaWithNotif.unreadCount != 0 ->
|
||||||
skippedUpdates.add(manga to getString(R.string.skipped_reason_not_caught_up))
|
skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_not_caught_up))
|
||||||
}
|
|
||||||
MANGA_NON_READ in restrictions && manga.totalChapters > 0 && !manga.hasStarted -> {
|
MANGA_NON_READ in restrictions && mangaWithNotif.totalChapters > 0 && !mangaWithNotif.hasStarted ->
|
||||||
skippedUpdates.add(manga to getString(R.string.skipped_reason_not_started))
|
skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_not_started))
|
||||||
}
|
|
||||||
else -> {
|
else -> {
|
||||||
// Convert to the manga that contains new chapters
|
// Convert to the manga that contains new chapters
|
||||||
val (newChapters, _) = updateManga(manga)
|
val (newChapters, _) = updateManga(mangaWithNotif)
|
||||||
|
|
||||||
if (newChapters.isNotEmpty()) {
|
if (newChapters.isNotEmpty()) {
|
||||||
if (manga.shouldDownloadNewChapters(db, preferences)) {
|
if (mangaWithNotif.shouldDownloadNewChapters(db, preferences)) {
|
||||||
downloadChapters(manga, newChapters)
|
downloadChapters(mangaWithNotif, newChapters)
|
||||||
hasDownloads.set(true)
|
hasDownloads.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to the manga that contains new chapters
|
// Convert to the manga that contains new chapters
|
||||||
newUpdates.add(
|
newUpdates.add(
|
||||||
manga to newChapters.sortedByDescending { ch -> ch.source_order }
|
mangaWithNotif to newChapters.sortedByDescending { ch -> ch.source_order }
|
||||||
.toTypedArray(),
|
.toTypedArray(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -356,11 +355,11 @@ class LibraryUpdateService(
|
|||||||
e.message
|
e.message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failedUpdates.add(manga to errorMessage)
|
failedUpdates.add(mangaWithNotif to errorMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preferences.autoUpdateTrackers()) {
|
if (preferences.autoUpdateTrackers()) {
|
||||||
updateTrackings(manga, loggedServices)
|
updateTrackings(mangaWithNotif, loggedServices)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -408,6 +407,7 @@ class LibraryUpdateService(
|
|||||||
suspend fun updateManga(manga: Manga): Pair<List<Chapter>, List<Chapter>> {
|
suspend fun updateManga(manga: Manga): Pair<List<Chapter>, List<Chapter>> {
|
||||||
val source = sourceManager.getOrStub(manga.source)
|
val source = sourceManager.getOrStub(manga.source)
|
||||||
|
|
||||||
|
var networkSManga: SManga? = null
|
||||||
// Update manga details metadata
|
// Update manga details metadata
|
||||||
if (preferences.autoUpdateMetadata()) {
|
if (preferences.autoUpdateMetadata()) {
|
||||||
val updatedManga = source.getMangaDetails(manga.toMangaInfo())
|
val updatedManga = source.getMangaDetails(manga.toMangaInfo())
|
||||||
@ -419,14 +419,26 @@ class LibraryUpdateService(
|
|||||||
sManga.thumbnail_url = manga.thumbnail_url
|
sManga.thumbnail_url = manga.thumbnail_url
|
||||||
}
|
}
|
||||||
|
|
||||||
manga.copyFrom(sManga)
|
networkSManga = sManga
|
||||||
db.insertManga(manga).executeAsBlocking()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val chapters = source.getChapterList(manga.toMangaInfo())
|
val chapters = source.getChapterList(manga.toMangaInfo())
|
||||||
.map { it.toSChapter() }
|
.map { it.toSChapter() }
|
||||||
|
|
||||||
return syncChaptersWithSource(db, chapters, manga, source)
|
// Get manga from database to account for if it was removed
|
||||||
|
// from library or database
|
||||||
|
val dbManga = db.getManga(manga.id!!).executeAsBlocking()
|
||||||
|
?: return Pair(emptyList(), emptyList())
|
||||||
|
|
||||||
|
// Copy into [dbManga] to retain favourite value
|
||||||
|
networkSManga?.let {
|
||||||
|
dbManga.copyFrom(it)
|
||||||
|
db.insertManga(dbManga).executeAsBlocking()
|
||||||
|
}
|
||||||
|
|
||||||
|
// [dbmanga] was used so that manga data doesn't get overwritten
|
||||||
|
// incase manga gets new chapter
|
||||||
|
return syncChaptersWithSource(db, chapters, dbManga, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun updateCovers() {
|
private suspend fun updateCovers() {
|
||||||
@ -449,16 +461,16 @@ class LibraryUpdateService(
|
|||||||
currentlyUpdatingManga,
|
currentlyUpdatingManga,
|
||||||
progressCount,
|
progressCount,
|
||||||
manga,
|
manga,
|
||||||
) { manga ->
|
) { mangaWithNotif ->
|
||||||
sourceManager.get(manga.source)?.let { source ->
|
sourceManager.get(mangaWithNotif.source)?.let { source ->
|
||||||
try {
|
try {
|
||||||
val networkManga =
|
val networkManga =
|
||||||
source.getMangaDetails(manga.toMangaInfo())
|
source.getMangaDetails(mangaWithNotif.toMangaInfo())
|
||||||
val sManga = networkManga.toSManga()
|
val sManga = networkManga.toSManga()
|
||||||
manga.prepUpdateCover(coverCache, sManga, true)
|
mangaWithNotif.prepUpdateCover(coverCache, sManga, true)
|
||||||
sManga.thumbnail_url?.let {
|
sManga.thumbnail_url?.let {
|
||||||
manga.thumbnail_url = it
|
mangaWithNotif.thumbnail_url = it
|
||||||
db.insertManga(manga).executeAsBlocking()
|
db.insertManga(mangaWithNotif).executeAsBlocking()
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
// Ignore errors and continue
|
// Ignore errors and continue
|
||||||
|
@ -26,10 +26,11 @@ object Notifications {
|
|||||||
private const val GROUP_LIBRARY = "group_library"
|
private const val GROUP_LIBRARY = "group_library"
|
||||||
const val CHANNEL_LIBRARY_PROGRESS = "library_progress_channel"
|
const val CHANNEL_LIBRARY_PROGRESS = "library_progress_channel"
|
||||||
const val ID_LIBRARY_PROGRESS = -101
|
const val ID_LIBRARY_PROGRESS = -101
|
||||||
|
const val ID_LIBRARY_SIZE_WARNING = -103
|
||||||
const val CHANNEL_LIBRARY_ERROR = "library_errors_channel"
|
const val CHANNEL_LIBRARY_ERROR = "library_errors_channel"
|
||||||
const val ID_LIBRARY_ERROR = -102
|
const val ID_LIBRARY_ERROR = -102
|
||||||
const val CHANNEL_LIBRARY_SKIPPED = "library_skipped_channel"
|
const val CHANNEL_LIBRARY_SKIPPED = "library_skipped_channel"
|
||||||
const val ID_LIBRARY_SKIPPED = -103
|
const val ID_LIBRARY_SKIPPED = -104
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification channel and ids used by the downloader.
|
* Notification channel and ids used by the downloader.
|
||||||
|
@ -3,7 +3,9 @@ package eu.kanade.tachiyomi.data.preference
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
|
||||||
const val DEVICE_ONLY_ON_WIFI = "wifi"
|
const val DEVICE_ONLY_ON_WIFI = "wifi"
|
||||||
|
const val DEVICE_NETWORK_NOT_METERED = "network_not_metered"
|
||||||
const val DEVICE_CHARGING = "ac"
|
const val DEVICE_CHARGING = "ac"
|
||||||
|
const val DEVICE_BATTERY_NOT_LOW = "battery_not_low"
|
||||||
|
|
||||||
const val MANGA_NON_COMPLETED = "manga_ongoing"
|
const val MANGA_NON_COMPLETED = "manga_ongoing"
|
||||||
const val MANGA_HAS_UNREAD = "manga_fully_read"
|
const val MANGA_HAS_UNREAD = "manga_fully_read"
|
||||||
@ -28,13 +30,14 @@ object PreferenceValues {
|
|||||||
enum class AppTheme(val titleResId: Int?) {
|
enum class AppTheme(val titleResId: Int?) {
|
||||||
DEFAULT(R.string.label_default),
|
DEFAULT(R.string.label_default),
|
||||||
MONET(R.string.theme_monet),
|
MONET(R.string.theme_monet),
|
||||||
|
GREEN_APPLE(R.string.theme_greenapple),
|
||||||
|
LAVENDER(R.string.theme_lavender),
|
||||||
MIDNIGHT_DUSK(R.string.theme_midnightdusk),
|
MIDNIGHT_DUSK(R.string.theme_midnightdusk),
|
||||||
STRAWBERRY_DAIQUIRI(R.string.theme_strawberrydaiquiri),
|
STRAWBERRY_DAIQUIRI(R.string.theme_strawberrydaiquiri),
|
||||||
YOTSUBA(R.string.theme_yotsuba),
|
|
||||||
TAKO(R.string.theme_tako),
|
TAKO(R.string.theme_tako),
|
||||||
GREEN_APPLE(R.string.theme_greenapple),
|
|
||||||
TEALTURQUOISE(R.string.theme_tealturquoise),
|
TEALTURQUOISE(R.string.theme_tealturquoise),
|
||||||
YINYANG(R.string.theme_yinyang),
|
YINYANG(R.string.theme_yinyang),
|
||||||
|
YOTSUBA(R.string.theme_yotsuba),
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
DARK_BLUE(null),
|
DARK_BLUE(null),
|
||||||
|
@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
|
|||||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
|
import eu.kanade.tachiyomi.util.system.isDevFlavor
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
@ -203,11 +204,11 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun downloadOnlyOverWifi() = prefs.getBoolean(Keys.downloadOnlyOverWifi, true)
|
fun downloadOnlyOverWifi() = prefs.getBoolean(Keys.downloadOnlyOverWifi, true)
|
||||||
|
|
||||||
fun saveChaptersAsCBZ() = flowPrefs.getBoolean("save_chapter_as_cbz", false)
|
fun saveChaptersAsCBZ() = flowPrefs.getBoolean("save_chapter_as_cbz", true)
|
||||||
|
|
||||||
fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false)
|
fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false)
|
||||||
|
|
||||||
fun numberOfBackups() = flowPrefs.getInt("backup_slots", 1)
|
fun numberOfBackups() = flowPrefs.getInt("backup_slots", 2)
|
||||||
|
|
||||||
fun backupInterval() = flowPrefs.getInt("backup_interval", 0)
|
fun backupInterval() = flowPrefs.getInt("backup_interval", 0)
|
||||||
|
|
||||||
@ -277,10 +278,10 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun pinnedSources() = flowPrefs.getStringSet("pinned_catalogues", emptySet())
|
fun pinnedSources() = flowPrefs.getStringSet("pinned_catalogues", emptySet())
|
||||||
|
|
||||||
fun downloadNew() = flowPrefs.getBoolean("download_new", false)
|
fun downloadNewChapter() = flowPrefs.getBoolean("download_new", false)
|
||||||
|
|
||||||
fun downloadNewCategories() = flowPrefs.getStringSet("download_new_categories", emptySet())
|
fun downloadNewChapterCategories() = flowPrefs.getStringSet("download_new_categories", emptySet())
|
||||||
fun downloadNewCategoriesExclude() = flowPrefs.getStringSet("download_new_categories_exclude", emptySet())
|
fun downloadNewChapterCategoriesExclude() = flowPrefs.getStringSet("download_new_categories_exclude", emptySet())
|
||||||
|
|
||||||
fun defaultCategory() = prefs.getInt(Keys.defaultCategory, -1)
|
fun defaultCategory() = prefs.getInt(Keys.defaultCategory, -1)
|
||||||
|
|
||||||
@ -319,7 +320,7 @@ class PreferencesHelper(val context: Context) {
|
|||||||
if (DeviceUtil.isMiui) Values.ExtensionInstaller.LEGACY else Values.ExtensionInstaller.PACKAGEINSTALLER,
|
if (DeviceUtil.isMiui) Values.ExtensionInstaller.LEGACY else Values.ExtensionInstaller.PACKAGEINSTALLER,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun verboseLogging() = prefs.getBoolean(Keys.verboseLogging, false)
|
fun verboseLogging() = prefs.getBoolean(Keys.verboseLogging, isDevFlavor)
|
||||||
|
|
||||||
fun autoClearChapterCache() = prefs.getBoolean(Keys.autoClearChapterCache, false)
|
fun autoClearChapterCache() = prefs.getBoolean(Keys.autoClearChapterCache, false)
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ import eu.kanade.tachiyomi.util.storage.DiskUtil
|
|||||||
import eu.kanade.tachiyomi.util.storage.cacheImageDir
|
import eu.kanade.tachiyomi.util.storage.cacheImageDir
|
||||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||||
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
|
import logcat.LogPriority
|
||||||
import okio.IOException
|
import okio.IOException
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
@ -30,11 +32,7 @@ class ImageSaver(
|
|||||||
val type = ImageUtil.findImageType(data) ?: throw Exception("Not an image")
|
val type = ImageUtil.findImageType(data) ?: throw Exception("Not an image")
|
||||||
val filename = DiskUtil.buildValidFilename("${image.name}.${type.extension}")
|
val filename = DiskUtil.buildValidFilename("${image.name}.${type.extension}")
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || image.location !is Location.Pictures) {
|
||||||
return save(data(), image.location.directory(context), filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image.location !is Location.Pictures) {
|
|
||||||
return save(data(), image.location.directory(context), filename)
|
return save(data(), image.location.directory(context), filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,13 +52,18 @@ class ImageSaver(
|
|||||||
val picture = context.contentResolver.insert(
|
val picture = context.contentResolver.insert(
|
||||||
pictureDir,
|
pictureDir,
|
||||||
contentValues,
|
contentValues,
|
||||||
) ?: throw IOException("Couldn't create file")
|
) ?: throw IOException(context.getString(R.string.error_saving_picture))
|
||||||
|
|
||||||
data().use { input ->
|
try {
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
data().use { input ->
|
||||||
context.contentResolver.openOutputStream(picture, "w").use { output ->
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
input.copyTo(output!!)
|
context.contentResolver.openOutputStream(picture, "w").use { output ->
|
||||||
|
input.copyTo(output!!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logcat(LogPriority.ERROR, e)
|
||||||
|
throw IOException(context.getString(R.string.error_saving_picture))
|
||||||
}
|
}
|
||||||
|
|
||||||
DiskUtil.scanMedia(context, picture)
|
DiskUtil.scanMedia(context, picture)
|
||||||
|
@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.network.NetworkHelper
|
|||||||
import eu.kanade.tachiyomi.network.await
|
import eu.kanade.tachiyomi.network.await
|
||||||
import eu.kanade.tachiyomi.network.parseAs
|
import eu.kanade.tachiyomi.network.parseAs
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||||
|
import eu.kanade.tachiyomi.util.system.getInstallerPackageName
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -33,14 +34,19 @@ class AppUpdateChecker {
|
|||||||
|
|
||||||
// Check if latest version is different from current version
|
// Check if latest version is different from current version
|
||||||
if (isNewVersion(it.version)) {
|
if (isNewVersion(it.version)) {
|
||||||
AppUpdateResult.NewUpdate(it)
|
if (context.getInstallerPackageName() == "org.fdroid.fdroid") {
|
||||||
|
AppUpdateResult.NewUpdateFdroidInstallation
|
||||||
|
} else {
|
||||||
|
AppUpdateResult.NewUpdate(it)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
AppUpdateResult.NoNewUpdate
|
AppUpdateResult.NoNewUpdate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result is AppUpdateResult.NewUpdate) {
|
when (result) {
|
||||||
AppUpdateNotifier(context).promptUpdate(result.release)
|
is AppUpdateResult.NewUpdate -> AppUpdateNotifier(context).promptUpdate(result.release)
|
||||||
|
is AppUpdateResult.NewUpdateFdroidInstallation -> AppUpdateNotifier(context).promptFdroidUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
@ -50,6 +56,7 @@ class AppUpdateChecker {
|
|||||||
private fun isNewVersion(versionTag: String): Boolean {
|
private fun isNewVersion(versionTag: String): Boolean {
|
||||||
// Removes prefixes like "r" or "v"
|
// Removes prefixes like "r" or "v"
|
||||||
val newVersion = versionTag.replace("[^\\d.]".toRegex(), "")
|
val newVersion = versionTag.replace("[^\\d.]".toRegex(), "")
|
||||||
|
val oldVersion = BuildConfig.VERSION_NAME.replace("[^\\d.]".toRegex(), "")
|
||||||
|
|
||||||
return if (BuildConfig.PREVIEW) {
|
return if (BuildConfig.PREVIEW) {
|
||||||
// Preview builds: based on releases in "tachiyomiorg/tachiyomi-preview" repo
|
// Preview builds: based on releases in "tachiyomiorg/tachiyomi-preview" repo
|
||||||
@ -58,7 +65,15 @@ class AppUpdateChecker {
|
|||||||
} else {
|
} else {
|
||||||
// Release builds: based on releases in "tachiyomiorg/tachiyomi" repo
|
// Release builds: based on releases in "tachiyomiorg/tachiyomi" repo
|
||||||
// tagged as something like "v0.1.2"
|
// tagged as something like "v0.1.2"
|
||||||
newVersion != BuildConfig.VERSION_NAME
|
val newSemVer = newVersion.split(".").map { it.toInt() }
|
||||||
|
val oldSemVer = oldVersion.split(".").map { it.toInt() }
|
||||||
|
|
||||||
|
oldSemVer.mapIndexed { index, i ->
|
||||||
|
if (newSemVer[index] > i) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,22 @@ internal class AppUpdateNotifier(private val context: Context) {
|
|||||||
notificationBuilder.show()
|
notificationBuilder.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some people are still installing the app from F-Droid, so we avoid prompting GitHub-based
|
||||||
|
* updates.
|
||||||
|
*
|
||||||
|
* We can prompt them to migrate to the GitHub version though.
|
||||||
|
*/
|
||||||
|
fun promptFdroidUpdate() {
|
||||||
|
with(notificationBuilder) {
|
||||||
|
setContentTitle(context.getString(R.string.update_check_notification_update_available))
|
||||||
|
setContentText(context.getString(R.string.update_check_fdroid_migration_info))
|
||||||
|
setSmallIcon(R.drawable.ic_tachi)
|
||||||
|
setContentIntent(NotificationHandler.openUrl(context, "https://tachiyomi.org/help/faq/#how-do-i-migrate-from-the-f-droid-version"))
|
||||||
|
}
|
||||||
|
notificationBuilder.show()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call when apk download starts.
|
* Call when apk download starts.
|
||||||
*
|
*
|
||||||
|
@ -2,5 +2,6 @@ package eu.kanade.tachiyomi.data.updater
|
|||||||
|
|
||||||
sealed class AppUpdateResult {
|
sealed class AppUpdateResult {
|
||||||
class NewUpdate(val release: GithubRelease) : AppUpdateResult()
|
class NewUpdate(val release: GithubRelease) : AppUpdateResult()
|
||||||
|
object NewUpdateFdroidInstallation : AppUpdateResult()
|
||||||
object NoNewUpdate : AppUpdateResult()
|
object NoNewUpdate : AppUpdateResult()
|
||||||
}
|
}
|
||||||
|
@ -244,11 +244,6 @@ class ExtensionManager(
|
|||||||
installer.updateInstallStep(downloadId, InstallStep.Installing)
|
installer.updateInstallStep(downloadId, InstallStep.Installing)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setInstallationResult(downloadId: Long, result: Boolean) {
|
|
||||||
val step = if (result) InstallStep.Installed else InstallStep.Error
|
|
||||||
installer.updateInstallStep(downloadId, step)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateInstallStep(downloadId: Long, step: InstallStep) {
|
fun updateInstallStep(downloadId: Long, step: InstallStep) {
|
||||||
installer.updateInstallStep(downloadId, step)
|
installer.updateInstallStep(downloadId, step)
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,9 @@ import eu.kanade.tachiyomi.network.NetworkHelper
|
|||||||
import eu.kanade.tachiyomi.network.await
|
import eu.kanade.tachiyomi.network.await
|
||||||
import eu.kanade.tachiyomi.network.parseAs
|
import eu.kanade.tachiyomi.network.parseAs
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||||
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import logcat.LogPriority
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -21,11 +23,27 @@ internal class ExtensionGithubApi {
|
|||||||
private val networkService: NetworkHelper by injectLazy()
|
private val networkService: NetworkHelper by injectLazy()
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
private val preferences: PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
|
private var requiresFallbackSource = false
|
||||||
|
|
||||||
suspend fun findExtensions(): List<Extension.Available> {
|
suspend fun findExtensions(): List<Extension.Available> {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val extensions = networkService.client
|
val githubResponse = if (requiresFallbackSource) null else try {
|
||||||
.newCall(GET("${REPO_URL_PREFIX}index.min.json"))
|
networkService.client
|
||||||
.await()
|
.newCall(GET("${REPO_URL_PREFIX}index.min.json"))
|
||||||
|
.await()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" }
|
||||||
|
requiresFallbackSource = true
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val response = githubResponse ?: run {
|
||||||
|
networkService.client
|
||||||
|
.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json"))
|
||||||
|
.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
val extensions = response
|
||||||
.parseAs<List<ExtensionJsonObject>>()
|
.parseAs<List<ExtensionJsonObject>>()
|
||||||
.toExtensions()
|
.toExtensions()
|
||||||
|
|
||||||
@ -85,7 +103,7 @@ internal class ExtensionGithubApi {
|
|||||||
hasChangelog = it.hasChangelog == 1,
|
hasChangelog = it.hasChangelog == 1,
|
||||||
sources = it.sources?.toExtensionSources() ?: emptyList(),
|
sources = it.sources?.toExtensionSources() ?: emptyList(),
|
||||||
apkName = it.apk,
|
apkName = it.apk,
|
||||||
iconUrl = "${REPO_URL_PREFIX}icon/${it.apk.replace(".apk", ".png")}",
|
iconUrl = "${getUrlPrefix()}icon/${it.apk.replace(".apk", ".png")}",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,11 +119,20 @@ internal class ExtensionGithubApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getApkUrl(extension: Extension.Available): String {
|
fun getApkUrl(extension: Extension.Available): String {
|
||||||
return "${REPO_URL_PREFIX}apk/${extension.apkName}"
|
return "${getUrlPrefix()}apk/${extension.apkName}"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUrlPrefix(): String {
|
||||||
|
return if (requiresFallbackSource) {
|
||||||
|
FALLBACK_REPO_URL_PREFIX
|
||||||
|
} else {
|
||||||
|
REPO_URL_PREFIX
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val REPO_URL_PREFIX = "https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/"
|
private const val REPO_URL_PREFIX = "https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/"
|
||||||
|
private const val FALLBACK_REPO_URL_PREFIX = "https://gcore.jsdelivr.net/gh/tachiyomiorg/tachiyomi-extensions@repo/"
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
private data class ExtensionJsonObject(
|
private data class ExtensionJsonObject(
|
||||||
|
@ -52,9 +52,9 @@ class ShizukuInstaller(private val service: Service) : Installer(service) {
|
|||||||
val size = service.getUriSize(entry.uri) ?: throw IllegalStateException()
|
val size = service.getUriSize(entry.uri) ?: throw IllegalStateException()
|
||||||
service.contentResolver.openInputStream(entry.uri)!!.use {
|
service.contentResolver.openInputStream(entry.uri)!!.use {
|
||||||
val createCommand = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
val createCommand = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
"pm install-create --user current -i ${service.packageName} -S $size"
|
"pm install-create --user current -r -i ${service.packageName} -S $size"
|
||||||
} else {
|
} else {
|
||||||
"pm install-create -i ${service.packageName} -S $size"
|
"pm install-create -r -i ${service.packageName} -S $size"
|
||||||
}
|
}
|
||||||
val createResult = exec(createCommand)
|
val createResult = exec(createCommand)
|
||||||
sessionId = SESSION_ID_REGEX.find(createResult.out)?.value
|
sessionId = SESSION_ID_REGEX.find(createResult.out)?.value
|
||||||
|
@ -29,9 +29,9 @@ class AndroidCookieJar : CookieJar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(url: HttpUrl, cookieNames: List<String>? = null, maxAge: Int = -1) {
|
fun remove(url: HttpUrl, cookieNames: List<String>? = null, maxAge: Int = -1): Int {
|
||||||
val urlString = url.toString()
|
val urlString = url.toString()
|
||||||
val cookies = manager.getCookie(urlString) ?: return
|
val cookies = manager.getCookie(urlString) ?: return 0
|
||||||
|
|
||||||
fun List<String>.filterNames(): List<String> {
|
fun List<String>.filterNames(): List<String> {
|
||||||
return if (cookieNames != null) {
|
return if (cookieNames != null) {
|
||||||
@ -41,10 +41,11 @@ class AndroidCookieJar : CookieJar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cookies.split(";")
|
return cookies.split(";")
|
||||||
.map { it.substringBefore("=") }
|
.map { it.substringBefore("=") }
|
||||||
.filterNames()
|
.filterNames()
|
||||||
.onEach { manager.setCookie(urlString, "$it=;Max-Age=$maxAge") }
|
.onEach { manager.setCookie(urlString, "$it=;Max-Age=$maxAge") }
|
||||||
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeAll() {
|
fun removeAll() {
|
||||||
|
@ -13,6 +13,10 @@ const val PREF_DOH_CLOUDFLARE = 1
|
|||||||
const val PREF_DOH_GOOGLE = 2
|
const val PREF_DOH_GOOGLE = 2
|
||||||
const val PREF_DOH_ADGUARD = 3
|
const val PREF_DOH_ADGUARD = 3
|
||||||
const val PREF_DOH_QUAD9 = 4
|
const val PREF_DOH_QUAD9 = 4
|
||||||
|
const val PREF_DOH_ALIDNS = 5
|
||||||
|
const val PREF_DOH_DNSPOD = 6
|
||||||
|
const val PREF_DOH_360 = 7
|
||||||
|
const val PREF_DOH_QUAD101 = 8
|
||||||
|
|
||||||
fun OkHttpClient.Builder.dohCloudflare() = dns(
|
fun OkHttpClient.Builder.dohCloudflare() = dns(
|
||||||
DnsOverHttps.Builder().client(build())
|
DnsOverHttps.Builder().client(build())
|
||||||
@ -68,3 +72,51 @@ fun OkHttpClient.Builder.dohQuad9() = dns(
|
|||||||
)
|
)
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun OkHttpClient.Builder.dohAliDNS() = dns(
|
||||||
|
DnsOverHttps.Builder().client(build())
|
||||||
|
.url("https://dns.alidns.com/dns-query".toHttpUrl())
|
||||||
|
.bootstrapDnsHosts(
|
||||||
|
InetAddress.getByName("223.5.5.5"),
|
||||||
|
InetAddress.getByName("223.6.6.6"),
|
||||||
|
InetAddress.getByName("2400:3200::1"),
|
||||||
|
InetAddress.getByName("2400:3200:baba::1"),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun OkHttpClient.Builder.dohDNSPod() = dns(
|
||||||
|
DnsOverHttps.Builder().client(build())
|
||||||
|
.url("https://doh.pub/dns-query".toHttpUrl())
|
||||||
|
.bootstrapDnsHosts(
|
||||||
|
InetAddress.getByName("1.12.12.12"),
|
||||||
|
InetAddress.getByName("120.53.53.53"),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun OkHttpClient.Builder.doh360() = dns(
|
||||||
|
DnsOverHttps.Builder().client(build())
|
||||||
|
.url("https://doh.360.cn/dns-query".toHttpUrl())
|
||||||
|
.bootstrapDnsHosts(
|
||||||
|
InetAddress.getByName("101.226.4.6"),
|
||||||
|
InetAddress.getByName("218.30.118.6"),
|
||||||
|
InetAddress.getByName("123.125.81.6"),
|
||||||
|
InetAddress.getByName("140.207.198.6"),
|
||||||
|
InetAddress.getByName("180.163.249.75"),
|
||||||
|
InetAddress.getByName("101.199.113.208"),
|
||||||
|
InetAddress.getByName("36.99.170.86"),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun OkHttpClient.Builder.dohQuad101() = dns(
|
||||||
|
DnsOverHttps.Builder().client(build())
|
||||||
|
.url("https://dns.twnic.tw/dns-query".toHttpUrl())
|
||||||
|
.bootstrapDnsHosts(
|
||||||
|
InetAddress.getByName("101.101.101.101"),
|
||||||
|
InetAddress.getByName("2001:de4::101"),
|
||||||
|
InetAddress.getByName("2001:de4::102"),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
@ -27,7 +27,8 @@ class NetworkHelper(context: Context) {
|
|||||||
.cookieJar(cookieManager)
|
.cookieJar(cookieManager)
|
||||||
.connectTimeout(30, TimeUnit.SECONDS)
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
.readTimeout(30, TimeUnit.SECONDS)
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
.fastFallback(true)
|
.callTimeout(2, TimeUnit.MINUTES)
|
||||||
|
// .fastFallback(true) // TODO: re-enable when OkHttp 5 is stabler
|
||||||
.addInterceptor(UserAgentInterceptor())
|
.addInterceptor(UserAgentInterceptor())
|
||||||
|
|
||||||
if (preferences.verboseLogging()) {
|
if (preferences.verboseLogging()) {
|
||||||
@ -42,6 +43,10 @@ class NetworkHelper(context: Context) {
|
|||||||
PREF_DOH_GOOGLE -> builder.dohGoogle()
|
PREF_DOH_GOOGLE -> builder.dohGoogle()
|
||||||
PREF_DOH_ADGUARD -> builder.dohAdGuard()
|
PREF_DOH_ADGUARD -> builder.dohAdGuard()
|
||||||
PREF_DOH_QUAD9 -> builder.dohQuad9()
|
PREF_DOH_QUAD9 -> builder.dohQuad9()
|
||||||
|
PREF_DOH_ALIDNS -> builder.dohAliDNS()
|
||||||
|
PREF_DOH_DNSPOD -> builder.dohDNSPod()
|
||||||
|
PREF_DOH_360 -> builder.doh360()
|
||||||
|
PREF_DOH_QUAD101 -> builder.dohQuad101()
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder
|
return builder
|
||||||
|
@ -4,6 +4,7 @@ import android.os.SystemClock
|
|||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import java.io.IOException
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,6 +37,11 @@ private class RateLimitInterceptor(
|
|||||||
private val rateLimitMillis = unit.toMillis(period)
|
private val rateLimitMillis = unit.toMillis(period)
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
// Ignore canceled calls, otherwise they would jam the queue
|
||||||
|
if (chain.call().isCanceled()) {
|
||||||
|
throw IOException()
|
||||||
|
}
|
||||||
|
|
||||||
synchronized(requestQueue) {
|
synchronized(requestQueue) {
|
||||||
val now = SystemClock.elapsedRealtime()
|
val now = SystemClock.elapsedRealtime()
|
||||||
val waitTime = if (requestQueue.size < permits) {
|
val waitTime = if (requestQueue.size < permits) {
|
||||||
@ -51,6 +57,11 @@ private class RateLimitInterceptor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final check
|
||||||
|
if (chain.call().isCanceled()) {
|
||||||
|
throw IOException()
|
||||||
|
}
|
||||||
|
|
||||||
if (requestQueue.size == permits) {
|
if (requestQueue.size == permits) {
|
||||||
requestQueue.removeAt(0)
|
requestQueue.removeAt(0)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import okhttp3.HttpUrl
|
|||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import java.io.IOException
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,9 +42,13 @@ class SpecificHostRateLimitInterceptor(
|
|||||||
private val host = httpUrl.host
|
private val host = httpUrl.host
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
if (chain.request().url.host != host) {
|
// Ignore canceled calls, otherwise they would jam the queue
|
||||||
|
if (chain.call().isCanceled()) {
|
||||||
|
throw IOException()
|
||||||
|
} else if (chain.request().url.host != host) {
|
||||||
return chain.proceed(chain.request())
|
return chain.proceed(chain.request())
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized(requestQueue) {
|
synchronized(requestQueue) {
|
||||||
val now = SystemClock.elapsedRealtime()
|
val now = SystemClock.elapsedRealtime()
|
||||||
val waitTime = if (requestQueue.size < permits) {
|
val waitTime = if (requestQueue.size < permits) {
|
||||||
@ -59,6 +64,11 @@ class SpecificHostRateLimitInterceptor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final check
|
||||||
|
if (chain.call().isCanceled()) {
|
||||||
|
throw IOException()
|
||||||
|
}
|
||||||
|
|
||||||
if (requestQueue.size == permits) {
|
if (requestQueue.size == permits) {
|
||||||
requestQueue.removeAt(0)
|
requestQueue.removeAt(0)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package eu.kanade.tachiyomi.source
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.junrar.Archive
|
import com.github.junrar.Archive
|
||||||
|
import com.hippo.unifile.UniFile
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
@ -17,7 +19,6 @@ import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
|
|||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
import eu.kanade.tachiyomi.util.storage.EpubFile
|
import eu.kanade.tachiyomi.util.storage.EpubFile
|
||||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@ -26,10 +27,11 @@ import kotlinx.serialization.json.decodeFromStream
|
|||||||
import kotlinx.serialization.json.intOrNull
|
import kotlinx.serialization.json.intOrNull
|
||||||
import kotlinx.serialization.json.jsonArray
|
import kotlinx.serialization.json.jsonArray
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import logcat.LogPriority
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import tachiyomi.source.model.ChapterInfo
|
import tachiyomi.source.model.ChapterInfo
|
||||||
import tachiyomi.source.model.MangaInfo
|
import tachiyomi.source.model.MangaInfo
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
@ -37,130 +39,104 @@ import java.io.InputStream
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
|
|
||||||
class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSource {
|
class LocalSource(
|
||||||
|
private val context: Context,
|
||||||
companion object {
|
private val coverCache: CoverCache = Injekt.get(),
|
||||||
const val ID = 0L
|
) : CatalogueSource, UnmeteredSource {
|
||||||
const val HELP_URL = "https://tachiyomi.org/help/guides/local-manga/"
|
|
||||||
|
|
||||||
private const val COVER_NAME = "cover.jpg"
|
|
||||||
private val LATEST_THRESHOLD = TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS)
|
|
||||||
|
|
||||||
fun updateCover(context: Context, manga: SManga, input: InputStream): File? {
|
|
||||||
val dir = getBaseDirectories(context).firstOrNull()
|
|
||||||
if (dir == null) {
|
|
||||||
input.close()
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
var cover = getCoverFile(File("${dir.absolutePath}/${manga.url}"))
|
|
||||||
if (cover == null) {
|
|
||||||
cover = File("${dir.absolutePath}/${manga.url}", COVER_NAME)
|
|
||||||
}
|
|
||||||
// It might not exist if using the external SD card
|
|
||||||
cover.parentFile?.mkdirs()
|
|
||||||
input.use {
|
|
||||||
cover.outputStream().use {
|
|
||||||
input.copyTo(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
manga.thumbnail_url = cover.absolutePath
|
|
||||||
return cover
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns valid cover file inside [parent] directory.
|
|
||||||
*/
|
|
||||||
private fun getCoverFile(parent: File): File? {
|
|
||||||
return parent.listFiles()?.find { it.nameWithoutExtension == "cover" }?.takeIf {
|
|
||||||
it.isFile && ImageUtil.isImage(it.name) { it.inputStream() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getBaseDirectories(context: Context): List<File> {
|
|
||||||
val c = context.getString(R.string.app_name) + File.separator + "local"
|
|
||||||
return DiskUtil.getExternalStorages(context).map { File(it.absolutePath, c) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override val id = ID
|
override val name: String = context.getString(R.string.local_source)
|
||||||
override val name = context.getString(R.string.local_source)
|
|
||||||
override val lang = "other"
|
override val id: Long = ID
|
||||||
override val supportsLatest = true
|
|
||||||
|
override val lang: String = "other"
|
||||||
|
|
||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
|
|
||||||
|
override val supportsLatest: Boolean = true
|
||||||
|
|
||||||
|
// Browse related
|
||||||
override fun fetchPopularManga(page: Int) = fetchSearchManga(page, "", POPULAR_FILTERS)
|
override fun fetchPopularManga(page: Int) = fetchSearchManga(page, "", POPULAR_FILTERS)
|
||||||
|
|
||||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
override fun fetchLatestUpdates(page: Int) = fetchSearchManga(page, "", LATEST_FILTERS)
|
||||||
val baseDirs = getBaseDirectories(context)
|
|
||||||
|
|
||||||
val time = if (filters === LATEST_FILTERS) System.currentTimeMillis() - LATEST_THRESHOLD else 0L
|
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
||||||
var mangaDirs = baseDirs
|
val baseDirsFiles = getBaseDirectoriesFiles(context)
|
||||||
.asSequence()
|
|
||||||
.mapNotNull { it.listFiles()?.toList() }
|
var mangaDirs = baseDirsFiles
|
||||||
.flatten()
|
// Filter out files that are hidden and is not a folder
|
||||||
.filter { it.isDirectory }
|
.filter { it.isDirectory && !it.name.startsWith('.') }
|
||||||
.filterNot { it.name.startsWith('.') }
|
|
||||||
.filter { if (time == 0L) it.name.contains(query, ignoreCase = true) else it.lastModified() >= time }
|
|
||||||
.distinctBy { it.name }
|
.distinctBy { it.name }
|
||||||
|
|
||||||
val state = ((if (filters.isEmpty()) POPULAR_FILTERS else filters)[0] as OrderBy).state
|
val lastModifiedLimit = if (filters === LATEST_FILTERS) System.currentTimeMillis() - LATEST_THRESHOLD else 0L
|
||||||
when (state?.index) {
|
// Filter by query or last modified
|
||||||
0 -> {
|
mangaDirs = mangaDirs.filter {
|
||||||
mangaDirs = if (state.ascending) {
|
if (lastModifiedLimit == 0L) {
|
||||||
mangaDirs.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, { it.name }))
|
it.name.contains(query, ignoreCase = true)
|
||||||
} else {
|
} else {
|
||||||
mangaDirs.sortedWith(compareByDescending(String.CASE_INSENSITIVE_ORDER, { it.name }))
|
it.lastModified() >= lastModifiedLimit
|
||||||
}
|
|
||||||
}
|
|
||||||
1 -> {
|
|
||||||
mangaDirs = if (state.ascending) {
|
|
||||||
mangaDirs.sortedBy(File::lastModified)
|
|
||||||
} else {
|
|
||||||
mangaDirs.sortedByDescending(File::lastModified)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filters.forEach { filter ->
|
||||||
|
when (filter) {
|
||||||
|
is OrderBy -> {
|
||||||
|
when (filter.state!!.index) {
|
||||||
|
0 -> {
|
||||||
|
mangaDirs = if (filter.state!!.ascending) {
|
||||||
|
mangaDirs.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.name })
|
||||||
|
} else {
|
||||||
|
mangaDirs.sortedWith(compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
mangaDirs = if (filter.state!!.ascending) {
|
||||||
|
mangaDirs.sortedBy(File::lastModified)
|
||||||
|
} else {
|
||||||
|
mangaDirs.sortedByDescending(File::lastModified)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> { /* Do nothing */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform mangaDirs to list of SManga
|
||||||
val mangas = mangaDirs.map { mangaDir ->
|
val mangas = mangaDirs.map { mangaDir ->
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
title = mangaDir.name
|
title = mangaDir.name
|
||||||
url = mangaDir.name
|
url = mangaDir.name
|
||||||
|
|
||||||
// Try to find the cover
|
// Try to find the cover
|
||||||
for (dir in baseDirs) {
|
val cover = getCoverFile(mangaDir.name, baseDirsFiles)
|
||||||
val cover = getCoverFile(File("${dir.absolutePath}/$url"))
|
if (cover != null && cover.exists()) {
|
||||||
if (cover != null && cover.exists()) {
|
thumbnail_url = cover.absolutePath
|
||||||
thumbnail_url = cover.absolutePath
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val sManga = this
|
// Fetch chapters of all the manga
|
||||||
val mangaInfo = this.toMangaInfo()
|
mangas.forEach { manga ->
|
||||||
runBlocking {
|
val mangaInfo = manga.toMangaInfo()
|
||||||
val chapters = getChapterList(mangaInfo)
|
runBlocking {
|
||||||
if (chapters.isNotEmpty()) {
|
val chapters = getChapterList(mangaInfo)
|
||||||
val chapter = chapters.last().toSChapter()
|
if (chapters.isNotEmpty()) {
|
||||||
val format = getFormat(chapter)
|
val chapter = chapters.last().toSChapter()
|
||||||
if (format is Format.Epub) {
|
val format = getFormat(chapter)
|
||||||
EpubFile(format.file).use { epub ->
|
|
||||||
epub.fillMangaMetadata(sManga)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the cover from the first chapter found.
|
if (format is Format.Epub) {
|
||||||
if (thumbnail_url == null) {
|
EpubFile(format.file).use { epub ->
|
||||||
try {
|
epub.fillMangaMetadata(manga)
|
||||||
val dest = updateCover(chapter, sManga)
|
|
||||||
thumbnail_url = dest?.absolutePath
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logcat(LogPriority.ERROR, e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the cover from the first chapter found if not available
|
||||||
|
if (manga.thumbnail_url == null) {
|
||||||
|
updateCover(chapter, manga)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,38 +144,44 @@ class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSour
|
|||||||
return Observable.just(MangasPage(mangas.toList(), false))
|
return Observable.just(MangasPage(mangas.toList(), false))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchLatestUpdates(page: Int) = fetchSearchManga(page, "", LATEST_FILTERS)
|
// Manga details related
|
||||||
|
|
||||||
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
|
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
|
||||||
val localDetails = getBaseDirectories(context)
|
var mangaInfo = manga
|
||||||
.asSequence()
|
|
||||||
.mapNotNull { File(it, manga.key).listFiles()?.toList() }
|
val baseDirsFile = getBaseDirectoriesFiles(context)
|
||||||
.flatten()
|
|
||||||
|
val coverFile = getCoverFile(manga.key, baseDirsFile)
|
||||||
|
|
||||||
|
coverFile?.let {
|
||||||
|
mangaInfo = mangaInfo.copy(cover = it.absolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
val localDetails = getMangaDirsFiles(manga.key, baseDirsFile)
|
||||||
.firstOrNull { it.extension.equals("json", ignoreCase = true) }
|
.firstOrNull { it.extension.equals("json", ignoreCase = true) }
|
||||||
|
|
||||||
return if (localDetails != null) {
|
if (localDetails != null) {
|
||||||
val obj = json.decodeFromStream<JsonObject>(localDetails.inputStream())
|
val obj = json.decodeFromStream<JsonObject>(localDetails.inputStream())
|
||||||
|
|
||||||
manga.copy(
|
mangaInfo = mangaInfo.copy(
|
||||||
title = obj["title"]?.jsonPrimitive?.contentOrNull ?: manga.title,
|
title = obj["title"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.title,
|
||||||
author = obj["author"]?.jsonPrimitive?.contentOrNull ?: manga.author,
|
author = obj["author"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.author,
|
||||||
artist = obj["artist"]?.jsonPrimitive?.contentOrNull ?: manga.artist,
|
artist = obj["artist"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.artist,
|
||||||
description = obj["description"]?.jsonPrimitive?.contentOrNull ?: manga.description,
|
description = obj["description"]?.jsonPrimitive?.contentOrNull ?: mangaInfo.description,
|
||||||
genres = obj["genre"]?.jsonArray?.map { it.jsonPrimitive.content } ?: manga.genres,
|
genres = obj["genre"]?.jsonArray?.map { it.jsonPrimitive.content } ?: mangaInfo.genres,
|
||||||
status = obj["status"]?.jsonPrimitive?.intOrNull ?: manga.status,
|
status = obj["status"]?.jsonPrimitive?.intOrNull ?: mangaInfo.status,
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
manga
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mangaInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chapters
|
||||||
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
|
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
|
||||||
val sManga = manga.toSManga()
|
val sManga = manga.toSManga()
|
||||||
|
|
||||||
val chapters = getBaseDirectories(context)
|
val baseDirsFile = getBaseDirectoriesFiles(context)
|
||||||
.asSequence()
|
return getMangaDirsFiles(manga.key, baseDirsFile)
|
||||||
.mapNotNull { File(it, manga.key).listFiles()?.toList() }
|
// Only keep supported formats
|
||||||
.flatten()
|
|
||||||
.filter { it.isDirectory || isSupportedFile(it.extension) }
|
.filter { it.isDirectory || isSupportedFile(it.extension) }
|
||||||
.map { chapterFile ->
|
.map { chapterFile ->
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
@ -211,15 +193,14 @@ class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSour
|
|||||||
}
|
}
|
||||||
date_upload = chapterFile.lastModified()
|
date_upload = chapterFile.lastModified()
|
||||||
|
|
||||||
|
ChapterRecognition.parseChapterNumber(this, sManga)
|
||||||
|
|
||||||
val format = getFormat(chapterFile)
|
val format = getFormat(chapterFile)
|
||||||
if (format is Format.Epub) {
|
if (format is Format.Epub) {
|
||||||
EpubFile(format.file).use { epub ->
|
EpubFile(format.file).use { epub ->
|
||||||
epub.fillChapterMetadata(this)
|
epub.fillChapterMetadata(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name = getCleanChapterTitle(name)
|
|
||||||
ChapterRecognition.parseChapterNumber(this, sManga)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map { it.toChapterInfo() }
|
.map { it.toChapterInfo() }
|
||||||
@ -228,19 +209,24 @@ class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSour
|
|||||||
if (c == 0) c2.name.compareToCaseInsensitiveNaturalOrder(c1.name) else c
|
if (c == 0) c2.name.compareToCaseInsensitiveNaturalOrder(c1.name) else c
|
||||||
}
|
}
|
||||||
.toList()
|
.toList()
|
||||||
|
|
||||||
return chapters
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getPageList(chapter: ChapterInfo) = throw Exception("Unused")
|
// Filters
|
||||||
|
override fun getFilterList() = FilterList(OrderBy(context))
|
||||||
|
|
||||||
/**
|
private val POPULAR_FILTERS = FilterList(OrderBy(context))
|
||||||
* Trim whitespace/delimiter characters from chapter names.
|
private val LATEST_FILTERS = FilterList(OrderBy(context).apply { state = Filter.Sort.Selection(1, false) })
|
||||||
*/
|
|
||||||
private fun getCleanChapterTitle(chapterName: String): String {
|
|
||||||
return chapterName.trim(*WHITESPACE_CHARS.toCharArray(), '-', '_', ',', ':')
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private class OrderBy(context: Context) : Filter.Sort(
|
||||||
|
context.getString(R.string.local_filter_order_by),
|
||||||
|
arrayOf(context.getString(R.string.title), context.getString(R.string.date)),
|
||||||
|
Selection(0, true),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unused stuff
|
||||||
|
override suspend fun getPageList(chapter: ChapterInfo) = throw UnsupportedOperationException("Unused")
|
||||||
|
|
||||||
|
// Miscellaneous
|
||||||
private fun isSupportedFile(extension: String): Boolean {
|
private fun isSupportedFile(extension: String): Boolean {
|
||||||
return extension.lowercase() in SUPPORTED_ARCHIVE_TYPES
|
return extension.lowercase() in SUPPORTED_ARCHIVE_TYPES
|
||||||
}
|
}
|
||||||
@ -304,54 +290,89 @@ class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.also { coverCache.clearMemoryCache() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList() = POPULAR_FILTERS
|
|
||||||
|
|
||||||
private val POPULAR_FILTERS = FilterList(OrderBy(context))
|
|
||||||
private val LATEST_FILTERS = FilterList(OrderBy(context).apply { state = Filter.Sort.Selection(1, false) })
|
|
||||||
|
|
||||||
private class OrderBy(context: Context) : Filter.Sort(
|
|
||||||
context.getString(R.string.local_filter_order_by),
|
|
||||||
arrayOf(context.getString(R.string.title), context.getString(R.string.date)),
|
|
||||||
Selection(0, true),
|
|
||||||
)
|
|
||||||
|
|
||||||
sealed class Format {
|
sealed class Format {
|
||||||
data class Directory(val file: File) : Format()
|
data class Directory(val file: File) : Format()
|
||||||
data class Zip(val file: File) : Format()
|
data class Zip(val file: File) : Format()
|
||||||
data class Rar(val file: File) : Format()
|
data class Rar(val file: File) : Format()
|
||||||
data class Epub(val file: File) : Format()
|
data class Epub(val file: File) : Format()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ID = 0L
|
||||||
|
const val HELP_URL = "https://tachiyomi.org/help/guides/local-manga/"
|
||||||
|
|
||||||
|
private const val DEFAULT_COVER_NAME = "cover.jpg"
|
||||||
|
private val LATEST_THRESHOLD = TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS)
|
||||||
|
|
||||||
|
private fun getBaseDirectories(context: Context): Sequence<File> {
|
||||||
|
val localFolder = context.getString(R.string.app_name) + File.separator + "local"
|
||||||
|
return DiskUtil.getExternalStorages(context)
|
||||||
|
.map { File(it.absolutePath, localFolder) }
|
||||||
|
.asSequence()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getBaseDirectoriesFiles(context: Context): Sequence<File> {
|
||||||
|
return getBaseDirectories(context)
|
||||||
|
// Get all the files inside all baseDir
|
||||||
|
.flatMap { it.listFiles().orEmpty().toList() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMangaDir(mangaUrl: String, baseDirsFile: Sequence<File>): File? {
|
||||||
|
return baseDirsFile
|
||||||
|
// Get the first mangaDir or null
|
||||||
|
.firstOrNull { it.isDirectory && it.name == mangaUrl }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMangaDirsFiles(mangaUrl: String, baseDirsFile: Sequence<File>): Sequence<File> {
|
||||||
|
return baseDirsFile
|
||||||
|
// Filter out ones that are not related to the manga and is not a directory
|
||||||
|
.filter { it.isDirectory && it.name == mangaUrl }
|
||||||
|
// Get all the files inside the filtered folders
|
||||||
|
.flatMap { it.listFiles().orEmpty().toList() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCoverFile(mangaUrl: String, baseDirsFile: Sequence<File>): File? {
|
||||||
|
return getMangaDirsFiles(mangaUrl, baseDirsFile)
|
||||||
|
// Get all file whose names start with 'cover'
|
||||||
|
.filter { it.isFile && it.nameWithoutExtension.equals("cover", ignoreCase = true) }
|
||||||
|
// Get the first actual image
|
||||||
|
.firstOrNull {
|
||||||
|
ImageUtil.isImage(it.name) { it.inputStream() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateCover(context: Context, manga: SManga, inputStream: InputStream): File? {
|
||||||
|
val baseDirsFiles = getBaseDirectoriesFiles(context)
|
||||||
|
|
||||||
|
val mangaDir = getMangaDir(manga.url, baseDirsFiles)
|
||||||
|
if (mangaDir == null) {
|
||||||
|
inputStream.close()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
var coverFile = getCoverFile(manga.url, baseDirsFiles)
|
||||||
|
if (coverFile == null) {
|
||||||
|
coverFile = File(mangaDir.absolutePath, DEFAULT_COVER_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
// It might not exist at this point
|
||||||
|
coverFile.parentFile?.mkdirs()
|
||||||
|
inputStream.use { input ->
|
||||||
|
coverFile.outputStream().use { output ->
|
||||||
|
input.copyTo(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a .nomedia file
|
||||||
|
DiskUtil.createNoMediaFile(UniFile.fromFile(mangaDir), context)
|
||||||
|
|
||||||
|
manga.thumbnail_url = coverFile.absolutePath
|
||||||
|
return coverFile
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val SUPPORTED_ARCHIVE_TYPES = listOf("zip", "cbz", "rar", "cbr", "epub")
|
private val SUPPORTED_ARCHIVE_TYPES = listOf("zip", "cbz", "rar", "cbr", "epub")
|
||||||
|
|
||||||
private val WHITESPACE_CHARS = arrayOf(
|
|
||||||
' ',
|
|
||||||
'\u0009',
|
|
||||||
'\u000A',
|
|
||||||
'\u000B',
|
|
||||||
'\u000C',
|
|
||||||
'\u000D',
|
|
||||||
'\u0020',
|
|
||||||
'\u0085',
|
|
||||||
'\u00A0',
|
|
||||||
'\u1680',
|
|
||||||
'\u2000',
|
|
||||||
'\u2001',
|
|
||||||
'\u2002',
|
|
||||||
'\u2003',
|
|
||||||
'\u2004',
|
|
||||||
'\u2005',
|
|
||||||
'\u2006',
|
|
||||||
'\u2007',
|
|
||||||
'\u2008',
|
|
||||||
'\u2009',
|
|
||||||
'\u200A',
|
|
||||||
'\u2028',
|
|
||||||
'\u2029',
|
|
||||||
'\u202F',
|
|
||||||
'\u205F',
|
|
||||||
'\u3000',
|
|
||||||
)
|
|
||||||
|
@ -371,6 +371,6 @@ abstract class HttpSource : CatalogueSource {
|
|||||||
override fun getFilterList() = FilterList()
|
override fun getFilterList() = FilterList()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63"
|
const val DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ abstract class DialogController : Controller {
|
|||||||
/**
|
/**
|
||||||
* Dismiss the dialog and pop this controller
|
* Dismiss the dialog and pop this controller
|
||||||
*/
|
*/
|
||||||
private fun dismissDialog() {
|
fun dismissDialog() {
|
||||||
if (dismissed) {
|
if (dismissed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,9 @@ interface ThemingDelegate {
|
|||||||
PreferenceValues.AppTheme.GREEN_APPLE -> {
|
PreferenceValues.AppTheme.GREEN_APPLE -> {
|
||||||
resIds += R.style.Theme_Tachiyomi_GreenApple
|
resIds += R.style.Theme_Tachiyomi_GreenApple
|
||||||
}
|
}
|
||||||
|
PreferenceValues.AppTheme.LAVENDER -> {
|
||||||
|
resIds += R.style.Theme_Tachiyomi_Lavender
|
||||||
|
}
|
||||||
PreferenceValues.AppTheme.MIDNIGHT_DUSK -> {
|
PreferenceValues.AppTheme.MIDNIGHT_DUSK -> {
|
||||||
resIds += R.style.Theme_Tachiyomi_MidnightDusk
|
resIds += R.style.Theme_Tachiyomi_MidnightDusk
|
||||||
}
|
}
|
||||||
|
@ -259,11 +259,11 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
?.map { it.baseUrl }
|
?.map { it.baseUrl }
|
||||||
?.distinct() ?: emptyList()
|
?.distinct() ?: emptyList()
|
||||||
|
|
||||||
urls.forEach {
|
val cleared = urls.sumOf {
|
||||||
network.cookieManager.remove(it.toHttpUrl())
|
network.cookieManager.remove(it.toHttpUrl())
|
||||||
}
|
}
|
||||||
|
|
||||||
logcat { "Cleared cookies for: ${urls.joinToString()}" }
|
logcat { "Cleared $cleared cookies for: ${urls.joinToString()}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Source.isEnabled(): Boolean {
|
private fun Source.isEnabled(): Boolean {
|
||||||
|
@ -129,7 +129,10 @@ class SearchController(
|
|||||||
}
|
}
|
||||||
(targetController as? SearchController)?.copyManga(manga, newManga)
|
(targetController as? SearchController)?.copyManga(manga, newManga)
|
||||||
}
|
}
|
||||||
.setNeutralButton(android.R.string.cancel, null)
|
.setNeutralButton(activity?.getString(R.string.action_show_manga)) { _, _ ->
|
||||||
|
dismissDialog()
|
||||||
|
router.pushController(MangaController(newManga).withFadeTransaction())
|
||||||
|
}
|
||||||
.create()
|
.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ open class TriStateItem(val filter: Filter.TriState) : AbstractFlexibleItem<TriS
|
|||||||
else -> throw Exception("Unknown state")
|
else -> throw Exception("Unknown state")
|
||||||
},
|
},
|
||||||
)?.apply {
|
)?.apply {
|
||||||
val color = if (filter.state == Filter.TriState.STATE_INCLUDE) {
|
val color = if (filter.state == Filter.TriState.STATE_IGNORE) {
|
||||||
view.context.getResourceColor(R.attr.colorAccent)
|
|
||||||
} else {
|
|
||||||
view.context.getResourceColor(R.attr.colorOnBackground, 0.38f)
|
view.context.getResourceColor(R.attr.colorOnBackground, 0.38f)
|
||||||
|
} else {
|
||||||
|
view.context.getResourceColor(R.attr.colorPrimary)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTint(color)
|
setTint(color)
|
||||||
|
@ -36,7 +36,7 @@ data class DownloadHeaderItem(
|
|||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other is DownloadHeaderItem) {
|
if (other is DownloadHeaderItem) {
|
||||||
return name == other.name
|
return id == other.id && name == other.name
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ class DownloadHolder(private val view: View, val adapter: DownloadAdapter) :
|
|||||||
view.popupMenu(
|
view.popupMenu(
|
||||||
menuRes = R.menu.download_single,
|
menuRes = R.menu.download_single,
|
||||||
initMenu = {
|
initMenu = {
|
||||||
findItem(R.id.move_to_top).isVisible = bindingAdapterPosition != 0
|
findItem(R.id.move_to_top).isVisible = bindingAdapterPosition > 1
|
||||||
findItem(R.id.move_to_bottom).isVisible =
|
findItem(R.id.move_to_bottom).isVisible =
|
||||||
bindingAdapterPosition != adapter.itemCount - 1
|
bindingAdapterPosition != adapter.itemCount - 1
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,6 @@ import android.view.MenuInflater
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.core.view.doOnAttach
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||||
import com.bluelinelabs.conductor.ControllerChangeType
|
import com.bluelinelabs.conductor.ControllerChangeType
|
||||||
@ -304,8 +303,10 @@ class LibraryController(
|
|||||||
onTabsSettingsChanged(firstLaunch = true)
|
onTabsSettingsChanged(firstLaunch = true)
|
||||||
|
|
||||||
// Delay the scroll position to allow the view to be properly measured.
|
// Delay the scroll position to allow the view to be properly measured.
|
||||||
view.doOnAttach {
|
view.post {
|
||||||
(activity as? MainActivity)?.binding?.tabs?.setScrollPosition(binding.libraryPager.currentItem, 0f, true)
|
if (isAttached) {
|
||||||
|
(activity as? MainActivity)?.binding?.tabs?.setScrollPosition(binding.libraryPager.currentItem, 0f, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the manga map to child fragments after the adapter is updated.
|
// Send the manga map to child fragments after the adapter is updated.
|
||||||
|
@ -795,7 +795,7 @@ class MangaController :
|
|||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
logcat(LogPriority.ERROR, e)
|
logcat(LogPriority.ERROR, e)
|
||||||
activity?.toast(R.string.error_saving_cover)
|
activity?.toast(R.string.error_sharing_cover)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import androidx.core.text.buildSpannedString
|
|||||||
import androidx.core.text.color
|
import androidx.core.text.color
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.databinding.ChaptersItemBinding
|
import eu.kanade.tachiyomi.databinding.ChaptersItemBinding
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
@ -35,6 +36,8 @@ class ChapterHolder(
|
|||||||
itemView.context.getString(R.string.display_mode_chapter, number)
|
itemView.context.getString(R.string.display_mode_chapter, number)
|
||||||
}
|
}
|
||||||
else -> chapter.name
|
else -> chapter.name
|
||||||
|
// TODO: show cleaned name consistently around the app
|
||||||
|
// else -> cleanChapterName(chapter, manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set correct text color
|
// Set correct text color
|
||||||
@ -80,4 +83,47 @@ class ChapterHolder(
|
|||||||
binding.download.isVisible = item.manga.source != LocalSource.ID
|
binding.download.isVisible = item.manga.source != LocalSource.ID
|
||||||
binding.download.setState(item.status, item.progress)
|
binding.download.setState(item.status, item.progress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun cleanChapterName(chapter: Chapter, manga: Manga): String {
|
||||||
|
return chapter.name
|
||||||
|
.trim()
|
||||||
|
.removePrefix(manga.title)
|
||||||
|
.trim(*CHAPTER_TRIM_CHARS)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val CHAPTER_TRIM_CHARS = arrayOf(
|
||||||
|
// Whitespace
|
||||||
|
' ',
|
||||||
|
'\u0009',
|
||||||
|
'\u000A',
|
||||||
|
'\u000B',
|
||||||
|
'\u000C',
|
||||||
|
'\u000D',
|
||||||
|
'\u0020',
|
||||||
|
'\u0085',
|
||||||
|
'\u00A0',
|
||||||
|
'\u1680',
|
||||||
|
'\u2000',
|
||||||
|
'\u2001',
|
||||||
|
'\u2002',
|
||||||
|
'\u2003',
|
||||||
|
'\u2004',
|
||||||
|
'\u2005',
|
||||||
|
'\u2006',
|
||||||
|
'\u2007',
|
||||||
|
'\u2008',
|
||||||
|
'\u2009',
|
||||||
|
'\u200A',
|
||||||
|
'\u2028',
|
||||||
|
'\u2029',
|
||||||
|
'\u202F',
|
||||||
|
'\u205F',
|
||||||
|
'\u3000',
|
||||||
|
|
||||||
|
// Separators
|
||||||
|
'-',
|
||||||
|
'_',
|
||||||
|
',',
|
||||||
|
':',
|
||||||
|
).toCharArray()
|
||||||
|
@ -121,6 +121,7 @@ class AboutController : SettingsController(), NoAppBarElevationController {
|
|||||||
is AppUpdateResult.NoNewUpdate -> {
|
is AppUpdateResult.NoNewUpdate -> {
|
||||||
activity?.toast(R.string.update_check_no_new_updates)
|
activity?.toast(R.string.update_check_no_new_updates)
|
||||||
}
|
}
|
||||||
|
else -> {}
|
||||||
}
|
}
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
activity?.toast(error.message)
|
activity?.toast(error.message)
|
||||||
|
@ -2,35 +2,58 @@ package eu.kanade.tachiyomi.ui.more
|
|||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.method.LinkMovementMethod
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
|
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
|
||||||
import eu.kanade.tachiyomi.data.updater.AppUpdateService
|
import eu.kanade.tachiyomi.data.updater.AppUpdateService
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
|
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
|
||||||
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
|
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
|
||||||
|
|
||||||
constructor(update: AppUpdateResult.NewUpdate) : this(
|
constructor(update: AppUpdateResult.NewUpdate) : this(
|
||||||
bundleOf(BODY_KEY to update.release.info, URL_KEY to update.release.getDownloadLink()),
|
bundleOf(
|
||||||
|
BODY_KEY to update.release.info,
|
||||||
|
RELEASE_URL_KEY to update.release.releaseLink,
|
||||||
|
DOWNLOAD_URL_KEY to update.release.getDownloadLink(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||||
|
val releaseBody = args.getString(BODY_KEY)!!
|
||||||
|
.replace("""---(\R|.)*Checksums(\R|.)*""".toRegex(), "")
|
||||||
|
val info = Markwon.create(activity!!).toMarkdown(releaseBody)
|
||||||
|
|
||||||
return MaterialAlertDialogBuilder(activity!!)
|
return MaterialAlertDialogBuilder(activity!!)
|
||||||
.setTitle(R.string.update_check_notification_update_available)
|
.setTitle(R.string.update_check_notification_update_available)
|
||||||
.setMessage(args.getString(BODY_KEY) ?: "")
|
.setMessage(info)
|
||||||
.setPositiveButton(R.string.update_check_confirm) { _, _ ->
|
.setPositiveButton(R.string.update_check_confirm) { _, _ ->
|
||||||
val appContext = applicationContext
|
applicationContext?.let { context ->
|
||||||
if (appContext != null) {
|
|
||||||
// Start download
|
// Start download
|
||||||
val url = args.getString(URL_KEY) ?: ""
|
val url = args.getString(DOWNLOAD_URL_KEY)!!
|
||||||
AppUpdateService.start(appContext, url)
|
AppUpdateService.start(context, url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.update_check_ignore, null)
|
.setNeutralButton(R.string.update_check_open) { _, _ ->
|
||||||
|
openInBrowser(args.getString(RELEASE_URL_KEY)!!)
|
||||||
|
}
|
||||||
.create()
|
.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAttach(view: View) {
|
||||||
|
super.onAttach(view)
|
||||||
|
|
||||||
|
// Make links in Markdown text clickable
|
||||||
|
(dialog?.findViewById(android.R.id.message) as? TextView)?.movementMethod =
|
||||||
|
LinkMovementMethod.getInstance()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val BODY_KEY = "NewUpdateDialogController.body"
|
private const val BODY_KEY = "NewUpdateDialogController.body"
|
||||||
private const val URL_KEY = "NewUpdateDialogController.key"
|
private const val RELEASE_URL_KEY = "NewUpdateDialogController.release_url"
|
||||||
|
private const val DOWNLOAD_URL_KEY = "NewUpdateDialogController.download_url"
|
||||||
|
@ -226,6 +226,11 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
|||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
presenter.saveProgress()
|
||||||
|
super.onPause()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set menu visibility again on activity resume to apply immersive mode again if needed.
|
* Set menu visibility again on activity resume to apply immersive mode again if needed.
|
||||||
* Helps with rotations.
|
* Helps with rotations.
|
||||||
|
@ -4,7 +4,6 @@ import android.app.Application
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.History
|
import eu.kanade.tachiyomi.data.database.models.History
|
||||||
@ -22,6 +21,7 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import eu.kanade.tachiyomi.ui.reader.loader.ChapterLoader
|
import eu.kanade.tachiyomi.ui.reader.loader.ChapterLoader
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.loader.HttpPageLoader
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||||
@ -345,6 +345,14 @@ class ReaderPresenter(
|
|||||||
* that the user doesn't have to wait too long to continue reading.
|
* that the user doesn't have to wait too long to continue reading.
|
||||||
*/
|
*/
|
||||||
private fun preload(chapter: ReaderChapter) {
|
private fun preload(chapter: ReaderChapter) {
|
||||||
|
if (chapter.pageLoader is HttpPageLoader) {
|
||||||
|
val manga = manga ?: return
|
||||||
|
val isDownloaded = downloadManager.isChapterDownloaded(chapter.chapter, manga)
|
||||||
|
if (isDownloaded) {
|
||||||
|
chapter.state = ReaderChapter.State.Wait
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (chapter.state != ReaderChapter.State.Wait && chapter.state !is ReaderChapter.State.Error) {
|
if (chapter.state != ReaderChapter.State.Wait && chapter.state !is ReaderChapter.State.Error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -456,6 +464,10 @@ class ReaderPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveProgress() {
|
||||||
|
getCurrentChapter()?.let { onChapterChanged(it) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the activity to preload the given [chapter].
|
* Called from the activity to preload the given [chapter].
|
||||||
*/
|
*/
|
||||||
@ -662,20 +674,22 @@ class ReaderPresenter(
|
|||||||
|
|
||||||
Observable
|
Observable
|
||||||
.fromCallable {
|
.fromCallable {
|
||||||
if (manga.isLocal()) {
|
stream().use {
|
||||||
val context = Injekt.get<Application>()
|
if (manga.isLocal()) {
|
||||||
LocalSource.updateCover(context, manga, stream())
|
val context = Injekt.get<Application>()
|
||||||
manga.updateCoverLastModified(db)
|
LocalSource.updateCover(context, manga, it)
|
||||||
R.string.cover_updated
|
|
||||||
SetAsCoverResult.Success
|
|
||||||
} else {
|
|
||||||
if (manga.favorite) {
|
|
||||||
coverCache.setCustomCoverToCache(manga, stream())
|
|
||||||
manga.updateCoverLastModified(db)
|
manga.updateCoverLastModified(db)
|
||||||
coverCache.clearMemoryCache()
|
coverCache.clearMemoryCache()
|
||||||
SetAsCoverResult.Success
|
SetAsCoverResult.Success
|
||||||
} else {
|
} else {
|
||||||
SetAsCoverResult.AddToLibraryFirst
|
if (manga.favorite) {
|
||||||
|
coverCache.setCustomCoverToCache(manga, it)
|
||||||
|
manga.updateCoverLastModified(db)
|
||||||
|
coverCache.clearMemoryCache()
|
||||||
|
SetAsCoverResult.Success
|
||||||
|
} else {
|
||||||
|
SetAsCoverResult.AddToLibraryFirst
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||||||
|
|
||||||
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
|
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
|
||||||
if (config != null && config!!.landscapeZoom && config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE && sWidth > sHeight && scale == minScale) {
|
if (config != null && config!!.landscapeZoom && config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE && sWidth > sHeight && scale == minScale) {
|
||||||
handler.postDelayed({
|
handler?.postDelayed({
|
||||||
val point = when (config!!.zoomStartPosition) {
|
val point = when (config!!.zoomStartPosition) {
|
||||||
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)
|
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)
|
||||||
ZoomStartPosition.RIGHT -> if (forward) PointF(sWidth.toFloat(), 0F) else PointF(0F, 0F)
|
ZoomStartPosition.RIGHT -> if (forward) PointF(sWidth.toFloat(), 0F) else PointF(0F, 0F)
|
||||||
|
@ -26,7 +26,6 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At
|
|||||||
is ChapterTransition.Prev -> bindPrevChapterTransition(transition)
|
is ChapterTransition.Prev -> bindPrevChapterTransition(transition)
|
||||||
is ChapterTransition.Next -> bindNextChapterTransition(transition)
|
is ChapterTransition.Next -> bindNextChapterTransition(transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
missingChapterWarning(transition)
|
missingChapterWarning(transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +66,14 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
|
|||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
if (value) {
|
if (value) {
|
||||||
awaitingIdleViewerChapters?.let {
|
awaitingIdleViewerChapters?.let { viewerChapters ->
|
||||||
setChaptersInternal(it)
|
setChaptersInternal(viewerChapters)
|
||||||
awaitingIdleViewerChapters = null
|
awaitingIdleViewerChapters = null
|
||||||
|
if (viewerChapters.currChapter.pages?.size == 1) {
|
||||||
|
adapter.nextTransition?.to?.let {
|
||||||
|
activity.requestPreloadChapter(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class WebtoonTransitionHolder(
|
|||||||
layout.orientation = LinearLayout.VERTICAL
|
layout.orientation = LinearLayout.VERTICAL
|
||||||
layout.gravity = Gravity.CENTER
|
layout.gravity = Gravity.CENTER
|
||||||
|
|
||||||
val paddingVertical = 48.dpToPx
|
val paddingVertical = 128.dpToPx
|
||||||
val paddingHorizontal = 32.dpToPx
|
val paddingHorizontal = 32.dpToPx
|
||||||
layout.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
|
layout.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
|
||||||
|
|
||||||
|
@ -103,6 +103,12 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
|
|||||||
activity.requestPreloadChapter(firstItem.to)
|
activity.requestPreloadChapter(firstItem.to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val lastIndex = layoutManager.findLastEndVisibleItemPosition()
|
||||||
|
val lastItem = adapter.items.getOrNull(lastIndex)
|
||||||
|
if (lastItem is ChapterTransition.Next && lastItem.to == null) {
|
||||||
|
activity.showMenu()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -216,9 +222,6 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
|
|||||||
if (toChapter != null) {
|
if (toChapter != null) {
|
||||||
logcat { "Request preload destination chapter because we're on the transition" }
|
logcat { "Request preload destination chapter because we're on the transition" }
|
||||||
activity.requestPreloadChapter(toChapter)
|
activity.requestPreloadChapter(toChapter)
|
||||||
} else if (transition is ChapterTransition.Next) {
|
|
||||||
// No more chapters, show menu because the user is probably going to close the reader
|
|
||||||
activity.showMenu()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +248,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
|
|||||||
logcat { "moveToPage" }
|
logcat { "moveToPage" }
|
||||||
val position = adapter.items.indexOf(page)
|
val position = adapter.items.indexOf(page)
|
||||||
if (position != -1) {
|
if (position != -1) {
|
||||||
recycler.scrollToPosition(position)
|
layoutManager.scrollToPositionWithOffset(position, 0)
|
||||||
if (layoutManager.findLastEndVisibleItemPosition() == -1) {
|
if (layoutManager.findLastEndVisibleItemPosition() == -1) {
|
||||||
onScrolled(pos = position)
|
onScrolled(pos = position)
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.webkit.WebStorage
|
||||||
|
import android.webkit.WebView
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
@ -15,9 +16,13 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
|||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Target
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Target
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
|
import eu.kanade.tachiyomi.network.PREF_DOH_360
|
||||||
import eu.kanade.tachiyomi.network.PREF_DOH_ADGUARD
|
import eu.kanade.tachiyomi.network.PREF_DOH_ADGUARD
|
||||||
|
import eu.kanade.tachiyomi.network.PREF_DOH_ALIDNS
|
||||||
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
|
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
|
||||||
|
import eu.kanade.tachiyomi.network.PREF_DOH_DNSPOD
|
||||||
import eu.kanade.tachiyomi.network.PREF_DOH_GOOGLE
|
import eu.kanade.tachiyomi.network.PREF_DOH_GOOGLE
|
||||||
|
import eu.kanade.tachiyomi.network.PREF_DOH_QUAD101
|
||||||
import eu.kanade.tachiyomi.network.PREF_DOH_QUAD9
|
import eu.kanade.tachiyomi.network.PREF_DOH_QUAD9
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
|
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
@ -38,11 +43,16 @@ import eu.kanade.tachiyomi.util.preference.summaryRes
|
|||||||
import eu.kanade.tachiyomi.util.preference.switchPreference
|
import eu.kanade.tachiyomi.util.preference.switchPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.titleRes
|
import eu.kanade.tachiyomi.util.preference.titleRes
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
|
import eu.kanade.tachiyomi.util.system.isDevFlavor
|
||||||
import eu.kanade.tachiyomi.util.system.isPackageInstalled
|
import eu.kanade.tachiyomi.util.system.isPackageInstalled
|
||||||
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.powerManager
|
import eu.kanade.tachiyomi.util.system.powerManager
|
||||||
|
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import logcat.LogPriority
|
||||||
import rikka.sui.Sui
|
import rikka.sui.Sui
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.io.File
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||||
|
|
||||||
class SettingsAdvancedController : SettingsController() {
|
class SettingsAdvancedController : SettingsController() {
|
||||||
@ -55,7 +65,7 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
||||||
titleRes = R.string.pref_category_advanced
|
titleRes = R.string.pref_category_advanced
|
||||||
|
|
||||||
if (BuildConfig.FLAVOR != "dev") {
|
if (isDevFlavor.not()) {
|
||||||
switchPreference {
|
switchPreference {
|
||||||
key = "acra.enable"
|
key = "acra.enable"
|
||||||
titleRes = R.string.pref_enable_acra
|
titleRes = R.string.pref_enable_acra
|
||||||
@ -78,7 +88,7 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
key = Keys.verboseLogging
|
key = Keys.verboseLogging
|
||||||
titleRes = R.string.pref_verbose_logging
|
titleRes = R.string.pref_verbose_logging
|
||||||
summaryRes = R.string.pref_verbose_logging_summary
|
summaryRes = R.string.pref_verbose_logging_summary
|
||||||
defaultValue = false
|
defaultValue = isDevFlavor
|
||||||
|
|
||||||
onChange {
|
onChange {
|
||||||
activity?.toast(R.string.requires_app_restart)
|
activity?.toast(R.string.requires_app_restart)
|
||||||
@ -161,6 +171,12 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
activity?.toast(R.string.cookies_cleared)
|
activity?.toast(R.string.cookies_cleared)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
preference {
|
||||||
|
key = "pref_clear_webview_data"
|
||||||
|
titleRes = R.string.pref_clear_webview_data
|
||||||
|
|
||||||
|
onClick { clearWebViewData() }
|
||||||
|
}
|
||||||
intListPreference {
|
intListPreference {
|
||||||
key = Keys.dohProvider
|
key = Keys.dohProvider
|
||||||
titleRes = R.string.pref_dns_over_https
|
titleRes = R.string.pref_dns_over_https
|
||||||
@ -170,6 +186,10 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
"Google",
|
"Google",
|
||||||
"AdGuard",
|
"AdGuard",
|
||||||
"Quad9",
|
"Quad9",
|
||||||
|
"AliDNS",
|
||||||
|
"DNSPod",
|
||||||
|
"360",
|
||||||
|
"Quad 101",
|
||||||
)
|
)
|
||||||
entryValues = arrayOf(
|
entryValues = arrayOf(
|
||||||
"-1",
|
"-1",
|
||||||
@ -177,6 +197,10 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
PREF_DOH_GOOGLE.toString(),
|
PREF_DOH_GOOGLE.toString(),
|
||||||
PREF_DOH_ADGUARD.toString(),
|
PREF_DOH_ADGUARD.toString(),
|
||||||
PREF_DOH_QUAD9.toString(),
|
PREF_DOH_QUAD9.toString(),
|
||||||
|
PREF_DOH_ALIDNS.toString(),
|
||||||
|
PREF_DOH_DNSPOD.toString(),
|
||||||
|
PREF_DOH_360.toString(),
|
||||||
|
PREF_DOH_QUAD101.toString(),
|
||||||
)
|
)
|
||||||
defaultValue = "-1"
|
defaultValue = "-1"
|
||||||
summary = "%s"
|
summary = "%s"
|
||||||
@ -274,10 +298,29 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
resources?.getString(R.string.used_cache, chapterCache.readableSize)
|
resources?.getString(R.string.used_cache, chapterCache.readableSize)
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
logcat(LogPriority.ERROR, e)
|
||||||
withUIContext { activity?.toast(R.string.cache_delete_error) }
|
withUIContext { activity?.toast(R.string.cache_delete_error) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clearWebViewData() {
|
||||||
|
if (activity == null) return
|
||||||
|
try {
|
||||||
|
val webview = WebView(activity!!)
|
||||||
|
webview.setDefaultSettings()
|
||||||
|
webview.clearCache(true)
|
||||||
|
webview.clearFormData()
|
||||||
|
webview.clearHistory()
|
||||||
|
webview.clearSslPreferences()
|
||||||
|
WebStorage.getInstance().deleteAllData()
|
||||||
|
activity?.applicationInfo?.dataDir?.let { File("$it/app_webview/").deleteRecursively() }
|
||||||
|
activity?.toast(R.string.webview_data_deleted)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logcat(LogPriority.ERROR, e)
|
||||||
|
activity?.toast(R.string.cache_delete_error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val CLEAR_CACHE_KEY = "pref_clear_cache_key"
|
private const val CLEAR_CACHE_KEY = "pref_clear_cache_key"
|
||||||
|
@ -125,20 +125,20 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
titleRes = R.string.pref_category_auto_download
|
titleRes = R.string.pref_category_auto_download
|
||||||
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
bindTo(preferences.downloadNew())
|
bindTo(preferences.downloadNewChapter())
|
||||||
titleRes = R.string.pref_download_new
|
titleRes = R.string.pref_download_new
|
||||||
}
|
}
|
||||||
preference {
|
preference {
|
||||||
bindTo(preferences.downloadNewCategories())
|
bindTo(preferences.downloadNewChapterCategories())
|
||||||
titleRes = R.string.categories
|
titleRes = R.string.categories
|
||||||
onClick {
|
onClick {
|
||||||
DownloadCategoriesDialog().showDialog(router)
|
DownloadCategoriesDialog().showDialog(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
visibleIf(preferences.downloadNew()) { it }
|
visibleIf(preferences.downloadNewChapter()) { it }
|
||||||
|
|
||||||
fun updateSummary() {
|
fun updateSummary() {
|
||||||
val selectedCategories = preferences.downloadNewCategories().get()
|
val selectedCategories = preferences.downloadNewChapterCategories().get()
|
||||||
.mapNotNull { id -> categories.find { it.id == id.toInt() } }
|
.mapNotNull { id -> categories.find { it.id == id.toInt() } }
|
||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
val includedItemsText = if (selectedCategories.isEmpty()) {
|
val includedItemsText = if (selectedCategories.isEmpty()) {
|
||||||
@ -147,7 +147,7 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
selectedCategories.joinToString { it.name }
|
selectedCategories.joinToString { it.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
val excludedCategories = preferences.downloadNewCategoriesExclude().get()
|
val excludedCategories = preferences.downloadNewChapterCategoriesExclude().get()
|
||||||
.mapNotNull { id -> categories.find { it.id == id.toInt() } }
|
.mapNotNull { id -> categories.find { it.id == id.toInt() } }
|
||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
val excludedItemsText = if (excludedCategories.isEmpty()) {
|
val excludedItemsText = if (excludedCategories.isEmpty()) {
|
||||||
@ -163,10 +163,10 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences.downloadNewCategories().asFlow()
|
preferences.downloadNewChapterCategories().asFlow()
|
||||||
.onEach { updateSummary() }
|
.onEach { updateSummary() }
|
||||||
.launchIn(viewScope)
|
.launchIn(viewScope)
|
||||||
preferences.downloadNewCategoriesExclude().asFlow()
|
preferences.downloadNewChapterCategoriesExclude().asFlow()
|
||||||
.onEach { updateSummary() }
|
.onEach { updateSummary() }
|
||||||
.launchIn(viewScope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
@ -254,8 +254,8 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
var selected = categories
|
var selected = categories
|
||||||
.map {
|
.map {
|
||||||
when (it.id.toString()) {
|
when (it.id.toString()) {
|
||||||
in preferences.downloadNewCategories().get() -> QuadStateTextView.State.CHECKED.ordinal
|
in preferences.downloadNewChapterCategories().get() -> QuadStateTextView.State.CHECKED.ordinal
|
||||||
in preferences.downloadNewCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal
|
in preferences.downloadNewChapterCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal
|
||||||
else -> QuadStateTextView.State.UNCHECKED.ordinal
|
else -> QuadStateTextView.State.UNCHECKED.ordinal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,8 +282,8 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
.map { categories[it].id.toString() }
|
.map { categories[it].id.toString() }
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
preferences.downloadNewCategories().set(included)
|
preferences.downloadNewChapterCategories().set(included)
|
||||||
preferences.downloadNewCategoriesExclude().set(excluded)
|
preferences.downloadNewChapterCategoriesExclude().set(excluded)
|
||||||
}
|
}
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.create()
|
.create()
|
||||||
|
@ -11,12 +11,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||||
import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING
|
import eu.kanade.tachiyomi.data.preference.*
|
||||||
import eu.kanade.tachiyomi.data.preference.DEVICE_ONLY_ON_WIFI
|
|
||||||
import eu.kanade.tachiyomi.data.preference.MANGA_HAS_UNREAD
|
|
||||||
import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED
|
|
||||||
import eu.kanade.tachiyomi.data.preference.MANGA_NON_READ
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.databinding.PrefLibraryColumnsBinding
|
import eu.kanade.tachiyomi.databinding.PrefLibraryColumnsBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
@ -159,8 +154,8 @@ class SettingsLibraryController : SettingsController() {
|
|||||||
multiSelectListPreference {
|
multiSelectListPreference {
|
||||||
bindTo(preferences.libraryUpdateDeviceRestriction())
|
bindTo(preferences.libraryUpdateDeviceRestriction())
|
||||||
titleRes = R.string.pref_library_update_restriction
|
titleRes = R.string.pref_library_update_restriction
|
||||||
entriesRes = arrayOf(R.string.connected_to_wifi, R.string.charging)
|
entriesRes = arrayOf(R.string.connected_to_wifi, R.string.network_not_metered, R.string.charging, R.string.battery_not_low)
|
||||||
entryValues = arrayOf(DEVICE_ONLY_ON_WIFI, DEVICE_CHARGING)
|
entryValues = arrayOf(DEVICE_ONLY_ON_WIFI, DEVICE_NETWORK_NOT_METERED, DEVICE_CHARGING, DEVICE_BATTERY_NOT_LOW)
|
||||||
|
|
||||||
visibleIf(preferences.libraryUpdateInterval()) { it > 0 }
|
visibleIf(preferences.libraryUpdateInterval()) { it > 0 }
|
||||||
|
|
||||||
@ -176,7 +171,9 @@ class SettingsLibraryController : SettingsController() {
|
|||||||
.map {
|
.map {
|
||||||
when (it) {
|
when (it) {
|
||||||
DEVICE_ONLY_ON_WIFI -> context.getString(R.string.connected_to_wifi)
|
DEVICE_ONLY_ON_WIFI -> context.getString(R.string.connected_to_wifi)
|
||||||
|
DEVICE_NETWORK_NOT_METERED -> context.getString(R.string.network_not_metered)
|
||||||
DEVICE_CHARGING -> context.getString(R.string.charging)
|
DEVICE_CHARGING -> context.getString(R.string.charging)
|
||||||
|
DEVICE_BATTERY_NOT_LOW -> context.getString(R.string.battery_not_low)
|
||||||
else -> it
|
else -> it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class ClearDatabaseController :
|
|||||||
|
|
||||||
adapter = FlexibleAdapter<ClearDatabaseSourceItem>(null, this, true)
|
adapter = FlexibleAdapter<ClearDatabaseSourceItem>(null, this, true)
|
||||||
binding.recycler.adapter = adapter
|
binding.recycler.adapter = adapter
|
||||||
binding.recycler.layoutManager = LinearLayoutManager(activity)
|
binding.recycler.layoutManager = LinearLayoutManager(activity!!)
|
||||||
binding.recycler.setHasFixedSize(true)
|
binding.recycler.setHasFixedSize(true)
|
||||||
adapter?.fastScroller = binding.fastScroller
|
adapter?.fastScroller = binding.fastScroller
|
||||||
recycler = binding.recycler
|
recycler = binding.recycler
|
||||||
|
@ -17,17 +17,20 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.WebviewActivityBinding
|
import eu.kanade.tachiyomi.databinding.WebviewActivityBinding
|
||||||
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||||
import eu.kanade.tachiyomi.util.system.WebViewClientCompat
|
import eu.kanade.tachiyomi.util.system.WebViewClientCompat
|
||||||
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||||
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import reactivecircus.flowbinding.appcompat.navigationClicks
|
import reactivecircus.flowbinding.appcompat.navigationClicks
|
||||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
@ -37,11 +40,16 @@ class WebViewActivity : BaseActivity() {
|
|||||||
private lateinit var binding: WebviewActivityBinding
|
private lateinit var binding: WebviewActivityBinding
|
||||||
|
|
||||||
private val sourceManager: SourceManager by injectLazy()
|
private val sourceManager: SourceManager by injectLazy()
|
||||||
|
private val network: NetworkHelper by injectLazy()
|
||||||
|
|
||||||
private var bundle: Bundle? = null
|
private var bundle: Bundle? = null
|
||||||
|
|
||||||
private var isRefreshing: Boolean = false
|
private var isRefreshing: Boolean = false
|
||||||
|
|
||||||
|
init {
|
||||||
|
registerSecureActivity(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
@ -176,6 +184,7 @@ class WebViewActivity : BaseActivity() {
|
|||||||
R.id.action_web_refresh -> refreshPage()
|
R.id.action_web_refresh -> refreshPage()
|
||||||
R.id.action_web_share -> shareWebpage()
|
R.id.action_web_share -> shareWebpage()
|
||||||
R.id.action_web_browser -> openInBrowser()
|
R.id.action_web_browser -> openInBrowser()
|
||||||
|
R.id.action_clear_cookies -> clearCookies()
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
@ -207,8 +216,10 @@ class WebViewActivity : BaseActivity() {
|
|||||||
openInBrowser(binding.webview.url!!, forceDefaultBrowser = true)
|
openInBrowser(binding.webview.url!!, forceDefaultBrowser = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
private fun clearCookies() {
|
||||||
registerSecureActivity(this)
|
val url = binding.webview.url!!
|
||||||
|
val cleared = network.cookieManager.remove(url.toHttpUrl())
|
||||||
|
logcat { "Cleared $cleared cookies for: $url" }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -56,14 +56,14 @@ fun Manga.shouldDownloadNewChapters(db: DatabaseHelper, prefs: PreferencesHelper
|
|||||||
if (!favorite) return false
|
if (!favorite) return false
|
||||||
|
|
||||||
// Boolean to determine if user wants to automatically download new chapters.
|
// Boolean to determine if user wants to automatically download new chapters.
|
||||||
val downloadNew = prefs.downloadNew().get()
|
val downloadNewChapter = prefs.downloadNewChapter().get()
|
||||||
if (!downloadNew) return false
|
if (!downloadNewChapter) return false
|
||||||
|
|
||||||
val categoriesToDownload = prefs.downloadNewCategories().get().map(String::toInt)
|
val includedCategories = prefs.downloadNewChapterCategories().get().map { it.toInt() }
|
||||||
val categoriesToExclude = prefs.downloadNewCategoriesExclude().get().map(String::toInt)
|
val excludedCategories = prefs.downloadNewChapterCategoriesExclude().get().map { it.toInt() }
|
||||||
|
|
||||||
// Default: download from all categories
|
// Default: Download from all categories
|
||||||
if (categoriesToDownload.isEmpty() && categoriesToExclude.isEmpty()) return true
|
if (includedCategories.isEmpty() && excludedCategories.isEmpty()) return true
|
||||||
|
|
||||||
// Get all categories, else default category (0)
|
// Get all categories, else default category (0)
|
||||||
val categoriesForManga =
|
val categoriesForManga =
|
||||||
@ -72,8 +72,11 @@ fun Manga.shouldDownloadNewChapters(db: DatabaseHelper, prefs: PreferencesHelper
|
|||||||
.takeUnless { it.isEmpty() } ?: listOf(0)
|
.takeUnless { it.isEmpty() } ?: listOf(0)
|
||||||
|
|
||||||
// In excluded category
|
// In excluded category
|
||||||
if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) return false
|
if (categoriesForManga.any { it in excludedCategories }) return false
|
||||||
|
|
||||||
|
// Included category not selected
|
||||||
|
if (includedCategories.isEmpty()) return true
|
||||||
|
|
||||||
// In included category
|
// In included category
|
||||||
return categoriesForManga.intersect(categoriesToDownload).isNotEmpty()
|
return categoriesForManga.any { it in includedCategories }
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import uy.kohesive.injekt.Injekt
|
|||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.TreeSet
|
import java.util.TreeSet
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for syncing the list of chapters from the source with the ones from the database.
|
* Helper method for syncing the list of chapters from the source with the ones from the database.
|
||||||
@ -59,6 +60,9 @@ fun syncChaptersWithSource(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var maxTimestamp = 0L // in previous chapters to add
|
||||||
|
val rightNow = Date().time
|
||||||
|
|
||||||
for (sourceChapter in sourceChapters) {
|
for (sourceChapter in sourceChapters) {
|
||||||
// This forces metadata update for the main viewable things in the chapter list.
|
// This forces metadata update for the main viewable things in the chapter list.
|
||||||
if (source is HttpSource) {
|
if (source is HttpSource) {
|
||||||
@ -72,7 +76,9 @@ fun syncChaptersWithSource(
|
|||||||
// Add the chapter if not in db already, or update if the metadata changed.
|
// Add the chapter if not in db already, or update if the metadata changed.
|
||||||
if (dbChapter == null) {
|
if (dbChapter == null) {
|
||||||
if (sourceChapter.date_upload == 0L) {
|
if (sourceChapter.date_upload == 0L) {
|
||||||
sourceChapter.date_upload = Date().time
|
sourceChapter.date_upload = if (maxTimestamp == 0L) rightNow else maxTimestamp
|
||||||
|
} else {
|
||||||
|
maxTimestamp = max(maxTimestamp, sourceChapter.date_upload)
|
||||||
}
|
}
|
||||||
toAdd.add(sourceChapter)
|
toAdd.add(sourceChapter)
|
||||||
} else {
|
} else {
|
||||||
@ -97,6 +103,7 @@ fun syncChaptersWithSource(
|
|||||||
return Pair(emptyList(), emptyList())
|
return Pair(emptyList(), emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep it a List instead of a Set. See #6372.
|
||||||
val readded = mutableListOf<Chapter>()
|
val readded = mutableListOf<Chapter>()
|
||||||
|
|
||||||
db.inTransaction {
|
db.inTransaction {
|
||||||
@ -154,6 +161,7 @@ fun syncChaptersWithSource(
|
|||||||
db.updateLastUpdated(manga).executeAsBlocking()
|
db.updateLastUpdated(manga).executeAsBlocking()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("ConvertArgumentToSet")
|
||||||
return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList())
|
return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
|
|
||||||
|
val isDevFlavor: Boolean
|
||||||
|
get() = BuildConfig.FLAVOR == "dev"
|
@ -87,7 +87,11 @@ fun Context.copyToClipboard(label: String, content: String) {
|
|||||||
val clipboard = getSystemService<ClipboardManager>()!!
|
val clipboard = getSystemService<ClipboardManager>()!!
|
||||||
clipboard.setPrimaryClip(ClipData.newPlainText(label, content))
|
clipboard.setPrimaryClip(ClipData.newPlainText(label, content))
|
||||||
|
|
||||||
toast(getString(R.string.copied_to_clipboard, content.truncateCenter(50)))
|
// Android 13 and higher shows a visual confirmation of copied contents
|
||||||
|
// https://developer.android.com/about/versions/13/features/copy-paste
|
||||||
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
||||||
|
toast(getString(R.string.copied_to_clipboard, content.truncateCenter(50)))
|
||||||
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
logcat(LogPriority.ERROR, e)
|
logcat(LogPriority.ERROR, e)
|
||||||
toast(R.string.clipboard_copy_error)
|
toast(R.string.clipboard_copy_error)
|
||||||
@ -382,6 +386,19 @@ fun Context.isPackageInstalled(packageName: String): Boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.getInstallerPackageName(): String? {
|
||||||
|
return try {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
packageManager.getInstallSourceInfo(packageName).installingPackageName
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
packageManager.getInstallerPackageName(packageName)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Context.getApplicationIcon(pkgName: String): Drawable? {
|
fun Context.getApplicationIcon(pkgName: String): Drawable? {
|
||||||
return try {
|
return try {
|
||||||
packageManager.getApplicationIcon(pkgName)
|
packageManager.getApplicationIcon(pkgName)
|
||||||
|
@ -10,6 +10,7 @@ import android.graphics.drawable.ColorDrawable
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.webkit.MimeTypeMap
|
||||||
import androidx.core.graphics.alpha
|
import androidx.core.graphics.alpha
|
||||||
import androidx.core.graphics.applyCanvas
|
import androidx.core.graphics.applyCanvas
|
||||||
import androidx.core.graphics.blue
|
import androidx.core.graphics.blue
|
||||||
@ -56,6 +57,12 @@ object ImageUtil {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getExtensionFromMimeType(mime: String?): String {
|
||||||
|
return MimeTypeMap.getSingleton().getExtensionFromMimeType(mime)
|
||||||
|
?: SUPPLEMENTARY_MIMETYPE_MAPPING[mime]
|
||||||
|
?: "jpg"
|
||||||
|
}
|
||||||
|
|
||||||
fun isAnimatedAndSupported(stream: InputStream): Boolean {
|
fun isAnimatedAndSupported(stream: InputStream): Boolean {
|
||||||
try {
|
try {
|
||||||
val type = getImageType(stream) ?: return false
|
val type = getImageType(stream) ?: return false
|
||||||
@ -392,4 +399,10 @@ object ImageUtil {
|
|||||||
|
|
||||||
private fun Int.isWhite(): Boolean =
|
private fun Int.isWhite(): Boolean =
|
||||||
red + blue + green > 740
|
red + blue + green > 740
|
||||||
|
|
||||||
|
// Android doesn't include some mappings
|
||||||
|
private val SUPPLEMENTARY_MIMETYPE_MAPPING = mapOf(
|
||||||
|
// https://issuetracker.google.com/issues/182703810
|
||||||
|
"image/jxl" to "jxl",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ open class ExtendedNavigationView @JvmOverloads constructor(
|
|||||||
* @param context any context.
|
* @param context any context.
|
||||||
* @param resId the vector resource to load and tint
|
* @param resId the vector resource to load and tint
|
||||||
*/
|
*/
|
||||||
fun tintVector(context: Context, resId: Int, @AttrRes colorAttrRes: Int = R.attr.colorAccent): Drawable {
|
fun tintVector(context: Context, resId: Int, @AttrRes colorAttrRes: Int = R.attr.colorPrimary): Drawable {
|
||||||
return AppCompatResources.getDrawable(context, resId)!!.apply {
|
return AppCompatResources.getDrawable(context, resId)!!.apply {
|
||||||
setTint(context.getResourceColor(if (enabled) colorAttrRes else R.attr.colorControlNormal))
|
setTint(context.getResourceColor(if (enabled) colorAttrRes else R.attr.colorControlNormal))
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ class QuadStateTextView @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
val tint = if (state == State.UNCHECKED) {
|
val tint = if (state == State.UNCHECKED) {
|
||||||
context.getThemeColor(R.attr.colorControlNormal)
|
context.getThemeColor(R.attr.colorControlNormal)
|
||||||
} else {
|
} else {
|
||||||
context.getThemeColor(R.attr.colorAccent)
|
context.getThemeColor(R.attr.colorPrimary)
|
||||||
}
|
}
|
||||||
if (tint != 0) {
|
if (tint != 0) {
|
||||||
TextViewCompat.setCompoundDrawableTintList(this, ColorStateList.valueOf(tint))
|
TextViewCompat.setCompoundDrawableTintList(this, ColorStateList.valueOf(tint))
|
||||||
|
5
app/src/main/res/color/slider_active_track.xml
Normal file
5
app/src/main/res/color/slider_active_track.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
|
||||||
|
<item android:alpha="@dimen/material_emphasis_disabled" android:color="?attr/colorOnSurface"/>
|
||||||
|
</selector>
|
5
app/src/main/res/color/slider_inactive_track.xml
Normal file
5
app/src/main/res/color/slider_inactive_track.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:alpha="0.24" android:color="?attr/colorPrimary" android:state_enabled="true"/>
|
||||||
|
<item android:alpha="@dimen/material_emphasis_disabled" android:color="?attr/colorOnSurface"/>
|
||||||
|
</selector>
|
@ -1,8 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="108dp"
|
||||||
<item
|
android:height="108dp"
|
||||||
android:width="36dp"
|
android:viewportWidth="108"
|
||||||
android:height="36dp"
|
android:viewportHeight="108">
|
||||||
android:drawable="@drawable/ic_tachi"
|
<path
|
||||||
android:gravity="center" />
|
android:pathData="M50.61,39.254C50.65,40.029 50.691,41.036 50.719,41.513L50.773,42.371L44.96,42.331C41.772,42.303 39.049,42.235 38.926,42.166C38.695,42.058 38.682,42.248 38.682,44.944L38.682,47.831L38.995,47.75C39.893,47.491 43.53,47.395 53.796,47.395C64.064,47.395 67.698,47.491 68.611,47.75L68.911,47.831L68.911,44.944C68.911,42.248 68.897,42.058 68.678,42.166C68.542,42.235 65.819,42.303 62.634,42.331L56.819,42.371L56.873,41.513C56.9,41.036 56.941,40.029 56.981,39.254L57.037,37.864L50.555,37.864L50.61,39.254ZM44.645,49.329C43.23,49.861 42.086,50.377 42.086,50.459C42.086,50.555 42.276,51.044 42.509,51.563C43.597,53.973 45.312,59.937 45.79,62.945C45.87,63.53 46.008,64.008 46.089,64.008C46.171,64.008 47.505,63.572 49.072,63.041C51.1,62.333 51.889,62.006 51.889,61.856C51.889,61.42 49.467,53.551 48.322,50.282C47.805,48.839 47.586,48.349 47.41,48.362C47.287,48.362 46.049,48.798 44.645,49.329Z"
|
||||||
</layer-list>
|
android:fillColor="#000000"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M59.406,49.397C58.957,52.257 57.282,57.785 55.484,62.333L54.545,64.688L37.456,64.688L37.456,70.136L70.544,70.136L70.544,64.688L65.493,64.688C61.503,64.688 60.454,64.648 60.509,64.511C60.55,64.43 60.876,63.708 61.23,62.918C61.571,62.128 62.252,60.426 62.728,59.12C63.641,56.614 65.643,50.364 65.643,49.997C65.643,49.819 65.016,49.614 62.756,49.057C61.163,48.662 59.788,48.349 59.706,48.349C59.624,48.349 59.488,48.825 59.406,49.397Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@id/side_nav"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
@ -35,7 +35,7 @@
|
|||||||
android:background="?attr/colorTertiary"
|
android:background="?attr/colorTertiary"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@id/side_nav"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/appbar"
|
app:layout_constraintTop_toBottomOf="@+id/appbar"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
@ -56,7 +56,7 @@
|
|||||||
android:background="?attr/colorPrimary"
|
android:background="?attr/colorPrimary"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@id/side_nav"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/downloaded_only"
|
app:layout_constraintTop_toBottomOf="@+id/downloaded_only"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
@ -73,11 +73,10 @@
|
|||||||
<com.google.android.material.navigationrail.NavigationRailView
|
<com.google.android.material.navigationrail.NavigationRailView
|
||||||
android:id="@+id/side_nav"
|
android:id="@+id/side_nav"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="0dp"
|
android:layout_height="match_parent"
|
||||||
app:elevation="0dp"
|
android:paddingTop="?attr/actionBarSize"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:elevation="1dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/incognito_mode"
|
|
||||||
app:menu="@menu/main_nav" />
|
app:menu="@menu/main_nav" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
@ -95,9 +95,10 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/left_page_text"
|
android:id="@+id/left_page_text"
|
||||||
android:layout_width="32dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:minWidth="32dp"
|
||||||
android:textColor="?attr/colorOnSurface"
|
android:textColor="?attr/colorOnSurface"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
tools:text="1" />
|
tools:text="1" />
|
||||||
@ -116,9 +117,10 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/right_page_text"
|
android:id="@+id/right_page_text"
|
||||||
android:layout_width="32dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:minWidth="32dp"
|
||||||
android:textColor="?attr/colorOnSurface"
|
android:textColor="?attr/colorOnSurface"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
tools:text="15" />
|
tools:text="15" />
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
android:id="@+id/upper_text"
|
android:id="@+id/upper_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
tools:text="Top" />
|
tools:text="Top" />
|
||||||
|
|
||||||
@ -19,7 +18,7 @@
|
|||||||
android:id="@+id/warning"
|
android:id="@+id/warning"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@ -44,6 +43,7 @@
|
|||||||
android:id="@+id/lower_text"
|
android:id="@+id/lower_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
tools:text="Bottom" />
|
tools:text="Bottom" />
|
||||||
|
|
||||||
|
@ -31,4 +31,9 @@
|
|||||||
android:title="@string/action_open_in_browser"
|
android:title="@string/action_open_in_browser"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_clear_cookies"
|
||||||
|
android:title="@string/pref_clear_cookies"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -250,7 +250,7 @@
|
|||||||
<string name="secure_screen_summary">Ocultar contenido de la aplicación al cambiar entre aplicaciones y bloquear las capturas de pantalla</string>
|
<string name="secure_screen_summary">Ocultar contenido de la aplicación al cambiar entre aplicaciones y bloquear las capturas de pantalla</string>
|
||||||
<string name="secure_screen">Pantalla segura</string>
|
<string name="secure_screen">Pantalla segura</string>
|
||||||
<plurals name="lock_after_mins">
|
<plurals name="lock_after_mins">
|
||||||
<item quantity="one">Después de 1 minuto</item>
|
<item quantity="one">Después de %1$s minuto</item>
|
||||||
<item quantity="other">Después de %1$s minutos</item>
|
<item quantity="other">Después de %1$s minutos</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="lock_never">Nunca</string>
|
<string name="lock_never">Nunca</string>
|
||||||
@ -364,7 +364,7 @@
|
|||||||
<string name="username">Nombre de usuario</string>
|
<string name="username">Nombre de usuario</string>
|
||||||
<string name="login_title">Iniciar sesión en %1$s</string>
|
<string name="login_title">Iniciar sesión en %1$s</string>
|
||||||
<plurals name="download_queue_summary">
|
<plurals name="download_queue_summary">
|
||||||
<item quantity="one">Queda 1</item>
|
<item quantity="one">Queda %1$s</item>
|
||||||
<item quantity="other">Quedan %1$s</item>
|
<item quantity="other">Quedan %1$s</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="downloaded_only_summary">Filtrar todo el manga en tu libreria</string>
|
<string name="downloaded_only_summary">Filtrar todo el manga en tu libreria</string>
|
||||||
@ -416,7 +416,7 @@
|
|||||||
\n\"%1$s\"</string>
|
\n\"%1$s\"</string>
|
||||||
<string name="delete_downloads_for_manga">¿Eliminar capítulos descargados\?</string>
|
<string name="delete_downloads_for_manga">¿Eliminar capítulos descargados\?</string>
|
||||||
<plurals name="manga_num_chapters">
|
<plurals name="manga_num_chapters">
|
||||||
<item quantity="one">1 capítulo</item>
|
<item quantity="one">%1$s capítulo</item>
|
||||||
<item quantity="other">%1$s capítulos</item>
|
<item quantity="other">%1$s capítulos</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="manga_info_collapse">Menos</string>
|
<string name="manga_info_collapse">Menos</string>
|
||||||
@ -448,11 +448,11 @@
|
|||||||
<string name="notification_chapters_single_and_more">Capítulo %1$s y %2$d más</string>
|
<string name="notification_chapters_single_and_more">Capítulo %1$s y %2$d más</string>
|
||||||
<string name="notification_chapters_single">Capítulo %1$s</string>
|
<string name="notification_chapters_single">Capítulo %1$s</string>
|
||||||
<plurals name="notification_chapters_generic">
|
<plurals name="notification_chapters_generic">
|
||||||
<item quantity="one">1 nuevo capítulo</item>
|
<item quantity="one">%1$d nuevo capítulo</item>
|
||||||
<item quantity="other">%1$d nuevos capítulos</item>
|
<item quantity="other">%1$d nuevos capítulos</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="notification_new_chapters_summary">
|
<plurals name="notification_new_chapters_summary">
|
||||||
<item quantity="one">Para 1 título</item>
|
<item quantity="one">Para %d título</item>
|
||||||
<item quantity="other">Para %d títulos</item>
|
<item quantity="other">Para %d títulos</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="notification_new_chapters">Nuevos capítulos encontrados</string>
|
<string name="notification_new_chapters">Nuevos capítulos encontrados</string>
|
||||||
@ -504,7 +504,7 @@
|
|||||||
<string name="pref_category_reading_mode">Modo de lectura</string>
|
<string name="pref_category_reading_mode">Modo de lectura</string>
|
||||||
<string name="pref_category_theme">Tema</string>
|
<string name="pref_category_theme">Tema</string>
|
||||||
<plurals name="num_trackers">
|
<plurals name="num_trackers">
|
||||||
<item quantity="one">1 rastreador</item>
|
<item quantity="one">%d rastreador</item>
|
||||||
<item quantity="other">%d rastreadores</item>
|
<item quantity="other">%d rastreadores</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="channel_errors">Errores</string>
|
<string name="channel_errors">Errores</string>
|
||||||
@ -519,7 +519,7 @@
|
|||||||
<string name="ext_nsfw_short">18+</string>
|
<string name="ext_nsfw_short">18+</string>
|
||||||
<string name="parental_controls_info">Esto no evita que las extensiones no oficiales o potencialmente marcadas incorrectamente muestren contenido para mayores de 18 años dentro de la aplicación.</string>
|
<string name="parental_controls_info">Esto no evita que las extensiones no oficiales o potencialmente marcadas incorrectamente muestren contenido para mayores de 18 años dentro de la aplicación.</string>
|
||||||
<plurals name="missing_chapters_warning">
|
<plurals name="missing_chapters_warning">
|
||||||
<item quantity="one">Omitiendo 1 capítulo, o la fuente no lo encuentra o se ha filtrado</item>
|
<item quantity="one">Omitiendo %d capítulo, o la fuente no lo encuentra o se ha filtrado</item>
|
||||||
<item quantity="other">Omitiendo %d capítulos, o la fuente no los encuentra o se han filtrado</item>
|
<item quantity="other">Omitiendo %d capítulos, o la fuente no los encuentra o se han filtrado</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="share_page_info">%1$s: %2$s, página %3$d</string>
|
<string name="share_page_info">%1$s: %2$s, página %3$d</string>
|
||||||
@ -714,4 +714,5 @@
|
|||||||
<string name="notification_update_skipped">%1$d actualización(es) omitida(s)</string>
|
<string name="notification_update_skipped">%1$d actualización(es) omitida(s)</string>
|
||||||
<string name="rotation_reverse_portrait">Retrato inverso</string>
|
<string name="rotation_reverse_portrait">Retrato inverso</string>
|
||||||
<string name="action_move_to_top_all_for_series">Mover la serie al principio</string>
|
<string name="action_move_to_top_all_for_series">Mover la serie al principio</string>
|
||||||
|
<string name="disabled_nav">Desactivado</string>
|
||||||
</resources>
|
</resources>
|
@ -441,7 +441,7 @@
|
|||||||
<string name="ext_updates_pending">Налични ъпдейти</string>
|
<string name="ext_updates_pending">Налични ъпдейти</string>
|
||||||
<string name="pref_category_display">Показване</string>
|
<string name="pref_category_display">Показване</string>
|
||||||
<string name="hide_notification_content">Скривай съдържанието на уведомленията</string>
|
<string name="hide_notification_content">Скривай съдържанието на уведомленията</string>
|
||||||
<string name="secure_screen_summary">Скрий съдържанието на приложението и блокирай скрийншотове</string>
|
<string name="secure_screen_summary">Скрий съдържанието на приложението и блокирай снимките на екрана</string>
|
||||||
<plurals name="lock_after_mins">
|
<plurals name="lock_after_mins">
|
||||||
<item quantity="one">След 1 минута</item>
|
<item quantity="one">След 1 минута</item>
|
||||||
<item quantity="other">След %1$s минути</item>
|
<item quantity="other">След %1$s минути</item>
|
||||||
@ -723,4 +723,7 @@
|
|||||||
<string name="connected_to_wifi">Само през Wi-Fi</string>
|
<string name="connected_to_wifi">Само през Wi-Fi</string>
|
||||||
<string name="download_queue_size_warning">Предупреждение: големите масови изтегляния могат да доведат до забавяне на източниците и/или блокиране на Tachiyomi</string>
|
<string name="download_queue_size_warning">Предупреждение: големите масови изтегляния могат да доведат до забавяне на източниците и/или блокиране на Tachiyomi</string>
|
||||||
<string name="action_filter_started">Започнати</string>
|
<string name="action_filter_started">Започнати</string>
|
||||||
|
<string name="action_show_manga">Покажи манга</string>
|
||||||
|
<string name="action_faq_and_guides">Често задавани въпроси и ръководства</string>
|
||||||
|
<string name="action_display_cover_only_grid">Решетка само с корици</string>
|
||||||
</resources>
|
</resources>
|
@ -708,10 +708,11 @@
|
|||||||
<string name="skipped_reason_completed">S\'ha omès perquè la sèrie està completada</string>
|
<string name="skipped_reason_completed">S\'ha omès perquè la sèrie està completada</string>
|
||||||
<string name="skipped_reason_not_started">S\'ha omès perquè no hi ha cap capítol llegit</string>
|
<string name="skipped_reason_not_started">S\'ha omès perquè no hi ha cap capítol llegit</string>
|
||||||
<string name="skipped_reason_not_caught_up">S\'ha omès perquè hi ha capítols no llegits</string>
|
<string name="skipped_reason_not_caught_up">S\'ha omès perquè hi ha capítols no llegits</string>
|
||||||
<string name="learn_more">Més informació</string>
|
<string name="learn_more">Premeu per a obtenir més informació</string>
|
||||||
<string name="channel_skipped">Omesa</string>
|
<string name="channel_skipped">Omesa</string>
|
||||||
<string name="notification_update_error">Han fallat %1$d actualitzacions</string>
|
<string name="notification_update_error">Han fallat %1$d actualitzacions</string>
|
||||||
<string name="notification_update_skipped">S\'han omès %1$d actualitzacions</string>
|
<string name="notification_update_skipped">S\'han omès %1$d actualitzacions</string>
|
||||||
<string name="rotation_reverse_portrait">Vertical inversa</string>
|
<string name="rotation_reverse_portrait">Vertical inversa</string>
|
||||||
<string name="action_move_to_top_all_for_series">Mou la sèrie a dalt de tot</string>
|
<string name="action_move_to_top_all_for_series">Mou la sèrie a dalt de tot</string>
|
||||||
|
<string name="disabled_nav">Desactivat</string>
|
||||||
</resources>
|
</resources>
|
@ -723,4 +723,5 @@
|
|||||||
<string name="learn_more">Zjistit více</string>
|
<string name="learn_more">Zjistit více</string>
|
||||||
<string name="skipped_reason_not_started">Přeskočeno, protože nebyly přečteny žádné kapitoly</string>
|
<string name="skipped_reason_not_started">Přeskočeno, protože nebyly přečteny žádné kapitoly</string>
|
||||||
<string name="skipped_reason_completed">Přeskočeno, protože série je dokončena</string>
|
<string name="skipped_reason_completed">Přeskočeno, protože série je dokončena</string>
|
||||||
|
<string name="disabled_nav">Zakázáno</string>
|
||||||
</resources>
|
</resources>
|
@ -6,7 +6,7 @@
|
|||||||
<string name="chapters">Kapitel</string>
|
<string name="chapters">Kapitel</string>
|
||||||
<string name="history">Verlauf</string>
|
<string name="history">Verlauf</string>
|
||||||
<string name="label_settings">Einstellungen</string>
|
<string name="label_settings">Einstellungen</string>
|
||||||
<string name="label_download_queue">Downloadwarteschlange</string>
|
<string name="label_download_queue">Download-Warteschlange</string>
|
||||||
<string name="label_library">Bibliothek</string>
|
<string name="label_library">Bibliothek</string>
|
||||||
<string name="label_recent_manga">Verlauf</string>
|
<string name="label_recent_manga">Verlauf</string>
|
||||||
<string name="label_backup">Sichern und Wiederherstellen</string>
|
<string name="label_backup">Sichern und Wiederherstellen</string>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
<string name="all">Alle</string>
|
<string name="all">Alle</string>
|
||||||
<string name="pref_library_update_restriction">Geräteeinschränkungen für automatische Aktualisierungen</string>
|
<string name="pref_library_update_restriction">Geräteeinschränkungen für automatische Aktualisierungen</string>
|
||||||
<string name="charging">Am Laden</string>
|
<string name="charging">Am Laden</string>
|
||||||
<string name="pref_update_only_non_completed">Ist abgeschlossene Serie</string>
|
<string name="pref_update_only_non_completed">Mit dem Status „Abgeschlossen“</string>
|
||||||
<string name="pref_auto_update_manga_sync">Fortschritt nach dem Lesen aktualisieren</string>
|
<string name="pref_auto_update_manga_sync">Fortschritt nach dem Lesen aktualisieren</string>
|
||||||
<string name="pref_start_screen">Startbildschirm</string>
|
<string name="pref_start_screen">Startbildschirm</string>
|
||||||
<string name="default_category">Standardkategorie</string>
|
<string name="default_category">Standardkategorie</string>
|
||||||
@ -128,7 +128,7 @@
|
|||||||
<string name="pref_remove_after_read">Automatisch nach dem Lesen löschen</string>
|
<string name="pref_remove_after_read">Automatisch nach dem Lesen löschen</string>
|
||||||
<string name="custom_dir">Eigener Speicherort</string>
|
<string name="custom_dir">Eigener Speicherort</string>
|
||||||
<string name="disabled">Deaktiviert</string>
|
<string name="disabled">Deaktiviert</string>
|
||||||
<string name="last_read_chapter">ab zuletzt gelesenem Kapitel</string>
|
<string name="last_read_chapter">Ab zuletzt gelesenem Kapitel</string>
|
||||||
<string name="second_to_last">Ab zweitletzt gelesenem Kapitel</string>
|
<string name="second_to_last">Ab zweitletzt gelesenem Kapitel</string>
|
||||||
<string name="third_to_last">Ab drittletzt gelesenem Kapitel</string>
|
<string name="third_to_last">Ab drittletzt gelesenem Kapitel</string>
|
||||||
<string name="fourth_to_last">Ab viertletzt gelesenem Kapitel</string>
|
<string name="fourth_to_last">Ab viertletzt gelesenem Kapitel</string>
|
||||||
@ -673,7 +673,7 @@
|
|||||||
<string name="pref_verbose_logging_summary">Ausführliche Protokolle im Systemprotokoll ausgeben (verringert die Anwendungsleistung)</string>
|
<string name="pref_verbose_logging_summary">Ausführliche Protokolle im Systemprotokoll ausgeben (verringert die Anwendungsleistung)</string>
|
||||||
<string name="action_display_language_badge">Sprache</string>
|
<string name="action_display_language_badge">Sprache</string>
|
||||||
<string name="label_warning">Warnung</string>
|
<string name="label_warning">Warnung</string>
|
||||||
<string name="notification_size_warning">Achtung: Große Aktualisierungen schaden Quellen und könnten zu langsameren Aktualisierungen sowie höherem Akkuverbrauch führen</string>
|
<string name="notification_size_warning">Große Aktualisierungen schaden Quellen und könnten zu langsameren Aktualisierungen sowie höherem Akkuverbrauch führen</string>
|
||||||
<string name="backup_info">Automatische Sicherungen sind sehr zu empfehlen. Du solltest auch Kopien an anderen Orten aufbewahren.</string>
|
<string name="backup_info">Automatische Sicherungen sind sehr zu empfehlen. Du solltest auch Kopien an anderen Orten aufbewahren.</string>
|
||||||
<string name="connected_to_wifi">Nur über WLAN</string>
|
<string name="connected_to_wifi">Nur über WLAN</string>
|
||||||
<string name="update_72hour">Alle 3 Tage</string>
|
<string name="update_72hour">Alle 3 Tage</string>
|
||||||
@ -686,8 +686,8 @@
|
|||||||
<string name="database_clean">Datenbank bereinigt</string>
|
<string name="database_clean">Datenbank bereinigt</string>
|
||||||
<string name="extension_api_error">Herunterladen der Erweiterungsliste ist fehlgeschlagen</string>
|
<string name="extension_api_error">Herunterladen der Erweiterungsliste ist fehlgeschlagen</string>
|
||||||
<string name="privacy_policy">Datenschutzbestimmungen</string>
|
<string name="privacy_policy">Datenschutzbestimmungen</string>
|
||||||
<string name="pref_update_only_completely_read">Hat ungelesene Kapitel</string>
|
<string name="pref_update_only_completely_read">Mit ungelesenen Kapiteln</string>
|
||||||
<string name="pref_library_update_manga_restriction">Aktualisierung überspringen</string>
|
<string name="pref_library_update_manga_restriction">Aktualisierung der Titel überspringen</string>
|
||||||
<string name="library_errors_help">Für Hilfe zum Beheben von Fehlern bei Bibliotheksaktualisierungen, siehe %1$s</string>
|
<string name="library_errors_help">Für Hilfe zum Beheben von Fehlern bei Bibliotheksaktualisierungen, siehe %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">Als CBZ-Archiv speichern</string>
|
<string name="save_chapter_as_cbz">Als CBZ-Archiv speichern</string>
|
||||||
<string name="cancelled">Abgebrochen</string>
|
<string name="cancelled">Abgebrochen</string>
|
||||||
@ -704,15 +704,17 @@
|
|||||||
<string name="pref_landscape_zoom">Bild im Querformat vergrößern</string>
|
<string name="pref_landscape_zoom">Bild im Querformat vergrößern</string>
|
||||||
<string name="pref_navigate_pan">Innerhalb der Seite navigieren</string>
|
<string name="pref_navigate_pan">Innerhalb der Seite navigieren</string>
|
||||||
<string name="action_filter_started">Angefangen</string>
|
<string name="action_filter_started">Angefangen</string>
|
||||||
<string name="pref_update_only_started">Keine gelesenen Kapitel</string>
|
<string name="pref_update_only_started">Die noch nicht begonnen wurden</string>
|
||||||
<string name="skipped_reason_completed">Übersprungen, da die Serie abgeschlossen ist</string>
|
<string name="skipped_reason_completed">Übersprungen, da die Serie abgeschlossen ist</string>
|
||||||
<string name="skipped_reason_not_caught_up">Übersprungen, weil es ungelesene Kapitel gibt</string>
|
<string name="skipped_reason_not_caught_up">Übersprungen, weil es ungelesene Kapitel gibt</string>
|
||||||
<string name="skipped_reason_not_started">Übersprungen, weil keine Kapitel gelesen wurden</string>
|
<string name="skipped_reason_not_started">Übersprungen, weil keine Kapitel gelesen wurden</string>
|
||||||
<string name="notification_update_error">%1$d Aktualisierung(en) fehlgeschlagen</string>
|
<string name="notification_update_error">%1$d Aktualisierung(en) fehlgeschlagen</string>
|
||||||
<string name="notification_update_skipped">%1$d Aktualisierung(en) übersprungen</string>
|
<string name="notification_update_skipped">%1$d Aktualisierung(en) übersprungen</string>
|
||||||
<string name="channel_skipped">Übersprungen</string>
|
<string name="channel_skipped">Übersprungen</string>
|
||||||
<string name="learn_more">Mehr erfahren</string>
|
<string name="learn_more">Antippen, um mehr zu erfahren</string>
|
||||||
<string name="rotation_reverse_portrait">Umgekehrtes Hochformat</string>
|
<string name="rotation_reverse_portrait">Umgekehrtes Hochformat</string>
|
||||||
<string name="action_move_to_top_all_for_series">Serie nach oben verschieben</string>
|
<string name="action_move_to_top_all_for_series">Serie nach oben verschieben</string>
|
||||||
<string name="disabled_nav">Deaktiviert</string>
|
<string name="disabled_nav">Deaktiviert</string>
|
||||||
|
<string name="error_saving_picture">Fehler beim Speichern des Bildes</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">Eine neue Version ist aus dem offiziellen Repository verfügbar. Tippe, um zu erfahren, wie man aus inoffiziellen F-Droid-Versionen migriert.</string>
|
||||||
</resources>
|
</resources>
|
@ -87,7 +87,7 @@
|
|||||||
<string name="all">Όλα</string>
|
<string name="all">Όλα</string>
|
||||||
<string name="pref_library_update_restriction">Περιορισμοί αυτόματων ενημερώσεων συσκευής</string>
|
<string name="pref_library_update_restriction">Περιορισμοί αυτόματων ενημερώσεων συσκευής</string>
|
||||||
<string name="charging">Φορτίζει</string>
|
<string name="charging">Φορτίζει</string>
|
||||||
<string name="pref_update_only_non_completed">Ολοκληρωμένη σειρά</string>
|
<string name="pref_update_only_non_completed">Με κατάσταση \"Ολοκληρωμένο\"</string>
|
||||||
<string name="pref_auto_update_manga_sync">Ενημέρωση προόδου μετά την ανάγνωση</string>
|
<string name="pref_auto_update_manga_sync">Ενημέρωση προόδου μετά την ανάγνωση</string>
|
||||||
<string name="pref_start_screen">Οθόνη εκκίνησης</string>
|
<string name="pref_start_screen">Οθόνη εκκίνησης</string>
|
||||||
<string name="default_category">Προεπιλεγμένη κατηγορία</string>
|
<string name="default_category">Προεπιλεγμένη κατηγορία</string>
|
||||||
@ -686,8 +686,8 @@
|
|||||||
<string name="database_clean">Καθαρισμός βάσης δεδομένων</string>
|
<string name="database_clean">Καθαρισμός βάσης δεδομένων</string>
|
||||||
<string name="extension_api_error">Απέτυχε η λήψη λίστας επεκτάσεων</string>
|
<string name="extension_api_error">Απέτυχε η λήψη λίστας επεκτάσεων</string>
|
||||||
<string name="privacy_policy">Πολιτική απορρήτου</string>
|
<string name="privacy_policy">Πολιτική απορρήτου</string>
|
||||||
<string name="pref_library_update_manga_restriction">Παράλειψη ενημέρωσης</string>
|
<string name="pref_library_update_manga_restriction">Παράλειψη ενημέρωσης τίτλων</string>
|
||||||
<string name="pref_update_only_completely_read">Έχει αδιάβαστα κεφάλαια</string>
|
<string name="pref_update_only_completely_read">Με αδιάβαστο(α) κεφάλαιο(α)</string>
|
||||||
<string name="library_errors_help">Για βοήθεια σχετικά με τον τρόπο διόρθωσης σφαλμάτων ενημέρωσης βιβλιοθήκης, ανατρέξτε στο %1$s</string>
|
<string name="library_errors_help">Για βοήθεια σχετικά με τον τρόπο διόρθωσης σφαλμάτων ενημέρωσης βιβλιοθήκης, ανατρέξτε στο %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">Αποθήκευση ως αρχείο CBZ</string>
|
<string name="save_chapter_as_cbz">Αποθήκευση ως αρχείο CBZ</string>
|
||||||
<string name="cancelled">Ακυρώθηκε</string>
|
<string name="cancelled">Ακυρώθηκε</string>
|
||||||
@ -703,16 +703,18 @@
|
|||||||
\nΘέλετε ακόμα να συνεχίσετε;</string>
|
\nΘέλετε ακόμα να συνεχίσετε;</string>
|
||||||
<string name="action_display_cover_only_grid">Πλέγμα μόνο με εξώφυλλα</string>
|
<string name="action_display_cover_only_grid">Πλέγμα μόνο με εξώφυλλα</string>
|
||||||
<string name="action_filter_started">Ξεκίνησε</string>
|
<string name="action_filter_started">Ξεκίνησε</string>
|
||||||
<string name="pref_update_only_started">Δεν έχει διαβασμένα κεφάλαια</string>
|
<string name="pref_update_only_started">Που δεν έχουν ξεκινήσει</string>
|
||||||
<string name="pref_navigate_pan">Πλοήγηση για οριζόντια μετακίνηση</string>
|
<string name="pref_navigate_pan">Πλοήγηση για οριζόντια μετακίνηση</string>
|
||||||
<string name="skipped_reason_completed">Παραλείφθηκε επειδή η σειρά ολοκληρώθηκε</string>
|
<string name="skipped_reason_completed">Παραλείφθηκε επειδή η σειρά ολοκληρώθηκε</string>
|
||||||
<string name="skipped_reason_not_caught_up">Παραβλέφθηκε επειδή υπάρχουν μη αναγνωσμένα κεφάλαια</string>
|
<string name="skipped_reason_not_caught_up">Παραβλέφθηκε επειδή υπάρχουν μη αναγνωσμένα κεφάλαια</string>
|
||||||
<string name="skipped_reason_not_started">Παραλείπεται επειδή δεν έχουν διαβαστεί κεφάλαια</string>
|
<string name="skipped_reason_not_started">Παραλείπεται επειδή δεν έχουν διαβαστεί κεφάλαια</string>
|
||||||
<string name="notification_update_error">%1$d ενημέρωση(ες) απέτυχε(-αν)</string>
|
<string name="notification_update_error">%1$d ενημέρωση(ες) απέτυχε(-αν)</string>
|
||||||
<string name="learn_more">Μάθετε περισσότερα</string>
|
<string name="learn_more">Πατήστε για να μάθετε περισσότερα</string>
|
||||||
<string name="channel_skipped">Παραλήφθηκαν</string>
|
<string name="channel_skipped">Παραλήφθηκαν</string>
|
||||||
<string name="notification_update_skipped">%1$d ενημέρωση(εις) παραλείφθηκε(-αν)</string>
|
<string name="notification_update_skipped">%1$d ενημέρωση(εις) παραλείφθηκε(-αν)</string>
|
||||||
<string name="rotation_reverse_portrait">Αντίστροφο πορτρέτο</string>
|
<string name="rotation_reverse_portrait">Αντίστροφο πορτρέτο</string>
|
||||||
<string name="action_move_to_top_all_for_series">Μετακίνηση σειράς στην κορυφή</string>
|
<string name="action_move_to_top_all_for_series">Μετακίνηση σειράς στην κορυφή</string>
|
||||||
<string name="disabled_nav">Απενεργοποιημένο</string>
|
<string name="disabled_nav">Απενεργοποιημένο</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">Μια νέα έκδοση είναι διαθέσιμη από τις επίσημες κυκλοφορίες. Πατήστε για να μάθετε πώς να μεταβείτε από ανεπίσημες κυκλοφορίες του F-Droid.</string>
|
||||||
|
<string name="error_saving_picture">Σφάλμα κατά την αποθήκευση της εικόνας</string>
|
||||||
</resources>
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="name">Nombre</string>
|
<string name="name">Español</string>
|
||||||
<!-- Activities and fragments labels (toolbar title) -->
|
<!-- Activities and fragments labels (toolbar title) -->
|
||||||
<string name="label_settings">Ajustes</string>
|
<string name="label_settings">Ajustes</string>
|
||||||
<string name="label_download_queue">Cola de descargas</string>
|
<string name="label_download_queue">Cola de descargas</string>
|
||||||
@ -63,7 +63,7 @@
|
|||||||
<string name="update_48hour">Cada 2 días</string>
|
<string name="update_48hour">Cada 2 días</string>
|
||||||
<string name="pref_library_update_restriction">Restricciones de actualización automática del dispositivo</string>
|
<string name="pref_library_update_restriction">Restricciones de actualización automática del dispositivo</string>
|
||||||
<string name="charging">Mientras se carga la batería</string>
|
<string name="charging">Mientras se carga la batería</string>
|
||||||
<string name="pref_update_only_non_completed">Serie completada</string>
|
<string name="pref_update_only_non_completed">Series completadas</string>
|
||||||
<string name="pref_auto_update_manga_sync">Actualizar progreso al terminar un capítulo</string>
|
<string name="pref_auto_update_manga_sync">Actualizar progreso al terminar un capítulo</string>
|
||||||
<!-- Reader section -->
|
<!-- Reader section -->
|
||||||
<string name="pref_fullscreen">Pantalla completa</string>
|
<string name="pref_fullscreen">Pantalla completa</string>
|
||||||
@ -644,7 +644,7 @@
|
|||||||
<string name="information_empty_category_dialog">Todavía no existen categorías.</string>
|
<string name="information_empty_category_dialog">Todavía no existen categorías.</string>
|
||||||
<string name="notification_updating">Actualizando biblioteca… (%1$d/%2$d)</string>
|
<string name="notification_updating">Actualizando biblioteca… (%1$d/%2$d)</string>
|
||||||
<string name="error_no_match">No se han encontrado coincidencias</string>
|
<string name="error_no_match">No se han encontrado coincidencias</string>
|
||||||
<string name="source_unsupported">No se admite el origen</string>
|
<string name="source_unsupported">Fuente no soportada</string>
|
||||||
<string name="unread">No leídos</string>
|
<string name="unread">No leídos</string>
|
||||||
<string name="tracker_komga_warning">Este servicio de seguimiento sólo es compatible con la fuente Komga.</string>
|
<string name="tracker_komga_warning">Este servicio de seguimiento sólo es compatible con la fuente Komga.</string>
|
||||||
<string name="error_sharing_cover">Error al compartir portada</string>
|
<string name="error_sharing_cover">Error al compartir portada</string>
|
||||||
@ -703,7 +703,7 @@
|
|||||||
<string name="pref_verbose_logging">Registro detallado</string>
|
<string name="pref_verbose_logging">Registro detallado</string>
|
||||||
<string name="pref_verbose_logging_summary">Mostrar registros detallados en el registro del sistema (reduce el rendimiento de la aplicación)</string>
|
<string name="pref_verbose_logging_summary">Mostrar registros detallados en el registro del sistema (reduce el rendimiento de la aplicación)</string>
|
||||||
<string name="label_warning">Advertencia</string>
|
<string name="label_warning">Advertencia</string>
|
||||||
<string name="notification_size_warning">Cuidado: las actualizaciones grandes pueden implicar un mayor uso de la batería y que los distintos servicios bloqueen o ralenticen el acceso a tu dispositivo</string>
|
<string name="notification_size_warning">Las actualizaciones grandes pueden implicar un mayor uso de la batería y que los distintos servicios bloqueen o ralenticen el acceso a tu dispositivo</string>
|
||||||
<string name="action_display_language_badge">Idioma</string>
|
<string name="action_display_language_badge">Idioma</string>
|
||||||
<string name="backup_info">Es una buena idea tener copias de respaldo automáticas, así como respaldarlas fuera de tu dispositivo.</string>
|
<string name="backup_info">Es una buena idea tener copias de respaldo automáticas, así como respaldarlas fuera de tu dispositivo.</string>
|
||||||
<string name="connected_to_wifi">Solo con Wi-Fi</string>
|
<string name="connected_to_wifi">Solo con Wi-Fi</string>
|
||||||
@ -717,8 +717,8 @@
|
|||||||
<string name="clear_database_source_item_count">Hay %1$d manga que no pertenece a la biblioteca en la base de datos</string>
|
<string name="clear_database_source_item_count">Hay %1$d manga que no pertenece a la biblioteca en la base de datos</string>
|
||||||
<string name="extension_api_error">No se pudo descargar el listado de extensiones</string>
|
<string name="extension_api_error">No se pudo descargar el listado de extensiones</string>
|
||||||
<string name="privacy_policy">Política de privacidad</string>
|
<string name="privacy_policy">Política de privacidad</string>
|
||||||
<string name="pref_update_only_completely_read">Capítulos sin leer</string>
|
<string name="pref_update_only_completely_read">Con capítulos sin leer</string>
|
||||||
<string name="pref_library_update_manga_restriction">Omitir la actualización</string>
|
<string name="pref_library_update_manga_restriction">Omitir actualizaciones</string>
|
||||||
<string name="library_errors_help">Si necesitas ayuda para resolver los errores de actualización de la biblioteca mira en %1$s</string>
|
<string name="library_errors_help">Si necesitas ayuda para resolver los errores de actualización de la biblioteca mira en %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">Guardar como archivo CBZ</string>
|
<string name="save_chapter_as_cbz">Guardar como archivo CBZ</string>
|
||||||
<string name="on_hiatus">En pausa</string>
|
<string name="on_hiatus">En pausa</string>
|
||||||
@ -735,15 +735,17 @@
|
|||||||
\n
|
\n
|
||||||
\n¿Quieres seguir\?</string>
|
\n¿Quieres seguir\?</string>
|
||||||
<string name="action_filter_started">Empezados</string>
|
<string name="action_filter_started">Empezados</string>
|
||||||
<string name="pref_update_only_started">Sin capítulos leídos</string>
|
<string name="pref_update_only_started">Series sin empezar</string>
|
||||||
<string name="skipped_reason_completed">Omitido porque la serie está completa</string>
|
<string name="skipped_reason_completed">Omitido porque la serie está completa</string>
|
||||||
<string name="skipped_reason_not_caught_up">Omitido porque hay capítulos sin leer</string>
|
<string name="skipped_reason_not_caught_up">Omitido porque hay capítulos sin leer</string>
|
||||||
<string name="skipped_reason_not_started">Omitido porque no hay capítulos leídos</string>
|
<string name="skipped_reason_not_started">Omitido porque no hay capítulos leídos</string>
|
||||||
<string name="learn_more">Más información</string>
|
<string name="learn_more">Ver más detalles</string>
|
||||||
<string name="channel_skipped">Omitidas</string>
|
<string name="channel_skipped">Omitidas</string>
|
||||||
<string name="notification_update_error">Actualizaciones fallidas: %1$d</string>
|
<string name="notification_update_error">Actualizaciones fallidas: %1$d</string>
|
||||||
<string name="notification_update_skipped">Actualizaciones omitidas: %1$d</string>
|
<string name="notification_update_skipped">Actualizaciones omitidas: %1$d</string>
|
||||||
<string name="rotation_reverse_portrait">En vertical, al revés</string>
|
<string name="rotation_reverse_portrait">En vertical, al revés</string>
|
||||||
<string name="action_move_to_top_all_for_series">Mover al primer puesto</string>
|
<string name="action_move_to_top_all_for_series">Mover al primer puesto</string>
|
||||||
<string name="disabled_nav">Desactivado</string>
|
<string name="disabled_nav">Desactivado</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">Hay una actualización disponible en la página oficial. Toca para aprender a migrar desde una versión no oficial de F-Droid.</string>
|
||||||
|
<string name="error_saving_picture">No se ha podido guardar la imagen</string>
|
||||||
</resources>
|
</resources>
|
@ -62,7 +62,7 @@
|
|||||||
<string name="information_no_downloads">Ei latauksia</string>
|
<string name="information_no_downloads">Ei latauksia</string>
|
||||||
<string name="information_no_recent">Ei viimeisimpiä päivityksiä</string>
|
<string name="information_no_recent">Ei viimeisimpiä päivityksiä</string>
|
||||||
<string name="information_no_recent_manga">Ei mitään luettu viime aikoina</string>
|
<string name="information_no_recent_manga">Ei mitään luettu viime aikoina</string>
|
||||||
<string name="information_empty_library">Kirjastosi on tyhjä. Lisää sarjoja kirjastoosi Selaa-kohdasta.</string>
|
<string name="information_empty_library">Kirjastosi on tyhjä.</string>
|
||||||
<string name="information_empty_category">Sinulla ei ole kategorioita. Napauta pluspainiketta, jos haluat luoda sellaisen kirjaston järjestämistä varten.</string>
|
<string name="information_empty_category">Sinulla ei ole kategorioita. Napauta pluspainiketta, jos haluat luoda sellaisen kirjaston järjestämistä varten.</string>
|
||||||
<string name="download_notifier_downloader_title">Lataaja</string>
|
<string name="download_notifier_downloader_title">Lataaja</string>
|
||||||
<string name="download_notifier_title_error">Virhe</string>
|
<string name="download_notifier_title_error">Virhe</string>
|
||||||
@ -104,7 +104,7 @@
|
|||||||
<string name="action_display">Näkymä</string>
|
<string name="action_display">Näkymä</string>
|
||||||
<string name="action_display_grid">Kompakti ruudukko</string>
|
<string name="action_display_grid">Kompakti ruudukko</string>
|
||||||
<string name="action_display_list">Lista</string>
|
<string name="action_display_list">Lista</string>
|
||||||
<string name="action_display_download_badge">Näytä ladattujen määrä</string>
|
<string name="action_display_download_badge">Ladatut luvut</string>
|
||||||
<string name="action_cancel">Peruuta</string>
|
<string name="action_cancel">Peruuta</string>
|
||||||
<string name="action_sort">Järjestä</string>
|
<string name="action_sort">Järjestä</string>
|
||||||
<string name="action_install">Asenna</string>
|
<string name="action_install">Asenna</string>
|
||||||
@ -125,17 +125,17 @@
|
|||||||
<string name="pref_library_columns">Kohteita per rivi</string>
|
<string name="pref_library_columns">Kohteita per rivi</string>
|
||||||
<string name="portrait">Pystysuunta</string>
|
<string name="portrait">Pystysuunta</string>
|
||||||
<string name="landscape">Vaakataso</string>
|
<string name="landscape">Vaakataso</string>
|
||||||
<string name="pref_library_update_interval">Päivitystiheys</string>
|
<string name="pref_library_update_interval">Automaattinen päivitys</string>
|
||||||
<string name="update_never">Manuaalinen</string>
|
<string name="update_never">Pois</string>
|
||||||
<string name="update_6hour">Kuuden tunnin välein</string>
|
<string name="update_6hour">Kuuden tunnin välein</string>
|
||||||
<string name="update_12hour">12 tunnin välein</string>
|
<string name="update_12hour">12 tunnin välein</string>
|
||||||
<string name="update_24hour">Päivittäin</string>
|
<string name="update_24hour">Päivittäin</string>
|
||||||
<string name="update_48hour">Kahden päivän välein</string>
|
<string name="update_48hour">Kahden päivän välein</string>
|
||||||
<string name="update_weekly">Viikoittain</string>
|
<string name="update_weekly">Viikoittain</string>
|
||||||
<string name="all">Kaikki</string>
|
<string name="all">Kaikki</string>
|
||||||
<string name="pref_library_update_restriction">Päivityksen rajoitukset</string>
|
<string name="pref_library_update_restriction">Automaattisen päivityksen laitteistorajoitukset</string>
|
||||||
<string name="charging">Latauksessa</string>
|
<string name="charging">Latauksessa</string>
|
||||||
<string name="pref_update_only_non_completed">Päivitä vain jatkuvat sarjat</string>
|
<string name="pref_update_only_non_completed">Sarja on päättynyt</string>
|
||||||
<string name="pref_auto_update_manga_sync">Päivitä luvun edistyminen lukemisen jälkeen</string>
|
<string name="pref_auto_update_manga_sync">Päivitä luvun edistyminen lukemisen jälkeen</string>
|
||||||
<string name="pref_start_screen">Aloitusnäyttö</string>
|
<string name="pref_start_screen">Aloitusnäyttö</string>
|
||||||
<string name="default_category">Oletus kategoria</string>
|
<string name="default_category">Oletus kategoria</string>
|
||||||
@ -372,7 +372,7 @@
|
|||||||
<string name="notification_check_updates">Etsitään uusia lukuja</string>
|
<string name="notification_check_updates">Etsitään uusia lukuja</string>
|
||||||
<string name="lock_when_idle">Lukitse käyttämättömänä</string>
|
<string name="lock_when_idle">Lukitse käyttämättömänä</string>
|
||||||
<string name="secure_screen">Salaa näyttö</string>
|
<string name="secure_screen">Salaa näyttö</string>
|
||||||
<string name="secure_screen_summary">Piilota sovelluksen sisältö kun sovelluksia vaihdetaan ja estä kuvakaappauksien otto</string>
|
<string name="secure_screen_summary">Turvallinen ruutu piilottaa sovelluksen sisällön sovelluksia vaihdettaessa ja estää kuvakaappauksen ottamisen</string>
|
||||||
<string name="pref_disable_battery_optimization">Poista akun optimointi käytöstä</string>
|
<string name="pref_disable_battery_optimization">Poista akun optimointi käytöstä</string>
|
||||||
<string name="pref_disable_battery_optimization_summary">Auttaa taustalla pyörivien kirjaston päivitysten ja varmuuskopioiden kanssa</string>
|
<string name="pref_disable_battery_optimization_summary">Auttaa taustalla pyörivien kirjaston päivitysten ja varmuuskopioiden kanssa</string>
|
||||||
<string name="battery_optimization_disabled">Akun optimointi on jo poistettu käytöstä</string>
|
<string name="battery_optimization_disabled">Akun optimointi on jo poistettu käytöstä</string>
|
||||||
@ -451,7 +451,7 @@
|
|||||||
<item quantity="other">Valmistui %1$s virheitä löytyi %2$s</item>
|
<item quantity="other">Valmistui %1$s virheitä löytyi %2$s</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_true_color_summary">Vähentää juovia, mutta vaikuttaa suorituskykyyn</string>
|
<string name="pref_true_color_summary">Vähentää juovia, mutta vaikuttaa suorituskykyyn</string>
|
||||||
<string name="action_display_unread_badge">Näytä lukemattomien määrä</string>
|
<string name="action_display_unread_badge">Lukemattomat</string>
|
||||||
<string name="viewer">Lukutila</string>
|
<string name="viewer">Lukutila</string>
|
||||||
<string name="battery_optimization_setting_activity_not_found">Laiteasetuksia ei voitu avata</string>
|
<string name="battery_optimization_setting_activity_not_found">Laiteasetuksia ei voitu avata</string>
|
||||||
<string name="tracking_info">Yksisuuntainen synkronointi lukujen seurantapalveluiden päivittämiseksi. Määritä yksittäisten mangamerkintöjen seuranta seurantapainikkeesta.</string>
|
<string name="tracking_info">Yksisuuntainen synkronointi lukujen seurantapalveluiden päivittämiseksi. Määritä yksittäisten mangamerkintöjen seuranta seurantapainikkeesta.</string>
|
||||||
@ -542,7 +542,7 @@
|
|||||||
<string name="spen_previous_page">Edellinen sivu</string>
|
<string name="spen_previous_page">Edellinen sivu</string>
|
||||||
<string name="migration_help_guide">Lähteen siirto-opas</string>
|
<string name="migration_help_guide">Lähteen siirto-opas</string>
|
||||||
<string name="pref_category_nsfw_content">NSFW (18+) lähteet</string>
|
<string name="pref_category_nsfw_content">NSFW (18+) lähteet</string>
|
||||||
<string name="pref_show_nsfw_source">Näytä lähdeluettelossa</string>
|
<string name="pref_show_nsfw_source">Näytä lähde- ja lisäosaluettelossa</string>
|
||||||
<string name="file_picker_error">Tiedostonvalitsinsovellusta ei löytynyt</string>
|
<string name="file_picker_error">Tiedostonvalitsinsovellusta ei löytynyt</string>
|
||||||
<string name="myanimelist_relogin">Kirjaudu uudelleen MAL: iin</string>
|
<string name="myanimelist_relogin">Kirjaudu uudelleen MAL: iin</string>
|
||||||
<string name="pref_viewer_nav">Navigointiasettelu</string>
|
<string name="pref_viewer_nav">Navigointiasettelu</string>
|
||||||
@ -582,7 +582,7 @@
|
|||||||
<string name="pref_download_new_categories_details">Poissuljettuihin kategorioihin kuuluvia mangoja ei ladata, vaikka ne olisivat myös sisällytetyissä kategorioissa.</string>
|
<string name="pref_download_new_categories_details">Poissuljettuihin kategorioihin kuuluvia mangoja ei ladata, vaikka ne olisivat myös sisällytetyissä kategorioissa.</string>
|
||||||
<string name="pref_category_auto_download">Automaattinen lataus</string>
|
<string name="pref_category_auto_download">Automaattinen lataus</string>
|
||||||
<string name="pref_library_update_categories_details">Poissuljettuihin kategorioihin sisältyvää mangaa ei päivitetä, vaikka ne olisivat myös sisällytetyissä kategorioissa.</string>
|
<string name="pref_library_update_categories_details">Poissuljettuihin kategorioihin sisältyvää mangaa ei päivitetä, vaikka ne olisivat myös sisällytetyissä kategorioissa.</string>
|
||||||
<string name="action_show_errors">Näytä virheet</string>
|
<string name="action_show_errors">Näytä lisätiedot</string>
|
||||||
<string name="update_check_eol">Tätä Android-versiota ei enää tueta</string>
|
<string name="update_check_eol">Tätä Android-versiota ei enää tueta</string>
|
||||||
<string name="clipboard_copy_error">Kopiointi leikepöydälle epäonnistui</string>
|
<string name="clipboard_copy_error">Kopiointi leikepöydälle epäonnistui</string>
|
||||||
<string name="rotation_landscape">Vaakatasossa</string>
|
<string name="rotation_landscape">Vaakatasossa</string>
|
||||||
@ -606,4 +606,63 @@
|
|||||||
<string name="on">Päällä</string>
|
<string name="on">Päällä</string>
|
||||||
<string name="getting_started_guide">Aloitusopas</string>
|
<string name="getting_started_guide">Aloitusopas</string>
|
||||||
<string name="download_queue_size_warning">Varoitus: massalataukset voivat johtaa siihen, että lähteet muuttuvat hitaammiksi käyttää ja/tai ne estävät Tachiyomin käytön</string>
|
<string name="download_queue_size_warning">Varoitus: massalataukset voivat johtaa siihen, että lähteet muuttuvat hitaammiksi käyttää ja/tai ne estävät Tachiyomin käytön</string>
|
||||||
|
<string name="pref_library_update_show_tab_badge">Näytä lukemattomien määrä päivitys ikoneissa</string>
|
||||||
|
<string name="alignment_center">Keskimmäinen</string>
|
||||||
|
<string name="pref_library_update_refresh_trackers_summary">Päivitä seurantapalvelimet kirjaston päivityksen yhteydessä</string>
|
||||||
|
<plurals name="relative_time">
|
||||||
|
<item quantity="one">Eilen</item>
|
||||||
|
<item quantity="other">%1$d päivää sitten</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="action_show_manga">Näytä manga</string>
|
||||||
|
<string name="action_display_cover_only_grid">Kansikuva ruudukko</string>
|
||||||
|
<string name="theme_monet">Dynaaminen</string>
|
||||||
|
<string name="theme_greenapple">Vihreä omena</string>
|
||||||
|
<string name="alignment_bottom">Alin</string>
|
||||||
|
<string name="recently">Viimeaikoina</string>
|
||||||
|
<string name="label_default">Oletus</string>
|
||||||
|
<string name="action_filter_started">Aloitettu</string>
|
||||||
|
<string name="action_display_local_badge">Laitteelle tallennettu manga</string>
|
||||||
|
<string name="pref_library_update_refresh_trackers">Päivitä seurantapalvelimet automaattisesti</string>
|
||||||
|
<string name="action_sort_count">Yhteenlaskettu manga</string>
|
||||||
|
<string name="action_start_downloading_now">Aloita lataaminen nyt</string>
|
||||||
|
<string name="theme_yinyang">Ying ja Yang</string>
|
||||||
|
<string name="theme_midnightdusk">Keskiyön hämärä</string>
|
||||||
|
<string name="theme_strawberrydaiquiri">Mansikka Daiquiri</string>
|
||||||
|
<string name="pref_category_appearance">Ulkonäkö</string>
|
||||||
|
<string name="theme_tealturquoise">Sinivihreä ja turkoosi</string>
|
||||||
|
<string name="theme_yotsuba">Yotsuba</string>
|
||||||
|
<string name="alignment_top">Päällimmäinen</string>
|
||||||
|
<string name="pref_side_nav_icon_alignment">Sivunavigaation kuvakkeiden kohdistus</string>
|
||||||
|
<string name="pref_dark_theme_pure_black">Täysin musta pimeätila</string>
|
||||||
|
<string name="pref_category_navigation">Navigaatio</string>
|
||||||
|
<string name="pref_update_only_started">Ei lukemattomia lukuja</string>
|
||||||
|
<string name="pref_relative_format">Suhteelliset aikamerkit</string>
|
||||||
|
<string name="pref_relative_time_short">Lyhyt (tänään, eilen)</string>
|
||||||
|
<string name="pref_relative_time_long">Pitkä (lyhyt+, N päivää sitten)</string>
|
||||||
|
<string name="relative_time_today">Tänään</string>
|
||||||
|
<string name="pref_update_only_completely_read">Sarjalla on lukemattomia kappaleita</string>
|
||||||
|
<string name="pref_app_theme">Sovelluksen teema</string>
|
||||||
|
<string name="label_warning">Varoitus</string>
|
||||||
|
<string name="confirm_lock_change">Tunnistaudu vahvistaaksesi muutokset</string>
|
||||||
|
<string name="action_display_language_badge">Kieli</string>
|
||||||
|
<string name="pref_category_timestamps">Aikaleimat</string>
|
||||||
|
<string name="action_faq_and_guides">Usein kysytyt kysymykset ja oppaat</string>
|
||||||
|
<string name="pref_library_update_manga_restriction">Ohita päivitys</string>
|
||||||
|
<string name="action_move_to_top_all_for_series">Siirrä sarja päällimmäiseksi</string>
|
||||||
|
<string name="theme_tako">Tako</string>
|
||||||
|
<string name="update_72hour">Joka 3. Päivä</string>
|
||||||
|
<string name="connected_to_wifi">Ainoastaan WiFillä</string>
|
||||||
|
<string name="pref_inverted_colors">Käänteisväri</string>
|
||||||
|
<string name="webtoon_side_padding_5">5%</string>
|
||||||
|
<string name="ext_app_info">Sovelluksen tiedot</string>
|
||||||
|
<string name="ext_installer_legacy">Perinteinen</string>
|
||||||
|
<string name="rotation_reverse_portrait">Käänteinen kuva</string>
|
||||||
|
<string name="categorized_display_settings">Kategoria kohtaiset asetukset lajittelulle ja näytölle</string>
|
||||||
|
<string name="ext_installer_shizuku_stopped">Shizuku on pysähtynyt</string>
|
||||||
|
<string name="disabled_nav">Poistettu käytöstä</string>
|
||||||
|
<string name="ext_installer_shizuku_unavailable_dialog">Asenna ja aja Shizuku käyttääksesi Shizukua laajennusten asentamiseen</string>
|
||||||
|
<string name="ext_update_all">Päivitä kaikki</string>
|
||||||
|
<string name="extension_api_error">Laajennusluettelon halu epäonnistui</string>
|
||||||
|
<string name="ext_install_service_notif">Asennetaan laajennusta…</string>
|
||||||
|
<string name="ext_installer_pref">Asentaja</string>
|
||||||
</resources>
|
</resources>
|
@ -520,7 +520,7 @@
|
|||||||
<string name="ext_nsfw_short">18+</string>
|
<string name="ext_nsfw_short">18+</string>
|
||||||
<plurals name="missing_chapters_warning">
|
<plurals name="missing_chapters_warning">
|
||||||
<item quantity="one">Lalaktawan ang %d kabanata, siguro baka wala sa source ito, o baka nasala ito</item>
|
<item quantity="one">Lalaktawan ang %d kabanata, siguro baka wala sa source ito, o baka nasala ito</item>
|
||||||
<item quantity="other">Lalaktawan ang %d (na) kabanata, siguro baka wala sa source sila, o baka nasala sila</item>
|
<item quantity="other">Lalaktawan ang %d (na) kabanata, siguro baka sa source ang mga ito, o baka nasala sila</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="no_chapters_error">Walang nakitang kabanata</string>
|
<string name="no_chapters_error">Walang nakitang kabanata</string>
|
||||||
<string name="confirm_set_chapter_settings">Gusto mo bang i-save at ipagpaubaya ang pagsasaayos na ito\?</string>
|
<string name="confirm_set_chapter_settings">Gusto mo bang i-save at ipagpaubaya ang pagsasaayos na ito\?</string>
|
||||||
@ -604,7 +604,7 @@
|
|||||||
<string name="local_invalid_format">Walang bisa ang ayos ng kabanata</string>
|
<string name="local_invalid_format">Walang bisa ang ayos ng kabanata</string>
|
||||||
<string name="chapter_not_found">Hindi makita ang kabanata</string>
|
<string name="chapter_not_found">Hindi makita ang kabanata</string>
|
||||||
<string name="source_unsupported">Di suportado ang source</string>
|
<string name="source_unsupported">Di suportado ang source</string>
|
||||||
<string name="unread">Hindi basahin</string>
|
<string name="unread">Hindi nababasa</string>
|
||||||
<string name="alignment_center">Gitna</string>
|
<string name="alignment_center">Gitna</string>
|
||||||
<string name="pref_side_nav_icon_alignment">Hilera ng nabigasyon sa gilid</string>
|
<string name="pref_side_nav_icon_alignment">Hilera ng nabigasyon sa gilid</string>
|
||||||
<string name="error_sharing_cover">Di maibahagi ang cover</string>
|
<string name="error_sharing_cover">Di maibahagi ang cover</string>
|
||||||
@ -690,7 +690,7 @@
|
|||||||
<string name="pref_update_only_completely_read">May hindi pa nabasang kabanata</string>
|
<string name="pref_update_only_completely_read">May hindi pa nabasang kabanata</string>
|
||||||
<string name="pref_library_update_manga_restriction">Lakdawan ang pag-update</string>
|
<string name="pref_library_update_manga_restriction">Lakdawan ang pag-update</string>
|
||||||
<string name="save_chapter_as_cbz">I-save bilang CBZ archive</string>
|
<string name="save_chapter_as_cbz">I-save bilang CBZ archive</string>
|
||||||
<string name="publishing_finished">Tapos na\'ng mailathala</string>
|
<string name="publishing_finished">Tapos nang mailathala</string>
|
||||||
<string name="on_hiatus">Naka-hiatus</string>
|
<string name="on_hiatus">Naka-hiatus</string>
|
||||||
<string name="cancelled">Kinansela</string>
|
<string name="cancelled">Kinansela</string>
|
||||||
<string name="backup_restore_invalid_uri">Error: walang URI</string>
|
<string name="backup_restore_invalid_uri">Error: walang URI</string>
|
||||||
@ -714,4 +714,5 @@
|
|||||||
<string name="rotation_reverse_portrait">Baligtad na patayo</string>
|
<string name="rotation_reverse_portrait">Baligtad na patayo</string>
|
||||||
<string name="notification_update_skipped">Nilaktawan ang %1$d (na) update</string>
|
<string name="notification_update_skipped">Nilaktawan ang %1$d (na) update</string>
|
||||||
<string name="action_move_to_top_all_for_series">Ilagay sa taas ang serye</string>
|
<string name="action_move_to_top_all_for_series">Ilagay sa taas ang serye</string>
|
||||||
|
<string name="disabled_nav">Nakasara</string>
|
||||||
</resources>
|
</resources>
|
@ -14,7 +14,7 @@
|
|||||||
<string name="action_filter_downloaded">Téléchargés</string>
|
<string name="action_filter_downloaded">Téléchargés</string>
|
||||||
<string name="action_filter_bookmarked">Signets</string>
|
<string name="action_filter_bookmarked">Signets</string>
|
||||||
<string name="action_filter_unread">Non lus</string>
|
<string name="action_filter_unread">Non lus</string>
|
||||||
<string name="action_filter_empty">Enlever le filtre</string>
|
<string name="action_filter_empty">Retirer le filtre</string>
|
||||||
<string name="action_sort_alpha">Alphabétiquement</string>
|
<string name="action_sort_alpha">Alphabétiquement</string>
|
||||||
<string name="action_sort_last_read">Dernier lu</string>
|
<string name="action_sort_last_read">Dernier lu</string>
|
||||||
<string name="action_search">Rechercher</string>
|
<string name="action_search">Rechercher</string>
|
||||||
@ -748,4 +748,5 @@
|
|||||||
<string name="channel_skipped">Ignoré</string>
|
<string name="channel_skipped">Ignoré</string>
|
||||||
<string name="rotation_reverse_portrait">Portrait inversé</string>
|
<string name="rotation_reverse_portrait">Portrait inversé</string>
|
||||||
<string name="action_move_to_top_all_for_series">Déplacer la série vers le haut</string>
|
<string name="action_move_to_top_all_for_series">Déplacer la série vers le haut</string>
|
||||||
|
<string name="disabled_nav">Désactivé</string>
|
||||||
</resources>
|
</resources>
|
@ -264,38 +264,38 @@
|
|||||||
<string name="backup_choice">מה אתה רוצה לגבות\?</string>
|
<string name="backup_choice">מה אתה רוצה לגבות\?</string>
|
||||||
<string name="backup_restore_content">פעולת שחזור משתמשת במקורות בכדי להשיג נתונים, עלויות הספק עשויות לחול.
|
<string name="backup_restore_content">פעולת שחזור משתמשת במקורות בכדי להשיג נתונים, עלויות הספק עשויות לחול.
|
||||||
\n
|
\n
|
||||||
\nוודא שהתקנת את כל התוספים הנחוצים והתחרת למקורות ושירותי המעקב לפני השחזור.</string>
|
\nוודא שהתקנת את כל התוספים הנחוצים והתחברת למקורות ושירותי המעקב לפני השחזור.</string>
|
||||||
<string name="restore_completed">השחזור הושלם</string>
|
<string name="restore_completed">השחזור הושלם</string>
|
||||||
<string name="backup_created">גיבוי נוצר</string>
|
<string name="backup_created">גיבוי נוצר</string>
|
||||||
<string name="pref_backup_slots">מספר גיבויים אוטומטיים מקסימליים</string>
|
<string name="pref_backup_slots">מספר גיבויים מקסימלי</string>
|
||||||
<string name="pref_backup_interval">תדירות גיבוי</string>
|
<string name="pref_backup_interval">תדירות גיבוי</string>
|
||||||
<string name="pref_backup_service_category">שירות</string>
|
<string name="pref_backup_service_category">גיבויים אוטומטיים</string>
|
||||||
<string name="pref_backup_directory">מיקום גיבוי</string>
|
<string name="pref_backup_directory">מיקום גיבוי</string>
|
||||||
<string name="pref_restore_backup_summ">שחזר ספרייה מקובץ גיבוי</string>
|
<string name="pref_restore_backup_summ">שחזר ספרייה מקובץ גיבוי</string>
|
||||||
<string name="pref_restore_backup">שחזור גיבוי</string>
|
<string name="pref_restore_backup">שחזור גיבוי</string>
|
||||||
<string name="pref_create_backup_summ">ניתן לשימוש על מנת לשחזר את הספרייה הנוכחית</string>
|
<string name="pref_create_backup_summ">ניתן לשימוש על מנת לשחזר את הספרייה הנוכחית</string>
|
||||||
<string name="pref_create_backup">צור גיבוי</string>
|
<string name="pref_create_backup">צור גיבוי</string>
|
||||||
<string name="services">שירותים</string>
|
<string name="services">שירותים</string>
|
||||||
<string name="pref_auto_update_manga_sync">סנכרן פרקים לאחר סיום קריאה</string>
|
<string name="pref_auto_update_manga_sync">עדכן התקדמות לאחר הקריאה</string>
|
||||||
<string name="pref_download_new">הורד פרקים חדשים</string>
|
<string name="pref_download_new">הורדת פרקים חדשים</string>
|
||||||
<string name="fifth_to_last">פרק חמישי מהסוף</string>
|
<string name="fifth_to_last">הפרק החמישי מהסוף שנקרא</string>
|
||||||
<string name="fourth_to_last">פרק רביעי מהסוף</string>
|
<string name="fourth_to_last">הפרק הרביעי מהסוף שנקרא</string>
|
||||||
<string name="third_to_last">פרק שלישי מהסוף</string>
|
<string name="third_to_last">הפרק השלישי מהסוף שנקרא</string>
|
||||||
<string name="second_to_last">פרק שני מהסוף</string>
|
<string name="second_to_last">הפרק השני מהסוף שנקרא</string>
|
||||||
<string name="last_read_chapter">פרק שנקרא בפעם האחרונה</string>
|
<string name="last_read_chapter">פרק שנקרא בפעם האחרונה</string>
|
||||||
<string name="custom_dir">מיקום מותאם אישית</string>
|
<string name="custom_dir">מיקום מותאם אישית</string>
|
||||||
<string name="pref_remove_after_read">הסר לאחר סיום קריאה</string>
|
<string name="pref_remove_after_read">אוטומטי לאחר סיום הקריאה</string>
|
||||||
<string name="pref_remove_after_marked_as_read">הסר כאשר מסומן כנקרא</string>
|
<string name="pref_remove_after_marked_as_read">אחרי שמסומן ידנית כנקרא</string>
|
||||||
<string name="pref_download_directory">מיקום הורדה</string>
|
<string name="pref_download_directory">מיקום הורדה</string>
|
||||||
<string name="pref_always_show_chapter_transition">הצג תמיד מעברי פרקים</string>
|
<string name="pref_always_show_chapter_transition">הצג תמיד מעברי פרקים</string>
|
||||||
<string name="color_filter_a_value">אלפא</string>
|
<string name="color_filter_a_value">אלפא</string>
|
||||||
<string name="color_filter_b_value">כחול</string>
|
<string name="color_filter_b_value">כחול</string>
|
||||||
<string name="color_filter_g_value">ירוק</string>
|
<string name="color_filter_g_value">ירוק</string>
|
||||||
<string name="color_filter_r_value">אדום</string>
|
<string name="color_filter_r_value">אדום</string>
|
||||||
<string name="rotation_force_landscape">כפה מצב מאוזן</string>
|
<string name="rotation_force_landscape">מאוזן נעול</string>
|
||||||
<string name="rotation_force_portrait">כפה מצב מאונך</string>
|
<string name="rotation_force_portrait">מאונך נעול</string>
|
||||||
<string name="rotation_free">חופשי</string>
|
<string name="rotation_free">חופשי</string>
|
||||||
<string name="pref_rotation_type">סיבוב</string>
|
<string name="pref_rotation_type">ברירת המחדל של סוג הסיבוב</string>
|
||||||
<string name="double_tap_anim_speed_fast">מהירה</string>
|
<string name="double_tap_anim_speed_fast">מהירה</string>
|
||||||
<string name="double_tap_anim_speed_normal">רגילה</string>
|
<string name="double_tap_anim_speed_normal">רגילה</string>
|
||||||
<string name="double_tap_anim_speed_0">בלי אנימציה</string>
|
<string name="double_tap_anim_speed_0">בלי אנימציה</string>
|
||||||
@ -315,7 +315,7 @@
|
|||||||
<string name="vertical_viewer">אנכי</string>
|
<string name="vertical_viewer">אנכי</string>
|
||||||
<string name="right_to_left_viewer">ימין לשמאל</string>
|
<string name="right_to_left_viewer">ימין לשמאל</string>
|
||||||
<string name="left_to_right_viewer">שמאל לימין</string>
|
<string name="left_to_right_viewer">שמאל לימין</string>
|
||||||
<string name="pref_viewer_type">מציג ברירת מחדל</string>
|
<string name="pref_viewer_type">ברירת המחדל של מצב הקריאה</string>
|
||||||
<string name="black_background">שחור</string>
|
<string name="black_background">שחור</string>
|
||||||
<string name="white_background">לבן</string>
|
<string name="white_background">לבן</string>
|
||||||
<string name="pref_reader_theme">צבע רקע</string>
|
<string name="pref_reader_theme">צבע רקע</string>
|
||||||
@ -327,15 +327,15 @@
|
|||||||
<string name="pref_keep_screen_on">השאר מסך דלוק</string>
|
<string name="pref_keep_screen_on">השאר מסך דלוק</string>
|
||||||
<string name="filter_mode_darken">שרוף / מוחשך</string>
|
<string name="filter_mode_darken">שרוף / מוחשך</string>
|
||||||
<string name="filter_mode_screen">מסך</string>
|
<string name="filter_mode_screen">מסך</string>
|
||||||
<string name="pref_custom_color_filter">השתמש במסנן צבע מותאם אישית</string>
|
<string name="pref_custom_color_filter">מסנן צבע מותאם אישית</string>
|
||||||
<string name="pref_custom_brightness">השתמש בבהירות מותאמת אישית</string>
|
<string name="pref_custom_brightness">בהירות מותאמת אישית</string>
|
||||||
<string name="pref_crop_borders">חתוך גבולות</string>
|
<string name="pref_crop_borders">חתוך גבולות</string>
|
||||||
<string name="pref_true_color">צבע 32-סיביות</string>
|
<string name="pref_true_color">צבע 32-סיביות</string>
|
||||||
<string name="pref_show_page_number">הצג מספר עמוד</string>
|
<string name="pref_show_page_number">הצג מספר עמוד</string>
|
||||||
<string name="pref_double_tap_anim_speed">מהירות הנפשה בהקשה כפולה</string>
|
<string name="pref_double_tap_anim_speed">מהירות הנפשה בהקשה כפולה</string>
|
||||||
<string name="pref_page_transitions">הנפשת מעברי דפים</string>
|
<string name="pref_page_transitions">הנפשת מעברי דפים</string>
|
||||||
<string name="pref_cutout_short">הצג תוכן באזור החתוך</string>
|
<string name="pref_cutout_short">הצג תוכן באזור החתוך</string>
|
||||||
<string name="pref_enable_automatic_extension_updates">בדוק אם קיימים עדכונים עבור תוספים</string>
|
<string name="pref_enable_automatic_extension_updates">בדוק אם קיימים עדכוני הרחבות</string>
|
||||||
<string name="untrusted_extension">תוסף לא מאומת</string>
|
<string name="untrusted_extension">תוסף לא מאומת</string>
|
||||||
<string name="obsolete_extension_message">תוסף זה אינו זמין עוד.</string>
|
<string name="obsolete_extension_message">תוסף זה אינו זמין עוד.</string>
|
||||||
<string name="pref_fullscreen">מסך מלא</string>
|
<string name="pref_fullscreen">מסך מלא</string>
|
||||||
@ -492,4 +492,63 @@
|
|||||||
<string name="update_72hour">כל 3 ימים</string>
|
<string name="update_72hour">כל 3 ימים</string>
|
||||||
<string name="connected_to_wifi">רק ב Wi-Fi</string>
|
<string name="connected_to_wifi">רק ב Wi-Fi</string>
|
||||||
<string name="restrictions">הגבלות: %s</string>
|
<string name="restrictions">הגבלות: %s</string>
|
||||||
|
<string name="pref_show_reading_mode_summary">הראה לזמן קצר את הסגנון כשהקראן נפתח</string>
|
||||||
|
<string name="pref_read_with_tapping_inverted">לחיצה הופכית</string>
|
||||||
|
<string name="off">כבוי</string>
|
||||||
|
<string name="on">פעיל</string>
|
||||||
|
<string name="pref_grayscale">טווח גווני האפור</string>
|
||||||
|
<string name="pref_inverted_colors">הופכי</string>
|
||||||
|
<string name="tapping_inverted_horizontal">אופקי</string>
|
||||||
|
<string name="right_and_left_nav">ימין ושמאל</string>
|
||||||
|
<string name="nav_zone_next">הבא</string>
|
||||||
|
<string name="nav_zone_right">ימין</string>
|
||||||
|
<string name="rotation_type">סוג הסיבוב</string>
|
||||||
|
<string name="rotation_portrait">מאונך</string>
|
||||||
|
<string name="rotation_landscape">מאוזן</string>
|
||||||
|
<string name="webtoon_side_padding_5">5%</string>
|
||||||
|
<string name="webtoon_side_padding_10">10%</string>
|
||||||
|
<string name="webtoon_side_padding_15">15%</string>
|
||||||
|
<string name="pref_hide_threshold">רגישות החבאת התפריט בגלילה</string>
|
||||||
|
<string name="pref_highest">הכי גבוה</string>
|
||||||
|
<string name="pref_high">גבוה</string>
|
||||||
|
<string name="pref_low">נמוך</string>
|
||||||
|
<string name="pref_lowest">הכי נמוך</string>
|
||||||
|
<string name="pref_category_delete_chapters">מחק פרקים</string>
|
||||||
|
<string name="pref_remove_exclude_categories">קטגוריות מוחרגות</string>
|
||||||
|
<string name="pref_download_new_categories_details">מנגה הנמצאת בקטגוריית מנועי ההורדות לא תעודכן גם אם היא נכללת בקטגורייה אחרת שכן מורדת.</string>
|
||||||
|
<string name="save_chapter_as_cbz">שמור כארכיון CBZ</string>
|
||||||
|
<string name="enhanced_services">שירותים משופרים</string>
|
||||||
|
<string name="edge_nav">גבול</string>
|
||||||
|
<string name="l_nav">עשוי בצורת L</string>
|
||||||
|
<string name="nav_zone_left">שמאל</string>
|
||||||
|
<string name="nav_zone_prev">הקודם</string>
|
||||||
|
<string name="pref_category_reading">קריאה</string>
|
||||||
|
<string name="webtoon_side_padding_20">20%</string>
|
||||||
|
<string name="webtoon_side_padding_25">25%</string>
|
||||||
|
<string name="pref_category_reading_mode">מצב קריאה</string>
|
||||||
|
<string name="webtoon_side_padding_0">ללא</string>
|
||||||
|
<string name="pref_category_auto_download">הורדה אוטומטית</string>
|
||||||
|
<string name="gray_background">אפור</string>
|
||||||
|
<string name="vertical_plus_viewer">אנכי מתמשך</string>
|
||||||
|
<string name="pager_viewer">עמודים</string>
|
||||||
|
<string name="rotation_reverse_portrait">מאונך הפוך</string>
|
||||||
|
<string name="pref_create_folder_per_manga">שמור דפים בתיקיות נפרדות</string>
|
||||||
|
<string name="tapping_inverted_vertical">אנכי</string>
|
||||||
|
<string name="tapping_inverted_both">שניהם</string>
|
||||||
|
<string name="pref_reader_actions">פעולות</string>
|
||||||
|
<string name="pref_read_with_long_tap">הראה בלחיצה ארוכה</string>
|
||||||
|
<string name="automatic_background">אוטומטי</string>
|
||||||
|
<string name="pref_remove_bookmarked_chapters">אפשר מחיקת פרקים שסומנו</string>
|
||||||
|
<string name="disabled">לא מאופשר</string>
|
||||||
|
<string name="pref_create_folder_per_manga_summary">צור תיקיות בהתאם לכותרת המנגה</string>
|
||||||
|
<string name="enhanced_tracking_info">שירותים המספקים שירותים משופרים למקורות ספציפיים. מנגות יהיו במעקב אוטומטי אחרי הוספה לספרייה שלך.</string>
|
||||||
|
<string name="backup_restore_missing_sources">מקורות חסרים:</string>
|
||||||
|
<string name="invalid_backup_file">קובץ גיבוי לא תקין</string>
|
||||||
|
<string name="invalid_backup_file_missing_data">חסרים נתונים בקובץ.</string>
|
||||||
|
<string name="invalid_backup_file_missing_manga">הגיבוי לא מכיל שום מנגה.</string>
|
||||||
|
<string name="pref_search_pinned_sources_only">כלול רק מקורות נעוצים</string>
|
||||||
|
<string name="source_not_found_name">מקור לא נמצא: %1$s</string>
|
||||||
|
<string name="tracker_not_logged_in">לא מחובר ל: %1$s</string>
|
||||||
|
<string name="backup_restore_invalid_uri">שגיאה: URI ריק</string>
|
||||||
|
<string name="action_track">מעקב</string>
|
||||||
</resources>
|
</resources>
|
@ -349,7 +349,7 @@
|
|||||||
<string name="lock_always">हमेशा</string>
|
<string name="lock_always">हमेशा</string>
|
||||||
<string name="lock_never">कभी नहीँ</string>
|
<string name="lock_never">कभी नहीँ</string>
|
||||||
<plurals name="lock_after_mins">
|
<plurals name="lock_after_mins">
|
||||||
<item quantity="one">1 मिनट के बाद</item>
|
<item quantity="one">%1$s मिनट के बाद</item>
|
||||||
<item quantity="other">%1$s मिनट के बाद</item>
|
<item quantity="other">%1$s मिनट के बाद</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="secure_screen">स्क्रीन सुरक्षित करें</string>
|
<string name="secure_screen">स्क्रीन सुरक्षित करें</string>
|
||||||
@ -380,8 +380,8 @@
|
|||||||
<string name="email">ईमेल पता</string>
|
<string name="email">ईमेल पता</string>
|
||||||
<string name="pref_always_show_chapter_transition">हमेशा अध्याय संक्रमण दिखाएं</string>
|
<string name="pref_always_show_chapter_transition">हमेशा अध्याय संक्रमण दिखाएं</string>
|
||||||
<plurals name="notification_new_chapters_summary">
|
<plurals name="notification_new_chapters_summary">
|
||||||
<item quantity="one">1 शीर्षक के लिए</item>
|
<item quantity="one">%d शीर्षक के लिए</item>
|
||||||
<item quantity="other">%d शीर्षक के लिए</item>
|
<item quantity="other">%d शीर्षकों के लिए</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_menu">मेन्यू</string>
|
<string name="action_menu">मेन्यू</string>
|
||||||
<string name="action_reorganize_by">पुनःक्रमित</string>
|
<string name="action_reorganize_by">पुनःक्रमित</string>
|
||||||
@ -436,8 +436,8 @@
|
|||||||
<string name="restore_duration">%02d मिनट,%02d सेकंड</string>
|
<string name="restore_duration">%02d मिनट,%02d सेकंड</string>
|
||||||
<string name="downloaded_only_summary">अपने पुस्तकालय में सभी मंगा फ़िल्टर करे</string>
|
<string name="downloaded_only_summary">अपने पुस्तकालय में सभी मंगा फ़िल्टर करे</string>
|
||||||
<plurals name="download_queue_summary">
|
<plurals name="download_queue_summary">
|
||||||
<item quantity="one">1 शेष</item>
|
<item quantity="one">%1$s बचा हुआ</item>
|
||||||
<item quantity="other">%1$s शेष</item>
|
<item quantity="other">%1$s बचा हुआ</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_search_pinned_sources_only">केवल पिन किए गए स्रोत शामिल हैं</string>
|
<string name="pref_search_pinned_sources_only">केवल पिन किए गए स्रोत शामिल हैं</string>
|
||||||
<string name="viewer">पढ़न मोड</string>
|
<string name="viewer">पढ़न मोड</string>
|
||||||
@ -482,7 +482,7 @@
|
|||||||
<string name="action_disable">बंद करें</string>
|
<string name="action_disable">बंद करें</string>
|
||||||
<string name="action_start">प्रारंभ</string>
|
<string name="action_start">प्रारंभ</string>
|
||||||
<plurals name="manga_num_chapters">
|
<plurals name="manga_num_chapters">
|
||||||
<item quantity="one">1 अध्याय</item>
|
<item quantity="one">%1$s अध्याय</item>
|
||||||
<item quantity="other">%1$s अध्याय</item>
|
<item quantity="other">%1$s अध्याय</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="label_network">नेटवर्क</string>
|
<string name="label_network">नेटवर्क</string>
|
||||||
@ -504,7 +504,7 @@
|
|||||||
<string name="pref_category_theme">थीम</string>
|
<string name="pref_category_theme">थीम</string>
|
||||||
<string name="action_sort_date_added">तारीख को जोड़ा गया</string>
|
<string name="action_sort_date_added">तारीख को जोड़ा गया</string>
|
||||||
<plurals name="num_trackers">
|
<plurals name="num_trackers">
|
||||||
<item quantity="one">1 ट्रैकर</item>
|
<item quantity="one">%d ट्रैकर</item>
|
||||||
<item quantity="other">%d ट्रैकरस</item>
|
<item quantity="other">%d ट्रैकरस</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="no_pinned_sources">कोई पिन किया हुआ सोर्स नही है</string>
|
<string name="no_pinned_sources">कोई पिन किया हुआ सोर्स नही है</string>
|
||||||
@ -519,8 +519,8 @@
|
|||||||
<string name="ext_nsfw_short">18+</string>
|
<string name="ext_nsfw_short">18+</string>
|
||||||
<string name="parental_controls_info">यह अनौपचारिक या संभावित रूप से फ़्लैग किए गए एक्सटेंशन को ऐप के भीतर NSFW (18+) सामग्री के सामने आने से नहीं रोकता है।</string>
|
<string name="parental_controls_info">यह अनौपचारिक या संभावित रूप से फ़्लैग किए गए एक्सटेंशन को ऐप के भीतर NSFW (18+) सामग्री के सामने आने से नहीं रोकता है।</string>
|
||||||
<plurals name="missing_chapters_warning">
|
<plurals name="missing_chapters_warning">
|
||||||
<item quantity="one">1 अध्याय छोड़ा जा रहा है, या तो स्रोत में यह अनुपलब्ध है या इसे फ़िल्टर कर दिया गया है</item>
|
<item quantity="one">%d अध्याय को छोड़कर, या तो स्रोत में यह अनुपलब्ध है या इसे फ़िल्टर कर दिया गया है</item>
|
||||||
<item quantity="other">%d अध्याय छोड़े जा रहा है, या तो स्रोत में यह अनुपलब्ध है या इसे फ़िल्टर कर दिया गया है</item>
|
<item quantity="other">%d अध्यायों को छोड़कर, या तो स्रोत में वे नहीं हैं या उन्हें फ़िल्टर कर दिया गया है</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="chapter_settings_updated">अपडेट किए गए डिफ़ॉल्ट अध्याय सेटिंग्स</string>
|
<string name="chapter_settings_updated">अपडेट किए गए डिफ़ॉल्ट अध्याय सेटिंग्स</string>
|
||||||
<string name="no_chapters_error">कोई अध्याय नहीं मिला</string>
|
<string name="no_chapters_error">कोई अध्याय नहीं मिला</string>
|
||||||
@ -703,6 +703,16 @@
|
|||||||
<string name="skipped_reason_not_started">छोड़ दिया गया क्योंकि कोई अध्याय पढ़ा नहीं गया</string>
|
<string name="skipped_reason_not_started">छोड़ दिया गया क्योंकि कोई अध्याय पढ़ा नहीं गया</string>
|
||||||
<string name="pref_update_only_started">कोई अध्याय नहीं पढ़ा</string>
|
<string name="pref_update_only_started">कोई अध्याय नहीं पढ़ा</string>
|
||||||
<string name="action_show_manga">मंगा दिखाएँ</string>
|
<string name="action_show_manga">मंगा दिखाएँ</string>
|
||||||
<string name="action_filter_started">शुरू किया</string>
|
<string name="action_filter_started">शुरू किया गया</string>
|
||||||
<string name="action_display_cover_only_grid">केवल कवर ग्रिड</string>
|
<string name="action_display_cover_only_grid">केवल कवर ग्रिड</string>
|
||||||
|
<string name="disabled_nav">अक्षम</string>
|
||||||
|
<string name="rotation_reverse_portrait">रिवर्स पोर्ट्रेट</string>
|
||||||
|
<string name="notification_update_error">%1$d अपडेट विफल</string>
|
||||||
|
<string name="confirm_manga_add_duplicate">आपकी लाइब्रेरी में एक ही नाम के साथ लेकिन एक अलग स्रोत (%1$s) से एक प्रविष्टि है।
|
||||||
|
\n
|
||||||
|
\nक्या आप अभी भी जारी रखना चाहते हैं\?</string>
|
||||||
|
<string name="notification_update_skipped">%1$d अपडेट छोड़े गए</string>
|
||||||
|
<string name="pref_navigate_pan">पैन पर नेविगेट करें</string>
|
||||||
|
<string name="pref_landscape_zoom">ज़ूम लैंडस्केप इमेज</string>
|
||||||
|
<string name="action_move_to_top_all_for_series">श्रृंखला को शीर्ष पर ले जाएं</string>
|
||||||
</resources>
|
</resources>
|
@ -271,7 +271,7 @@
|
|||||||
<string name="notification_first_add_to_library">Prije toga, dodaj manga u biblioteku</string>
|
<string name="notification_first_add_to_library">Prije toga, dodaj manga u biblioteku</string>
|
||||||
<string name="notification_cover_update_failed">Neuspjelo ažuriranje naslovnice</string>
|
<string name="notification_cover_update_failed">Neuspjelo ažuriranje naslovnice</string>
|
||||||
<plurals name="notification_chapters_multiple_and_more">
|
<plurals name="notification_chapters_multiple_and_more">
|
||||||
<item quantity="one">Poglavlja %1$s i još %2$s</item>
|
<item quantity="one">Poglavlja %1$s i još jedno</item>
|
||||||
<item quantity="few">Poglavlja %1$s i još %2$s</item>
|
<item quantity="few">Poglavlja %1$s i još %2$s</item>
|
||||||
<item quantity="other">Poglavlja %1$s i još %2$s</item>
|
<item quantity="other">Poglavlja %1$s i još %2$s</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
@ -726,4 +726,5 @@
|
|||||||
<string name="notification_update_skipped">Preskočena aktualiziranja: %1$d</string>
|
<string name="notification_update_skipped">Preskočena aktualiziranja: %1$d</string>
|
||||||
<string name="rotation_reverse_portrait">Preokrenuto uspravno</string>
|
<string name="rotation_reverse_portrait">Preokrenuto uspravno</string>
|
||||||
<string name="action_move_to_top_all_for_series">Pomakni serijal na vrh</string>
|
<string name="action_move_to_top_all_for_series">Pomakni serijal na vrh</string>
|
||||||
|
<string name="disabled_nav">Deaktivirano</string>
|
||||||
</resources>
|
</resources>
|
@ -73,7 +73,7 @@
|
|||||||
<string name="all">Tutte</string>
|
<string name="all">Tutte</string>
|
||||||
<string name="pref_library_update_restriction">Restrizioni del dispositivo agli aggiornamenti automatici</string>
|
<string name="pref_library_update_restriction">Restrizioni del dispositivo agli aggiornamenti automatici</string>
|
||||||
<string name="charging">In carica</string>
|
<string name="charging">In carica</string>
|
||||||
<string name="pref_update_only_non_completed">È una serie completa</string>
|
<string name="pref_update_only_non_completed">Con stato \"completa\"</string>
|
||||||
<string name="pref_auto_update_manga_sync">Aggiorna il tracking dopo la lettura</string>
|
<string name="pref_auto_update_manga_sync">Aggiorna il tracking dopo la lettura</string>
|
||||||
<string name="pref_start_screen">Schermata iniziale</string>
|
<string name="pref_start_screen">Schermata iniziale</string>
|
||||||
<!-- Reader section -->
|
<!-- Reader section -->
|
||||||
@ -707,7 +707,7 @@
|
|||||||
<string name="action_display_language_badge">Lingua</string>
|
<string name="action_display_language_badge">Lingua</string>
|
||||||
<string name="label_warning">Attenzione</string>
|
<string name="label_warning">Attenzione</string>
|
||||||
<string name="backup_info">I backup automatici sono altamente consigliati. Dovresti tenere delle copie anche in altri posti.</string>
|
<string name="backup_info">I backup automatici sono altamente consigliati. Dovresti tenere delle copie anche in altri posti.</string>
|
||||||
<string name="notification_size_warning">Attenzione: grossi aggiornamenti danneggiano le fonti, possono rallentare gli aggiornamenti e aumentare il consumo di batteria</string>
|
<string name="notification_size_warning">Grossi aggiornamenti danneggiano le fonti, possono rallentare gli aggiornamenti e aumentare il consumo di batteria</string>
|
||||||
<string name="connected_to_wifi">Solo su Wi-Fi</string>
|
<string name="connected_to_wifi">Solo su Wi-Fi</string>
|
||||||
<string name="update_72hour">Ogni 3 giorni</string>
|
<string name="update_72hour">Ogni 3 giorni</string>
|
||||||
<string name="download_queue_size_warning">Attenzione: grossi download di massa possono rallentare le fonti e/o bloccare tachiyomi</string>
|
<string name="download_queue_size_warning">Attenzione: grossi download di massa possono rallentare le fonti e/o bloccare tachiyomi</string>
|
||||||
@ -719,8 +719,8 @@
|
|||||||
<string name="database_clean">Database pulito</string>
|
<string name="database_clean">Database pulito</string>
|
||||||
<string name="extension_api_error">Impossibile ottenere l\'elenco estensioni</string>
|
<string name="extension_api_error">Impossibile ottenere l\'elenco estensioni</string>
|
||||||
<string name="privacy_policy">Politica sulla privacy</string>
|
<string name="privacy_policy">Politica sulla privacy</string>
|
||||||
<string name="pref_update_only_completely_read">Ha capitoli non letti</string>
|
<string name="pref_update_only_completely_read">Con capitoli non letti</string>
|
||||||
<string name="pref_library_update_manga_restriction">Salta l\'aggiornamento</string>
|
<string name="pref_library_update_manga_restriction">Salta l\'aggiornamento di serie</string>
|
||||||
<string name="library_errors_help">Per un aiuto su come risolvere gli errori di aggiornamento della libreria vedi %1$s</string>
|
<string name="library_errors_help">Per un aiuto su come risolvere gli errori di aggiornamento della libreria vedi %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">Salva come archivio CBZ</string>
|
<string name="save_chapter_as_cbz">Salva come archivio CBZ</string>
|
||||||
<string name="cancelled">Cancellata</string>
|
<string name="cancelled">Cancellata</string>
|
||||||
@ -737,15 +737,17 @@
|
|||||||
\nVuoi comunque continuare\?</string>
|
\nVuoi comunque continuare\?</string>
|
||||||
<string name="action_display_cover_only_grid">Griglia con solo copertine</string>
|
<string name="action_display_cover_only_grid">Griglia con solo copertine</string>
|
||||||
<string name="action_filter_started">Iniziati</string>
|
<string name="action_filter_started">Iniziati</string>
|
||||||
<string name="pref_update_only_started">Nessun capitolo letto</string>
|
<string name="pref_update_only_started">Che non sono state iniziate</string>
|
||||||
<string name="skipped_reason_completed">Saltato perché la serie è completa</string>
|
<string name="skipped_reason_completed">Saltato perché la serie è completa</string>
|
||||||
<string name="skipped_reason_not_caught_up">Saltato perché ci sono capitoli non letti</string>
|
<string name="skipped_reason_not_caught_up">Saltato perché ci sono capitoli non letti</string>
|
||||||
<string name="skipped_reason_not_started">Saltato perché non ci sono capitoli letti</string>
|
<string name="skipped_reason_not_started">Saltato perché non ci sono capitoli letti</string>
|
||||||
<string name="channel_skipped">Saltato</string>
|
<string name="channel_skipped">Saltato</string>
|
||||||
<string name="notification_update_error">%1$d aggiornamento(i) fallito(i)</string>
|
<string name="notification_update_error">%1$d aggiornamento(i) fallito(i)</string>
|
||||||
<string name="notification_update_skipped">%1$d aggiornamento(i) saltato(i)</string>
|
<string name="notification_update_skipped">%1$d aggiornamento(i) saltato(i)</string>
|
||||||
<string name="learn_more">Approfondisci</string>
|
<string name="learn_more">Tocca per approfondire</string>
|
||||||
<string name="rotation_reverse_portrait">Verticale inverso</string>
|
<string name="rotation_reverse_portrait">Verticale inverso</string>
|
||||||
<string name="action_move_to_top_all_for_series">Sposta la serie in cima</string>
|
<string name="action_move_to_top_all_for_series">Sposta la serie in cima</string>
|
||||||
<string name="disabled_nav">Disattivato</string>
|
<string name="disabled_nav">Disattivato</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">C\'è una nuova versione ufficiale disponibile. Tocca per imparare a migrare dalle release non ufficiali di F-droid.</string>
|
||||||
|
<string name="error_saving_picture">Errore durante il salvataggio dell\'immagine</string>
|
||||||
</resources>
|
</resources>
|
@ -702,4 +702,5 @@
|
|||||||
<string name="notification_update_error">%1$d件の更新に失敗しました</string>
|
<string name="notification_update_error">%1$d件の更新に失敗しました</string>
|
||||||
<string name="rotation_reverse_portrait">縦向き(反転)</string>
|
<string name="rotation_reverse_portrait">縦向き(反転)</string>
|
||||||
<string name="action_move_to_top_all_for_series">シリーズをトップに移動</string>
|
<string name="action_move_to_top_all_for_series">シリーズをトップに移動</string>
|
||||||
|
<string name="disabled_nav">無効</string>
|
||||||
</resources>
|
</resources>
|
@ -12,8 +12,8 @@
|
|||||||
<string name="action_filter_bookmarked">북마크됨</string>
|
<string name="action_filter_bookmarked">북마크됨</string>
|
||||||
<string name="action_filter_unread">읽지 않음</string>
|
<string name="action_filter_unread">읽지 않음</string>
|
||||||
<string name="action_filter_empty">필터 제거</string>
|
<string name="action_filter_empty">필터 제거</string>
|
||||||
<string name="action_sort_alpha">알파벳 순으로</string>
|
<string name="action_sort_alpha">알파벳 순</string>
|
||||||
<string name="action_sort_last_read">읽은 순으로</string>
|
<string name="action_sort_last_read">마지막으로 읽은 순</string>
|
||||||
<string name="action_search">검색</string>
|
<string name="action_search">검색</string>
|
||||||
<string name="action_select_all">전체 선택</string>
|
<string name="action_select_all">전체 선택</string>
|
||||||
<string name="action_mark_as_read">읽음으로 표시</string>
|
<string name="action_mark_as_read">읽음으로 표시</string>
|
||||||
@ -34,10 +34,10 @@
|
|||||||
<string name="action_edit_cover">표지 수정</string>
|
<string name="action_edit_cover">표지 수정</string>
|
||||||
<string name="action_stop">정지</string>
|
<string name="action_stop">정지</string>
|
||||||
<string name="action_remove">제거</string>
|
<string name="action_remove">제거</string>
|
||||||
<string name="action_resume">계속 읽기</string>
|
<string name="action_resume">계속</string>
|
||||||
<string name="action_open_in_browser">브라우저에서 열기</string>
|
<string name="action_open_in_browser">브라우저에서 열기</string>
|
||||||
<string name="action_display_mode">타이틀 표시 변경</string>
|
<string name="action_display_mode">타이틀 표시 변경</string>
|
||||||
<string name="action_display_grid">그리드</string>
|
<string name="action_display_grid">작은 그리드</string>
|
||||||
<string name="action_display_list">리스트</string>
|
<string name="action_display_list">리스트</string>
|
||||||
<string name="action_cancel">취소</string>
|
<string name="action_cancel">취소</string>
|
||||||
<string name="action_sort">정렬</string>
|
<string name="action_sort">정렬</string>
|
||||||
@ -49,7 +49,7 @@
|
|||||||
<string name="label_library">서재</string>
|
<string name="label_library">서재</string>
|
||||||
<string name="label_recent_manga">기록</string>
|
<string name="label_recent_manga">기록</string>
|
||||||
<string name="label_recent_updates">업데이트</string>
|
<string name="label_recent_updates">업데이트</string>
|
||||||
<string name="action_sort_total">모든 회차</string>
|
<string name="action_sort_total">회차의 수 순</string>
|
||||||
<string name="action_previous_chapter">이전 화</string>
|
<string name="action_previous_chapter">이전 화</string>
|
||||||
<string name="action_next_chapter">다음 화</string>
|
<string name="action_next_chapter">다음 화</string>
|
||||||
<string name="action_retry">재시도</string>
|
<string name="action_retry">재시도</string>
|
||||||
@ -77,14 +77,14 @@
|
|||||||
<string name="portrait">세로</string>
|
<string name="portrait">세로</string>
|
||||||
<string name="landscape">가로</string>
|
<string name="landscape">가로</string>
|
||||||
<string name="pref_library_update_interval">자동 업데이트</string>
|
<string name="pref_library_update_interval">자동 업데이트</string>
|
||||||
<string name="update_never">수동</string>
|
<string name="update_never">끄기</string>
|
||||||
<string name="update_6hour">6시간</string>
|
<string name="update_6hour">6시간</string>
|
||||||
<string name="update_12hour">12시간</string>
|
<string name="update_12hour">12시간</string>
|
||||||
<string name="update_24hour">1일</string>
|
<string name="update_24hour">1일</string>
|
||||||
<string name="update_48hour">2일</string>
|
<string name="update_48hour">2일</string>
|
||||||
<string name="update_weekly">1주</string>
|
<string name="update_weekly">1주</string>
|
||||||
<string name="all">전부</string>
|
<string name="all">전부</string>
|
||||||
<string name="pref_library_update_restriction">서재 업데이트 제한</string>
|
<string name="pref_library_update_restriction">자동 업데이트 조건</string>
|
||||||
<string name="charging">충전중</string>
|
<string name="charging">충전중</string>
|
||||||
<string name="pref_start_screen">시작 화면</string>
|
<string name="pref_start_screen">시작 화면</string>
|
||||||
<string name="default_category">기본 카테고리</string>
|
<string name="default_category">기본 카테고리</string>
|
||||||
@ -146,9 +146,9 @@
|
|||||||
<string name="pref_restore_backup">백업 복원</string>
|
<string name="pref_restore_backup">백업 복원</string>
|
||||||
<string name="pref_restore_backup_summ">백업 파일에서 서재 복원</string>
|
<string name="pref_restore_backup_summ">백업 파일에서 서재 복원</string>
|
||||||
<string name="pref_backup_directory">백업 위치</string>
|
<string name="pref_backup_directory">백업 위치</string>
|
||||||
<string name="pref_backup_service_category">서비스</string>
|
<string name="pref_backup_service_category">자동 백업</string>
|
||||||
<string name="pref_backup_interval">백업 주기</string>
|
<string name="pref_backup_interval">백업 주기</string>
|
||||||
<string name="pref_backup_slots">최대 자동 백업</string>
|
<string name="pref_backup_slots">최대 백업</string>
|
||||||
<string name="backup_created">백업 생성됨</string>
|
<string name="backup_created">백업 생성됨</string>
|
||||||
<string name="restore_completed">복원 완료</string>
|
<string name="restore_completed">복원 완료</string>
|
||||||
<string name="restoring_backup">백업 복원중</string>
|
<string name="restoring_backup">백업 복원중</string>
|
||||||
@ -162,7 +162,7 @@
|
|||||||
<string name="pref_clear_database">데이터베이스 삭제</string>
|
<string name="pref_clear_database">데이터베이스 삭제</string>
|
||||||
<string name="pref_clear_database_summary">서재에 추가되지 않은 만화의 기록을 삭제합니다</string>
|
<string name="pref_clear_database_summary">서재에 추가되지 않은 만화의 기록을 삭제합니다</string>
|
||||||
<string name="clear_database_confirmation">확실합니까\? 서재에 없는 만화의 읽은 기록이 삭제됩니다</string>
|
<string name="clear_database_confirmation">확실합니까\? 서재에 없는 만화의 읽은 기록이 삭제됩니다</string>
|
||||||
<string name="pref_refresh_library_tracking">동기화 메타데이터 새로 고침</string>
|
<string name="pref_refresh_library_tracking">트래커 동기화 새로고침</string>
|
||||||
<string name="pref_refresh_library_tracking_summary">상태 및 평점, 마지막으로 읽은 회차를 동기화 서비스로부터 업데이트합니다</string>
|
<string name="pref_refresh_library_tracking_summary">상태 및 평점, 마지막으로 읽은 회차를 동기화 서비스로부터 업데이트합니다</string>
|
||||||
<string name="version">버전</string>
|
<string name="version">버전</string>
|
||||||
<string name="pref_enable_acra">오류 보고서 전송</string>
|
<string name="pref_enable_acra">오류 보고서 전송</string>
|
||||||
@ -219,7 +219,7 @@
|
|||||||
<string name="chapter_progress">페이지: %1$d</string>
|
<string name="chapter_progress">페이지: %1$d</string>
|
||||||
<string name="no_next_chapter">다음 화가 없습니다</string>
|
<string name="no_next_chapter">다음 화가 없습니다</string>
|
||||||
<string name="no_previous_chapter">이전 화가 없습니다</string>
|
<string name="no_previous_chapter">이전 화가 없습니다</string>
|
||||||
<string name="decode_image_error">이미지를 디코드 할 수 없습니다</string>
|
<string name="decode_image_error">이미지를 로드할 수 없습니다</string>
|
||||||
<string name="confirm_set_image_as_cover">이 이미지를 표지로 사용합니까\?</string>
|
<string name="confirm_set_image_as_cover">이 이미지를 표지로 사용합니까\?</string>
|
||||||
<string name="transition_finished">완료:</string>
|
<string name="transition_finished">완료:</string>
|
||||||
<string name="transition_current">현재:</string>
|
<string name="transition_current">현재:</string>
|
||||||
@ -250,7 +250,7 @@
|
|||||||
<string name="download_notifier_unknown_error">다운로드 중에 예기치 않은 오류가 발생하였습니다</string>
|
<string name="download_notifier_unknown_error">다운로드 중에 예기치 않은 오류가 발생하였습니다</string>
|
||||||
<string name="download_notifier_download_paused">다운로드 일시중지됨</string>
|
<string name="download_notifier_download_paused">다운로드 일시중지됨</string>
|
||||||
<string name="action_display_download_badge">다운로드된 회차</string>
|
<string name="action_display_download_badge">다운로드된 회차</string>
|
||||||
<string name="pref_update_only_non_completed">연재 중인 만화만 업데이트</string>
|
<string name="pref_update_only_non_completed">연재가 끝남</string>
|
||||||
<string name="pref_auto_update_manga_sync">읽은 기록 동기화</string>
|
<string name="pref_auto_update_manga_sync">읽은 기록 동기화</string>
|
||||||
<string name="default_category_summary">항상 물어보기</string>
|
<string name="default_category_summary">항상 물어보기</string>
|
||||||
<string name="pref_create_backup_summ">현재 서재를 나중에 복구하는 데 사용 가능</string>
|
<string name="pref_create_backup_summ">현재 서재를 나중에 복구하는 데 사용 가능</string>
|
||||||
@ -286,7 +286,7 @@
|
|||||||
<string name="licensed">판권작</string>
|
<string name="licensed">판권작</string>
|
||||||
<string name="copied_to_clipboard">클립보드에 복사됨:
|
<string name="copied_to_clipboard">클립보드에 복사됨:
|
||||||
\n%1$s</string>
|
\n%1$s</string>
|
||||||
<string name="show_title">제목 표시</string>
|
<string name="show_title">소스 제목</string>
|
||||||
<string name="custom_download">다운로드 할 회차 직접 입력</string>
|
<string name="custom_download">다운로드 할 회차 직접 입력</string>
|
||||||
<string name="download_custom">사용자 정의</string>
|
<string name="download_custom">사용자 정의</string>
|
||||||
<string name="reading">읽는 중</string>
|
<string name="reading">읽는 중</string>
|
||||||
@ -308,7 +308,7 @@
|
|||||||
<string name="download_notifier_text_only_wifi">Wi-Fi 연결 사용 불가능</string>
|
<string name="download_notifier_text_only_wifi">Wi-Fi 연결 사용 불가능</string>
|
||||||
<string name="download_notifier_no_network">네트워크 연결 사용 불가능</string>
|
<string name="download_notifier_no_network">네트워크 연결 사용 불가능</string>
|
||||||
<string name="channel_common">일반</string>
|
<string name="channel_common">일반</string>
|
||||||
<string name="pref_read_with_long_tap">길게 눌러 대화상자 표시</string>
|
<string name="pref_read_with_long_tap">길게 눌러 표시</string>
|
||||||
<string name="action_open_in_web_view">WebView로 열기</string>
|
<string name="action_open_in_web_view">WebView로 열기</string>
|
||||||
<string name="pref_true_color">32비트 컬러</string>
|
<string name="pref_true_color">32비트 컬러</string>
|
||||||
<string name="pref_skip_read_chapters">읽음 표시된 회차 건너뛰기</string>
|
<string name="pref_skip_read_chapters">읽음 표시된 회차 건너뛰기</string>
|
||||||
@ -339,7 +339,7 @@
|
|||||||
<string name="logout">로그아웃</string>
|
<string name="logout">로그아웃</string>
|
||||||
<string name="logout_title">%1$s 에서 로그아웃 하시겠습니까\?</string>
|
<string name="logout_title">%1$s 에서 로그아웃 하시겠습니까\?</string>
|
||||||
<plurals name="download_queue_summary">
|
<plurals name="download_queue_summary">
|
||||||
<item quantity="other">%1$s 개 남았습니다</item>
|
<item quantity="other">%1$s 개 남음</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="notification_incognito_text">시크릿 모드 끄기</string>
|
<string name="notification_incognito_text">시크릿 모드 끄기</string>
|
||||||
<string name="label_downloaded_only">다운로드가 완료된 항목만 표시</string>
|
<string name="label_downloaded_only">다운로드가 완료된 항목만 표시</string>
|
||||||
@ -349,10 +349,10 @@
|
|||||||
<string name="licenses">오픈 소스 라이센스</string>
|
<string name="licenses">오픈 소스 라이센스</string>
|
||||||
<string name="battery_optimization_setting_activity_not_found">디바이스 설정을 열 수 없습니다</string>
|
<string name="battery_optimization_setting_activity_not_found">디바이스 설정을 열 수 없습니다</string>
|
||||||
<string name="pref_disable_battery_optimization">배터리 최적화 끄기</string>
|
<string name="pref_disable_battery_optimization">배터리 최적화 끄기</string>
|
||||||
<string name="restore_miui_warning">MIUI 최적화가 꺼져 있을 경우 백업/복원 기능은 정상 작동하지 않을 수 있습니다.</string>
|
<string name="restore_miui_warning">MIUI 최적화가 꺼져 있을 경우 백업/복원 기능이 정상 작동하지 않을 수 있습니다.</string>
|
||||||
<string name="restore_in_progress">복원이 이미 진행중 입니다</string>
|
<string name="restore_in_progress">복원이 이미 진행중 입니다</string>
|
||||||
<string name="requires_app_restart">설정을 적용하기 위해 앱을 재시작해야 합니다</string>
|
<string name="requires_app_restart">설정을 적용하기 위해 앱을 재시작해야 합니다</string>
|
||||||
<string name="pref_dns_over_https">DNS over HTTPS</string>
|
<string name="pref_dns_over_https">DNS over HTTPS (DoH)</string>
|
||||||
<string name="label_data">데이터</string>
|
<string name="label_data">데이터</string>
|
||||||
<string name="backup_in_progress">백업이 이미 진행중입니다</string>
|
<string name="backup_in_progress">백업이 이미 진행중입니다</string>
|
||||||
<string name="restoring_backup_error">백업 복원 실패</string>
|
<string name="restoring_backup_error">백업 복원 실패</string>
|
||||||
@ -392,8 +392,8 @@
|
|||||||
<string name="label_default">기본값</string>
|
<string name="label_default">기본값</string>
|
||||||
<string name="action_select_inverse">선택 반전</string>
|
<string name="action_select_inverse">선택 반전</string>
|
||||||
<string name="action_search_settings">검색 설정</string>
|
<string name="action_search_settings">검색 설정</string>
|
||||||
<string name="action_sort_date_added">추가된 날짜</string>
|
<string name="action_sort_date_added">서재에 추가된 시간 순</string>
|
||||||
<string name="action_sort_latest_chapter">최신 화</string>
|
<string name="action_sort_latest_chapter">최신 화 업로드 순</string>
|
||||||
<string name="l_nav">L자 모양</string>
|
<string name="l_nav">L자 모양</string>
|
||||||
<string name="pref_read_with_tapping_inverted">터치 반전</string>
|
<string name="pref_read_with_tapping_inverted">터치 반전</string>
|
||||||
<string name="tapping_inverted_none">없음</string>
|
<string name="tapping_inverted_none">없음</string>
|
||||||
@ -500,4 +500,207 @@
|
|||||||
<string name="channel_app_updates">앱 업데이트</string>
|
<string name="channel_app_updates">앱 업데이트</string>
|
||||||
<string name="channel_progress">진행 상황</string>
|
<string name="channel_progress">진행 상황</string>
|
||||||
<string name="channel_errors">오류</string>
|
<string name="channel_errors">오류</string>
|
||||||
|
<string name="database_clean">데이터베이스 정리</string>
|
||||||
|
<string name="learn_more">터치하여 자세히 알아보기</string>
|
||||||
|
<string name="chapter_settings_updated">기본 회차 설정을 업데이트 했습니다</string>
|
||||||
|
<string name="channel_skipped">건너뜀</string>
|
||||||
|
<string name="channel_new_chapters">회차 업데이트</string>
|
||||||
|
<string name="pref_jump_to_chapters">시작 시 회차 표시</string>
|
||||||
|
<string name="include">포함: %s</string>
|
||||||
|
<string name="label_background_activity">백그라운드 활동</string>
|
||||||
|
<string name="pref_update_only_completely_read">안 읽은 회차가 있음</string>
|
||||||
|
<string name="categorized_display_settings">카테고리 별 표시/정렬 설정</string>
|
||||||
|
<string name="ext_installer_shizuku_unavailable_dialog">Shizuku를 확장기능 인스톨러로 사용하려면 Shizuku를 먼저 설치해 주세요.</string>
|
||||||
|
<string name="ext_update_all">전부 업데이트</string>
|
||||||
|
<string name="backup_restore_invalid_uri">에러: 빈 URI</string>
|
||||||
|
<string name="invalid_backup_file_missing_manga">백업에 만화가 포함되어있지 않습니다.</string>
|
||||||
|
<string name="pref_dump_crash_logs_summary">개발자와 공유할 수 있는 오류 로그 파일을 생성합니다</string>
|
||||||
|
<string name="crash_log_saved">오류 로그가 저장되었습니다</string>
|
||||||
|
<string name="privacy_policy">개인정보 보호 정책</string>
|
||||||
|
<string name="share_page_info">%1$s: %2$s, %3$d페이지</string>
|
||||||
|
<string name="clear_history_confirmation">계속하시겠습니까\? 모든 기록이 삭제됩니다.</string>
|
||||||
|
<string name="disabled_nav">비활성화</string>
|
||||||
|
<string name="invalid_backup_file_missing_data">파일에 필요한 데이터가 포함되어있지 않습니다.</string>
|
||||||
|
<string name="backup_restore_missing_sources">없어진 소스:</string>
|
||||||
|
<string name="backup_restore_missing_trackers">로그인 되지않은 트래커:</string>
|
||||||
|
<string name="pref_auto_clear_chapter_cache">앱 종료 시 회차 캐시 삭제</string>
|
||||||
|
<string name="clear_database_source_item_count">데이터베이스에 없는 만화가 %1$d개 있습니다</string>
|
||||||
|
<string name="about_dont_kill_my_app">일부 제조사는 백그라운드 서비스를 종료하는 추가적인 제한 사항이 있습니다. 자세한 사항은 웹사이트를 참조하세요.</string>
|
||||||
|
<string name="pref_tablet_ui_mode">태블릿 UI</string>
|
||||||
|
<string name="tabs_header">탭</string>
|
||||||
|
<string name="http_error_hint">WebView에서 사이트 열기</string>
|
||||||
|
<string name="pinned_sources">핀 설정됨</string>
|
||||||
|
<string name="action_global_search_query">\"%1$s\"를 전역 검색합니다</string>
|
||||||
|
<string name="local_source_help_guide">로컬 저장소 사용법</string>
|
||||||
|
<string name="no_pinned_sources">핀 설정된 소스가 없습니다</string>
|
||||||
|
<string name="local_invalid_format">잘못된 회차 포맷</string>
|
||||||
|
<string name="unknown_status">알 수 없는 상태</string>
|
||||||
|
<string name="on_hiatus">휴재중</string>
|
||||||
|
<string name="manga_info_expand">상세정보 표시</string>
|
||||||
|
<string name="manga_info_collapse">상세정보 숨김</string>
|
||||||
|
<string name="clipboard_copy_error">클립보드로 복사에 실패하였습니다</string>
|
||||||
|
<string name="tracker_komga_warning">이 트래커는 Komga 소스에만 호환됩니다.</string>
|
||||||
|
<plurals name="num_trackers">
|
||||||
|
<item quantity="other">%d개의 트래커</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="add_tracking">트래커 추가</string>
|
||||||
|
<string name="paused">일시정지</string>
|
||||||
|
<string name="error_invalid_date_supplied">잘못된 날짜입니다</string>
|
||||||
|
<string name="myanimelist_relogin">MAL에 다시 로그인해 주세요</string>
|
||||||
|
<string name="loader_not_implemented_error">소스를 찾을 수 없습니다</string>
|
||||||
|
<string name="page_list_empty_error">페이지를 찾을 수 없습니다</string>
|
||||||
|
<plurals name="missing_chapters_warning">
|
||||||
|
<item quantity="other">소스에 존재하지 않거나 필터링되어 있는 %d개의 회차를 건너뛰었습니다</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="pref_clear_history">내역 삭제</string>
|
||||||
|
<string name="clear_history_completed">기록이 삭제되었습니다</string>
|
||||||
|
<string name="download_insufficient_space">저장 공간이 부족하여 회차를 다운로드 할 수 없습니다</string>
|
||||||
|
<string name="download_queue_size_warning">경고: 한꺼번에 많은 양을 다운로드 할 경우 소스가 느려지거나 Tachiyomi를 차단할 수 있습니다</string>
|
||||||
|
<string name="notification_check_updates">새로운 회차 확인 중</string>
|
||||||
|
<string name="notification_size_warning">경고: 대량의 업데이트는 소스에 과도한 부하를 줄 수 있고 배터리 사용량을 증가시킵니다</string>
|
||||||
|
<string name="notification_chapters_single">%1$s화</string>
|
||||||
|
<string name="notification_update_error">%1$d개의 업데이트가 실패했습니다</string>
|
||||||
|
<string name="notification_update_skipped">%1$d개의 업데이트를 건너 뛰었습니다</string>
|
||||||
|
<string name="library_errors_help">서재 업데이트 오류를 해결하려면 %1$s를 참조하세요</string>
|
||||||
|
<string name="skipped_reason_completed">완결된 만화를 건너 뛰었습니다</string>
|
||||||
|
<string name="skipped_reason_not_started">읽지 않은 만화를 건너 뛰었습니다</string>
|
||||||
|
<string name="update_check_eol">이 안드로이드 버젼은 더이상 지원되지 않습니다</string>
|
||||||
|
<plurals name="update_check_notification_ext_updates">
|
||||||
|
<item quantity="other">%d개의 확장기능 업데이트가 있습니다</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="information_cloudflare_bypass_failure">Cloudflare를 통과하지 못했습니다</string>
|
||||||
|
<string name="information_webview_required">Tachiyomi를 사용하려면 WebView가 필요합니다</string>
|
||||||
|
<string name="information_webview_outdated">호환성을 위해 WebView 어플리케이션을 업데이트 해 주세요</string>
|
||||||
|
<string name="pref_navigate_pan">페이지 내 이동</string>
|
||||||
|
<string name="obsolete_extension_message">이 확장기능은 더이상 이용이 불가능합니다.</string>
|
||||||
|
<string name="ext_install_service_notif">확장기능 설치 중…</string>
|
||||||
|
<string name="ext_installer_legacy">레거시</string>
|
||||||
|
<string name="webtoon_side_padding_10">10%</string>
|
||||||
|
<string name="action_track">트래킹</string>
|
||||||
|
<string name="pref_refresh_library_covers">서재 만화 표지 새로고침</string>
|
||||||
|
<string name="pref_dump_crash_logs">오류 로그 덤프</string>
|
||||||
|
<string name="chapter_not_found">회차를 찾을 수 없습니다</string>
|
||||||
|
<string name="error_no_match">결과가 없습니다</string>
|
||||||
|
<string name="channel_crash_logs">오류 로그</string>
|
||||||
|
<string name="ext_nsfw_warning">19금 콘텐츠가 포함될 수 있습니다</string>
|
||||||
|
<string name="action_filter_tracked">트래커 사용</string>
|
||||||
|
<string name="action_start">시작</string>
|
||||||
|
<string name="source_not_found_name">소스 %1$s를 찾을 수 없습니다</string>
|
||||||
|
<string name="action_start_downloading_now">지금 다운로드 시작</string>
|
||||||
|
<string name="ext_installer_pref">인스톨러</string>
|
||||||
|
<string name="ext_installer_shizuku_stopped">Shizuku가 실행 중이 아닙니다</string>
|
||||||
|
<string name="manga_from_library">서재의 만화</string>
|
||||||
|
<string name="downloaded_chapters">다운로드된 회차</string>
|
||||||
|
<string name="publishing_finished">완결됨</string>
|
||||||
|
<string name="confirm_manga_add_duplicate">서재에 제목이 같지만 소스가 다른 항목이 있습니다 (%1$s).
|
||||||
|
\n
|
||||||
|
\n계속하시겠습니까\?</string>
|
||||||
|
<string name="unread">읽지 않음</string>
|
||||||
|
<string name="cancelled">취소됨</string>
|
||||||
|
<string name="no_chapters_error">검색된 회차가 없습니다</string>
|
||||||
|
<string name="source_unsupported">지원되지 않는 소스입니다</string>
|
||||||
|
<string name="download_notifier_download_finish">다운로드 완료</string>
|
||||||
|
<string name="spen_previous_page">이전 페이지</string>
|
||||||
|
<string name="action_show_manga">만화 보기</string>
|
||||||
|
<string name="action_desc">내림차순</string>
|
||||||
|
<string name="theme_monet">활력</string>
|
||||||
|
<string name="action_display_cover_only_grid">표지 그리드</string>
|
||||||
|
<string name="action_reorganize_by">재정렬</string>
|
||||||
|
<string name="action_newest">최신 순</string>
|
||||||
|
<string name="pref_category_theme">테마</string>
|
||||||
|
<string name="theme_midnightdusk">한밤중의 어둠</string>
|
||||||
|
<string name="ext_obsolete">지원 종료</string>
|
||||||
|
<string name="tracker_not_logged_in">로그인 불가: %1$s</string>
|
||||||
|
<string name="no_results_found">검색 결과가 없습니다</string>
|
||||||
|
<string name="pref_dual_page_invert_summary">이중 페이지 분할 시 배치가 읽는 방향과 다를 경우 사용하세요</string>
|
||||||
|
<string name="ext_nsfw_short">19금</string>
|
||||||
|
<string name="action_filter_started">읽는 중</string>
|
||||||
|
<string name="action_display_show_tabs">카테고리 탭 보이기</string>
|
||||||
|
<string name="action_sort_chapter_fetch_date">정보가 갱신된 시간 순</string>
|
||||||
|
<string name="action_sort_count">만화의 총 개수</string>
|
||||||
|
<string name="action_webview_back">뒤로가기</string>
|
||||||
|
<string name="battery_optimization_disabled">배터리 최적화가 이미 꺼져 있습니다</string>
|
||||||
|
<string name="action_order_by_chapter_number">회차 번호 순</string>
|
||||||
|
<string name="action_move_to_top">맨 위로 이동</string>
|
||||||
|
<string name="action_sort_last_checked">마지막으로 확인한 순</string>
|
||||||
|
<string name="action_order_by_upload_date">업로드 날짜 순</string>
|
||||||
|
<string name="action_move_to_bottom">맨 아래로 이동</string>
|
||||||
|
<string name="action_asc">오름차순</string>
|
||||||
|
<string name="action_oldest">오래된 순</string>
|
||||||
|
<string name="theme_tealturquoise">옥색</string>
|
||||||
|
<string name="recently">최근</string>
|
||||||
|
<string name="theme_strawberrydaiquiri">딸기 칵테일</string>
|
||||||
|
<string name="extension_api_error">확장기능 목록 취득 실패</string>
|
||||||
|
<string name="pref_library_update_refresh_trackers_summary">서재 업데이트 시 트래커 갱신</string>
|
||||||
|
<string name="exclude">제외: %s</string>
|
||||||
|
<string name="unofficial_extension_message">이 확장기능은 공식 확장기능이 아닙니다.</string>
|
||||||
|
<string name="tracking_info">트래커 서비스에 만화 진행 상황을 동기화합니다. 트래킹 버튼을 이용하여 각각의 만화 별로 트래킹을 설정하세요.</string>
|
||||||
|
<string name="webtoon_side_padding_20">20%</string>
|
||||||
|
<string name="webtoon_side_padding_25">25%</string>
|
||||||
|
<string name="tracking_guide">트래커 가이드</string>
|
||||||
|
<string name="enhanced_services">향상된 서비스</string>
|
||||||
|
<string name="webtoon_side_padding_5">5%</string>
|
||||||
|
<string name="webtoon_side_padding_15">15%</string>
|
||||||
|
<string name="pref_download_new_categories_details">카테고리가 다운로드에서 제외된 경우 다른 카테고리에 포함되어 있어도 다운로드 되지 않습니다.</string>
|
||||||
|
<string name="enhanced_tracking_info">특정 소스에 향상된 서비스를 제공합니다. 서재에 만화가 추가될 시 자동으로 트래킹 됩니다.</string>
|
||||||
|
<string name="pref_search_pinned_sources_only">핀 설정된 소스만 포함</string>
|
||||||
|
<string name="backup_restore_content_full">백업 파일에서 데이터가 복구됩니다.
|
||||||
|
\n
|
||||||
|
\n복구 완료 후 없어진 소스를 다시 설치하고 트래킹 서비스에 로그인 해야 합니다.</string>
|
||||||
|
<string name="backup_info">자동 백업이 매우 권장됩니다. 백업 파일은 다른 장소에 나눠 보관하세요.</string>
|
||||||
|
<string name="pref_disable_battery_optimization_summary">백그라운드 서재 업데이트와 라이브러리 업데이트를 도울 수 있습니다</string>
|
||||||
|
<string name="pref_verbose_logging">자세한 로그</string>
|
||||||
|
<string name="pref_verbose_logging_summary">자세한 로그를 시스템 로그에 기록 (성능이 하락할 수 있습니다)</string>
|
||||||
|
<string name="badges_header">배지</string>
|
||||||
|
<string name="date">날짜</string>
|
||||||
|
<string name="local_filter_order_by">정렬</string>
|
||||||
|
<string name="track_started_reading_date">읽기 시작한 날짜</string>
|
||||||
|
<string name="track_finished_reading_date">다 읽은 날짜</string>
|
||||||
|
<plurals name="notification_new_chapters_summary">
|
||||||
|
<item quantity="other">%d개의 만화</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="notification_chapters_generic">
|
||||||
|
<item quantity="other">%1$d개의 새로운 회차</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="skipped_reason_not_caught_up">읽지 않은 회차가 있는 만화를 건너 뛰었습니다</string>
|
||||||
|
<string name="information_empty_category_dialog">등록된 카테고리가 없습니다.</string>
|
||||||
|
<string name="pref_create_folder_per_manga_summary">만화 제목에 따라 폴더 생성</string>
|
||||||
|
<string name="migration_help_guide">소스 이전 설명서</string>
|
||||||
|
<string name="migration_selection_prompt">원본 소스를 선택하세요</string>
|
||||||
|
<string name="action_display_local_badge">로컬 만화</string>
|
||||||
|
<string name="action_display_show_number_of_items">항목 수 보이기</string>
|
||||||
|
<string name="action_disable">끄기</string>
|
||||||
|
<string name="action_pin">핀</string>
|
||||||
|
<string name="action_unpin">핀 해제</string>
|
||||||
|
<string name="action_cancel_all">모두 취소</string>
|
||||||
|
<string name="cancel_all_for_series">이 만화의 항목을 모두 취소</string>
|
||||||
|
<string name="action_webview_forward">앞으로가기</string>
|
||||||
|
<string name="pref_create_folder_per_manga">각각의 폴더에 페이지 저장</string>
|
||||||
|
<string name="action_faq_and_guides">FAQ와 설명서</string>
|
||||||
|
<string name="pref_update_only_started">읽은 회차 없음</string>
|
||||||
|
<string name="action_move_to_top_all_for_series">만화 전체를 맨 위로 이동</string>
|
||||||
|
<string name="action_webview_refresh">새로고침</string>
|
||||||
|
<string name="theme_greenapple">초록 사과</string>
|
||||||
|
<string name="theme_tako">문어</string>
|
||||||
|
<string name="theme_yinyang">음과 양</string>
|
||||||
|
<string name="theme_yotsuba">요츠바</string>
|
||||||
|
<string name="pref_side_nav_icon_alignment">네비게이션 아이콘 정렬</string>
|
||||||
|
<string name="alignment_top">위</string>
|
||||||
|
<string name="alignment_center">중앙</string>
|
||||||
|
<string name="alignment_bottom">아래</string>
|
||||||
|
<string name="pref_category_nsfw_content">19금 소스</string>
|
||||||
|
<string name="pref_show_nsfw_source">소스 또는 확장기능 목록에 보이기</string>
|
||||||
|
<string name="parental_controls_info">오류 또는 잘못된 분류로 인하여 19금 콘텐츠가 표시될 가능성이 있습니다.</string>
|
||||||
|
<string name="action_show_errors">터치하여 자세히 보기</string>
|
||||||
|
<string name="update_72hour">3일</string>
|
||||||
|
<string name="restrictions">제한: %s</string>
|
||||||
|
<string name="pref_library_update_categories_details">카테고리가 업데이트에서 제외된 경우 다른 카테고리에 포함되어 있어도 업데이트 되지 않습니다.</string>
|
||||||
|
<string name="ext_updates_pending">업데이트 대기 중</string>
|
||||||
|
<string name="pref_library_update_refresh_metadata_summary">서재 업데이트 시 새로운 표지와 설명 확인</string>
|
||||||
|
<string name="notification_chapters_single_and_more">%1$s화와 그 이후 %2$d화</string>
|
||||||
|
<string name="notification_chapters_multiple">%1$s화</string>
|
||||||
|
<plurals name="notification_chapters_multiple_and_more">
|
||||||
|
<item quantity="other">%1$s화와 그 이후 %2$d화</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="file_picker_error">파일 선택 어플리케이션이 없습니다</string>
|
||||||
</resources>
|
</resources>
|
@ -83,7 +83,7 @@
|
|||||||
<string name="all">Semua</string>
|
<string name="all">Semua</string>
|
||||||
<string name="pref_library_update_restriction">Sekatan kemas kini automatik peranti</string>
|
<string name="pref_library_update_restriction">Sekatan kemas kini automatik peranti</string>
|
||||||
<string name="charging">Ketika mengecas</string>
|
<string name="charging">Ketika mengecas</string>
|
||||||
<string name="pref_update_only_non_completed">Siri sudah selesai</string>
|
<string name="pref_update_only_non_completed">Dengan status \"Sudah selesai\"</string>
|
||||||
<string name="pref_auto_update_manga_sync">Kemas kini selepas dibaca</string>
|
<string name="pref_auto_update_manga_sync">Kemas kini selepas dibaca</string>
|
||||||
<string name="pref_start_screen">Skrin permulaan</string>
|
<string name="pref_start_screen">Skrin permulaan</string>
|
||||||
<string name="default_category">Kategori lalai</string>
|
<string name="default_category">Kategori lalai</string>
|
||||||
@ -674,8 +674,8 @@
|
|||||||
<string name="clear_database_source_item_count">%1$d manga bukan pustaka dalam pangkalan data</string>
|
<string name="clear_database_source_item_count">%1$d manga bukan pustaka dalam pangkalan data</string>
|
||||||
<string name="extension_api_error">Gagal mendapatkan senarai sambungan</string>
|
<string name="extension_api_error">Gagal mendapatkan senarai sambungan</string>
|
||||||
<string name="privacy_policy">Dasar privasi</string>
|
<string name="privacy_policy">Dasar privasi</string>
|
||||||
<string name="pref_library_update_manga_restriction">Langkau mengemaskini</string>
|
<string name="pref_library_update_manga_restriction">Langkau mengemaskini siri</string>
|
||||||
<string name="pref_update_only_completely_read">Ada bab yang belum dibaca</string>
|
<string name="pref_update_only_completely_read">Dengan bab yang belum dibaca</string>
|
||||||
<string name="library_errors_help">Untuk bantuan cara menyelesaikan ralat kemas kini pustaka, lihat %1$s</string>
|
<string name="library_errors_help">Untuk bantuan cara menyelesaikan ralat kemas kini pustaka, lihat %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">Simpan sebagai arkib CBZ</string>
|
<string name="save_chapter_as_cbz">Simpan sebagai arkib CBZ</string>
|
||||||
<string name="cancelled">Dibatalkan</string>
|
<string name="cancelled">Dibatalkan</string>
|
||||||
@ -691,7 +691,7 @@
|
|||||||
\nAdakah anda masih ingin meneruskan\?</string>
|
\nAdakah anda masih ingin meneruskan\?</string>
|
||||||
<string name="action_display_cover_only_grid">Cuma grid muka hadapan</string>
|
<string name="action_display_cover_only_grid">Cuma grid muka hadapan</string>
|
||||||
<string name="skipped_reason_completed">Dilangkau kerana siri sudah lengkap</string>
|
<string name="skipped_reason_completed">Dilangkau kerana siri sudah lengkap</string>
|
||||||
<string name="pref_update_only_started">Tiada bab dibaca</string>
|
<string name="pref_update_only_started">Yang mana bacaan belum dimulakan</string>
|
||||||
<string name="skipped_reason_not_caught_up">Dilangkau kerana ada bab yang belum dibaca</string>
|
<string name="skipped_reason_not_caught_up">Dilangkau kerana ada bab yang belum dibaca</string>
|
||||||
<string name="skipped_reason_not_started">Dilangkau kerana masih belum membaca mana-mana bab</string>
|
<string name="skipped_reason_not_started">Dilangkau kerana masih belum membaca mana-mana bab</string>
|
||||||
<string name="pref_landscape_zoom">Zum imej landskap</string>
|
<string name="pref_landscape_zoom">Zum imej landskap</string>
|
||||||
@ -699,7 +699,10 @@
|
|||||||
<string name="notification_update_error">%1$d kemas kini gagal</string>
|
<string name="notification_update_error">%1$d kemas kini gagal</string>
|
||||||
<string name="notification_update_skipped">%1$d kemas kini dilangkau</string>
|
<string name="notification_update_skipped">%1$d kemas kini dilangkau</string>
|
||||||
<string name="channel_skipped">Dilangkau</string>
|
<string name="channel_skipped">Dilangkau</string>
|
||||||
<string name="learn_more">Ketahui selebihnya</string>
|
<string name="learn_more">Ketik untuk ketahui selebihnya</string>
|
||||||
<string name="rotation_reverse_portrait">Potret terbalik</string>
|
<string name="rotation_reverse_portrait">Potret terbalik</string>
|
||||||
<string name="action_move_to_top_all_for_series">Alih siri ke atas</string>
|
<string name="action_move_to_top_all_for_series">Alih siri ke atas</string>
|
||||||
|
<string name="disabled_nav">Dinyahkan</string>
|
||||||
|
<string name="error_saving_picture">Ralat menyimpan gambar</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">Versi baharu tersedia daripada pengeluaran rasmi. Ketik untuk mengetahui bagaimana untuk berhijrah daripada keluaran tidak rasmi F-Droid.</string>
|
||||||
</resources>
|
</resources>
|
@ -711,7 +711,8 @@
|
|||||||
<string name="pref_auto_clear_chapter_cache">Tøm kapittelbufferen ved lukking av appen</string>
|
<string name="pref_auto_clear_chapter_cache">Tøm kapittelbufferen ved lukking av appen</string>
|
||||||
<string name="notification_update_error">%1$d oppdatering(er) mislyktes</string>
|
<string name="notification_update_error">%1$d oppdatering(er) mislyktes</string>
|
||||||
<string name="notification_update_skipped">%1$d oppdatering(er) hoppet over</string>
|
<string name="notification_update_skipped">%1$d oppdatering(er) hoppet over</string>
|
||||||
<string name="learn_more">Lær mer</string>
|
<string name="learn_more">Trykk for å finne ut mer</string>
|
||||||
<string name="skipped_reason_not_started">Hoppet over fordi ingen kapitler er lest</string>
|
<string name="skipped_reason_not_started">Hoppet over fordi ingen kapitler er lest</string>
|
||||||
<string name="channel_skipped">Hoppet over</string>
|
<string name="channel_skipped">Hoppet over</string>
|
||||||
|
<string name="disabled_nav">Deaktivert</string>
|
||||||
</resources>
|
</resources>
|
37
app/src/main/res/values-night/color_lavender.xml
Normal file
37
app/src/main/res/values-night/color_lavender.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Colors for Lavender theme
|
||||||
|
~
|
||||||
|
~ Color scheme by Osyx
|
||||||
|
~
|
||||||
|
~ Key colors:
|
||||||
|
~ Primary #A177FF
|
||||||
|
~ Secondary #A177FF
|
||||||
|
~ Tertiary #5E25E1
|
||||||
|
~ Neutral #111129
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<color name="lavender_primary">#A177FF</color>
|
||||||
|
<color name="lavender_onPrimary">#111129</color>
|
||||||
|
<color name="lavender_primaryContainer">#A177FF</color>
|
||||||
|
<color name="lavender_onPrimaryContainer">#111129</color>
|
||||||
|
<color name="lavender_secondary">#A177FF</color>
|
||||||
|
<color name="lavender_onSecondary">#111129</color>
|
||||||
|
<color name="lavender_secondaryContainer">#A177FF</color>
|
||||||
|
<color name="lavender_onSecondaryContainer">#111129</color>
|
||||||
|
<color name="lavender_tertiary">#5E25E1</color>
|
||||||
|
<color name="lavender_onTertiary">#E8E8E8</color>
|
||||||
|
<color name="lavender_tertiaryContainer">#111129</color>
|
||||||
|
<color name="lavender_onTertiaryContainer">#DEE8FF</color>
|
||||||
|
<color name="lavender_background">#111129</color>
|
||||||
|
<color name="lavender_onBackground">#DEE8FF</color>
|
||||||
|
<color name="lavender_surface">#111129</color>
|
||||||
|
<color name="lavender_onSurface">#DEE8FF</color>
|
||||||
|
<color name="lavender_surfaceVariant">#2CB6B6B6</color>
|
||||||
|
<color name="lavender_onSurfaceVariant">#E8E8E8</color>
|
||||||
|
<color name="lavender_outline">#A8905FFF</color>
|
||||||
|
<color name="lavender_inverseOnSurface">#DEE8FF</color>
|
||||||
|
<color name="lavender_inverseSurface">#221247</color>
|
||||||
|
<color name="lavender_primaryInverse">#A177FF</color>
|
||||||
|
<color name="lavender_elevationOverlay">@color/lavender_primary</color>
|
||||||
|
</resources>
|
@ -1,2 +1,83 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="download_notifier_title_error">ତ୍ରୁଟି</string>
|
||||||
|
<string name="date">ତାରିଖ</string>
|
||||||
|
<string name="privacy_policy">ଗୋପନୀୟତା ନୀତି</string>
|
||||||
|
<string name="black_background">କଳା</string>
|
||||||
|
<string name="white_background">ଧଳା</string>
|
||||||
|
<string name="nav_zone_left">ବାମ</string>
|
||||||
|
<string name="nav_zone_right">ଡାହାଣ</string>
|
||||||
|
<string name="left_to_right_viewer">ବାମରୁ ଡାହାଣ</string>
|
||||||
|
<string name="right_to_left_viewer">ଡାହାଣରୁ ବାମ</string>
|
||||||
|
<string name="zoom_start_left">ବାମ</string>
|
||||||
|
<string name="zoom_start_right">ଡାହାଣ</string>
|
||||||
|
<string name="version">ସଂସ୍କରଣ</string>
|
||||||
|
<string name="description">ବର୍ଣ୍ଣନା</string>
|
||||||
|
<string name="in_library">ଲାଇବ୍ରେରୀରେ</string>
|
||||||
|
<string name="manga_info_full_title_label">ଆଖ୍ୟା</string>
|
||||||
|
<string name="copied_to_clipboard">କ୍ଲିପବୋର୍ଡରେ କପି କରିନିଆଗଲା:
|
||||||
|
\n%1$s</string>
|
||||||
|
<string name="manga_cover">ମଲାଟ</string>
|
||||||
|
<string name="learn_more">ଅଧିକ ଜାଣନ୍ତୁ</string>
|
||||||
|
<string name="channel_progress">ପ୍ରଗତି</string>
|
||||||
|
<string name="email">ଇମେଲ୍ ଠିକଣା</string>
|
||||||
|
<string name="action_filter_started">ଆରମ୍ଭ କରିଛନ୍ତି</string>
|
||||||
|
<string name="action_sort_alpha">ବର୍ଣ୍ଣମାଳା ଅନୁଯାୟୀ</string>
|
||||||
|
<string name="action_newest">ସବୁଠୁ ନୂଆ</string>
|
||||||
|
<string name="action_asc">ଆରୋହଣ</string>
|
||||||
|
<string name="ext_language_info">ଭାଷା: %1$s</string>
|
||||||
|
<string name="action_oldest">ସବୁଠୁ ପୁରୁଣା</string>
|
||||||
|
<string name="add_to_library">ଲାଇବ୍ରେରୀରେ ଯୋଡ଼ନ୍ତୁ</string>
|
||||||
|
<string name="action_desc">ଅବରୋହଣ</string>
|
||||||
|
<string name="pref_category_library">ଲାଇବ୍ରେରୀ</string>
|
||||||
|
<string name="pref_category_reader">ପାଠକ</string>
|
||||||
|
<plurals name="relative_time">
|
||||||
|
<item quantity="one">ଗତକାଲି</item>
|
||||||
|
<item quantity="other">%1$d ଦିନ ପୂର୍ବେ</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="title">ଆଖ୍ୟା</string>
|
||||||
|
<string name="action_sort">ସଜାନ୍ତୁ</string>
|
||||||
|
<string name="name">ନାମ</string>
|
||||||
|
<string name="history">ଇତିବୃତ୍ତି</string>
|
||||||
|
<string name="label_default">ଡିଫଲ୍ଟ</string>
|
||||||
|
<string name="manga">ମାଙ୍ଗା</string>
|
||||||
|
<string name="action_edit">ସମ୍ପାଦନା</string>
|
||||||
|
<string name="action_add">ଯୋଡ଼ନ୍ତୁ</string>
|
||||||
|
<string name="action_edit_cover">ମଲାଟ ସମ୍ପାଦନା</string>
|
||||||
|
<string name="on">ଚାଲୁ</string>
|
||||||
|
<string name="off">ବନ୍ଦ</string>
|
||||||
|
<string name="action_sort_date_added">ଯୋଡ଼ାଯିବା ତାରିଖ</string>
|
||||||
|
<string name="action_select_all">ସବୁ ଚୟନ କରନ୍ତୁ</string>
|
||||||
|
<string name="pref_incognito_mode">ଅପରିଚିତ ମୋଡ୍</string>
|
||||||
|
<string name="action_display_language_badge">ଭାଷା</string>
|
||||||
|
<string name="action_menu">ମେନୁ</string>
|
||||||
|
<string name="action_filter">ଶୋଧନ</string>
|
||||||
|
<string name="action_filter_downloaded">ଡାଉନଲୋଡ୍ ହୋଇଅଛି</string>
|
||||||
|
<string name="action_filter_bookmarked">ବୁକମାର୍କ ହୋଇଅଛି</string>
|
||||||
|
<string name="action_filter_tracked">ଟ୍ରାକ୍ ହୋଇଅଛି</string>
|
||||||
|
<string name="action_filter_unread">ପଢ଼ି ନାହାଁନ୍ତି</string>
|
||||||
|
<string name="action_filter_empty">ଶୋଧକ ହଟାନ୍ତୁ</string>
|
||||||
|
<string name="action_sort_count">ସର୍ବମୋଟ ମାଙ୍ଗା</string>
|
||||||
|
<string name="action_sort_last_read">ଶେଷ ପଠନ</string>
|
||||||
|
<string name="action_sort_chapter_fetch_date">ଅଣାଯିବା ତାରିଖ</string>
|
||||||
|
<string name="pref_category_advanced">ବିକଶିତ</string>
|
||||||
|
<string name="pref_category_theme">ଥିମ୍</string>
|
||||||
|
<string name="pref_theme_mode">ଗାଢ଼ ମୋଡ୍</string>
|
||||||
|
<string name="theme_light">ବନ୍ଦ</string>
|
||||||
|
<string name="theme_dark">ଚାଲୁ</string>
|
||||||
|
<string name="pref_app_theme">ଆପ୍ ଥିମ୍</string>
|
||||||
|
<string name="password">ପାସ୍ୱାର୍ଡ଼</string>
|
||||||
|
<string name="update_never">ବନ୍ଦ</string>
|
||||||
|
<string name="pref_category_appearance">ରୂପ</string>
|
||||||
|
<string name="theme_system">ସିଷ୍ଟମ୍ କୁ ଅନୁସରଣ କରିବା</string>
|
||||||
|
<string name="relative_time_today">ଆଜି</string>
|
||||||
|
<string name="portrait">ପୋର୍ଟ୍ରେଟ୍</string>
|
||||||
|
<string name="landscape">ଲ୍ୟାଣ୍ଡସ୍କେପ୍</string>
|
||||||
|
<string name="update_48hour">ପ୍ରତି ୨ ଦିନରେ</string>
|
||||||
|
<string name="ext_app_info">ଆପ୍ ସୂଚନା</string>
|
||||||
|
<string name="ext_version_info">ସଂସ୍କରଣ: %1$s</string>
|
||||||
|
<string name="pref_keep_screen_on">ସ୍କ୍ରିନ୍ ସଚଳ ରଖନ୍ତୁ</string>
|
||||||
|
<string name="update_6hour">ପ୍ରତି ୬ ଘଣ୍ଟାରେ</string>
|
||||||
|
<string name="update_12hour">ପ୍ରତି ୧୨ ଘଣ୍ଟାରେ</string>
|
||||||
|
<string name="update_72hour">ପ୍ରତି ୩ ଦିନରେ</string>
|
||||||
|
</resources>
|
@ -82,7 +82,7 @@
|
|||||||
<string name="all">Todas</string>
|
<string name="all">Todas</string>
|
||||||
<string name="pref_library_update_restriction">Restrições do dispositivo para atualizações automáticas</string>
|
<string name="pref_library_update_restriction">Restrições do dispositivo para atualizações automáticas</string>
|
||||||
<string name="charging">Carregando</string>
|
<string name="charging">Carregando</string>
|
||||||
<string name="pref_update_only_non_completed">É uma série finalizada</string>
|
<string name="pref_update_only_non_completed">Com o estado \"Completo\"</string>
|
||||||
<string name="pref_auto_update_manga_sync">Atualizar o progresso após a leitura</string>
|
<string name="pref_auto_update_manga_sync">Atualizar o progresso após a leitura</string>
|
||||||
<string name="pref_start_screen">Tela inicial</string>
|
<string name="pref_start_screen">Tela inicial</string>
|
||||||
<string name="default_category">Categoria padrão</string>
|
<string name="default_category">Categoria padrão</string>
|
||||||
@ -672,7 +672,7 @@
|
|||||||
<string name="pref_verbose_logging_summary">Imprime registros detalhados no registro de eventos do sistema (reduz o desempenho do aplicativo)</string>
|
<string name="pref_verbose_logging_summary">Imprime registros detalhados no registro de eventos do sistema (reduz o desempenho do aplicativo)</string>
|
||||||
<string name="pref_verbose_logging">Registro de eventos verboso</string>
|
<string name="pref_verbose_logging">Registro de eventos verboso</string>
|
||||||
<string name="action_display_language_badge">Idioma</string>
|
<string name="action_display_language_badge">Idioma</string>
|
||||||
<string name="notification_size_warning">Aviso: atualizações com muitos itens prejudicam as fontes e podem deixar as atualizações lentas e aumentar o uso da bateria</string>
|
<string name="notification_size_warning">Atualizações com muitos itens prejudicam as fontes e podem deixar as atualizações lentas e aumentar o uso da bateria</string>
|
||||||
<string name="label_warning">Aviso</string>
|
<string name="label_warning">Aviso</string>
|
||||||
<string name="backup_info">Backups automáticos são altamente recomendados. Você deve manter cópias em outros locais também.</string>
|
<string name="backup_info">Backups automáticos são altamente recomendados. Você deve manter cópias em outros locais também.</string>
|
||||||
<string name="connected_to_wifi">Somente no Wi-Fi</string>
|
<string name="connected_to_wifi">Somente no Wi-Fi</string>
|
||||||
@ -686,8 +686,8 @@
|
|||||||
<string name="database_clean">Banco de dados limpo</string>
|
<string name="database_clean">Banco de dados limpo</string>
|
||||||
<string name="extension_api_error">Erro ao obter a lista de extensões</string>
|
<string name="extension_api_error">Erro ao obter a lista de extensões</string>
|
||||||
<string name="privacy_policy">Política de privacidade</string>
|
<string name="privacy_policy">Política de privacidade</string>
|
||||||
<string name="pref_update_only_completely_read">Possui capítulos não lidos</string>
|
<string name="pref_update_only_completely_read">Com capítulos não lidos</string>
|
||||||
<string name="pref_library_update_manga_restriction">Pular a atualização</string>
|
<string name="pref_library_update_manga_restriction">Pular a atualização de títulos</string>
|
||||||
<string name="library_errors_help">Para obter ajuda sobre como corrigir erros de atualização da biblioteca, veja %1$s</string>
|
<string name="library_errors_help">Para obter ajuda sobre como corrigir erros de atualização da biblioteca, veja %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">Salvar como arquivo CBZ</string>
|
<string name="save_chapter_as_cbz">Salvar como arquivo CBZ</string>
|
||||||
<string name="publishing_finished">Publicação finalizada</string>
|
<string name="publishing_finished">Publicação finalizada</string>
|
||||||
@ -704,15 +704,17 @@
|
|||||||
<string name="pref_landscape_zoom">Dar zoom em imagens horizontais</string>
|
<string name="pref_landscape_zoom">Dar zoom em imagens horizontais</string>
|
||||||
<string name="action_display_cover_only_grid">Grade somente com capas</string>
|
<string name="action_display_cover_only_grid">Grade somente com capas</string>
|
||||||
<string name="action_filter_started">Iniciado</string>
|
<string name="action_filter_started">Iniciado</string>
|
||||||
<string name="pref_update_only_started">Sem capítulos lidos</string>
|
<string name="pref_update_only_started">Que não tiveram a leitura iniciada</string>
|
||||||
<string name="skipped_reason_completed">Pulado porque a série está finalizada</string>
|
<string name="skipped_reason_completed">Pulado porque a série está finalizada</string>
|
||||||
<string name="skipped_reason_not_caught_up">Pulado porque há capítulos não lidos</string>
|
<string name="skipped_reason_not_caught_up">Pulado porque há capítulos não lidos</string>
|
||||||
<string name="skipped_reason_not_started">Pulado porque nenhum capítulo foi lido</string>
|
<string name="skipped_reason_not_started">Pulado porque nenhum capítulo foi lido</string>
|
||||||
<string name="notification_update_skipped">%1$d atualização(ões) pulada(s)</string>
|
<string name="notification_update_skipped">%1$d atualização(ões) pulada(s)</string>
|
||||||
<string name="channel_skipped">Puladas</string>
|
<string name="channel_skipped">Puladas</string>
|
||||||
<string name="notification_update_error">%1$d atualização(ões) falhou(aram)</string>
|
<string name="notification_update_error">%1$d atualização(ões) falhou(aram)</string>
|
||||||
<string name="learn_more">Saiba mais</string>
|
<string name="learn_more">Toque para saber mais</string>
|
||||||
<string name="rotation_reverse_portrait">Retrato invertido</string>
|
<string name="rotation_reverse_portrait">Retrato invertido</string>
|
||||||
<string name="action_move_to_top_all_for_series">Mover série para o topo</string>
|
<string name="action_move_to_top_all_for_series">Mover série para o topo</string>
|
||||||
<string name="disabled_nav">Desativado</string>
|
<string name="disabled_nav">Desativado</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">Uma nova versão está disponível nos releases oficiais. Toque para saber como migrar dos releases não oficiais do F-Droid.</string>
|
||||||
|
<string name="error_saving_picture">Erro ao salvar a imagem</string>
|
||||||
</resources>
|
</resources>
|
@ -620,4 +620,7 @@
|
|||||||
<string name="theme_tako">Tako</string>
|
<string name="theme_tako">Tako</string>
|
||||||
<string name="theme_yinyang">Yin și Yang</string>
|
<string name="theme_yinyang">Yin și Yang</string>
|
||||||
<string name="theme_yotsuba">Yotsuba</string>
|
<string name="theme_yotsuba">Yotsuba</string>
|
||||||
|
<string name="publishing_finished">Editare finalizată</string>
|
||||||
|
<string name="cancelled">Anulat</string>
|
||||||
|
<string name="on_hiatus">În pauză</string>
|
||||||
</resources>
|
</resources>
|
@ -156,7 +156,7 @@
|
|||||||
<string name="pref_rotation_type">Ориентация по умолчанию</string>
|
<string name="pref_rotation_type">Ориентация по умолчанию</string>
|
||||||
<string name="pref_show_page_number">Номер страницы</string>
|
<string name="pref_show_page_number">Номер страницы</string>
|
||||||
<string name="pref_start_screen">Начальный экран</string>
|
<string name="pref_start_screen">Начальный экран</string>
|
||||||
<string name="pref_update_only_non_completed">Завершенная серия</string>
|
<string name="pref_update_only_non_completed">Серия завершена</string>
|
||||||
<string name="pref_viewer_type">Режим чтения</string>
|
<string name="pref_viewer_type">Режим чтения</string>
|
||||||
<string name="pref_zoom_start">Стартовая позиция увеличения</string>
|
<string name="pref_zoom_start">Стартовая позиция увеличения</string>
|
||||||
<string name="reading">Читаю</string>
|
<string name="reading">Читаю</string>
|
||||||
@ -696,7 +696,7 @@
|
|||||||
<string name="pref_verbose_logging_summary">Записывать подробный журнал в системный журнал (снижает производительность приложения)</string>
|
<string name="pref_verbose_logging_summary">Записывать подробный журнал в системный журнал (снижает производительность приложения)</string>
|
||||||
<string name="action_display_language_badge">Язык</string>
|
<string name="action_display_language_badge">Язык</string>
|
||||||
<string name="label_warning">Предупреждение</string>
|
<string name="label_warning">Предупреждение</string>
|
||||||
<string name="notification_size_warning">Предупреждение: большое количество обновлений серий могут привести к замедлению работы источников и увеличению расхода батареи</string>
|
<string name="notification_size_warning">Большое количество обновлений серий могут привести к замедлению работы источников и увеличению расхода батареи</string>
|
||||||
<string name="backup_info">Настоятельно рекомендуется использовать автоматические резервные копии. Вы также должны хранить копии в разных папках.</string>
|
<string name="backup_info">Настоятельно рекомендуется использовать автоматические резервные копии. Вы также должны хранить копии в разных папках.</string>
|
||||||
<string name="connected_to_wifi">Только по Wi-Fi</string>
|
<string name="connected_to_wifi">Только по Wi-Fi</string>
|
||||||
<string name="update_72hour">Каждые 3 дня</string>
|
<string name="update_72hour">Каждые 3 дня</string>
|
||||||
@ -709,8 +709,8 @@
|
|||||||
<string name="database_clean">Очистка базы данных</string>
|
<string name="database_clean">Очистка базы данных</string>
|
||||||
<string name="extension_api_error">Не удалось получить список расширений</string>
|
<string name="extension_api_error">Не удалось получить список расширений</string>
|
||||||
<string name="privacy_policy">Политика конфиденциальности</string>
|
<string name="privacy_policy">Политика конфиденциальности</string>
|
||||||
<string name="pref_update_only_completely_read">Имеет непрочитанные главы</string>
|
<string name="pref_update_only_completely_read">Есть непрочитанные главы</string>
|
||||||
<string name="pref_library_update_manga_restriction">Пропускать обновление</string>
|
<string name="pref_library_update_manga_restriction">Пропускать обновления</string>
|
||||||
<string name="library_errors_help">Для помощи в исправлении ошибок библиотеки, нажать %1$s</string>
|
<string name="library_errors_help">Для помощи в исправлении ошибок библиотеки, нажать %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">Сохранить как архив CBZ</string>
|
<string name="save_chapter_as_cbz">Сохранить как архив CBZ</string>
|
||||||
<string name="cancelled">Отменено</string>
|
<string name="cancelled">Отменено</string>
|
||||||
@ -731,11 +731,13 @@
|
|||||||
<string name="skipped_reason_completed">Пропущено, так как серия завершена</string>
|
<string name="skipped_reason_completed">Пропущено, так как серия завершена</string>
|
||||||
<string name="skipped_reason_not_caught_up">Пропущено, потому что есть непрочитанные главы</string>
|
<string name="skipped_reason_not_caught_up">Пропущено, потому что есть непрочитанные главы</string>
|
||||||
<string name="skipped_reason_not_started">Пропущено, потому что серия не начата</string>
|
<string name="skipped_reason_not_started">Пропущено, потому что серия не начата</string>
|
||||||
<string name="learn_more">Подробнее</string>
|
<string name="learn_more">Нажать для подробностей</string>
|
||||||
<string name="channel_skipped">Пропущено</string>
|
<string name="channel_skipped">Пропущено</string>
|
||||||
<string name="notification_update_error">%1$d обновление(ий) не удалось</string>
|
<string name="notification_update_error">%1$d обновление(ий) не удалось</string>
|
||||||
<string name="notification_update_skipped">%1$d обновление(ий) пропущено</string>
|
<string name="notification_update_skipped">%1$d обновление(ий) пропущено</string>
|
||||||
<string name="rotation_reverse_portrait">Портретная наоборот</string>
|
<string name="rotation_reverse_portrait">Портретная наоборот</string>
|
||||||
<string name="action_move_to_top_all_for_series">Переместить серию в начало</string>
|
<string name="action_move_to_top_all_for_series">Переместить серию в начало</string>
|
||||||
<string name="disabled_nav">Отключено</string>
|
<string name="disabled_nav">Отключено</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">Новая версия доступна на оф. странице Tachiyomi. Нажмите, чтобы узнать как мигрировать с неофициальной версии из F-Droid.</string>
|
||||||
|
<string name="error_saving_picture">Не удалось сохранить изображение</string>
|
||||||
</resources>
|
</resources>
|
@ -689,7 +689,7 @@
|
|||||||
<string name="save_chapter_as_cbz">Sarva comente archìviu CBZ</string>
|
<string name="save_chapter_as_cbz">Sarva comente archìviu CBZ</string>
|
||||||
<string name="library_errors_help">Pro tènnere un\'agiudu pro acontzare sos errores de agiornamentu de sa biblioteca pòmpia·ti %1$s</string>
|
<string name="library_errors_help">Pro tènnere un\'agiudu pro acontzare sos errores de agiornamentu de sa biblioteca pòmpia·ti %1$s</string>
|
||||||
<string name="pref_library_update_manga_restriction">Brinca sos agiornamentos</string>
|
<string name="pref_library_update_manga_restriction">Brinca sos agiornamentos</string>
|
||||||
<string name="pref_update_only_completely_read">Tenet capìtulos non lèghidos</string>
|
<string name="pref_update_only_completely_read">Cun capìtulos non lèghidos</string>
|
||||||
<string name="action_faq_and_guides">PF e ghias</string>
|
<string name="action_faq_and_guides">PF e ghias</string>
|
||||||
<string name="publishing_finished">Publicatzione acabada</string>
|
<string name="publishing_finished">Publicatzione acabada</string>
|
||||||
<string name="on_hiatus">In pàusa</string>
|
<string name="on_hiatus">In pàusa</string>
|
||||||
@ -700,7 +700,7 @@
|
|||||||
<string name="pref_landscape_zoom">Ismànnia s\'immàgine in orizontale</string>
|
<string name="pref_landscape_zoom">Ismànnia s\'immàgine in orizontale</string>
|
||||||
<string name="action_filter_started">Incumintzadu</string>
|
<string name="action_filter_started">Incumintzadu</string>
|
||||||
<string name="action_display_cover_only_grid">Grìllia cun coberteddas ebbia</string>
|
<string name="action_display_cover_only_grid">Grìllia cun coberteddas ebbia</string>
|
||||||
<string name="pref_update_only_started">Perunu capìtulu lèghidu</string>
|
<string name="pref_update_only_started">No incumintzadas</string>
|
||||||
<string name="confirm_manga_add_duplicate">Tenes un\'elementu in sa biblioteca tua cun su matessi nùmene ma dae una fonte diferente (%1$s).
|
<string name="confirm_manga_add_duplicate">Tenes un\'elementu in sa biblioteca tua cun su matessi nùmene ma dae una fonte diferente (%1$s).
|
||||||
\n
|
\n
|
||||||
\nBoles sighire su matessi\?</string>
|
\nBoles sighire su matessi\?</string>
|
||||||
@ -708,10 +708,13 @@
|
|||||||
<string name="skipped_reason_completed">Brincadu ca sa sèrie est acabada</string>
|
<string name="skipped_reason_completed">Brincadu ca sa sèrie est acabada</string>
|
||||||
<string name="skipped_reason_not_caught_up">Brincadu ca bi sunt capìtulos non lèghidos</string>
|
<string name="skipped_reason_not_caught_up">Brincadu ca bi sunt capìtulos non lèghidos</string>
|
||||||
<string name="skipped_reason_not_started">Brincadu ca non bi sunt capìtulos lèghidos</string>
|
<string name="skipped_reason_not_started">Brincadu ca non bi sunt capìtulos lèghidos</string>
|
||||||
<string name="learn_more">Àteras informatziones</string>
|
<string name="learn_more">Toca pro àteras informatziones</string>
|
||||||
<string name="channel_skipped">Brincadu</string>
|
<string name="channel_skipped">Brincadu</string>
|
||||||
<string name="notification_update_error">%1$d agiornamentu(os) fallidu(os)</string>
|
<string name="notification_update_error">%1$d agiornamentu(os) fallidu(os)</string>
|
||||||
<string name="notification_update_skipped">%1$d agiornamentu(os) brincadu(os)</string>
|
<string name="notification_update_skipped">%1$d agiornamentu(os) brincadu(os)</string>
|
||||||
<string name="rotation_reverse_portrait">Verticale a s\'imbesse</string>
|
<string name="rotation_reverse_portrait">Verticale a s\'imbesse</string>
|
||||||
<string name="action_move_to_top_all_for_series">Move sa sèrie cara a pitzos</string>
|
<string name="action_move_to_top_all_for_series">Move sa sèrie cara a pitzos</string>
|
||||||
|
<string name="disabled_nav">Disabilitadu</string>
|
||||||
|
<string name="error_saving_picture">Errore in su sarvamentu de s\'immàgine</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">B\'est una versione noa ufitziale a disponimentu. Toca pro imparare comente tramudare dae sas versiones no ufitziales de F-Droid.</string>
|
||||||
</resources>
|
</resources>
|
@ -274,7 +274,7 @@
|
|||||||
<string name="lock_always">Увек</string>
|
<string name="lock_always">Увек</string>
|
||||||
<string name="lock_never">Никада</string>
|
<string name="lock_never">Никада</string>
|
||||||
<plurals name="lock_after_mins">
|
<plurals name="lock_after_mins">
|
||||||
<item quantity="one">Након %1$s минут</item>
|
<item quantity="one">After 1%1$s minutes</item>
|
||||||
<item quantity="few">Након %1$s минута</item>
|
<item quantity="few">Након %1$s минута</item>
|
||||||
<item quantity="other">Након %1$s минута</item>
|
<item quantity="other">Након %1$s минута</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
@ -495,9 +495,9 @@
|
|||||||
<string name="pref_category_reading_mode">Начин читања</string>
|
<string name="pref_category_reading_mode">Начин читања</string>
|
||||||
<string name="ext_installer_pref">Instaler</string>
|
<string name="ext_installer_pref">Instaler</string>
|
||||||
<plurals name="missing_chapters_warning">
|
<plurals name="missing_chapters_warning">
|
||||||
<item quantity="one">Прескаче се %d поглавље, или не постоји у извору или је филтером издвојено</item>
|
<item quantity="one">Preskače se %d poglavlje,ili ne postoji u izvori ili su izdvojeni filterom</item>
|
||||||
<item quantity="few">Прескаче се %d поглавља, или не постоји у извору или је филтером издвојено</item>
|
<item quantity="few">Preskače se %d poglavlje,ili ne postoji u izvori ili su izdvojeni filterom</item>
|
||||||
<item quantity="other">Прескаче се %d поглавља, или не постоји у извору или је филтером издвојено</item>
|
<item quantity="other">Preskače se %d poglavlje,ili ne postoji u izvori ili su izdvojeni filterom</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_category_auto_download">Аутоматско преузимање</string>
|
<string name="pref_category_auto_download">Аутоматско преузимање</string>
|
||||||
<string name="action_track">Прати</string>
|
<string name="action_track">Прати</string>
|
||||||
@ -529,9 +529,9 @@
|
|||||||
<string name="unknown_status">Nepoznat status</string>
|
<string name="unknown_status">Nepoznat status</string>
|
||||||
<string name="local_filter_order_by">Poređaj po</string>
|
<string name="local_filter_order_by">Poređaj po</string>
|
||||||
<plurals name="num_trackers">
|
<plurals name="num_trackers">
|
||||||
<item quantity="one">%d трекер</item>
|
<item quantity="one">%d tragač</item>
|
||||||
<item quantity="few">%d трекера</item>
|
<item quantity="few">%d tragača</item>
|
||||||
<item quantity="other">%d трекера</item>
|
<item quantity="other">%d tragač</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="enhanced_services">Побољшани сервиси</string>
|
<string name="enhanced_services">Побољшани сервиси</string>
|
||||||
<string name="tracker_not_logged_in">Нисте пријаљени у: %1$s</string>
|
<string name="tracker_not_logged_in">Нисте пријаљени у: %1$s</string>
|
||||||
@ -711,7 +711,7 @@
|
|||||||
\n
|
\n
|
||||||
\nDa li i dalje želite da nastavite\?</string>
|
\nDa li i dalje želite da nastavite\?</string>
|
||||||
<string name="notification_update_error">%1$d ažuriranje nije uspelo</string>
|
<string name="notification_update_error">%1$d ažuriranje nije uspelo</string>
|
||||||
<string name="learn_more">Saznajte više</string>
|
<string name="learn_more">Pritisnite za više</string>
|
||||||
<string name="library_errors_help">Za pomoć o tome kako da popravite greške u ažuriranju kolekcije, pogledajte %1$s</string>
|
<string name="library_errors_help">Za pomoć o tome kako da popravite greške u ažuriranju kolekcije, pogledajte %1$s</string>
|
||||||
<string name="skipped_reason_not_started">Preskočeno jer nijedno poglavlje nije pročitano</string>
|
<string name="skipped_reason_not_started">Preskočeno jer nijedno poglavlje nije pročitano</string>
|
||||||
<string name="channel_skipped">Preskočeno</string>
|
<string name="channel_skipped">Preskočeno</string>
|
||||||
@ -726,4 +726,5 @@
|
|||||||
<string name="notification_update_skipped">%1$d ažuriranje je preskočeno</string>
|
<string name="notification_update_skipped">%1$d ažuriranje je preskočeno</string>
|
||||||
<string name="skipped_reason_completed">Preskočeno jer je serijal završen</string>
|
<string name="skipped_reason_completed">Preskočeno jer je serijal završen</string>
|
||||||
<string name="skipped_reason_not_caught_up">Preskočeno jer ima nepročitanih poglavlja</string>
|
<string name="skipped_reason_not_caught_up">Preskočeno jer ima nepročitanih poglavlja</string>
|
||||||
|
<string name="disabled_nav">Onesposobljen</string>
|
||||||
</resources>
|
</resources>
|
@ -87,7 +87,7 @@
|
|||||||
<string name="all">Alla</string>
|
<string name="all">Alla</string>
|
||||||
<string name="pref_library_update_restriction">Automatiska uppdateringar av enhetsbegränsningar</string>
|
<string name="pref_library_update_restriction">Automatiska uppdateringar av enhetsbegränsningar</string>
|
||||||
<string name="charging">Laddning</string>
|
<string name="charging">Laddning</string>
|
||||||
<string name="pref_update_only_non_completed">Är avslutad serie</string>
|
<string name="pref_update_only_non_completed">Med status \"Avslutat\"</string>
|
||||||
<string name="pref_auto_update_manga_sync">Uppdatera förlopp efter läsning</string>
|
<string name="pref_auto_update_manga_sync">Uppdatera förlopp efter läsning</string>
|
||||||
<string name="pref_start_screen">Startskärm</string>
|
<string name="pref_start_screen">Startskärm</string>
|
||||||
<string name="default_category">Standardkategori</string>
|
<string name="default_category">Standardkategori</string>
|
||||||
@ -686,20 +686,20 @@
|
|||||||
<string name="database_clean">Rengör databasen</string>
|
<string name="database_clean">Rengör databasen</string>
|
||||||
<string name="backup_restore_invalid_uri">Fel: tom URI</string>
|
<string name="backup_restore_invalid_uri">Fel: tom URI</string>
|
||||||
<string name="library_errors_help">För hjälp med att åtgärda fel i biblioteksuppdateringar, se %1$s</string>
|
<string name="library_errors_help">För hjälp med att åtgärda fel i biblioteksuppdateringar, se %1$s</string>
|
||||||
<string name="pref_library_update_manga_restriction">Hoppa över uppdatering</string>
|
<string name="pref_library_update_manga_restriction">Hoppa över att uppdatera titlar</string>
|
||||||
<string name="cancelled">Avbruten</string>
|
<string name="cancelled">Avbruten</string>
|
||||||
<string name="on_hiatus">På uppehåll</string>
|
<string name="on_hiatus">På uppehåll</string>
|
||||||
<string name="publishing_finished">Publiceringen avslutad</string>
|
<string name="publishing_finished">Publiceringen avslutad</string>
|
||||||
<string name="save_chapter_as_cbz">Spara som CBZ-arkiv</string>
|
<string name="save_chapter_as_cbz">Spara som CBZ-arkiv</string>
|
||||||
<string name="privacy_policy">Integritetspolicy</string>
|
<string name="privacy_policy">Integritetspolicy</string>
|
||||||
<string name="action_faq_and_guides">Vanliga frågor och guider</string>
|
<string name="action_faq_and_guides">Vanliga frågor och guider</string>
|
||||||
<string name="pref_update_only_completely_read">Har olästa kapitel</string>
|
<string name="pref_update_only_completely_read">Med olästa kapitel</string>
|
||||||
<string name="extension_api_error">Det gick inte att hämta tilläggslistan</string>
|
<string name="extension_api_error">Det gick inte att hämta tilläggslistan</string>
|
||||||
<string name="webtoon_side_padding_5">5%</string>
|
<string name="webtoon_side_padding_5">5%</string>
|
||||||
<string name="action_show_manga">Visa manga</string>
|
<string name="action_show_manga">Visa manga</string>
|
||||||
<string name="action_filter_started">Startad</string>
|
<string name="action_filter_started">Startad</string>
|
||||||
<string name="action_display_cover_only_grid">Endast omslags-rutnät</string>
|
<string name="action_display_cover_only_grid">Endast omslags-rutnät</string>
|
||||||
<string name="pref_update_only_started">Inga lästa kapitel</string>
|
<string name="pref_update_only_started">Som inte har startats</string>
|
||||||
<string name="pref_navigate_pan">Navigera till pan</string>
|
<string name="pref_navigate_pan">Navigera till pan</string>
|
||||||
<string name="confirm_manga_add_duplicate">Du har en post i ditt bibliotek med samma namn men från en annan källa (%1$s).
|
<string name="confirm_manga_add_duplicate">Du har en post i ditt bibliotek med samma namn men från en annan källa (%1$s).
|
||||||
\n
|
\n
|
||||||
@ -708,10 +708,13 @@
|
|||||||
<string name="skipped_reason_completed">Hoppade över eftersom serien är klar</string>
|
<string name="skipped_reason_completed">Hoppade över eftersom serien är klar</string>
|
||||||
<string name="skipped_reason_not_caught_up">Hoppade över eftersom det finns olästa kapitel</string>
|
<string name="skipped_reason_not_caught_up">Hoppade över eftersom det finns olästa kapitel</string>
|
||||||
<string name="skipped_reason_not_started">Hoppade över eftersom inga kapitel läses</string>
|
<string name="skipped_reason_not_started">Hoppade över eftersom inga kapitel läses</string>
|
||||||
<string name="learn_more">Läs mer</string>
|
<string name="learn_more">Tryck på för att få veta mer</string>
|
||||||
<string name="notification_update_error">%1$d uppdatering(ar) misslyckades</string>
|
<string name="notification_update_error">%1$d uppdatering(ar) misslyckades</string>
|
||||||
<string name="notification_update_skipped">%1$d uppdatering(ar) hoppades över</string>
|
<string name="notification_update_skipped">%1$d uppdatering(ar) hoppades över</string>
|
||||||
<string name="channel_skipped">Hoppat över</string>
|
<string name="channel_skipped">Hoppat över</string>
|
||||||
<string name="rotation_reverse_portrait">Omvänt porträtt</string>
|
<string name="rotation_reverse_portrait">Omvänt porträtt</string>
|
||||||
<string name="action_move_to_top_all_for_series">Flytta serien till toppen</string>
|
<string name="action_move_to_top_all_for_series">Flytta serien till toppen</string>
|
||||||
|
<string name="disabled_nav">Inaktiverad</string>
|
||||||
|
<string name="error_saving_picture">Fel vid lagring av bild</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">En ny version finns tillgänglig i de officiella utgåvorna. Tryck på för att lära dig hur du flyttar från inofficiella F-Droid-versioner.</string>
|
||||||
</resources>
|
</resources>
|
@ -702,4 +702,5 @@
|
|||||||
<string name="channel_skipped">ข้ามแล้ว</string>
|
<string name="channel_skipped">ข้ามแล้ว</string>
|
||||||
<string name="rotation_reverse_portrait">แนวตั้งแบบกลับด้าน</string>
|
<string name="rotation_reverse_portrait">แนวตั้งแบบกลับด้าน</string>
|
||||||
<string name="action_move_to_top_all_for_series">ย้ายเรื่องไปด้านบน</string>
|
<string name="action_move_to_top_all_for_series">ย้ายเรื่องไปด้านบน</string>
|
||||||
|
<string name="disabled_nav">ปิดใช้งาน</string>
|
||||||
</resources>
|
</resources>
|
@ -87,7 +87,7 @@
|
|||||||
<string name="all">Tümü</string>
|
<string name="all">Tümü</string>
|
||||||
<string name="pref_library_update_restriction">Otomatik güncellemeler aygıt kısıtlamaları</string>
|
<string name="pref_library_update_restriction">Otomatik güncellemeler aygıt kısıtlamaları</string>
|
||||||
<string name="charging">Şarj oluyor</string>
|
<string name="charging">Şarj oluyor</string>
|
||||||
<string name="pref_update_only_non_completed">Tamamlanan seriler</string>
|
<string name="pref_update_only_non_completed">\"Tamamlanan\" durumda olan</string>
|
||||||
<string name="pref_auto_update_manga_sync">Okuyunca ilerlemeyi güncelle</string>
|
<string name="pref_auto_update_manga_sync">Okuyunca ilerlemeyi güncelle</string>
|
||||||
<string name="pref_start_screen">Başlangıç ekranı</string>
|
<string name="pref_start_screen">Başlangıç ekranı</string>
|
||||||
<string name="default_category">Varsayılan kategori</string>
|
<string name="default_category">Varsayılan kategori</string>
|
||||||
@ -672,7 +672,7 @@
|
|||||||
<string name="label_warning">Uyarı</string>
|
<string name="label_warning">Uyarı</string>
|
||||||
<string name="action_display_language_badge">Dil</string>
|
<string name="action_display_language_badge">Dil</string>
|
||||||
<string name="backup_info">Otomatik yedeklemeler şiddetle tavsiye edilir. Kopyaları başka yerlerde de tutmalısınız.</string>
|
<string name="backup_info">Otomatik yedeklemeler şiddetle tavsiye edilir. Kopyaları başka yerlerde de tutmalısınız.</string>
|
||||||
<string name="notification_size_warning">Uyarı: büyük güncellemeler kaynaklara zarar verir ve daha yavaş güncellemelere ve de pil kullanımının artmasına neden olabilir</string>
|
<string name="notification_size_warning">Büyük güncellemeler kaynaklara zarar verir ve daha yavaş güncellemelere ve ayrıca pil kullanımının artmasına neden olabilir</string>
|
||||||
<string name="pref_verbose_logging">Ayrıntılı günlük kaydı</string>
|
<string name="pref_verbose_logging">Ayrıntılı günlük kaydı</string>
|
||||||
<string name="pref_verbose_logging_summary">Ayrıntılı günlükleri sistem günlüğüne yaz (uygulama performansını düşürür)</string>
|
<string name="pref_verbose_logging_summary">Ayrıntılı günlükleri sistem günlüğüne yaz (uygulama performansını düşürür)</string>
|
||||||
<string name="connected_to_wifi">Yalnızca Wi-Fi\'de</string>
|
<string name="connected_to_wifi">Yalnızca Wi-Fi\'de</string>
|
||||||
@ -685,7 +685,7 @@
|
|||||||
<string name="clear_database_source_item_count">Veri tabanında %1$d kitaplık dışı manga</string>
|
<string name="clear_database_source_item_count">Veri tabanında %1$d kitaplık dışı manga</string>
|
||||||
<string name="database_clean">Veri tabanı temiz</string>
|
<string name="database_clean">Veri tabanı temiz</string>
|
||||||
<string name="extension_api_error">Uzantı listesi alınamadı</string>
|
<string name="extension_api_error">Uzantı listesi alınamadı</string>
|
||||||
<string name="pref_library_update_manga_restriction">Güncellemeyi atla</string>
|
<string name="pref_library_update_manga_restriction">Başlıkları güncellemeyi atla</string>
|
||||||
<string name="save_chapter_as_cbz">CBZ arşivi olarak kaydet</string>
|
<string name="save_chapter_as_cbz">CBZ arşivi olarak kaydet</string>
|
||||||
<string name="publishing_finished">Yayımı tamamlandı</string>
|
<string name="publishing_finished">Yayımı tamamlandı</string>
|
||||||
<string name="privacy_policy">Gizlilik politikası</string>
|
<string name="privacy_policy">Gizlilik politikası</string>
|
||||||
@ -701,8 +701,8 @@
|
|||||||
<string name="action_display_cover_only_grid">Sadece-kapak ızgara</string>
|
<string name="action_display_cover_only_grid">Sadece-kapak ızgara</string>
|
||||||
<string name="backup_restore_invalid_uri">Hata: boş URI</string>
|
<string name="backup_restore_invalid_uri">Hata: boş URI</string>
|
||||||
<string name="action_faq_and_guides">SSS ve Kılavuzlar</string>
|
<string name="action_faq_and_guides">SSS ve Kılavuzlar</string>
|
||||||
<string name="pref_update_only_completely_read">Okunmayan bölümleri olan</string>
|
<string name="pref_update_only_completely_read">Okunmayan bölüm(ler)i olan</string>
|
||||||
<string name="pref_update_only_started">Yalnızca okumaya başlanan mangaları güncelleme</string>
|
<string name="pref_update_only_started">Bu başlamadı</string>
|
||||||
<string name="skipped_reason_completed">Manga tamamlandığı için atlandı</string>
|
<string name="skipped_reason_completed">Manga tamamlandığı için atlandı</string>
|
||||||
<string name="skipped_reason_not_caught_up">Okunmamış bölümler olduğu için atlandı</string>
|
<string name="skipped_reason_not_caught_up">Okunmamış bölümler olduğu için atlandı</string>
|
||||||
<string name="skipped_reason_not_started">Hiçbir bölüm okunmadığı için atlandı</string>
|
<string name="skipped_reason_not_started">Hiçbir bölüm okunmadığı için atlandı</string>
|
||||||
@ -710,9 +710,11 @@
|
|||||||
<string name="pref_landscape_zoom">Yatay görseli yakınlaştır</string>
|
<string name="pref_landscape_zoom">Yatay görseli yakınlaştır</string>
|
||||||
<string name="notification_update_error">%1$d güncelleme başarısız oldu</string>
|
<string name="notification_update_error">%1$d güncelleme başarısız oldu</string>
|
||||||
<string name="notification_update_skipped">%1$d güncelleme atlandı</string>
|
<string name="notification_update_skipped">%1$d güncelleme atlandı</string>
|
||||||
<string name="learn_more">Daha fazla bilgi edin</string>
|
<string name="learn_more">Daha fazla bilgi edinmek için dokunun</string>
|
||||||
<string name="channel_skipped">Atlandı</string>
|
<string name="channel_skipped">Atlandı</string>
|
||||||
<string name="rotation_reverse_portrait">Ters dikey</string>
|
<string name="rotation_reverse_portrait">Ters dikey</string>
|
||||||
<string name="action_move_to_top_all_for_series">Seriyi en üste taşı</string>
|
<string name="action_move_to_top_all_for_series">Seriyi en üste taşı</string>
|
||||||
<string name="disabled_nav">Devre dışı</string>
|
<string name="disabled_nav">Devre dışı</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">Resmi yayınlardan yeni bir sürüm var. Resmi olmayan F-Droid sürümlerinden nasıl geçiş yapacağınızı öğrenmek için dokunun.</string>
|
||||||
|
<string name="error_saving_picture">Resim kaydedilirken hata oluştu</string>
|
||||||
</resources>
|
</resources>
|
@ -629,7 +629,7 @@
|
|||||||
<string name="date">Ngày</string>
|
<string name="date">Ngày</string>
|
||||||
<string name="local_filter_order_by">Xếp theo</string>
|
<string name="local_filter_order_by">Xếp theo</string>
|
||||||
<string name="local_invalid_format">Định dạng chương không đúng</string>
|
<string name="local_invalid_format">Định dạng chương không đúng</string>
|
||||||
<string name="chapter_not_found">Chương không tìm thấy</string>
|
<string name="chapter_not_found">Không tìm thấy chương</string>
|
||||||
<string name="on">Bật</string>
|
<string name="on">Bật</string>
|
||||||
<string name="off">Tắt</string>
|
<string name="off">Tắt</string>
|
||||||
<string name="pref_library_update_refresh_trackers_summary">Cập nhật theo dõi khi cập nhật thư viện</string>
|
<string name="pref_library_update_refresh_trackers_summary">Cập nhật theo dõi khi cập nhật thư viện</string>
|
||||||
@ -736,4 +736,5 @@
|
|||||||
<string name="skipped_reason_not_started">Đã bỏ qua vì không có chương được đọc</string>
|
<string name="skipped_reason_not_started">Đã bỏ qua vì không có chương được đọc</string>
|
||||||
<string name="channel_skipped">Bỏ qua</string>
|
<string name="channel_skipped">Bỏ qua</string>
|
||||||
<string name="action_move_to_top_all_for_series">Di chuyển bộ truyện lên đầu</string>
|
<string name="action_move_to_top_all_for_series">Di chuyển bộ truyện lên đầu</string>
|
||||||
|
<string name="disabled_nav">Vô hiệu hóa</string>
|
||||||
</resources>
|
</resources>
|
@ -87,7 +87,7 @@
|
|||||||
<string name="all">全部</string>
|
<string name="all">全部</string>
|
||||||
<string name="pref_library_update_restriction">设备自动更新限制</string>
|
<string name="pref_library_update_restriction">设备自动更新限制</string>
|
||||||
<string name="charging">正在充电</string>
|
<string name="charging">正在充电</string>
|
||||||
<string name="pref_update_only_non_completed">已完结连载</string>
|
<string name="pref_update_only_non_completed">状态为“已完结”</string>
|
||||||
<string name="pref_auto_update_manga_sync">阅读后更新进度</string>
|
<string name="pref_auto_update_manga_sync">阅读后更新进度</string>
|
||||||
<string name="pref_start_screen">起始页面</string>
|
<string name="pref_start_screen">起始页面</string>
|
||||||
<string name="default_category">默认分类</string>
|
<string name="default_category">默认分类</string>
|
||||||
@ -662,7 +662,7 @@
|
|||||||
<string name="label_warning">警告</string>
|
<string name="label_warning">警告</string>
|
||||||
<string name="action_display_language_badge">语言</string>
|
<string name="action_display_language_badge">语言</string>
|
||||||
<string name="backup_info">强烈建议启用自动备份,你也应该在其他地方保存副本。</string>
|
<string name="backup_info">强烈建议启用自动备份,你也应该在其他地方保存副本。</string>
|
||||||
<string name="notification_size_warning">警告:大型更新会损害图源,并可能导致更新速度变慢以及电池用量增加</string>
|
<string name="notification_size_warning">大型更新会损害图源,并可能导致更新速度变慢以及电池用量增加</string>
|
||||||
<string name="connected_to_wifi">仅连接至 Wi-Fi 时</string>
|
<string name="connected_to_wifi">仅连接至 Wi-Fi 时</string>
|
||||||
<string name="update_72hour">每 3 天</string>
|
<string name="update_72hour">每 3 天</string>
|
||||||
<string name="download_queue_size_warning">警告:批量下载可能会导致图源变慢和/或图源封锁 Tachiyomi</string>
|
<string name="download_queue_size_warning">警告:批量下载可能会导致图源变慢和/或图源封锁 Tachiyomi</string>
|
||||||
@ -674,8 +674,8 @@
|
|||||||
<string name="clear_database_source_item_count">数据库有 %1$d 本漫画不在书架中</string>
|
<string name="clear_database_source_item_count">数据库有 %1$d 本漫画不在书架中</string>
|
||||||
<string name="extension_api_error">无法获取扩展插件列表</string>
|
<string name="extension_api_error">无法获取扩展插件列表</string>
|
||||||
<string name="privacy_policy">隐私政策</string>
|
<string name="privacy_policy">隐私政策</string>
|
||||||
<string name="pref_update_only_completely_read">有未读完的章节</string>
|
<string name="pref_update_only_completely_read">有未读章节</string>
|
||||||
<string name="pref_library_update_manga_restriction">跳过更新</string>
|
<string name="pref_library_update_manga_restriction">跳过更新标题</string>
|
||||||
<string name="library_errors_help">有关如何修复库更新错误的帮助,请参阅 %1$s</string>
|
<string name="library_errors_help">有关如何修复库更新错误的帮助,请参阅 %1$s</string>
|
||||||
<string name="save_chapter_as_cbz">保存为 CBZ 存档</string>
|
<string name="save_chapter_as_cbz">保存为 CBZ 存档</string>
|
||||||
<string name="publishing_finished">发布完成</string>
|
<string name="publishing_finished">发布完成</string>
|
||||||
@ -692,15 +692,17 @@
|
|||||||
\n
|
\n
|
||||||
\n你仍希望继续吗?</string>
|
\n你仍希望继续吗?</string>
|
||||||
<string name="action_filter_started">已开始</string>
|
<string name="action_filter_started">已开始</string>
|
||||||
<string name="pref_update_only_started">无已读章节</string>
|
<string name="pref_update_only_started">尚未开始</string>
|
||||||
<string name="skipped_reason_completed">跳过,因连载完结</string>
|
<string name="skipped_reason_completed">跳过,因连载完结</string>
|
||||||
<string name="skipped_reason_not_caught_up">跳过,因有未读章节</string>
|
<string name="skipped_reason_not_caught_up">跳过,因有未读章节</string>
|
||||||
<string name="skipped_reason_not_started">跳过,因无已读章节</string>
|
<string name="skipped_reason_not_started">跳过,因无已读章节</string>
|
||||||
<string name="learn_more">了解更多</string>
|
<string name="learn_more">轻按了解更多</string>
|
||||||
<string name="notification_update_error">%1$d 个更新失败了</string>
|
<string name="notification_update_error">%1$d 个更新失败了</string>
|
||||||
<string name="notification_update_skipped">已跳过 %1$d 个更新</string>
|
<string name="notification_update_skipped">已跳过 %1$d 个更新</string>
|
||||||
<string name="channel_skipped">已跳过</string>
|
<string name="channel_skipped">已跳过</string>
|
||||||
<string name="rotation_reverse_portrait">反转竖屏</string>
|
<string name="rotation_reverse_portrait">反转竖屏</string>
|
||||||
<string name="action_move_to_top_all_for_series">将连载移动到顶部</string>
|
<string name="action_move_to_top_all_for_series">将连载置顶</string>
|
||||||
<string name="disabled_nav">已禁用</string>
|
<string name="disabled_nav">已禁用</string>
|
||||||
|
<string name="error_saving_picture">保存图片出错</string>
|
||||||
|
<string name="update_check_fdroid_migration_info">新版本可从官方版本中获得。 轻按以了解如何从非官方 F-Droid 版本迁移。</string>
|
||||||
</resources>
|
</resources>
|
@ -506,7 +506,7 @@
|
|||||||
<string name="pref_category_delete_chapters">刪除章節</string>
|
<string name="pref_category_delete_chapters">刪除章節</string>
|
||||||
<string name="chapter_settings_updated">已更新章節設定預設值</string>
|
<string name="chapter_settings_updated">已更新章節設定預設值</string>
|
||||||
<plurals name="missing_chapters_warning">
|
<plurals name="missing_chapters_warning">
|
||||||
<item quantity="other">略過了 %d 章,也許是來源沒有這些章節,或其已被你的篩選規則排除</item>
|
<item quantity="other">略過了 %d 章,也許是來源沒有這些章節,或其已被篩選規則排除</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_search_settings">搜尋設定</string>
|
<string name="action_search_settings">搜尋設定</string>
|
||||||
<string name="chapter_settings">章節設定</string>
|
<string name="chapter_settings">章節設定</string>
|
||||||
@ -701,4 +701,6 @@
|
|||||||
<string name="notification_update_error">%1$d 項更新失敗</string>
|
<string name="notification_update_error">%1$d 項更新失敗</string>
|
||||||
<string name="notification_update_skipped">已略過 %1$d 項更新</string>
|
<string name="notification_update_skipped">已略過 %1$d 項更新</string>
|
||||||
<string name="channel_skipped">略過</string>
|
<string name="channel_skipped">略過</string>
|
||||||
|
<string name="action_move_to_top_all_for_series">置頂此叢書</string>
|
||||||
|
<string name="disabled_nav">已停用</string>
|
||||||
</resources>
|
</resources>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user