Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 557c2b018a | |||
| 3add01d57e | |||
| 2ad1ea98f1 | |||
| 3121532217 | |||
| 20ac12ca0d | |||
| f0b222140e | |||
| 2a35ca6094 | |||
| 93f9636916 | |||
| 2c24aba558 |
27
README.md
27
README.md
@@ -10,9 +10,9 @@ Kotatsu is a free and open source manga reader for Android.
|
|||||||
alt="Get it on F-Droid"
|
alt="Get it on F-Droid"
|
||||||
height="80">](https://f-droid.org/packages/org.koitharu.kotatsu)
|
height="80">](https://f-droid.org/packages/org.koitharu.kotatsu)
|
||||||
|
|
||||||
Download APK from GitHub Releases:
|
Download APK directly from GitHub:
|
||||||
|
|
||||||
- [Latest release](https://github.com/KotatsuApp/Kotatsu/releases/latest)
|
- **[Latest release](https://github.com/KotatsuApp/Kotatsu/releases/latest)**
|
||||||
|
|
||||||
### Main Features
|
### Main Features
|
||||||
|
|
||||||
@@ -24,8 +24,8 @@ Download APK from GitHub Releases:
|
|||||||
* Tablet-optimized material design UI
|
* Tablet-optimized material design UI
|
||||||
* Standard and Webtoon-optimized reader
|
* Standard and Webtoon-optimized reader
|
||||||
* Notifications about new chapters with updates feed
|
* Notifications about new chapters with updates feed
|
||||||
* Available in multiple languages
|
* Shikimori integration (manga tracking)
|
||||||
* Password protect access to the app
|
* Password/fingerprint protect access to the app
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
@@ -38,23 +38,20 @@ Download APK from GitHub Releases:
|
|||||||
|
|
||||||
### Localization
|
### Localization
|
||||||
|
|
||||||
<a href="https://hosted.weblate.org/engage/kotatsu/">
|
[<img src="https://hosted.weblate.org/widgets/kotatsu/-/287x66-white.png" alt="Translation status">](https://hosted.weblate.org/engage/kotatsu/)
|
||||||
<img src="https://hosted.weblate.org/widgets/kotatsu/-/287x66-white.png" alt="Translation status" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
Kotatsu is localized in a number of different languages, if you would like to help improve these or add new languages,
|
Kotatsu is localized in a number of different languages, if you would like to help improve these or add new languages,
|
||||||
please head over to the Weblate <a href="https://hosted.weblate.org/engage/kotatsu/">project page</a>
|
please head over to the [Weblate project page](https://hosted.weblate.org/engage/kotatsu/)
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
|
||||||
[](http://www.gnu.org/licenses/gpl-3.0.en.html)
|
[](http://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||||
|
|
||||||
Kotatsu is Free Software: You can use, study share and improve it at your
|
You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications
|
||||||
will. Specifically you can redistribute and/or modify it under the terms of the
|
to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build &
|
||||||
[GNU General Public License](https://www.gnu.org/licenses/gpl.html) as
|
install instructions.
|
||||||
published by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
### Disclaimer
|
### DMCA disclaimer
|
||||||
|
|
||||||
The developers of this application does not have any affiliation with the content providers available.
|
The developers of this application does not have any affiliation with the content available in the app.
|
||||||
|
It is collecting from the sources freely available through any web browser.
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ android {
|
|||||||
applicationId 'org.koitharu.kotatsu'
|
applicationId 'org.koitharu.kotatsu'
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 32
|
targetSdkVersion 32
|
||||||
versionCode 412
|
versionCode 414
|
||||||
versionName '3.4'
|
versionName '3.4.2'
|
||||||
generatedDensities = []
|
generatedDensities = []
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
@@ -76,8 +76,7 @@ afterEvaluate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
implementation('com.github.nv95:kotatsu-parsers:26d951bc20') {
|
||||||
implementation('com.github.nv95:kotatsu-parsers:da3b0ae0cf') {
|
|
||||||
exclude group: 'org.json', module: 'json'
|
exclude group: 'org.json', module: 'json'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import com.google.android.material.snackbar.Snackbar
|
|||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.acra.ktx.sendWithAcra
|
|
||||||
import org.koin.android.ext.android.get
|
import org.koin.android.ext.android.get
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
@@ -39,7 +38,6 @@ import org.koitharu.kotatsu.core.os.ShortcutsRepository
|
|||||||
import org.koitharu.kotatsu.databinding.ActivityDetailsBinding
|
import org.koitharu.kotatsu.databinding.ActivityDetailsBinding
|
||||||
import org.koitharu.kotatsu.details.ui.adapter.BranchesAdapter
|
import org.koitharu.kotatsu.details.ui.adapter.BranchesAdapter
|
||||||
import org.koitharu.kotatsu.download.ui.service.DownloadService
|
import org.koitharu.kotatsu.download.ui.service.DownloadService
|
||||||
import org.koitharu.kotatsu.parsers.exception.ParseException
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
||||||
@@ -48,6 +46,8 @@ import org.koitharu.kotatsu.reader.ui.ReaderState
|
|||||||
import org.koitharu.kotatsu.scrobbling.ui.selector.ScrobblingSelectorBottomSheet
|
import org.koitharu.kotatsu.scrobbling.ui.selector.ScrobblingSelectorBottomSheet
|
||||||
import org.koitharu.kotatsu.search.ui.multi.MultiSearchActivity
|
import org.koitharu.kotatsu.search.ui.multi.MultiSearchActivity
|
||||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||||
|
import org.koitharu.kotatsu.utils.ext.isReportable
|
||||||
|
import org.koitharu.kotatsu.utils.ext.report
|
||||||
|
|
||||||
class DetailsActivity :
|
class DetailsActivity :
|
||||||
BaseActivity<ActivityDetailsBinding>(),
|
BaseActivity<ActivityDetailsBinding>(),
|
||||||
@@ -118,7 +118,7 @@ class DetailsActivity :
|
|||||||
Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show()
|
Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show()
|
||||||
finishAfterTransition()
|
finishAfterTransition()
|
||||||
}
|
}
|
||||||
e is ParseException || e is IllegalArgumentException || e is IllegalStateException -> {
|
e.isReportable() -> {
|
||||||
binding.snackbar.show(
|
binding.snackbar.show(
|
||||||
messageText = e.getDisplayMessage(resources),
|
messageText = e.getDisplayMessage(resources),
|
||||||
actionId = R.string.report,
|
actionId = R.string.report,
|
||||||
@@ -128,7 +128,7 @@ class DetailsActivity :
|
|||||||
Snackbar.LENGTH_LONG
|
Snackbar.LENGTH_LONG
|
||||||
},
|
},
|
||||||
onActionClick = {
|
onActionClick = {
|
||||||
e.sendWithAcra()
|
e.report("DetailsActivity::onError")
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import kotlin.math.sign
|
||||||
|
|
||||||
|
class WebtoonLayoutManager : LinearLayoutManager {
|
||||||
|
|
||||||
|
private var scrollDirection: Int = 0
|
||||||
|
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
orientation: Int,
|
||||||
|
reverseLayout: Boolean,
|
||||||
|
) : super(context, orientation, reverseLayout)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet?,
|
||||||
|
defStyleAttr: Int,
|
||||||
|
defStyleRes: Int,
|
||||||
|
) : super(context, attrs, defStyleAttr, defStyleRes)
|
||||||
|
|
||||||
|
override fun scrollVerticallyBy(dy: Int, recycler: RecyclerView.Recycler?, state: RecyclerView.State): Int {
|
||||||
|
scrollDirection = dy.sign
|
||||||
|
return super.scrollVerticallyBy(dy, recycler, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun calculateExtraLayoutSpace(state: RecyclerView.State, extraLayoutSpace: IntArray) {
|
||||||
|
if (state.hasTargetScrollPosition()) {
|
||||||
|
super.calculateExtraLayoutSpace(state, extraLayoutSpace)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val pageSize = height
|
||||||
|
extraLayoutSpace[0] = if (scrollDirection < 0) pageSize else 0
|
||||||
|
extraLayoutSpace[1] = if (scrollDirection < 0) 0 else pageSize
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,6 @@ import org.koitharu.kotatsu.reader.ui.ReaderState
|
|||||||
import org.koitharu.kotatsu.reader.ui.pager.BaseReader
|
import org.koitharu.kotatsu.reader.ui.pager.BaseReader
|
||||||
import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter
|
import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter
|
||||||
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
|
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
|
||||||
import org.koitharu.kotatsu.utils.ext.doOnCurrentItemChanged
|
|
||||||
import org.koitharu.kotatsu.utils.ext.findCenterViewPosition
|
import org.koitharu.kotatsu.utils.ext.findCenterViewPosition
|
||||||
import org.koitharu.kotatsu.utils.ext.firstVisibleItemPosition
|
import org.koitharu.kotatsu.utils.ext.firstVisibleItemPosition
|
||||||
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
|
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
|
||||||
@@ -33,7 +32,7 @@ class WebtoonReaderFragment : BaseReader<FragmentReaderWebtoonBinding>() {
|
|||||||
with(binding.recyclerView) {
|
with(binding.recyclerView) {
|
||||||
setHasFixedSize(true)
|
setHasFixedSize(true)
|
||||||
adapter = webtoonAdapter
|
adapter = webtoonAdapter
|
||||||
doOnCurrentItemChanged(::notifyPageChanged)
|
addOnPageScrollListener(PageScrollListener())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,4 +92,12 @@ class WebtoonReaderFragment : BaseReader<FragmentReaderWebtoonBinding>() {
|
|||||||
override fun switchPageTo(position: Int, smooth: Boolean) {
|
override fun switchPageTo(position: Int, smooth: Boolean) {
|
||||||
binding.recyclerView.firstVisibleItemPosition = position
|
binding.recyclerView.firstVisibleItemPosition = position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inner class PageScrollListener : WebtoonRecyclerView.OnPageScrollListener() {
|
||||||
|
|
||||||
|
override fun onPageChanged(recyclerView: WebtoonRecyclerView, index: Int) {
|
||||||
|
super.onPageChanged(recyclerView, index)
|
||||||
|
notifyPageChanged(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,25 +2,27 @@ package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat.TYPE_TOUCH
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.koitharu.kotatsu.utils.ext.findCenterViewPosition
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class WebtoonRecyclerView @JvmOverloads constructor(
|
class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||||
) : RecyclerView(context, attrs, defStyleAttr) {
|
) : RecyclerView(context, attrs, defStyleAttr) {
|
||||||
|
|
||||||
override fun startNestedScroll(axes: Int) = startNestedScroll(axes, ViewCompat.TYPE_TOUCH)
|
private var onPageScrollListeners: MutableList<OnPageScrollListener>? = null
|
||||||
|
|
||||||
override fun startNestedScroll(axes: Int, type: Int): Boolean {
|
override fun startNestedScroll(axes: Int) = startNestedScroll(axes, TYPE_TOUCH)
|
||||||
return true
|
|
||||||
}
|
override fun startNestedScroll(axes: Int, type: Int): Boolean = true
|
||||||
|
|
||||||
override fun dispatchNestedPreScroll(
|
override fun dispatchNestedPreScroll(
|
||||||
dx: Int,
|
dx: Int,
|
||||||
dy: Int,
|
dy: Int,
|
||||||
consumed: IntArray?,
|
consumed: IntArray?,
|
||||||
offsetInWindow: IntArray?
|
offsetInWindow: IntArray?
|
||||||
) = dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, ViewCompat.TYPE_TOUCH)
|
) = dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, TYPE_TOUCH)
|
||||||
|
|
||||||
override fun dispatchNestedPreScroll(
|
override fun dispatchNestedPreScroll(
|
||||||
dx: Int,
|
dx: Int,
|
||||||
@@ -34,6 +36,7 @@ class WebtoonRecyclerView @JvmOverloads constructor(
|
|||||||
consumed[0] = 0
|
consumed[0] = 0
|
||||||
consumed[1] = consumedY
|
consumed[1] = consumedY
|
||||||
}
|
}
|
||||||
|
notifyScrollChanged(dy)
|
||||||
return consumedY != 0 || dy == 0
|
return consumedY != 0 || dy == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,4 +78,39 @@ class WebtoonRecyclerView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addOnPageScrollListener(listener: OnPageScrollListener) {
|
||||||
|
val list = onPageScrollListeners ?: LinkedList<OnPageScrollListener>().also { onPageScrollListeners = it }
|
||||||
|
list.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeOnPageScrollListener(listener: OnPageScrollListener) {
|
||||||
|
onPageScrollListeners?.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notifyScrollChanged(dy: Int) {
|
||||||
|
val listeners = onPageScrollListeners
|
||||||
|
if (listeners.isNullOrEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val centerPosition = findCenterViewPosition()
|
||||||
|
listeners.forEach { it.dispatchScroll(this, dy, centerPosition) }
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class OnPageScrollListener {
|
||||||
|
|
||||||
|
private var lastPosition = NO_POSITION
|
||||||
|
|
||||||
|
fun dispatchScroll(recyclerView: WebtoonRecyclerView, dy: Int, centerPosition: Int) {
|
||||||
|
onScroll(recyclerView, dy)
|
||||||
|
if (centerPosition != NO_POSITION && centerPosition != lastPosition) {
|
||||||
|
lastPosition = centerPosition
|
||||||
|
onPageChanged(recyclerView, centerPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onScroll(recyclerView: WebtoonRecyclerView, dy: Int) = Unit
|
||||||
|
|
||||||
|
open fun onPageChanged(recyclerView: WebtoonRecyclerView, index: Int) = Unit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,9 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.annotation.MainThread
|
import androidx.annotation.MainThread
|
||||||
|
import androidx.core.net.toUri
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -23,9 +23,6 @@ import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
|||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.security.NoSuchAlgorithmException
|
|
||||||
import java.security.cert.CertificateEncodingException
|
|
||||||
import java.security.cert.CertificateException
|
|
||||||
import java.security.cert.CertificateFactory
|
import java.security.cert.CertificateFactory
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@@ -74,7 +71,8 @@ class AppUpdateChecker(private val activity: ComponentActivity) {
|
|||||||
.setTitle(R.string.app_update_available)
|
.setTitle(R.string.app_update_available)
|
||||||
.setMessage(message)
|
.setMessage(message)
|
||||||
.setPositiveButton(R.string.download) { _, _ ->
|
.setPositiveButton(R.string.download) { _, _ ->
|
||||||
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(version.apkUrl)))
|
val intent = Intent(Intent.ACTION_VIEW, version.apkUrl.toUri())
|
||||||
|
activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.open_in_browser)))
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.close, null)
|
.setNegativeButton(R.string.close, null)
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
@@ -88,42 +86,23 @@ class AppUpdateChecker(private val activity: ComponentActivity) {
|
|||||||
private val PERIOD = TimeUnit.HOURS.toMillis(6)
|
private val PERIOD = TimeUnit.HOURS.toMillis(6)
|
||||||
|
|
||||||
fun isUpdateSupported(context: Context): Boolean {
|
fun isUpdateSupported(context: Context): Boolean {
|
||||||
return getCertificateSHA1Fingerprint(context) == CERT_SHA1
|
return BuildConfig.DEBUG || getCertificateSHA1Fingerprint(context) == CERT_SHA1
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@SuppressLint("PackageManagerGetSignatures")
|
@SuppressLint("PackageManagerGetSignatures")
|
||||||
private fun getCertificateSHA1Fingerprint(context: Context): String? {
|
private fun getCertificateSHA1Fingerprint(context: Context): String? = runCatching {
|
||||||
val packageInfo = try {
|
val packageInfo = context.packageManager.getPackageInfo(context.packageName, PackageManager.GET_SIGNATURES)
|
||||||
context.packageManager.getPackageInfo(
|
val signatures = requireNotNull(packageInfo?.signatures)
|
||||||
context.packageName,
|
val cert: ByteArray = signatures.first().toByteArray()
|
||||||
PackageManager.GET_SIGNATURES
|
|
||||||
)
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
e.printStackTraceDebug()
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val signatures = packageInfo?.signatures
|
|
||||||
val cert: ByteArray = signatures?.firstOrNull()?.toByteArray() ?: return null
|
|
||||||
val input: InputStream = ByteArrayInputStream(cert)
|
val input: InputStream = ByteArrayInputStream(cert)
|
||||||
val c = try {
|
val cf = CertificateFactory.getInstance("X509")
|
||||||
val cf = CertificateFactory.getInstance("X509")
|
val c = cf.generateCertificate(input) as X509Certificate
|
||||||
cf.generateCertificate(input) as X509Certificate
|
val md: MessageDigest = MessageDigest.getInstance("SHA1")
|
||||||
} catch (e: CertificateException) {
|
val publicKey: ByteArray = md.digest(c.encoded)
|
||||||
e.printStackTraceDebug()
|
return publicKey.byte2HexFormatted()
|
||||||
return null
|
}.onFailure { error ->
|
||||||
}
|
error.printStackTraceDebug()
|
||||||
return try {
|
}.getOrNull()
|
||||||
val md: MessageDigest = MessageDigest.getInstance("SHA1")
|
|
||||||
val publicKey: ByteArray = md.digest(c.encoded)
|
|
||||||
publicKey.byte2HexFormatted()
|
|
||||||
} catch (e: NoSuchAlgorithmException) {
|
|
||||||
e.printStackTraceDebug()
|
|
||||||
null
|
|
||||||
} catch (e: CertificateEncodingException) {
|
|
||||||
e.printStackTraceDebug()
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import android.view.View
|
|||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
@@ -74,11 +75,15 @@ class SourceSettingsFragment : BasePreferenceFragment(0) {
|
|||||||
when {
|
when {
|
||||||
error is AuthRequiredException -> Unit
|
error is AuthRequiredException -> Unit
|
||||||
ExceptionResolver.canResolve(error) -> {
|
ExceptionResolver.canResolve(error) -> {
|
||||||
Snackbar.make(listView, error.getDisplayMessage(resources), Snackbar.LENGTH_INDEFINITE)
|
ensureActive()
|
||||||
.setAction(ExceptionResolver.getResolveStringId(error)) { resolveError(error) }
|
Snackbar.make(
|
||||||
|
listView ?: return@onFailure,
|
||||||
|
error.getDisplayMessage(preference.context.resources),
|
||||||
|
Snackbar.LENGTH_INDEFINITE,
|
||||||
|
).setAction(ExceptionResolver.getResolveStringId(error)) { resolveError(error) }
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
else -> preference.summary = error.getDisplayMessage(resources)
|
else -> preference.summary = error.getDisplayMessage(preference.context.resources)
|
||||||
}
|
}
|
||||||
error.printStackTraceDebug()
|
error.printStackTraceDebug()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ import android.content.ActivityNotFoundException
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import okio.FileNotFoundException
|
import okio.FileNotFoundException
|
||||||
import org.acra.ACRA
|
import org.acra.ACRA
|
||||||
|
import org.acra.ktx.sendWithAcra
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
||||||
import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException
|
import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException
|
||||||
import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException
|
import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException
|
||||||
import org.koitharu.kotatsu.core.exceptions.WrongPasswordException
|
import org.koitharu.kotatsu.core.exceptions.WrongPasswordException
|
||||||
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
|
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
|
||||||
|
import org.koitharu.kotatsu.parsers.exception.ParseException
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
|
|
||||||
@@ -26,4 +28,17 @@ fun Throwable.getDisplayMessage(resources: Resources) = when (this) {
|
|||||||
else -> localizedMessage ?: resources.getString(R.string.error_occurred)
|
else -> localizedMessage ?: resources.getString(R.string.error_occurred)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ACRA.setCurrentManga(manga: Manga?) = errorReporter.putCustomData("manga", manga?.publicUrl.toString())
|
fun Throwable.isReportable(): Boolean {
|
||||||
|
if (this !is Exception) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return this is ParseException || this is IllegalArgumentException || this is IllegalStateException
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Throwable.report(message: String?) {
|
||||||
|
CaughtException(this, message).sendWithAcra()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ACRA.setCurrentManga(manga: Manga?) = errorReporter.putCustomData("manga", manga?.publicUrl.toString())
|
||||||
|
|
||||||
|
private class CaughtException(cause: Throwable, override val message: String?) : RuntimeException(cause)
|
||||||
@@ -91,22 +91,6 @@ fun View.resetTransformations() {
|
|||||||
rotationY = 0f
|
rotationY = 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun RecyclerView.doOnCurrentItemChanged(crossinline callback: (Int) -> Unit) {
|
|
||||||
addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
|
||||||
|
|
||||||
private var lastItem = -1
|
|
||||||
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
val item = recyclerView.findCenterViewPosition()
|
|
||||||
if (item != RecyclerView.NO_POSITION && item != lastItem) {
|
|
||||||
lastItem = item
|
|
||||||
callback(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun RecyclerView.findCenterViewPosition(): Int {
|
fun RecyclerView.findCenterViewPosition(): Int {
|
||||||
val centerX = width / 2f
|
val centerX = width / 2f
|
||||||
val centerY = height / 2f
|
val centerY = height / 2f
|
||||||
|
|||||||
@@ -42,9 +42,8 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layout_titles"
|
android:id="@+id/layout_titles"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@@ -151,6 +150,14 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Barrier
|
||||||
|
android:id="@+id/barrier_header"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:barrierDirection="bottom"
|
||||||
|
app:barrierMargin="8dp"
|
||||||
|
app:constraint_referenced_ids="layout_titles,imageView_cover" />
|
||||||
|
|
||||||
<org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
<org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
||||||
android:id="@+id/chips_tags"
|
android:id="@+id/chips_tags"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@@ -162,7 +169,7 @@
|
|||||||
app:chipSpacingVertical="6dp"
|
app:chipSpacingVertical="6dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/layout_titles" />
|
app:layout_constraintTop_toBottomOf="@+id/barrier_header" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView_bookmarks"
|
android:id="@+id/textView_bookmarks"
|
||||||
@@ -223,7 +230,7 @@
|
|||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/recyclerView_bookmarks"
|
app:layout_constraintTop_toBottomOf="@id/scrobbling_layout"
|
||||||
tools:ignore="UnusedAttribute"
|
tools:ignore="UnusedAttribute"
|
||||||
tools:text="@tools:sample/lorem/random[250]" />
|
tools:text="@tools:sample/lorem/random[250]" />
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,4 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
app:layoutManager="org.koitharu.kotatsu.reader.ui.pager.webtoon.WebtoonLayoutManager" />
|
||||||
@@ -1,305 +1,320 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="close_menu">Закрыть меню</string>
|
<string name="close_menu">Закрыть меню</string>
|
||||||
<string name="open_menu">Открыть меню</string>
|
<string name="open_menu">Открыть меню</string>
|
||||||
<string name="local_storage">На устройстве</string>
|
<string name="local_storage">На устройстве</string>
|
||||||
<string name="favourites">Избранное</string>
|
<string name="favourites">Избранное</string>
|
||||||
<string name="history">История</string>
|
<string name="history">История</string>
|
||||||
<string name="error_occurred">Произошла ошибка</string>
|
<string name="error_occurred">Произошла ошибка</string>
|
||||||
<string name="network_error">Не удалось подключиться к интернету</string>
|
<string name="network_error">Не удалось подключиться к интернету</string>
|
||||||
<string name="details">Подробности</string>
|
<string name="details">Подробности</string>
|
||||||
<string name="chapters">Главы</string>
|
<string name="chapters">Главы</string>
|
||||||
<string name="list">Список</string>
|
<string name="list">Список</string>
|
||||||
<string name="detailed_list">Подробный список</string>
|
<string name="detailed_list">Подробный список</string>
|
||||||
<string name="grid">Таблица</string>
|
<string name="grid">Таблица</string>
|
||||||
<string name="list_mode">Вид списка</string>
|
<string name="list_mode">Вид списка</string>
|
||||||
<string name="settings">Настройки</string>
|
<string name="settings">Настройки</string>
|
||||||
<string name="remote_sources">Онлайн каталоги</string>
|
<string name="remote_sources">Онлайн каталоги</string>
|
||||||
<string name="loading_">Загрузка…</string>
|
<string name="loading_">Загрузка…</string>
|
||||||
<string name="chapter_d_of_d">Глава %1$d из %2$d</string>
|
<string name="chapter_d_of_d">Глава %1$d из %2$d</string>
|
||||||
<string name="close">Закрыть</string>
|
<string name="close">Закрыть</string>
|
||||||
<string name="try_again">Повторить</string>
|
<string name="try_again">Повторить</string>
|
||||||
<string name="clear_history">Очистить историю</string>
|
<string name="clear_history">Очистить историю</string>
|
||||||
<string name="nothing_found">Ничего не найдено</string>
|
<string name="nothing_found">Ничего не найдено</string>
|
||||||
<string name="history_is_empty">Истории пока нет</string>
|
<string name="history_is_empty">Истории пока нет</string>
|
||||||
<string name="read">Читать</string>
|
<string name="read">Читать</string>
|
||||||
<string name="you_have_not_favourites_yet">Избранного пока нет</string>
|
<string name="you_have_not_favourites_yet">Избранного пока нет</string>
|
||||||
<string name="add_to_favourites">В избранное</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="add">Добавить</string>
|
||||||
<string name="enter_category_name">Введите название</string>
|
<string name="enter_category_name">Введите название</string>
|
||||||
<string name="save">Сохранить</string>
|
<string name="save">Сохранить</string>
|
||||||
<string name="share">Поделиться</string>
|
<string name="share">Поделиться</string>
|
||||||
<string name="create_shortcut">Создать ярлык…</string>
|
<string name="create_shortcut">Создать ярлык…</string>
|
||||||
<string name="share_s">Поделиться %s</string>
|
<string name="share_s">Поделиться %s</string>
|
||||||
<string name="search">Поиск</string>
|
<string name="search">Поиск</string>
|
||||||
<string name="search_manga">Поиск манги</string>
|
<string name="search_manga">Поиск манги</string>
|
||||||
<string name="manga_downloading_">Загрузка…</string>
|
<string name="manga_downloading_">Загрузка…</string>
|
||||||
<string name="processing_">Обработка…</string>
|
<string name="processing_">Обработка…</string>
|
||||||
<string name="download_complete">Загружено</string>
|
<string name="download_complete">Загружено</string>
|
||||||
<string name="downloads">Загрузки</string>
|
<string name="downloads">Загрузки</string>
|
||||||
<string name="by_name">Имя</string>
|
<string name="by_name">Имя</string>
|
||||||
<string name="popular">Популярная</string>
|
<string name="popular">Популярная</string>
|
||||||
<string name="updated">Обновлённая</string>
|
<string name="updated">Обновлённая</string>
|
||||||
<string name="newest">Новая</string>
|
<string name="newest">Новая</string>
|
||||||
<string name="by_rating">Рейтинг</string>
|
<string name="by_rating">Рейтинг</string>
|
||||||
<string name="sort_order">Порядок сортировки</string>
|
<string name="sort_order">Порядок сортировки</string>
|
||||||
<string name="filter">Фильтр</string>
|
<string name="filter">Фильтр</string>
|
||||||
<string name="theme">Тема</string>
|
<string name="theme">Тема</string>
|
||||||
<string name="light">Светлая</string>
|
<string name="light">Светлая</string>
|
||||||
<string name="dark">Тёмная</string>
|
<string name="dark">Тёмная</string>
|
||||||
<string name="automatic">Как в системе</string>
|
<string name="automatic">Как в системе</string>
|
||||||
<string name="pages">Страницы</string>
|
<string name="pages">Страницы</string>
|
||||||
<string name="clear">Очистить</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="remove">Удалить</string>
|
||||||
<string name="_s_removed_from_history">«%s» удалено из истории</string>
|
<string name="_s_removed_from_history">«%s» удалено из истории</string>
|
||||||
<string name="_s_deleted_from_local_storage">«%s» удалено с устройства</string>
|
<string name="_s_deleted_from_local_storage">«%s» удалено с устройства</string>
|
||||||
<string name="wait_for_loading_finish">Дождитесь завершения загрузки…</string>
|
<string name="wait_for_loading_finish">Дождитесь завершения загрузки…</string>
|
||||||
<string name="save_page">Сохранить страницу</string>
|
<string name="save_page">Сохранить страницу</string>
|
||||||
<string name="page_saved">Сохранено</string>
|
<string name="page_saved">Сохранено</string>
|
||||||
<string name="share_image">Поделиться изображением</string>
|
<string name="share_image">Поделиться изображением</string>
|
||||||
<string name="_import">Импорт</string>
|
<string name="_import">Импорт</string>
|
||||||
<string name="delete">Удалить</string>
|
<string name="delete">Удалить</string>
|
||||||
<string name="operation_not_supported">Операция не поддерживается</string>
|
<string name="operation_not_supported">Операция не поддерживается</string>
|
||||||
<string name="text_file_not_supported">Выберите CBZ-файл или ZIP</string>
|
<string name="text_file_not_supported">Выберите CBZ-файл или ZIP</string>
|
||||||
<string name="no_description">Нет описания</string>
|
<string name="no_description">Нет описания</string>
|
||||||
<string name="history_and_cache">История и кэш</string>
|
<string name="history_and_cache">История и кэш</string>
|
||||||
<string name="clear_pages_cache">Очистить кэш страниц</string>
|
<string name="clear_pages_cache">Очистить кэш страниц</string>
|
||||||
<string name="cache">Кэш</string>
|
<string name="cache">Кэш</string>
|
||||||
<string name="text_file_sizes">Б|кБ|МБ|ГБ|ТБ</string>
|
<string name="text_file_sizes">Б|кБ|МБ|ГБ|ТБ</string>
|
||||||
<string name="standard">Стандартный</string>
|
<string name="standard">Стандартный</string>
|
||||||
<string name="webtoon">Манхва</string>
|
<string name="webtoon">Манхва</string>
|
||||||
<string name="read_mode">Режим чтения</string>
|
<string name="read_mode">Режим чтения</string>
|
||||||
<string name="grid_size">Размер таблицы</string>
|
<string name="grid_size">Размер таблицы</string>
|
||||||
<string name="search_on_s">Поиск по %s</string>
|
<string name="search_on_s">Поиск по %s</string>
|
||||||
<string name="delete_manga">Удалить мангу</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="reader_settings">Настройки чтения</string>
|
||||||
<string name="switch_pages">Листание страниц</string>
|
<string name="switch_pages">Листание страниц</string>
|
||||||
<string name="taps_on_edges">Нажатия по краям</string>
|
<string name="taps_on_edges">Нажатия по краям</string>
|
||||||
<string name="volume_buttons">Кнопки громкости</string>
|
<string name="volume_buttons">Кнопки громкости</string>
|
||||||
<string name="_continue">Продолжить</string>
|
<string name="_continue">Продолжить</string>
|
||||||
<string name="warning">Предупреждение</string>
|
<string name="warning">Предупреждение</string>
|
||||||
<string name="network_consumption_warning">Это может привести к расходу большого количества трафика</string>
|
<string name="network_consumption_warning">Это может привести к расходу большого количества трафика</string>
|
||||||
<string name="dont_ask_again">Больше не спрашивать</string>
|
<string name="dont_ask_again">Больше не спрашивать</string>
|
||||||
<string name="cancelling_">Отмена…</string>
|
<string name="cancelling_">Отмена…</string>
|
||||||
<string name="error">Ошибка</string>
|
<string name="error">Ошибка</string>
|
||||||
<string name="clear_thumbs_cache">Очистить кэш миниатюр</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="search_history_cleared">Очищено</string>
|
||||||
<string name="gestures_only">Только жесты</string>
|
<string name="gestures_only">Только жесты</string>
|
||||||
<string name="internal_storage">Внутренний накопитель</string>
|
<string name="internal_storage">Внутренний накопитель</string>
|
||||||
<string name="external_storage">Внешнее хранилище</string>
|
<string name="external_storage">Внешнее хранилище</string>
|
||||||
<string name="domain">Домен</string>
|
<string name="domain">Домен</string>
|
||||||
<string name="application_update">Проверять наличие новых версий приложения</string>
|
<string name="application_update">Проверять наличие новых версий приложения</string>
|
||||||
<string name="app_update_available">Доступна новая версия приложения</string>
|
<string name="app_update_available">Доступна новая версия приложения</string>
|
||||||
<string name="show_notification_app_update">Показывать уведомление, если доступна новая версия</string>
|
<string name="show_notification_app_update">Показывать уведомление, если доступна новая версия</string>
|
||||||
<string name="open_in_browser">Открыть в веб-браузере</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="save_manga">Сохранить</string>
|
||||||
<string name="notifications">Уведомления</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="new_chapters">Новые главы</string>
|
||||||
<string name="download">Загрузить</string>
|
<string name="download">Загрузить</string>
|
||||||
<string name="read_from_start">Читать с начала</string>
|
<string name="read_from_start">Читать с начала</string>
|
||||||
<string name="restart">Перезапустить</string>
|
<string name="restart">Перезапустить</string>
|
||||||
<string name="notifications_settings">Настройки уведомлений</string>
|
<string name="notifications_settings">Настройки уведомлений</string>
|
||||||
<string name="notification_sound">Звук уведомления</string>
|
<string name="notification_sound">Звук уведомления</string>
|
||||||
<string name="light_indicator">Светодиодная индикация</string>
|
<string name="light_indicator">Светодиодная индикация</string>
|
||||||
<string name="vibration">Вибросигнал</string>
|
<string name="vibration">Вибросигнал</string>
|
||||||
<string name="favourites_categories">Категории избранного</string>
|
<string name="favourites_categories">Категории избранного</string>
|
||||||
<string name="categories_">Категории…</string>
|
<string name="categories_">Категории…</string>
|
||||||
<string name="rename">Переименовать</string>
|
<string name="rename">Переименовать</string>
|
||||||
<string name="category_delete_confirm">Удалить категорию \"%s\" из избранного\?
|
<string name="category_delete_confirm">Удалить категорию \"%s\" из избранного\?
|
||||||
\nВся манга в ней будет потеряна.</string>
|
\nВся манга в ней будет потеряна.</string>
|
||||||
<string name="remove_category">Удалить</string>
|
<string name="remove_category">Удалить</string>
|
||||||
<string name="text_empty_holder_primary">Как-то здесь пусто…</string>
|
<string name="text_empty_holder_primary">Как-то здесь пусто…</string>
|
||||||
<string name="text_search_holder_secondary">Попробуйте переформулировать запрос.</string>
|
<string name="text_search_holder_secondary">Попробуйте переформулировать запрос.</string>
|
||||||
<string name="text_categories_holder">Вы можете использовать категории для организации своих избранных. Нажмите «+», чтобы создать категорию</string>
|
<string name="text_categories_holder">Вы можете использовать категории для организации своих избранных. Нажмите «+», чтобы создать категорию</string>
|
||||||
<string name="text_history_holder_primary">То, что вы прочитаете, будет отображено здесь</string>
|
<string name="text_history_holder_primary">То, что вы прочитаете, будет отображено здесь</string>
|
||||||
<string name="text_history_holder_secondary">Найдите, что почитать, в боковом меню.</string>
|
<string name="text_history_holder_secondary">Найдите, что почитать, в боковом меню.</string>
|
||||||
<string name="text_local_holder_primary">Сохраните что-нибудь</string>
|
<string name="text_local_holder_primary">Сохраните что-нибудь</string>
|
||||||
<string name="text_local_holder_secondary">Сохраните что-нибудь из онлайн-каталога или импортируйте из файла.</string>
|
<string name="text_local_holder_secondary">Сохраните что-нибудь из онлайн-каталога или импортируйте из файла.</string>
|
||||||
<string name="manga_shelf">Полка</string>
|
<string name="manga_shelf">Полка</string>
|
||||||
<string name="recent_manga">Недавнее</string>
|
<string name="recent_manga">Недавнее</string>
|
||||||
<string name="pages_animation">Анимация листания</string>
|
<string name="pages_animation">Анимация листания</string>
|
||||||
<string name="manga_save_location">Папка для загрузок</string>
|
<string name="manga_save_location">Папка для загрузок</string>
|
||||||
<string name="not_available">Недоступно</string>
|
<string name="not_available">Недоступно</string>
|
||||||
<string name="cannot_find_available_storage">Нет доступного хранилища</string>
|
<string name="cannot_find_available_storage">Нет доступного хранилища</string>
|
||||||
<string name="other_storage">Другое хранилище</string>
|
<string name="other_storage">Другое хранилище</string>
|
||||||
<string name="done">Готово</string>
|
<string name="done">Готово</string>
|
||||||
<string name="all_favourites">Всё избранное</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="read_later">Прочитать позже</string>
|
||||||
<string name="updates">Обновления</string>
|
<string name="updates">Обновления</string>
|
||||||
<string name="text_feed_holder">Новые главы из того, что вы читаете, будут показаны здесь</string>
|
<string name="text_feed_holder">Новые главы из того, что вы читаете, будут показаны здесь</string>
|
||||||
<string name="search_results">Результаты поиска</string>
|
<string name="search_results">Результаты поиска</string>
|
||||||
<string name="related">Похожие</string>
|
<string name="related">Похожие</string>
|
||||||
<string name="new_version_s">Новая версия: %s</string>
|
<string name="new_version_s">Новая версия: %s</string>
|
||||||
<string name="size_s">Размер: %s</string>
|
<string name="size_s">Размер: %s</string>
|
||||||
<string name="waiting_for_network">Ожидание подключения…</string>
|
<string name="waiting_for_network">Ожидание подключения…</string>
|
||||||
<string name="clear_updates_feed">Очистить ленту обновлений</string>
|
<string name="clear_updates_feed">Очистить ленту обновлений</string>
|
||||||
<string name="updates_feed_cleared">Очищено</string>
|
<string name="updates_feed_cleared">Очищено</string>
|
||||||
<string name="rotate_screen">Повернуть экран</string>
|
<string name="rotate_screen">Повернуть экран</string>
|
||||||
<string name="update">Обновить</string>
|
<string name="update">Обновить</string>
|
||||||
<string name="feed_will_update_soon">Обновление скоро начнётся</string>
|
<string name="feed_will_update_soon">Обновление скоро начнётся</string>
|
||||||
<string name="track_sources">Следить за обновлениями</string>
|
<string name="track_sources">Следить за обновлениями</string>
|
||||||
<string name="dont_check">Не проверять</string>
|
<string name="dont_check">Не проверять</string>
|
||||||
<string name="enter_password">Введите пароль</string>
|
<string name="enter_password">Введите пароль</string>
|
||||||
<string name="wrong_password">Неверный пароль</string>
|
<string name="wrong_password">Неверный пароль</string>
|
||||||
<string name="protect_application">Защитить приложение</string>
|
<string name="protect_application">Защитить приложение</string>
|
||||||
<string name="protect_application_summary">Запрашивать пароль при запуске Kotatsu</string>
|
<string name="protect_application_summary">Запрашивать пароль при запуске Kotatsu</string>
|
||||||
<string name="repeat_password">Повторите пароль</string>
|
<string name="repeat_password">Повторите пароль</string>
|
||||||
<string name="passwords_mismatch">Пароли не совпадают</string>
|
<string name="passwords_mismatch">Пароли не совпадают</string>
|
||||||
<string name="about">О программе</string>
|
<string name="about">О программе</string>
|
||||||
<string name="app_version">Версия %s</string>
|
<string name="app_version">Версия %s</string>
|
||||||
<string name="check_for_updates">Проверить обновления</string>
|
<string name="check_for_updates">Проверить обновления</string>
|
||||||
<string name="checking_for_updates">Проверка обновления…</string>
|
<string name="checking_for_updates">Проверка обновления…</string>
|
||||||
<string name="update_check_failed">Не удалось проверить обновления</string>
|
<string name="update_check_failed">Не удалось проверить обновления</string>
|
||||||
<string name="no_update_available">Нет доступных обновлений</string>
|
<string name="no_update_available">Нет доступных обновлений</string>
|
||||||
<string name="right_to_left">Справа налево (←)</string>
|
<string name="right_to_left">Справа налево (←)</string>
|
||||||
<string name="create_category">Создать категорию</string>
|
<string name="create_category">Создать категорию</string>
|
||||||
<string name="scale_mode">Масштабирование</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_height">Подогнать по высоте</string>
|
||||||
<string name="zoom_mode_fit_width">Подогнать по ширине</string>
|
<string name="zoom_mode_fit_width">Подогнать по ширине</string>
|
||||||
<string name="zoom_mode_keep_start">Исходный размер</string>
|
<string name="zoom_mode_keep_start">Исходный размер</string>
|
||||||
<string name="black_dark_theme">Чёрная</string>
|
<string name="black_dark_theme">Чёрная</string>
|
||||||
<string name="black_dark_theme_summary">Потребляет меньше энергии на экранах AMOLED</string>
|
<string name="black_dark_theme_summary">Потребляет меньше энергии на экранах AMOLED</string>
|
||||||
<string name="backup_restore">Резервное копирование и восстановление</string>
|
<string name="backup_restore">Резервное копирование и восстановление</string>
|
||||||
<string name="create_backup">Создать резервную копию</string>
|
<string name="create_backup">Создать резервную копию</string>
|
||||||
<string name="restore_backup">Восстановить данные</string>
|
<string name="restore_backup">Восстановить данные</string>
|
||||||
<string name="data_restored">Восстановлено</string>
|
<string name="data_restored">Восстановлено</string>
|
||||||
<string name="preparing_">Подготовка…</string>
|
<string name="preparing_">Подготовка…</string>
|
||||||
<string name="file_not_found">Файл не найден</string>
|
<string name="file_not_found">Файл не найден</string>
|
||||||
<string name="data_restored_success">Все данные были восстановлены</string>
|
<string name="data_restored_success">Все данные были восстановлены</string>
|
||||||
<string name="data_restored_with_errors">Данные были восстановлены, но возникли некоторые ошибки</string>
|
<string name="data_restored_with_errors">Данные были восстановлены, но возникли некоторые ошибки</string>
|
||||||
<string name="backup_information">Вы можете создать резервную копию избранного и истории и потом восстановить их</string>
|
<string name="backup_information">Вы можете создать резервную копию избранного и истории и потом восстановить их</string>
|
||||||
<string name="just_now">Только что</string>
|
<string name="just_now">Только что</string>
|
||||||
<string name="yesterday">Вчера</string>
|
<string name="yesterday">Вчера</string>
|
||||||
<string name="long_ago">Давно</string>
|
<string name="long_ago">Давно</string>
|
||||||
<string name="group">Группировать</string>
|
<string name="group">Группировать</string>
|
||||||
<string name="today">Сегодня</string>
|
<string name="today">Сегодня</string>
|
||||||
<string name="tap_to_try_again">Попробовать ещё раз</string>
|
<string name="tap_to_try_again">Попробовать ещё раз</string>
|
||||||
<string name="reader_mode_hint">Выбранный режим будет сохранён для текущей манги</string>
|
<string name="reader_mode_hint">Выбранный режим будет сохранён для текущей манги</string>
|
||||||
<string name="silent">Без звука</string>
|
<string name="silent">Без звука</string>
|
||||||
<string name="captcha_required">Необходимо пройти CAPTCHA</string>
|
<string name="captcha_required">Необходимо пройти CAPTCHA</string>
|
||||||
<string name="captcha_solve">Пройти</string>
|
<string name="captcha_solve">Пройти</string>
|
||||||
<string name="clear_cookies">Очистить куки</string>
|
<string name="clear_cookies">Очистить куки</string>
|
||||||
<string name="cookies_cleared">Все файлы cookie были удалены</string>
|
<string name="cookies_cleared">Все файлы cookie были удалены</string>
|
||||||
<string name="chapters_checking_progress">Проверка новых глав: %1$d из %2$d</string>
|
<string name="chapters_checking_progress">Проверка новых глав: %1$d из %2$d</string>
|
||||||
<string name="clear_feed">Очистить ленту</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="check_for_new_chapters">Проверка новых глав</string>
|
||||||
<string name="reverse">В обратном порядке</string>
|
<string name="reverse">В обратном порядке</string>
|
||||||
<string name="sign_in">Войти</string>
|
<string name="sign_in">Войти</string>
|
||||||
<string name="auth_required">Авторизуйтесь, чтобы просмотреть этот контент</string>
|
<string name="auth_required">Авторизуйтесь, чтобы просмотреть этот контент</string>
|
||||||
<string name="default_s">По умолчанию: %s</string>
|
<string name="default_s">По умолчанию: %s</string>
|
||||||
<string name="_and_x_more">…и ещё %1$d</string>
|
<string name="_and_x_more">…и ещё %1$d</string>
|
||||||
<string name="next">Далее</string>
|
<string name="next">Далее</string>
|
||||||
<string name="protect_application_subtitle">Введите пароль для запуска приложения</string>
|
<string name="protect_application_subtitle">Введите пароль для запуска приложения</string>
|
||||||
<string name="confirm">Подтвердить</string>
|
<string name="confirm">Подтвердить</string>
|
||||||
<string name="password_length_hint">Пароль должен состоять из 4 символов или более</string>
|
<string name="password_length_hint">Пароль должен состоять из 4 символов или более</string>
|
||||||
<string name="search_only_on_s">Поиск только по %s</string>
|
<string name="search_only_on_s">Поиск только по %s</string>
|
||||||
<string name="other">Другие</string>
|
<string name="other">Другие</string>
|
||||||
<string name="welcome">Добро пожаловать</string>
|
<string name="welcome">Добро пожаловать</string>
|
||||||
<string name="text_clear_search_history_prompt">Удалить все последние поисковые запросы навсегда\?</string>
|
<string name="text_clear_search_history_prompt">Удалить все последние поисковые запросы навсегда\?</string>
|
||||||
<string name="backup_saved">Резервная копия сохранена</string>
|
<string name="backup_saved">Резервная копия сохранена</string>
|
||||||
<string name="tracker_warning">Некоторые устройства имеют различное поведение системы, что может привести к нарушению фоновых задач.</string>
|
<string name="tracker_warning">Некоторые устройства имеют различное поведение системы, что может привести к нарушению фоновых задач.</string>
|
||||||
<string name="read_more">Подробнее</string>
|
<string name="read_more">Подробнее</string>
|
||||||
<string name="queued">В очереди</string>
|
<string name="queued">В очереди</string>
|
||||||
<string name="text_downloads_holder">Нет активных загрузок</string>
|
<string name="text_downloads_holder">Нет активных загрузок</string>
|
||||||
<string name="chapter_is_missing">Глава отсутствует</string>
|
<string name="chapter_is_missing">Глава отсутствует</string>
|
||||||
<string name="chapter_is_missing_text">Скачайте или прочитайте эту недостающую главу онлайн.</string>
|
<string name="chapter_is_missing_text">Скачайте или прочитайте эту недостающую главу онлайн.</string>
|
||||||
<string name="about_app_translation_summary">Помочь с переводом приложения</string>
|
<string name="about_app_translation_summary">Помочь с переводом приложения</string>
|
||||||
<string name="about_app_translation">Перевод</string>
|
<string name="about_app_translation">Перевод</string>
|
||||||
<string name="about_feedback_4pda">Тема на 4PDA</string>
|
<string name="about_feedback_4pda">Тема на 4PDA</string>
|
||||||
<string name="about_feedback">Обратная связь</string>
|
<string name="about_feedback">Обратная связь</string>
|
||||||
<string name="auth_complete">Авторизация выполнена</string>
|
<string name="auth_complete">Авторизация выполнена</string>
|
||||||
<string name="auth_not_supported_by">Вход в %s не поддерживается</string>
|
<string name="auth_not_supported_by">Вход в %s не поддерживается</string>
|
||||||
<string name="text_clear_cookies_prompt">Вы выйдете из всех источников</string>
|
<string name="text_clear_cookies_prompt">Вы выйдете из всех источников</string>
|
||||||
<string name="genres">Жанры</string>
|
<string name="genres">Жанры</string>
|
||||||
<string name="state_finished">Завершено</string>
|
<string name="state_finished">Завершено</string>
|
||||||
<string name="state_ongoing">Онгоинг</string>
|
<string name="state_ongoing">Онгоинг</string>
|
||||||
<string name="date_format">Формат даты</string>
|
<string name="date_format">Формат даты</string>
|
||||||
<string name="system_default">По умолчанию</string>
|
<string name="system_default">По умолчанию</string>
|
||||||
<string name="exclude_nsfw_from_history">Исключить NSFW мангу из истории</string>
|
<string name="exclude_nsfw_from_history">Исключить NSFW мангу из истории</string>
|
||||||
<string name="error_empty_name">Вы должны ввести имя</string>
|
<string name="error_empty_name">Вы должны ввести имя</string>
|
||||||
<string name="show_pages_numbers">Показывать номера страницы</string>
|
<string name="show_pages_numbers">Показывать номера страницы</string>
|
||||||
<string name="enabled_sources">Включенные источники</string>
|
<string name="enabled_sources">Включенные источники</string>
|
||||||
<string name="available_sources">Доступные источники</string>
|
<string name="available_sources">Доступные источники</string>
|
||||||
<string name="dynamic_theme">Динамическая тема</string>
|
<string name="dynamic_theme">Динамическая тема</string>
|
||||||
<string name="dynamic_theme_summary">Применяет тему приложения, основанную на цветовой палитре обоев на устройстве</string>
|
<string name="dynamic_theme_summary">Применяет тему приложения, основанную на цветовой палитре обоев на устройстве</string>
|
||||||
<string name="screenshots_policy">Политика скриншотов</string>
|
<string name="screenshots_policy">Политика скриншотов</string>
|
||||||
<string name="screenshots_allow">Разрешить</string>
|
<string name="screenshots_allow">Разрешить</string>
|
||||||
<string name="screenshots_block_nsfw">Запретить для NSFW</string>
|
<string name="screenshots_block_nsfw">Запретить для NSFW</string>
|
||||||
<string name="screenshots_block_all">Всегда блокировать</string>
|
<string name="screenshots_block_all">Всегда блокировать</string>
|
||||||
<string name="suggestions">Рекомендации</string>
|
<string name="suggestions">Рекомендации</string>
|
||||||
<string name="suggestions_enable">Включить рекомендации</string>
|
<string name="suggestions_enable">Включить рекомендации</string>
|
||||||
<string name="suggestions_summary">Предлагать мангу на основе Ваших предпочтений</string>
|
<string name="suggestions_summary">Предлагать мангу на основе Ваших предпочтений</string>
|
||||||
<string name="suggestions_info">Все данные анализируются локально на устройстве. Ваши персональные данные не передаются в какие-либо сервисы</string>
|
<string name="suggestions_info">Все данные анализируются локально на устройстве. Ваши персональные данные не передаются в какие-либо сервисы</string>
|
||||||
<string name="text_suggestion_holder">Начните читать мангу, чтобы получать персональные предложения</string>
|
<string name="text_suggestion_holder">Начните читать мангу, чтобы получать персональные предложения</string>
|
||||||
<string name="exclude_nsfw_from_suggestions">Не предлагать NSFW мангу</string>
|
<string name="exclude_nsfw_from_suggestions">Не предлагать NSFW мангу</string>
|
||||||
<string name="enabled">Включено</string>
|
<string name="enabled">Включено</string>
|
||||||
<string name="disabled">Выключено</string>
|
<string name="disabled">Выключено</string>
|
||||||
<string name="filter_load_error">Не удалось загрузить список жанров</string>
|
<string name="filter_load_error">Не удалось загрузить список жанров</string>
|
||||||
<string name="computing_">Вычисление…</string>
|
<string name="computing_">Вычисление…</string>
|
||||||
<string name="report_github">Создать проблему на GitHub</string>
|
<string name="report_github">Создать проблему на GitHub</string>
|
||||||
<string name="importing_progress">Импорт манги: %1$d из %2$d</string>
|
<string name="importing_progress">Импорт манги: %1$d из %2$d</string>
|
||||||
<string name="reset_filter">Сбросить фильтр</string>
|
<string name="reset_filter">Сбросить фильтр</string>
|
||||||
<string name="find_genre">Поиск по жанрам</string>
|
<string name="find_genre">Поиск по жанрам</string>
|
||||||
<string name="onboard_text">Выберите языки, на которых Вы хоите читать мангу. Это можно будет изменить позже в настройках.</string>
|
<string name="onboard_text">Выберите языки, на которых Вы хоите читать мангу. Это можно будет изменить позже в настройках.</string>
|
||||||
<string name="never">Никогда</string>
|
<string name="never">Никогда</string>
|
||||||
<string name="only_using_wifi">Только по Wi-Fi</string>
|
<string name="only_using_wifi">Только по Wi-Fi</string>
|
||||||
<string name="always">Всегда</string>
|
<string name="always">Всегда</string>
|
||||||
<string name="preload_pages">Предварительная загрузка страниц</string>
|
<string name="preload_pages">Предварительная загрузка страниц</string>
|
||||||
<string name="logged_in_as">Вы авторизованы как %s</string>
|
<string name="logged_in_as">Вы авторизованы как %s</string>
|
||||||
<string name="nsfw">18+</string>
|
<string name="nsfw">18+</string>
|
||||||
<string name="various_languages">Разные языки</string>
|
<string name="various_languages">Разные языки</string>
|
||||||
<string name="search_chapters">Найти главу</string>
|
<string name="search_chapters">Найти главу</string>
|
||||||
<string name="chapters_empty">В этой манге нет глав</string>
|
<string name="chapters_empty">В этой манге нет глав</string>
|
||||||
<string name="appearance">Оформление</string>
|
<string name="appearance">Оформление</string>
|
||||||
<string name="content">Контент</string>
|
<string name="content">Контент</string>
|
||||||
<string name="suggestions_updating">Обновление рекомендаций</string>
|
<string name="suggestions_updating">Обновление рекомендаций</string>
|
||||||
<string name="suggestions_excluded_genres">Исключить жанры</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="text_delete_local_manga_batch">Удалить выбранную мангу с накопителя?</string>
|
||||||
<string name="removal_completed">Удаление завершено</string>
|
<string name="removal_completed">Удаление завершено</string>
|
||||||
<string name="batch_manga_save_confirm">Загрузить выбранную мангу со всеми главами? Это может привести к большому расходу трафика и места на накопителе</string>
|
<string name="batch_manga_save_confirm">Загрузить выбранную мангу со всеми главами? Это может привести к большому расходу трафика и места на накопителе</string>
|
||||||
<string name="parallel_downloads">Загружать параллельно</string>
|
<string name="parallel_downloads">Загружать параллельно</string>
|
||||||
<string name="download_slowdown">Замедление загрузки</string>
|
<string name="download_slowdown">Замедление загрузки</string>
|
||||||
<string name="download_slowdown_summary">Помогает избежать блокировки IP-адреса</string>
|
<string name="download_slowdown_summary">Помогает избежать блокировки IP-адреса</string>
|
||||||
<string name="local_manga_processing">Обработка сохранённой манги</string>
|
<string name="local_manga_processing">Обработка сохранённой манги</string>
|
||||||
<string name="chapters_will_removed_background">Главы будут удалены в фоновом режиме. Это может занять какое-то время</string>
|
<string name="chapters_will_removed_background">Главы будут удалены в фоновом режиме. Это может занять какое-то время</string>
|
||||||
<string name="hide">Скрыть</string>
|
<string name="hide">Скрыть</string>
|
||||||
<string name="new_sources_text">Доступны новые источники манги</string>
|
<string name="new_sources_text">Доступны новые источники манги</string>
|
||||||
<string name="check_new_chapters_title">Проверять новые главы и уведомлять о них</string>
|
<string name="check_new_chapters_title">Проверять новые главы и уведомлять о них</string>
|
||||||
<string name="show_notification_new_chapters_on">Вы будете получать уведомления об обновлении манги, которую Вы читаете</string>
|
<string name="show_notification_new_chapters_on">Вы будете получать уведомления об обновлении манги, которую Вы читаете</string>
|
||||||
<string name="show_notification_new_chapters_off">Вы не будете получать уведомления, но новые главы будут отображаться в списке</string>
|
<string name="show_notification_new_chapters_off">Вы не будете получать уведомления, но новые главы будут отображаться в списке</string>
|
||||||
<string name="notifications_enable">Включить уведомления</string>
|
<string name="notifications_enable">Включить уведомления</string>
|
||||||
<string name="name">Название</string>
|
<string name="name">Название</string>
|
||||||
<string name="edit">Изменить</string>
|
<string name="edit">Изменить</string>
|
||||||
<string name="edit_category">Изменить категорию</string>
|
<string name="edit_category">Изменить категорию</string>
|
||||||
<string name="tracking">Отслеживание</string>
|
<string name="tracking">Отслеживание</string>
|
||||||
<string name="empty_favourite_categories">Нет категорий избранного</string>
|
<string name="empty_favourite_categories">Нет категорий избранного</string>
|
||||||
<string name="bookmark_add">Добавить закладку</string>
|
<string name="bookmark_add">Добавить закладку</string>
|
||||||
<string name="bookmark_remove">Удалить закладку</string>
|
<string name="bookmark_remove">Удалить закладку</string>
|
||||||
<string name="bookmarks">Закладки</string>
|
<string name="bookmarks">Закладки</string>
|
||||||
<string name="bookmark_removed">Закладка удалена</string>
|
<string name="bookmark_removed">Закладка удалена</string>
|
||||||
<string name="bookmark_added">Закладка добавлена</string>
|
<string name="bookmark_added">Закладка добавлена</string>
|
||||||
<string name="undo">Отменить</string>
|
<string name="undo">Отменить</string>
|
||||||
<string name="removed_from_history">Удалено из истории</string>
|
<string name="removed_from_history">Удалено из истории</string>
|
||||||
<string name="dns_over_https">DNS через HTTPS</string>
|
<string name="dns_over_https">DNS через HTTPS</string>
|
||||||
<string name="default_mode">Режим по умолчанию</string>
|
<string name="default_mode">Режим по умолчанию</string>
|
||||||
<string name="detect_reader_mode">Автоопределение режима чтения</string>
|
<string name="detect_reader_mode">Автоопределение режима чтения</string>
|
||||||
<string name="detect_reader_mode_summary">Автоматически определяет, является ли манга веб-комиксом</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="disable_battery_optimization_summary">Помогает с фоновой проверкой обновлений</string>
|
||||||
<string name="crash_text">Что-то пошло не так. Пожалуйста, отправьте отчёт разработчикам, чтобы помочь всё исправить</string>
|
<string name="crash_text">Что-то пошло не так. Пожалуйста, отправьте отчёт разработчикам, чтобы помочь всё исправить</string>
|
||||||
<string name="send">Отправить</string>
|
<string name="send">Отправить</string>
|
||||||
<string name="disable_all">Отключить все</string>
|
<string name="disable_all">Отключить все</string>
|
||||||
<string name="use_fingerprint">Использовать отпечаток пальца, если доступно</string>
|
<string name="use_fingerprint">Использовать отпечаток пальца, если доступно</string>
|
||||||
<string name="appwidget_shelf_description">Манга из Вашего избранного</string>
|
<string name="appwidget_shelf_description">Манга из Вашего избранного</string>
|
||||||
<string name="appwidget_recent_description">Манга, которую Вы недавно читали</string>
|
<string name="appwidget_recent_description">Манга, которую Вы недавно читали</string>
|
||||||
|
<string name="status_reading">Читаю</string>
|
||||||
|
<string name="status_planned">Запланировано</string>
|
||||||
|
<string name="status_on_hold">Отложено</string>
|
||||||
|
<string name="status_dropped">Заброшено</string>
|
||||||
|
<string name="status_completed">Завершено</string>
|
||||||
|
<string name="show_reading_indicators_summary">Показать процент прочитанного в истории и избранном</string>
|
||||||
|
<string name="exclude_nsfw_from_history_summary">Манга, помеченная как NSFW, никогда не будет добавлена в историю и ваш прогресс чтения не будет сохранен</string>
|
||||||
|
<string name="percent_string_pattern">%1$s%%</string>
|
||||||
|
<string name="report">Отчёт</string>
|
||||||
|
<string name="logout">Выйти</string>
|
||||||
|
<string name="status_re_reading">Перечитываю</string>
|
||||||
|
<string name="show_reading_indicators">Показать индикаторы прогресса чтения</string>
|
||||||
|
<string name="data_deletion">Удаление данных</string>
|
||||||
|
<string name="clear_cookies_summary">Может помочь в случае каких-либо проблем. Все авторизации будут аннулированы</string>
|
||||||
|
<string name="show_all">Показать все</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
Kotatsu is a free and open source manga reader for Android.<br>
|
Kotatsu is a free and open source manga reader for Android.
|
||||||
|
|
||||||
|
|
||||||
**Main Features:**
|
**Main Features:**
|
||||||
|
|
||||||
- Online manga catalogues
|
- Online manga catalogues
|
||||||
@@ -9,5 +11,5 @@ Kotatsu is a free and open source manga reader for Android.<br>
|
|||||||
- Tablet-optimized material design UI
|
- Tablet-optimized material design UI
|
||||||
- Standard and Webtoon-optimized reader
|
- Standard and Webtoon-optimized reader
|
||||||
- Notifications about new chapters with updates feed
|
- Notifications about new chapters with updates feed
|
||||||
- Available in multiple languages
|
- Shikimori integration (manga tracking)
|
||||||
- Password protect access to the app
|
- Password/fingerprint protect access to the app
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
Kotatsu - приложения для чтения манги с открытым исходным кодом.<br>
|
Kotatsu - приложения для чтения манги с открытым исходным кодом.
|
||||||
|
|
||||||
|
|
||||||
**Основные возможности:**
|
**Основные возможности:**
|
||||||
|
|
||||||
- Онлайн каталоги с мангой
|
- Онлайн каталоги с мангой
|
||||||
@@ -9,3 +11,5 @@ Kotatsu - приложения для чтения манги с открыты
|
|||||||
- Интерфейс также оптимизирован для планшетов
|
- Интерфейс также оптимизирован для планшетов
|
||||||
- Поддержка манхвы (Webtoon)
|
- Поддержка манхвы (Webtoon)
|
||||||
- Уведомления о новых главах и лента обновлений
|
- Уведомления о новых главах и лента обновлений
|
||||||
|
- Интеграция с Shikimori
|
||||||
|
- Защита доступа в приложение паролем/отпечатком пальца
|
||||||
|
|||||||
Reference in New Issue
Block a user