Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b1240fccb | ||
|
|
e00a5b7505 | ||
|
|
2c07d2c8e1 | ||
|
|
45c3c05f01 | ||
|
|
e97a745713 | ||
|
|
2dc4de0a3c | ||
|
|
3cf2c58058 | ||
|
|
1e19f32fc5 | ||
|
|
99e4359523 | ||
|
|
04868488cc | ||
|
|
2b3b406b84 | ||
|
|
7ab3c75232 | ||
|
|
61f7755465 | ||
|
|
9389015ab9 | ||
|
|
bc56a94aa6 | ||
|
|
7cfcaec6dd | ||
|
|
39c7ae31cd | ||
|
|
9349eccc0c | ||
|
|
8204934359 | ||
|
|
b5497c571e | ||
|
|
b4d52f1367 | ||
|
|
325a8be484 | ||
|
|
8cc04b0f7a | ||
|
|
258dbf3dc3 | ||
|
|
e7af4e8450 | ||
|
|
0c25c61858 | ||
|
|
abc3e45907 | ||
|
|
bd98d8eded | ||
|
|
2e81f41073 | ||
|
|
5cccebc416 | ||
|
|
c668ffd555 | ||
|
|
a0f77b715f | ||
|
|
2831843a25 | ||
|
|
86c1aa11b0 | ||
|
|
d71514ec7a | ||
|
|
92ed320f57 | ||
|
|
2de1fe8b77 | ||
|
|
cebc3cd9e8 | ||
|
|
6c0e2e2b90 | ||
|
|
b4bd923ce8 | ||
|
|
813561fd3b | ||
|
|
4107336132 | ||
|
|
30d9d87c17 | ||
|
|
c4b5be657d | ||
|
|
8a763b2b9f | ||
|
|
c783378022 | ||
|
|
c4355f16e8 | ||
|
|
522dfc2418 | ||
|
|
06d03e3ddd | ||
|
|
9dc8c7959d | ||
|
|
db219020ca | ||
|
|
c04edcb76c | ||
|
|
936fc2e4ae | ||
|
|
cbed866665 | ||
|
|
ac568b6361 | ||
|
|
84157f988d | ||
|
|
6f6339f0f8 | ||
|
|
a7019b9096 | ||
|
|
867e3f10ca | ||
|
|
fb2cf04d75 | ||
|
|
3ed44ba0d6 | ||
|
|
b78104a0f1 | ||
|
|
e4ee93f77c | ||
|
|
c6e8da5f23 | ||
|
|
376de7cce3 | ||
|
|
bec2195971 | ||
|
|
722ac4ecc7 | ||
|
|
516c1c02a6 | ||
|
|
0cb7e71781 |
@@ -16,8 +16,8 @@ android {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 622
|
||||
versionName = '6.7'
|
||||
versionCode = 625
|
||||
versionName = '6.7.3'
|
||||
generatedDensities = []
|
||||
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
|
||||
ksp {
|
||||
@@ -82,13 +82,13 @@ afterEvaluate {
|
||||
}
|
||||
dependencies {
|
||||
//noinspection GradleDependency
|
||||
implementation('com.github.KotatsuApp:kotatsu-parsers:014ea5ef49') {
|
||||
implementation('com.github.KotatsuApp:kotatsu-parsers:103f578c61') {
|
||||
exclude group: 'org.json', module: 'json'
|
||||
}
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.22'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
@@ -128,11 +128,11 @@ dependencies {
|
||||
|
||||
implementation 'com.google.dagger:hilt-android:2.50'
|
||||
kapt 'com.google.dagger:hilt-compiler:2.50'
|
||||
implementation 'androidx.hilt:hilt-work:1.1.0'
|
||||
kapt 'androidx.hilt:hilt-compiler:1.1.0'
|
||||
implementation 'androidx.hilt:hilt-work:1.2.0'
|
||||
kapt 'androidx.hilt:hilt-compiler:1.2.0'
|
||||
|
||||
implementation 'io.coil-kt:coil-base:2.5.0'
|
||||
implementation 'io.coil-kt:coil-svg:2.5.0'
|
||||
implementation 'io.coil-kt:coil-base:2.6.0'
|
||||
implementation 'io.coil-kt:coil-svg:2.6.0'
|
||||
implementation 'com.github.KotatsuApp:subsampling-scale-image-view:02e6d6cfe9'
|
||||
implementation 'com.github.solkin:disk-lru-cache:1.4'
|
||||
implementation 'io.noties.markwon:core:4.6.2'
|
||||
@@ -148,14 +148,14 @@ dependencies {
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.json:json:20240205'
|
||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
|
||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0'
|
||||
|
||||
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
androidTestImplementation 'androidx.test:core-ktx:1.5.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.5'
|
||||
|
||||
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
|
||||
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0'
|
||||
|
||||
androidTestImplementation 'androidx.room:room-testing:2.6.1'
|
||||
androidTestImplementation 'com.squareup.moshi:moshi-kotlin:1.15.1'
|
||||
|
||||
@@ -57,6 +57,7 @@ class AppShortcutManagerTest {
|
||||
page = 4,
|
||||
scroll = 2,
|
||||
percent = 0.3f,
|
||||
force = false,
|
||||
)
|
||||
awaitUpdate()
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ import dagger.hilt.android.testing.HiltAndroidRule
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@@ -61,6 +63,7 @@ class AppBackupAgentTest {
|
||||
page = 3,
|
||||
scroll = 40,
|
||||
percent = 0.2f,
|
||||
force = false,
|
||||
)
|
||||
val history = checkNotNull(historyRepository.getOne(SampleData.manga))
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.util.ext.catchingWebViewUnavailability
|
||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||
import org.koitharu.kotatsu.parsers.network.UserAgents
|
||||
import com.google.android.material.R as materialR
|
||||
@@ -26,7 +25,7 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (!catchingWebViewUnavailability { setContentView(ActivityBrowserBinding.inflate(layoutInflater)) }) {
|
||||
if (!setContentViewWebViewSafe { ActivityBrowserBinding.inflate(layoutInflater) }) {
|
||||
return
|
||||
}
|
||||
supportActionBar?.run {
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.koitharu.kotatsu.core.network.CommonHeaders
|
||||
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.util.TaggedActivityResult
|
||||
import org.koitharu.kotatsu.core.util.ext.catchingWebViewUnavailability
|
||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||
import org.koitharu.kotatsu.parsers.network.UserAgents
|
||||
import javax.inject.Inject
|
||||
@@ -45,13 +44,7 @@ class CloudFlareActivity : BaseActivity<ActivityBrowserBinding>(), CloudFlareCal
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (!catchingWebViewUnavailability {
|
||||
setContentView(
|
||||
ActivityBrowserBinding.inflate(
|
||||
layoutInflater,
|
||||
),
|
||||
)
|
||||
}) {
|
||||
if (!setContentViewWebViewSafe { ActivityBrowserBinding.inflate(layoutInflater) }) {
|
||||
return
|
||||
}
|
||||
supportActionBar?.run {
|
||||
|
||||
@@ -227,6 +227,5 @@ class RemoteMangaRepository(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Result<*>.isValidResult() = exceptionOrNull() !is ParseException
|
||||
&& (getOrNull() as? Collection<*>)?.isEmpty() != true
|
||||
private fun Result<*>.isValidResult() = isSuccess && (getOrNull() as? Collection<*>)?.isEmpty() != true
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.collection.ArraySet
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.preference.PreferenceManager
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import org.json.JSONArray
|
||||
@@ -70,6 +71,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
val isNavLabelsVisible: Boolean
|
||||
get() = prefs.getBoolean(KEY_NAV_LABELS, true)
|
||||
|
||||
var gridSize: Int
|
||||
get() = prefs.getInt(KEY_GRID_SIZE, 100)
|
||||
set(value) = prefs.edit { putInt(KEY_GRID_SIZE, value) }
|
||||
@@ -111,6 +115,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
val isReaderZoomButtonsEnabled: Boolean
|
||||
get() = prefs.getBoolean(KEY_READER_ZOOM_BUTTONS, false)
|
||||
|
||||
val isReaderControlAlwaysLTR: Boolean
|
||||
get() = prefs.getBoolean(KEY_READER_CONTROL_LTR, false)
|
||||
|
||||
val isReaderFullscreenEnabled: Boolean
|
||||
get() = prefs.getBoolean(KEY_READER_FULLSCREEN, true)
|
||||
|
||||
@@ -406,6 +413,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
val isReadingTimeEstimationEnabled: Boolean
|
||||
get() = prefs.getBoolean(KEY_READING_TIME, true)
|
||||
|
||||
val isPagesSavingAskEnabled: Boolean
|
||||
get() = prefs.getBoolean(KEY_PAGES_SAVE_ASK, true)
|
||||
|
||||
fun isTipEnabled(tip: String): Boolean {
|
||||
return prefs.getStringSet(KEY_TIPS_CLOSED, emptySet())?.contains(tip) != true
|
||||
}
|
||||
@@ -418,6 +428,15 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
prefs.edit { putStringSet(KEY_TIPS_CLOSED, closedTips + tip) }
|
||||
}
|
||||
|
||||
fun getPagesSaveDir(context: Context): DocumentFile? =
|
||||
prefs.getString(KEY_PAGES_SAVE_DIR, null)?.toUriOrNull()?.let {
|
||||
DocumentFile.fromTreeUri(context, it)?.takeIf { it.canWrite() }
|
||||
}
|
||||
|
||||
fun setPagesSaveDir(uri: Uri?) {
|
||||
prefs.edit { putString(KEY_PAGES_SAVE_DIR, uri?.toString()) }
|
||||
}
|
||||
|
||||
fun subscribe(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
|
||||
prefs.registerOnSharedPreferenceChangeListener(listener)
|
||||
}
|
||||
@@ -488,6 +507,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
const val KEY_LOCAL_STORAGE = "local_storage"
|
||||
const val KEY_READER_DOUBLE_PAGES = "reader_double_pages"
|
||||
const val KEY_READER_ZOOM_BUTTONS = "reader_zoom_buttons"
|
||||
const val KEY_READER_CONTROL_LTR = "reader_taps_ltr"
|
||||
const val KEY_READER_FULLSCREEN = "reader_fullscreen"
|
||||
const val KEY_READER_VOLUME_BUTTONS = "reader_volume_buttons"
|
||||
const val KEY_TRACKER_ENABLED = "tracker_enabled"
|
||||
@@ -573,6 +593,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
const val KEY_DISABLE_NSFW = "no_nsfw"
|
||||
const val KEY_RELATED_MANGA = "related_manga"
|
||||
const val KEY_NAV_MAIN = "nav_main"
|
||||
const val KEY_NAV_LABELS = "nav_labels"
|
||||
const val KEY_32BIT_COLOR = "enhanced_colors"
|
||||
const val KEY_SOURCES_ORDER = "sources_sort_order"
|
||||
const val KEY_SOURCES_CATALOG = "sources_catalog"
|
||||
@@ -583,6 +604,8 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
const val KEY_IGNORE_DOZE = "ignore_dose"
|
||||
const val KEY_DETAILS_TAB = "details_tab"
|
||||
const val KEY_READING_TIME = "reading_time"
|
||||
const val KEY_PAGES_SAVE_DIR = "pages_dir"
|
||||
const val KEY_PAGES_SAVE_ASK = "pages_dir_ask"
|
||||
|
||||
// About
|
||||
const val KEY_APP_UPDATE = "app_update"
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
@@ -29,6 +30,7 @@ import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate
|
||||
import org.koitharu.kotatsu.core.ui.util.BaseActivityEntryPoint
|
||||
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.core.util.ext.isWebViewUnavailable
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
abstract class BaseActivity<B : ViewBinding> :
|
||||
@@ -164,6 +166,21 @@ abstract class BaseActivity<B : ViewBinding> :
|
||||
intent?.putExtra(EXTRA_DATA, intent.data)
|
||||
}
|
||||
|
||||
protected fun setContentViewWebViewSafe(viewBindingProducer: () -> B): Boolean {
|
||||
return try {
|
||||
setContentView(viewBindingProducer())
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
if (e.isWebViewUnavailable()) {
|
||||
Toast.makeText(this, R.string.web_view_unavailable, Toast.LENGTH_LONG).show()
|
||||
finishAfterTransition()
|
||||
false
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val EXTRA_DATA = "data"
|
||||
|
||||
@@ -68,6 +68,14 @@ class RecyclerViewAlertDialog private constructor(
|
||||
return this
|
||||
}
|
||||
|
||||
fun setNeutralButton(
|
||||
@StringRes textId: Int,
|
||||
listener: DialogInterface.OnClickListener,
|
||||
): Builder<T> {
|
||||
delegate.setNeutralButton(textId, listener)
|
||||
return this
|
||||
}
|
||||
|
||||
fun setCancelable(isCancelable: Boolean): Builder<T> {
|
||||
delegate.setCancelable(isCancelable)
|
||||
return this
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.graphics.withClip
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.util.Colors
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
class FaviconDrawable(
|
||||
@@ -44,7 +45,7 @@ class FaviconDrawable(
|
||||
}
|
||||
paint.textAlign = Paint.Align.CENTER
|
||||
paint.isFakeBoldText = true
|
||||
colorForeground = MaterialColors.harmonize(colorOfString(name), colorBackground)
|
||||
colorForeground = MaterialColors.harmonize(Colors.random(name), colorBackground)
|
||||
}
|
||||
|
||||
override fun draw(canvas: Canvas) {
|
||||
@@ -104,9 +105,4 @@ class FaviconDrawable(
|
||||
paint.getTextBounds(text, 0, text.length, tempRect)
|
||||
return testTextSize * width / tempRect.width()
|
||||
}
|
||||
|
||||
private fun colorOfString(str: String): Int {
|
||||
val hue = (str.hashCode() % 360).absoluteValue.toFloat()
|
||||
return ColorUtils.HSLToColor(floatArrayOf(hue, 0.5f, 0.5f))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ abstract class AbstractSelectionItemDecoration : RecyclerView.ItemDecoration() {
|
||||
canvas.restoreToCount(checkpoint)
|
||||
}
|
||||
|
||||
protected open fun getItemId(parent: RecyclerView, child: View) = parent.getChildItemId(child)
|
||||
abstract fun getItemId(parent: RecyclerView, child: View): Long
|
||||
|
||||
protected open fun onDrawBackground(
|
||||
canvas: Canvas,
|
||||
|
||||
@@ -7,12 +7,16 @@ import org.koitharu.kotatsu.R
|
||||
|
||||
class ReversibleActionObserver(
|
||||
private val snackbarHost: View,
|
||||
private val snackbarAnchor: View? = null,
|
||||
) : FlowCollector<ReversibleAction> {
|
||||
|
||||
override suspend fun emit(value: ReversibleAction) {
|
||||
val handle = value.handle
|
||||
val length = if (handle == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG
|
||||
val snackbar = Snackbar.make(snackbarHost, value.stringResId, length)
|
||||
if (snackbarAnchor?.isShown == true) {
|
||||
snackbar.anchorView = snackbarAnchor
|
||||
}
|
||||
if (handle != null) {
|
||||
snackbar.setAction(R.string.undo) { handle.reverseAsync() }
|
||||
}
|
||||
|
||||
41
app/src/main/kotlin/org/koitharu/kotatsu/core/util/Colors.kt
Normal file
41
app/src/main/kotlin/org/koitharu/kotatsu/core/util/Colors.kt
Normal file
@@ -0,0 +1,41 @@
|
||||
package org.koitharu.kotatsu.core.util
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import com.google.android.material.R
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
object Colors {
|
||||
|
||||
@ColorInt
|
||||
fun segmentColor(context: Context, @AttrRes resId: Int): Int {
|
||||
val colorHex = String.format("%06x", context.getThemeColor(resId))
|
||||
val hue = getHue(colorHex)
|
||||
val color = ColorUtils.HSLToColor(floatArrayOf(hue, 0.5f, 0.5f))
|
||||
val backgroundColor = context.getThemeColor(R.attr.colorSurfaceContainerHigh)
|
||||
return MaterialColors.harmonize(color, backgroundColor)
|
||||
}
|
||||
|
||||
fun random(seed: Any): Int {
|
||||
val hue = (seed.hashCode() % 360).absoluteValue.toFloat()
|
||||
return ColorUtils.HSLToColor(floatArrayOf(hue, 0.5f, 0.5f))
|
||||
}
|
||||
|
||||
private fun getHue(hex: String): Float {
|
||||
val r = (hex.substring(0, 2).toInt(16)).toFloat()
|
||||
val g = (hex.substring(2, 4).toInt(16)).toFloat()
|
||||
val b = (hex.substring(4, 6).toInt(16)).toFloat()
|
||||
|
||||
var hue = 0F
|
||||
if ((r >= g) && (g >= b)) {
|
||||
hue = 60 * (g - b) / (r - b)
|
||||
} else if ((g > r) && (r >= b)) {
|
||||
hue = 60 * (2 - (r - b) / (g - b))
|
||||
}
|
||||
return hue
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import android.provider.Settings
|
||||
import android.view.View
|
||||
import android.view.ViewPropertyAnimator
|
||||
import android.view.Window
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.annotation.IntegerRes
|
||||
import androidx.annotation.WorkerThread
|
||||
@@ -216,21 +215,6 @@ fun Context.findActivity(): Activity? = when (this) {
|
||||
else -> null
|
||||
}
|
||||
|
||||
inline fun Activity.catchingWebViewUnavailability(block: () -> Unit): Boolean {
|
||||
return try {
|
||||
block()
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
if (e.isWebViewUnavailable()) {
|
||||
Toast.makeText(this, R.string.web_view_unavailable, Toast.LENGTH_LONG).show()
|
||||
finishAfterTransition()
|
||||
false
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.checkNotificationPermission(): Boolean = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
|
||||
} else {
|
||||
|
||||
@@ -24,11 +24,15 @@ inline fun <reified T : Parcelable> Intent.getParcelableExtraCompat(key: String)
|
||||
}
|
||||
|
||||
inline fun <reified T : Serializable> Intent.getSerializableExtraCompat(key: String): T? {
|
||||
return getSerializableExtra(key) as T?
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
getSerializableExtra(key, T::class.java)
|
||||
} else {
|
||||
getSerializableExtra(key) as T?
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Serializable> Bundle.getSerializableCompat(key: String): T? {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
getSerializable(key, T::class.java)
|
||||
} else {
|
||||
getSerializable(key) as T?
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.koitharu.kotatsu.core.util.ext
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.res.Resources
|
||||
import android.util.AndroidRuntimeException
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.collection.arraySetOf
|
||||
import coil.network.HttpException
|
||||
@@ -115,8 +114,8 @@ private val reportableExceptions = arraySetOf<Class<*>>(
|
||||
)
|
||||
|
||||
fun Throwable.isWebViewUnavailable(): Boolean {
|
||||
return (this is AndroidRuntimeException && message?.contains("WebView") == true) ||
|
||||
cause?.isWebViewUnavailable() == true
|
||||
val trace = stackTraceToString()
|
||||
return trace.contains("android.webkit.WebView.<init>")
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package org.koitharu.kotatsu.core.util.ext
|
||||
|
||||
import android.app.Activity
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.View.MeasureSpec
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Checkable
|
||||
import androidx.appcompat.widget.ActionMenuView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.SoftwareKeyboardControllerCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.descendants
|
||||
import androidx.core.view.isVisible
|
||||
@@ -24,13 +23,11 @@ import com.google.android.material.tabs.TabLayout
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun View.hideKeyboard() {
|
||||
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(this.windowToken, 0)
|
||||
SoftwareKeyboardControllerCompat(this).hide()
|
||||
}
|
||||
|
||||
fun View.showKeyboard() {
|
||||
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.showSoftInput(this, 0)
|
||||
SoftwareKeyboardControllerCompat(this).show()
|
||||
}
|
||||
|
||||
fun View.hasGlobalPoint(x: Int, y: Int): Boolean {
|
||||
|
||||
@@ -138,7 +138,7 @@ class DetailsActivity :
|
||||
},
|
||||
),
|
||||
)
|
||||
viewModel.onActionDone.observeEvent(this, ReversibleActionObserver(viewBinding.containerDetails))
|
||||
viewModel.onActionDone.observeEvent(this, ReversibleActionObserver(viewBinding.containerDetails, viewBinding.layoutBottom))
|
||||
viewModel.onShowTip.observeEvent(this) { showTip() }
|
||||
viewModel.historyInfo.observe(this, ::onHistoryChanged)
|
||||
viewModel.selectedBranch.observe(this) {
|
||||
@@ -187,6 +187,9 @@ class DetailsActivity :
|
||||
buttonTip = null
|
||||
val menu = PopupMenu(v.context, v)
|
||||
menu.inflate(R.menu.popup_read)
|
||||
menu.menu.findItem(R.id.action_forget)?.isVisible = viewModel.historyInfo.value.run {
|
||||
!isIncognitoMode && history != null
|
||||
}
|
||||
menu.setOnMenuItemClickListener(this)
|
||||
menu.setForceShowIcon(true)
|
||||
menu.show()
|
||||
@@ -203,6 +206,11 @@ class DetailsActivity :
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_forget -> {
|
||||
viewModel.removeFromHistory()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_pages_thumbs -> {
|
||||
val history = viewModel.historyInfo.value.history
|
||||
PagesThumbnailsSheet.show(
|
||||
|
||||
@@ -62,6 +62,7 @@ import org.koitharu.kotatsu.list.ui.adapter.mangaGridItemAD
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
|
||||
import org.koitharu.kotatsu.list.ui.size.StaticItemSizeResolver
|
||||
import org.koitharu.kotatsu.local.ui.info.LocalInfoDialog
|
||||
import org.koitharu.kotatsu.main.ui.owners.NoModalBottomSheetOwner
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
@@ -71,8 +72,6 @@ import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
|
||||
import org.koitharu.kotatsu.scrobbling.common.ui.selector.ScrobblingSelectorSheet
|
||||
import org.koitharu.kotatsu.search.ui.MangaListActivity
|
||||
import org.koitharu.kotatsu.search.ui.SearchActivity
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -104,6 +103,7 @@ class DetailsFragment :
|
||||
binding.buttonScrobblingMore.setOnClickListener(this)
|
||||
binding.buttonRelatedMore.setOnClickListener(this)
|
||||
binding.infoLayout.textViewSource.setOnClickListener(this)
|
||||
binding.infoLayout.textViewSize.setOnClickListener(this)
|
||||
binding.textViewDescription.addOnLayoutChangeListener(this)
|
||||
binding.textViewDescription.viewTreeObserver.addOnDrawListener(this)
|
||||
binding.textViewDescription.movementMethod = LinkMovementMethodCompat.getInstance()
|
||||
@@ -326,6 +326,10 @@ class DetailsFragment :
|
||||
)
|
||||
}
|
||||
|
||||
R.id.textView_size -> {
|
||||
LocalInfoDialog.show(parentFragmentManager, manga)
|
||||
}
|
||||
|
||||
R.id.imageView_cover -> {
|
||||
startActivity(
|
||||
ImageActivity.newIntent(
|
||||
|
||||
@@ -320,6 +320,7 @@ class DetailsViewModel @Inject constructor(
|
||||
page = 0,
|
||||
scroll = 0,
|
||||
percent = percent,
|
||||
force = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -346,6 +347,13 @@ class DetailsViewModel @Inject constructor(
|
||||
settings.closeTip(DetailsActivity.TIP_BUTTON)
|
||||
}
|
||||
|
||||
fun removeFromHistory() {
|
||||
launchJob(Dispatchers.Default) {
|
||||
val handle = historyRepository.delete(setOf(mangaId))
|
||||
onActionDone.call(ReversibleAction(R.string.removed_from_history, handle))
|
||||
}
|
||||
}
|
||||
|
||||
private fun doLoad() = launchLoadingJob(Dispatchers.Default) {
|
||||
detailsLoadUseCase.invoke(intent)
|
||||
.onEachWhile {
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.koitharu.kotatsu.core.ui.dialog.RecyclerViewAlertDialog
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.download.ui.dialog.DownloadOption
|
||||
import org.koitharu.kotatsu.download.ui.dialog.downloadOptionAD
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
|
||||
class DownloadDialogHelper(
|
||||
private val host: View,
|
||||
@@ -57,6 +58,9 @@ class DownloadDialogHelper(
|
||||
.setCancelable(true)
|
||||
.setTitle(R.string.download)
|
||||
.setNegativeButton(android.R.string.cancel)
|
||||
.setNeutralButton(R.string.settings) { _, _ ->
|
||||
host.context.startActivity(SettingsActivity.newDownloadsSettingsIntent(host.context))
|
||||
}
|
||||
.setItems(options)
|
||||
.create()
|
||||
.also { it.show() }
|
||||
|
||||
@@ -5,7 +5,6 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.formatNumber
|
||||
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.util.ext.drawableStart
|
||||
@@ -14,6 +13,7 @@ import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
||||
import org.koitharu.kotatsu.databinding.ItemChapterBinding
|
||||
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import com.google.android.material.R as MR
|
||||
|
||||
fun chapterListItemAD(
|
||||
clickListener: OnListItemClickListener<ChapterListItem>,
|
||||
@@ -46,7 +46,7 @@ fun chapterListItemAD(
|
||||
null
|
||||
}
|
||||
binding.textViewTitle.setTextColor(context.getThemeColorStateList(android.R.attr.textColorPrimary))
|
||||
binding.textViewDescription.setTextColor(context.getThemeColorStateList(android.R.attr.textColorPrimary))
|
||||
binding.textViewDescription.setTextColor(context.getThemeColorStateList(MR.attr.colorOutline))
|
||||
binding.textViewTitle.typeface = Typeface.DEFAULT
|
||||
binding.textViewDescription.typeface = Typeface.DEFAULT
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import android.view.View
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.koitharu.kotatsu.core.ui.list.decor.AbstractSelectionItemDecoration
|
||||
import org.koitharu.kotatsu.core.util.ext.getItem
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() {
|
||||
@@ -25,6 +27,12 @@ class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecor
|
||||
paint.style = Paint.Style.FILL
|
||||
}
|
||||
|
||||
override fun getItemId(parent: RecyclerView, child: View): Long {
|
||||
val holder = parent.getChildViewHolder(child) ?: return RecyclerView.NO_ID
|
||||
val item = holder.getItem(ChapterListItem::class.java) ?: return RecyclerView.NO_ID
|
||||
return item.chapter.id
|
||||
}
|
||||
|
||||
override fun onDrawBackground(
|
||||
canvas: Canvas,
|
||||
parent: RecyclerView,
|
||||
|
||||
@@ -234,7 +234,7 @@ class ChaptersFragment :
|
||||
}
|
||||
|
||||
override fun onSelectionChanged(controller: ListSelectionController, count: Int) {
|
||||
requireViewBinding().recyclerViewChapters.invalidateItemDecorations()
|
||||
viewBinding?.recyclerViewChapters?.invalidateItemDecorations()
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) = Unit
|
||||
|
||||
@@ -13,7 +13,9 @@ import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.ImageLoader
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
@@ -65,11 +67,12 @@ class PagesFragment :
|
||||
detailsViewModel.selectedBranch,
|
||||
) { details, history, branch ->
|
||||
if (details != null && (details.isLoaded || details.chapters.isNotEmpty())) {
|
||||
PagesViewModel.State(details, history, branch)
|
||||
PagesViewModel.State(details.filterChapters(branch), history, branch)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}.observe(this, viewModel::updateState)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
.observe(this, viewModel::updateState)
|
||||
}
|
||||
|
||||
override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentPagesBinding {
|
||||
|
||||
@@ -57,7 +57,7 @@ class MangaSourcesRepository @Inject constructor(
|
||||
observeIsNsfwDisabled(),
|
||||
dao.observeEnabled(SourcesSortOrder.MANUAL),
|
||||
) { skipNsfw, sources ->
|
||||
sources.count { skipNsfw || !MangaSource(it.source).isNsfw() }
|
||||
sources.count { !skipNsfw || !MangaSource(it.source).isNsfw() }
|
||||
}.distinctUntilChanged()
|
||||
}
|
||||
|
||||
|
||||
@@ -68,9 +68,8 @@ class FavouritesCategoryEditActivity :
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
val order = savedInstanceState.getSerializableCompat<ListSortOrder>(KEY_SORT_ORDER)
|
||||
if (order != null) {
|
||||
selectedSortOrder = order
|
||||
savedInstanceState.getSerializableCompat<ListSortOrder>(KEY_SORT_ORDER)?.let {
|
||||
selectedSortOrder = it
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,8 +90,8 @@ class HistoryRepository @Inject constructor(
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
suspend fun addOrUpdate(manga: Manga, chapterId: Long, page: Int, scroll: Int, percent: Float) {
|
||||
if (shouldSkip(manga)) {
|
||||
suspend fun addOrUpdate(manga: Manga, chapterId: Long, page: Int, scroll: Int, percent: Float, force: Boolean) {
|
||||
if (!force && shouldSkip(manga)) {
|
||||
return
|
||||
}
|
||||
db.withTransaction {
|
||||
|
||||
@@ -24,6 +24,7 @@ class HistoryUpdateUseCase @Inject constructor(
|
||||
page = readerState.page,
|
||||
scroll = readerState.scroll,
|
||||
percent = percent,
|
||||
force = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ class MarkAsReadUseCase @Inject constructor(
|
||||
page = pages.lastIndex,
|
||||
scroll = 0,
|
||||
percent = 1f,
|
||||
force = true,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.koitharu.kotatsu.local.ui.info
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.widget.TextViewCompat
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.ui.AlertDialogFragment
|
||||
import org.koitharu.kotatsu.core.ui.widgets.SegmentedBarView
|
||||
import org.koitharu.kotatsu.core.util.Colors
|
||||
import org.koitharu.kotatsu.core.util.FileSize
|
||||
import org.koitharu.kotatsu.core.util.ext.combine
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.showDistinct
|
||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||
import org.koitharu.kotatsu.databinding.DialogLocalInfoBinding
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.settings.userdata.StorageUsage
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class LocalInfoDialog : AlertDialogFragment<DialogLocalInfoBinding>() {
|
||||
|
||||
private val viewModel: LocalInfoViewModel by viewModels()
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setTitle(R.string.saved_manga)
|
||||
.setNegativeButton(R.string.close, null)
|
||||
}
|
||||
|
||||
override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): DialogLocalInfoBinding {
|
||||
return DialogLocalInfoBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewBindingCreated(binding: DialogLocalInfoBinding, savedInstanceState: Bundle?) {
|
||||
super.onViewBindingCreated(binding, savedInstanceState)
|
||||
viewModel.path.observe(this) {
|
||||
binding.textViewPath.text = it
|
||||
}
|
||||
combine(viewModel.size, viewModel.availableSize, ::Pair).observe(this) {
|
||||
if (it.first >= 0 && it.second >= 0) {
|
||||
setSegments(it.first, it.second)
|
||||
} else {
|
||||
binding.barView.animateSegments(emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setSegments(size: Long, available: Long) {
|
||||
val view = viewBinding?.barView ?: return
|
||||
val total = size + available
|
||||
val segment = SegmentedBarView.Segment(
|
||||
percent = (size.toDouble() / total.toDouble()).toFloat(),
|
||||
color = Colors.segmentColor(view.context, materialR.attr.colorPrimary),
|
||||
)
|
||||
requireViewBinding().labelUsed.text = view.context.getString(
|
||||
R.string.memory_usage_pattern,
|
||||
getString(R.string.this_manga),
|
||||
FileSize.BYTES.format(view.context, size),
|
||||
)
|
||||
requireViewBinding().labelAvailable.text = view.context.getString(
|
||||
R.string.memory_usage_pattern,
|
||||
getString(R.string.available),
|
||||
FileSize.BYTES.format(view.context, available),
|
||||
)
|
||||
TextViewCompat.setCompoundDrawableTintList(
|
||||
requireViewBinding().labelUsed,
|
||||
ColorStateList.valueOf(segment.color),
|
||||
)
|
||||
view.animateSegments(listOf(segment))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ARG_MANGA = "manga"
|
||||
private const val TAG = "LocalInfoDialog"
|
||||
|
||||
fun show(fm: FragmentManager, manga: Manga) {
|
||||
LocalInfoDialog().withArgs(1) {
|
||||
putParcelable(ARG_MANGA, ParcelableManga(manga))
|
||||
}.showDistinct(fm, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.koitharu.kotatsu.local.ui.info
|
||||
|
||||
import androidx.core.net.toFile
|
||||
import androidx.core.net.toUri
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.ui.widgets.SegmentedBarView
|
||||
import org.koitharu.kotatsu.core.util.ext.computeSize
|
||||
import org.koitharu.kotatsu.core.util.ext.require
|
||||
import org.koitharu.kotatsu.core.util.ext.toFileOrNull
|
||||
import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
||||
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class LocalInfoViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val localMangaRepository: LocalMangaRepository,
|
||||
private val storageManager: LocalStorageManager,
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val manga = savedStateHandle.require<ParcelableManga>(LocalInfoDialog.ARG_MANGA).manga
|
||||
|
||||
val path = MutableStateFlow<String?>(null)
|
||||
val size = MutableStateFlow(-1L)
|
||||
val availableSize = MutableStateFlow(-1L)
|
||||
|
||||
init {
|
||||
launchLoadingJob(Dispatchers.Default) {
|
||||
val file = manga.url.toUri().toFileOrNull() ?: localMangaRepository.findSavedManga(manga)?.file
|
||||
requireNotNull(file)
|
||||
path.value = file.path
|
||||
size.value = file.computeSize()
|
||||
availableSize.value = storageManager.computeAvailableSize()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import com.google.android.material.navigation.NavigationBarView
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -34,6 +35,7 @@ import org.koitharu.kotatsu.local.ui.LocalListFragment
|
||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment
|
||||
import org.koitharu.kotatsu.tracker.ui.feed.FeedFragment
|
||||
import java.util.LinkedList
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
private const val TAG_PRIMARY = "primary"
|
||||
|
||||
@@ -194,12 +196,15 @@ class MainNavigationDelegate(
|
||||
|
||||
private fun observeSettings(lifecycleOwner: LifecycleOwner) {
|
||||
settings.observe()
|
||||
.filter { x -> x == AppSettings.KEY_TRACKER_ENABLED || x == AppSettings.KEY_SUGGESTIONS }
|
||||
.filter { x ->
|
||||
x == AppSettings.KEY_TRACKER_ENABLED || x == AppSettings.KEY_SUGGESTIONS || x == AppSettings.KEY_NAV_LABELS
|
||||
}
|
||||
.onStart { emit("") }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.onEach {
|
||||
setItemVisibility(R.id.nav_suggestions, settings.isSuggestionsEnabled)
|
||||
setItemVisibility(R.id.nav_feed, settings.isTrackerEnabled)
|
||||
setNavbarIsLabeled(settings.isNavLabelsVisible)
|
||||
}.launchIn(lifecycleOwner.lifecycleScope)
|
||||
}
|
||||
|
||||
@@ -211,6 +216,23 @@ class MainNavigationDelegate(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun setNavbarIsLabeled(value: Boolean) {
|
||||
if (navBar is BottomNavigationView) {
|
||||
navBar.minimumHeight = navBar.resources.getDimensionPixelSize(
|
||||
if (value) {
|
||||
materialR.dimen.m3_bottom_nav_min_height
|
||||
} else {
|
||||
R.dimen.nav_bar_height_compact
|
||||
},
|
||||
)
|
||||
}
|
||||
navBar.labelVisibilityMode = if (value) {
|
||||
NavigationBarView.LABEL_VISIBILITY_LABELED
|
||||
} else {
|
||||
NavigationBarView.LABEL_VISIBILITY_UNLABELED
|
||||
}
|
||||
}
|
||||
|
||||
interface OnFragmentChangedListener {
|
||||
|
||||
fun onFragmentChanged(fragment: Fragment, fromUser: Boolean)
|
||||
|
||||
@@ -61,6 +61,8 @@ class WelcomeViewModel @Inject constructor(
|
||||
selectedItems = selectedLocales,
|
||||
isLoading = false,
|
||||
)
|
||||
repository.assimilateNewSources()
|
||||
commit()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,19 +8,26 @@ import android.provider.DocumentsContract
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.net.toUri
|
||||
import org.koitharu.kotatsu.core.util.ext.toUriOrNull
|
||||
import java.io.File
|
||||
|
||||
class PageSaveContract : ActivityResultContracts.CreateDocument("image/*") {
|
||||
|
||||
override fun createIntent(context: Context, input: String): Intent {
|
||||
val intent = super.createIntent(context, input)
|
||||
val intent = super.createIntent(context, input.substringAfterLast(File.separatorChar))
|
||||
intent.type = MimeTypeMap.getSingleton()
|
||||
.getMimeTypeFromExtension(input.substringAfterLast('.')) ?: "image/*"
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val defaultUri = input.toUriOrNull()?.run {
|
||||
path?.let { p ->
|
||||
buildUpon().path(p.substringBeforeLast('/')).build()
|
||||
}
|
||||
}
|
||||
intent.putExtra(
|
||||
DocumentsContract.EXTRA_INITIAL_URI,
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toUri(),
|
||||
defaultUri ?: Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toUri(),
|
||||
)
|
||||
}
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okio.IOException
|
||||
import okio.buffer
|
||||
import okio.sink
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.util.ext.source
|
||||
import org.koitharu.kotatsu.core.util.ext.toFileOrNull
|
||||
import org.koitharu.kotatsu.core.util.ext.writeAllCancellable
|
||||
@@ -30,7 +31,8 @@ private const val MAX_FILENAME_LENGTH = 10
|
||||
private const val EXTENSION_FALLBACK = "png"
|
||||
|
||||
class PageSaveHelper @Inject constructor(
|
||||
@ApplicationContext context: Context,
|
||||
@ApplicationContext private val context: Context,
|
||||
private val settings: AppSettings,
|
||||
) {
|
||||
|
||||
private var continuation: Continuation<Uri>? = null
|
||||
@@ -44,14 +46,7 @@ class PageSaveHelper @Inject constructor(
|
||||
val pageUrl = pageLoader.getPageUrl(page)
|
||||
val pageUri = pageLoader.loadPage(page, force = false)
|
||||
val proposedName = getProposedFileName(pageUrl, pageUri)
|
||||
val destination = withContext(Dispatchers.Main) {
|
||||
suspendCancellableCoroutine { cont ->
|
||||
continuation = cont
|
||||
saveLauncher.launch(proposedName)
|
||||
}.also {
|
||||
continuation = null
|
||||
}
|
||||
}
|
||||
val destination = getDefaultFileUri(proposedName) ?: pickFileUri(saveLauncher, proposedName)
|
||||
runInterruptible(Dispatchers.IO) {
|
||||
contentResolver.openOutputStream(destination)?.sink()?.buffer()
|
||||
}?.use { output ->
|
||||
@@ -62,12 +57,35 @@ class PageSaveHelper @Inject constructor(
|
||||
return destination
|
||||
}
|
||||
|
||||
private fun getDefaultFileUri(proposedName: String): Uri? {
|
||||
if (settings.isPagesSavingAskEnabled) {
|
||||
return null
|
||||
}
|
||||
return settings.getPagesSaveDir(context)?.let {
|
||||
val ext = proposedName.substringAfterLast('.', "")
|
||||
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext) ?: return null
|
||||
it.createFile(mime, proposedName.substringBeforeLast('.'))?.uri
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun pickFileUri(saveLauncher: ActivityResultLauncher<String>, proposedName: String): Uri {
|
||||
val defaultUri = settings.getPagesSaveDir(context)?.uri?.buildUpon()?.appendPath(proposedName)?.toString()
|
||||
return withContext(Dispatchers.Main) {
|
||||
suspendCancellableCoroutine { cont ->
|
||||
continuation = cont
|
||||
saveLauncher.launch(defaultUri ?: proposedName)
|
||||
}.also {
|
||||
continuation = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onActivityResult(uri: Uri): Boolean = continuation?.apply {
|
||||
resume(uri)
|
||||
} != null
|
||||
|
||||
private suspend fun getProposedFileName(url: String, fileUri: Uri): String {
|
||||
var name = if (url.startsWith("cbz://")) {
|
||||
var name = if (url.startsWith("cbz:")) {
|
||||
requireNotNull(url.toUri().fragment)
|
||||
} else {
|
||||
url.toHttpUrl().pathSegments.last()
|
||||
|
||||
@@ -206,11 +206,13 @@ class ReaderActivity :
|
||||
}
|
||||
|
||||
override fun onGridTouch(area: TapGridArea): Boolean {
|
||||
return controlDelegate.onGridTouch(area)
|
||||
return isReaderResumed() && controlDelegate.onGridTouch(area)
|
||||
}
|
||||
|
||||
override fun onGridLongTouch(area: TapGridArea) {
|
||||
controlDelegate.onGridLongTouch(area)
|
||||
if (isReaderResumed()) {
|
||||
controlDelegate.onGridLongTouch(area)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProcessTouch(rawX: Int, rawY: Int): Boolean {
|
||||
|
||||
@@ -114,7 +114,7 @@ class ReaderControlDelegate(
|
||||
}
|
||||
|
||||
private fun isReaderTapsReversed(): Boolean {
|
||||
return listener.readerMode == ReaderMode.REVERSED
|
||||
return settings.isReaderControlAlwaysLTR && listener.readerMode == ReaderMode.REVERSED
|
||||
}
|
||||
|
||||
interface OnInteractionListener {
|
||||
|
||||
@@ -117,6 +117,7 @@ class ReaderConfigSheet :
|
||||
R.id.button_save_page -> {
|
||||
val page = viewModel.getCurrentPage() ?: return
|
||||
viewModel.saveCurrentPage(page, savePageRequest)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
R.id.button_screen_rotate -> {
|
||||
|
||||
@@ -108,7 +108,7 @@ abstract class BasePagerReaderFragment : BaseReaderFragment<FragmentReaderPagerB
|
||||
val axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL)
|
||||
val withCtrl = event.metaState and KeyEvent.META_CTRL_MASK != 0
|
||||
if (!withCtrl) {
|
||||
switchPageBy(-axisValue.sign.toInt())
|
||||
onWheelScroll(axisValue)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -172,6 +172,10 @@ abstract class BasePagerReaderFragment : BaseReaderFragment<FragmentReaderPagerB
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun onWheelScroll(axisValue: Float) {
|
||||
switchPageBy(-axisValue.sign.toInt())
|
||||
}
|
||||
|
||||
protected open fun onCreateAdvancedTransformer(): PageTransformer = PageAnimTransformer()
|
||||
|
||||
protected open fun onInitPager(pager: ViewPager2) {
|
||||
|
||||
@@ -22,6 +22,9 @@ abstract class BaseReaderAdapter<H : BasePageHolder<*>>(
|
||||
|
||||
private val differ = AsyncListDiffer(this, DiffCallback())
|
||||
|
||||
val hasItems: Boolean
|
||||
get() = itemCount != 0
|
||||
|
||||
init {
|
||||
stateRestorationPolicy = StateRestorationPolicy.PREVENT
|
||||
}
|
||||
|
||||
@@ -29,7 +29,11 @@ abstract class BaseReaderFragment<B : ViewBinding> : BaseFragment<B>(), ZoomCont
|
||||
readerAdapter = onCreateAdapter()
|
||||
|
||||
viewModel.content.observe(viewLifecycleOwner) {
|
||||
onPagesChanged(it.pages, restoredState ?: it.state)
|
||||
var pendingState = restoredState ?: it.state
|
||||
if (pendingState == null && it.pages.isNotEmpty() && readerAdapter?.hasItems != true) {
|
||||
pendingState = viewModel.getCurrentState()
|
||||
}
|
||||
onPagesChanged(it.pages, pendingState)
|
||||
restoredState = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,18 @@ package org.koitharu.kotatsu.reader.ui.pager.reversed
|
||||
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderState
|
||||
import org.koitharu.kotatsu.reader.ui.pager.BasePagerReaderFragment
|
||||
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ReversedReaderFragment : BasePagerReaderFragment() {
|
||||
|
||||
@Inject
|
||||
lateinit var settings: AppSettings
|
||||
|
||||
override fun onCreateAdvancedTransformer(): ViewPager2.PageTransformer = ReversedPageAnimTransformer()
|
||||
|
||||
override fun onCreateAdapter() = ReversedPagesAdapter(
|
||||
@@ -19,6 +24,11 @@ class ReversedReaderFragment : BasePagerReaderFragment() {
|
||||
exceptionResolver = exceptionResolver,
|
||||
)
|
||||
|
||||
override fun onWheelScroll(axisValue: Float) {
|
||||
val value = if (settings.isReaderControlAlwaysLTR) -axisValue else axisValue
|
||||
super.onWheelScroll(value)
|
||||
}
|
||||
|
||||
override fun switchPageBy(delta: Int) {
|
||||
super.switchPageBy(-delta)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Point
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.util.AttributeSet
|
||||
@@ -19,12 +20,16 @@ import android.widget.OverScroller
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.view.GestureDetectorCompat
|
||||
import androidx.core.view.ViewConfigurationCompat
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.widgets.ZoomControl
|
||||
import org.koitharu.kotatsu.core.util.ext.getAnimationDuration
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private const val MAX_SCALE = 2.5f
|
||||
private const val MIN_SCALE = 0.5f
|
||||
|
||||
private const val FLING_RANGE = 20_000
|
||||
|
||||
class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@@ -36,6 +41,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
private val scaleDetector = ScaleGestureDetector(context, this)
|
||||
private val gestureDetector = GestureDetectorCompat(context, GestureListener())
|
||||
private val overScroller = OverScroller(context, AccelerateDecelerateInterpolator())
|
||||
|
||||
private val transformMatrix = Matrix()
|
||||
private val matrixValues = FloatArray(9)
|
||||
private val scale
|
||||
@@ -49,6 +55,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
private val translateBounds = RectF()
|
||||
private val targetHitRect = Rect()
|
||||
private var animator: ValueAnimator? = null
|
||||
private var pendingScroll = 0
|
||||
|
||||
var isZoomEnable = false
|
||||
set(value) {
|
||||
@@ -80,7 +87,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
overScroller.forceFinished(true)
|
||||
}
|
||||
|
||||
gestureDetector.onTouchEvent(ev)
|
||||
val consumed = gestureDetector.onTouchEvent(ev)
|
||||
scaleDetector.onTouchEvent(ev)
|
||||
|
||||
// Offset event to inside the child view
|
||||
@@ -88,11 +95,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
ev.offsetLocation(halfWidth - ev.x + targetHitRect.width() / 3, 0f)
|
||||
}
|
||||
|
||||
// Send action cancel to avoid recycler jump when scale end
|
||||
if (scaleDetector.isInProgress) {
|
||||
ev.action = MotionEvent.ACTION_CANCEL
|
||||
}
|
||||
return super.dispatchTouchEvent(ev)
|
||||
return consumed || scaleDetector.isInProgress || super.dispatchTouchEvent(ev)
|
||||
}
|
||||
|
||||
override fun onGenericMotionEvent(event: MotionEvent): Boolean {
|
||||
@@ -178,6 +181,10 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
scaleY = scale
|
||||
translationX = transX
|
||||
translationY = transY
|
||||
if (pendingScroll != 0) {
|
||||
nestedScrollBy(0, pendingScroll)
|
||||
pendingScroll = 0
|
||||
}
|
||||
}
|
||||
|
||||
val newHeight = if (scale < 1f) (height / scale).toInt() else height
|
||||
@@ -210,6 +217,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
else -> 0f
|
||||
}
|
||||
|
||||
pendingScroll = if (scale > 1) (dy / scale).roundToInt() else 0
|
||||
transformMatrix.postTranslate(dx, dy)
|
||||
syncMatrixValues()
|
||||
}
|
||||
@@ -277,6 +285,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
private fun findTargetChild() = getChildAt(0) as WebtoonRecyclerView
|
||||
|
||||
private inner class GestureListener : GestureDetector.SimpleOnGestureListener(), Runnable {
|
||||
private val prevPos = Point()
|
||||
|
||||
override fun onScroll(
|
||||
e1: MotionEvent?,
|
||||
@@ -294,7 +303,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
val newScale = if (scale != 1f) 1f else MAX_SCALE * 0.8f
|
||||
ValueAnimator.ofFloat(scale, newScale).run {
|
||||
interpolator = AccelerateDecelerateInterpolator()
|
||||
duration = 300
|
||||
duration = context.getAnimationDuration(R.integer.config_defaultAnimTime)
|
||||
addUpdateListener {
|
||||
scaleChild(it.animatedValue as Float, e.x, e.y)
|
||||
}
|
||||
@@ -311,15 +320,16 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
): Boolean {
|
||||
if (scale <= 1) return false
|
||||
|
||||
prevPos.set(transX.toInt(), transY.toInt())
|
||||
overScroller.fling(
|
||||
transX.toInt(),
|
||||
transY.toInt(),
|
||||
prevPos.x,
|
||||
prevPos.y,
|
||||
velocityX.toInt(),
|
||||
velocityY.toInt(),
|
||||
translateBounds.left.toInt(),
|
||||
translateBounds.right.toInt(),
|
||||
translateBounds.top.toInt(),
|
||||
translateBounds.bottom.toInt(),
|
||||
translateBounds.top.toInt() - FLING_RANGE,
|
||||
translateBounds.bottom.toInt() + FLING_RANGE,
|
||||
)
|
||||
postOnAnimation(this)
|
||||
return true
|
||||
@@ -328,9 +338,10 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
override fun run() {
|
||||
if (overScroller.computeScrollOffset()) {
|
||||
transformMatrix.postTranslate(
|
||||
overScroller.currX - transX,
|
||||
overScroller.currY - transY,
|
||||
overScroller.currX.toFloat() - prevPos.x,
|
||||
overScroller.currY.toFloat() - prevPos.y
|
||||
)
|
||||
prevPos.set(overScroller.currX, overScroller.currY)
|
||||
invalidateTarget()
|
||||
postOnAnimation(this)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ class TapGridDispatcher(
|
||||
if (!isDispatching) {
|
||||
return true
|
||||
}
|
||||
return listener.onGridTouch(getArea(event.rawX, event.rawY))
|
||||
val area = getArea(event.rawX, event.rawY) ?: return false
|
||||
return listener.onGridTouch(area)
|
||||
}
|
||||
|
||||
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
|
||||
@@ -42,11 +43,12 @@ class TapGridDispatcher(
|
||||
|
||||
override fun onLongPress(event: MotionEvent) {
|
||||
if (isDispatching) {
|
||||
listener.onGridLongTouch(getArea(event.rawX, event.rawY))
|
||||
val area = getArea(event.rawX, event.rawY) ?: return
|
||||
listener.onGridLongTouch(area)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getArea(x: Float, y: Float): TapGridArea {
|
||||
private fun getArea(x: Float, y: Float): TapGridArea? {
|
||||
val xIndex = (x * 2f / width).roundToInt()
|
||||
val yIndex = (y * 2f / height).roundToInt()
|
||||
val area = when (xIndex) {
|
||||
@@ -73,7 +75,8 @@ class TapGridDispatcher(
|
||||
|
||||
else -> null
|
||||
}
|
||||
return checkNotNull(area) { "Invalid area ($xIndex, $yIndex)" }
|
||||
assert(area != null) { "Invalid area ($xIndex, $yIndex)" }
|
||||
return area
|
||||
}
|
||||
|
||||
interface OnGridTouchListener {
|
||||
|
||||
@@ -52,6 +52,7 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>(), SearchView.OnQuery
|
||||
viewBinding.toolbar.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
top = insets.top
|
||||
)
|
||||
viewBinding.container.updatePadding(
|
||||
bottom = insets.bottom,
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package org.koitharu.kotatsu.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.preference.Preference
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -12,6 +17,8 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
|
||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||
import org.koitharu.kotatsu.core.util.ext.resolveFile
|
||||
import org.koitharu.kotatsu.core.util.ext.tryLaunch
|
||||
import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope
|
||||
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
||||
@@ -25,7 +32,7 @@ class DownloadsSettingsFragment :
|
||||
BasePreferenceFragment(R.string.downloads),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private val dozeHelper = DozeHelper(this)
|
||||
private val dozeHelper = DozeHelper(this)
|
||||
|
||||
@Inject
|
||||
lateinit var storageManager: LocalStorageManager
|
||||
@@ -33,6 +40,10 @@ class DownloadsSettingsFragment :
|
||||
@Inject
|
||||
lateinit var downloadsScheduler: DownloadWorker.Scheduler
|
||||
|
||||
private val pickFileTreeLauncher = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
|
||||
if (it != null) onDirectoryPicked(it)
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.pref_downloads)
|
||||
dozeHelper.updatePreference()
|
||||
@@ -42,6 +53,7 @@ class DownloadsSettingsFragment :
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
findPreference<Preference>(AppSettings.KEY_LOCAL_STORAGE)?.bindStorageName()
|
||||
findPreference<Preference>(AppSettings.KEY_LOCAL_MANGA_DIRS)?.bindDirectoriesCount()
|
||||
findPreference<Preference>(AppSettings.KEY_PAGES_SAVE_DIR)?.bindPagesDirectory()
|
||||
settings.subscribe(this)
|
||||
}
|
||||
|
||||
@@ -63,6 +75,10 @@ class DownloadsSettingsFragment :
|
||||
AppSettings.KEY_DOWNLOADS_WIFI -> {
|
||||
updateDownloadsConstraints()
|
||||
}
|
||||
|
||||
AppSettings.KEY_PAGES_SAVE_DIR -> {
|
||||
findPreference<Preference>(AppSettings.KEY_PAGES_SAVE_DIR)?.bindPagesDirectory()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,10 +98,27 @@ class DownloadsSettingsFragment :
|
||||
dozeHelper.startIgnoreDoseActivity()
|
||||
}
|
||||
|
||||
AppSettings.KEY_PAGES_SAVE_DIR -> {
|
||||
if (!pickFileTreeLauncher.tryLaunch(settings.getPagesSaveDir(preference.context)?.uri)) {
|
||||
Snackbar.make(
|
||||
requireView(), R.string.operation_not_supported, Snackbar.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onDirectoryPicked(uri: Uri) {
|
||||
storageManager.takePermissions(uri)
|
||||
val doc = DocumentFile.fromTreeUri(requireContext(), uri)?.takeIf {
|
||||
it.canWrite()
|
||||
}
|
||||
settings.setPagesSaveDir(doc?.uri)
|
||||
}
|
||||
|
||||
private fun Preference.bindStorageName() {
|
||||
viewLifecycleScope.launch {
|
||||
val storage = storageManager.getDefaultWriteableDir()
|
||||
@@ -104,6 +137,16 @@ class DownloadsSettingsFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun Preference.bindPagesDirectory() {
|
||||
viewLifecycleScope.launch {
|
||||
val df = withContext(Dispatchers.IO) {
|
||||
settings.getPagesSaveDir(this@bindPagesDirectory.context)
|
||||
}
|
||||
summary = df?.getDisplayPath(this@bindPagesDirectory.context)
|
||||
?: this@bindPagesDirectory.context.getString(androidx.preference.R.string.not_set)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateDownloadsConstraints() {
|
||||
val preference = findPreference<Preference>(AppSettings.KEY_DOWNLOADS_WIFI)
|
||||
viewLifecycleScope.launch {
|
||||
@@ -119,4 +162,9 @@ class DownloadsSettingsFragment :
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun DocumentFile.getDisplayPath(context: Context): String {
|
||||
return uri.resolveFile(context)?.path ?: uri.toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.koitharu.kotatsu.scrobbling.shikimori.data.ShikimoriRepository
|
||||
import org.koitharu.kotatsu.sync.domain.SyncController
|
||||
import org.koitharu.kotatsu.sync.ui.SyncSettingsIntent
|
||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||
import org.koitharu.kotatsu.scrobbling.kitsu.ui.KitsuAuthActivity
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -111,7 +112,7 @@ class ServicesSettingsFragment : BasePreferenceFragment(R.string.services),
|
||||
|
||||
AppSettings.KEY_KITSU -> {
|
||||
if (!kitsuRepository.isAuthorized) {
|
||||
launchScrobblerAuth(kitsuRepository)
|
||||
startActivity(Intent(preference.context, KitsuAuthActivity::class.java))
|
||||
} else {
|
||||
startActivity(ScrobblerConfigActivity.newIntent(preference.context, ScrobblerService.KITSU))
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ class SettingsActivity :
|
||||
ACTION_SOURCES -> SourcesSettingsFragment()
|
||||
ACTION_MANAGE_DOWNLOADS -> DownloadsSettingsFragment()
|
||||
ACTION_SOURCE -> SourceSettingsFragment.newInstance(
|
||||
intent.getSerializableExtraCompat(EXTRA_SOURCE) as? MangaSource ?: MangaSource.LOCAL,
|
||||
intent.getSerializableExtraCompat(EXTRA_SOURCE) ?: MangaSource.LOCAL,
|
||||
)
|
||||
|
||||
ACTION_MANAGE_SOURCES -> SourcesManageFragment()
|
||||
|
||||
@@ -59,6 +59,7 @@ class RestoreDialogFragment : AlertDialogFragment<DialogRestoreBinding>(), OnLis
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
return super.onBuildDialog(builder)
|
||||
.setTitle(R.string.restore_backup)
|
||||
.setCancelable(false)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.util.TaggedActivityResult
|
||||
import org.koitharu.kotatsu.core.util.ext.catchingWebViewUnavailability
|
||||
import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat
|
||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
|
||||
@@ -43,10 +42,10 @@ class SourceAuthActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallba
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (!catchingWebViewUnavailability { setContentView(ActivityBrowserBinding.inflate(layoutInflater)) }) {
|
||||
if (!setContentViewWebViewSafe { ActivityBrowserBinding.inflate(layoutInflater) }) {
|
||||
return
|
||||
}
|
||||
val source = intent?.getSerializableExtraCompat(EXTRA_SOURCE) as? MangaSource
|
||||
val source = intent?.getSerializableExtraCompat<MangaSource>(EXTRA_SOURCE)
|
||||
if (source == null) {
|
||||
finishAfterTransition()
|
||||
return
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.google.android.material.color.MaterialColors
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.widgets.SegmentedBarView
|
||||
import org.koitharu.kotatsu.core.util.Colors
|
||||
import org.koitharu.kotatsu.core.util.FileSize
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.databinding.PreferenceMemoryUsageBinding
|
||||
@@ -38,15 +39,15 @@ class StorageUsagePreference @JvmOverloads constructor(
|
||||
val binding = PreferenceMemoryUsageBinding.bind(holder.itemView)
|
||||
val storageSegment = SegmentedBarView.Segment(
|
||||
usage?.savedManga?.percent ?: 0f,
|
||||
segmentColor(materialR.attr.colorPrimary),
|
||||
Colors.segmentColor(context, materialR.attr.colorPrimary),
|
||||
)
|
||||
val pagesSegment = SegmentedBarView.Segment(
|
||||
usage?.pagesCache?.percent ?: 0f,
|
||||
segmentColor(materialR.attr.colorSecondary),
|
||||
Colors.segmentColor(context, materialR.attr.colorSecondary),
|
||||
)
|
||||
val otherSegment = SegmentedBarView.Segment(
|
||||
usage?.otherCache?.percent ?: 0f,
|
||||
segmentColor(materialR.attr.colorTertiary),
|
||||
Colors.segmentColor(context, materialR.attr.colorTertiary),
|
||||
)
|
||||
|
||||
with(binding) {
|
||||
@@ -81,27 +82,4 @@ class StorageUsagePreference @JvmOverloads constructor(
|
||||
context.getString(emptyResId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getHue(hex: String): Float {
|
||||
val r = (hex.substring(0, 2).toInt(16)).toFloat()
|
||||
val g = (hex.substring(2, 4).toInt(16)).toFloat()
|
||||
val b = (hex.substring(4, 6).toInt(16)).toFloat()
|
||||
|
||||
var hue = 0F
|
||||
if ((r >= g) && (g >= b)) {
|
||||
hue = 60 * (g - b) / (r - b)
|
||||
} else if ((g > r) && (r >= b)) {
|
||||
hue = 60 * (2 - (r - b) / (g - b))
|
||||
}
|
||||
return hue
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
private fun segmentColor(@AttrRes resId: Int): Int {
|
||||
val colorHex = String.format("%06x", context.getThemeColor(resId))
|
||||
val hue = getHue(colorHex)
|
||||
val color = ColorUtils.HSLToColor(floatArrayOf(hue, 0.5f, 0.5f))
|
||||
val backgroundColor = context.getThemeColor(materialR.attr.colorSurfaceContainerHigh)
|
||||
return MaterialColors.harmonize(color, backgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.util.ext.ifNullOrEmpty
|
||||
import javax.inject.Inject
|
||||
|
||||
@Reusable
|
||||
class SyncSettings(
|
||||
context: Context,
|
||||
private val account: Account?,
|
||||
|
||||
@@ -293,6 +293,7 @@ class TrackWorker @AssistedInject constructor(
|
||||
setCategory(NotificationCompat.CATEGORY_SERVICE)
|
||||
setDefaults(0)
|
||||
setOngoing(false)
|
||||
setOnlyAlertOnce(true)
|
||||
setSilent(true)
|
||||
setContentIntent(
|
||||
PendingIntentCompat.getActivity(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:minHeight="16dp"
|
||||
android:paddingHorizontal="6dp"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
android:autofillHints="emailAddress"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textEmailAddress"
|
||||
android:maxLength="512"
|
||||
android:singleLine="true"
|
||||
android:textSize="16sp"
|
||||
tools:hint="Email" />
|
||||
@@ -84,7 +85,7 @@
|
||||
android:autofillHints="password"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textPassword"
|
||||
android:maxLength="24"
|
||||
android:maxLength="512"
|
||||
android:singleLine="true"
|
||||
android:textSize="16sp"
|
||||
tools:hint="Password" />
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@id/toolbar"
|
||||
|
||||
54
app/src/main/res/layout/dialog_local_info.xml
Normal file
54
app/src/main/res/layout/dialog_local_info.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="?dialogPreferredPadding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_path_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/location"
|
||||
android:textAppearance="?textAppearanceLabelMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_path"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textAppearance="?textAppearanceBodyMedium"
|
||||
tools:text="/storage/emulated/0/Manga/lorem.cbz" />
|
||||
|
||||
<org.koitharu.kotatsu.core.ui.widgets.SegmentedBarView
|
||||
android:id="@+id/barView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="?colorSecondaryContainer" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label_used"
|
||||
style="@style/Widget.Kotatsu.TextView.Indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_normal"
|
||||
android:text="@string/this_manga"
|
||||
app:drawableStartCompat="@drawable/bg_rounded_square"
|
||||
tools:drawableTint="?colorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label_available"
|
||||
style="@style/Widget.Kotatsu.TextView.Indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_small"
|
||||
android:text="@string/available"
|
||||
app:drawableStartCompat="@drawable/bg_rounded_square"
|
||||
app:drawableTint="?colorSecondaryContainer" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -4,20 +4,11 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:paddingVertical="?dialogPreferredPadding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="?dialogPreferredPadding"
|
||||
android:paddingBottom="@dimen/margin_normal"
|
||||
android:text="@string/restore_backup"
|
||||
android:textAppearance="?textAppearanceTitleLarge" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
@@ -31,7 +22,8 @@
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:scrollIndicators="top|bottom"
|
||||
android:visibility="gone"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
|
||||
|
||||
<TextView
|
||||
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
|
||||
android:id="@+id/textView_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -52,12 +52,13 @@
|
||||
android:ellipsize="end"
|
||||
android:maxLines="5"
|
||||
android:textAppearance="?attr/textAppearanceHeadlineSmall"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
|
||||
<TextView
|
||||
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
|
||||
android:id="@+id/textView_subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -67,6 +68,7 @@
|
||||
android:ellipsize="end"
|
||||
android:maxLines="3"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
||||
app:layout_constraintTop_toBottomOf="@id/textView_title"
|
||||
@@ -172,8 +174,8 @@
|
||||
android:ellipsize="end"
|
||||
android:paddingVertical="2dp"
|
||||
android:singleLine="true"
|
||||
tools:text="@string/approximate_reading_time"
|
||||
android:textAppearance="?attr/textAppearanceBodyLarge" />
|
||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||
tools:text="@string/approximate_reading_time" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/approximate_read_time"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:paddingHorizontal="12dp"
|
||||
@@ -13,6 +13,8 @@
|
||||
android:id="@+id/chips_tags"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:paddingVertical="@dimen/margin_small"
|
||||
app:chipStyle="@style/Widget.Kotatsu.Chip.Filter"
|
||||
app:selectionRequired="false"
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||
tools:text="@tools:sample/lorem[15]" />
|
||||
tools:text="@tools:sample/lorem[15]"
|
||||
tools:textColor="?android:textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_description"
|
||||
@@ -38,7 +39,8 @@
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||
tools:text="05.10.2021 • Scanlator" />
|
||||
tools:text="05.10.2021 • Scanlator"
|
||||
tools:textColor="?android:textColorTertiary" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/custom_selectable_item_background"
|
||||
android:visibility="gone"
|
||||
app:drawableTopCompat="@drawable/ic_storage"
|
||||
tools:text="1.8 GiB"
|
||||
|
||||
@@ -12,4 +12,9 @@
|
||||
android:icon="@drawable/ic_grid"
|
||||
android:title="@string/pages" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_forget"
|
||||
android:icon="@drawable/ic_delete"
|
||||
android:title="@string/remove_from_history" />
|
||||
|
||||
</menu>
|
||||
|
||||
@@ -78,15 +78,15 @@
|
||||
<string name="search_history_cleared">Гісторыя пошуку ачышчана</string>
|
||||
<string name="clear_search_history">Ачысціць гісторыю пошуку</string>
|
||||
<string name="gestures_only">Толькі жэсты</string>
|
||||
<string name="internal_storage">Унутранае сховішча</string>
|
||||
<string name="internal_storage">Ўнутранае сховішча</string>
|
||||
<string name="external_storage">Знешняе сховішча</string>
|
||||
<string name="domain">Дамен</string>
|
||||
<string name="app_update_available">Даступна абнаўленне праграмы</string>
|
||||
<string name="open_in_browser">Адкрыць у браўзеры</string>
|
||||
<string name="large_manga_save_confirm">У гэтай манге %s. Вы ўпэўненыя, што хочаце захаваць іх усё\?</string>
|
||||
<string name="large_manga_save_confirm">Ў гэтай манге %s. Вы ўпэўненыя, што хочаце захаваць іх усё?</string>
|
||||
<string name="save_manga">Захаваць мангу</string>
|
||||
<string name="notifications">Паведамленні</string>
|
||||
<string name="enabled_d_of_d">Уключана %1$d з %2$d</string>
|
||||
<string name="enabled_d_of_d">Ўключана %1$d з %2$d</string>
|
||||
<string name="new_chapters">Новыя раздзелы</string>
|
||||
<string name="download">Спампаваць</string>
|
||||
<string name="notifications_settings">Налады апавяшчэнняў</string>
|
||||
@@ -104,7 +104,7 @@
|
||||
<string name="other_storage">Іншае сховішча</string>
|
||||
<string name="done">Гатова</string>
|
||||
<string name="all_favourites">Усе абраныя</string>
|
||||
<string name="favourites_category_empty">У гэтай катэгорыі нічога няма</string>
|
||||
<string name="favourites_category_empty">Ў гэтай катэгорыі нічога няма</string>
|
||||
<string name="read_later">Прачытаць пазней</string>
|
||||
<string name="updates">Абнаўленні</string>
|
||||
<string name="text_feed_holder">Тут паказваюцца новыя раздзелы таго, што вы чытаеце</string>
|
||||
@@ -118,7 +118,7 @@
|
||||
<string name="feed_will_update_soon">Абнаўленне хутка пачнецца</string>
|
||||
<string name="track_sources">Правяраць абнаўленні мангі</string>
|
||||
<string name="dont_check">Не правяраць</string>
|
||||
<string name="enter_password">Увядзіце пароль</string>
|
||||
<string name="enter_password">Ўвядзіце пароль</string>
|
||||
<string name="wrong_password">Няверны пароль</string>
|
||||
<string name="protect_application">Абараніць праграму</string>
|
||||
<string name="protect_application_summary">Запытваць пароль пры запуску праграмы</string>
|
||||
@@ -131,7 +131,7 @@
|
||||
<string name="right_to_left">Справа налева</string>
|
||||
<string name="create_category">Стварыць катэгорыю</string>
|
||||
<string name="scale_mode">Маштабаванне</string>
|
||||
<string name="zoom_mode_fit_center">Умясціць у экран</string>
|
||||
<string name="zoom_mode_fit_center">Ўмясціць ў экран</string>
|
||||
<string name="zoom_mode_fit_height">Падагнаць па вышыні</string>
|
||||
<string name="zoom_mode_fit_width">Падагнаць па шырыні</string>
|
||||
<string name="zoom_mode_keep_start">Зыходны памер</string>
|
||||
@@ -147,7 +147,7 @@
|
||||
<string name="data_restored_with_errors">Данныя адноўлены, але ўзніклі некаторыя памылкі</string>
|
||||
<string name="backup_information">Вы можаце стварыць рэзервовую копію абранага і гісторыі і потым аднавіць іх</string>
|
||||
<string name="just_now">Толькі што</string>
|
||||
<string name="yesterday">Учора</string>
|
||||
<string name="yesterday">Ўчора</string>
|
||||
<string name="long_ago">Даўно</string>
|
||||
<string name="group">Групаваць</string>
|
||||
<string name="today">Сёння</string>
|
||||
@@ -161,8 +161,8 @@
|
||||
<string name="clear_feed">Ачысціць стужку</string>
|
||||
<string name="text_clear_updates_feed_prompt">Уся гісторыя абнаўленняў будзе ачышчана і яе нельга будзе вярнуць. Вы ўпэўненыя\?</string>
|
||||
<string name="check_for_new_chapters">Праверка новых глаў</string>
|
||||
<string name="reverse">У адваротным парадку</string>
|
||||
<string name="sign_in">Увайсці</string>
|
||||
<string name="reverse">Ў адваротным парадку</string>
|
||||
<string name="sign_in">Ўвайсці</string>
|
||||
<string name="auth_required">Для прагляду гэтага кантэнту патрабуецца аўтарызацыя</string>
|
||||
<string name="default_s">Прадвызначаны: %s</string>
|
||||
<string name="next">Далей</string>
|
||||
@@ -181,7 +181,7 @@
|
||||
<string name="text_search_holder_secondary">Паспрабуйце перафармуляваць запыт.</string>
|
||||
<string name="text_empty_holder_primary">Неяк тут пуста…</string>
|
||||
<string name="chapter_is_missing">Глава адсутнічае</string>
|
||||
<string name="queued">У чарзе</string>
|
||||
<string name="queued">Ў чарзе</string>
|
||||
<string name="about_app_translation_summary">Дапамагчы з перакладам праграмы</string>
|
||||
<string name="about_app_translation">Пераклад</string>
|
||||
<string name="text_clear_cookies_prompt">Вы выйдзеце з усіх крыніц, у якіх вы аўтарызаваны</string>
|
||||
@@ -193,7 +193,7 @@
|
||||
<string name="system_default">Па змаўчанні</string>
|
||||
<string name="exclude_nsfw_from_history">Выключыць NSFW мангу з гісторыі</string>
|
||||
<string name="show_pages_numbers">Паказваць нумары старонак</string>
|
||||
<string name="enabled_sources">Уключаныя крыніцы</string>
|
||||
<string name="enabled_sources">Ўключаныя крыніцы</string>
|
||||
<string name="available_sources">Даступныя крыніцы</string>
|
||||
<string name="computing_">Вылічэнні…</string>
|
||||
<string name="screenshots_allow">Дазваляць</string>
|
||||
@@ -202,12 +202,12 @@
|
||||
<string name="screenshots_block_nsfw">Забараніць для NSFW</string>
|
||||
<string name="filter_load_error">Немагчыма загрузіць спіс жанраў</string>
|
||||
<string name="disabled">Адключаны</string>
|
||||
<string name="enabled">Уключаны</string>
|
||||
<string name="enabled">Ўключаны</string>
|
||||
<string name="exclude_nsfw_from_suggestions">Ня прапаноўваць NSFW мангу</string>
|
||||
<string name="text_suggestion_holder">Пачніце чытаць мангу, і вы атрымаеце персаналізаваныя прапановы</string>
|
||||
<string name="suggestions_info">Усе даныя аналізуюцца толькі лакальна на гэтай прыладзе і нікуды не адпраўляюцца.</string>
|
||||
<string name="suggestions_summary">Прапануеце мангу, заснаваную на вашых перавагах</string>
|
||||
<string name="suggestions_enable">Уключыць прапановы</string>
|
||||
<string name="suggestions_enable">Ўключыць прапановы</string>
|
||||
<string name="suggestions">Прапанова</string>
|
||||
<string name="onboard_text">Выберыце мову, на якой вы хочаце чытаць мангу. Вы зможаце змяніць гэта пазней.</string>
|
||||
<string name="reset_filter">Скінуць фільтр</string>
|
||||
@@ -220,7 +220,7 @@
|
||||
<string name="various_languages">Розныя мовы</string>
|
||||
<string name="search_chapters">Знайсці главу</string>
|
||||
<string name="percent_string_pattern">%1$s%%</string>
|
||||
<string name="chapters_empty">У гэтай манзе няма глаў</string>
|
||||
<string name="chapters_empty">Ў гэтай манге няма раздзелаў</string>
|
||||
<string name="hide">Схаваць</string>
|
||||
<string name="appearance">Знешні выгляд</string>
|
||||
<string name="disable_all">Выключыць усё</string>
|
||||
@@ -233,7 +233,7 @@
|
||||
<string name="check_new_chapters_title">Правяраць новыя главы і паведамляць пра іх</string>
|
||||
<string name="show_notification_new_chapters_on">Вы будзеце атрымліваць апавяшчэнні пра абнаўленні мангі, якую вы чытаеце</string>
|
||||
<string name="show_notification_new_chapters_off">Вы не будзеце атрымліваць паведамленні, але новыя главы будуць паказаны ў спісе</string>
|
||||
<string name="notifications_enable">Уключыць апавяшчэнні</string>
|
||||
<string name="notifications_enable">Ўключыць апавяшчэнні</string>
|
||||
<string name="bookmarks">Закладкі</string>
|
||||
<string name="bookmark_removed">Закладка выдалена</string>
|
||||
<string name="bookmark_added">Закладка дадазена</string>
|
||||
@@ -244,7 +244,7 @@
|
||||
<string name="new_sources_text">Даступныя новыя крыніцы мангі</string>
|
||||
<string name="download_slowdown">Запавольванне спампоўкі</string>
|
||||
<string name="suggestions_excluded_genres">Выключыць жанры</string>
|
||||
<string name="suggestions_excluded_genres_summary">Укажыце жанры, якія вы не хочаце бачыць у рэкамендацыях</string>
|
||||
<string name="suggestions_excluded_genres_summary">Укажыце жанры, якія вы не хочаце бачыць ў рэкамендацыях</string>
|
||||
<string name="text_delete_local_manga_batch">Выдаліць выбраныя элементы з прылады назаўжды\?</string>
|
||||
<string name="removal_completed">Выдаленне завершана</string>
|
||||
<string name="download_slowdown_summary">Дапамагае пазбегнуць блакіроўкі па IP-адрасе</string>
|
||||
@@ -303,7 +303,7 @@
|
||||
<string name="theme_name_dynamic">Дынамічны</string>
|
||||
<string name="color_theme">Каляровая гама</string>
|
||||
<string name="language">Мова</string>
|
||||
<string name="account_already_exists">Уліковы запіс ужо існуе</string>
|
||||
<string name="account_already_exists">Ўліковы запіс ужо існуе</string>
|
||||
<string name="back">Назад</string>
|
||||
<string name="sync">Сінхранізацыя</string>
|
||||
<string name="sync_title">Сінхранізацыя вашых дадзеных</string>
|
||||
@@ -313,7 +313,7 @@
|
||||
<string name="manga_error_description_pattern">Дэталі памылкі:<br><tt>%1$s</tt><br><br>1. Паспрабуйце <a href=%2$s>адкрыць мангу ў вэб-браўзеры</a>, каб пераканацца, што яна даступная ў крыніцы<br>2. Упэўніцеся, што вы выкарыстоўваеце <a href=kotatsu://about>апошнюю версію Kotatsu</a><br>3. Калі ён даступны, адпраўце распрацоўнікам справаздачу аб памылцы.</string>
|
||||
<string name="history_shortcuts">Паказаць апошнія ярлыкі мангі</string>
|
||||
<string name="history_shortcuts_summary">Зрабіце нядаўнюю мангу даступнай, доўга націскаючы на значок праграмы</string>
|
||||
<string name="reader_control_ltr_summary">Дакрананне да правага краю або націсканне правай клавішы заўсёды пераключае на наступную старонку</string>
|
||||
<string name="reader_control_ltr_summary">Націск на правы край або націск правай клавішы заўсёды перамыкае на наступную старонку.</string>
|
||||
<string name="reader_control_ltr">Эрганамічны упраўленне чытаннем</string>
|
||||
<string name="color_correction">Карэкцыя колеру</string>
|
||||
<string name="brightness">Яркасць</string>
|
||||
@@ -322,9 +322,9 @@
|
||||
<string name="color_correction_hint">Выбраныя налады колеру будуць запомнены для гэтай мангі</string>
|
||||
<string name="text_unsaved_changes_prompt">Захаваць ці адхіліць незахаваныя змены\?</string>
|
||||
<string name="discard">Адмяніць</string>
|
||||
<string name="enable_logging">Уключыць запіс</string>
|
||||
<string name="enable_logging">Ўключыць запіс</string>
|
||||
<string name="share_logs">Падзяліцца логамі</string>
|
||||
<string name="enable_logging_summary">Запішыце некаторыя дзеянні для адладкі. Уключайце толькі калі ведаеце, што робіце</string>
|
||||
<string name="enable_logging_summary">Запішыце некаторыя дзеянні для адладкі. Ўключайце толькі калі ведаеце, што робіце</string>
|
||||
<string name="show_suspicious_content">Паказаць падазроны кантэнт</string>
|
||||
<string name="text_shelf_holder_primary">Ваша манга будзе адлюстроўвацца тут</string>
|
||||
<string name="text_shelf_holder_secondary">Знайдзіце, што пачытаць, у раздзеле «Агляд»</string>
|
||||
@@ -395,7 +395,7 @@
|
||||
<string name="downloads_wifi_only_summary">Спыніць загрузку пры пераключэнні на мабільную сетку</string>
|
||||
<string name="suggestions_notifications_summary">Часам паказваць апавяшчэнні з прапанаванай мангай</string>
|
||||
<string name="more">Больш</string>
|
||||
<string name="enable">Уключыць</string>
|
||||
<string name="enable">Ўключыць</string>
|
||||
<string name="cancel_all_downloads_confirm">Усе актыўныя спампоўкі будуць адменены, часткова спампаваныя даныя будуць страчаны</string>
|
||||
<string name="suggestions_enable_prompt">Хочаце атрымліваць персаналізаваныя прапановы мангі\?</string>
|
||||
<string name="suggestion_manga">Прапанова: %s</string>
|
||||
@@ -431,7 +431,7 @@
|
||||
<string name="restore_summary">Аднавіць раней створаную рэзервовую копію</string>
|
||||
<string name="reader_info_bar_summary">Паказаць бягучы час і ход чытання ў верхняй частцы экрана</string>
|
||||
<string name="pages_animation_summary">Анімацыя перагортвання старонак</string>
|
||||
<string name="clear_source_cookies_summary">Выдаліць файлы cookie толькі для вызначанага дамена. У большасці выпадкаў гэта робіць аўтарызацыю несапраўднай</string>
|
||||
<string name="clear_source_cookies_summary">Выдаліць файлы cookie толькі для вызначанага дамена. Ў большасці выпадкаў гэта робіць аўтарызацыю несапраўднай</string>
|
||||
<string name="download_option_whole_manga">Манга цалкам</string>
|
||||
<string name="local_manga_directories">Лакальныя каталогі мангі</string>
|
||||
<string name="download_option_all_chapters">Усе раздзелы з перакладам %s</string>
|
||||
@@ -456,16 +456,16 @@
|
||||
<string name="color_black">Чорны</string>
|
||||
<string name="background">Фон</string>
|
||||
<string name="data_not_restored_text">Пераканайцеся, што вы выбралі правільны файл рэзервовай копіі</string>
|
||||
<string name="search_hint">Увядзіце назву мангі, жанр або назву крыніцы</string>
|
||||
<string name="search_hint">Ўвядзіце назву мангі, жанр або назву крыніцы</string>
|
||||
<string name="progress">Прагрэс</string>
|
||||
<string name="manage_categories">Упраўленне катэгорыямі</string>
|
||||
<string name="manage_categories">Кіраванне катэгорыямі</string>
|
||||
<string name="order_added">Дададзена</string>
|
||||
<string name="view_list">Прагляд спісу</string>
|
||||
<string name="show">Паказаць</string>
|
||||
<string name="captcha_required_summary">Для правільнай працы %s патрабуецца праверка captcha</string>
|
||||
<string name="languages">Мовы</string>
|
||||
<string name="unknown">Невядомы</string>
|
||||
<string name="in_progress">У працэсе</string>
|
||||
<string name="in_progress">Ў працэсе</string>
|
||||
<string name="disable_nsfw">Адключыць NSFW</string>
|
||||
<string name="too_many_requests_message">Занадта шмат запытаў. Паўтарыце спробу пазней</string>
|
||||
<string name="related_manga_summary">Паказаць спіс звязанай мангі. У некаторых выпадках ён можа быць недакладным або адсутнічаць</string>
|
||||
@@ -478,7 +478,7 @@
|
||||
<string name="items_limit_exceeded">Больш нельга дадаваць элементы</string>
|
||||
<string name="directories">Каталогі</string>
|
||||
<string name="main_screen_sections">Раздзелы галоўнага экрана</string>
|
||||
<string name="to_top">Уверх</string>
|
||||
<string name="to_top">Ўверх</string>
|
||||
<string name="zoom_in">Павялічыць</string>
|
||||
<string name="reader_zoom_buttons_summary">Ці паказваць кнопкі кіравання маштабаваннем у правым ніжнім куце</string>
|
||||
<string name="reader_zoom_buttons">Паказаць кнопкі маштабавання</string>
|
||||
@@ -496,7 +496,7 @@
|
||||
<string name="online_variant">Анлайн варыянт</string>
|
||||
<string name="frequency_every_day">Кожны дзень</string>
|
||||
<string name="backup_frequency">Частата стварэння рэзервовых копій</string>
|
||||
<string name="periodic_backups_enable">Уключыць перыядычнае рэзервовае капіраванне</string>
|
||||
<string name="periodic_backups_enable">Ўключыць перыядычнае рэзервовае капіраванне</string>
|
||||
<string name="frequency_every_2_days">Кожныя 2 дні</string>
|
||||
<string name="frequency_once_per_week">Раз на тыдзень</string>
|
||||
<string name="periodic_backups">Перыядычнае рэзервовае капіраванне</string>
|
||||
@@ -514,10 +514,10 @@
|
||||
<string name="catalog">Каталог</string>
|
||||
<string name="manage_sources">Кіраванне крыніцамі</string>
|
||||
<string name="no_manga_sources_found">Па вашаму запыту не знойдзена даступных крыніц мангі</string>
|
||||
<string name="manual">Уручную</string>
|
||||
<string name="manual">Ўручную</string>
|
||||
<string name="source_enabled">Крыніца ўключана</string>
|
||||
<string name="disable_nsfw_summary">Адключыць крыніцы NSFW і схавайць мангу для дарослых са спісу, калі гэта магчыма</string>
|
||||
<string name="no_manga_sources_catalog_text">У гэтым раздзеле няма даступных крыніц, ці ўсе яны маглі быць ужо дададзены.
|
||||
<string name="no_manga_sources_catalog_text">Ў гэтым раздзеле няма даступных крыніц, ці ўсе яны маглі быць ужо дададзены.
|
||||
\nСачыце за абнаўленнямі</string>
|
||||
<string name="available_d">Даступна: %1$d</string>
|
||||
<string name="content_type_other">Іншае</string>
|
||||
@@ -542,7 +542,7 @@
|
||||
<string name="welcome_text">Выберыце, якія крыніцы змесціва вы хочаце ўключыць. Гэта таксама можна наладзіць пазней у наладах</string>
|
||||
<string name="restore">Аднавіць</string>
|
||||
<string name="backup_date_">Дата стварэння рэзервовай копіі: %s</string>
|
||||
<string name="sync_auth">Увайдзіце, каб сінхранізаваць уліковы запіс</string>
|
||||
<string name="sync_auth">Ўвайдзіце, каб сінхранізаваць ўліковы запіс</string>
|
||||
<string name="by_name_reverse">Імя (зваротнае)</string>
|
||||
<string name="content_rating">Рэйтынг кантэнту</string>
|
||||
<string name="genres_exclude">Выключыць жанры</string>
|
||||
@@ -565,7 +565,7 @@
|
||||
<string name="prev_page">Папярэдняя старонка</string>
|
||||
<string name="next_page">Наступная старонка</string>
|
||||
<string name="reader_actions">Дзеянні ў рэжыме чытання</string>
|
||||
<string name="switch_pages_volume_buttons">Уключыць кнопкі гучнасці</string>
|
||||
<string name="switch_pages_volume_buttons">Ўключыць кнопкі гучнасці</string>
|
||||
<string name="switch_pages_volume_buttons_summary">Выкарыстоўвайце кнопкі гучнасці для гартання старонак</string>
|
||||
<string name="tap_action">Дзеянне пры націску</string>
|
||||
<string name="long_tap_action">Дзеянне пры доўгім націску</string>
|
||||
@@ -584,4 +584,13 @@
|
||||
<string name="default_webtoon_zoom_out">Аддаленне ў рэжыме манхвы</string>
|
||||
<string name="fullscreen_mode">Поўнаэкранны рэжым</string>
|
||||
<string name="reader_fullscreen_summary">Схаваць інтэрфейс сістэмы</string>
|
||||
<string name="suggestions_unavailable_text">Функцыя прапаноў адключана</string>
|
||||
<string name="check_for_new_chapters_disabled">Праверка новых раздзелаў адключана</string>
|
||||
<string name="reading_time_estimation">Паказаць прыблізны час чытання</string>
|
||||
<string name="reading_time_estimation_summary">Значэнне ацэнкі часу можа быць недакладным</string>
|
||||
<string name="show_labels_in_navbar">Паказаць меткі на панэлі навігацыі</string>
|
||||
<string name="ask_for_dest_dir_every_time">Кожны раз запытваць каталог прызначэння</string>
|
||||
<string name="default_page_save_dir">Каталог захавання старонкі па змаўчанні</string>
|
||||
<string name="remove_from_history">Выдаліць з гісторыі</string>
|
||||
<string name="pages_saving">Захаванне старонак</string>
|
||||
</resources>
|
||||
@@ -328,7 +328,7 @@
|
||||
<string name="color_correction_hint">Los ajustes de color elegidos serán recordados para este manga</string>
|
||||
<string name="feed">Fuente</string>
|
||||
<string name="history_shortcuts">Mostrar los accesos directos a los mangas recientes</string>
|
||||
<string name="reader_control_ltr_summary">Tocando el borde derecho o pulsando la tecla derecha se pasa siempre a la página siguiente</string>
|
||||
<string name="reader_control_ltr_summary">Navegar a continuación siempre te lleva a la página siguiente cuando utilizas el ratón y el teclado.</string>
|
||||
<string name="reader_control_ltr">Control ergonómico del lector</string>
|
||||
<string name="color_correction">Corrección del color</string>
|
||||
<string name="brightness">Brillo</string>
|
||||
@@ -584,4 +584,13 @@
|
||||
<string name="default_webtoon_zoom_out">Alejar el zoom del webtoon predeterminado</string>
|
||||
<string name="fullscreen_mode">Modo de pantalla completa</string>
|
||||
<string name="reader_fullscreen_summary">Ocultar las barras de estado y navegación del sistema</string>
|
||||
<string name="reading_time_estimation">Mostrar el iempo estimado de lectura</string>
|
||||
<string name="reading_time_estimation_summary">El valor estimado puede ser inexacto</string>
|
||||
<string name="check_for_new_chapters_disabled">La búsqueda de nuevos capítulos está desactivada</string>
|
||||
<string name="suggestions_unavailable_text">Sugerencias desactivadas</string>
|
||||
<string name="show_labels_in_navbar">Mostrar etiquetas en la barra de navegación</string>
|
||||
<string name="ask_for_dest_dir_every_time">Preguntar siempre por el directorio de destino</string>
|
||||
<string name="remove_from_history">Eliminar del historial</string>
|
||||
<string name="pages_saving">Guardar páginas</string>
|
||||
<string name="default_page_save_dir">Directorio predeterminado para guardar páginas</string>
|
||||
</resources>
|
||||
@@ -1,27 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<plurals name="items">
|
||||
<item quantity="one">%1$d aytem</item>
|
||||
<item quantity="other">%1$d (na) aytem</item>
|
||||
</plurals>
|
||||
<plurals name="minutes_ago">
|
||||
<item quantity="one">%1$d minutong nakakalipas</item>
|
||||
<item quantity="other">%1$d (na) minutong nakakalipas</item>
|
||||
</plurals>
|
||||
<plurals name="new_chapters">
|
||||
<item quantity="one">%1$d bagong kabanata</item>
|
||||
<item quantity="other">%1$d mga bagong kabanata</item>
|
||||
</plurals>
|
||||
<plurals name="chapters">
|
||||
<item quantity="one">"%1$d kabanata"</item>
|
||||
<item quantity="other">%1$d (na) kabanata</item>
|
||||
</plurals>
|
||||
<plurals name="hours_ago">
|
||||
<item quantity="one">%1$d oras ang nakalipas</item>
|
||||
<item quantity="other">%1$d (na) oras ang nakalipas</item>
|
||||
</plurals>
|
||||
<plurals name="days_ago">
|
||||
<item quantity="one">%1$d araw ang nakalipas</item>
|
||||
<item quantity="other">%1$d (na) araw ang nakalipas</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
<plurals name="items">
|
||||
<item quantity="one">%1$d aytem</item>
|
||||
<item quantity="other">%1$d (na) aytem</item>
|
||||
</plurals>
|
||||
<plurals name="minutes_ago">
|
||||
<item quantity="one">%1$d minutong nakakalipas</item>
|
||||
<item quantity="other">%1$d (na) minutong nakakalipas</item>
|
||||
</plurals>
|
||||
<plurals name="new_chapters">
|
||||
<item quantity="one">%1$d bagong kabanata</item>
|
||||
<item quantity="other">%1$d mga bagong kabanata</item>
|
||||
</plurals>
|
||||
<plurals name="chapters">
|
||||
<item quantity="one">"%1$d kabanata"</item>
|
||||
<item quantity="other">%1$d (na) kabanata</item>
|
||||
</plurals>
|
||||
<plurals name="hours_ago">
|
||||
<item quantity="one">%1$d oras ang nakalipas</item>
|
||||
<item quantity="other">%1$d (na) oras ang nakalipas</item>
|
||||
</plurals>
|
||||
<plurals name="days_ago">
|
||||
<item quantity="one">%1$d araw ang nakalipas</item>
|
||||
<item quantity="other">%1$d (na) araw ang nakalipas</item>
|
||||
</plurals>
|
||||
<plurals name="months_ago">
|
||||
<item quantity="one">%1$d buwan nakakalipas</item>
|
||||
<item quantity="other">%1$d (na) buwan nakakalipas</item>
|
||||
</plurals>
|
||||
<plurals name="hours">
|
||||
<item quantity="one">%1$d oras</item>
|
||||
<item quantity="other">%1$d (na) oras</item>
|
||||
</plurals>
|
||||
<plurals name="minutes">
|
||||
<item quantity="one">%1$d minuto</item>
|
||||
<item quantity="other">%1$d (na) minuto</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -346,7 +346,7 @@
|
||||
<string name="allow_unstable_updates_summary">Makakuha ng paunawa tungkol sa mga unstable build</string>
|
||||
<string name="network_unavailable">Hindi magagamit ang network</string>
|
||||
<string name="network_unavailable_hint">I-on ang Wi-Fi o mobile network para magbasa ng manga online</string>
|
||||
<string name="reader_control_ltr_summary">Mag-tap sa kanang gilid o ang pagpindot sa kanang key ay palaging lilipat sa susunod na pahina</string>
|
||||
<string name="reader_control_ltr_summary">Ang susunod na pag-navigate ay palaging magdadala sa iyo sa susunod na pahina kapag gumagamit ng mouse at keyboard.</string>
|
||||
<string name="reader_slider">Ipakita ang slider ng paglipat ng pahina</string>
|
||||
<string name="manga_error_description_pattern">Mga detalye ng error:<br><tt>%1$s</tt><br><br>1. Subukang <a href=%2$s>magbukas ng manga sa isang web browser</a> upang matiyak na available ito sa souce<br>2. Tiyaking ginagamit mo ang <a href=kotatsu://about>pinakabagong bersyon ng Kotatsu</a><br>3. Kung available ito, magpadala ng ulat ng error sa mga developer.</string>
|
||||
<string name="enable_logging">Paganahin ang pag-log</string>
|
||||
@@ -377,7 +377,7 @@
|
||||
<string name="show_on_shelf">Ipakita sa Istante</string>
|
||||
<string name="speed">Bilis</string>
|
||||
<string name="comics_archive_import_description">Maaari kang pumili ng isa o higit pang .cbz o .zip file, ang bawat file ay makikilala bilang isang hiwalay na manga.</string>
|
||||
<string name="folder_with_images_import_description">Maaari kang pumili ng isang directory na may mga archive o mga larawan. Ang bawat archive (o subdirectory) ay makikilala bilang isang kabanata.</string>
|
||||
<string name="folder_with_images_import_description">Maaari kang pumili ng isang direktoryo na may mga archive o mga larawan. Ang bawat archive (o subdirectory) ay makikilala bilang isang kabanata.</string>
|
||||
<string name="find_similar">Maghanap ng katulad</string>
|
||||
<string name="sync_auth_hint">Maaari kang mag-sign in sa isang umiiral na account o lumikha ng bago</string>
|
||||
<string name="translations">Mga pagsasalin</string>
|
||||
@@ -438,7 +438,7 @@
|
||||
<string name="download_option_manual_selection">Manu-manong pumili ng mga kabanata</string>
|
||||
<string name="invert_colors">Baliktarin ang mga kulay</string>
|
||||
<string name="custom_directory">Custom na direktoryo</string>
|
||||
<string name="pick_custom_directory">Pumili ng Custom na direktoryo</string>
|
||||
<string name="pick_custom_directory">Pumili ng custom na direktoryo</string>
|
||||
<string name="no_access_to_file">Wala kang access sa file o direktoryo na ito</string>
|
||||
<string name="local_manga_directories">Mga lokal na direktoryo ng manga</string>
|
||||
<string name="password">Password</string>
|
||||
@@ -478,7 +478,7 @@
|
||||
<string name="on_device">Sa device</string>
|
||||
<string name="moved_to_top">Nailipat sa itaas</string>
|
||||
<string name="items_limit_exceeded">Wala nang mga aytem na pwedeng idagdag</string>
|
||||
<string name="directories">Mga Directory</string>
|
||||
<string name="directories">Mga direktoryo</string>
|
||||
<string name="reader_zoom_buttons">Ipakita ang mga button ng pag-zoom</string>
|
||||
<string name="main_screen_sections">Mga pangunahing seksyon ng screen</string>
|
||||
<string name="zoom_out">Mag-zoom palabas</string>
|
||||
@@ -502,7 +502,7 @@
|
||||
<string name="periodic_backups">Mga periodic na pag-backup</string>
|
||||
<string name="frequency_twice_per_month">Dalawang beses bawat buwan</string>
|
||||
<string name="frequency_once_per_month">Isang beses bawat buwan</string>
|
||||
<string name="backups_output_directory">Output directory ng mga backup</string>
|
||||
<string name="backups_output_directory">Output na direktoryo sa mga backup</string>
|
||||
<string name="last_successful_backup">Huling matagumpay na pag-backup: %s</string>
|
||||
<string name="speed_value">x%.1f</string>
|
||||
<string name="sources_catalog">Katalugo ng mga source</string>
|
||||
@@ -557,4 +557,40 @@
|
||||
\n
|
||||
\nBabala: mawawala ang kasalukuyang progress sa pagbabasa.</string>
|
||||
<string name="category_hidden_done">Nakatago ang kategoryang ito mula sa pangunahing screen at naa-access sa pamamagitan ng Menu → Ayusin ang mga kategorya</string>
|
||||
<string name="remove_from_history">Alisin sa kasaysayan</string>
|
||||
<string name="incognito_mode_hint">Hindi mase-save ang iyong progress sa pagbabasa</string>
|
||||
<string name="last_read">Huling nabasa</string>
|
||||
<string name="default_webtoon_zoom_out">Default zoom out sa webtoon</string>
|
||||
<string name="show_labels_in_navbar">Ipakita ang mga label sa navigation bar</string>
|
||||
<string name="pages_saving">Nagse-save ng mga pahina</string>
|
||||
<string name="ask_for_dest_dir_every_time">Laging magtanong sa direktoryo ng patutunguhan</string>
|
||||
<string name="default_page_save_dir">Default na direktoryo ng pag-save ng pahina</string>
|
||||
<string name="email_password_enter_hint">Ilagay ang iyong email at password upang magpatuloy</string>
|
||||
<string name="remaining_time_pattern">%1$s %2$s</string>
|
||||
<string name="volume_">Volume %d</string>
|
||||
<string name="volume_unknown">Hindi kilalang volume</string>
|
||||
<string name="approximate_remaining_time">Tinatayang natitirang oras</string>
|
||||
<string name="vertical">Patayo</string>
|
||||
<string name="show_menu">Ipakita ang menu</string>
|
||||
<string name="tap_action">Aksyon sa pag-tap</string>
|
||||
<string name="long_tap_action">Aksyon sa matagal na pag-tap</string>
|
||||
<string name="none">Wala</string>
|
||||
<string name="config_reset_confirm">I-reset ang mga setting sa mga default na value? Ang gawaing ito ay hindi pwedeng bawiin.</string>
|
||||
<string name="use_two_pages_landscape">Gumamit ng dalawang page na layout sa landscape na oryentasyon (beta)</string>
|
||||
<string name="fullscreen_mode">Fullscreen mode</string>
|
||||
<string name="reader_fullscreen_summary">Itago ang status ng system at mga navigation bar</string>
|
||||
<string name="two_pages">Dalawang pahina</string>
|
||||
<string name="toggle_ui">Ipakita/itago ang UI</string>
|
||||
<string name="prev_chapter">Nakaraang kabanata</string>
|
||||
<string name="next_chapter">Sunod na kabanata</string>
|
||||
<string name="prev_page">Nakaraang pahina</string>
|
||||
<string name="next_page">Susunod na pahina</string>
|
||||
<string name="reader_actions">Mga aksyon sa reader</string>
|
||||
<string name="reader_actions_summary">Ayusin ang mga pagkilos para sa mga nata-tap na lugar ng screen</string>
|
||||
<string name="switch_pages_volume_buttons">Paganahin ang mga volume button</string>
|
||||
<string name="switch_pages_volume_buttons_summary">Gumamit ng mga volume button para sa paglipat ng mga pahina</string>
|
||||
<string name="suggestions_unavailable_text">Naka-disable ang feature na Mga suhestiyon</string>
|
||||
<string name="check_for_new_chapters_disabled">Naka-disable ang pagsuri para sa mga bagong kabanata</string>
|
||||
<string name="reading_time_estimation">Ipakita ang tinantyang oras ng pagbabasa</string>
|
||||
<string name="reading_time_estimation_summary">Maaaring hindi tumpak ang halaga ng pagtatantya ng oras</string>
|
||||
</resources>
|
||||
@@ -35,4 +35,14 @@
|
||||
<item quantity="many">Il y a %1$d mois</item>
|
||||
<item quantity="other">Il y a %1$d mois</item>
|
||||
</plurals>
|
||||
<plurals name="hours">
|
||||
<item quantity="one">%1$d heure</item>
|
||||
<item quantity="many">%1$d heures</item>
|
||||
<item quantity="other">%1$d heures</item>
|
||||
</plurals>
|
||||
<plurals name="minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="many">%1$d minutes</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -66,7 +66,7 @@
|
||||
<string name="size_s">Taille : %s</string>
|
||||
<string name="new_version_s">Nouvelle version : %s</string>
|
||||
<string name="search_results">Résultats de la recherche</string>
|
||||
<string name="text_feed_holder">Les nouveaux chapitres de ce que vous lisez sont présentés ici</string>
|
||||
<string name="text_feed_holder">Les nouveaux chapitres de ce que vous lisez sont affichés ici</string>
|
||||
<string name="updates">Mises à jour</string>
|
||||
<string name="read_later">Lire plus tard</string>
|
||||
<string name="favourites_category_empty">Catégorie vide</string>
|
||||
@@ -79,7 +79,7 @@
|
||||
<string name="pages_animation">Animation de page</string>
|
||||
<string name="recent_manga">Récents</string>
|
||||
<string name="manga_shelf">Étagère</string>
|
||||
<string name="text_local_holder_secondary">Enregistrez-le à partir de sources en ligne ou importez des fichiers.</string>
|
||||
<string name="text_local_holder_secondary">Enregistrez quelque chose à partir d\'un catalogue en ligne ou importez-le à partir d\'un fichier.</string>
|
||||
<string name="text_local_holder_primary">Sauvegardez d\'abord quelque chose</string>
|
||||
<string name="text_history_holder_secondary">Trouver quoi lire dans la section « Explorer »</string>
|
||||
<string name="text_history_holder_primary">Ce que vous lisez sera affiché ici</string>
|
||||
@@ -112,7 +112,7 @@
|
||||
<string name="taps_on_edges">Appuis au bord</string>
|
||||
<string name="switch_pages">Changer de pages</string>
|
||||
<string name="reader_settings">Paramètres du lecteur</string>
|
||||
<string name="text_delete_local_manga">Supprimer « %s » de l\'appareil de façon permanente \?</string>
|
||||
<string name="text_delete_local_manga">Supprimer « %s » de l\'appareil de façon permanente ?</string>
|
||||
<string name="delete_manga">Supprimer le manga</string>
|
||||
<string name="search_on_s">Rechercher sur %s</string>
|
||||
<string name="grid_size">Taille de la grille</string>
|
||||
@@ -328,7 +328,7 @@
|
||||
<string name="text_unsaved_changes_prompt">Sauvegarde ou abandon des modifications non sauvegardées \?</string>
|
||||
<string name="discard">Abandonner</string>
|
||||
<string name="history_shortcuts_summary">Rendre les mangas récents disponibles en appuyant longuement sur l\'icône de l\'application</string>
|
||||
<string name="reader_control_ltr_summary">Taper sur le bord droit ou appuyer sur la touche droite permet toujours de passer à la page suivante</string>
|
||||
<string name="reader_control_ltr_summary">Taper sur le bord droit ou appuyer sur la touche droite permet toujours de passer à la page suivante.</string>
|
||||
<string name="reader_control_ltr">Contrôle ergonomique du lecteur</string>
|
||||
<string name="history_shortcuts">Afficher les raccourcis des mangas récents</string>
|
||||
<string name="color_correction">Correction des couleurs</string>
|
||||
@@ -424,7 +424,7 @@
|
||||
<string name="authorization_optional">Autorisation (optionnel)</string>
|
||||
<string name="invalid_port_number">Numéro de port invalide</string>
|
||||
<string name="restore_summary">Restaurer la sauvegarde précédemment créée</string>
|
||||
<string name="webtoon_zoom_summary">Autoriser le geste de zoom avant en mode webtoon</string>
|
||||
<string name="webtoon_zoom_summary">Autoriser le geste de zoom en mode webtoon</string>
|
||||
<string name="reader_info_bar_summary">Afficher l\'heure actuelle et la progression de la lecture en haut de l\'écran</string>
|
||||
<string name="pages_animation_summary">Animation de tournage de page</string>
|
||||
<string name="details_button_tip">Appuyez et maintenez le bouton Lire pour voir plus d\'options</string>
|
||||
@@ -528,8 +528,8 @@
|
||||
<string name="backups_output_directory">Sauvegardes répertoire de sortie</string>
|
||||
<string name="suggest_new_sources_summary">Prompt pour permettre des sources nouvellement ajoutées après la mise à jour de l\'application</string>
|
||||
<string name="content_type_other">Autre</string>
|
||||
<string name="state_upcoming">A venir</string>
|
||||
<string name="welcome_text">S\'il vous plaît choisissez les sources que vous souhaitez activer. Cela peux aussi être fait plus tard dans les paramètres</string>
|
||||
<string name="state_upcoming">À venir</string>
|
||||
<string name="welcome_text">Veuillez choisir les sources que vous souhaitez activer. Cela peut aussi être configuré plus tard dans les paramètres</string>
|
||||
<string name="sync_auth">Connectez-vous pour synchroniser le compte</string>
|
||||
<string name="skip">Passer</string>
|
||||
<string name="restore">Restaurer</string>
|
||||
@@ -543,11 +543,54 @@
|
||||
<string name="this_manga">Ce manga</string>
|
||||
<string name="apply">Appliqué</string>
|
||||
<string name="genres_search_hint">Commence a écrit un nom de genre</string>
|
||||
<string name="downloads_settings_info">Vous pouvez activer la vitesse de téléchargement réduite individuellement pour chaque source de manga dans les paramètres si vous rencontrez des problèmes de bloquage avec le serveur.</string>
|
||||
<string name="backup_date_">Date de sauvegarde: %s</string>
|
||||
<string name="by_name_reverse">Nom réservé</string>
|
||||
<string name="mark_as_completed">Marque comme terminé</string>
|
||||
<string name="mark_as_completed_prompt">Marqué le manga sélectionné en terminé?
|
||||
<string name="downloads_settings_info">Vous pouvez réduire la vitesse de téléchargement individuellement pour chaque source de manga dans les paramètres si vous rencontrez des problèmes de blocage avec le serveur</string>
|
||||
<string name="backup_date_">Date de sauvegarde : %s</string>
|
||||
<string name="by_name_reverse">Nom inversé</string>
|
||||
<string name="mark_as_completed">Marquer comme terminé</string>
|
||||
<string name="mark_as_completed_prompt">Marquer le manga sélectionné comme terminé ?
|
||||
\n
|
||||
\nAttention: la progression actuelle sera perdu.</string>
|
||||
\nAttention : la progression actuelle sera perdue.</string>
|
||||
<string name="approximate_reading_time">Temps de lecture approximatif</string>
|
||||
<string name="incognito_mode_hint">Votre progression de lecture ne sera pas sauvegardée</string>
|
||||
<string name="last_read">Dernier lu</string>
|
||||
<string name="vertical">Vertical</string>
|
||||
<string name="email_password_enter_hint">Entrez votre email et mot de passe pour continuer</string>
|
||||
<string name="grayscale">Niveaux de gris</string>
|
||||
<string name="error_filter_locale_genre_not_supported">Le filtrage à la fois par genres et par langues n\'est pas supporté par cette source</string>
|
||||
<string name="error_filter_states_genre_not_supported">Le filtrage à la fois par genres et par statut n\'est pas supporté par cette source</string>
|
||||
<string name="approximate_remaining_time">Temps restant approximatif</string>
|
||||
<string name="volume_">Volume %d</string>
|
||||
<string name="volume_unknown">Volume inconnu</string>
|
||||
<string name="show_menu">Afficher le menu</string>
|
||||
<string name="toggle_ui">Afficher/cacher UI</string>
|
||||
<string name="prev_chapter">Chapitre précèdent</string>
|
||||
<string name="next_chapter">Chapitre suivant</string>
|
||||
<string name="prev_page">Page précédente</string>
|
||||
<string name="next_page">Page suivante</string>
|
||||
<string name="switch_pages_volume_buttons">Activer les boutons de volume</string>
|
||||
<string name="switch_pages_volume_buttons_summary">Utiliser les boutons de volume pour changer de page</string>
|
||||
<string name="none">Aucun</string>
|
||||
<string name="config_reset_confirm">Revenir aux paramètres par défaut ? Cette action ne pourra pas être annulée.</string>
|
||||
<string name="use_two_pages_landscape">Utiliser la disposition pages doubles en orientation paysage (bêta)</string>
|
||||
<string name="fullscreen_mode">Mode plein écran</string>
|
||||
<string name="category_hidden_done">Cette catégorie a été cachée du menu principal et est accessible via Menu → Gérer les catégories</string>
|
||||
<string name="two_pages">Pages doubles</string>
|
||||
<string name="reading_time_estimation">Afficher le temps de lecture estimé</string>
|
||||
<string name="reading_time_estimation_summary">Le temps estimé peut être inexact</string>
|
||||
<string name="ask_for_dest_dir_every_time">Demander pour le répertoire de destination à chaque fois</string>
|
||||
<string name="default_page_save_dir">Répertoire par défaut pour les pages sauvegardées</string>
|
||||
<string name="remove_from_history">Retirer de l\'historique</string>
|
||||
<string name="reader_actions">Actions du lecteur</string>
|
||||
<string name="reader_fullscreen_summary">Cache la barre d\'état et les barres de navigations</string>
|
||||
<string name="suggestions_unavailable_text">La fonctionnalité de suggestions est désactivée</string>
|
||||
<string name="check_for_new_chapters_disabled">La vérification des nouveaux chapitres est désactivée</string>
|
||||
<string name="rating_suggestive">Suggestif</string>
|
||||
<string name="disable_battery_optimization_summary_downloads">Peut aider à démarrer le téléchargement si vous avez des problèmes avec</string>
|
||||
<string name="remaining_time_pattern">%1$s %2$s</string>
|
||||
<string name="reader_actions_summary">Configurer les actions pour les zones d’écran tactiles</string>
|
||||
<string name="tap_action">Action de tapoter</string>
|
||||
<string name="long_tap_action">Action d\'appuyez longuement</string>
|
||||
<string name="show_labels_in_navbar">Afficher les étiquettes dans la barre de navigation</string>
|
||||
<string name="pages_saving">Sauvegarder les pages</string>
|
||||
<string name="default_webtoon_zoom_out">Zoom webtoon par défaut</string>
|
||||
</resources>
|
||||
@@ -93,7 +93,7 @@
|
||||
<string name="new_version_s">नया संस्करण: %s</string>
|
||||
<string name="text_delete_local_manga">डिवाइस से \"%s\" को स्थायी रूप से हटाएं?</string>
|
||||
<string name="text_history_holder_primary">जो भी आप पढ़ोगे वे सब यहां दिखेगा</string>
|
||||
<string name="delete_manga">मांगा को नष्ट करे</string>
|
||||
<string name="delete_manga">मंगा हटाएं</string>
|
||||
<string name="notification_sound">सूचना की ध्वनि</string>
|
||||
<string name="search_history_cleared">साफ हो गया</string>
|
||||
<string name="open_in_browser">ब्राउसर में खोले</string>
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
<string name="new_version_s">Versi baru: %s</string>
|
||||
<string name="size_s">Ukuran: %s</string>
|
||||
<string name="updates_feed_cleared">Dibersihkan</string>
|
||||
<string name="update">Pembaruan</string>
|
||||
<string name="update">Perbarui</string>
|
||||
<string name="track_sources">Mencari pembaruan</string>
|
||||
<string name="dont_check">Jangan periksa</string>
|
||||
<string name="wrong_password">Kata sandi salah</string>
|
||||
|
||||
@@ -21,4 +21,10 @@
|
||||
<plurals name="items">
|
||||
<item quantity="other">%1$d item</item>
|
||||
</plurals>
|
||||
<plurals name="hours">
|
||||
<item quantity="other">%1$d jam</item>
|
||||
</plurals>
|
||||
<plurals name="minutes">
|
||||
<item quantity="other">%1$d minit</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -308,4 +308,10 @@
|
||||
<string name="update">Kemas kini</string>
|
||||
<string name="feed_will_update_soon">Kemaskini siaran akan bermula sebentar</string>
|
||||
<string name="dont_check">Jangan semak</string>
|
||||
<string name="advanced">lanjutan</string>
|
||||
<string name="default_section">Bahagian lalai</string>
|
||||
<string name="manga_list">Senarai manga</string>
|
||||
<string name="error_corrupted_file">Data tidak sah dikembalikan atau fail rosak</string>
|
||||
<string name="on_device">Pada peranti</string>
|
||||
<string name="directories">Panduan</string>
|
||||
</resources>
|
||||
@@ -18,7 +18,7 @@
|
||||
<plurals name="new_chapters">
|
||||
<item quantity="one">%1$d novo capítulo</item>
|
||||
<item quantity="many">%1$d novos capítulos</item>
|
||||
<item quantity="other">%1$d capítulos novos</item>
|
||||
<item quantity="other">%1$d novos capítulos</item>
|
||||
</plurals>
|
||||
<plurals name="months_ago">
|
||||
<item quantity="one">%1$d mês atrás</item>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<string name="share_image">Compartilhar imagem</string>
|
||||
<string name="_import">Importar</string>
|
||||
<string name="updated">Atualizado</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="delete">Excluir</string>
|
||||
<string name="operation_not_supported">Essa operação não é suportada</string>
|
||||
<string name="clear_pages_cache">Limpar cache de página</string>
|
||||
<string name="text_file_sizes">B|kB|MB|GB|TB</string>
|
||||
@@ -164,7 +164,7 @@
|
||||
<string name="vibration">Vibração</string>
|
||||
<string name="cannot_find_available_storage">Sem armazenamento disponível</string>
|
||||
<string name="favourites_categories">Categorias favoritas</string>
|
||||
<string name="text_history_holder_secondary">Encontre o que ler na aba «Explorar»</string>
|
||||
<string name="text_history_holder_secondary">Encontre o que ler na seção «Explorar»</string>
|
||||
<string name="text_local_holder_secondary">Salve-o de catálogos online ou importe de um arquivo.</string>
|
||||
<string name="recent_manga">Recente</string>
|
||||
<string name="other_storage">Outro armazenamento</string>
|
||||
@@ -584,4 +584,8 @@
|
||||
<string name="default_webtoon_zoom_out">Diminuir para zoom padrão do webtoon</string>
|
||||
<string name="fullscreen_mode">Modo de tela cheia</string>
|
||||
<string name="reader_fullscreen_summary">Ocultar a barra de status e navegação</string>
|
||||
<string name="suggestions_unavailable_text">O recurso de sugestões está desativado</string>
|
||||
<string name="check_for_new_chapters_disabled">A verificação de novos capítulos está desativada</string>
|
||||
<string name="reading_time_estimation">Mostrar tempo estimado de leitura</string>
|
||||
<string name="reading_time_estimation_summary">O valor do tempo estimado pode ser impreciso</string>
|
||||
</resources>
|
||||
@@ -327,7 +327,7 @@
|
||||
<string name="manga_error_description_pattern">Сведения об ошибке:<br><tt>%1$s</tt><br><br>1. Попробуйте <a href=%2$s>открыть мангу в веб-браузере</a>, чтобы убедиться, что она доступна в источнике<br>2. Убедитесь, что вы используете <a href=kotatsu://about>последнюю версию Kotatsu</a><br>3. Если возможно, отправьте отчёт об ошибке разработчикам.</string>
|
||||
<string name="history_shortcuts">Показывать ярлыки последней прочитанной манги</string>
|
||||
<string name="history_shortcuts_summary">Сделать недавно прочитанную мангу доступной по долгому нажатию на иконку приложения</string>
|
||||
<string name="reader_control_ltr_summary">Нажатие на правый край или нажатие правой клавиши всегда переключает на следующую страницу</string>
|
||||
<string name="reader_control_ltr_summary">Нажатие на правый край или нажатие правой клавиши всегда переключает на следующую страницу.</string>
|
||||
<string name="reader_control_ltr">Эргономичное управление режимом чтения</string>
|
||||
<string name="reset">Сбросить</string>
|
||||
<string name="discard">Отклонить</string>
|
||||
@@ -586,4 +586,11 @@
|
||||
<string name="reader_fullscreen_summary">Скрывать интерфейс системы</string>
|
||||
<string name="reading_time_estimation">Отображать предполагаемое время чтения</string>
|
||||
<string name="reading_time_estimation_summary">Данное значение может быть неточным</string>
|
||||
<string name="check_for_new_chapters_disabled">Проверка новых глав отключена</string>
|
||||
<string name="suggestions_unavailable_text">Функция предложения отключена</string>
|
||||
<string name="pages_saving">Сохранение страниц</string>
|
||||
<string name="ask_for_dest_dir_every_time">Спрашивать папку для сохранения каждый раз</string>
|
||||
<string name="remove_from_history">Убрать из истории</string>
|
||||
<string name="show_labels_in_navbar">Показывать подписи на панели навигации</string>
|
||||
<string name="default_page_save_dir">Папка для сохранений по умолчанию</string>
|
||||
</resources>
|
||||
@@ -4,7 +4,7 @@
|
||||
<string name="error_occurred">Грешка се појавила</string>
|
||||
<string name="favourites">Омиљено</string>
|
||||
<string name="history">Историја</string>
|
||||
<string name="network_error">Мрежна грешка</string>
|
||||
<string name="network_error">Грешка на мрежи</string>
|
||||
<string name="details">Детаљи</string>
|
||||
<string name="chapters">Поглавља</string>
|
||||
<string name="list">Листа</string>
|
||||
@@ -569,7 +569,7 @@
|
||||
<string name="remaining_time_pattern">%1$s %2$s</string>
|
||||
<string name="show_menu">Прикажи изборник</string>
|
||||
<string name="prev_chapter">Претходна поглавља</string>
|
||||
<string name="tap_action">Радња додира</string>
|
||||
<string name="tap_action">Радња при додиру</string>
|
||||
<string name="config_reset_confirm">Вратити подешавања на подразумеване вредности? Ова радња се не може опозвати.</string>
|
||||
<string name="two_pages">Две стране</string>
|
||||
<string name="reader_actions_summary">Конфигуриши радње за области екрана које се могу додирнути</string>
|
||||
@@ -580,4 +580,12 @@
|
||||
<string name="reader_actions">Радње читаоца</string>
|
||||
<string name="volume_unknown">Непозната запремина</string>
|
||||
<string name="last_read">Последње прочитано</string>
|
||||
<string name="volume_">Количина %d</string>
|
||||
<string name="default_webtoon_zoom_out">Подразумевано умањивање вебтоон-а</string>
|
||||
<string name="reader_fullscreen_summary">Сакриј статус система и траке за навигацију</string>
|
||||
<string name="suggestions_unavailable_text">Предлози су искључени</string>
|
||||
<string name="reading_time_estimation">Прикажи процењено време читања</string>
|
||||
<string name="reading_time_estimation_summary">Вредност процене времена може бити нетачна</string>
|
||||
<string name="check_for_new_chapters_disabled">Провера нових поглавља је искључена</string>
|
||||
<string name="fullscreen_mode">Режим целог екрана</string>
|
||||
</resources>
|
||||
@@ -344,7 +344,7 @@
|
||||
<string name="server_error">Sunucu hatası (%1$d). Lütfen daha sonra tekrar deneyin</string>
|
||||
<string name="saved_manga">Kaydedilen mangalar</string>
|
||||
<string name="history_shortcuts_summary">Uygulama simgesine uzun basarak son mangaları kullanılabilir hale getirin</string>
|
||||
<string name="reader_control_ltr_summary">Sağ kenara dokunulduğunda veya sağ tuşa basıldığında her zaman bir sonraki sayfaya geçilir</string>
|
||||
<string name="reader_control_ltr_summary">Sağ kenara dokunulduğunda veya sağ tuşa basıldığında her zaman bir sonraki sayfaya geçilir.</string>
|
||||
<string name="source_disabled">Kaynak devre dışı</string>
|
||||
<string name="prefetch_content">İçerik ön yüklemesi</string>
|
||||
<string name="mark_as_current">Geçerli olarak işaretle</string>
|
||||
@@ -584,4 +584,13 @@
|
||||
<string name="default_webtoon_zoom_out">Öntanımlı webtoon uzaklaştırması</string>
|
||||
<string name="fullscreen_mode">Tam ekran modu</string>
|
||||
<string name="reader_fullscreen_summary">Sistem durumunu ve gezinme çubuklarını gizle</string>
|
||||
<string name="suggestions_unavailable_text">Öneriler özelliği devre dışı</string>
|
||||
<string name="check_for_new_chapters_disabled">Yeni bölümlerin denetlenmesi devre dışı</string>
|
||||
<string name="reading_time_estimation">Tahmini okuma süresini göster</string>
|
||||
<string name="reading_time_estimation_summary">Süre tahmin değeri yanlış olabilir</string>
|
||||
<string name="show_labels_in_navbar">Gezinme çubuğunda etiketleri göster</string>
|
||||
<string name="pages_saving">Sayfalar kaydediliyor</string>
|
||||
<string name="ask_for_dest_dir_every_time">Her seferinde hedef dizini sor</string>
|
||||
<string name="default_page_save_dir">Öntanımlı sayfa kaydetme dizini</string>
|
||||
<string name="remove_from_history">Geçmişten kaldır</string>
|
||||
</resources>
|
||||
@@ -327,7 +327,7 @@
|
||||
<string name="manga_error_description_pattern">Деталі помилки:<br><tt>%1$s</tt><br><br>1. Спробуйте <a href=%2$s>відкрити манґу у веб-браузері</a>, щоб переконатися, що вона доступна в джерелі<br>2. Переконайтеся, що ви використовуєте <a href=kotatsu://about>останню версію Kotatsu</a><br>3. Якщо він доступний, надішліть звіт про помилку розробникам.</string>
|
||||
<string name="history_shortcuts">Показувати ярлики останньої прочитаної манґи</string>
|
||||
<string name="history_shortcuts_summary">Зробити нещодавно прочитану манґу доступною за довгим натисканням на іконку застосунку</string>
|
||||
<string name="reader_control_ltr_summary">Натискання на правий край або натискання правої клавіші завжди переходить на наступну сторінку</string>
|
||||
<string name="reader_control_ltr_summary">Натискання на правий край або натискання правої клавіші завжди перемикається на наступну сторінку.</string>
|
||||
<string name="reader_control_ltr">Ергономічне керування режимом читання</string>
|
||||
<string name="brightness">Яскравість</string>
|
||||
<string name="color_correction">Корекція кольору</string>
|
||||
@@ -586,4 +586,11 @@
|
||||
<string name="default_webtoon_zoom_out">Віддалення у режимі манхви</string>
|
||||
<string name="reading_time_estimation">Відображати передбачуваний час читання</string>
|
||||
<string name="reading_time_estimation_summary">Це значення може бути неточним</string>
|
||||
<string name="check_for_new_chapters_disabled">Перевірка нових глав вимкнена</string>
|
||||
<string name="suggestions_unavailable_text">Функція пропозицій вимкнена</string>
|
||||
<string name="pages_saving">Збереження сторінок</string>
|
||||
<string name="ask_for_dest_dir_every_time">Щоразу запитувати директорію призначення</string>
|
||||
<string name="remove_from_history">Видалити з історії</string>
|
||||
<string name="show_labels_in_navbar">Показувати мітки на панелі навігації</string>
|
||||
<string name="default_page_save_dir">Директорія збереження сторінки за замовчуванням</string>
|
||||
</resources>
|
||||
@@ -4,18 +4,18 @@
|
||||
<string name="local_storage">本地</string>
|
||||
<string name="favourites">收藏</string>
|
||||
<string name="history">历史</string>
|
||||
<string name="error_occurred">发生错误</string>
|
||||
<string name="error_occurred">出错了</string>
|
||||
<string name="network_error">网络错误</string>
|
||||
<string name="chapters">章节</string>
|
||||
<string name="list">列表</string>
|
||||
<string name="data_restored_with_errors">数据已恢复,但发生了一些错误</string>
|
||||
<string name="data_restored_with_errors">数据已恢复,但出现了一些错误</string>
|
||||
<string name="processing_">正在处理…</string>
|
||||
<string name="newest">最新</string>
|
||||
<string name="by_rating">评分</string>
|
||||
<string name="cookies_cleared">已清除所有 Cookies</string>
|
||||
<string name="data_restored_success">数据已全部恢复</string>
|
||||
<string name="silent">无声</string>
|
||||
<string name="preparing_">准备…</string>
|
||||
<string name="preparing_">准备中…</string>
|
||||
<string name="file_not_found">未找到文件</string>
|
||||
<string name="yesterday">昨天</string>
|
||||
<string name="backup_information">可创建历史和收藏的备份并开始恢复</string>
|
||||
@@ -24,22 +24,22 @@
|
||||
<string name="group">分组</string>
|
||||
<string name="tap_to_try_again">点击重试</string>
|
||||
<string name="reader_mode_hint">所选模式只会在此漫画上使用</string>
|
||||
<string name="captcha_required">需要通过验证</string>
|
||||
<string name="captcha_required">需要通过人机身份验证</string>
|
||||
<string name="captcha_solve">开始验证</string>
|
||||
<string name="today">今天</string>
|
||||
<string name="clear_cookies">清除 Cookies</string>
|
||||
<string name="new_sources_text">有新的可用图源</string>
|
||||
<string name="suggestions_summary">根据你的喜好推荐漫画</string>
|
||||
<string name="suggestions_info">所有数据都在本地设备上进行分析,不会发送到其他地方。</string>
|
||||
<string name="suggestions_info">所有数据都在本地分析,不会发送到其他地方。</string>
|
||||
<string name="never">从不</string>
|
||||
<string name="show_notification_new_chapters_on">发送正在阅读漫画的更新通知</string>
|
||||
<string name="nsfw">18+</string>
|
||||
<string name="nsfw">R18</string>
|
||||
<string name="various_languages">多语言</string>
|
||||
<string name="search_chapters">查找章节</string>
|
||||
<string name="suggestions_excluded_genres">排除分类</string>
|
||||
<string name="suggestions_updating">正在更新漫画推荐</string>
|
||||
<string name="check_new_chapters_title">检查新章节并通知结果</string>
|
||||
<string name="details">作品详情</string>
|
||||
<string name="details">详情</string>
|
||||
<string name="detailed_list">卡片</string>
|
||||
<string name="grid">网格</string>
|
||||
<string name="list_mode">视图选项</string>
|
||||
@@ -49,13 +49,13 @@
|
||||
<string name="chapter_d_of_d">%1$d/%2$d 章</string>
|
||||
<string name="close">关闭</string>
|
||||
<string name="try_again">重试</string>
|
||||
<string name="clear_history">清除历史</string>
|
||||
<string name="clear_history">清除历史记录</string>
|
||||
<string name="nothing_found">结果为空</string>
|
||||
<string name="history_is_empty">暂无历史记录</string>
|
||||
<string name="read">阅读</string>
|
||||
<string name="you_have_not_favourites_yet">暂无漫画收藏</string>
|
||||
<string name="add_to_favourites">收藏此漫画</string>
|
||||
<string name="add_new_category">新分类</string>
|
||||
<string name="add_new_category">添加新分类</string>
|
||||
<string name="add">添加</string>
|
||||
<string name="save">保存</string>
|
||||
<string name="share">分享</string>
|
||||
@@ -77,10 +77,10 @@
|
||||
<string name="automatic">跟随系统</string>
|
||||
<string name="pages">页面</string>
|
||||
<string name="clear">清除</string>
|
||||
<string name="text_clear_history_prompt">要永久清除所有阅读历史吗?</string>
|
||||
<string name="text_clear_history_prompt">确定永久清除所有阅读历史吗?</string>
|
||||
<string name="remove">删除</string>
|
||||
<string name="_s_deleted_from_local_storage">已从本地存储中删除“%s”</string>
|
||||
<string name="save_page">保存本页</string>
|
||||
<string name="save_page">保存图片</string>
|
||||
<string name="page_saved">保存成功</string>
|
||||
<string name="share_image">分享图片</string>
|
||||
<string name="_import">导入</string>
|
||||
@@ -96,7 +96,7 @@
|
||||
<string name="grid_size">网格大小</string>
|
||||
<string name="search_on_s">在%s上搜索</string>
|
||||
<string name="delete_manga">删除漫画</string>
|
||||
<string name="text_delete_local_manga">要从设备中永久删除\"%s\"吗?</string>
|
||||
<string name="text_delete_local_manga">确定从设备中永久删除\"%s\"吗?</string>
|
||||
<string name="reader_settings">阅读</string>
|
||||
<string name="switch_pages">翻页方式</string>
|
||||
<string name="volume_buttons">音量键</string>
|
||||
@@ -104,7 +104,7 @@
|
||||
<string name="taps_on_edges">点击边缘</string>
|
||||
<string name="error">错误</string>
|
||||
<string name="clear_thumbs_cache">清除缩略图缓存</string>
|
||||
<string name="clear_search_history">清除搜索历史</string>
|
||||
<string name="clear_search_history">清除搜索记录</string>
|
||||
<string name="search_history_cleared">清除完毕</string>
|
||||
<string name="gestures_only">仅限滑动手势</string>
|
||||
<string name="internal_storage">内部存储</string>
|
||||
@@ -112,7 +112,7 @@
|
||||
<string name="domain">图源域名</string>
|
||||
<string name="app_update_available">发现新版本</string>
|
||||
<string name="open_in_browser">在浏览器中打开</string>
|
||||
<string name="large_manga_save_confirm">这部漫画有 %s 。要全部保存吗?</string>
|
||||
<string name="large_manga_save_confirm">这部漫画有 %s ,要全部保存吗?</string>
|
||||
<string name="save_manga">保存</string>
|
||||
<string name="notifications">通知</string>
|
||||
<string name="new_chapters">新章节</string>
|
||||
@@ -126,9 +126,9 @@
|
||||
<string name="text_empty_holder_primary">什么都没有…</string>
|
||||
<string name="text_search_holder_secondary">试试换一个词再搜索。</string>
|
||||
<string name="text_history_holder_primary">看过的漫画将在这里显示</string>
|
||||
<string name="text_history_holder_secondary">在<浏览>页面搜索要读的漫画</string>
|
||||
<string name="text_local_holder_primary">请先在线下载或进行本地导入</string>
|
||||
<string name="text_local_holder_secondary">下载图源内容或通过本地文件导入。</string>
|
||||
<string name="text_history_holder_secondary">在<浏览>页面搜索想读的漫画</string>
|
||||
<string name="text_local_holder_primary">存点什么吧</string>
|
||||
<string name="text_local_holder_secondary">可下载在线图源里的漫画或导入本地漫画文件。</string>
|
||||
<string name="manga_shelf">书架</string>
|
||||
<string name="recent_manga">最近</string>
|
||||
<string name="pages_animation">翻页动画</string>
|
||||
@@ -141,13 +141,13 @@
|
||||
<string name="favourites_category_empty">目前分类为空</string>
|
||||
<string name="read_later">稍后阅读</string>
|
||||
<string name="updates">更新内容</string>
|
||||
<string name="text_feed_holder">正在阅读漫画的新章节将在这里显示</string>
|
||||
<string name="text_feed_holder">在读漫画的新章节将在这里显示</string>
|
||||
<string name="search_results">搜索结果</string>
|
||||
<string name="new_version_s">新版本: %s</string>
|
||||
<string name="clear_updates_feed">清除订阅更新记录</string>
|
||||
<string name="updates_feed_cleared">订阅更新已清除</string>
|
||||
<string name="rotate_screen">旋转屏幕</string>
|
||||
<string name="update">更新订阅</string>
|
||||
<string name="update">开始更新</string>
|
||||
<string name="feed_will_update_soon">即将开始更新订阅</string>
|
||||
<string name="track_sources">章节更新范围</string>
|
||||
<string name="dont_check">不检查</string>
|
||||
@@ -160,9 +160,9 @@
|
||||
<string name="about">关于</string>
|
||||
<string name="app_version">版本 %s</string>
|
||||
<string name="check_for_updates">检查更新</string>
|
||||
<string name="no_update_available">无可用更新</string>
|
||||
<string name="no_update_available">已是最新版本</string>
|
||||
<string name="right_to_left">从右到左</string>
|
||||
<string name="create_category">新分类</string>
|
||||
<string name="create_category">添加新分类</string>
|
||||
<string name="scale_mode">显示模式</string>
|
||||
<string name="zoom_mode_fit_center">填充屏幕</string>
|
||||
<string name="zoom_mode_fit_height">适应高度</string>
|
||||
@@ -175,7 +175,7 @@
|
||||
<string name="restore_backup">恢复备份</string>
|
||||
<string name="data_restored">恢复完成</string>
|
||||
<string name="clear_feed">清除订阅</string>
|
||||
<string name="text_clear_updates_feed_prompt">要永久清除所有的更新历史吗?</string>
|
||||
<string name="text_clear_updates_feed_prompt">确定要永久清除所有的更新历史吗?</string>
|
||||
<string name="check_for_new_chapters">章节更新</string>
|
||||
<string name="reverse">倒序</string>
|
||||
<string name="sign_in">登录</string>
|
||||
@@ -185,10 +185,10 @@
|
||||
<string name="protect_application_subtitle">输入密码以解锁</string>
|
||||
<string name="confirm">确认</string>
|
||||
<string name="password_length_hint">密码必须大于或等于4个字符</string>
|
||||
<string name="text_clear_search_history_prompt">要永久删除所有搜索记录吗?</string>
|
||||
<string name="text_clear_search_history_prompt">确定要永久清除所有搜索记录吗?</string>
|
||||
<string name="welcome">欢迎</string>
|
||||
<string name="backup_saved">备份已保存</string>
|
||||
<string name="tracker_warning">不同设备导致不同的系统调度可能会杀掉后台任务。</string>
|
||||
<string name="tracker_warning">不同设备及不同的系统调度可能会杀掉本应用的后台任务。</string>
|
||||
<string name="read_more">了解详情</string>
|
||||
<string name="queued">等待</string>
|
||||
<string name="chapter_is_missing">该章缺失</string>
|
||||
@@ -205,19 +205,19 @@
|
||||
<string name="show_pages_numbers">页码</string>
|
||||
<string name="enabled_sources">已用图源</string>
|
||||
<string name="available_sources">可用图源</string>
|
||||
<string name="screenshots_policy">截图限制</string>
|
||||
<string name="screenshots_policy">阅读时截图限制</string>
|
||||
<string name="screenshots_allow">无限制</string>
|
||||
<string name="screenshots_block_nsfw">仅阅读成人内容时禁止</string>
|
||||
<string name="screenshots_block_all">总是禁止截图</string>
|
||||
<string name="suggestions">漫画推荐</string>
|
||||
<string name="suggestions_enable">开启漫画推荐</string>
|
||||
<string name="text_suggestion_holder">开始阅读漫画,即可获取个性化推荐</string>
|
||||
<string name="exclude_nsfw_from_suggestions">禁止推荐成人内容漫画</string>
|
||||
<string name="exclude_nsfw_from_suggestions">禁止推荐成人漫画</string>
|
||||
<string name="enabled">启用</string>
|
||||
<string name="disabled">禁用</string>
|
||||
<string name="disabled">关闭</string>
|
||||
<string name="filter_load_error">无法加载分类列表</string>
|
||||
<string name="reset_filter">重置筛选</string>
|
||||
<string name="onboard_text">选择想要阅读漫画的语言。可之后在设置中更改。</string>
|
||||
<string name="onboard_text">选择想要阅读漫画的语言,可之后在设置中更改。</string>
|
||||
<string name="only_using_wifi">仅连接 Wi-Fi 时</string>
|
||||
<string name="always">总是</string>
|
||||
<string name="preload_pages">页面预加载</string>
|
||||
@@ -225,9 +225,9 @@
|
||||
<string name="chapters_empty">此漫画没有章节</string>
|
||||
<string name="appearance">外观</string>
|
||||
<string name="suggestions_excluded_genres_summary">输入不希望在推荐中看到的分类</string>
|
||||
<string name="text_delete_local_manga_batch">要从系统中永久删除所选项目吗?</string>
|
||||
<string name="text_delete_local_manga_batch">确定从系统中永久删除所选项目吗?</string>
|
||||
<string name="removal_completed">删除成功</string>
|
||||
<string name="download_slowdown">减慢下载速度</string>
|
||||
<string name="download_slowdown">限速下载</string>
|
||||
<string name="download_slowdown_summary">有助于避免封禁你的IP地址</string>
|
||||
<string name="local_manga_processing">正在处理已保存漫画</string>
|
||||
<string name="chapters_will_removed_background">章节将在后台被删除</string>
|
||||
@@ -244,16 +244,16 @@
|
||||
<string name="bookmark_removed">书签已删除</string>
|
||||
<string name="bookmark_added">书签已添加</string>
|
||||
<string name="undo">撤销</string>
|
||||
<string name="removed_from_history">已从历史记录中删除</string>
|
||||
<string name="removed_from_history">历史记录已删除</string>
|
||||
<string name="dns_over_https">基于 HTTPS 的 DNS</string>
|
||||
<string name="default_mode">默认阅读模式</string>
|
||||
<string name="detect_reader_mode">自动检测阅读模式</string>
|
||||
<string name="detect_reader_mode_summary">自动检测是否应用条漫模式</string>
|
||||
<string name="disable_battery_optimization">禁用电池优化</string>
|
||||
<string name="disable_battery_optimization">关闭电池优化</string>
|
||||
<string name="disable_battery_optimization_summary">有助于进行后台更新检查</string>
|
||||
<string name="crash_text">出错了。请向开发人员提交错误报告以帮助修复问题。</string>
|
||||
<string name="crash_text">出错了,请向开发人员提交错误报告以帮助修复问题。</string>
|
||||
<string name="send">发送</string>
|
||||
<string name="disable_all">全部禁用</string>
|
||||
<string name="disable_all">全部关闭</string>
|
||||
<string name="status_planned">想读</string>
|
||||
<string name="status_on_hold">休刊中</string>
|
||||
<string name="report">报告</string>
|
||||
@@ -268,13 +268,13 @@
|
||||
<string name="show_reading_indicators_summary">在历史和收藏中显示阅读百分比</string>
|
||||
<string name="show_reading_indicators">显示阅读进度</string>
|
||||
<string name="data_deletion">数据删除</string>
|
||||
<string name="exclude_nsfw_from_history_summary">标记为成人内容的漫画将不会添加到历史记录,也不会保存阅读记录</string>
|
||||
<string name="clear_cookies_summary">能对部分问题起到一些作用。所有网站的授权将会失效</string>
|
||||
<string name="exclude_nsfw_from_history_summary">标记为含有成人内容的漫画将不会添加到历史记录,也不会保存阅读记录</string>
|
||||
<string name="clear_cookies_summary">可帮助稍微解决部分问题,所有网站的授权将会失效</string>
|
||||
<string name="show_all">显示全部</string>
|
||||
<string name="manga_error_description_pattern">错误详情:<br><tt>%1$s</tt><br><br>1.尝试<a href=%2$s>在网络浏览器中打开漫画</a>以确保在其图源中可用<br>2.请确保使用的是<a href=kotatsu://about>最新版本的Kotatsu</a><br>3.若图源没有问题,请向开发人员发送错误报告。</string>
|
||||
<string name="invalid_domain_message">无效域名</string>
|
||||
<string name="text_shelf_holder_primary">此处将显示你的漫画</string>
|
||||
<string name="text_shelf_holder_secondary">在<浏览>页面搜索要读的漫画</string>
|
||||
<string name="text_shelf_holder_secondary">在<浏览>页面搜索想读的漫画</string>
|
||||
<string name="percent_string_pattern">%1$s%%</string>
|
||||
<string name="canceled">已取消</string>
|
||||
<string name="account_already_exists">账号已存在</string>
|
||||
@@ -284,17 +284,17 @@
|
||||
<string name="email_enter_hint">输入邮箱地址以继续</string>
|
||||
<string name="status_dropped">已腰斩</string>
|
||||
<string name="select_range">选择范围</string>
|
||||
<string name="clear_all_history">清除所有历史</string>
|
||||
<string name="clear_all_history">清除所有历史记录</string>
|
||||
<string name="last_2_hours">过去2小时</string>
|
||||
<string name="bookmarks_removed">书签已删除</string>
|
||||
<string name="history_cleared">历史记录已清除</string>
|
||||
<string name="manage">管理</string>
|
||||
<string name="no_bookmarks_yet">暂无书签</string>
|
||||
<string name="no_bookmarks_summary">可在阅读漫画时创建书签</string>
|
||||
<string name="no_manga_sources">没有图源</string>
|
||||
<string name="no_manga_sources_text">启用图源即可在线阅读漫画</string>
|
||||
<string name="no_manga_sources">暂无图源</string>
|
||||
<string name="no_manga_sources_text">开启一个图源即可在线阅读漫画</string>
|
||||
<string name="random">随机</string>
|
||||
<string name="categories_delete_confirm">确定要删除选定的分类吗?
|
||||
<string name="categories_delete_confirm">确定要删除选中的分类吗?
|
||||
\n该分类中的所有漫画将丢失且无法恢复。</string>
|
||||
<string name="reorder">重新排序</string>
|
||||
<string name="empty">分类为空</string>
|
||||
@@ -315,7 +315,7 @@
|
||||
<string name="other_cache">其他缓存</string>
|
||||
<string name="storage_usage">存储占用</string>
|
||||
<string name="available">可用</string>
|
||||
<string name="removed_from_favourites">已从收藏中删除</string>
|
||||
<string name="removed_from_favourites">收藏漫画已删除</string>
|
||||
<string name="options">选项</string>
|
||||
<string name="incognito_mode">无痕模式</string>
|
||||
<string name="no_chapters">没有章节</string>
|
||||
@@ -325,8 +325,8 @@
|
||||
<string name="feed">订阅</string>
|
||||
<string name="memory_usage_pattern">%s - %s</string>
|
||||
<string name="not_found_404">没有章节或已被删除</string>
|
||||
<string name="reader_control_ltr_summary">点击屏幕右侧或按下右键始终翻到下一页</string>
|
||||
<string name="reader_control_ltr">简易控制</string>
|
||||
<string name="reader_control_ltr_summary">点击屏幕右侧边缘或按下右键都会翻到下一页</string>
|
||||
<string name="reader_control_ltr">阅读简易操作</string>
|
||||
<string name="history_shortcuts_summary">长按应用图标显示最近阅读的漫画</string>
|
||||
<string name="history_shortcuts">显示最近阅读漫画的快捷方式</string>
|
||||
<string name="reset">重置</string>
|
||||
@@ -343,9 +343,9 @@
|
||||
<string name="network_unavailable">网络未连接</string>
|
||||
<string name="network_unavailable_hint">打开 Wi-Fi 或移动网络开始在线阅读漫画</string>
|
||||
<string name="clear_new_chapters_counters">同时清除新章节信息</string>
|
||||
<string name="server_error">服务器错误 (%1$d)。请稍后再试</string>
|
||||
<string name="compact">紧凑</string>
|
||||
<string name="source_disabled">图源已禁用</string>
|
||||
<string name="server_error">服务器错误 (%1$d)。请稍后重试</string>
|
||||
<string name="compact">列表</string>
|
||||
<string name="source_disabled">图源已关闭</string>
|
||||
<string name="prefetch_content">内容预加载</string>
|
||||
<string name="mark_as_current">标为当前</string>
|
||||
<string name="language">语言</string>
|
||||
@@ -365,28 +365,28 @@
|
||||
<string name="theme_name_mamimi">Mamimi</string>
|
||||
<string name="theme_name_kanade">Kanade</string>
|
||||
<string name="nothing_here">这里什么也没有</string>
|
||||
<string name="scrobbling_empty_hint">要记录阅读进度,在漫画详情中选中【菜单】→【进度记录】。</string>
|
||||
<string name="scrobbling_empty_hint">要记录阅读进度,在漫画详情页里选中【菜单】→【进度记录】。</string>
|
||||
<string name="allow_unstable_updates">允许更新不稳定版本</string>
|
||||
<string name="allow_unstable_updates_summary">接收不稳定版本的更新通知</string>
|
||||
<string name="download_started">已开始下载</string>
|
||||
<string name="download_started">下载已开始</string>
|
||||
<string name="user_agent">UserAgent 标识</string>
|
||||
<string name="settings_apply_restart_required">要应用这些更改请重启程序</string>
|
||||
<string name="settings_apply_restart_required">重启程序后更改</string>
|
||||
<string name="sources_reorder_tip">点击并长按项目排序</string>
|
||||
<string name="got_it">知道了</string>
|
||||
<string name="speed">速度</string>
|
||||
<string name="restore_backup_description">导入先前创建的用户数据备份</string>
|
||||
<string name="show_on_shelf">在书架上显示</string>
|
||||
<string name="comics_archive_import_description">可选择一个或多个 .cbz 或 .zip 文件,每个文件都将识别为一个单独的漫画。</string>
|
||||
<string name="folder_with_images_import_description">可选择一个包含压缩包或图片的文件夹。每个压缩包(或子文件夹)都会被识别为一个章节。</string>
|
||||
<string name="find_similar">寻找类似漫画</string>
|
||||
<string name="comics_archive_import_description">可选择一个或多个 cbz 或 zip 文件,每个文件都将识别为一个单独的漫画。</string>
|
||||
<string name="folder_with_images_import_description">可选择一个包含压缩包或图片的文件夹,每个压缩包 (或子文件夹) 都会被识别为一个章节。</string>
|
||||
<string name="find_similar">搜索相似漫画</string>
|
||||
<string name="translations">翻译</string>
|
||||
<string name="web_view_unavailable">WebView不可用:检查是否已安装WebView</string>
|
||||
<string name="sync_host_description">可使用自建同步服务器或默认同步服务器。若不知道有何用处请不要自行修改。</string>
|
||||
<string name="sync_host_description">可使用自建同步服务器或默认同步服务器,若不知道有何用处请不要自行修改。</string>
|
||||
<string name="mirror_switching">自动选择镜像网址</string>
|
||||
<string name="mirror_switching_summary">若存在可用的镜像网址,在出错时开始自动切换</string>
|
||||
<string name="paused">已暂停</string>
|
||||
<string name="downloads_wifi_only_summary">切换到移动网络时停止下载</string>
|
||||
<string name="remove_completed">删除已完成任务</string>
|
||||
<string name="remove_completed">清除已完成任务</string>
|
||||
<string name="cancel_all">取消所有下载中的任务</string>
|
||||
<string name="downloads_wifi_only">仅在连接 Wi-Fi 时下载</string>
|
||||
<string name="enable">启用</string>
|
||||
@@ -399,14 +399,14 @@
|
||||
<string name="text_downloads_list_holder">暂无下载任务</string>
|
||||
<string name="downloads_resumed">下载已继续</string>
|
||||
<string name="downloads_paused">下载已暂停</string>
|
||||
<string name="downloads_removed">下载记录已删除</string>
|
||||
<string name="downloads_removed">下载记录已清除</string>
|
||||
<string name="downloads_cancelled">下载已取消</string>
|
||||
<string name="suggestions_enable_prompt">想要接收个性化的漫画推荐吗?</string>
|
||||
<string name="suggestion_manga">推荐:%s</string>
|
||||
<string name="suggestions_notifications_summary">偶尔显示漫画推荐通知</string>
|
||||
<string name="more">更多</string>
|
||||
<string name="cancel_all_downloads_confirm">将取消所有进行中的下载,部分下载完成的数据将会删除</string>
|
||||
<string name="remove_completed_downloads_confirm">下载历史将会永久删除</string>
|
||||
<string name="cancel_all_downloads_confirm">将取消所有进行中的下载,部分已下载完成的数据将会丢失</string>
|
||||
<string name="remove_completed_downloads_confirm">所有已完成的下载记录将会永久清除</string>
|
||||
<string name="sync_auth_hint">可登陆已有账号或创建新账号</string>
|
||||
<string name="address">地址</string>
|
||||
<string name="clear_network_cache">清除网络缓存</string>
|
||||
@@ -417,7 +417,7 @@
|
||||
<string name="restore_summary">从以前创建的备份恢复</string>
|
||||
<string name="show_pages_numbers_summary">在右下角显示页码</string>
|
||||
<string name="details_button_tip">长按阅读按钮可显示更多选项</string>
|
||||
<string name="clear_source_cookies_summary">仅清除特定域名的 Cookies。大多数情况下会使网站授权失效</string>
|
||||
<string name="clear_source_cookies_summary">仅清除特定域名的 Cookies,大多数情况下会使网站授权失效</string>
|
||||
<string name="data_and_privacy">数据与隐私</string>
|
||||
<string name="reader_info_bar_summary">在屏幕顶部显示当前时间和阅读进度</string>
|
||||
<string name="webtoon_zoom_summary">允许在条漫模式下使用缩放手势</string>
|
||||
@@ -436,21 +436,21 @@
|
||||
<string name="username">用户名</string>
|
||||
<string name="download_option_all_unread_b">所有未读章节 (%s)</string>
|
||||
<string name="authorization_optional">授权 (可选)</string>
|
||||
<string name="download_option_first_n_chapters">前 %s 章</string>
|
||||
<string name="download_option_first_n_chapters">前%s</string>
|
||||
<string name="downloaded">下载进度</string>
|
||||
<string name="custom_directory">自定义目录</string>
|
||||
<string name="pages_animation_summary">翻页动画</string>
|
||||
<string name="download_option_next_unread_n_chapters">后 %s 章</string>
|
||||
<string name="download_option_next_unread_n_chapters">后续未读的 %s</string>
|
||||
<string name="images_procy_description">尽可能使用 wsrv.nl 代理服务减少流量使用并加快图片加载</string>
|
||||
<string name="invert_colors">反色</string>
|
||||
<string name="related_manga">相关漫画</string>
|
||||
<string name="voice_search">语音搜索</string>
|
||||
<string name="this_month">本月</string>
|
||||
<string name="languages">语言</string>
|
||||
<string name="captcha_required_summary">%s 需要通过验证才能正常运行</string>
|
||||
<string name="captcha_required_summary">%s 需要通过人机身份验证才能正常运行</string>
|
||||
<string name="progress">阅读进度</string>
|
||||
<string name="error_corrupted_file">回传的数据无效或文件已损坏</string>
|
||||
<string name="related_manga_summary">显示相关漫画。可能并不准确或缺失</string>
|
||||
<string name="related_manga_summary">显示相关漫画,可能并不相关或没有相关漫画</string>
|
||||
<string name="tracker_wifi_only_summary">使用移动网络时停止检查新章节</string>
|
||||
<string name="order_added">添加日期</string>
|
||||
<string name="on_device">本地</string>
|
||||
@@ -464,15 +464,15 @@
|
||||
<string name="manage_categories">管理分类</string>
|
||||
<string name="color_light">浅色</string>
|
||||
<string name="search_hint">输入漫画标题、分类或图源名称</string>
|
||||
<string name="main_screen_sections">底部导航栏</string>
|
||||
<string name="main_screen_sections">主页底部导航栏</string>
|
||||
<string name="advanced">高级</string>
|
||||
<string name="color_dark">深色</string>
|
||||
<string name="too_many_requests_message">请求次数过多,稍候再尝试</string>
|
||||
<string name="too_many_requests_message">请求次数过多,请稍后重试</string>
|
||||
<string name="suggestions_wifi_only_summary">使用移动网络时停止推荐漫画</string>
|
||||
<string name="default_section">默认页面</string>
|
||||
<string name="background">背景颜色</string>
|
||||
<string name="manga_list">漫画列表</string>
|
||||
<string name="disable_nsfw">禁用成人内容图源</string>
|
||||
<string name="disable_nsfw">隐藏成人内容</string>
|
||||
<string name="color_white">白色</string>
|
||||
<string name="to_top">置顶</string>
|
||||
<string name="show">显示</string>
|
||||
@@ -484,7 +484,7 @@
|
||||
<string name="keep_screen_on">保持屏幕常亮</string>
|
||||
<string name="keep_screen_on_summary">阅读时不息屏</string>
|
||||
<string name="list_options">显示选项</string>
|
||||
<string name="suggest_new_sources">新增漫画源推荐</string>
|
||||
<string name="suggest_new_sources">推荐新增图源</string>
|
||||
<string name="enhanced_colors_summary">减少色带,但可能会影响性能</string>
|
||||
<string name="enhanced_colors">32位色彩模式</string>
|
||||
<string name="suggest_new_sources_summary">应用更新后提示开启新增图源</string>
|
||||
@@ -500,9 +500,9 @@
|
||||
<string name="frequency_once_per_month">每月一次</string>
|
||||
<string name="last_successful_backup">上次备份成功:%s</string>
|
||||
<string name="backups_output_directory">备份保存路径</string>
|
||||
<string name="download_option_all_chapters">所有已翻译的章节 %s</string>
|
||||
<string name="download_option_all_chapters">所有已翻译的章节 (%s)</string>
|
||||
<string name="state_upcoming">即将推出</string>
|
||||
<string name="by_name_reverse">名称倒序</string>
|
||||
<string name="by_name_reverse">名称 (倒序)</string>
|
||||
<string name="manage_sources">管理图源</string>
|
||||
<string name="catalog">图源目录</string>
|
||||
<string name="content_type_comics">美漫</string>
|
||||
@@ -510,14 +510,14 @@
|
||||
<string name="content_type_manga">日漫</string>
|
||||
<string name="source_summary_pattern">%1$s,%2$s</string>
|
||||
<string name="sources_catalog">图源目录</string>
|
||||
<string name="source_enabled">已启用图源</string>
|
||||
<string name="source_enabled">图源已开启</string>
|
||||
<string name="content_type_hentai">成人</string>
|
||||
<string name="no_manga_sources_found">本次搜索未发现可用图源</string>
|
||||
<string name="no_manga_sources_catalog_text">此页面没有可用图源,或可能已添加所有图源。
|
||||
<string name="no_manga_sources_catalog_text">此页面暂无可用图源,或可能已添加所有可用图源。
|
||||
\n敬请期待后续更新</string>
|
||||
<string name="welcome_text">请选择需要开启的图源内容。可稍后在设置选项中设定</string>
|
||||
<string name="welcome_text">请选择需要开启的图源内容,可之后在设置中更改</string>
|
||||
<string name="sync_auth">网络同步</string>
|
||||
<string name="downloads_settings_info">若遇到服务器端阻塞,可以在图源设置中为每个图源单独开启限速下载功能</string>
|
||||
<string name="downloads_settings_info">若出现服务器阻塞的情况,可在图源设置中为每个图源单独开启限速下载功能</string>
|
||||
<string name="skip">跳过</string>
|
||||
<string name="backup_date_">备份日期:%s</string>
|
||||
<string name="content_rating">内容分级</string>
|
||||
@@ -526,7 +526,7 @@
|
||||
<string name="rating_suggestive">R15</string>
|
||||
<string name="rating_adult">R18</string>
|
||||
<string name="lock_screen_rotation">锁定屏幕方向</string>
|
||||
<string name="default_tab">默认导航栏</string>
|
||||
<string name="default_tab">漫画详情页默认界面</string>
|
||||
<string name="grayscale">灰度</string>
|
||||
<string name="globally">全局</string>
|
||||
<string name="this_manga">此漫画</string>
|
||||
@@ -537,22 +537,22 @@
|
||||
<string name="state_abandoned">已腰斩</string>
|
||||
<string name="manual">手动</string>
|
||||
<string name="available_d">%1$d 个可用</string>
|
||||
<string name="disable_nsfw_summary">禁用成人内容图源并尽可能从列表中隐藏成人漫画</string>
|
||||
<string name="disable_nsfw_summary">关闭含有成人内容的图源并尽可能从列表中隐藏成人漫画</string>
|
||||
<string name="speed_value">x%.1f</string>
|
||||
<string name="error_filter_locale_genre_not_supported">此图源不支持同时按分类和区域筛选</string>
|
||||
<string name="error_filter_states_genre_not_supported">此图源不支持同时按分类和状态筛选</string>
|
||||
<string name="genres_search_hint">开始输入分类名称</string>
|
||||
<string name="state_paused">休刊中</string>
|
||||
<string name="reader_optimize">降低内存占用(测试)</string>
|
||||
<string name="reader_optimize">降低内存占用 (测试)</string>
|
||||
<string name="reader_optimize_summary">降低当前画面外的页面质量以减少内存占用</string>
|
||||
<string name="disable_battery_optimization_summary_downloads">可能帮助解决下载过程相关的问题</string>
|
||||
<string name="disable_battery_optimization_summary_downloads">也许能帮助解决下载过程相关的问题</string>
|
||||
<string name="error_search_not_supported">此图源不支持搜索</string>
|
||||
<string name="state">状态</string>
|
||||
<string name="error_multiple_genres_not_supported">此图源不支持按多个分类筛选</string>
|
||||
<string name="error_multiple_states_not_supported">此图源不支持按多个状态筛选</string>
|
||||
<string name="by_relevance">关联</string>
|
||||
<string name="mark_as_completed">标记为已读</string>
|
||||
<string name="mark_as_completed_prompt">要将选定的漫画标记为已读吗?
|
||||
<string name="mark_as_completed_prompt">确定将选定的漫画标记为已读吗?
|
||||
\n
|
||||
\n警告: 当前的阅读进度将会丢失。</string>
|
||||
<string name="category_hidden_done">此分类已从主页隐藏,可通过菜单 → 管理分类来访问</string>
|
||||
@@ -578,10 +578,19 @@
|
||||
<string name="reader_actions_summary">配置屏幕点按区域的操作</string>
|
||||
<string name="reader_actions">阅读操作</string>
|
||||
<string name="tap_action">点按操作</string>
|
||||
<string name="use_two_pages_landscape">在横屏时开启双页模式(测试)</string>
|
||||
<string name="config_reset_confirm">要恢复为默认设置吗?恢复后无法撤销。</string>
|
||||
<string name="use_two_pages_landscape">横屏时开启双页模式 (测试)</string>
|
||||
<string name="config_reset_confirm">确定恢复为默认设置吗?恢复后无法撤销。</string>
|
||||
<string name="email_password_enter_hint">输入邮箱和密码以继续</string>
|
||||
<string name="fullscreen_mode">全屏模式</string>
|
||||
<string name="default_webtoon_zoom_out">条漫默认缩小值</string>
|
||||
<string name="reader_fullscreen_summary">将系统状态栏与通知栏隐藏</string>
|
||||
<string name="suggestions_unavailable_text">漫画推荐功能已被关闭</string>
|
||||
<string name="check_for_new_chapters_disabled">章节更新功能已被关闭</string>
|
||||
<string name="reading_time_estimation">在漫画详情页显示估计阅读时间</string>
|
||||
<string name="reading_time_estimation_summary">估计阅读时间可能会不准确</string>
|
||||
<string name="show_labels_in_navbar">显示主页底部导航栏名称</string>
|
||||
<string name="ask_for_dest_dir_every_time">保存时总是询问图片保存目录</string>
|
||||
<string name="pages_saving">图片保存</string>
|
||||
<string name="default_page_save_dir">图片默认保存目录</string>
|
||||
<string name="remove_from_history">删除阅读历史</string>
|
||||
</resources>
|
||||
@@ -10,6 +10,7 @@
|
||||
<dimen name="list_spacing_large">12dp</dimen>
|
||||
<!-- Navigation -->
|
||||
<dimen name="nav_header_logo_size">36dp</dimen>
|
||||
<dimen name="nav_bar_height_compact">62dp</dimen>
|
||||
|
||||
<dimen name="toolbar_height_expanded">172dp</dimen>
|
||||
<dimen name="grid_spacing">8dp</dimen>
|
||||
|
||||
@@ -331,7 +331,7 @@
|
||||
<string name="manga_error_description_pattern">Error details:<br><tt>%1$s</tt><br><br>1. Try to <a href="%2$s">open manga in a web browser</a> to ensure it is available on its source<br>2. Make sure you are using the <a href="kotatsu://about">latest version of Kotatsu</a><br>3. If it is available, send an error report to the developers.</string>
|
||||
<string name="history_shortcuts">Show recent manga shortcuts</string>
|
||||
<string name="history_shortcuts_summary">Make recent manga available by long pressing on application icon</string>
|
||||
<string name="reader_control_ltr_summary">Tap on the right edge or pressing the right key always switches to the next page</string>
|
||||
<string name="reader_control_ltr_summary">Tapping on the right edge, or pressing the right key, always switches to the next page.</string>
|
||||
<string name="reader_control_ltr">Ergonomic reader control</string>
|
||||
<string name="color_correction">Color correction</string>
|
||||
<string name="brightness">Brightness</string>
|
||||
@@ -585,12 +585,18 @@
|
||||
<string name="none">None</string>
|
||||
<string name="config_reset_confirm">Reset settings to default values? This action cannot be undone.</string>
|
||||
<string name="use_two_pages_landscape">Use two pages layout on landscape orientation (beta)</string>
|
||||
<string name="default_webtoon_zoom_out">Default webtoon zoom out</string>
|
||||
<string name="fullscreen_mode">Fullscreen mode</string>
|
||||
<string name="reader_fullscreen_summary">Hide system status and navigation bars</string>
|
||||
<string name="fraction_pattern" translatable="false">%1$d/%2$d</string>
|
||||
<string name="reading_time_estimation">Show estimated reading time</string>
|
||||
<string name="reading_time_estimation_summary">The time estimation value may be inaccurate</string>
|
||||
<string name="suggestions_unavailable_text">Suggestions feature is disabled</string>
|
||||
<string name="check_for_new_chapters_disabled">Checking for new chapters is disabled</string>
|
||||
<string name="default_webtoon_zoom_out">Default webtoon zoom out</string>
|
||||
<string name="fullscreen_mode">Fullscreen mode</string>
|
||||
<string name="reader_fullscreen_summary">Hide system status and navigation bars</string>
|
||||
<string name="fraction_pattern" translatable="false">%1$d/%2$d</string>
|
||||
<string name="reading_time_estimation">Show estimated reading time</string>
|
||||
<string name="reading_time_estimation_summary">The time estimation value may be inaccurate</string>
|
||||
<string name="suggestions_unavailable_text">Suggestions feature is disabled</string>
|
||||
<string name="check_for_new_chapters_disabled">Checking for new chapters is disabled</string>
|
||||
<string name="show_labels_in_navbar">Show labels in navigation bar</string>
|
||||
<string name="pages_saving">Saving pages</string>
|
||||
<string name="ask_for_dest_dir_every_time">Ask for the destination dir every time</string>
|
||||
<string name="default_page_save_dir">Default page save directory</string>
|
||||
<string name="remove_from_history">Remove from history</string>
|
||||
<string name="location">Location</string>
|
||||
</resources>
|
||||
|
||||
@@ -46,8 +46,7 @@
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/details">
|
||||
<PreferenceCategory android:title="@string/details">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
@@ -71,6 +70,11 @@
|
||||
android:title="@string/main_screen_sections"
|
||||
app:allowDividerAbove="true" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="nav_labels"
|
||||
android:title="@string/show_labels_in_navbar" />
|
||||
|
||||
<org.koitharu.kotatsu.settings.utils.ActivityListPreference
|
||||
android:key="app_locale"
|
||||
android:title="@string/language" />
|
||||
|
||||
@@ -35,4 +35,18 @@
|
||||
android:summary="@string/downloads_settings_info"
|
||||
app:allowDividerAbove="true" />
|
||||
|
||||
<PreferenceCategory android:title="@string/pages_saving">
|
||||
|
||||
<Preference
|
||||
android:key="pages_dir"
|
||||
android:persistent="false"
|
||||
android:title="@string/default_page_save_dir" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="pages_dir_ask"
|
||||
android:title="@string/ask_for_dest_dir_every_time" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
android:title="@string/reader_actions"
|
||||
app:allowDividerAbove="true" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="reader_taps_ltr"
|
||||
android:summary="@string/reader_control_ltr_summary"
|
||||
android:title="@string/reader_control_ltr" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="reader_volume_buttons"
|
||||
|
||||
Reference in New Issue
Block a user