Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 759fd4d4e3 | |||
| fc956fc791 | |||
| 9d7346157b | |||
| 0f0f4cf4a9 | |||
| 426ef65102 | |||
| 95c834581b | |||
| 71f2daf8f3 |
@@ -212,10 +212,6 @@ dependencies {
|
||||
// Disk
|
||||
implementation(libs.disklrucache)
|
||||
implementation(libs.unifile)
|
||||
implementation(libs.bundles.archive)
|
||||
// SY -->
|
||||
implementation(libs.zip4j)
|
||||
// SY <--
|
||||
|
||||
// Preferences
|
||||
implementation(libs.preferencektx)
|
||||
|
||||
Vendored
-3
@@ -127,9 +127,6 @@
|
||||
# XmlUtil
|
||||
-keep public enum nl.adaptivity.xmlutil.EventType { *; }
|
||||
|
||||
# Apache Commons Compress
|
||||
-keep class * extends org.apache.commons.compress.archivers.zip.ZipExtraField { <init>(); }
|
||||
|
||||
# Firebase
|
||||
-keep class com.google.firebase.installations.** { *; }
|
||||
-keep interface com.google.firebase.installations.** { *; }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package eu.kanade.tachiyomi.data.coil
|
||||
|
||||
import android.app.Application
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import coil3.ImageLoader
|
||||
@@ -11,37 +12,37 @@ import coil3.decode.ImageSource
|
||||
import coil3.fetch.SourceFetchResult
|
||||
import coil3.request.Options
|
||||
import coil3.request.bitmapConfig
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto.getCoverStream
|
||||
import eu.kanade.tachiyomi.util.system.GLUtil
|
||||
import net.lingala.zip4j.ZipFile
|
||||
import net.lingala.zip4j.model.FileHeader
|
||||
import mihon.core.common.archive.archiveReader
|
||||
import okio.BufferedSource
|
||||
import tachiyomi.core.common.util.system.ImageUtil
|
||||
import tachiyomi.decoder.ImageDecoder
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.BufferedInputStream
|
||||
|
||||
/**
|
||||
* A [Decoder] that uses built-in [ImageDecoder] to decode images that is not supported by the system.
|
||||
*/
|
||||
class TachiyomiImageDecoder(private val resources: ImageSource, private val options: Options) : Decoder {
|
||||
private val context = Injekt.get<Application>()
|
||||
|
||||
override suspend fun decode(): DecodeResult {
|
||||
// SY -->
|
||||
var zip4j: ZipFile? = null
|
||||
var entry: FileHeader? = null
|
||||
|
||||
var coverStream: BufferedInputStream? = null
|
||||
if (resources.sourceOrNull()?.peek()?.use { CbzCrypto.detectCoverImageArchive(it.inputStream()) } == true) {
|
||||
if (resources.source().peek().use { ImageUtil.findImageType(it.inputStream()) == null }) {
|
||||
zip4j = ZipFile(resources.file().toFile().absolutePath)
|
||||
entry = zip4j.fileHeaders.firstOrNull {
|
||||
it.fileName.equals(CbzCrypto.DEFAULT_COVER_NAME, ignoreCase = true)
|
||||
}
|
||||
|
||||
if (zip4j.isEncrypted) zip4j.setPassword(CbzCrypto.getDecryptedPasswordCbz())
|
||||
coverStream = UniFile.fromFile(resources.file().toFile())
|
||||
?.archiveReader(context = context)
|
||||
?.getCoverStream()
|
||||
}
|
||||
}
|
||||
val decoder = resources.sourceOrNull()?.use {
|
||||
zip4j.use { zipFile ->
|
||||
ImageDecoder.newInstance(zipFile?.getInputStream(entry) ?: it.inputStream(), options.cropBorders, displayProfile)
|
||||
coverStream.use { coverStream ->
|
||||
ImageDecoder.newInstance(coverStream ?: it.inputStream(), options.cropBorders, displayProfile)
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
|
||||
@@ -44,10 +44,10 @@ import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import logcat.LogPriority
|
||||
import mihon.core.common.archive.ZipWriter
|
||||
import nl.adaptivity.xmlutil.serialization.XML
|
||||
import okhttp3.Response
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.storage.addFilesToZip
|
||||
import tachiyomi.core.common.storage.extension
|
||||
import tachiyomi.core.common.util.lang.launchIO
|
||||
import tachiyomi.core.common.util.lang.launchNow
|
||||
@@ -65,12 +65,8 @@ import tachiyomi.domain.track.interactor.GetTracks
|
||||
import tachiyomi.i18n.MR
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import java.util.zip.CRC32
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
/**
|
||||
* This class is the one in charge of downloading chapters.
|
||||
@@ -619,70 +615,19 @@ class Downloader(
|
||||
tmpDir: UniFile,
|
||||
) {
|
||||
// SY -->
|
||||
if (CbzCrypto.getPasswordProtectDlPref() && CbzCrypto.isPasswordSet()) {
|
||||
archiveEncryptedChapter(mangaDir, dirname, tmpDir)
|
||||
return
|
||||
}
|
||||
val encrypt = CbzCrypto.getPasswordProtectDlPref() && CbzCrypto.isPasswordSet()
|
||||
// SY <--
|
||||
|
||||
val zip = mangaDir.createFile("$dirname.cbz$TMP_DIR_SUFFIX")!!
|
||||
ZipOutputStream(BufferedOutputStream(zip.openOutputStream())).use { zipOut ->
|
||||
zipOut.setMethod(ZipEntry.STORED)
|
||||
|
||||
tmpDir.listFiles()?.forEach { img ->
|
||||
img.openInputStream().use { input ->
|
||||
val data = input.readBytes()
|
||||
val size = img.length()
|
||||
val entry = ZipEntry(img.name).apply {
|
||||
val crc = CRC32().apply {
|
||||
update(data)
|
||||
}
|
||||
setCrc(crc.value)
|
||||
|
||||
compressedSize = size
|
||||
setSize(size)
|
||||
}
|
||||
zipOut.putNextEntry(entry)
|
||||
zipOut.write(data)
|
||||
}
|
||||
ZipWriter(context, zip, /* SY --> */ encrypt /* SY <-- */).use { writer ->
|
||||
tmpDir.listFiles()?.forEach { file ->
|
||||
writer.write(file)
|
||||
}
|
||||
}
|
||||
zip.renameTo("$dirname.cbz")
|
||||
tmpDir.delete()
|
||||
}
|
||||
|
||||
// SY -->
|
||||
|
||||
private fun archiveEncryptedChapter(
|
||||
mangaDir: UniFile,
|
||||
dirname: String,
|
||||
tmpDir: UniFile,
|
||||
) {
|
||||
tmpDir.filePath?.let { addPaddingToImage(File(it)) }
|
||||
|
||||
tmpDir.listFiles()?.toList()?.let { files ->
|
||||
mangaDir.createFile("$dirname.cbz$TMP_DIR_SUFFIX")
|
||||
?.addFilesToZip(files, CbzCrypto.getDecryptedPasswordCbz())
|
||||
}
|
||||
|
||||
mangaDir.findFile("$dirname.cbz$TMP_DIR_SUFFIX")?.renameTo("$dirname.cbz")
|
||||
tmpDir.delete()
|
||||
}
|
||||
|
||||
private fun addPaddingToImage(imageDir: File) {
|
||||
imageDir.listFiles()
|
||||
// using ImageUtils isImage and findImageType functions causes IO errors when deleting files to set Exif Metadata
|
||||
// it should be safe to assume that all files with image extensions are actual images at this point
|
||||
?.filter {
|
||||
it.extension.equals("jpg", true) ||
|
||||
it.extension.equals("jpeg", true) ||
|
||||
it.extension.equals("png", true) ||
|
||||
it.extension.equals("webp", true)
|
||||
}
|
||||
?.forEach { ImageUtil.addPaddingToImageExif(it) }
|
||||
}
|
||||
// SY <--
|
||||
|
||||
/**
|
||||
* Creates a ComicInfo.xml file inside the given directory.
|
||||
*/
|
||||
|
||||
@@ -707,7 +707,12 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||
it.chapterNumber.toFloat() == readerChapter.chapter.chapter_number
|
||||
}
|
||||
.ifEmpty { null }
|
||||
?.also { setReadStatus.await(true, *it.toTypedArray()) }
|
||||
?.also {
|
||||
setReadStatus.await(true, *it.toTypedArray())
|
||||
it.forEach { chapter ->
|
||||
deleteChapterIfNeeded(ReaderChapter(chapter))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (manga?.isEhBasedManga() == true) {
|
||||
viewModelScope.launchNonCancellable {
|
||||
|
||||
+32
-65
@@ -1,9 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.reader.loader
|
||||
|
||||
import android.app.Application
|
||||
import android.os.Build
|
||||
import com.github.junrar.Archive
|
||||
import com.github.junrar.rarfile.FileHeader
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
@@ -16,80 +13,69 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import tachiyomi.core.common.storage.UniFileTempFileManager
|
||||
import mihon.core.common.archive.ArchiveReader
|
||||
import tachiyomi.core.common.util.system.ImageUtil
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.PipedInputStream
|
||||
import java.io.PipedOutputStream
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* Loader used to load a chapter from a .rar or .cbr file.
|
||||
* Loader used to load a chapter from an archive file.
|
||||
*/
|
||||
internal class RarPageLoader(file: UniFile) : PageLoader() {
|
||||
|
||||
internal class ArchivePageLoader(private val reader: ArchiveReader) : PageLoader() {
|
||||
// SY -->
|
||||
private val tempFileManager: UniFileTempFileManager by injectLazy()
|
||||
|
||||
private val rar = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
Archive(tempFileManager.createTempFile(file))
|
||||
} else {
|
||||
Archive(file.openInputStream())
|
||||
}
|
||||
|
||||
private val mutex = Mutex()
|
||||
private val context: Application by injectLazy()
|
||||
private val readerPreferences: ReaderPreferences by injectLazy()
|
||||
private val tmpDir = File(context.externalCacheDir, "reader_${file.hashCode()}").also {
|
||||
private val tmpDir = File(context.externalCacheDir, "reader_${reader.archiveHashCode}").also {
|
||||
it.deleteRecursively()
|
||||
}
|
||||
|
||||
init {
|
||||
reader.wrongPassword?.let { wrongPassword ->
|
||||
if (wrongPassword) {
|
||||
error("Incorrect archive password")
|
||||
}
|
||||
}
|
||||
if (readerPreferences.archiveReaderMode().get() == ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK) {
|
||||
tmpDir.mkdirs()
|
||||
rar.fileHeaders.asSequence()
|
||||
.filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { rar.getInputStream(it) } }
|
||||
.sortedWith { f1, f2 -> f1.fileName.compareToCaseInsensitiveNaturalOrder(f2.fileName) }
|
||||
.forEach { header ->
|
||||
File(tmpDir, header.fileName.substringAfterLast("/"))
|
||||
.also { it.createNewFile() }
|
||||
.outputStream()
|
||||
.use { output ->
|
||||
rar.getInputStream(header).use { input ->
|
||||
input.copyTo(output)
|
||||
reader.useEntries { entries ->
|
||||
entries
|
||||
.filter { it.isFile && ImageUtil.isImage(it.name) { reader.getInputStream(it.name)!! } }
|
||||
.sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }
|
||||
.forEach { entry ->
|
||||
File(tmpDir, entry.name.substringAfterLast("/"))
|
||||
.also { it.createNewFile() }
|
||||
.outputStream()
|
||||
.use { output ->
|
||||
reader.getInputStream(entry.name)?.use { input ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
|
||||
override var isLocal: Boolean = true
|
||||
|
||||
/**
|
||||
* Pool for copying compressed files to an input stream.
|
||||
*/
|
||||
private val pool = Executors.newFixedThreadPool(1)
|
||||
|
||||
override suspend fun getPages(): List<ReaderPage> {
|
||||
override suspend fun getPages(): List<ReaderPage> = reader.useEntries { entries ->
|
||||
// SY -->
|
||||
if (readerPreferences.archiveReaderMode().get() == ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK) {
|
||||
return DirectoryPageLoader(UniFile.fromFile(tmpDir)!!).getPages()
|
||||
}
|
||||
val mutex = Mutex()
|
||||
// SY <--
|
||||
return rar.fileHeaders.asSequence()
|
||||
.filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { rar.getInputStream(it) } }
|
||||
.sortedWith { f1, f2 -> f1.fileName.compareToCaseInsensitiveNaturalOrder(f2.fileName) }
|
||||
.mapIndexed { i, header ->
|
||||
entries
|
||||
.filter { it.isFile && ImageUtil.isImage(it.name) { reader.getInputStream(it.name)!! } }
|
||||
.sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }
|
||||
.mapIndexed { i, entry ->
|
||||
// SY -->
|
||||
val imageBytesDeferred: Deferred<ByteArray>? =
|
||||
when (readerPreferences.archiveReaderMode().get()) {
|
||||
ReaderPreferences.ArchiveReaderMode.LOAD_INTO_MEMORY -> {
|
||||
CoroutineScope(Dispatchers.IO).async {
|
||||
mutex.withLock {
|
||||
getStream(header).buffered().use { stream ->
|
||||
reader.getInputStream(entry.name)!!.buffered().use { stream ->
|
||||
stream.readBytes()
|
||||
}
|
||||
}
|
||||
@@ -98,12 +84,11 @@ internal class RarPageLoader(file: UniFile) : PageLoader() {
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
val imageBytes by lazy { runBlocking { imageBytesDeferred?.await() } }
|
||||
// SY <--
|
||||
ReaderPage(i).apply {
|
||||
// SY -->
|
||||
stream = { imageBytes?.copyOf()?.inputStream() ?: getStream(header) }
|
||||
stream = { imageBytes?.copyOf()?.inputStream() ?: reader.getInputStream(entry.name)!! }
|
||||
// SY <--
|
||||
status = Page.State.READY
|
||||
}
|
||||
@@ -117,27 +102,9 @@ internal class RarPageLoader(file: UniFile) : PageLoader() {
|
||||
|
||||
override fun recycle() {
|
||||
super.recycle()
|
||||
rar.close()
|
||||
reader.close()
|
||||
// SY -->
|
||||
tmpDir.deleteRecursively()
|
||||
// SY <--
|
||||
pool.shutdown()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream for the given [header].
|
||||
*/
|
||||
private fun getStream(header: FileHeader): InputStream {
|
||||
val pipeIn = PipedInputStream()
|
||||
val pipeOut = PipedOutputStream(pipeIn)
|
||||
pool.execute {
|
||||
try {
|
||||
pipeOut.use {
|
||||
rar.extractFile(header, it)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
return pipeIn
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.reader.loader
|
||||
|
||||
import android.content.Context
|
||||
import com.github.junrar.exception.UnsupportedRarV5Exception
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.DownloadProvider
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
@@ -9,6 +8,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.all.MergedSource
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import mihon.core.common.archive.archiveReader
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.util.lang.withIOContext
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
@@ -124,34 +124,26 @@ class ChapterLoader(
|
||||
source is LocalSource -> source.getFormat(chapter.chapter).let { format ->
|
||||
when (format) {
|
||||
is Format.Directory -> DirectoryPageLoader(format.file)
|
||||
is Format.Zip -> ZipPageLoader(format.file, context)
|
||||
is Format.Rar -> try {
|
||||
RarPageLoader(format.file)
|
||||
} catch (e: UnsupportedRarV5Exception) {
|
||||
error(context.stringResource(MR.strings.loader_rar5_error))
|
||||
}
|
||||
is Format.Epub -> EpubPageLoader(format.file, context)
|
||||
is Format.Archive -> ArchivePageLoader(format.file.archiveReader(context))
|
||||
is Format.Epub -> EpubPageLoader(format.file.archiveReader(context))
|
||||
}
|
||||
}
|
||||
else -> error(context.stringResource(MR.strings.loader_not_implemented_error))
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
isDownloaded -> DownloadPageLoader(chapter, manga, source, downloadManager, downloadProvider)
|
||||
isDownloaded -> DownloadPageLoader(
|
||||
chapter,
|
||||
manga,
|
||||
source,
|
||||
downloadManager,
|
||||
downloadProvider,
|
||||
)
|
||||
source is LocalSource -> source.getFormat(chapter.chapter).let { format ->
|
||||
when (format) {
|
||||
is Format.Directory -> DirectoryPageLoader(format.file)
|
||||
// SY -->
|
||||
is Format.Zip -> ZipPageLoader(format.file, context)
|
||||
is Format.Rar -> try {
|
||||
RarPageLoader(format.file)
|
||||
// SY <--
|
||||
} catch (e: UnsupportedRarV5Exception) {
|
||||
error(context.stringResource(MR.strings.loader_rar5_error))
|
||||
}
|
||||
// SY -->
|
||||
is Format.Epub -> EpubPageLoader(format.file, context)
|
||||
// SY <--
|
||||
is Format.Archive -> ArchivePageLoader(format.file.archiveReader(context))
|
||||
is Format.Epub -> EpubPageLoader(format.file.archiveReader(context))
|
||||
}
|
||||
}
|
||||
source is HttpSource -> HttpPageLoader(chapter, source)
|
||||
|
||||
@@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import mihon.core.common.archive.archiveReader
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
@@ -26,7 +27,7 @@ internal class DownloadPageLoader(
|
||||
|
||||
private val context: Application by injectLazy()
|
||||
|
||||
private var zipPageLoader: ZipPageLoader? = null
|
||||
private var archivePageLoader: ArchivePageLoader? = null
|
||||
|
||||
override var isLocal: Boolean = true
|
||||
|
||||
@@ -42,13 +43,11 @@ internal class DownloadPageLoader(
|
||||
|
||||
override fun recycle() {
|
||||
super.recycle()
|
||||
zipPageLoader?.recycle()
|
||||
archivePageLoader?.recycle()
|
||||
}
|
||||
|
||||
private suspend fun getPagesFromArchive(file: UniFile): List<ReaderPage> {
|
||||
// SY -->
|
||||
val loader = ZipPageLoader(file, context).also { zipPageLoader = it }
|
||||
// SY <--
|
||||
val loader = ArchivePageLoader(file.archiveReader(context)).also { archivePageLoader = it }
|
||||
return loader.getPages()
|
||||
}
|
||||
|
||||
@@ -64,6 +63,6 @@ internal class DownloadPageLoader(
|
||||
}
|
||||
|
||||
override suspend fun loadPage(page: ReaderPage) {
|
||||
zipPageLoader?.loadPage(page)
|
||||
archivePageLoader?.loadPage(page)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
package eu.kanade.tachiyomi.ui.reader.loader
|
||||
|
||||
import android.content.Context
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.util.storage.EpubFile
|
||||
import mihon.core.common.archive.ArchiveReader
|
||||
|
||||
/**
|
||||
* Loader used to load a chapter from a .epub file.
|
||||
*/
|
||||
// SY -->
|
||||
internal class EpubPageLoader(file: UniFile, context: Context) : PageLoader() {
|
||||
internal class EpubPageLoader(reader: ArchiveReader) : PageLoader() {
|
||||
|
||||
private val epub = EpubFile(file, context)
|
||||
// SY <--
|
||||
private val epub = EpubFile(reader)
|
||||
|
||||
override var isLocal: Boolean = true
|
||||
|
||||
override suspend fun getPages(): List<ReaderPage> {
|
||||
return epub.getImagesFromPages()
|
||||
.mapIndexed { i, path ->
|
||||
val streamFn = { epub.getInputStream(epub.getEntry(path)!!) }
|
||||
val streamFn = { epub.getInputStream(path)!! }
|
||||
ReaderPage(i).apply {
|
||||
stream = streamFn
|
||||
status = Page.State.READY
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.reader.loader
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.storage.UniFileTempFileManager
|
||||
import tachiyomi.core.common.storage.isEncryptedZip
|
||||
import tachiyomi.core.common.storage.openReadOnlyChannel
|
||||
import tachiyomi.core.common.storage.testCbzPassword
|
||||
import tachiyomi.core.common.storage.unzip
|
||||
import tachiyomi.core.common.util.system.ImageUtil
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.File
|
||||
import java.nio.channels.SeekableByteChannel
|
||||
import net.lingala.zip4j.ZipFile as Zip4jFile
|
||||
|
||||
/**
|
||||
* Loader used to load a chapter from a .zip or .cbz file.
|
||||
*/
|
||||
internal class ZipPageLoader(file: UniFile, context: Context) : PageLoader() {
|
||||
|
||||
// SY -->
|
||||
private val channel: SeekableByteChannel = file.openReadOnlyChannel(context)
|
||||
private val tempFileManager: UniFileTempFileManager by injectLazy()
|
||||
private val readerPreferences: ReaderPreferences by injectLazy()
|
||||
private val tmpDir = File(context.externalCacheDir, "reader_${file.hashCode()}").also {
|
||||
it.deleteRecursively()
|
||||
}
|
||||
|
||||
private val apacheZip: ZipFile? = if (!file.isEncryptedZip() && Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
|
||||
ZipFile.Builder()
|
||||
.setSeekableByteChannel(channel)
|
||||
.get()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
private val tmpFile =
|
||||
if (
|
||||
apacheZip == null &&
|
||||
readerPreferences.archiveReaderMode().get() != ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK
|
||||
) {
|
||||
tempFileManager.createTempFile(file)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
private val zip4j =
|
||||
if (apacheZip == null && tmpFile != null) {
|
||||
Zip4jFile(tmpFile)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
init {
|
||||
if (file.isEncryptedZip()) {
|
||||
if (!file.testCbzPassword()) {
|
||||
this.recycle()
|
||||
throw IllegalStateException(context.stringResource(SYMR.strings.wrong_cbz_archive_password))
|
||||
}
|
||||
zip4j?.setPassword(CbzCrypto.getDecryptedPasswordCbz())
|
||||
}
|
||||
if (readerPreferences.archiveReaderMode().get() == ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK) {
|
||||
file.unzip(tmpDir, onlyCopyImages = true)
|
||||
}
|
||||
}
|
||||
|
||||
// SY <--
|
||||
override fun recycle() {
|
||||
super.recycle()
|
||||
apacheZip?.close()
|
||||
// SY -->
|
||||
zip4j?.close()
|
||||
tmpDir.deleteRecursively()
|
||||
}
|
||||
|
||||
override var isLocal: Boolean = true
|
||||
|
||||
override suspend fun getPages(): List<ReaderPage> {
|
||||
if (readerPreferences.archiveReaderMode().get() == ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK) {
|
||||
return DirectoryPageLoader(UniFile.fromFile(tmpDir)!!).getPages()
|
||||
}
|
||||
return if (apacheZip == null) {
|
||||
loadZip4j()
|
||||
} else {
|
||||
loadApacheZip(apacheZip)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadZip4j(): List<ReaderPage> {
|
||||
val mutex = Mutex()
|
||||
return zip4j!!.fileHeaders.asSequence()
|
||||
.filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { zip4j.getInputStream(it) } }
|
||||
.sortedWith { f1, f2 -> f1.fileName.compareToCaseInsensitiveNaturalOrder(f2.fileName) }
|
||||
.mapIndexed { i, entry ->
|
||||
val imageBytesDeferred: Deferred<ByteArray>? =
|
||||
when (readerPreferences.archiveReaderMode().get()) {
|
||||
ReaderPreferences.ArchiveReaderMode.LOAD_INTO_MEMORY -> {
|
||||
CoroutineScope(Dispatchers.IO).async {
|
||||
mutex.withLock {
|
||||
zip4j.getInputStream(entry).buffered().use { stream ->
|
||||
stream.readBytes()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
val imageBytes by lazy { runBlocking { imageBytesDeferred?.await() } }
|
||||
ReaderPage(i).apply {
|
||||
stream = { imageBytes?.copyOf()?.inputStream() ?: zip4j.getInputStream(entry) }
|
||||
status = Page.State.READY
|
||||
}
|
||||
}.toList()
|
||||
}
|
||||
|
||||
private fun loadApacheZip(zip: ZipFile): List<ReaderPage> {
|
||||
val mutex = Mutex()
|
||||
return zip.entries.asSequence()
|
||||
.filter { !it.isDirectory && ImageUtil.isImage(it.name) { zip.getInputStream(it) } }
|
||||
.sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }
|
||||
.mapIndexed { i, entry ->
|
||||
val imageBytesDeferred: Deferred<ByteArray>? =
|
||||
when (readerPreferences.archiveReaderMode().get()) {
|
||||
ReaderPreferences.ArchiveReaderMode.LOAD_INTO_MEMORY -> {
|
||||
CoroutineScope(Dispatchers.IO).async {
|
||||
mutex.withLock {
|
||||
zip.getInputStream(entry).buffered().use { stream ->
|
||||
stream.readBytes()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
val imageBytes by lazy { runBlocking { imageBytesDeferred?.await() } }
|
||||
ReaderPage(i).apply {
|
||||
stream = { imageBytes?.copyOf()?.inputStream() ?: zip.getInputStream(entry) }
|
||||
status = Page.State.READY
|
||||
}
|
||||
}.toList()
|
||||
}
|
||||
// SY <--
|
||||
|
||||
/**
|
||||
* No additional action required to load the page
|
||||
*/
|
||||
override suspend fun loadPage(page: ReaderPage) {
|
||||
check(!isRecycled)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
|
||||
|
||||
import android.graphics.PointF
|
||||
import android.os.Build
|
||||
import android.view.KeyEvent
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
@@ -402,4 +403,5 @@ class WebtoonViewer(
|
||||
}
|
||||
}
|
||||
|
||||
private const val RecyclerViewCacheSize = 4
|
||||
// Double the cache size to reduce rebinds/recycles incurred by the extra layout space on scroll direction changes
|
||||
private val RecyclerViewCacheSize = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 4 else 2
|
||||
|
||||
@@ -4,8 +4,13 @@
|
||||
<!--== AMOLED Mode Overlay ==-->
|
||||
<style name="ThemeOverlay.Tachiyomi.Amoled" parent="">
|
||||
<!-- Theme Colors -->
|
||||
<item name="colorSurface">@color/surface_amoled</item>
|
||||
<item name="android:colorBackground">@color/background_amoled</item>
|
||||
<item name="android:colorBackground">@color/amoled_background</item>
|
||||
<item name="colorOnBackground">@color/amoled_onBackground</item>
|
||||
<item name="colorSurface">@color/amoled_surface</item>
|
||||
<item name="colorOnSurface">@color/amoled_onSurface</item>
|
||||
<item name="colorSurfaceContainer">@color/amoled_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/amoled_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/amoled_surfaceContainerHighest</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<item name="colorOnPrimary">@color/tachiyomi_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/tachiyomi_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/tachiyomi_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/tachiyomi_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/tachiyomi_secondary</item>
|
||||
<item name="colorOnSecondary">@color/tachiyomi_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/tachiyomi_secondaryContainer</item>
|
||||
@@ -29,14 +30,20 @@
|
||||
<item name="colorOnSurface">@color/tachiyomi_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/tachiyomi_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/tachiyomi_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/tachiyomi_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tachiyomi_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/tachiyomi_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/tachiyomi_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/tachiyomi_primaryInverse</item>
|
||||
<item name="colorError">@color/error</item>
|
||||
<item name="colorOnError">@color/onError</item>
|
||||
<item name="colorErrorContainer">@color/errorContainer</item>
|
||||
<item name="colorOnErrorContainer">@color/onErrorContainer</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tachiyomi_inverseOnSurface</item>
|
||||
<item name="colorError">@color/tachiyomi_error</item>
|
||||
<item name="colorOnError">@color/tachiyomi_onError</item>
|
||||
<item name="colorErrorContainer">@color/tachiyomi_errorContainer</item>
|
||||
<item name="colorOnErrorContainer">@color/tachiyomi_onErrorContainer</item>
|
||||
<item name="colorOutline">@color/tachiyomi_outline</item>
|
||||
<item name="colorOutlineVariant">@color/tachiyomi_outlineVariant</item>
|
||||
<item name="colorSurfaceContainer">@color/tachiyomi_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/tachiyomi_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/tachiyomi_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/tachiyomi_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/tachiyomi_surfaceContainerLowest</item>
|
||||
|
||||
<item name="android:divider">@color/divider_default</item>
|
||||
<item name="android:listDivider">@drawable/line_divider</item>
|
||||
@@ -52,7 +59,7 @@
|
||||
<!-- Themes -->
|
||||
<item name="android:windowLightStatusBar">@bool/lightStatusBar</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@color/surface_amoled</item>
|
||||
<item name="android:navigationBarColor">@color/amoled_surface</item>
|
||||
<item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">@null</item>
|
||||
<item name="android:enforceNavigationBarContrast" tools:targetApi="Q">false</item>
|
||||
<item name="android:enforceStatusBarContrast" tools:targetApi="Q">false</item>
|
||||
@@ -96,6 +103,7 @@
|
||||
<item name="colorOnPrimary">@color/greenapple_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/greenapple_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/greenapple_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/greenapple_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/greenapple_secondary</item>
|
||||
<item name="colorOnSecondary">@color/greenapple_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/greenapple_secondaryContainer</item>
|
||||
@@ -110,10 +118,22 @@
|
||||
<item name="colorOnSurface">@color/greenapple_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/greenapple_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/greenapple_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/greenapple_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/greenapple_inverseOnSurface</item>
|
||||
<item name="colorSurfaceInverse">@color/greenapple_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/greenapple_primaryInverse</item>
|
||||
<item name="colorOnSurfaceInverse">@color/greenapple_inverseOnSurface</item>
|
||||
<item name="colorError">@color/greenapple_error</item>
|
||||
<item name="colorOnError">@color/greenapple_onError</item>
|
||||
<item name="colorErrorContainer">@color/greenapple_errorContainer</item>
|
||||
<item name="colorOnErrorContainer">@color/greenapple_onErrorContainer</item>
|
||||
<item name="colorOutline">@color/greenapple_outline</item>
|
||||
<item name="colorOutlineVariant">@color/greenapple_outlineVariant</item>
|
||||
<item name="scrimBackground">@color/greenapple_scrim</item>
|
||||
<item name="colorSurfaceBright">@color/greenapple_surfaceBright</item>
|
||||
<item name="colorSurfaceDim">@color/greenapple_surfaceDim</item>
|
||||
<item name="colorSurfaceContainer">@color/greenapple_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/greenapple_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/greenapple_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/greenapple_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/greenapple_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Lavender Theme ==-->
|
||||
@@ -123,6 +143,7 @@
|
||||
<item name="colorOnPrimary">@color/lavender_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/lavender_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/lavender_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/lavender_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/lavender_secondary</item>
|
||||
<item name="colorOnSecondary">@color/lavender_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/lavender_secondaryContainer</item>
|
||||
@@ -137,11 +158,22 @@
|
||||
<item name="colorOnSurface">@color/lavender_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/lavender_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/lavender_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/lavender_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/lavender_inverseOnSurface</item>
|
||||
<item name="colorSurfaceInverse">@color/lavender_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/lavender_primaryInverse</item>
|
||||
<item name="elevationOverlayColor">@color/lavender_elevationOverlay</item>
|
||||
<item name="colorOnSurfaceInverse">@color/lavender_inverseOnSurface</item>
|
||||
<item name="colorError">@color/lavender_error</item>
|
||||
<item name="colorOnError">@color/lavender_onError</item>
|
||||
<item name="colorErrorContainer">@color/lavender_errorContainer</item>
|
||||
<item name="colorOnErrorContainer">@color/lavender_onErrorContainer</item>
|
||||
<item name="colorOutline">@color/lavender_outline</item>
|
||||
<item name="colorOutlineVariant">@color/lavender_outlineVariant</item>
|
||||
<item name="scrimBackground">@color/lavender_scrim</item>
|
||||
<item name="colorSurfaceBright">@color/lavender_surfaceBright</item>
|
||||
<item name="colorSurfaceDim">@color/lavender_surfaceDim</item>
|
||||
<item name="colorSurfaceContainer">@color/lavender_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/lavender_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/lavender_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/lavender_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/lavender_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Midnight Dusk Theme ==-->
|
||||
@@ -151,6 +183,7 @@
|
||||
<item name="colorOnPrimary">@color/midnightdusk_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/midnightdusk_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/midnightdusk_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/midnightdusk_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/midnightdusk_secondary</item>
|
||||
<item name="colorOnSecondary">@color/midnightdusk_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/midnightdusk_secondaryContainer</item>
|
||||
@@ -165,11 +198,15 @@
|
||||
<item name="colorOnSurface">@color/midnightdusk_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/midnightdusk_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/midnightdusk_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/midnightdusk_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/midnightdusk_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/midnightdusk_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/midnightdusk_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/midnightdusk_primaryInverse</item>
|
||||
<item name="elevationOverlayColor">@color/midnightdusk_elevationOverlay</item>
|
||||
<item name="colorOnSurfaceInverse">@color/midnightdusk_inverseOnSurface</item>
|
||||
<item name="colorOutline">@color/midnightdusk_outline</item>
|
||||
<item name="colorSurfaceContainer">@color/midnightdusk_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/midnightdusk_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/midnightdusk_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/midnightdusk_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/midnightdusk_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Strawberry Daiquiri Theme ==-->
|
||||
@@ -179,6 +216,7 @@
|
||||
<item name="colorOnPrimary">@color/strawberry_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/strawberry_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/strawberry_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/strawberry_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/strawberry_secondary</item>
|
||||
<item name="colorOnSecondary">@color/strawberry_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/strawberry_secondaryContainer</item>
|
||||
@@ -193,10 +231,22 @@
|
||||
<item name="colorOnSurface">@color/strawberry_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/strawberry_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/strawberry_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/strawberry_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/strawberry_inverseOnSurface</item>
|
||||
<item name="colorSurfaceInverse">@color/strawberry_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/strawberry_primaryInverse</item>
|
||||
<item name="colorOnSurfaceInverse">@color/strawberry_inverseOnSurface</item>
|
||||
<item name="colorError">@color/strawberry_error</item>
|
||||
<item name="colorOnError">@color/strawberry_onError</item>
|
||||
<item name="colorErrorContainer">@color/strawberry_errorContainer</item>
|
||||
<item name="colorOnErrorContainer">@color/strawberry_onErrorContainer</item>
|
||||
<item name="colorOutline">@color/strawberry_outline</item>
|
||||
<item name="colorOutlineVariant">@color/strawberry_outlineVariant</item>
|
||||
<item name="scrimBackground">@color/strawberry_scrim</item>
|
||||
<item name="colorSurfaceBright">@color/strawberry_surfaceBright</item>
|
||||
<item name="colorSurfaceDim">@color/strawberry_surfaceDim</item>
|
||||
<item name="colorSurfaceContainer">@color/strawberry_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/strawberry_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/strawberry_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/strawberry_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/strawberry_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Tako Theme ==-->
|
||||
@@ -206,6 +256,7 @@
|
||||
<item name="colorOnPrimary">@color/tako_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/tako_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/tako_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/tako_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/tako_secondary</item>
|
||||
<item name="colorOnSecondary">@color/tako_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/tako_secondaryContainer</item>
|
||||
@@ -220,11 +271,15 @@
|
||||
<item name="colorOnSurface">@color/tako_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/tako_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/tako_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/tako_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tako_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/tako_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/tako_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/tako_primaryInverse</item>
|
||||
<item name="elevationOverlayColor">@color/tako_elevationOverlay</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tako_inverseOnSurface</item>
|
||||
<item name="colorOutline">@color/tako_outline</item>
|
||||
<item name="colorSurfaceContainer">@color/tako_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/tako_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/tako_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/tako_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/tako_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Teal & Turquoise Theme ==-->
|
||||
@@ -234,6 +289,7 @@
|
||||
<item name="colorOnPrimary">@color/tealturquoise_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/tealturquoise_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/tealturquoise_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/tealturquoise_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/tealturquoise_secondary</item>
|
||||
<item name="colorOnSecondary">@color/tealturquoise_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/tealturquoise_secondaryContainer</item>
|
||||
@@ -248,13 +304,15 @@
|
||||
<item name="colorOnSurface">@color/tealturquoise_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/tealturquoise_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/tealturquoise_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/tealturquoise_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tealturquoise_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/tealturquoise_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/tealturquoise_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/tealturquoise_primaryInverse</item>
|
||||
<item name="colorError">@color/tealturquoise_tertiary</item>
|
||||
<item name="colorOnError">@color/tealturquoise_onTertiary</item>
|
||||
<item name="elevationOverlayColor">@color/tealturquoise_elevationOverlay</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tealturquoise_inverseOnSurface</item>
|
||||
<item name="colorOutline">@color/tealturquoise_outline</item>
|
||||
<item name="colorSurfaceContainer">@color/tealturquoise_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/tealturquoise_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/tealturquoise_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/tealturquoise_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/tealturquoise_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Yin & Yang Theme ==-->
|
||||
@@ -264,6 +322,7 @@
|
||||
<item name="colorOnPrimary">@color/yinyang_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/yinyang_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/yinyang_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/yinyang_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/yinyang_secondary</item>
|
||||
<item name="colorOnSecondary">@color/yinyang_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/yinyang_secondaryContainer</item>
|
||||
@@ -278,10 +337,15 @@
|
||||
<item name="colorOnSurface">@color/yinyang_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/yinyang_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/yinyang_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/yinyang_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/yinyang_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/yinyang_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/yinyang_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/yinyang_primaryInverse</item>
|
||||
<item name="colorOnSurfaceInverse">@color/yinyang_inverseOnSurface</item>
|
||||
<item name="colorOutline">@color/yinyang_outline</item>
|
||||
<item name="colorSurfaceContainer">@color/yinyang_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/yinyang_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/yinyang_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/yinyang_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/yinyang_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Yotsuba Theme ==-->
|
||||
@@ -291,6 +355,7 @@
|
||||
<item name="colorOnPrimary">@color/yotsuba_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/yotsuba_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/yotsuba_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/yotsuba_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/yotsuba_secondary</item>
|
||||
<item name="colorOnSecondary">@color/yotsuba_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/yotsuba_secondaryContainer</item>
|
||||
@@ -305,10 +370,15 @@
|
||||
<item name="colorOnSurface">@color/yotsuba_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/yotsuba_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/yotsuba_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/yotsuba_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/yotsuba_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/yotsuba_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/yotsuba_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/yotsuba_primaryInverse</item>
|
||||
<item name="colorOnSurfaceInverse">@color/yotsuba_inverseOnSurface</item>
|
||||
<item name="colorOutline">@color/yotsuba_outline</item>
|
||||
<item name="colorSurfaceContainer">@color/yotsuba_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/yotsuba_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/yotsuba_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/yotsuba_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/yotsuba_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Tidal Wave Theme ==-->
|
||||
@@ -318,6 +388,7 @@
|
||||
<item name="colorOnPrimary">@color/tidalwave_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/tidalwave_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/tidalwave_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/tidalwave_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/tidalwave_secondary</item>
|
||||
<item name="colorOnSecondary">@color/tidalwave_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/tidalwave_secondaryContainer</item>
|
||||
@@ -332,10 +403,15 @@
|
||||
<item name="colorOnSurface">@color/tidalwave_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/tidalwave_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/tidalwave_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/tidalwave_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tidalwave_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/tidalwave_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/tidalwave_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/tidalwave_primaryInverse</item>
|
||||
<item name="colorOnSurfaceInverse">@color/tidalwave_inverseOnSurface</item>
|
||||
<item name="colorOutline">@color/tidalwave_outline</item>
|
||||
<item name="colorSurfaceContainer">@color/tidalwave_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/tidalwave_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/tidalwave_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/tidalwave_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/tidalwave_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== Nord Theme ==-->
|
||||
@@ -345,6 +421,7 @@
|
||||
<item name="colorOnPrimary">@color/nord_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/nord_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/nord_onPrimaryContainer</item>
|
||||
<item name="colorPrimaryInverse">@color/nord_inversePrimary</item>
|
||||
<item name="colorSecondary">@color/nord_secondary</item>
|
||||
<item name="colorOnSecondary">@color/nord_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/nord_secondaryContainer</item>
|
||||
@@ -359,14 +436,19 @@
|
||||
<item name="colorOnSurface">@color/nord_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/nord_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/nord_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/nord_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/nord_inverseOnSurface</item>
|
||||
<item name="elevationOverlayColor">@color/nord_surfaceTint</item>
|
||||
<item name="colorSurfaceInverse">@color/nord_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/nord_primaryInverse</item>
|
||||
<item name="colorOnSurfaceInverse">@color/nord_inverseOnSurface</item>
|
||||
<item name="colorOnError">@color/nord_onError</item>
|
||||
<item name="colorErrorContainer">@color/nord_errorContainer</item>
|
||||
<item name="colorOnErrorContainer">@color/nord_onErrorContainer</item>
|
||||
<item name="elevationOverlayColor">@color/nord_elevationOverlay</item>
|
||||
<item name="colorOutline">@color/nord_outline</item>
|
||||
<item name="colorOutlineVariant">@color/nord_outlineVariant</item>
|
||||
<item name="colorSurfaceContainer">@color/nord_surfaceContainer</item>
|
||||
<item name="colorSurfaceContainerHigh">@color/nord_surfaceContainerHigh</item>
|
||||
<item name="colorSurfaceContainerHighest">@color/nord_surfaceContainerHighest</item>
|
||||
<item name="colorSurfaceContainerLow">@color/nord_surfaceContainerLow</item>
|
||||
<item name="colorSurfaceContainerLowest">@color/nord_surfaceContainerLowest</item>
|
||||
</style>
|
||||
|
||||
<!--== AMOLED Mode Overlay ==-->
|
||||
|
||||
@@ -558,6 +558,7 @@
|
||||
<ID>LongParameterList:UpdatesRepositoryImpl.kt$UpdatesRepositoryImpl$( mangaId: Long, mangaTitle: String, chapterId: Long, chapterName: String, scanlator: String?, read: Boolean, bookmark: Boolean, lastPageRead: Long, sourceId: Long, favorite: Boolean, thumbnailUrl: String?, coverLastModified: Long, dateUpload: Long, dateFetch: Long, )</ID>
|
||||
<ID>LongParameterList:UpdatesUiItem.kt$( uiModels: List<UpdatesUiModel>, selectionMode: Boolean, // SY --> preserveReadingPosition: Boolean, // SY <-- onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit, onClickCover: (UpdatesItem) -> Unit, onClickUpdate: (UpdatesItem) -> Unit, onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit, )</ID>
|
||||
<ID>LongParameterList:WebtoonRecyclerView.kt$WebtoonRecyclerView$( fromRate: Float, toRate: Float, fromX: Float, toX: Float, fromY: Float, toY: Float, )</ID>
|
||||
<ID>LoopWithTooManyJumpStatements:ArchiveReader.kt$ArchiveReader$while</ID>
|
||||
<ID>LoopWithTooManyJumpStatements:DownloadStore.kt$DownloadStore$for</ID>
|
||||
<ID>LoopWithTooManyJumpStatements:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$for</ID>
|
||||
<ID>LoopWithTooManyJumpStatements:ImageUtil.kt$ImageUtil$for</ID>
|
||||
@@ -1510,6 +1511,7 @@
|
||||
<ID>NestedBlockDepth:Anilist.kt$Anilist$override suspend fun update(track: Track, didReadChapter: Boolean): Track</ID>
|
||||
<ID>NestedBlockDepth:ApiMangaParser.kt$ApiMangaParser$fun parseIntoMetadata( metadata: MangaDexSearchMetadata, mangaDto: MangaDto, simpleChapters: List<String>, statistics: StatisticsMangaDto?, )</ID>
|
||||
<ID>NestedBlockDepth:AppLanguageScreen.kt$AppLanguageScreen$private fun getLangs(context: Context): ImmutableList<Language></ID>
|
||||
<ID>NestedBlockDepth:ArchiveReader.kt$ArchiveReader$private fun isPasswordIncorrect(): Boolean?</ID>
|
||||
<ID>NestedBlockDepth:BackupRestorer.kt$BackupRestorer$private fun writeErrorLog(): File</ID>
|
||||
<ID>NestedBlockDepth:BrowseSourceScreenModel.kt$BrowseSourceScreenModel$fun searchGenre(genreName: String)</ID>
|
||||
<ID>NestedBlockDepth:ChapterLoader.kt$ChapterLoader$private fun getPageLoader(chapter: ReaderChapter): PageLoader</ID>
|
||||
|
||||
@@ -36,7 +36,7 @@ dependencies {
|
||||
implementation(libs.image.decoder)
|
||||
|
||||
implementation(libs.unifile)
|
||||
implementation(libs.bundles.archive)
|
||||
implementation(libs.libarchive)
|
||||
|
||||
api(kotlinx.coroutines.core)
|
||||
api(kotlinx.serialization.json)
|
||||
@@ -56,7 +56,6 @@ dependencies {
|
||||
|
||||
// SY -->
|
||||
implementation(sylibs.xlog)
|
||||
implementation(libs.zip4j)
|
||||
implementation(libs.injekt.core)
|
||||
implementation(sylibs.exifinterface)
|
||||
// SY <--
|
||||
|
||||
@@ -56,7 +56,6 @@ class SecurityPreferences(
|
||||
// SY -->
|
||||
enum class EncryptionType(val titleRes: StringResource) {
|
||||
AES_256(SYMR.strings.aes_256),
|
||||
AES_192(SYMR.strings.aes_192),
|
||||
AES_128(SYMR.strings.aes_128),
|
||||
ZIP_STANDARD(SYMR.strings.standard_zip_encryption),
|
||||
}
|
||||
|
||||
@@ -9,14 +9,13 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import net.lingala.zip4j.model.ZipParameters
|
||||
import net.lingala.zip4j.model.enums.AesKeyStrength
|
||||
import net.lingala.zip4j.model.enums.EncryptionMethod
|
||||
import mihon.core.common.archive.ArchiveReader
|
||||
import tachiyomi.core.common.util.system.ImageUtil
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.CharBuffer
|
||||
import java.security.KeyStore
|
||||
import java.security.SecureRandom
|
||||
@@ -33,7 +32,7 @@ import javax.crypto.spec.IvParameterSpec
|
||||
*/
|
||||
object CbzCrypto {
|
||||
const val DATABASE_NAME = "tachiyomiEncrypted.db"
|
||||
const val DEFAULT_COVER_NAME = "cover.jpg"
|
||||
private const val DEFAULT_COVER_NAME = "cover.jpg"
|
||||
private val securityPreferences: SecurityPreferences by injectLazy()
|
||||
private val keyStore = KeyStore.getInstance(Keystore).apply {
|
||||
load(null)
|
||||
@@ -129,15 +128,11 @@ object CbzCrypto {
|
||||
return encrypt(password.toByteArray(), encryptionCipherCbz)
|
||||
}
|
||||
|
||||
fun getDecryptedPasswordCbz(): CharArray {
|
||||
fun getDecryptedPasswordCbz(): ByteArray {
|
||||
val encryptedPassword = securityPreferences.cbzPassword().get()
|
||||
if (encryptedPassword.isBlank()) error("This archive is encrypted please set a password")
|
||||
|
||||
val cbzBytes = decrypt(encryptedPassword, AliasCbz)
|
||||
return Charsets.UTF_8.decode(ByteBuffer.wrap(cbzBytes)).array()
|
||||
.also {
|
||||
cbzBytes.fill('#'.code.toByte())
|
||||
}
|
||||
return decrypt(encryptedPassword, AliasCbz)
|
||||
}
|
||||
|
||||
private fun generateAndEncryptSqlPw() {
|
||||
@@ -185,27 +180,12 @@ object CbzCrypto {
|
||||
}
|
||||
}
|
||||
|
||||
fun setZipParametersEncrypted(zipParameters: ZipParameters) {
|
||||
zipParameters.isEncryptFiles = true
|
||||
|
||||
fun getPreferredEncryptionAlgo(): ByteArray =
|
||||
when (securityPreferences.encryptionType().get()) {
|
||||
SecurityPreferences.EncryptionType.AES_256 -> {
|
||||
zipParameters.encryptionMethod = EncryptionMethod.AES
|
||||
zipParameters.aesKeyStrength = AesKeyStrength.KEY_STRENGTH_256
|
||||
}
|
||||
SecurityPreferences.EncryptionType.AES_192 -> {
|
||||
zipParameters.encryptionMethod = EncryptionMethod.AES
|
||||
zipParameters.aesKeyStrength = AesKeyStrength.KEY_STRENGTH_192
|
||||
}
|
||||
SecurityPreferences.EncryptionType.AES_128 -> {
|
||||
zipParameters.encryptionMethod = EncryptionMethod.AES
|
||||
zipParameters.aesKeyStrength = AesKeyStrength.KEY_STRENGTH_128
|
||||
}
|
||||
SecurityPreferences.EncryptionType.ZIP_STANDARD -> {
|
||||
zipParameters.encryptionMethod = EncryptionMethod.ZIP_STANDARD
|
||||
}
|
||||
SecurityPreferences.EncryptionType.AES_256 -> "zip:encryption=aes256".toByteArray()
|
||||
SecurityPreferences.EncryptionType.AES_128 -> "zip:encryption=aes128".toByteArray()
|
||||
SecurityPreferences.EncryptionType.ZIP_STANDARD -> "zip:encryption=zipcrypt".toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
fun detectCoverImageArchive(stream: InputStream): Boolean {
|
||||
val bytes = ByteArray(128)
|
||||
@@ -217,6 +197,15 @@ object CbzCrypto {
|
||||
}
|
||||
return String(bytes).contains(DEFAULT_COVER_NAME, ignoreCase = true)
|
||||
}
|
||||
|
||||
fun ArchiveReader.getCoverStream(): BufferedInputStream? {
|
||||
this.getInputStream(DEFAULT_COVER_NAME)?.let { stream ->
|
||||
if (ImageUtil.isImage(DEFAULT_COVER_NAME) { stream }) {
|
||||
return this.getInputStream(DEFAULT_COVER_NAME)?.buffered()
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private const val BufferSize = 2048
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
package eu.kanade.tachiyomi.util.storage
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import com.hippo.unifile.UniFile
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile
|
||||
import mihon.core.common.archive.ArchiveReader
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import tachiyomi.core.common.storage.UniFileTempFileManager
|
||||
import tachiyomi.core.common.storage.openReadOnlyChannel
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
@@ -17,45 +10,18 @@ import java.io.InputStream
|
||||
/**
|
||||
* Wrapper over ZipFile to load files in epub format.
|
||||
*/
|
||||
// SY -->
|
||||
class EpubFile(file: UniFile, context: Context) : Closeable {
|
||||
|
||||
private val tempFileManager: UniFileTempFileManager by injectLazy()
|
||||
|
||||
/**
|
||||
* Zip file of this epub.
|
||||
*/
|
||||
private val zip = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
ZipFile.Builder().setFile(tempFileManager.createTempFile(file)).get()
|
||||
} else {
|
||||
ZipFile.Builder().setSeekableByteChannel(file.openReadOnlyChannel(context)).get()
|
||||
}
|
||||
// SY <--
|
||||
class EpubFile(private val reader: ArchiveReader) : Closeable by reader {
|
||||
|
||||
/**
|
||||
* Path separator used by this epub.
|
||||
*/
|
||||
private val pathSeparator = getPathSeparator()
|
||||
|
||||
/**
|
||||
* Closes the underlying zip file.
|
||||
*/
|
||||
override fun close() {
|
||||
zip.close()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream for reading the contents of the specified zip file entry.
|
||||
*/
|
||||
fun getInputStream(entry: ZipArchiveEntry): InputStream {
|
||||
return zip.getInputStream(entry)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the zip file entry for the specified name, or null if not found.
|
||||
*/
|
||||
fun getEntry(name: String): ZipArchiveEntry? {
|
||||
return zip.getEntry(name)
|
||||
fun getInputStream(entryName: String): InputStream? {
|
||||
return reader.getInputStream(entryName)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,9 +38,9 @@ class EpubFile(file: UniFile, context: Context) : Closeable {
|
||||
* Returns the path to the package document.
|
||||
*/
|
||||
fun getPackageHref(): String {
|
||||
val meta = zip.getEntry(resolveZipPath("META-INF", "container.xml"))
|
||||
val meta = getInputStream(resolveZipPath("META-INF", "container.xml"))
|
||||
if (meta != null) {
|
||||
val metaDoc = zip.getInputStream(meta).use { Jsoup.parse(it, null, "") }
|
||||
val metaDoc = meta.use { Jsoup.parse(it, null, "") }
|
||||
val path = metaDoc.getElementsByTag("rootfile").first()?.attr("full-path")
|
||||
if (path != null) {
|
||||
return path
|
||||
@@ -87,8 +53,7 @@ class EpubFile(file: UniFile, context: Context) : Closeable {
|
||||
* Returns the package document where all the files are listed.
|
||||
*/
|
||||
fun getPackageDocument(ref: String): Document {
|
||||
val entry = zip.getEntry(ref)
|
||||
return zip.getInputStream(entry).use { Jsoup.parse(it, null, "") }
|
||||
return getInputStream(ref)!!.use { Jsoup.parse(it, null, "") }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,8 +76,7 @@ class EpubFile(file: UniFile, context: Context) : Closeable {
|
||||
val basePath = getParentDirectory(packageHref)
|
||||
pages.forEach { page ->
|
||||
val entryPath = resolveZipPath(basePath, page)
|
||||
val entry = zip.getEntry(entryPath)
|
||||
val document = zip.getInputStream(entry).use { Jsoup.parse(it, null, "") }
|
||||
val document = getInputStream(entryPath)!!.use { Jsoup.parse(it, null, "") }
|
||||
val imageBasePath = getParentDirectory(entryPath)
|
||||
|
||||
document.allElements.forEach {
|
||||
@@ -130,8 +94,9 @@ class EpubFile(file: UniFile, context: Context) : Closeable {
|
||||
* Returns the path separator used by the epub file.
|
||||
*/
|
||||
private fun getPathSeparator(): String {
|
||||
val meta = zip.getEntry("META-INF\\container.xml")
|
||||
val meta = getInputStream("META-INF\\container.xml")
|
||||
return if (meta != null) {
|
||||
meta.close()
|
||||
"\\"
|
||||
} else {
|
||||
"/"
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package mihon.core.common.archive
|
||||
|
||||
class ArchiveEntry(
|
||||
val name: String,
|
||||
val isFile: Boolean,
|
||||
val isEncrypted: Boolean,
|
||||
)
|
||||
@@ -0,0 +1,84 @@
|
||||
package mihon.core.common.archive
|
||||
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||
import me.zhanghai.android.libarchive.Archive
|
||||
import me.zhanghai.android.libarchive.ArchiveEntry
|
||||
import me.zhanghai.android.libarchive.ArchiveException
|
||||
import java.io.InputStream
|
||||
import java.nio.ByteBuffer
|
||||
import kotlin.concurrent.Volatile
|
||||
|
||||
class ArchiveInputStream(
|
||||
buffer: Long,
|
||||
size: Long,
|
||||
// SY -->
|
||||
encrypted: Boolean,
|
||||
// SY <--
|
||||
) : InputStream() {
|
||||
private val lock = Any()
|
||||
|
||||
@Volatile
|
||||
private var isClosed = false
|
||||
|
||||
private val archive = Archive.readNew()
|
||||
|
||||
init {
|
||||
try {
|
||||
// SY -->
|
||||
if (encrypted) {
|
||||
Archive.readAddPassphrase(archive, CbzCrypto.getDecryptedPasswordCbz())
|
||||
}
|
||||
// SY <--
|
||||
Archive.setCharset(archive, Charsets.UTF_8.name().toByteArray())
|
||||
Archive.readSupportFilterAll(archive)
|
||||
Archive.readSupportFormatAll(archive)
|
||||
Archive.readOpenMemoryUnsafe(archive, buffer, size)
|
||||
} catch (e: ArchiveException) {
|
||||
close()
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
private val oneByteBuffer = ByteBuffer.allocateDirect(1)
|
||||
|
||||
override fun read(): Int {
|
||||
read(oneByteBuffer)
|
||||
return if (oneByteBuffer.hasRemaining()) oneByteBuffer.get().toUByte().toInt() else -1
|
||||
}
|
||||
|
||||
override fun read(b: ByteArray, off: Int, len: Int): Int {
|
||||
val buffer = ByteBuffer.wrap(b, off, len)
|
||||
read(buffer)
|
||||
return if (buffer.hasRemaining()) buffer.remaining() else -1
|
||||
}
|
||||
|
||||
private fun read(buffer: ByteBuffer) {
|
||||
buffer.clear()
|
||||
Archive.readData(archive, buffer)
|
||||
buffer.flip()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
synchronized(lock) {
|
||||
if (isClosed) return
|
||||
isClosed = true
|
||||
}
|
||||
|
||||
Archive.readFree(archive)
|
||||
}
|
||||
|
||||
fun getNextEntry() = Archive.readNextHeader(archive).takeUnless { it == 0L }?.let { entry ->
|
||||
val name = ArchiveEntry.pathnameUtf8(entry) ?: ArchiveEntry.pathname(entry)?.decodeToString() ?: return null
|
||||
val isFile = ArchiveEntry.filetype(entry) == ArchiveEntry.AE_IFREG
|
||||
// SY -->
|
||||
val isEncrypted = ArchiveEntry.isEncrypted(entry)
|
||||
// SY <--
|
||||
ArchiveEntry(
|
||||
name,
|
||||
isFile,
|
||||
// SY -->
|
||||
isEncrypted
|
||||
// SY <--
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package mihon.core.common.archive
|
||||
|
||||
import android.content.Context
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.system.Os
|
||||
import android.system.OsConstants
|
||||
import com.hippo.unifile.UniFile
|
||||
import me.zhanghai.android.libarchive.ArchiveException
|
||||
import tachiyomi.core.common.storage.openFileDescriptor
|
||||
import java.io.Closeable
|
||||
import java.io.InputStream
|
||||
|
||||
class ArchiveReader(pfd: ParcelFileDescriptor) : Closeable {
|
||||
val size = pfd.statSize
|
||||
val address = Os.mmap(0, size, OsConstants.PROT_READ, OsConstants.MAP_PRIVATE, pfd.fileDescriptor, 0)
|
||||
|
||||
// SY -->
|
||||
var encrypted: Boolean = false
|
||||
private set
|
||||
var wrongPassword: Boolean? = null
|
||||
private set
|
||||
val archiveHashCode = pfd.hashCode()
|
||||
|
||||
init {
|
||||
checkEncryptionStatus()
|
||||
}
|
||||
// SY <--
|
||||
|
||||
inline fun <T> useEntries(block: (Sequence<ArchiveEntry>) -> T): T = ArchiveInputStream(
|
||||
address,
|
||||
size,
|
||||
// SY -->
|
||||
encrypted,
|
||||
// SY <--
|
||||
).use { block(generateSequence { it.getNextEntry() }) }
|
||||
|
||||
fun getInputStream(entryName: String): InputStream? {
|
||||
val archive = ArchiveInputStream(address, size, /* SY --> */ encrypted /* SY <-- */)
|
||||
try {
|
||||
while (true) {
|
||||
val entry = archive.getNextEntry() ?: break
|
||||
if (entry.name == entryName) {
|
||||
return archive
|
||||
}
|
||||
}
|
||||
} catch (e: ArchiveException) {
|
||||
archive.close()
|
||||
throw e
|
||||
}
|
||||
archive.close()
|
||||
return null
|
||||
}
|
||||
|
||||
// SY -->
|
||||
private fun checkEncryptionStatus() {
|
||||
val archive = ArchiveInputStream(address, size, false)
|
||||
try {
|
||||
while (true) {
|
||||
val entry = archive.getNextEntry() ?: break
|
||||
if (entry.isEncrypted) {
|
||||
encrypted = true
|
||||
isPasswordIncorrect(entry.name)
|
||||
break
|
||||
}
|
||||
}
|
||||
} catch (e: ArchiveException) {
|
||||
archive.close()
|
||||
throw e
|
||||
}
|
||||
archive.close()
|
||||
}
|
||||
|
||||
private fun isPasswordIncorrect(entryName: String) {
|
||||
try {
|
||||
getInputStream(entryName).use { stream ->
|
||||
stream!!.read()
|
||||
}
|
||||
} catch (e: ArchiveException) {
|
||||
if (e.message == "Incorrect passphrase") {
|
||||
wrongPassword = true
|
||||
return
|
||||
}
|
||||
throw e
|
||||
}
|
||||
wrongPassword = false
|
||||
}
|
||||
// SY <--
|
||||
|
||||
override fun close() {
|
||||
Os.munmap(address, size)
|
||||
}
|
||||
}
|
||||
|
||||
fun UniFile.archiveReader(context: Context) = openFileDescriptor(context, "r").use { ArchiveReader(it) }
|
||||
@@ -0,0 +1,119 @@
|
||||
package mihon.core.common.archive
|
||||
|
||||
import android.content.Context
|
||||
import android.system.Os
|
||||
import android.system.StructStat
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||
import me.zhanghai.android.libarchive.Archive
|
||||
import me.zhanghai.android.libarchive.ArchiveEntry
|
||||
import me.zhanghai.android.libarchive.ArchiveEntry.AE_IFREG
|
||||
import me.zhanghai.android.libarchive.ArchiveException
|
||||
import tachiyomi.core.common.storage.openFileDescriptor
|
||||
import java.io.Closeable
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
class ZipWriter(
|
||||
val context: Context,
|
||||
file: UniFile,
|
||||
// SY -->
|
||||
encrypt: Boolean = false,
|
||||
// SY <--
|
||||
) : Closeable {
|
||||
private val pfd = file.openFileDescriptor(context, "wt")
|
||||
private val archive = Archive.writeNew()
|
||||
private val entry = ArchiveEntry.new2(archive)
|
||||
private val buffer = ByteBuffer.allocateDirect(
|
||||
// SY -->
|
||||
BUFFER_SIZE
|
||||
// SY <--
|
||||
)
|
||||
|
||||
init {
|
||||
try {
|
||||
Archive.setCharset(archive, Charsets.UTF_8.name().toByteArray())
|
||||
Archive.writeSetFormatZip(archive)
|
||||
Archive.writeZipSetCompressionStore(archive)
|
||||
// SY -->
|
||||
if (encrypt) {
|
||||
Archive.writeSetOptions(archive, CbzCrypto.getPreferredEncryptionAlgo())
|
||||
Archive.writeSetPassphrase(archive, CbzCrypto.getDecryptedPasswordCbz())
|
||||
}
|
||||
// SY <--
|
||||
Archive.writeOpenFd(archive, pfd.fd)
|
||||
} catch (e: ArchiveException) {
|
||||
close()
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
fun write(file: UniFile) {
|
||||
file.openFileDescriptor(context, "r").use {
|
||||
val fd = it.fileDescriptor
|
||||
ArchiveEntry.clear(entry)
|
||||
ArchiveEntry.setPathnameUtf8(entry, file.name)
|
||||
val stat = Os.fstat(fd)
|
||||
ArchiveEntry.setStat(entry, stat.toArchiveStat())
|
||||
Archive.writeHeader(archive, entry)
|
||||
while (true) {
|
||||
buffer.clear()
|
||||
Os.read(fd, buffer)
|
||||
if (buffer.position() == 0) break
|
||||
buffer.flip()
|
||||
Archive.writeData(archive, buffer)
|
||||
}
|
||||
Archive.writeFinishEntry(archive)
|
||||
}
|
||||
}
|
||||
|
||||
// SY -->
|
||||
fun write(fileData: ByteArray, fileName: String) {
|
||||
ArchiveEntry.clear(entry)
|
||||
ArchiveEntry.setPathnameUtf8(entry, fileName)
|
||||
ArchiveEntry.setSize(entry, fileData.size.toLong())
|
||||
ArchiveEntry.setFiletype(entry, AE_IFREG)
|
||||
Archive.writeHeader(archive, entry)
|
||||
|
||||
var position = 0
|
||||
while (position < fileData.size) {
|
||||
val lengthToRead = minOf(BUFFER_SIZE, fileData.size - position)
|
||||
buffer.clear()
|
||||
buffer.put(fileData, position, lengthToRead)
|
||||
buffer.flip()
|
||||
Archive.writeData(archive, buffer)
|
||||
position += lengthToRead
|
||||
}
|
||||
Archive.writeFinishEntry(archive)
|
||||
}
|
||||
// SY <--
|
||||
|
||||
override fun close() {
|
||||
ArchiveEntry.free(entry)
|
||||
Archive.writeFree(archive)
|
||||
pfd.close()
|
||||
}
|
||||
|
||||
// SY -->
|
||||
companion object {
|
||||
private const val BUFFER_SIZE = 8192
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
||||
private fun StructStat.toArchiveStat() = ArchiveEntry.StructStat().apply {
|
||||
stDev = st_dev
|
||||
stMode = st_mode
|
||||
stNlink = st_nlink.toInt()
|
||||
stUid = st_uid
|
||||
stGid = st_gid
|
||||
stRdev = st_rdev
|
||||
stSize = st_size
|
||||
stBlksize = st_blksize
|
||||
stBlocks = st_blocks
|
||||
stAtim = timespec(st_atime)
|
||||
stMtim = timespec(st_mtime)
|
||||
stCtim = timespec(st_ctime)
|
||||
stIno = st_ino
|
||||
}
|
||||
|
||||
private fun timespec(tvSec: Long) = ArchiveEntry.StructTimespec().also { it.tvSec = tvSec }
|
||||
@@ -3,19 +3,6 @@ package tachiyomi.core.common.storage
|
||||
import android.content.Context
|
||||
import android.os.ParcelFileDescriptor
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||
import logcat.LogPriority
|
||||
import net.lingala.zip4j.exception.ZipException
|
||||
import net.lingala.zip4j.io.inputstream.ZipInputStream
|
||||
import net.lingala.zip4j.io.outputstream.ZipOutputStream
|
||||
import net.lingala.zip4j.model.LocalFileHeader
|
||||
import net.lingala.zip4j.model.ZipParameters
|
||||
import tachiyomi.core.common.util.system.ImageUtil
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.nio.channels.FileChannel
|
||||
|
||||
val UniFile.extension: String?
|
||||
get() = name?.substringAfterLast('.')
|
||||
@@ -26,200 +13,5 @@ val UniFile.nameWithoutExtension: String?
|
||||
val UniFile.displayablePath: String
|
||||
get() = filePath ?: uri.toString()
|
||||
|
||||
fun UniFile.openReadOnlyChannel(context: Context): FileChannel {
|
||||
return ParcelFileDescriptor.AutoCloseInputStream(context.contentResolver.openFileDescriptor(uri, "r")).channel
|
||||
// SY -->
|
||||
}
|
||||
|
||||
fun UniFile.isEncryptedZip(): Boolean {
|
||||
return try {
|
||||
val stream = ZipInputStream(this.openInputStream())
|
||||
stream.nextEntry
|
||||
stream.close()
|
||||
false
|
||||
} catch (zipException: ZipException) {
|
||||
if (zipException.type == ZipException.Type.WRONG_PASSWORD) {
|
||||
true
|
||||
} else {
|
||||
throw zipException
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun UniFile.testCbzPassword(): Boolean {
|
||||
return try {
|
||||
val stream = ZipInputStream(this.openInputStream())
|
||||
stream.setPassword(CbzCrypto.getDecryptedPasswordCbz())
|
||||
stream.nextEntry
|
||||
stream.close()
|
||||
true
|
||||
} catch (zipException: ZipException) {
|
||||
if (zipException.type == ZipException.Type.WRONG_PASSWORD) {
|
||||
false
|
||||
} else {
|
||||
throw zipException
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun UniFile.addStreamToZip(inputStream: InputStream, filename: String, password: CharArray? = null) {
|
||||
val zipOutputStream =
|
||||
if (password != null) {
|
||||
ZipOutputStream(this.openOutputStream(), password)
|
||||
} else {
|
||||
ZipOutputStream(this.openOutputStream())
|
||||
}
|
||||
|
||||
val zipParameters = ZipParameters()
|
||||
zipParameters.fileNameInZip = filename
|
||||
|
||||
if (password != null) CbzCrypto.setZipParametersEncrypted(zipParameters)
|
||||
zipOutputStream.putNextEntry(zipParameters)
|
||||
|
||||
zipOutputStream.use { output ->
|
||||
inputStream.use { input ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzips encrypted or unencrypted zip files using zip4j.
|
||||
* The caller is responsible to ensure, that the file this is called from is a zip archive
|
||||
*/
|
||||
fun UniFile.unzip(destination: File, onlyCopyImages: Boolean = false) {
|
||||
destination.mkdirs()
|
||||
if (!destination.isDirectory) return
|
||||
|
||||
val zipInputStream = ZipInputStream(this.openInputStream())
|
||||
var fileHeader: LocalFileHeader?
|
||||
|
||||
if (this.isEncryptedZip()) {
|
||||
zipInputStream.setPassword(CbzCrypto.getDecryptedPasswordCbz())
|
||||
}
|
||||
try {
|
||||
while (
|
||||
run {
|
||||
fileHeader = zipInputStream.nextEntry
|
||||
fileHeader != null
|
||||
}
|
||||
) {
|
||||
val tmpFile = File("${destination.absolutePath}/${fileHeader!!.fileName}")
|
||||
|
||||
if (onlyCopyImages) {
|
||||
if (!fileHeader!!.isDirectory && ImageUtil.isImage(fileHeader!!.fileName)) {
|
||||
tmpFile.createNewFile()
|
||||
tmpFile.outputStream().buffered().use { tmpOut ->
|
||||
zipInputStream.buffered().copyTo(tmpOut)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!fileHeader!!.isDirectory && ImageUtil.isImage(fileHeader!!.fileName)) {
|
||||
tmpFile.createNewFile()
|
||||
tmpFile
|
||||
.outputStream()
|
||||
.buffered()
|
||||
.use { zipInputStream.buffered().copyTo(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
zipInputStream.close()
|
||||
} catch (zipException: ZipException) {
|
||||
if (zipException.type == ZipException.Type.WRONG_PASSWORD) {
|
||||
logcat(LogPriority.WARN) {
|
||||
"Wrong CBZ archive password for: ${this.name} in: ${this.parentFile?.name}"
|
||||
}
|
||||
} else {
|
||||
throw zipException
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun UniFile.addFilesToZip(files: List<UniFile>, password: CharArray? = null) {
|
||||
val zipOutputStream =
|
||||
if (password != null) {
|
||||
ZipOutputStream(this.openOutputStream(), password)
|
||||
} else {
|
||||
ZipOutputStream(this.openOutputStream())
|
||||
}
|
||||
|
||||
files.forEach {
|
||||
val zipParameters = ZipParameters()
|
||||
if (password != null) CbzCrypto.setZipParametersEncrypted(zipParameters)
|
||||
zipParameters.fileNameInZip = it.name
|
||||
|
||||
zipOutputStream.putNextEntry(zipParameters)
|
||||
|
||||
it.openInputStream().use { input ->
|
||||
input.copyTo(zipOutputStream)
|
||||
}
|
||||
zipOutputStream.closeEntry()
|
||||
}
|
||||
zipOutputStream.close()
|
||||
}
|
||||
|
||||
fun UniFile.getZipInputStream(filename: String): InputStream? {
|
||||
val zipInputStream = ZipInputStream(this.openInputStream())
|
||||
var fileHeader: LocalFileHeader?
|
||||
|
||||
if (this.isEncryptedZip()) zipInputStream.setPassword(CbzCrypto.getDecryptedPasswordCbz())
|
||||
|
||||
try {
|
||||
while (
|
||||
run {
|
||||
fileHeader = zipInputStream.nextEntry
|
||||
fileHeader != null
|
||||
}
|
||||
) {
|
||||
if (fileHeader?.fileName == filename) return zipInputStream
|
||||
}
|
||||
} catch (zipException: ZipException) {
|
||||
if (zipException.type == ZipException.Type.WRONG_PASSWORD) {
|
||||
logcat(LogPriority.WARN) {
|
||||
"Wrong CBZ archive password for: ${this.name} in: ${this.parentFile?.name}"
|
||||
}
|
||||
} else {
|
||||
throw zipException
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun UniFile.getCoverStreamFromZip(): InputStream? {
|
||||
val zipInputStream = ZipInputStream(this.openInputStream())
|
||||
var fileHeader: LocalFileHeader?
|
||||
val fileHeaderList: MutableList<LocalFileHeader?> = mutableListOf()
|
||||
|
||||
if (this.isEncryptedZip()) zipInputStream.setPassword(CbzCrypto.getDecryptedPasswordCbz())
|
||||
|
||||
try {
|
||||
while (
|
||||
run {
|
||||
fileHeader = zipInputStream.nextEntry
|
||||
fileHeader != null
|
||||
}
|
||||
) {
|
||||
fileHeaderList.add(fileHeader)
|
||||
}
|
||||
var coverHeader = fileHeaderList
|
||||
.mapNotNull { it }
|
||||
.sortedWith { f1, f2 -> f1.fileName.compareToCaseInsensitiveNaturalOrder(f2.fileName) }
|
||||
.find { !it.isDirectory && ImageUtil.isImage(it.fileName) }
|
||||
|
||||
val coverStream = coverHeader?.fileName?.let { this.getZipInputStream(it) }
|
||||
if (coverStream != null) {
|
||||
if (!ImageUtil.isImage(coverHeader?.fileName) { coverStream }) coverHeader = null
|
||||
}
|
||||
return coverHeader?.fileName?.let { getZipInputStream(it) }
|
||||
} catch (zipException: ZipException) {
|
||||
if (zipException.type == ZipException.Type.WRONG_PASSWORD) {
|
||||
logcat(LogPriority.WARN) {
|
||||
"Wrong CBZ archive password for: ${this.name} in: ${this.parentFile?.name}"
|
||||
}
|
||||
return null
|
||||
} else {
|
||||
throw zipException
|
||||
}
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
fun UniFile.openFileDescriptor(context: Context, mode: String): ParcelFileDescriptor =
|
||||
context.contentResolver.openFileDescriptor(uri, mode) ?: error("Failed to open file descriptor: $displayablePath")
|
||||
|
||||
@@ -32,9 +32,7 @@ jsoup = "org.jsoup:jsoup:1.18.1"
|
||||
|
||||
disklrucache = "com.jakewharton:disklrucache:2.0.2"
|
||||
unifile = "com.github.tachiyomiorg:unifile:e0def6b3dc"
|
||||
common-compress = "org.apache.commons:commons-compress:1.26.2"
|
||||
junrar = "com.github.junrar:junrar:7.5.5"
|
||||
zip4j = "net.lingala.zip4j:zip4j:2.11.5"
|
||||
libarchive = "me.zhanghai.android.libarchive:library:1.1.0"
|
||||
|
||||
sqlite-framework = { module = "androidx.sqlite:sqlite-framework", version.ref = "sqlite" }
|
||||
sqlite-ktx = { module = "androidx.sqlite:sqlite-ktx", version.ref = "sqlite" }
|
||||
@@ -105,7 +103,6 @@ detekt-rules-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatt
|
||||
detekt-rules-compose = { module = "io.nlopez.compose.rules:detekt", version.ref = "detektCompose" }
|
||||
|
||||
[bundles]
|
||||
archive = ["common-compress", "junrar"]
|
||||
okhttp = ["okhttp-core", "okhttp-logging", "okhttp-brotli", "okhttp-dnsoverhttps"]
|
||||
js-engine = ["quickjs-android"]
|
||||
sqlite = ["sqlite-framework", "sqlite-ktx", "sqlite-android"]
|
||||
|
||||
@@ -447,4 +447,9 @@
|
||||
<string name="favorites_sync_done_errors_message">حدث خطا اثناء المزامنه وتم تجاهلها</string>
|
||||
<string name="favorites_sync_verifying_library">تاكيد المكتبه المحليه</string>
|
||||
<string name="favorites_sync_network_error">خطأ في الشبكة!</string>
|
||||
<string name="action_copy_second_page">نسخ الصفحة الثانية</string>
|
||||
<string name="action_copy_first_page">نسخ الصفحة الأولى</string>
|
||||
<string name="action_copy_combined_page">نسخ الصفحة المجمعة</string>
|
||||
<string name="only_show_updated_entries">إظهار الإدخالات التي تحتوي على فصول جديدة فقط</string>
|
||||
<string name="pref_crop_borders_pager">قص اطراف الصفحات</string>
|
||||
</resources>
|
||||
@@ -279,7 +279,6 @@
|
||||
<string name="wrong_cbz_archive_password">Wrong CBZ archive password</string>
|
||||
<string name="encryption_type">Encryption type</string>
|
||||
<string name="aes_256">AES 256</string>
|
||||
<string name="aes_192">AES 192</string>
|
||||
<string name="aes_128">AES 128</string>
|
||||
<string name="standard_zip_encryption">Standard zip encryption (fast but insecure)</string>
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
@@ -0,0 +1,536 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="action_search_manually">Mano-manong maghanap</string>
|
||||
<string name="action_migrate_now">Maglipat na</string>
|
||||
<string name="action_copy_now">Kopyahin na</string>
|
||||
<string name="action_edit_info">E-edit ang impo</string>
|
||||
<string name="pref_category_all_sources">Lahat ng mga Source</string>
|
||||
<string name="pref_category_fork">Mga Setting ng Fork</string>
|
||||
<string name="pref_ehentai_summary">Mag-login sa E/ExHentai, pag-sync ng gallery</string>
|
||||
<string name="pref_mangadex_summary">Pag-login sa Mangadex, sundin ang pag-sync</string>
|
||||
<string name="changelog_version">Bersyon %1$s</string>
|
||||
<string name="enable_exhentai">Paganahin ang ExHentai</string>
|
||||
<string name="requires_login">Kinakailangan ng login</string>
|
||||
<string name="use_hentai_at_home">Gamitin ang Hentai@Home Network</string>
|
||||
<string name="use_hentai_at_home_option_1">Anumang Client (Inirerekomenda)</string>
|
||||
<string name="use_hentai_at_home_option_2">Default na port ng client lamang</string>
|
||||
<string name="show_japanese_titles">Ipakita ang mga title na Japanese sa resulta ng paghahanap</string>
|
||||
<string name="show_japanese_titles_option_1">Kasalukuyang nagpapakita ng mga Japanese na title sa mga resulta ng paghahanap. I-clear ang cache ng kabanata pagkatapos baguhin ito (sa Karagdagan na seksyion)</string>
|
||||
<string name="use_original_images">Gamitin ang orihinal na imahe</string>
|
||||
<string name="use_original_images_on">Kasalukuyang gumagamit ng orihinal na imahe</string>
|
||||
<string name="use_original_images_off">Kasalukuyang gumagamit ng na-resample na imahe</string>
|
||||
<string name="watched_tags_summary">Nagbubukas ng webview sa iyong page ng watched tags ng E/ExHentai</string>
|
||||
<string name="watched_tags_exh">Mga Watched Tag ng ExHentai</string>
|
||||
<string name="tag_filtering_threshold">Pag-filter ng threshold sa Tag</string>
|
||||
<string name="tag_filtering_threshhold_error">Dapat nasa pagitan ng -9999 at 0!</string>
|
||||
<string name="tag_watching_threshhold_error">Dapat nasa pagitan ng 0 at 9999!</string>
|
||||
<string name="tag_watching_threshhold_summary">Ang mga kamakailang in-upload na gallery ay isasama sa watched screen kung mayroon itong hindi bababa sa isang watched tag na may positibong weight, at ang kabuuang weight ng mga watched tags nito ay nagkakabigay ng halagang ito o mas mataas. Ang threshold na ito ay maaaring itakda sa pagitan ng 0 at 9999. Kasalukuyan: %1$d</string>
|
||||
<string name="watched_list_state_summary">Kapag nagba-browse sa ExHentai/E-Hentai, dapat paganahin bilang default na filter para sa watched list</string>
|
||||
<string name="eh_image_quality_summary">Kalidad ng mga na-download na imahe</string>
|
||||
<string name="eh_image_quality">Kalidad ng imahe</string>
|
||||
<string name="eh_image_quality_auto">Awto</string>
|
||||
<string name="pref_enhanced_e_hentai_view">Pinahusay na pagba-browse sa E/ExHentai</string>
|
||||
<string name="pref_enhanced_e_hentai_view_summary">Paganahin/Patayin ang pinahusay na browse menu para sa E/ExHentai</string>
|
||||
<string name="favorites_sync">Pag-sync ng mga Paborito ng E-Hentai</string>
|
||||
<string name="ignore_sync_errors_summary">Huwag agad mag-abort kapag may mga error sa panahon ng proseso ng sync. Ang mga error ay magpapakita pa rin pagkatapos ng pagkumpleto ng sync. Maaring magdulot ng pagkawala ng mga paborito sa ilang kaso. Kapaki-pakinabang ito kapag nag-sync ng malalaking aklatan.</string>
|
||||
<string name="force_sync_state_reset">Pilitin ang pag-reset ng estado ng pag-sync</string>
|
||||
<string name="force_sync_state_reset_summary">Isinasagawa ang buong pag-resynchonize sa susunod na sync. Hindi isasama ang mga pagtanggal. Lahat ng mga paborito sa app ay muling iu-upload sa ExHentai at lahat ng mga paborito sa ExHentai ay muling iu-download sa app. Kapaki-pakinabang ito para sa pagkumpuni ng sync matapos itong maantala.</string>
|
||||
<string name="time_between_batches">Oras sa pagitan ng mga batch ng pag-update</string>
|
||||
<string name="time_between_batches_never">Huwag kailanman i-update ang mga gallery</string>
|
||||
<string name="time_between_batches_1_hour">1 oras</string>
|
||||
<string name="time_between_batches_2_hours">2 oras</string>
|
||||
<string name="time_between_batches_3_hours">3 oras</string>
|
||||
<string name="time_between_batches_6_hours">6 (na) oras</string>
|
||||
<string name="time_between_batches_12_hours">12 (na) oras</string>
|
||||
<string name="time_between_batches_24_hours">24 (na) oras</string>
|
||||
<string name="show_updater_statistics">Ipakita ang mga istatistika ng updater</string>
|
||||
<string name="gallery_updater_statistics_collection">Nangongolekta ng mga istatistika…</string>
|
||||
<string name="gallery_updater_statistics">Mga istatistika ng updater ng gallery</string>
|
||||
<string name="gallery_updater_stats_text">Huling pinatakbo ng updater mula %1$s, at na-check ang %2$d sa %3$d na mga gallery na handa nang i-check.</string>
|
||||
<string name="gallery_updater_not_ran_yet">Hindi pa tumatakbo ang updater.</string>
|
||||
<string name="eh_settings_successfully_uploaded">Matagumpay na na-upload ang mga setting!</string>
|
||||
<string name="eh_settings_configuration_failed">Nabigo ang configuration!</string>
|
||||
<string name="skip_page_restyling">Laktawan ang pag-restyle ng pahina</string>
|
||||
<string name="custom_igneous_cookie">Custom na igneous cookie</string>
|
||||
<string name="custom_igneous_cookie_message">May ilang mga user na hindi makakapasok sa ExHentai sa normal na paraan, at kailangan nilang magbigay ng isang partikular na igneous cookie value, ang opsiyong ito ay para sa mga user na iyon.</string>
|
||||
<string name="developer_tools">Mga tool ng Developer</string>
|
||||
<string name="toggle_hentai_features">Paganahin ang pinagsamang mga feature ng hentai</string>
|
||||
<string name="toggle_hentai_features_summary">Ito ay isang eksperimental na tampok na magpapatay ng lahat ng mga hentai na feature kapag ito ay hindi pinagana</string>
|
||||
<string name="toggle_delegated_sources">Paganahin ang itinalagang mga source</string>
|
||||
<string name="toggle_delegated_sources_summary">Ilapat ang %1$s na mga pagpapahusay sa mga sumusunod na source kung naka-install ang mga ito: %2$s</string>
|
||||
<string name="log_level">Level ng pag-log</string>
|
||||
<string name="log_level_summary">Ang pagbabago nito ay maaaring makaapekto sa performance ng app. Piliting i-restart ang app pagkatapos baguhin. Kasalukuyang halaga: %s</string>
|
||||
<string name="open_debug_menu">Buksan ang menu ng pag-debug</string>
|
||||
<string name="open_debug_menu_summary">HUWAG PAKIALAMAN ANG MENU NA ITO MALIBAN KUNG ALAM MO ANG GINAGAWA MO! <font color="red">MAARI ITONG MA-CORRUPT ANG IYONG AKLATAN! </font></string>
|
||||
<string name="clean_orphaned_downloads">Linisin ang na-orphan</string>
|
||||
<string name="clean_read_downloads">Linisin ang nabasa-na</string>
|
||||
<string name="clean_read_entries_not_in_library">Linisin ang mga entry na wala sa aklatan</string>
|
||||
<string name="data_saver_summary">I-compress ang mga imahe bago mag-download o i-load sa reader</string>
|
||||
<string name="data_saver_downloader">Gumamit ng data saver sa pag-download</string>
|
||||
<string name="data_saver_ignore_jpeg">Di-pansinin ang Jpeg na Imahe</string>
|
||||
<string name="data_saver_ignore_gif">Di-pansinin ang Animation na Gif</string>
|
||||
<string name="data_saver_image_quality">Kalidad ng Imahe</string>
|
||||
<string name="put_merge_in_overflow_summary">Ilagay ang magsama na button sa overflow na menu sa halip na sa entry page</string>
|
||||
<string name="ehentai_prefs_account_settings">Setting ng Account sa E-Hentai na Website</string>
|
||||
<string name="use_hentai_at_home_summary">Gusto mo bang mag-load ng mga imahe sa pamamagitan ng Hentai@Home Network, kung magagamit? Ang pag-disable ng opsiyong ito ay magpapabawas sa dami ng mga pahina na maaari mong tingnan. Maaari kang pumili sa mga sumusunod na opsyon:
|
||||
\nMga Opsiyon:
|
||||
\n- Anumang Client (Inirerekomenda)
|
||||
\n- Default na port ng client lamang (Maaaring mas mabagal. Paganahin lamang ito kung nasa likod ng firewall/proxy na nagba-block ng palabas sa non-standard na port.)</string>
|
||||
<string name="show_japanese_titles_option_2">Kasalukuyang nagpapakita ng mga English/Romanized na title sa mga resulta ng paghahanap. I-clear ang cache ng kabanata pagkatapos baguhin ito (sa Karagdagan na seksyion)</string>
|
||||
<string name="tag_filtering_threshhold_summary">Maaari kang gumamit ng soft filter ng mga tag sa pamamagitan ng pagdaragdag ng mga ito sa My Tags ng E/ExHentai page na may negatibong weight. Kung ang isang gallery ay may mga tag na nagdaragdag ng hanggang sa weight sa ilalim ng halagang ito, ito ay hindi makikita. Ang threshold na ito sa pagitan ng -9999 at 0. Kasalukuyan: %1$d</string>
|
||||
<string name="language_filtering">Pag-filter ng Wika</string>
|
||||
<string name="fromt_page_categories_summary">Anong mga kategorya ang nais mong ipakita sa default sa front page at sa mga paghahanap? Maaari pa rin silang paganahin gamit ng kanilang filter</string>
|
||||
<string name="language_filtering_summary">Kung nais mong itago ang mga gallery sa ilang wika mula sa listahan ng gallery at mga paghahanap, piliin sila sa dialog box na lalabas.
|
||||
\nTandaan na ang mga kalahok na gallery ay hindi kailanman magpapakita, anuman ang iyong query sa paghahanap.
|
||||
\nSa maikli, ang may tsekeng marka ay ibig sabihin ay ibubukod</string>
|
||||
<string name="disable_favorites_uploading">Di-paganahin ang pag-upload ng mga paborito</string>
|
||||
<string name="disable_favorites_uploading_summary">Ang mga paborito ay ina-download lamang mula sa ExHentai. Ang anumang pagbabago sa mga paborito sa app ay hindi mai-a-upload. Ito ay nag-iwas sa aksidenteng pagkawala ng mga paborito sa ExHentai. Tandaan na ang mga pagtanggal ay magpapatuloy pa rin na ma-download (kung inalis mo ang isang paborito sa ExHentai, ito ay tatanggalin din sa app).</string>
|
||||
<string name="show_favorite_sync_notes">Ipakita ang sync note ng mga paborito</string>
|
||||
<string name="action_skip_entry">Huwag maglipat</string>
|
||||
<string name="show_favorite_sync_notes_summary">Magpakita ng ilang impormasyon tungkol sa tampok na pag-sync ng mga paborito</string>
|
||||
<string name="please_login">Maaring mag-log in!</string>
|
||||
<string name="ignore_sync_errors">Huwag pansinin ang mga error sa pag-sync kapag posible</string>
|
||||
<string name="action_start_reading">Simulang magbasa</string>
|
||||
<string name="sync_state_reset">Pag-reset ng kalagayan ng sync</string>
|
||||
<string name="auto_update_restrictions">Mga restriksyon sa awtomatikong pag-update</string>
|
||||
<string name="time_between_batches_48_hours">48 (na) oras</string>
|
||||
<string name="time_between_batches_summary_2">%1$s nagsusuri/nag-update ng mga gallery ng batch. Nangangahulugan ito na maghihintay ito ng %2$d (na) oras, tingnan ang %3$d gallery, maghintay ng %2$d (na) oras, suriin ang %3$d at iba pa…</string>
|
||||
<string name="time_between_batches_summary_1">Kasalukuyang hindi titingnan ng %1$s ang mga gallery sa iyong aklatan para sa mga update.</string>
|
||||
<string name="settings_profile_note_message">Ang app ay magdadagdag ng bagong profile ng mga setting sa E-Hentai at ExHentai upang mapabuti ang performance ng app. Siguruhing mayroon kang hindi hihigit sa tatlong profile sa parehong mga site.
|
||||
\n
|
||||
\nKung wala kang ideya kung ano ang mga setting profiles, malamang ay hindi ito importante, pindutin lang ang ‘OK’.</string>
|
||||
<string name="eh_settings_configuration_failed_message">Nagkaroon ng error sa proseso ng pagsasaayos: %1$s</string>
|
||||
<string name="eh_settings_uploading_to_server">Nag-a-upload ng mga setting sa server</string>
|
||||
<string name="alternative_login_page">Alternatibong login page</string>
|
||||
<string name="enable_source_blacklist">Paganahin ang pag-blacklist ng source</string>
|
||||
<string name="gallery_updater_stats_time">"
|
||||
\nMga gallery na sinuri sa huling:
|
||||
\n- oras: %1$d
|
||||
\n- 6 na oras: %2$d
|
||||
\n- 12 oras: %3$d
|
||||
\n- araw: %4$d
|
||||
\n- 2 araw: %5$d
|
||||
\n- linggo: %6$d
|
||||
\n- buwan: %7$d
|
||||
\n- taon: %8$d"</string>
|
||||
<string name="eh_settings_uploading_to_server_message">Mangyaring maghintay, maaaring tumagal ito ng ilang oras…</string>
|
||||
<string name="eh_settings_out_of_slots_error">Naubusan ng slot na profile sa %1$s, mangyaring tanggalin ang isang profile!</string>
|
||||
<string name="recheck_login_status">Suriin muli ang status sa pag-log in</string>
|
||||
<string name="enable_source_blacklist_summary">Itago ang mga extension/source na hindi compatible sa %1$s. Piliting i-restart ang app pagkatapos baguhin.</string>
|
||||
<string name="starting_cleanup">Sinisimulan na ang paglilinis</string>
|
||||
<string name="delete_unused_chapters">Tanggalin ang hindi umiiral, bahagyang na-download, at nabasang mga folder ng kabanata</string>
|
||||
<string name="no_folders_to_cleanup">Walang folder na linisin</string>
|
||||
<string name="clean_up_downloaded_chapters">Linisin ang mga na-download na kabanata</string>
|
||||
<string name="data_saver_image_quality_summary">Mas mataas na halaga ay nangangahulugang mas mataas na porsiento ng kalidad ng imahe, ngunit ito rin ay nangangahulugang mas malaki ang laki ng file, ang 80 porsyento ay isang magandang median sa pagitan ng laki ng file at kalidad ng imahe</string>
|
||||
<string name="data_saver_image_format_summary_off">Ang file size ng Jpeg ay mas maliit kaysa sa Webp ay (ibig sabihin, mas maraming data ang nai-save), ngunit ginagawa nitong mas mawalan din ng kalidad ang mga imahe.
|
||||
\nKasalukuyang nag-compress bilang Webp</string>
|
||||
<string name="data_saver_color_bw">I-convert bilang Itim at Puti</string>
|
||||
<string name="bandwidth_hero">Bandwidth Hero (kinakailangan ng Bandwidth Hero Proxy server)</string>
|
||||
<string name="log_minimal">Maliit</string>
|
||||
<string name="data_saver_image_format">I-compress bilang Jpeg</string>
|
||||
<string name="data_saver_image_format_summary_on">Ang file size ng Jpeg ay mas maliit kaysa sa Webp ay (ibig sabihin, mas maraming data ang nai-save), ngunit ginagawa nitong mas mawalan din ng kalidad ang mga imahe.
|
||||
\nKasalukuyang nag-compress bilang Jpeg</string>
|
||||
<string name="data_saver_server_summary">Ilagay dito ang url ng Bandwidth Hero Proxt server</string>
|
||||
<string name="log_extra">Dagdag</string>
|
||||
<string name="clear_db_exclude_read">Panatilihin ang mga entry na may mga nabasang kabanata</string>
|
||||
<string name="log_minimal_desc">Mga kritikal na error lamang</string>
|
||||
<string name="log_extra_desc">I-log lahat</string>
|
||||
<string name="toggle_expand_search_filters">Palakihin lahat ng filter ng pagahahap bilang default</string>
|
||||
<string name="put_recommends_in_overflow_summary">Ilagay ang rekomendasyon na button sa overflow menu sa halip na sa entry page</string>
|
||||
<string name="put_merge_in_overflow">Isama sa overflow</string>
|
||||
<string name="put_recommends_in_overflow">Mga rekomendasyon sa overflow</string>
|
||||
<string name="pref_previews_row_count">Mga preview ng row count</string>
|
||||
<string name="pref_hide_updates_button">Ipakita ang mga update sa nav</string>
|
||||
<string name="pref_hide_history_button">Ipakita ang nakaraan sa nav</string>
|
||||
<string name="pref_show_bottom_bar_labels">Laging ipakita ang mga label sa nav</string>
|
||||
<string name="pref_sorting_settings">Mga setting ng Pagso-sort</string>
|
||||
<string name="pref_skip_pre_migration_summary">Gumamit ng huling na-save na kagustuhan at mga source para mag-lipat ng maramihan</string>
|
||||
<string name="library_group_updates">Mga update sa dynamic na kategorya ng aklatan</string>
|
||||
<string name="library_group_updates_global">Palaging ilunsad ang panglahatang pag-update</string>
|
||||
<string name="library_group_updates_all">Ilunsad ang mga update sa kategorya sa lahat ng oras</string>
|
||||
<string name="library_group_updates_all_but_ungrouped">Ilunsad ang mga panglahatang pag-update para lang sa hindi naka-grupo, mga update sa kategorya para sa iba</string>
|
||||
<string name="pref_mark_read_dupe_chapters">Markahan ang mga nadobleng kabanata bilang nabasa na</string>
|
||||
<string name="pref_mark_read_dupe_chapters_summary">Markahan ang mga nadobleng kabanata bilang nabasa pagkatapos basahin</string>
|
||||
<string name="pref_library_mark_duplicate_chapters">Markahan ang bagong nadobleng kabanata bilang nabasa na</string>
|
||||
<string name="pref_library_mark_duplicate_chapters_summary">Awtomatikong markahan ang mga bagong kabanata bilang nabasa kung nabasa na ito dati</string>
|
||||
<string name="update_30min">Kada 30 minuto</string>
|
||||
<string name="update_1hour">Kada oras</string>
|
||||
<string name="update_3hour">Kada 3 oras</string>
|
||||
<string name="pref_hide_feed">Itago ang Feed na tab</string>
|
||||
<string name="pref_feed_position">Posisyon ng Feed tab</string>
|
||||
<string name="pref_local_source_hidden_folders_summery">Payagan ang lokal na source na magbasa ang nakatagong mga folder</string>
|
||||
<string name="all_read_entries">Lahat ng nabasang entry</string>
|
||||
<string name="sync_error">Nabigo ang pag-sync ng aklatan</string>
|
||||
<string name="pref_sync_now">Mag-sync ngayon</string>
|
||||
<string name="pref_sync_service">Serbisyo</string>
|
||||
<string name="pref_sync_interval">Dalas ng pag-synchronize</string>
|
||||
<string name="google_drive_sync_data_purged">Natanggal ang datos ng pag-sync mula sa Google Drive</string>
|
||||
<string name="google_drive_login_success">Naka-log in sa Google Drive</string>
|
||||
<string name="error_deleting_google_drive_lock_file">Nagka-error sa Pag-alis ng Lock File ng Google Drive</string>
|
||||
<string name="pref_sync_options">Gumawa ng mga trigger sa pag-sync</string>
|
||||
<string name="sync_on_chapter_open">Mag-sync sa Pagbukas ng Kabanata</string>
|
||||
<string name="biometric_lock_times_empty">Wala kang mga oras ng biometric lock. I-tap ang plus na button upang lumikha nito.</string>
|
||||
<string name="biometric_lock_end_time">Ilagay ang oras ng pagtatapos</string>
|
||||
<string name="wednesday">Miyerkules</string>
|
||||
<string name="saturday">Sabado</string>
|
||||
<string name="cbz_archive_password">Password ng CBZ archive</string>
|
||||
<string name="aggressively_load_pages">Agresibong mag-load ng mga pahina</string>
|
||||
<string name="skip_queue_on_retry">Laktawan ang queue sa pag-ulit</string>
|
||||
<string name="reader_preload_amount">Dami ng Pag-preload ng Pahina</string>
|
||||
<string name="reader_preload_amount_4_pages">4 na Pahina</string>
|
||||
<string name="reader_preload_amount_8_pages">8 na Pahina</string>
|
||||
<string name="reader_preload_amount_14_pages">14 na Pahina</string>
|
||||
<string name="reader_cache_size">Laki ng cache sa Reader</string>
|
||||
<string name="pref_show_vert_seekbar_landscape">Ipakita ang patayong seekbar sa landscape</string>
|
||||
<string name="pref_left_handed_vertical_seekbar_summary">Magpapalit kung saang bahagi naka-on ang seekbar</string>
|
||||
<string name="pref_force_horz_seekbar">Pilitin ang pahalang na seekbar</string>
|
||||
<string name="eh_retry_all">Subukan muli ang lahat</string>
|
||||
<string name="eh_autoscroll_freq_invalid">Di-balidong frequency</string>
|
||||
<string name="eh_retry_all_help">Tulong sa subukan muli lahat</string>
|
||||
<string name="eh_boost_page_help">Tulong sa pag-boost ng pahina</string>
|
||||
<string name="eh_boost_page_errored">Ang pahina ay bigong mag-load, muling pindutin ang subukan muli na button!</string>
|
||||
<string name="eh_boost_page_downloading">Ang pahinang ito ay nagda-download na!</string>
|
||||
<string name="eh_boost_invalid_loader">Ang pahinang ito ay hindi pwedeng maboost (di-balidong loader ng pahina)!</string>
|
||||
<string name="page_downloading">Nagdadownload ng Pahina</string>
|
||||
<string name="download_threads">Mga thread sa pag-download</string>
|
||||
<string name="download_threads_summary">Ang mas mataas na halaga ay maaaring mapabilis nang malaki ang pag-download ng imahe, ngunit maaari ring mag-trigger ng mga ban. Ang inirerekomendang halaga ay 2 o 3. Kasalukuyang halaga: %s</string>
|
||||
<string name="aggressively_load_pages_summary">Dahan-dahang i-download ang buong kabanata habang nagbabasa sa halip na i-load lang ang mga pahinang iyong binabasa.</string>
|
||||
<string name="skip_queue_on_retry_summary">Karaniwan, kapag pindutin mo ang retry button sa isang nabigong pag-download, maghihintay ito hanggang matapos ang pag-download ng huling pahina bago magsimulang muli ang pag-download ng nabigong pahina. Kapag pinagana ito, agad itong magsisimula ulit ang pag-download ng nabigong pahina pagkatapos mong pindutin ang subukan muli button.</string>
|
||||
<string name="reader_preload_amount_6_pages">6 na Pahina</string>
|
||||
<string name="reader_preload_amount_10_pages">10 Pahina</string>
|
||||
<string name="reader_preload_amount_12_pages">12 Pahina</string>
|
||||
<string name="reader_preload_amount_20_pages">20 Pahina</string>
|
||||
<string name="reader_preload_amount_16_pages">16 na Pahina</string>
|
||||
<string name="reader_cache_size_summary">Ang dami ng mga imahe na i-save sa iyong device habang nagbabasa. Mas mataas na value ay magreresulta sa mas magandang karanasan sa pagbabasa, ngunit may kaakibat na mas mataas na paggamit ng disk space</string>
|
||||
<string name="enable_zoom_out">Paganahin ang pag-zoom out</string>
|
||||
<string name="tap_scroll_page">I-tap ang mag-scroll ayon sa pahina</string>
|
||||
<string name="reader_bottom_buttons_summary">I-customize kung anong mga button ang lalabas sa ibaba ng reader</string>
|
||||
<string name="reader_preload_amount_summary">Ang dami ng mga pahina na i-preload kapag nagbabasa. Mas mataas na value ay magreresulta sa mas magandang karanasan sa pagbabasa, pero may kaakibat na mas mataas na paggamit ng cache. Inirerekomenda na palakihin ang alokasyon ng cache kapag gumagamit ng mas malalaking value</string>
|
||||
<string name="preserve_reading_position">Panatilihin ang posisyon sa pagbabasa sa mga nabasang entry</string>
|
||||
<string name="auto_webtoon_mode_summary">Gamitin ang auto webtoon mode para sa mga entry na natukoy na malamang na gumamit ng mahabang strip na pormat</string>
|
||||
<string name="tap_scroll_page_summary">Ang pag-tap ay mag-i-scroll ayon sa pahina sa halip na laki ng screen kapag pinagana ang opsyong ito</string>
|
||||
<string name="reader_bottom_buttons">Mga Button sa Ibaba ng Reader</string>
|
||||
<string name="pref_force_horz_seekbar_summary">Alisin ang patayong seekbar nang tuluyan sa pabor na pahalang</string>
|
||||
<string name="pref_left_handed_vertical_seekbar">Pang-kaliwang kamay na patayong seekbar</string>
|
||||
<string name="pref_show_vert_seekbar_landscape_summary">Pinapagana ang patayong seekbar kapag nasa landscape</string>
|
||||
<string name="eh_boost_page">I-boost ang pahina</string>
|
||||
<string name="eh_boost_page_help_message">Karaniwan, ang downloader ay maaari lamang mag-download ng isang tiyak na bilang ng mga pahina nang sabay-sabay. Ibig sabihin, maaari kang maghintay para sa isang pahina na mag-download ngunit hindi magsisimula ang downloader na i-download ang pahina hanggang sa magkaroon ito ng libreng download slot. Ang pagpindot sa \'I-boost ang pahina\' ay pipilitin ang downloader na simulan ang pag-download ng kasalukuyang pahina, kahit na walang available na slot.</string>
|
||||
<string name="eh_autoscroll_help">Tulong sa autoscroll</string>
|
||||
<string name="eh_boost_page_invalid">Ang pahinang ito ay hindi maboost (di-balidong pahina)!</string>
|
||||
<string name="eh_autoscroll_help_message">Awtomatikong mag-scroll sa susunod na pahina sa itinakdang interval. Ang interval ay itinakda sa mga segundo.</string>
|
||||
<string name="eh_retry_all_help_message">Ibalik ang lahat ng nabigong pahina sa queue ng pag-download.</string>
|
||||
<string name="eh_boost_page_downloaded">Ang pahinang ito ay na-download na!</string>
|
||||
<string name="eh_boost_boosted">Na-boost ang kasalukuyang page!</string>
|
||||
<string name="pref_feed_position_summery">Gusto mo bang ang feed tab ang maging unang tab sa maghanap? Gagawin nitong default na tab kapag binubuksan ang maghanap, hindi inirerekomenda kung ikaw ay nasa data o isang metered na network</string>
|
||||
<string name="thursday">Huwebes</string>
|
||||
<string name="custom_entry_info">Custom na inpo ng entry</string>
|
||||
<string name="pref_source_source_filtering">I-filter ang mga source sa kategorya</string>
|
||||
<string name="pref_source_source_filtering_summery">I-filter ang mga source na nasa mga kategorya, na ginagawang hindi mailalagay sa ilalim ng wika ang mga source kung sila ay nasa isang kategorya</string>
|
||||
<string name="pref_source_navigation">Palitan ang pinakabago na button</string>
|
||||
<string name="pref_source_navigation_summery">Palitan ang pinakabago na button ng custom na view ng pag-browse na kasali ng pinakabago at maghanap</string>
|
||||
<string name="pref_local_source_hidden_folders">Mga nakatagong folder ng lokal na source</string>
|
||||
<string name="label_triggers">Mga trigger</string>
|
||||
<string name="sync_complete">Kumpleto na ang pag-sync ng aklatan</string>
|
||||
<string name="pref_sync_host_summ">Ilagay ang host address sa pag-sync ng iyong akalatan</string>
|
||||
<string name="pref_sync_api_key_summ">Ilagay ang API key para ma-synchronize ang iyong akalatan</string>
|
||||
<string name="sync_in_progress">Isinasagawa na ang pag-sync</string>
|
||||
<string name="pref_sync_now_group_title">Mga aksiyon sa Pag-Sync</string>
|
||||
<string name="pref_sync_now_subtitle">Magsimula ng agarang pag-synchronize ng iyong data</string>
|
||||
<string name="pref_sync_automatic_category">Awtomatikong Pag-synchronize</string>
|
||||
<string name="pref_choose_what_to_sync">Piliin ano ang i-sync</string>
|
||||
<string name="last_synchronization">Huling pag-sync: %1$s</string>
|
||||
<string name="pref_google_drive_sign_in">Mag sign-in</string>
|
||||
<string name="google_drive_sync_data_not_found">Walang nahanap na datos ng pag-sync sa Google Drive</string>
|
||||
<string name="pref_google_drive_purge_sync_data">I-clear ang Datos ng Pag-sync mula sa Google Drive</string>
|
||||
<string name="google_drive_sync_data_purge_error">Nagkaroon ng error sa pag-linis ng datos ng pag-sync mula sa Google Drive, Subukang mag sign-in muli.</string>
|
||||
<string name="google_drive_login_failed">Nabigong mag-log in sa Google Drive: %s</string>
|
||||
<string name="google_drive_not_signed_in">Hindi naka sign-in sa Google Drive</string>
|
||||
<string name="error_uploading_sync_data">Nagka-error sa pag-upload ng data sa pag-sync sa Google Drive</string>
|
||||
<string name="pref_purge_confirmation_title">Kumpirmasyon sa paglinis</string>
|
||||
<string name="error_before_sync_gdrive">Error bago nag-sync: %s</string>
|
||||
<string name="pref_purge_confirmation_message">Linisin ang datos ng pag-sync ay matatanggal lahat ng iyong naka-sync na datos mula sa Google Drive. Sigurado ka bang gusto mong magpatuloy?</string>
|
||||
<string name="pref_sync_options_summ">Upang magamit sa pag-set ng mga sync trigger</string>
|
||||
<string name="sync_on_app_resume">Mag-sync sa Pagpapatuloy ng App</string>
|
||||
<string name="sync_on_chapter_read">Mag-sync sa Pagbasa ng Kabanata</string>
|
||||
<string name="sync_on_app_start">Mag-sync sa Pag-start ng App</string>
|
||||
<string name="sync_library">Mag-sync ng Akalatan</string>
|
||||
<string name="biometric_lock_times">Mga oras ng biometric lock</string>
|
||||
<string name="action_edit_biometric_lock_times">I-edit ang oras ng pag-lock</string>
|
||||
<string name="biometric_lock_time_conflicts">Ang oras ng lock ay sumasalungat sa isa na umiiral na!</string>
|
||||
<string name="biometric_lock_start_time">Ilagay ang oras ng pagsisimula</string>
|
||||
<string name="delete_time_range">Tanggalin ang pagitan ng oras</string>
|
||||
<string name="delete_time_range_confirmation">Gusto mo bang tanggalin ang pagitan ng oras na %s?</string>
|
||||
<string name="biometric_lock_days">Araw ng Biometric lock</string>
|
||||
<string name="biometric_lock_days_summary">Araw upang mai-lock ang app</string>
|
||||
<string name="sunday">Linggo</string>
|
||||
<string name="monday">Lunes</string>
|
||||
<string name="tuesday">Martes</string>
|
||||
<string name="friday">Biyernes</string>
|
||||
<string name="encrypt_database">I-encrypt ang database</string>
|
||||
<string name="encrypt_database_subtitle">Kinakailangang mag-restart ng app upang magkabisa</string>
|
||||
<string name="encrypt_database_message"><font color=\'red\'>ANG PAGPAPAGANA NITO AY GAGAWA NG BAGONG DATABASE. GAMITIN ANG MGA HAKBANG NA ITO UPANG MAPANATILI ANG IYONG DATA<br>1. MGA SETTING -> BACKUP -> GUMAWA<br>2. MGA SETTING NG SISTEMA -> I-CLEAR ANG APP DATA<br>3. BUKSAN ANG APP AT PAGANAHIN ITO<br>4. MGA SETTING NG SISTEMA -> PILITING MAG-RESTART<br>5. MGA SETTING -> BACKUP -> I-RESTORE</font></string>
|
||||
<string name="set_cbz_zip_password">I-set ang archive password ng CBZ</string>
|
||||
<string name="password_protect_downloads">Protektahan ng password ang mga download</string>
|
||||
<string name="delete_cbz_archive_password">Alisin ang password ng CBZ archive</string>
|
||||
<string name="wrong_cbz_archive_password">Maling password ng CBZ archive</string>
|
||||
<string name="password_protect_downloads_summary">I-encrypt ang mga na-download na CBZ archive gamit ang ibinigay na password.
|
||||
\nBABALA: ANG DATOS SA LOOB NG ARCHIVE AY MAWAWALA NANG TULUYAN KAPAG NAKALIMUTAN ANG PASSWORD</string>
|
||||
<string name="encryption_type">Uri ng encryption</string>
|
||||
<string name="standard_zip_encryption">Karaniwang zip encryption (mabilis ngunit hindi secure)</string>
|
||||
<string name="tag_watching_threshhold">Threshold sa Tag Watching</string>
|
||||
<string name="watched_list_default">Default na Kalagayan ng Filter sa Watched List</string>
|
||||
<string name="gallery_update_checker">Tagapag-check ng mga update sa gallery</string>
|
||||
<string name="pref_smooth_scroll">Smooth na pag Awto Scroll</string>
|
||||
<string name="pref_crop_borders_pager">I-crop ang border ng Pahina</string>
|
||||
<string name="pref_crop_borders_continuous_vertical">I-crop ang border sa Tuloy-tuloy na Vertical</string>
|
||||
<string name="action_clean_titles">Linsin ang mga title</string>
|
||||
<string name="frong_page_categories">Kategorya ng Front Page</string>
|
||||
<string name="action_set_first_page_cover">I-set ang unang pahina bilang cover</string>
|
||||
<string name="action_copy_first_page">Kopyahin ang unang pahina</string>
|
||||
<string name="action_share_second_page">I-share ang ikalawang pahina</string>
|
||||
<string name="shift_double_pages">Ilipat ng isang pahina</string>
|
||||
<string name="pref_center_margin">Uri ng gitnang margin</string>
|
||||
<string name="archive_mode_cache_to_disk">Kopyahin sa disk</string>
|
||||
<string name="merge">Pagsamahin</string>
|
||||
<string name="merge_with_another_source">Pagsamahin sa Iba</string>
|
||||
<string name="merge_unknown_entry">Di-kilalang entry ID: %1$d</string>
|
||||
<string name="reset_tags">I-reset ang mga Tag</string>
|
||||
<string name="add_tag">Magdagdag ng Tag</string>
|
||||
<string name="reset_info">I-reset ang Impo</string>
|
||||
<string name="author_hint">May Akda: %1$s</string>
|
||||
<string name="data_saver_exclude">Ibukod mula sa data saver</string>
|
||||
<string name="could_not_find_entry">Hindi mahanap ang entry sa source!</string>
|
||||
<string name="save_search_failed_to_load">Bigong ma-load ang na-save na paghahanap!</string>
|
||||
<string name="save_search_delete">Taggalin ang na-save na search query?</string>
|
||||
<string name="save_search_invalid_name">Di-balidong na-save na pangalan sa paghahanap</string>
|
||||
<string name="invalid_category_name">Di-balidong pangalan ng kategorya</string>
|
||||
<string name="tag_sorting">Mag-sort ng tag</string>
|
||||
<string name="migration">Maglipat</string>
|
||||
<string name="data_to_include_in_migration">Datos na isasama sa paglilipat</string>
|
||||
<string name="use_most_chapters">Gamitin ang source sa karamihan ng mga kabanata (mas mabagal)</string>
|
||||
<string name="search_parameter">Parameter sa paghahanap (hal. language:english)</string>
|
||||
<string name="latest_">Pinakabago: %1$s</string>
|
||||
<string name="migrating_to">lumipat sa</string>
|
||||
<string name="match_pinned_sources">Ipares ang mga naka-pin na source</string>
|
||||
<string name="no_alternatives_found">Walang Alternatibong Nahanap</string>
|
||||
<string name="skipping_">(nilalaktawan ang %1$d)</string>
|
||||
<string name="no_valid_entry">Walang napiling wastong entry</string>
|
||||
<string name="sync_favorites">I-sync ang mga paborito ng EH</string>
|
||||
<string name="favorites_sync_bad_library_state">Hindi magsisimula ang pag-sync ng %1$s hangga\'t ang gallery ay nasa isang kategorya lamang.</string>
|
||||
<string name="favorites_syncing">Nagsi-sync ang mga paborito</string>
|
||||
<string name="favorites_sync_verifying_library">Tinitignan ang lokal na aklatan</string>
|
||||
<string name="favorites_sync_downloading">Mag-download ng mga paborito mula sa remote server</string>
|
||||
<string name="favorites_sync_calculating_local_changes">Kinakalkula ang mga lokal na pagbabago</string>
|
||||
<string name="favorites_sync_unknown_error">Di-kilalang error: %1$s</string>
|
||||
<string name="favorites_sync_unable_to_delete">Hindi matanggal ang mga gallery mula sa mga remote server!</string>
|
||||
<string name="favorites_sync_remove_from_local">Tinatangal ang gallery %1$d ng %2$d mula sa lokal na aklatan</string>
|
||||
<string name="pref_crop_borders_webtoon">I-crop ang border pa-Webtoon</string>
|
||||
<string name="action_copy_combined_page">Kopyahin ang pinagsamang pahina</string>
|
||||
<string name="action_share_first_page">I-share ang unang pahina</string>
|
||||
<string name="action_set_second_page_cover">I-set ang ikalawang pahina bilang cover</string>
|
||||
<string name="action_save_first_page">I-save ang unang pahina</string>
|
||||
<string name="action_share_combined_page">I-share ang pinagsamang pahina</string>
|
||||
<string name="action_copy_second_page">Kopyahin ang ikalawang pahina</string>
|
||||
<string name="share_pages_info">%1$s: %2$s, mga pahinang %3$s</string>
|
||||
<string name="action_save_second_page">I-save ang ikalawang pahina</string>
|
||||
<string name="double_pages">Dobleng pahina</string>
|
||||
<string name="action_save_combined_page">I-save ang pinagsamang pahina</string>
|
||||
<string name="eh_auto_webtoon_snack">Pahinang pa-webtoon na style</string>
|
||||
<string name="page_layout">Layout ng pahina</string>
|
||||
<string name="automatic_orientation">Awtomatiko (base sa oryentasyon)</string>
|
||||
<string name="automatic_can_still_switch">Habang ginagamit ang awtomatikong pag-layout ng pahina, maari ka pa ring magpalit ng layout habang nagbabasa nang hindi ino-override ang setting na ito</string>
|
||||
<string name="invert_double_pages">Baliktarin ang Dobleng pahina</string>
|
||||
<string name="center_margin_double_page">Idagdag sa dobleng Pahina</string>
|
||||
<string name="center_margin">Gitnang Margin</string>
|
||||
<string name="center_margin_none">Wala</string>
|
||||
<string name="center_margin_double_and_wide_page">Idadag sila pareho</string>
|
||||
<string name="single_page">Isang pahina</string>
|
||||
<string name="center_margin_wide_page">Idagdag sa malawak na Pahina</string>
|
||||
<string name="archive_mode_load_into_memory">I-load sa memory</string>
|
||||
<string name="too_many_in_feed">Masyadong maraming source sa iyong feed, hindi maaaring magdagdag ng higit sa 10</string>
|
||||
<string name="pref_center_margin_summary">Maglagay ng spacer upang mabawasan ang deadspace sa mga foldable na device.</string>
|
||||
<string name="archive_mode_load_from_file">Magload mula sa file</string>
|
||||
<string name="pref_archive_reader_mode_summary">Ang paraan kung paano naglo-load ang mga imahe sa loob ng mga archive, tulad ng CBZ o CBR</string>
|
||||
<string name="az_recommends">Tingnan ang Mga Rekomendasyon</string>
|
||||
<string name="entry_merged">Napagsama na ang entry!</string>
|
||||
<string name="failed_merge">Nabigong pagsamahin ang entry: %1$s</string>
|
||||
<string name="merged_already">Ang entry na ito ay pinagsama na sa kasalukuyang entry!</string>
|
||||
<string name="merge_duplicate">Ang pinagsamang entry na ito ay isang kopya!</string>
|
||||
<string name="description_hint">Paglalarawan: %1$s</string>
|
||||
<string name="find_in_another_source">Maghanap sa ibang source</string>
|
||||
<string name="searching_source">Naghahanap sa source…</string>
|
||||
<string name="thumbnail_url_hint">Url ng Thumbnail: %1$s</string>
|
||||
<string name="feed_tab_empty">Wala kang mga source sa iyong feed, pumunta sa itaas na kanan (top-right) upang magdagdag ng isa</string>
|
||||
<string name="data_saver_stop_exclude">Itigil ang pagbubukod mula sa data saver</string>
|
||||
<string name="feed_add">Idagdag ang %1$s sa feed?</string>
|
||||
<string name="automatic_search_error">Nagkaroon ng error sa pagsasagawa ng awtomatikong paghahanap!</string>
|
||||
<string name="pref_tag_sorting">Pagso-sort ng mga tag</string>
|
||||
<string name="saved_searches">Mga Naka-save na Paghahanap</string>
|
||||
<string name="save_search">I-save ang kasalukuyang search query?</string>
|
||||
<string name="save_search_failed_to_load_message">Nagkaroon ng error habang naglo-load ng mga na-save na paghahanap.</string>
|
||||
<string name="save_search_hint">Pangalan ng search</string>
|
||||
<string name="save_search_invalid">Di-balido ang na-save na paghahanap, napalitan ang mga filter</string>
|
||||
<string name="save_search_delete_message">Sigurado ka bang gusto mong tanggalin ang iyong naka-save na query sa paghahanap: \'%1$s\'?</string>
|
||||
<string name="feed_delete">Tanggalin ang feed item?</string>
|
||||
<string name="no_source_categories">Walang kategorya ng source ay available</string>
|
||||
<string name="action_add_tags_message">Basahin ito! Ang mga tag ay dapat eksakto, walang mga bahagyang tugma, hindi mo magagamit ang netorare upang i-filter ang female:netorare o katulad nito!
|
||||
\nAng istilo para sa mga namespace tag ay
|
||||
\n\"female: solo female\"
|
||||
\nnang walang mga panipi (quotes)!
|
||||
\nSuportado ang pagdaragdag ng maraming variant ng parehong tag, kaya huwag mag-atubiling gamitin ang \"tag: netorare\" para sa NHentai at \"female: netorare\" para sa E-Hentai!</string>
|
||||
<string name="action_edit_tags">I-edit ang mga tag</string>
|
||||
<string name="delete_tag_confirmation">Gusto mo bang tanggalin ang tag na %s?</string>
|
||||
<string name="information_empty_tags">Wala kang mga tag. I-tap ang plus na button upang lumikha para sa pag-sort ng iyong aklatan gamit ang mga tag</string>
|
||||
<string name="delete_tag">Taggalin ang tag</string>
|
||||
<string name="error_tag_exists">Umiiral ang tag na ito!</string>
|
||||
<string name="select_none">Walang napili</string>
|
||||
<string name="redundant_extension_message">Ang extension na ito ay redundant at hindi ito gagamitin sa bersyon na ito ng Tachiyomi.</string>
|
||||
<string name="select_sources">Pumili ng mga source</string>
|
||||
<string name="skip_pre_migration">Laktawan bago maglipat</string>
|
||||
<string name="pre_migration_skip_toast">Para makita itong screen na ito, pumunta sa Mga Setting -> Aklatan.</string>
|
||||
<string name="use_intelligent_search">Maghanap ng title + mga keyword ng title</string>
|
||||
<string name="include_extra_search_parameter">Isama ang karagdagang parameter sa paghahanap</string>
|
||||
<string name="use_first_source">Gamitin ang unang source na may alternatibo</string>
|
||||
<string name="hide_not_found_entries">Itago ang mga di-hanap na mga entry</string>
|
||||
<string name="skip_this_step_next_time">Laktawan ang step na ito sa susunod</string>
|
||||
<string name="only_show_updated_entries">Ipakita lamang ang mga entry na may bagong kabanata</string>
|
||||
<string name="match_enabled_sources">Paganahin ang mga nakapares na mga source</string>
|
||||
<string name="no_chapters_found_for_migration">Walang nakitang kabanata, hindi magagamit ang entry na ito para sa paglipat</string>
|
||||
<string name="stop_migrating">Ihinto ang paglilipat?</string>
|
||||
<string name="action_stop">Itigil</string>
|
||||
<string name="tracking_status">Status ng pagta-track</string>
|
||||
<string name="ungrouped">Di-nakagrupo</string>
|
||||
<string name="not_tracked">Hindi naka-track</string>
|
||||
<string name="favorites_sync_error">Error sa pag-sync ng mga paborito</string>
|
||||
<string name="show_gallery">Ipakita ng Gallery</string>
|
||||
<string name="favorites_sync_error_string">Nagkaroon ng error sa proseso ng pag-sync: %1$s</string>
|
||||
<string name="favorites_sync_done_errors">Natapos ang pag-sync na may mga error</string>
|
||||
<string name="favorites_sync_done_errors_message">Nagkaroon ng mga error sa proseso ng pag-sync na hindi pinansin:
|
||||
\n%1$s</string>
|
||||
<string name="favorites_sync_gallery_multiple_categories_error">Ang Gallery na %1$d ay nasa maraming kategorya!</string>
|
||||
<string name="favorites_sync_failed_to_featch">Bigong makuha ang mga paborito mula sa remote server!</string>
|
||||
<string name="favorites_sync_could_not_fetch">Hindi makuha ang mga paborito!</string>
|
||||
<string name="favorites_sync_complete">Natapos ang pag-sync!</string>
|
||||
<string name="favorites_sync_calculating_remote_changes">Kinakalkula ang mga remote na pagbabago</string>
|
||||
<string name="favorites_sync_cleaning_up">Naglilinis</string>
|
||||
<string name="favorites_sync_ignoring_exception">Di-pinapansin ang exception!</string>
|
||||
<string name="favorites_sync_syncing_category_names">Na-a-update ng mga pangalan ng kategorya</string>
|
||||
<string name="favorites_sync_sync_error">Error sa pag-sync!</string>
|
||||
<string name="favorites_sync_network_error">Error sa network ng pag-sync!</string>
|
||||
<string name="favorites_sync_adding_to_remote">Dinadagdag ang gallery %1$d ng %2$d sa remote server</string>
|
||||
<string name="favorites_sync_removing_galleries">Tinatanggal ang mga %1$d na gallery mula sa remote server</string>
|
||||
<string name="favorites_sync_add_to_local">Dinadagdag ang gallery %1$d ng %2$d sa lokal na aklatan</string>
|
||||
<string name="favorites_sync_failed_to_add_to_local">Nabigong magdagdag ang gallery sa lokal na database:</string>
|
||||
<string name="favorites_sync_notes">MAHALAGANG SYNC NOTE NG MGA PABORITO</string>
|
||||
<string name="favorites_sync_reset">Sigurado ka ba?</string>
|
||||
<string name="favorites_sync_reset_message">Ang pag-reset ng estado ng sync ay maaaring magdulot ng napakabagal na pag-sync sa susunod na pagkakataon.</string>
|
||||
<string name="favorites_sync_conformation_message">Sigurado ka bang gusto mong i-sync ang iyong mga paborito sa E-Hentai?</string>
|
||||
<string name="eh_batch_add_description">Halimbawa:
|
||||
\n
|
||||
\nhttp://e-hentai.org/g/12345/1a2b3c4e
|
||||
\nhttp://g.e-hentai.org/g/67890/6f7g8h9i
|
||||
\nhttp://exhentai.org/g/13579/1a3b5c7e
|
||||
\nhttps://exhentai.org/g/24680/2f4g6h8i
|
||||
\n
|
||||
\nSinusuportahan din nito ang na-export na data mula sa E-H Visited
|
||||
\n</string>
|
||||
<string name="eh_batch_add_title">Ilagay ang mga gallery na idaragdag (pinaghihiwalay gamit ng isang bagong linya):</string>
|
||||
<string name="eh_batch_add_button">Magdagdag ng mga Gallery</string>
|
||||
<string name="eh_batch_add_adding_galleries">Nagdaragdag ng mga gallery…</string>
|
||||
<string name="eh_batch_add_finish">Tapos</string>
|
||||
<string name="batch_add_no_valid_galleries">Walang mga gallery na idaragdag!</string>
|
||||
<string name="batch_add_no_valid_galleries_message">Dapat kang tumukoy ng kahit isang gallery na idaragdag!</string>
|
||||
<string name="batch_add_unknown_source_log_message">Hindi kilalang source para sa gallery: %1$s</string>
|
||||
<string name="batch_add_not_exist_log_message">Walang gallery: %1$s</string>
|
||||
<string name="gallery_adder_importing_gallery">Ini-import ang gallery (url: %1$s, fav: %2$s, forceSource: %3$s)…</string>
|
||||
<string name="gallery_adder_uri_map_to_gallery_error">Error sa pagmamapa ng Source URI map-to-gallery!</string>
|
||||
<string name="gallery_adder_uri_map_to_chapter_error">Error sa pagmamapa ng Source URI map-to-chapter!</string>
|
||||
<string name="gallery_adder_chapter_fetch_error">Nabigong mag-update ang mga kabanata para sa gallery: %1$s!</string>
|
||||
<string name="gallery_adder_could_not_add_gallery">Hindi maidagdag ang gallery (url: %1$s)!</string>
|
||||
<string name="gallery_adder_could_not_identify_chapter">Hindi matukoy ang kabanata (url: %1$s)!</string>
|
||||
<string name="launching_app">Nagsisimula ang app…</string>
|
||||
<string name="could_not_open_entry">Hindi mabuksan ang entry na ito:
|
||||
\n
|
||||
\n%1$s</string>
|
||||
<string name="loading_entry">Naglo-load ang entry…</string>
|
||||
<string name="more_previews">Maraming preview</string>
|
||||
<string name="pref_clear_page_preview_cache">Linisin ang cache ng pag preview</string>
|
||||
<string name="page_preview_page_go_to">Pumunta sa</string>
|
||||
<string name="no_rating">Walang rating</string>
|
||||
<string name="more_info">Maraming impo</string>
|
||||
<string name="is_exhentai_gallery">ay Exhentai na gallery</string>
|
||||
<string name="thumbnail_url">URL ng thumbnail</string>
|
||||
<string name="date_posted">Petsang nai-post</string>
|
||||
<string name="page_count">Dami ng pahina</string>
|
||||
<string name="language">Wika</string>
|
||||
<string name="gallery_size">Laki ng gallery</string>
|
||||
<string name="total_favorites">Bilang ng paborito</string>
|
||||
<string name="total_ratings">Bilang ng rating</string>
|
||||
<string name="characters">Mga Karakter</string>
|
||||
<string name="japanese_title">Japanese na Title</string>
|
||||
<string name="english_title">Ingles na Title</string>
|
||||
<string name="short_title">Maikling Title</string>
|
||||
<string name="cover_image_file_type">Uri ng file type ng imahe ng cover</string>
|
||||
<string name="thumbnail_image_file_type">Uri ng file type ng imahe ng thumbnail</string>
|
||||
<string name="collection">Koleksyon</string>
|
||||
<string name="parodies">Mga parody</string>
|
||||
<string name="author">May akda</string>
|
||||
<string name="last_chapter_number">Huling numero ng kabanata</string>
|
||||
<string name="follow_status">Sundan ang status</string>
|
||||
<string name="anilist_id">ID ng Anilist</string>
|
||||
<string name="kitsu_id">ID ng Kitsu</string>
|
||||
<string name="mal_id">ID ng MAL</string>
|
||||
<string name="manga_updates_id">ID ng Manga updates</string>
|
||||
<string name="fetch_chapter_updates">Kunin ang mga update sa kabanata</string>
|
||||
<string name="delete_merged_entry">Sigurado ka ba?</string>
|
||||
<string name="chapter_updates_merged_entry">I-toggle ang mga update sa kabanata</string>
|
||||
<string name="chapter_updates_merged_entry_desc">Kapag na-toggle ito, hindi papaganahin o papaganahin ang mga update sa kabanata para sa pinagsamang entry na ito</string>
|
||||
<string name="download_merged_entry">I-toggle ang pag-download ng bagong kabanata</string>
|
||||
<string name="merged_references_invalid">Di-balido ang mga pinagsamang reference</string>
|
||||
<string name="merged_chapter_updates_error">I-toggle ang error sa mga update sa kabanata</string>
|
||||
<string name="merged_toggle_download_chapters_error">I-toggle ang error sa pag-download ng mga kabanata</string>
|
||||
<string name="allow_deduplication">Payagan ang pag-deduplikasyon:</string>
|
||||
<string name="mangadex_add_to_follows">Idagdag sa MangaDex follows</string>
|
||||
<string name="mangadex_preffered_source_summary">I-set ang iyong napiling source ng MangaDex, gagamitin ito para sa mga sumusunod at marami pang feature sa app</string>
|
||||
<string name="mangadex_push_favorites_to_mangadex">I-sync ang mga entry ng aklatan sa MangaDex</string>
|
||||
<string name="mangadex_push_favorites_to_mangadex_summary">Nag-sync ng anumang mga entry na hindi naka-track sa MdList sa MangaDex bilang \'reading\'.</string>
|
||||
<string name="mangadex_similar">Katulad sa MangaDex</string>
|
||||
<string name="community_recommendations">Mga rekomendasyon ng komunidad</string>
|
||||
<string name="select_scanlators">Ipapakitang Scanlator group</string>
|
||||
<string name="similar">Katulad sa %1$s</string>
|
||||
<string name="relation_similar">Katulad</string>
|
||||
<string name="humanize_fallback">ilang sandali ang nakalipas</string>
|
||||
<string name="favorites_sync_notes_message">1. Ang mga pagbabago sa pangalan ng kategorya sa app ay <b>HINDI</b> nai-sync! Mangyaring <i>palitan ang pangalan ng kategorya sa ExHentai sa halip</i>. Ang mga pangalan ng kategorya ay kokopyahin mula sa ExHentai servers sa bawat pag-sync.<br><br>2. Ang mga paboritong kategorya sa ExHentai ay tumutukoy sa <b>unang 10 kategorya sa app</b> (hindi kasama ang \'Default\' na kategorya). <i>Ang mga gallery sa ibang mga kategorya ay <b>HINDI</b> nai-sync!</i><br><br>3. <font color=\'red\'><b>PANATALIHING MAY MALAKAS NA KONEKSYON NG INTERNET KAPAG NAGPRPROSESO NG PAG-SYNC!</b></font> Kung mawawalan ng koneksyon sa internet habang nag-sync ang app, ang iyong mga paborito ay maaaring maiwan sa isang <i>bahagyang nai-sync na estado</i>.<br><br>4. Panatilihing bukas ang app habang nag-sync ang mga paborito. Ang Android ay minsang nagsasara ng mga app na nasa background at maaaring hindi maganda kung mangyari ito habang nag-sisync ang app.<br><br>5. <b>Huwag ilagay ang mga paborito sa maraming kategorya</b> (suportado ito ng app). Maaari malilito ang algorithm ng pag-sync dahil pinapayagan lang ng ExH na ang bawat paborito ay nasa isang kategorya.<br><br> Ang dialog na ito ay lilitaw lamang ng isang beses. Maaari mong basahin muli ang mga tala na ito sa pamamagitan ng pagpunta sa \'Mga Setting > E-Hentai > Ipakita ang sync note ng mga paborito\'.</string>
|
||||
<string name="batch_add_unknown_type_log_message">Di-kilalang uri ng entry para sa gallery: %1$s</string>
|
||||
<string name="batch_add_summary">"
|
||||
\nBuod:
|
||||
\nIdinagdag: %1$d (mga) gallery
|
||||
\nNabigo: %2$d (mga) gallery"</string>
|
||||
<string name="batch_add_success_log_message">Idinagdag na gallery: %1$s</string>
|
||||
<string name="gallery_adder_source_uri_must_match">Error sa pagsusuri ng pagtutugma ng source URI!</string>
|
||||
<string name="favorites_sync_failed_to_add_to_local_unknown_type">\'%1$s\' (%2$s) ay di-balidong gallery!</string>
|
||||
<string name="favorites_sync_remote_not_exist">Ang remote na gallery ay di umiiral, nilalaktawan ang: %1$s!</string>
|
||||
<string name="favorites_sync_waiting_for_start">Naghihintay na magsimula ang pag-sync</string>
|
||||
<string name="favorites_sync_gallery_in_multiple_categories">Ang gallery na: %1$s ay nasa higit sa isang kategorya (%2$s)!</string>
|
||||
<string name="favorites_sync_initializing">Sinisimulan ang pag-sync</string>
|
||||
<string name="favorites_sync_processing_throttle">%1$s
|
||||
\n
|
||||
\nKasalukuyang binabawasan ng sync (upang maiwasan ang ban mula sa ExHentai) at maaaring tumagal ng mahabang oras upang makumpleto.</string>
|
||||
<string name="gallery_adder_uri_clean_error">Error sa paglilinis ng Source URI!</string>
|
||||
<string name="translated">Naisalin</string>
|
||||
<string name="anime_planet_id">ID ng Anime planet</string>
|
||||
<string name="merge_settings">Pagsamahin ang mga setting</string>
|
||||
<string name="dedupe_most_chapters">Ipakita ang source na may maraming kabanata</string>
|
||||
<string name="delete_merged_entry_desc">Tatanggalin nito ang entry mula sa pinagsama, ang paggamit nito ay mawawalan din ng anumang hindi nai-save na mga pagbabago na inilapat sa pinagsamang entry</string>
|
||||
<string name="dedupe_highest_chapter">Ipakita ang source na may mataas na bilang ng kabanata</string>
|
||||
<string name="download_merged_entry_desc">Kapag na-toggle ito, hindi papaganahin o papaganahin ang mga pag-download ng kabanata para sa pinagsamang entry na ito</string>
|
||||
<string name="md_follows_unfollowed">Di-sinusundan</string>
|
||||
<string name="no_dedupe">Walang dedupe</string>
|
||||
<string name="dedupe_priority">Mag-dedupe ng may prioridad</string>
|
||||
<string name="mangadex_sync_follows_to_library">Mag-sync ng mga entry ng MangaDex sa iyong akalatan</string>
|
||||
<string name="mangadex_sync_follows_to_library_summary">Kinukuha ang mga entry mula sa MangaDex papunta sa iyong aklatan kung hindi pa ito naidagdag.</string>
|
||||
<string name="mangadex_preffered_source">Piniling MangaDex source</string>
|
||||
<string name="group">Grupo</string>
|
||||
<string name="uploader_capital">Naka-capitalize ang Uploader</string>
|
||||
<string name="deduplication_entry_info">Impo ng entry:</string>
|
||||
</resources>
|
||||
@@ -8,20 +8,17 @@
|
||||
<string name="action_clean_titles">Hapus judul</string>
|
||||
<string name="action_start_reading">Mulai baca</string>
|
||||
<string name="action_edit_info">Edit info</string>
|
||||
|
||||
<!-- Manga Type -->
|
||||
<string name="entry_type_manhwa">Manhwa</string>
|
||||
<string name="entry_type_manhua">Manhua</string>
|
||||
<string name="entry_type_comic">Komik</string>
|
||||
<string name="entry_type_webtoon">Webtoon</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<!-- Subsections -->
|
||||
<string name="pref_category_all_sources">Semua Sumber</string>
|
||||
<string name="pref_category_eh">E-Hentai</string>
|
||||
<string name="pref_category_fork">Pengaturan Fork</string>
|
||||
<string name="pref_category_mangadex">MangaDex</string>
|
||||
|
||||
<!-- EH Settings -->
|
||||
<string name="ehentai_prefs_account_settings">E-Hentai Website Account Settings</string>
|
||||
<string name="enable_exhentai">Enable ExHentai</string>
|
||||
@@ -91,7 +88,6 @@
|
||||
<string name="gallery_updater_stats_text">The updater last ran %1$s, and checked %2$d out of the %3$d galleries that were ready for checking.</string>
|
||||
<string name="gallery_updater_not_ran_yet">The updater has not ran yet.</string>
|
||||
<string name="gallery_updater_stats_time">\nGalleries that were checked in the last:\n- hour: %1$d\n- 6 hours: %2$d\n- 12 hours: %3$d\n- day: %4$d\n- 2 days: %5$d\n- week: %6$d\n- month: %7$d\n- year: %8$d</string>
|
||||
|
||||
<!-- EH Settings Upload Dialogs -->
|
||||
<string name="settings_profile_note">Settings profile note</string>
|
||||
<string name="settings_profile_note_message">The app will now add a new settings profile on E-Hentai and ExHentai to optimize app performance. Please ensure that you have less than three profiles on both sites.\n\nIf you have no idea what settings profiles are, then it probably doesn\'t matter, just hit \'OK\'.</string>
|
||||
@@ -101,14 +97,12 @@
|
||||
<string name="eh_settings_uploading_to_server">Uploading settings to server</string>
|
||||
<string name="eh_settings_uploading_to_server_message">Please wait, this may take some time…</string>
|
||||
<string name="eh_settings_out_of_slots_error">You are out of profile slots on %1$s, please delete a profile!</string>
|
||||
|
||||
<!-- EH Settings Login Activity -->
|
||||
<string name="recheck_login_status">Recheck login status</string>
|
||||
<string name="alternative_login_page">Alternative login page</string>
|
||||
<string name="skip_page_restyling">Skip page restyling</string>
|
||||
<string name="custom_igneous_cookie">Custom igneous cookie</string>
|
||||
<string name="custom_igneous_cookie_message">Some users cannot access ExHentai the normal way, and have to pass in a specific igneous cookie value, this option is for those users.</string>
|
||||
|
||||
<!-- Advanced Settings -->
|
||||
<string name="developer_tools">Opsi Pengembang</string>
|
||||
<string name="toggle_hentai_features">Aktifkan fitur hentai terintegrasi</string>
|
||||
@@ -141,7 +135,6 @@
|
||||
<string name="data_saver_color_bw">Konversi ke Hitam Putih</string>
|
||||
<string name="data_saver_server_summary">Masukkan url server Bandwidth Hero Proxy disini</string>
|
||||
<string name="clear_db_exclude_read">Abaikab manga yang sudah dibaca</string>
|
||||
|
||||
<!-- Log Level -->
|
||||
<string name="log_minimal">Mode Minimum</string>
|
||||
<string name="log_extra">Mode Ekstra</string>
|
||||
@@ -149,18 +142,15 @@
|
||||
<string name="log_minimal_desc">Hanya kesalahan fatal</string>
|
||||
<string name="log_extra_desc">log semuanya</string>
|
||||
<string name="log_extreme_desc">mode inspeksi jaringan</string>
|
||||
|
||||
<!-- General Settings -->
|
||||
<string name="toggle_expand_search_filters">Perluas semua filter pencarian secara default</string>
|
||||
<string name="put_recommends_in_overflow">Rekomendasi di tombol overflow</string>
|
||||
<string name="put_recommends_in_overflow_summary">Letakkan tombol rekomendasi di tombol overflow alih-alih di halaman info manga</string>
|
||||
|
||||
<!-- Appearance Settings -->
|
||||
<string name="pref_category_navbar">Navbar</string>
|
||||
<string name="pref_hide_updates_button">Tampilkan menu Pembaruan di navbar</string>
|
||||
<string name="pref_hide_history_button">Tampilkan menu Riwayat di navbar</string>
|
||||
<string name="pref_show_bottom_bar_labels">Tampilkan label di navbar</string>
|
||||
|
||||
<!-- Library settings -->
|
||||
<string name="pref_sorting_settings">Pengaturan Penyortiran</string>
|
||||
<string name="pref_skip_pre_migration_summary">Gunakan preferensi dan sumber pra-migrasi yang terakhir disimpan untuk migrasi masal</string>
|
||||
@@ -168,7 +158,6 @@
|
||||
<string name="library_group_updates_global">Selalu jalankan pembaruan global</string>
|
||||
<string name="library_group_updates_all_but_ungrouped">Jalankan pembaruan global hanya untuk yang tidak dikelompokkan, pembaruan kategori untuk yang lainnya</string>
|
||||
<string name="library_group_updates_all">Hanya jalankan pembaruan kategori</string>
|
||||
|
||||
<!-- Browse settings -->
|
||||
<string name="pref_source_source_filtering">Filter Sumber dalam kategori</string>
|
||||
<string name="pref_source_source_filtering_summery">Saring sumber-sumber yang ada dalam kategori, agar sumber-sumber tersebut tidak dimasukkan ke dalam kategori bahasa jika berada dalam suatu kategori</string>
|
||||
@@ -176,11 +165,9 @@
|
||||
<string name="pref_source_navigation_summery">Ganti tombol Terbaru dengan tampilan penelusuran khusus yang mencakup bab terbaru dan daftar manga</string>
|
||||
<string name="pref_local_source_hidden_folders">Folder tersembunyi sumber lokal</string>
|
||||
<string name="pref_local_source_hidden_folders_summery">Izinkan sumber lokal untuk melihat folder tersembunyi</string>
|
||||
|
||||
<!-- Backup settings -->
|
||||
<string name="custom_entry_info">Info manga yang diedit</string>
|
||||
<string name="all_read_entries">Semua manga yang dibaca</string>
|
||||
|
||||
<!-- Security settings -->
|
||||
<string name="biometric_lock_times">Waktu kunci biometrik</string>
|
||||
<string name="action_edit_biometric_lock_times">Edit waktu kunci</string>
|
||||
@@ -190,7 +177,6 @@
|
||||
<string name="biometric_lock_end_time">Berakhir pada</string>
|
||||
<string name="biometric_lock_days">Hari kunci biometrik diaktifkan</string>
|
||||
<string name="biometric_lock_days_summary">Hari tertentu untuk mengunci aplikasi</string>
|
||||
|
||||
<string name="sunday">Minggu</string>
|
||||
<string name="monday">Senin</string>
|
||||
<string name="tuesday">Selasa</string>
|
||||
@@ -198,11 +184,10 @@
|
||||
<string name="thursday">Kamis</string>
|
||||
<string name="friday">Jumat</string>
|
||||
<string name="saturday">Sabtu</string>
|
||||
|
||||
<!-- Reader Settings -->
|
||||
<string name="page_downloading">Pengunduhan Halaman</string>
|
||||
<string name="download_threads">Thread unduhan</string>
|
||||
<string name="download_threads_summary">Nilai yang lebih tinggi dapat mempercepat pengunduhan gambar secara signifikan, tapi dapat mengakibatkan diblokir. Nilai yang disarankan adalah 2 atau 3. Nilai saat ini adalah: %s</string>
|
||||
<string name="download_threads_summary">Nilai yang lebih tinggi dapat mempercepat pengunduhan gambar secara signifikan, tapi dapat mengakibatkan diblokir. Nilai yang disarankan adalah 2 atau 3. Nilai saat ini adalah: %s</string>
|
||||
<string name="aggressively_load_pages">Muat halaman secara agresif</string>
|
||||
<string name="aggressively_load_pages_summary">Unduh perlahan seluruh bab sambil membaca, alih-alih hanya memuat halaman yang Anda lihat.</string>
|
||||
<string name="skip_queue_on_retry">Lewati antrean saat mencoba lagi</string>
|
||||
@@ -227,14 +212,12 @@
|
||||
<string name="tap_scroll_page_summary">Mengetuk akan menggulir berdasarkan halaman alih-alih ukuran layar saat opsi ini diaktifkan</string>
|
||||
<string name="reader_bottom_buttons">Tombol Bawah Pembaca</string>
|
||||
<string name="reader_bottom_buttons_summary">Sesuaikan tombol apa yang muncul di bagian bawah pembaca</string>
|
||||
|
||||
<string name="pref_show_vert_seekbar_landscape">Tampilkan seekbar vertikal dalam mode layar mendatar</string>
|
||||
<string name="pref_show_vert_seekbar_landscape_summary">Mengaktifkan seekbar dalam mode layar mendatar</string>
|
||||
<string name="pref_left_handed_vertical_seekbar">Seekbar Vertikal Kidal</string>
|
||||
<string name="pref_left_handed_vertical_seekbar_summary">Membalikkan sisi seekbar vertikal</string>
|
||||
<string name="pref_force_horz_seekbar">Paksa aktifkan seekbar horizontal</string>
|
||||
<string name="pref_force_horz_seekbar_summary">Menghapus seekbar vertikal sepenuhnya dan menggantikanya dengan seekbar horizontal</string>
|
||||
|
||||
<!-- Reader -->
|
||||
<!-- Reader Actions -->
|
||||
<string name="eh_autoscroll">Gulir otomatis</string>
|
||||
@@ -263,13 +246,10 @@
|
||||
<string name="action_share_second_page">Bagikan halaman kedua</string>
|
||||
<string name="action_save_combined_page">Simpan halaman yang disatukan</string>
|
||||
<string name="action_share_combined_page">Bagikan halaman yang disatukan</string>
|
||||
|
||||
<!-- Reader Sharing -->
|
||||
<string name="share_pages_info">%1$s: %2$s, halaman %3$s</string>
|
||||
|
||||
<!-- Auto Webtoon Mode -->
|
||||
<string name="eh_auto_webtoon_snack">Mode webtoon</string>
|
||||
|
||||
<!-- Double page spread -->
|
||||
<string name="page_layout">Tata letak halaman</string>
|
||||
<string name="shift_double_pages">Geser satu halaman ke atas</string>
|
||||
@@ -278,7 +258,6 @@
|
||||
<string name="automatic_orientation">Otomatis (berdasarkan orientasi)</string>
|
||||
<string name="automatic_can_still_switch">Saat menggunakan tata letak halaman otomatis, kamu masih dapat beralih di antara tata letak saat membaca tanpa mengesampingkan pengaturan ini</string>
|
||||
<string name="invert_double_pages">Balikkan halaman ganda</string>
|
||||
|
||||
<!-- Manga Page -->
|
||||
<!-- Manga Info -->
|
||||
<string name="az_recommends">Lihat Rekomendasi</string>
|
||||
@@ -289,7 +268,6 @@
|
||||
<string name="merge_unknown_entry">ID manga tak diketahui: %1$d</string>
|
||||
<string name="merged_already">Manga ini sudah tergabung dengan manga saat ini!</string>
|
||||
<string name="merge_duplicate">Manga gabungan ini adalah duplikat!</string>
|
||||
|
||||
<!-- Manga Info Edit -->
|
||||
<string name="reset_tags">Reset Tagar</string>
|
||||
<string name="add_tag">Tambah Tagar</string>
|
||||
@@ -298,18 +276,15 @@
|
||||
<string name="author_hint">Author: %1$s</string>
|
||||
<string name="artist_hint">Artist: %1$s</string>
|
||||
<string name="thumbnail_url_hint">Thumbnail Url: %1$s</string>
|
||||
|
||||
<!-- Browse -->
|
||||
<!-- Sources Tab -->
|
||||
<string name="find_in_another_source">Cari di sumber yang lain</string>
|
||||
<string name="data_saver_exclude">Kecualikan dari penghemat data</string>
|
||||
<string name="data_saver_stop_exclude">Berhenti mengecualikan dari penghemat data</string>
|
||||
|
||||
<!-- Smart Search -->
|
||||
<string name="searching_source">Menelusuri…</string>
|
||||
<string name="could_not_find_entry">Tak dapat menemukan manga di sumber ini!</string>
|
||||
<string name="automatic_search_error">Terjadi kesalahan saat melakukan pencarian!</string>
|
||||
|
||||
<!-- Saved Searches -->
|
||||
<string name="saved_searches">Penelusuran Disimpan</string>
|
||||
<string name="save_search">Simpan kueri penelusuran saat ini?</string>
|
||||
@@ -319,11 +294,9 @@
|
||||
<string name="save_search_delete">Hapus kueri penelusuran yang disimpan?</string>
|
||||
<string name="save_search_delete_message">Apa kamu benar-benar ingin menghapus penelusuran yang disimpan ini: \'%1$s\'?</string>
|
||||
<string name="save_search_invalid">Penelusuran yang disimpan tidak valid</string>
|
||||
|
||||
<!-- Source Categories -->
|
||||
<string name="no_source_categories">Tak ada kategori sumber yang tersedia</string>
|
||||
<string name="invalid_category_name">Nama kategori tidak valid</string>
|
||||
|
||||
<!-- Sort by tags -->
|
||||
<string name="pref_tag_sorting">Penyortir Tagar</string>
|
||||
<string name="tag_sorting">Menyortir tagar</string>
|
||||
@@ -331,17 +304,15 @@
|
||||
<string name="action_edit_tags">Edit tagar</string>
|
||||
<string name="information_empty_tags">Kamu tidak memiliki tagar. Ketuk tombol tambah untuk membuatnya</string>
|
||||
<string name="error_tag_exists">Tagar ini sudah ada!</string>
|
||||
|
||||
<!-- Extension section -->
|
||||
<string name="ext_redundant">Duplikat</string>
|
||||
<string name="redundant_extension_message">Ekstensi ini duplikat dan tak akan digunakan di dalam versi Tachiyomi ini.</string>
|
||||
|
||||
<!-- Migration -->
|
||||
<string name="select_sources">Pilih sumber</string>
|
||||
<string name="select_none">Tak ada yang dipilih</string>
|
||||
<string name="migration">Migrasi</string>
|
||||
<string name="skip_pre_migration">Lewati pra-migrasi</string>
|
||||
<string name="pre_migration_skip_toast">Untuk menampilkan layar ini lagi, buka Pengaturan -> Pustaka.</string>
|
||||
<string name="pre_migration_skip_toast">Untuk menampilkan layar ini lagi, buka Pengaturan -> Pustaka.</string>
|
||||
<string name="use_intelligent_search">Cari judul + kata kunci dari judul</string>
|
||||
<string name="data_to_include_in_migration">Data yang dipindahkan</string>
|
||||
<string name="include_extra_search_parameter">Gunakan parameter tambahan saat melakukan penelusuran</string>
|
||||
@@ -358,19 +329,15 @@
|
||||
<string name="no_alternatives_found">Tidak Ditemukan</string>
|
||||
<string name="stop_migrating">Hentikan migrasi?</string>
|
||||
<string name="skipping_">(melewati %1$d)</string>
|
||||
|
||||
<!-- Library -->
|
||||
<!-- Library Actions -->
|
||||
<string name="no_valid_entry">Tak ada yang dipilih</string>
|
||||
|
||||
<!-- Library Sheet -->
|
||||
<string name="lewd">Lewd</string>
|
||||
|
||||
<!-- Library Grouping -->
|
||||
<string name="tracking_status">Status pelacakan</string>
|
||||
<string name="ungrouped">Tidak dikelompokkan</string>
|
||||
<string name="not_tracked">Tidak dilacak</string>
|
||||
|
||||
<!-- Favorites Sync -->
|
||||
<string name="sync_favorites">Sync EH favorites</string>
|
||||
<string name="favorites_sync_error">Favorites sync error</string>
|
||||
@@ -411,7 +378,6 @@
|
||||
<string name="favorites_sync_notes_message"><![CDATA[1. Changes to category names in the app are <b>NOT</b> synced! Please <i>change the category names on ExHentai instead</i>. The category names will be copied from the ExHentai servers every sync.<br><br>2. The favorite categories on ExHentai correspond to the <b>first 10 categories in the app</b> (excluding the \'Default\' category). <i>Galleries in other categories will <b>NOT</b> be synced!</i><br><br>3. <font color=\'red\'><b>ENSURE YOU HAVE A STABLE INTERNET CONNECTION WHEN SYNC IS IN PROGRESS!</b></font> If the internet disconnects while the app is syncing, your favorites may be left in a <i>partially-synced state</i>.<br><br>4. Keep the app open while favorites are syncing. Android will close apps that are in the background sometimes and that could be bad if it happens while the app is syncing.<br><br>5. <b>Do NOT put favorites in multiple categories</b> (the app supports this). This can confuse the sync algorithm as ExHentai only allows each favorite to be in one category.<br><br>This dialog will only popup once. You can read these notes again by going to \'Settings > E-Hentai > Show favorites sync notes\'.]]></string>
|
||||
<string name="favorites_sync_reset">Are you sure?</string>
|
||||
<string name="favorites_sync_reset_message">Resetting the sync state can cause your next sync to be extremely slow.</string>
|
||||
|
||||
<!-- Gallery Adder -->
|
||||
<!-- Batch Add -->
|
||||
<string name="eh_batch_add">Batch Add</string>
|
||||
@@ -438,13 +404,11 @@
|
||||
<string name="gallery_adder_chapter_fetch_error">Failed to update chapters for manga: %1$s!</string>
|
||||
<string name="gallery_adder_could_not_add_gallery">Could not add manga (url: %1$s)!</string>
|
||||
<string name="gallery_adder_could_not_identify_chapter">Could not identify chapter (url: %1$s)!</string>
|
||||
|
||||
<!-- Intercept Activity -->
|
||||
<string name="launching_app">Launching app…</string>
|
||||
<string name="error_with_reason">Error: %1$s</string>
|
||||
<string name="could_not_open_entry">Could not open this manga:\n\n%1$s</string>
|
||||
<string name="loading_entry">Loading manga…</string>
|
||||
|
||||
<!-- Rating 0-10 (0, 0.5, 1, 1.5 and so fourth) -->
|
||||
<string name="rating10">Masterpiece</string>
|
||||
<string name="rating9">Amazing</string>
|
||||
@@ -458,8 +422,6 @@
|
||||
<string name="rating1">Unbearable</string>
|
||||
<string name="rating0">Disaster</string>
|
||||
<string name="no_rating">No rating</string>
|
||||
|
||||
|
||||
<!-- Gallery types -->
|
||||
<string name="doujinshi">Doujinshi</string>
|
||||
<string name="artist_cg">Artist CG</string>
|
||||
@@ -472,7 +434,6 @@
|
||||
<string name="misc">Misc</string>
|
||||
<string name="artbook">Artbook</string>
|
||||
<string name="video">Video</string>
|
||||
|
||||
<!-- More Info Menu -->
|
||||
<string name="more_info">More info</string>
|
||||
<string name="alt_title">Alt Title</string>
|
||||
@@ -517,11 +478,9 @@
|
||||
<string name="manga_updates_id">Manga updates id</string>
|
||||
<string name="anime_planet_id">Anime planet id</string>
|
||||
<string name="translated">Translated</string>
|
||||
|
||||
<!-- Extra gallery info -->
|
||||
<string name="is_visible">Visible: %1$s</string>
|
||||
<string name="language_translated">%1$s TR</string>
|
||||
|
||||
<!-- Merged manga -->
|
||||
<string name="merge_settings">Pengaturan gabung</string>
|
||||
<string name="fetch_chapter_updates">Perbarui bab</string>
|
||||
@@ -541,7 +500,6 @@
|
||||
<string name="dedupe_priority">Deduplikasi menurut prioritas</string>
|
||||
<string name="dedupe_most_chapters">Tampilkan sumber dengan bab terbanyak</string>
|
||||
<string name="dedupe_highest_chapter">Tampilkan sumber dengan nomor bab tertinggi</string>
|
||||
|
||||
<!-- MangaDex -->
|
||||
<string name="md_follows_unfollowed">Tak diikuti</string>
|
||||
<string name="mangadex_sync_follows_to_library">Sinkronkan MangaDex ke pustaka</string>
|
||||
@@ -553,15 +511,20 @@
|
||||
<string name="random">Acak</string>
|
||||
<string name="mangadex_push_favorites_to_mangadex">Sinkronkan pustaka ke MangaDex</string>
|
||||
<string name="mangadex_push_favorites_to_mangadex_summary">Sinkronkan manga yang bukan berasal dari MangaDex dan masukkan ke MDList.</string>
|
||||
|
||||
|
||||
<!-- Scanlator filters -->
|
||||
<string name="select_scanlators">Grup pemindai yang ditampilkan</string>
|
||||
|
||||
<!-- Similar -->
|
||||
<string name="similar">Mirip dengan %1$s</string>
|
||||
|
||||
<!-- Humanize time -->
|
||||
<string name="humanize_fallback">Beberapa saat yang lalu</string>
|
||||
|
||||
</resources>
|
||||
<string name="entry_type_manga">Manga</string>
|
||||
<string name="pref_ehentai_summary">Login E/ExHentai, sinkronisasi galeri</string>
|
||||
<string name="pref_mangadex_summary">Login MangaDex, mengikuti sinkronisasi</string>
|
||||
<string name="changelog_version">Versi %1$s</string>
|
||||
<string name="bandwidth_hero">Bandwidth Hero (membutuhkan server Proxy Bandwidth Hero)</string>
|
||||
<string name="wsrv">wsrv.nl</string>
|
||||
<string name="bandwidth_data_saver_server">Server Proxy Bandwidth Hero</string>
|
||||
<string name="put_merge_in_overflow">Gabungkan dalam luapan</string>
|
||||
<string name="put_merge_in_overflow_summary">Letakkan tombol penggabungan di menu luapan, bukan di halaman entri</string>
|
||||
<string name="pref_previews_row_count">Mempratinjau jumlah baris</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<plurals name="cleanup_done">
|
||||
<item quantity="one">クリーンアップが終了しました。%d フォルダーを消去しました</item>
|
||||
<item quantity="other">クリーンアップが終了しました。%d フォルダーを消去しました</item>
|
||||
</plurals>
|
||||
<plurals name="num_lock_times">
|
||||
<item quantity="one">%d ロック時間</item>
|
||||
<item quantity="other">%d ロック時間</item>
|
||||
</plurals>
|
||||
<plurals name="eh_retry_toast">
|
||||
<item quantity="zero">失敗したページを0ページ再試行中…</item>
|
||||
<item quantity="one">失敗したページ %1$d を再試行しています…</item>
|
||||
<item quantity="other">失敗したページ %1$d を再試行しています…</item>
|
||||
</plurals>
|
||||
<plurals name="pref_tag_sorting_desc">
|
||||
<item quantity="zero">並べ替えリストにタグを表示しません。これは、優先順位に基づいたタグリストで並べ替えするをオプションをライブラリに追加します</item>
|
||||
<item quantity="one">1$d タグを並べ替えリストに追加しました。これは、優先順位に基づいたタグリストで並べ替えをするオプションをライブラリに追加します</item>
|
||||
<item quantity="other">1$d タグを並べ替えリストに追加しました。これは、優先順位に基づいたタグリストで並べ替えをするオプションをライブラリに追加します</item>
|
||||
</plurals>
|
||||
<plurals name="migrate_entry">
|
||||
<item quantity="one">1$d%2$s の作品を移行しますか?</item>
|
||||
<item quantity="other">1$d%2$s の作品を移行しますか?</item>
|
||||
</plurals>
|
||||
<plurals name="copy_entry">
|
||||
<item quantity="one">1$d%2$s の作品をコピーしますか?</item>
|
||||
<item quantity="other">1$d%2$s 作品をコピーしますか?</item>
|
||||
</plurals>
|
||||
<plurals name="entry_migrated">
|
||||
<item quantity="one">%d の作品が移行されました</item>
|
||||
<item quantity="other">%d の作品が移行されました</item>
|
||||
</plurals>
|
||||
<!-- Extra gallery info -->
|
||||
<plurals name="num_pages">
|
||||
<item quantity="one">%1$d ページ</item>
|
||||
<item quantity="other">%1$d ページ</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Enhanced E/ExHentai Browse View -->
|
||||
<plurals name="browse_language_and_pages">
|
||||
<item quantity="one">%2$s, %1$d ページ</item>
|
||||
<item quantity="other">%2$s, %1$d ページ</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Humanize time -->
|
||||
<plurals name="humanize_year">
|
||||
<item quantity="one">%1$d 年前</item>
|
||||
<item quantity="other">%1$d 年前</item>
|
||||
</plurals>
|
||||
<plurals name="humanize_month">
|
||||
<item quantity="one">%1$d ヶ月前</item>
|
||||
<item quantity="other">%1$d ヶ月前</item>
|
||||
</plurals>
|
||||
<plurals name="humanize_week">
|
||||
<item quantity="one">%1$d 週間前</item>
|
||||
<item quantity="other">%1$d 週間前</item>
|
||||
</plurals>
|
||||
<plurals name="humanize_day">
|
||||
<item quantity="one">%1$d 日前</item>
|
||||
<item quantity="other">%1$d 日前</item>
|
||||
</plurals>
|
||||
<plurals name="humanize_hour">
|
||||
<item quantity="one">%1$d 時間前</item>
|
||||
<item quantity="other">%1$d 時間前</item>
|
||||
</plurals>
|
||||
<plurals name="humanize_minute">
|
||||
<item quantity="one">%1$d 分前</item>
|
||||
<item quantity="other">%1$d 分前</item>
|
||||
</plurals>
|
||||
<plurals name="humanize_second">
|
||||
<item quantity="one">%1$d 秒前</item>
|
||||
<item quantity="other">%1$d 秒前</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Manga preview row counter -->
|
||||
<plurals name="row_count">
|
||||
<item quantity="one">%d 行</item>
|
||||
<item quantity="other">%d 行</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -0,0 +1,655 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Actions -->
|
||||
<string name="action_skip_entry">移行しない</string>
|
||||
<string name="action_search_manually">マニュアル検索</string>
|
||||
<string name="action_migrate_now">移行する</string>
|
||||
<string name="action_copy_now">コピーする</string>
|
||||
<string name="action_clean_titles">タイトルを削除</string>
|
||||
<string name="action_start_reading">読み始める</string>
|
||||
<string name="action_edit_info">情報を編集</string>
|
||||
<!-- Entry Type -->
|
||||
<string name="entry_type_manga">漫画</string>
|
||||
<string name="entry_type_manhwa">韓国漫画</string>
|
||||
<string name="entry_type_manhua">中国漫画</string>
|
||||
<string name="entry_type_comic">コミック</string>
|
||||
<string name="entry_type_webtoon">Webtoon</string>
|
||||
<!-- Preferences -->
|
||||
<!-- Subsections -->
|
||||
<string name="pref_category_all_sources">すべてのソース</string>
|
||||
<string name="pref_category_eh">E-Hentai</string>
|
||||
<string name="pref_category_fork">フォークの設定</string>
|
||||
<string name="pref_category_mangadex">MangaDex</string>
|
||||
<string name="pref_ehentai_summary">E/EXHentai ログイン、ギャラリー同期</string>
|
||||
<string name="pref_mangadex_summary">MangaDex ログイン、同期に従う</string>
|
||||
<!-- About -->
|
||||
<string name="changelog_version">バージョン %1$s</string>
|
||||
<!-- EH Settings -->
|
||||
<string name="ehentai_prefs_account_settings">E-Hentai ウェブサイトのアカウント設定</string>
|
||||
<string name="enable_exhentai">ExHentai を有効化</string>
|
||||
<string name="requires_login">ログインが必要です</string>
|
||||
<string name="use_hentai_at_home">Hentai@Home Networkを使用</string>
|
||||
<string name="use_hentai_at_home_summary">Hentai@Home Network が利用可能な場合、Hentai@Home Network 経由で画像を読み込みますか? このオプションを無効にすると、\nオプション:\n- 任意のクライアント (推奨)\n- デフォルトのポートクライアントのみ (遅くなることがあります。 ファイアウォールやプロキシが標準以外のポートの発信をブロックしている場合は有効にしてください)。</string>
|
||||
<string name="use_hentai_at_home_option_1">任意のクライアント (推奨)</string>
|
||||
<string name="use_hentai_at_home_option_2">デフォルトのポートクライアントのみ</string>
|
||||
<string name="show_japanese_titles">検索結果に日本語タイトルを表示</string>
|
||||
<string name="show_japanese_titles_option_1">現在、検索結果に日本語のタイトルが表示されています。 変更後は章のキャッシュをクリアしてください。 (詳細セクション内)</string>
|
||||
<string name="show_japanese_titles_option_2">現在、検索結果に英語/ローマ字のタイトルが表示されています。 変更後は章のキャッシュをクリアしてください。 (詳細セクション内)</string>
|
||||
<string name="use_original_images">オリジナルの画像を使用</string>
|
||||
<string name="use_original_images_on">現在オリジナルの画像を使用しています</string>
|
||||
<string name="use_original_images_off">現在、リサンプリングされた画像を使用しています</string>
|
||||
<string name="watched_tags">既読タグ</string>
|
||||
<string name="watched_tags_summary">E/EXHentai の既読済みタグのページに Webビューを開きます</string>
|
||||
<string name="watched_tags_exh">ExHentai 既読タグ</string>
|
||||
<string name="tag_filtering_threshold">タグフィルターのしきい値</string>
|
||||
<string name="tag_filtering_threshhold_error">-9999〜0 の間でなければなりません!</string>
|
||||
<string name="tag_filtering_threshhold_summary">タグを「My Tags」の E/ExHentai ページに負の重みで追加することで、タグをソフトフィルタリングできます。ギャラリーのタグの合計重みがこの値を下回る場合、そのギャラリーは表示からフィルタリングされます。しきい値は -9999〜0 の間で設定できます。現在の設定値: %1$d</string>
|
||||
<string name="tag_watching_threshhold">タグ閲覧のしきい値</string>
|
||||
<string name="tag_watching_threshhold_error">0〜9999 の間でなければなりません!</string>
|
||||
<string name="tag_watching_threshhold_summary">最近アップロードされたギャラリーは、少なくとも1つの既読タグに正の重みがあり、その既読タグの重みの合計がこの値以上であれば、視聴画面に含まれます。しきい値は 0〜9999 の間で設定できます。現在の設定値: %1$d</string>
|
||||
<string name="language_filtering">言語フィルター</string>
|
||||
<string name="language_filtering_summary">特定の言語のギャラリーをギャラリーリストや検索から非表示にしたい場合は、ポップアップするダイアログで選択してください。\n検索クエリに関わらず、一致するギャラリーは表示されません。\nTldrチェックマーク付き=除外</string>
|
||||
<string name="frong_page_categories">フロントページのカテゴリー</string>
|
||||
<string name="fromt_page_categories_summary">初期設定でフロントページや検索結果にどのカテゴリーを表示しますか?フィルターを有効にすることで、それらのカテゴリも表示することができます</string>
|
||||
<string name="watched_list_default">既読リストフィルターのデフォルト状態</string>
|
||||
<string name="watched_list_state_summary">ExHentai/E-Hentai を参照するとき、既読リストフィルターがデフォルトで有効になっている必要があります</string>
|
||||
<string name="eh_image_quality_summary">ダウンロードした画像の品質</string>
|
||||
<string name="eh_image_quality">画像品質</string>
|
||||
<string name="eh_image_quality_auto">自動</string>
|
||||
<string name="eh_image_quality_2400">2400x</string>
|
||||
<string name="eh_image_quality_1600">1600x</string>
|
||||
<string name="eh_image_quality_1280">1280x</string>
|
||||
<string name="eh_image_quality_980">980x</string>
|
||||
<string name="eh_image_quality_780">780x</string>
|
||||
<string name="pref_enhanced_e_hentai_view">拡張した E/EXHentai ブラウズ</string>
|
||||
<string name="pref_enhanced_e_hentai_view_summary">E/ExHentai のために作られた拡張ブラウズメニューを有効化/無効化します</string>
|
||||
<string name="favorites_sync">E-Hentai のお気に入りを同期</string>
|
||||
<string name="disable_favorites_uploading">お気に入りのアップロードを無効化</string>
|
||||
<string name="disable_favorites_uploading_summary">お気に入りは ExHentai からのみダウンロードされます。アプリ内のお気に入りへの変更はアップロードされません。ExHentai でお気に入りが誤って失われるのを防ぎます。 削除してもダウンロードされることに注意してください。(ExHentai でお気に入りを削除した場合は、アプリ内でも削除されます)</string>
|
||||
<string name="show_favorite_sync_notes">お気に入りの同期ノートを表示</string>
|
||||
<string name="show_favorite_sync_notes_summary">お気に入りの同期機能に関するいくつかの情報を表示</string>
|
||||
<string name="please_login">ログインしてください!</string>
|
||||
<string name="ignore_sync_errors">可能な場合は同期エラーを無視</string>
|
||||
<string name="ignore_sync_errors_summary">同期中にエラーが発生しても、すぐに中止しないでください。 同期が完了してもエラーは表示されます。 場合によってはお気に入りが失われることがあります。 大きなライブラリを同期する場合に便利です。</string>
|
||||
<string name="force_sync_state_reset">強制的に同期状態をリセット</string>
|
||||
<string name="force_sync_state_reset_summary">次の同期で完全な再同期を実行します。削除は同期されません。 アプリ内のお気に入りは全て ExHentai に再度アップロードされ、ExHentai のすべてのお気に入りはアプリ内に再ダウンロードされます。 同期が中断後に同期を修復するのに役立ちます。</string>
|
||||
<string name="sync_state_reset">同期状態をリセット</string>
|
||||
<string name="gallery_update_checker">ギャラリーの更新をチェック</string>
|
||||
<string name="auto_update_restrictions">自動更新の制限</string>
|
||||
<string name="time_between_batches">更新バッチの間隔</string>
|
||||
<string name="time_between_batches_never">ギャラリーを更新しない</string>
|
||||
<string name="time_between_batches_1_hour">1時間</string>
|
||||
<string name="time_between_batches_2_hours">2時間</string>
|
||||
<string name="time_between_batches_3_hours">3時間</string>
|
||||
<string name="time_between_batches_6_hours">6時間</string>
|
||||
<string name="time_between_batches_12_hours">12時間</string>
|
||||
<string name="time_between_batches_24_hours">24時間</string>
|
||||
<string name="time_between_batches_48_hours">48時間</string>
|
||||
<string name="time_between_batches_summary_1">%1$s は現在、ライブラリ内のギャラリーで更新を確認することはありません。</string>
|
||||
<string name="time_between_batches_summary_2">%1$s のチェック/更新ギャラリーは一括で行われます。つまり、 %2$d 時間待機します。 %3$d ギャラリーをチェックし、 %2$d 時間待機します。…で %3$d をチェックします。</string>
|
||||
<string name="show_updater_statistics">更新の統計情報を表示</string>
|
||||
<string name="gallery_updater_statistics_collection">統計情報を収集中...</string>
|
||||
<string name="gallery_updater_statistics">ギャラリー更新の統計情報</string>
|
||||
<string name="gallery_updater_stats_text">更新は最後に %1$s を実行し、確認可能な %3$d ギャラリーのうち %2$d を確認しました。</string>
|
||||
<string name="gallery_updater_not_ran_yet">更新はまだ実行されていません。</string>
|
||||
<string name="gallery_updater_stats_time">\n最後に確認されたギャラリー:\n- 時間: %1$d\n- 6 時間: %2$d\n- 12 時間: %3$d\n- 日: %4$d\n- 2 日: %5$d\n- 週: %6$d\n- 月: %7$d\n- 年: %8$d</string>
|
||||
<!-- EH Settings Upload Dialogs -->
|
||||
<string name="settings_profile_note">設定プロファイルノート</string>
|
||||
<string name="settings_profile_note_message">アプリのパフォーマンスを最適化するため、 E-Hentai と ExHentai に新しい設定プロファイルが追加されます。両サイトのプロファイルが3つ以下であることを確認してください。\n\n設定プロファイルが分からない場合は、「OK」を押してください。</string>
|
||||
<string name="eh_settings_successfully_uploaded">設定が正常にアップロードされました!</string>
|
||||
<string name="eh_settings_configuration_failed">設定に失敗しました!</string>
|
||||
<string name="eh_settings_configuration_failed_message">設定処理中にエラーが発生しました: %1$s</string>
|
||||
<string name="eh_settings_uploading_to_server">設定をサーバーにアップロードしています</string>
|
||||
<string name="eh_settings_uploading_to_server_message">しばらくお待ちください…</string>
|
||||
<string name="eh_settings_out_of_slots_error">%1$sのプロファイルの枠がありません。プロファイルを削除してください!</string>
|
||||
<!-- EH Settings Login Activity -->
|
||||
<string name="recheck_login_status">ログイン状態を再確認</string>
|
||||
<string name="alternative_login_page">代替のログインページ</string>
|
||||
<string name="skip_page_restyling">ページのスタイル変更をスキップ</string>
|
||||
<string name="custom_igneous_cookie">任意の火成 Cookie</string>
|
||||
<string name="custom_igneous_cookie_message">一部のユーザーは、通常の方法で ExHentai にアクセスできず、特定の火成 Cookie の値を渡す必要があります。このオプションは、それらのユーザーのためのものです。</string>
|
||||
<!-- Advanced Settings -->
|
||||
<string name="developer_tools">開発者ツール</string>
|
||||
<string name="toggle_hentai_features">統合されたセンシティブな機能を有効化</string>
|
||||
<string name="toggle_hentai_features_summary">これをオフに切り替えるとすべてのセンシティブな機能を無効にする実験的な機能です。</string>
|
||||
<string name="toggle_delegated_sources">委任されたソースを有効化</string>
|
||||
<string name="toggle_delegated_sources_summary">以下のソースがインストールされている場合は %1$s の機能強化を適用します: %2$s</string>
|
||||
<string name="log_level">ログレベル</string>
|
||||
<string name="log_level_summary">これを変更するとアプリのパフォーマンスに影響を与える可能性があります。変更後の強制再起動アプリ。現在の値: %s</string>
|
||||
<string name="enable_source_blacklist">ソースのブラックリストを有効化</string>
|
||||
<string name="enable_source_blacklist_summary">%1$s と互換性のない拡張機能/ソースを非表示にします。変更後にアプリを強制再起動します。</string>
|
||||
<string name="open_debug_menu">デバッグメニューを開く</string>
|
||||
<string name="open_debug_menu_summary"><![CDATA[このメニューには触れないで下さい!操作を理解している場合のみ使用して下さい。 <font color=\'red\'>ライブラリが破損する可能性があります!</font>]]></string>
|
||||
<string name="starting_cleanup">クリーンアップを開始中</string>
|
||||
<string name="clean_up_downloaded_chapters">ダウンロード済みの章をクリーンアップ</string>
|
||||
<string name="delete_unused_chapters">存在しないフォルダ、部分的にダウンロードされたフォルダ、および既読の章のフォルダを削除します。</string>
|
||||
<string name="no_folders_to_cleanup">クリーンアップするフォルダーがありません</string>
|
||||
<string name="clean_orphaned_downloads">孤立したものを消去</string>
|
||||
<string name="clean_read_downloads">既読をクリア</string>
|
||||
<string name="clean_read_entries_not_in_library">ライブラリにない項目を消去</string>
|
||||
<string name="data_saver">データセーバー</string>
|
||||
<string name="data_saver_summary">ダウンロードまたはリーダーで読み込む前に画像を圧縮します</string>
|
||||
<string name="data_saver_downloader">ダウンローダーでデータセーバーを使用</string>
|
||||
<string name="data_saver_ignore_jpeg">Jpeg 画像を除外</string>
|
||||
<string name="data_saver_ignore_gif">Gif アニメーションを除外</string>
|
||||
<string name="data_saver_image_quality">画像品質</string>
|
||||
<string name="data_saver_image_quality_summary">値が高いほど画像の品質も高く保存されるが、ファイルサイズも大きくなります。80 パーセントはファイルサイズと画像品質のバランスが取れた中間値です。</string>
|
||||
<string name="data_saver_image_format">Jpeg に圧縮</string>
|
||||
<string name="data_saver_image_format_summary_on">Jpeg のファイルサイズは Webp よりかなり小さい (つまり、より多くのデータが保存される) が、その分画質も低下します。\n現在は Jpeg に圧縮</string>
|
||||
<string name="data_saver_image_format_summary_off">Jpeg のファイルサイズは Webp よりかなり小さい (つまり、より多くのデータが保存される) が、その分画質も低下します。\n現在は Webp に圧縮</string>
|
||||
<string name="data_saver_color_bw">モノクロに変換</string>
|
||||
<string name="bandwidth_hero">Bandwidth Hero (Bandwidth Hero Proxy サーバが必要)</string>
|
||||
<string name="wsrv">wsrv.nl</string>
|
||||
<string name="bandwidth_data_saver_server">Bandwidth Hero Proxy Server</string>
|
||||
<string name="data_saver_server_summary">ここに Bandwidth Hero Proxy server のurlを入力して下さい</string>
|
||||
<string name="clear_db_exclude_read">既読の章がある作品を保留</string>
|
||||
<!-- Log Level -->
|
||||
<string name="log_minimal">最小</string>
|
||||
<string name="log_extra">最大</string>
|
||||
<string name="log_extreme">最高</string>
|
||||
<string name="log_minimal_desc">重大なエラーのみ</string>
|
||||
<string name="log_extra_desc">すべてのログを記録</string>
|
||||
<string name="log_extreme_desc">ネットワーク検査モード</string>
|
||||
<!-- General Settings -->
|
||||
<string name="toggle_expand_search_filters">デフォルトですべての検索フィルタを展開</string>
|
||||
<string name="put_recommends_in_overflow">3点メニューからおすすめを見る</string>
|
||||
<string name="put_recommends_in_overflow_summary">「おすすめを見る」ボタンを作品ページの代わりに3点メニューに配置</string>
|
||||
<string name="put_merge_in_overflow">3点メニューから合併</string>
|
||||
<string name="put_merge_in_overflow_summary">合併ボタンを作品ページの代わりに3点メニューに配置</string>
|
||||
<string name="pref_previews_row_count">プレビューする行数</string>
|
||||
<!-- Appearance Settings -->
|
||||
<string name="pref_category_navbar">ナビゲーションバー</string>
|
||||
<string name="pref_hide_updates_button">ナビゲーションバーに新着を表示</string>
|
||||
<string name="pref_hide_history_button">ナビゲーションバーに履歴を表示</string>
|
||||
<string name="pref_show_bottom_bar_labels">常にナビゲーションバーのラベルを表示</string>
|
||||
<!-- Library settings -->
|
||||
<string name="pref_sorting_settings">並べ替え設定</string>
|
||||
<string name="pref_skip_pre_migration_summary">最後に使用した移行設定とソースを使用して、一括移行します</string>
|
||||
<string name="library_group_updates">ライブラリーで動的なカテゴリー更新</string>
|
||||
<string name="library_group_updates_global">常にグローバル更新を開始</string>
|
||||
<string name="library_group_updates_all_but_ungrouped">グループ化されていないカテゴリの更新に対してのみグローバル更新を開始</string>
|
||||
<string name="library_group_updates_all">カテゴリーを常時更新</string>
|
||||
<string name="pref_mark_read_dupe_chapters">重複する章に既読のマーク</string>
|
||||
<string name="pref_mark_read_dupe_chapters_summary">既読後に重複した章に既読マークをつけます</string>
|
||||
<string name="pref_library_mark_duplicate_chapters">重複した新しい章を既読</string>
|
||||
<string name="pref_library_mark_duplicate_chapters_summary">以前に読んだことがある場合、自動的に新しい章を既読としてマークします</string>
|
||||
<string name="update_30min">30分毎</string>
|
||||
<string name="update_1hour">毎時間</string>
|
||||
<string name="update_3hour">3時間毎</string>
|
||||
<!-- Browse settings -->
|
||||
<string name="pref_hide_feed">フィードタブを非表示</string>
|
||||
<string name="pref_feed_position">フィードタブの位置</string>
|
||||
<string name="pref_feed_position_summery">フィードタブをブラウズの最初のタブにしますか? これは、ブラウズを開いたときのデフォルトのタブになります。データ通信や従量制のネットワークを使用している場合はお勧めしません。</string>
|
||||
<string name="pref_source_source_filtering">カテゴリー内のソースをフィルター</string>
|
||||
<string name="pref_source_source_filtering_summery">カテゴリーに含まれるソースをフィルタリングし、カテゴリーに含まれるソースが言語の下に置かれないようにします</string>
|
||||
<string name="pref_source_navigation">ソースの表示形式を変更</string>
|
||||
<string name="pref_source_navigation_summery">ソースを、最近の更新とブラウズの両方を含むブラウズの表示形式に変更します</string>
|
||||
<string name="pref_local_source_hidden_folders">ローカルソースの隠しフォルダー</string>
|
||||
<string name="pref_local_source_hidden_folders_summery">ローカルソースに隠しフォルダの読み取りを許可します</string>
|
||||
<!-- Backup settings -->
|
||||
<string name="custom_entry_info">カスタムした作品の情報</string>
|
||||
<string name="all_read_entries">全ての既読の作品</string>
|
||||
<string name="label_sync">同期</string>
|
||||
<string name="label_triggers">トリガー</string>
|
||||
<!-- Sync settings -->
|
||||
<string name="sync_error">ライブラリの同期に失敗しました</string>
|
||||
<string name="sync_complete">ライブラリの同期が完了しました</string>
|
||||
<string name="sync_in_progress">同期は既に実行中です</string>
|
||||
<string name="pref_sync_host">ホスト</string>
|
||||
<string name="pref_sync_host_summ">ライブラリを同期するためのホストアドレスを入力してください</string>
|
||||
<string name="pref_sync_api_key">API キー</string>
|
||||
<string name="pref_sync_api_key_summ">ライブラリを同期するための API キーを入力してください</string>
|
||||
<string name="pref_sync_now_group_title">同期アクション</string>
|
||||
<string name="pref_sync_now">今すぐ同期</string>
|
||||
<string name="pref_sync_now_subtitle">データの即時同期を開始</string>
|
||||
<string name="pref_sync_service">サービス</string>
|
||||
<string name="pref_sync_service_category">同期</string>
|
||||
<string name="pref_sync_automatic_category">自動同期</string>
|
||||
<string name="pref_sync_interval">同期の間隔</string>
|
||||
<string name="pref_choose_what_to_sync">同期する項目を選択</string>
|
||||
<string name="syncyomi">SyncYomi</string>
|
||||
<string name="last_synchronization">最後の同期: %1$s</string>
|
||||
<string name="google_drive">Google ドライブ</string>
|
||||
<string name="pref_google_drive_sign_in">サインイン</string>
|
||||
<string name="pref_google_drive_purge_sync_data">Google ドライブから同期データを消去</string>
|
||||
<string name="google_drive_sync_data_purged">Google ドライブから消去したデータを同期</string>
|
||||
<string name="google_drive_sync_data_not_found">Google ドライブに同期データが見つかりませんでした</string>
|
||||
<string name="google_drive_sync_data_purge_error">Google ドライブから同期データの消去中にエラーが発生しました。もう一度サインインしてみてください。</string>
|
||||
<string name="google_drive_login_success">Google Driveにログイン</string>
|
||||
<string name="google_drive_login_failed">Google ドライブにログインできませんでした: %s</string>
|
||||
<string name="google_drive_not_signed_in">Google ドライブにサインインしていません</string>
|
||||
<string name="error_uploading_sync_data">Google ドライブに同期データのアップロード中にエラーが発生しました</string>
|
||||
<string name="error_deleting_google_drive_lock_file">Google ドライブのロックファイルの削除エラー</string>
|
||||
<string name="error_before_sync_gdrive">同期前にエラーが発生しました: %s</string>
|
||||
<string name="pref_purge_confirmation_title">削除の確認</string>
|
||||
<string name="pref_purge_confirmation_message">同期データを消去すると、Google ドライブからすべての同期データが削除されます。続行してもよろしいですか?</string>
|
||||
<string name="pref_sync_options">同期トリガーを作成</string>
|
||||
<string name="pref_sync_options_summ">同期トリガーの設定に使用できます</string>
|
||||
<string name="sync_on_chapter_read">章の既読時に同期</string>
|
||||
<string name="sync_on_chapter_open">章を開いた時に同期</string>
|
||||
<string name="sync_on_app_start">アプリ起動時に同期</string>
|
||||
<string name="sync_on_app_resume">アプリ再開時に同期</string>
|
||||
<string name="sync_library">ライブラリーを同期</string>
|
||||
<!-- Security settings -->
|
||||
<string name="biometric_lock_times">生体認証ロックの時間設定</string>
|
||||
<string name="action_edit_biometric_lock_times">ロック時間を編集</string>
|
||||
<string name="biometric_lock_times_empty">生体認証ロックの時間設定がありません。 プラスボタンをタップして作成します。</string>
|
||||
<string name="biometric_lock_time_conflicts">設定したロック時間が既に存在するものと競合しています!</string>
|
||||
<string name="biometric_lock_start_time">開始時刻を入力</string>
|
||||
<string name="biometric_lock_end_time">終了時刻を入力</string>
|
||||
<string name="delete_time_range">削除する時間範囲</string>
|
||||
<string name="delete_time_range_confirmation">時間範囲 %s を削除しますか?</string>
|
||||
<string name="biometric_lock_days">生体認証ロックの曜日</string>
|
||||
<string name="biometric_lock_days_summary">アプリをロックさせる曜日</string>
|
||||
<string name="sunday">日曜日</string>
|
||||
<string name="monday">月曜日</string>
|
||||
<string name="tuesday">火曜日</string>
|
||||
<string name="wednesday">水曜日</string>
|
||||
<string name="thursday">木曜日</string>
|
||||
<string name="friday">金曜日</string>
|
||||
<string name="saturday">土曜日</string>
|
||||
<string name="encrypt_database">データベースを暗号化</string>
|
||||
<string name="encrypt_database_subtitle">適用するにはアプリの再起動が必要です</string>
|
||||
<string name="encrypt_database_message"><![CDATA[<font color=\'red\'>これを有効にすると、新しいデータベースが作成されます。 以下の手順でデータを保存してください<br>1. 設定 -> バックアップ -> 作成<br>2. システム設定 -> アプリのデータを消去<br>3. アプリを開き、この設定を有効にする<br>4. システム設定 -> 強制再起動<br>5. 設定 -> バックアップ -> 復元</font>]]></string>
|
||||
<string name="set_cbz_zip_password">CBZ アーカイブのパスワードを設定</string>
|
||||
<string name="password_protect_downloads">ダウンロードをパスワードで保護</string>
|
||||
<string name="password_protect_downloads_summary">ダウンロードした CBZ アーカイブを指定したパスワードで暗号化します。\n注意: パスワードを忘れると、アーカイブ内のデータは永久的に失われます。</string>
|
||||
<string name="delete_cbz_archive_password">CBZ アーカイブのパスワードを削除</string>
|
||||
<string name="cbz_archive_password">CBZ アーカイブのパスワード</string>
|
||||
<string name="wrong_cbz_archive_password">CBZ アーカイブのパスワードが間違っています</string>
|
||||
<string name="encryption_type">暗号化の種類</string>
|
||||
<string name="aes_256">AES 256</string>
|
||||
<string name="aes_192">AES 192</string>
|
||||
<string name="aes_128">AES 128</string>
|
||||
<string name="standard_zip_encryption">標準的な zip 暗号化 (高速ですが安全ではありません)</string>
|
||||
<!-- Reader Settings -->
|
||||
<string name="page_downloading">ページをダウンロード中</string>
|
||||
<string name="download_threads">ダウンロードスレッド</string>
|
||||
<string name="download_threads_summary">値を高いほど画像のダウンロードが大幅に速くなりますが、banされることもあります。 推奨値は 2 または 3 です。 現在の値は %s です。</string>
|
||||
<string name="aggressively_load_pages">積極的にページを読み込む</string>
|
||||
<string name="aggressively_load_pages_summary">閲覧中のページだけを読み込むのではなく、読書中に章全体をゆっくりとダウンロードします。</string>
|
||||
<string name="skip_queue_on_retry">再試行時にキューをスキップ</string>
|
||||
<string name="skip_queue_on_retry_summary">通常、失敗したダウンロードの再試行ボタンを押すと、失敗したページを再ダウンロードし始める前にダウンロードが終了するまで待機します。 これを有効にした場合、再試行ボタンを押した瞬間にダウンローダーが失敗したページの再ダウンロードを強制的に開始します。</string>
|
||||
<string name="reader_preload_amount">プリロードするページ数</string>
|
||||
<string name="reader_preload_amount_4_pages">4ページ</string>
|
||||
<string name="reader_preload_amount_6_pages">6ページ</string>
|
||||
<string name="reader_preload_amount_8_pages">8ページ</string>
|
||||
<string name="reader_preload_amount_10_pages">10ページ</string>
|
||||
<string name="reader_preload_amount_12_pages">12ページ</string>
|
||||
<string name="reader_preload_amount_14_pages">14ページ</string>
|
||||
<string name="reader_preload_amount_16_pages">16ページ</string>
|
||||
<string name="reader_preload_amount_20_pages">20ページ</string>
|
||||
<string name="reader_preload_amount_summary">読み込み時にプリロードするページ数です。 値が大きいほど、キャッシュの使用量が増え、読み込みがスムーズになります。 大きい値を使用する場合は、割り当てるキャッシュの量を増やすことをお勧めします</string>
|
||||
<string name="reader_cache_size">リーダーのキャッシュサイズ</string>
|
||||
<string name="reader_cache_size_summary">読書中にデバイスに保存する画像の量です。 値が大きいほど、よりスムーズな読書体験が得られますが、ディスクの使用量が増えます。</string>
|
||||
<string name="preserve_reading_position">読んだ作品の読書位置を保持</string>
|
||||
<string name="auto_webtoon_mode">自動的にWebtoonモードを使用</string>
|
||||
<string name="auto_webtoon_mode_summary">長いストリップ形式の可能性のある作品を検出した場合、自動的にWebtoonモードを使用します</string>
|
||||
<string name="enable_zoom_out">ズームアウトを有効化</string>
|
||||
<string name="tap_scroll_page">ページごとにスクロールをタップ</string>
|
||||
<string name="tap_scroll_page_summary">このオプションを有効にすると、画面サイズではなくページ単位でスクロールします</string>
|
||||
<string name="reader_bottom_buttons">リーダーの下部にあるボタン</string>
|
||||
<string name="reader_bottom_buttons_summary">リーダーの下部に表示されるボタンをカスタマイズします</string>
|
||||
<string name="pref_show_vert_seekbar_landscape">横向き時に垂直シークバーを表示</string>
|
||||
<string name="pref_show_vert_seekbar_landscape_summary">横向き時に垂直シークバーを有効にする</string>
|
||||
<string name="pref_left_handed_vertical_seekbar">左利きの垂直シークバー</string>
|
||||
<string name="pref_left_handed_vertical_seekbar_summary">シークバーの位置を左右に切り替えます</string>
|
||||
<string name="pref_force_horz_seekbar">水平方向のシークバーを強制</string>
|
||||
<string name="pref_force_horz_seekbar_summary">垂直方向のシークバーを完全に削除し、水平方向に変更します</string>
|
||||
<string name="pref_smooth_scroll">スムーズな自動スクロール</string>
|
||||
<!-- Reader -->
|
||||
<!-- Reader Actions -->
|
||||
<string name="eh_autoscroll">自動スクロール</string>
|
||||
<string name="eh_retry_all">全て再試行</string>
|
||||
<string name="eh_boost_page">ブーストページ</string>
|
||||
<string name="eh_autoscroll_help">自動スクロールのヘルプ</string>
|
||||
<string name="eh_autoscroll_help_message">指定した間隔で自動的に次のページにスクロールします。 間隔は秒単位で指定する必要があります。</string>
|
||||
<string name="eh_autoscroll_freq_invalid">無効な値</string>
|
||||
<string name="eh_retry_all_help">すべてのヘルプを再試行</string>
|
||||
<string name="eh_retry_all_help_message">失敗したすべてのページをダウンロードキューに再追加します。</string>
|
||||
<string name="eh_boost_page_help">ブーストページのヘルプ</string>
|
||||
<string name="eh_boost_page_help_message">通常、ダウンローダーは一度に特定の数のページしかダウンロードできません。つまり、ページのダウンロードを待っている間、ダウンローダーは空きスロットができるまでそのページのダウンロードを開始しできません。「ページをブースト」を押すと、空きスロットがあるかどうかに関係なく、現在のページのダウンロードを強制的に開始します。</string>
|
||||
<string name="eh_boost_page_invalid">このページはブーストできません (無効なページ)!</string>
|
||||
<string name="eh_boost_page_errored">ページの読み込みに失敗しました。代わりに再試行ボタンを押してください!</string>
|
||||
<string name="eh_boost_page_downloading">このページは既にダウンロード中です!</string>
|
||||
<string name="eh_boost_page_downloaded">このページは既にダウンロードされています!</string>
|
||||
<string name="eh_boost_boosted">現在のページをブーストしました!</string>
|
||||
<string name="eh_boost_invalid_loader">このページはブーストできません (無効なページローダー)!</string>
|
||||
<string name="pref_crop_borders_pager">ページを分けるのクロップボーダー</string>
|
||||
<string name="pref_crop_borders_continuous_vertical">縦長のストリップのクロップボーダー</string>
|
||||
<string name="pref_crop_borders_webtoon">ギャップ付き縦長のストリップのクロップボーダー</string>
|
||||
<string name="action_set_first_page_cover">1ページ目をカバーとして設定</string>
|
||||
<string name="action_set_second_page_cover">2ページ目をカバーとして設定</string>
|
||||
<string name="action_save_first_page">1ページ目を保存</string>
|
||||
<string name="action_save_second_page">2ページ目を保存</string>
|
||||
<string name="action_share_first_page">1ページ目をシェア</string>
|
||||
<string name="action_share_second_page">2ページ目をシェア</string>
|
||||
<string name="action_save_combined_page">合併されたページを保存</string>
|
||||
<string name="action_share_combined_page">合併されたページをシェア</string>
|
||||
<!-- Reader Sharing -->
|
||||
<string name="share_pages_info">%1$s: %2$s, ページ %3$s</string>
|
||||
<!-- Auto Webtoon Mode -->
|
||||
<string name="eh_auto_webtoon_snack">Webtoonのスタイルを読み込み中</string>
|
||||
<!-- Double page spread -->
|
||||
<string name="page_layout">ページレイアウト</string>
|
||||
<string name="shift_double_pages">1ページずらす</string>
|
||||
<string name="double_pages">見開きページ</string>
|
||||
<string name="single_page">単ページ</string>
|
||||
<string name="automatic_orientation">自動 (向きに基づく)</string>
|
||||
<string name="automatic_can_still_switch">ページレイアウトで自動を使用している場合でも、この設定を上書きせずに、読書中にレイアウトを切り替えることができます</string>
|
||||
<string name="invert_double_pages">見開きページを反転</string>
|
||||
<!-- Center margin -->
|
||||
<string name="center_margin">中央に余白</string>
|
||||
<string name="center_margin_none">なし</string>
|
||||
<string name="center_margin_double_page">見開きページに追加</string>
|
||||
<string name="center_margin_wide_page">幅広いページに追加</string>
|
||||
<string name="center_margin_double_and_wide_page">両方に追加</string>
|
||||
<string name="pref_center_margin">中央に余白の種類</string>
|
||||
<string name="pref_center_margin_summary">折りたたみ式デバイスのデッドスペースに対応するスペーサーを挿入します。</string>
|
||||
<!-- Archive reader mode -->
|
||||
<string name="archive_mode_load_from_file">ファイルから読み込む</string>
|
||||
<string name="archive_mode_load_into_memory">メモリに読み込む</string>
|
||||
<string name="archive_mode_cache_to_disk">ディスクにコピー</string>
|
||||
<string name="pref_archive_reader_mode">アーカイブリーダーモード</string>
|
||||
<string name="pref_archive_reader_mode_summary">CBZ や CBR などのアーカイブ内の画像の読み込み方法</string>
|
||||
<!-- Entry Page -->
|
||||
<!-- Entry Info -->
|
||||
<string name="az_recommends">おすすめを見る</string>
|
||||
<string name="merge">合併</string>
|
||||
<string name="merge_with_another_source">もう一つと合併</string>
|
||||
<string name="entry_merged">作品が合併されました!</string>
|
||||
<string name="failed_merge">合併に失敗: %1$s</string>
|
||||
<string name="merge_unknown_entry">不明な作品ID: %1$d</string>
|
||||
<string name="merged_already">この作品は既に現在の作品と合併されています!</string>
|
||||
<string name="merge_duplicate">合併する作品が重複しています!</string>
|
||||
<!-- Entry Info Edit -->
|
||||
<string name="reset_tags">タグをリセット</string>
|
||||
<string name="add_tag">タグを追加</string>
|
||||
<string name="reset_info">情報をリセット</string>
|
||||
<string name="title_hint">タイトル: %1$s</string>
|
||||
<string name="description_hint">説明: %1$s</string>
|
||||
<string name="author_hint">著者: %1$s</string>
|
||||
<string name="artist_hint">アーティスト: %1$s</string>
|
||||
<string name="thumbnail_url_hint">サムネイル Url: %1$s</string>
|
||||
<!-- Browse -->
|
||||
<!-- Sources Tab -->
|
||||
<string name="find_in_another_source">別のソースから検索</string>
|
||||
<string name="data_saver_exclude">データセーバーから除外する</string>
|
||||
<string name="data_saver_stop_exclude">データセーバーからの除外を停止</string>
|
||||
<!-- Smart Search -->
|
||||
<string name="searching_source">ソースから検索中…</string>
|
||||
<string name="could_not_find_entry">ソース内に作品が見つかりませんでした!</string>
|
||||
<string name="automatic_search_error">自動検索中にエラーが発生しました!</string>
|
||||
<!-- Saved Searches -->
|
||||
<string name="saved_searches">保存済みの検索</string>
|
||||
<string name="save_search">現在の検索条件を保存しますか?</string>
|
||||
<string name="save_search_hint">検索名</string>
|
||||
<string name="save_search_failed_to_load">保存した検索の読み込みに失敗しました!</string>
|
||||
<string name="save_search_failed_to_load_message">保存した検索の読み込み中にエラーが発生しました。</string>
|
||||
<string name="save_search_delete">保存した検索条件を削除しますか?</string>
|
||||
<string name="save_search_delete_message">保存した検索条件「%1$s」を削除してもよろしいですか?</string>
|
||||
<string name="save_search_invalid">保存された検索は無効です。フィルターが変更されました</string>
|
||||
<string name="save_search_invalid_name">保存された検索名が無効です</string>
|
||||
<!-- Source Categories -->
|
||||
<string name="no_source_categories">利用可能なソースカテゴリーがありません</string>
|
||||
<string name="invalid_category_name">無効なカテゴリー名です</string>
|
||||
<!-- Feed Tab -->
|
||||
<string name="feed">フィード</string>
|
||||
<string name="feed_delete">フィードのアイテムを削除しますか?</string>
|
||||
<string name="too_many_in_feed">フィードにソースが多すぎます。10 以上を追加できません。</string>
|
||||
<string name="feed_tab_empty">フィードにソースがありません。右上に移動して追加してください</string>
|
||||
<string name="feed_add">フィードに %1$s を追加しますか?</string>
|
||||
<!-- Sort by tags -->
|
||||
<string name="pref_tag_sorting">タグの並べ替えタグ</string>
|
||||
<string name="tag_sorting">タグの並べ替え</string>
|
||||
<string name="action_add_tags_message">これを読んでください!タグは正確でなければならず、部分一致はありません。「female:netorare」などをフィルタリングするために「netorare」を使用することはできません!\nネームスペースタグの形式は、引用符なしで「female: sole female」となります。\n同じタグの複数のバリエーションを追加することがサポートされているので、NHentai用には「tag: netorare」、E-Hentai用には「female: netorare」を自由に使用してください!</string>
|
||||
<string name="action_edit_tags">タグを編集</string>
|
||||
<string name="information_empty_tags">タグがありません。プラスボタンをタップして、ライブラリをタグで並べ替えをするためのタグを作成してください。</string>
|
||||
<string name="error_tag_exists">このタグは既に存在します!</string>
|
||||
<string name="delete_tag">タグを削除</string>
|
||||
<string name="delete_tag_confirmation">タグ %s を削除しますか?</string>
|
||||
<!-- Extension section -->
|
||||
<string name="ext_redundant">冗長</string>
|
||||
<string name="redundant_extension_message">この拡張機能は冗長であり、このバージョンのTachiyomiでは使用されません。</string>
|
||||
<!-- Migration -->
|
||||
<string name="select_sources">ソースを選択</string>
|
||||
<string name="select_none">選択なし</string>
|
||||
<string name="migration">移行</string>
|
||||
<string name="skip_pre_migration">移行設定をスキップ</string>
|
||||
<string name="pre_migration_skip_toast">この画面を再度表示するには、設定 -> ライブラリに移動してください。</string>
|
||||
<string name="use_intelligent_search">検索タイトル + タイトルのキーワード</string>
|
||||
<string name="data_to_include_in_migration">移行に含めるデータ</string>
|
||||
<string name="include_extra_search_parameter">検索時に追加の検索パラメータを含める</string>
|
||||
<string name="use_most_chapters">章が最も多いソースを使用する (低速)</string>
|
||||
<string name="use_first_source">最初のソースを代わりに使用</string>
|
||||
<string name="skip_this_step_next_time">次回はこのステップをスキップ</string>
|
||||
<string name="hide_not_found_entries">見つからない作品を非表示</string>
|
||||
<string name="search_parameter">検索パラメータ (言語:英語)</string>
|
||||
<string name="latest_">最新: %1$s</string>
|
||||
<string name="migrating_to">移行先</string>
|
||||
<string name="match_pinned_sources">ピン留めしたソースを選択</string>
|
||||
<string name="match_enabled_sources">有効化したソースを選択</string>
|
||||
<string name="no_chapters_found_for_migration">章が見つかりませんでした。この作品は移行に使用できません。</string>
|
||||
<string name="no_alternatives_found">代替が見つかりませんでした</string>
|
||||
<string name="stop_migrating">移行を停止しますか?</string>
|
||||
<string name="action_stop">停止</string>
|
||||
<string name="skipping_">(スキップ %1$d)</string>
|
||||
<!-- Library -->
|
||||
<!-- Library Actions -->
|
||||
<string name="no_valid_entry">有効な作品が選択されていません</string>
|
||||
<!-- Library Sheet -->
|
||||
<string name="lewd">Lewd</string>
|
||||
<!-- Library Grouping -->
|
||||
<string name="tracking_status">追跡のステータス</string>
|
||||
<string name="ungrouped">非グループ</string>
|
||||
<string name="not_tracked">未追跡</string>
|
||||
<!-- Favorites Sync -->
|
||||
<string name="sync_favorites">EH のお気に入りを同期</string>
|
||||
<string name="favorites_sync_error">お気に入りの同期エラー</string>
|
||||
<string name="show_gallery">ギャラリーを表示</string>
|
||||
<string name="favorites_sync_bad_library_state">%1$s 同期は、ギャラリーが1つのカテゴリのみになるまで開始されません。</string>
|
||||
<string name="favorites_syncing">お気に入りの同期中</string>
|
||||
<string name="favorites_sync_error_string">同期中にエラーが発生しました: %1$s</string>
|
||||
<string name="favorites_sync_done_errors">お気に入りの同期がエラー付きで完了しました。</string>
|
||||
<string name="favorites_sync_done_errors_message">同期処理中に発生したエラーを無視しました:\n%1$s</string>
|
||||
<string name="favorites_sync_verifying_library">ローカルライブラリの確認</string>
|
||||
<string name="favorites_sync_gallery_multiple_categories_error">ギャラリー %1$d が複数のカテゴリに登録されています!</string>
|
||||
<string name="favorites_sync_downloading">リモートサーバーからお気に入りをダウンロード中です</string>
|
||||
<string name="favorites_sync_failed_to_featch">リモートサーバーからお気に入りを取得できませんでした!</string>
|
||||
<string name="favorites_sync_could_not_fetch">お気に入りを取得できませんでした!</string>
|
||||
<string name="favorites_sync_calculating_remote_changes">リモート変更を計算中</string>
|
||||
<string name="favorites_sync_calculating_local_changes">ローカルの変更を計算中</string>
|
||||
<string name="favorites_sync_syncing_category_names">カテゴリ名を更新中</string>
|
||||
<string name="favorites_sync_cleaning_up">クリーンアップ</string>
|
||||
<string name="favorites_sync_complete">同期が完了しました!</string>
|
||||
<string name="favorites_sync_ignoring_exception">例外を無視しました!</string>
|
||||
<string name="favorites_sync_sync_error">同期エラー!</string>
|
||||
<string name="favorites_sync_unknown_error">不明なエラー: %1$s</string>
|
||||
<string name="favorites_sync_network_error">同期ネットワークエラー!</string>
|
||||
<string name="favorites_sync_removing_galleries">リモートサーバーから %1$d ギャラリーを削除します</string>
|
||||
<string name="favorites_sync_unable_to_delete">リモートサーバーからギャラリーを削除できません!</string>
|
||||
<string name="favorites_sync_adding_to_remote">リモートサーバーにギャラリー %1$d の %2$d を追加しています</string>
|
||||
<string name="favorites_sync_remove_from_local">ローカルライブラリから %1$d のギャラリー %2$d を削除しています</string>
|
||||
<string name="favorites_sync_add_to_local">ローカルライブラリにギャラリー %1$d の %2$d を追加しています</string>
|
||||
<string name="favorites_sync_remote_not_exist">リモートギャラリーが存在しません。スキップ中: %1$s!</string>
|
||||
<string name="favorites_sync_failed_to_add_to_local">ローカルデータベースにギャラリーを追加できませんでした: </string>
|
||||
<string name="favorites_sync_failed_to_add_to_local_error">\'%1$s\' %2$s</string>
|
||||
<string name="favorites_sync_failed_to_add_to_local_unknown_type">\'%1$s\' (%2$s) は有効なギャラリーではありません!</string>
|
||||
<string name="favorites_sync_waiting_for_start">同期開始待ち</string>
|
||||
<string name="favorites_sync_gallery_in_multiple_categories">ギャラリー: %1$s は複数のカテゴリ (%2$s ) にあります!</string>
|
||||
<string name="favorites_sync_initializing">同期を初期化中</string>
|
||||
<string name="favorites_sync_processing_throttle">%1$s\n\n同期は現在(ExhentaiからのBANを避けるため)、完了までに時間がかかることがあります。</string>
|
||||
<string name="favorites_sync_notes">お気に入り同期に関する重要な注意事項</string>
|
||||
<string name="favorites_sync_notes_message"><![CDATA[1. アプリ内のカテゴリ名の変更は<b>同期されません!</b>カテゴリ名を変更する場合は、<i>ExHentaiで変更してください</i>。カテゴリ名は毎回の同期でExHentaiサーバーからコピーされます。<br><br>
|
||||
2. ExHentaiのお気に入りカテゴリは、アプリ内の<b>最初の10カテゴリ</b>(「デフォルト」カテゴリを除く)に対応しています。<i>他のカテゴリにあるギャラリーは<b>同期されません!</b></i><br><br>3. <font color=\'red\'><b>同期中は安定したインターネット接続を確保してください!</b></font> インターネットが同期中に切断されると、お気に入りが<i>部分的に同期された状態</i>になる可能性があります。<br><br>4. お気に入りを同期している間はアプリを開いたままにしてください。Androidはバックグラウンドでアプリを閉じることがあり、同期中にこれが起こると問題が発生する可能性があります。<br><br>5. <b>お気に入りを複数のカテゴリに入れないでください</b>(アプリはこれをサポートしています)。ExHentaiでは各お気に入りが1つのカテゴリにしか入れられないため、同期アルゴリズムが混乱する可能性があります。<br><br>このダイアログは一度だけ表示されます。これらの注意事項を再度確認するには、「設定 > E-Hentai > お気に入り同期の注意事項を表示」に進んでください。]]></string>
|
||||
<string name="favorites_sync_reset">本当によろしいですか?</string>
|
||||
<string name="favorites_sync_reset_message">同期の状態をリセットすると、次の同期が極端に遅くなることがあります。</string>
|
||||
<string name="favorites_sync_conformation_message">お気に入りをE-Hentaiと同期してもよろしいですか?</string>
|
||||
<!-- Gallery Adder -->
|
||||
<!-- Batch Add -->
|
||||
<string name="eh_batch_add">一括追加</string>
|
||||
<string name="eh_batch_add_description">例:\n\nhttp://e-hentai.org/g/12345/1a2b3c4e\nhttp://g.e-hentai.org/g/67890/6f7g8h9i\nhttp://exhentai.org/g/13579/1a3b5c7e\nhttps://exhentai.org/g/24680/2f4g6h8i\n\nE-H Visitedデータ\n もサポートしています。</string>
|
||||
<string name="eh_batch_add_title">追加するギャラリーを入力してください (改行区切り):</string>
|
||||
<string name="eh_batch_add_button">ギャラリーを追加</string>
|
||||
<string name="eh_batch_add_adding_galleries">ギャラリーを追加中…</string>
|
||||
<string name="eh_batch_add_finish">完了しました</string>
|
||||
<string name="batch_add_no_valid_galleries">追加できるギャラリーがありません!</string>
|
||||
<string name="batch_add_no_valid_galleries_message">追加するには少なくとも1つのギャラリーを指定する必要があります!</string>
|
||||
<string name="batch_add">一括追加</string>
|
||||
<string name="batch_add_ok">[OK]</string>
|
||||
<string name="batch_add_error">[ERROR]</string>
|
||||
<string name="batch_add_summary">\n概要:\n追加: %1$d ギャラリー\n失敗: %2$d ギャラリー</string>
|
||||
<string name="batch_add_success_log_message">追加ギャラリー: %1$s</string>
|
||||
<string name="batch_add_unknown_type_log_message">ギャラリーのエントリータイプが不明です: %1$s</string>
|
||||
<string name="batch_add_unknown_source_log_message">ギャラリーのソースが不明です: %1$s</string>
|
||||
<string name="batch_add_not_exist_log_message">ギャラリーが存在しません: %1$s</string>
|
||||
<string name="gallery_adder_importing_gallery">ギャラリーをインポート中 (url: %1$s, fav: %2$s, forceソース: %3$s)…</string>
|
||||
<string name="gallery_adder_source_uri_must_match">ソースURIの一致チェックエラーが発生しました!</string>
|
||||
<string name="gallery_adder_uri_map_to_gallery_error">ソースURIのマップからギャラリーへのエラーが発生しました!</string>
|
||||
<string name="gallery_adder_uri_map_to_chapter_error">ソースURIのマップから章へのエラーが発生しました!</string>
|
||||
<string name="gallery_adder_uri_clean_error">ソースURIのクリーンアップエラーが発生しました!</string>
|
||||
<string name="gallery_adder_chapter_fetch_error">ギャラリーの章を更新できませんでした: %1$s!</string>
|
||||
<string name="gallery_adder_could_not_add_gallery">ギャラリーを追加できませんでした (url: %1$s)!</string>
|
||||
<string name="gallery_adder_could_not_identify_chapter">章を識別できませんでした (url: %1$s)!</string>
|
||||
<!-- Intercept Activity -->
|
||||
<string name="launching_app">アプリを起動しています…</string>
|
||||
<string name="error_with_reason">エラー: %1$s</string>
|
||||
<string name="could_not_open_entry">この作品を開けませんでした:\n\n%1$s</string>
|
||||
<string name="loading_entry">作品をロード中…</string>
|
||||
<!-- Page previews -->
|
||||
<string name="page_previews">ページプレビュー</string>
|
||||
<string name="more_previews">もっと表示</string>
|
||||
<string name="pref_clear_page_preview_cache">ページプレビューのキャッシュを消去</string>
|
||||
<string name="page_preview_page_go_to">Go to</string>
|
||||
<!-- Rating 0-10 (0, 0.5, 1, 1.5 and so fourth) -->
|
||||
<string name="rating10">Masterpiece</string>
|
||||
<string name="rating9">Amazing</string>
|
||||
<string name="rating8">Great</string>
|
||||
<string name="rating7">Good</string>
|
||||
<string name="rating6">Okay</string>
|
||||
<string name="rating5">Mediocre</string>
|
||||
<string name="rating4">Bad</string>
|
||||
<string name="rating3">Awful</string>
|
||||
<string name="rating2">Painful</string>
|
||||
<string name="rating1">Unbearable</string>
|
||||
<string name="rating0">Disaster</string>
|
||||
<string name="no_rating">No rating</string>
|
||||
<!-- Gallery types -->
|
||||
<string name="doujinshi">Doujinshi</string>
|
||||
<string name="artist_cg">Artist CG</string>
|
||||
<string name="game_cg">Game CG</string>
|
||||
<string name="western">Western</string>
|
||||
<string name="non_h">Non-H</string>
|
||||
<string name="image_set">Image Set</string>
|
||||
<string name="cosplay">Cosplay</string>
|
||||
<string name="asian_porn">Asian Porn</string>
|
||||
<string name="misc">Misc</string>
|
||||
<string name="artbook">Artbook</string>
|
||||
<string name="video">Video</string>
|
||||
<!-- More Info Menu -->
|
||||
<string name="more_info">More info</string>
|
||||
<string name="alt_title">Alt Title</string>
|
||||
<string name="id">Id</string>
|
||||
<string name="token">Token</string>
|
||||
<string name="is_exhentai_gallery">is Exhentai gallery</string>
|
||||
<string name="thumbnail_url">Thumbnail url</string>
|
||||
<string name="genre">Genre</string>
|
||||
<string name="date_posted">Date posted</string>
|
||||
<string name="page_count">Page count</string>
|
||||
<string name="parent">Parent</string>
|
||||
<string name="visible">Visible</string>
|
||||
<string name="language">言語</string>
|
||||
<string name="gallery_size">ギャラリーサイズ</string>
|
||||
<string name="total_favorites">お気に入りの合計</string>
|
||||
<string name="total_ratings">総評価</string>
|
||||
<string name="average_rating">平均評価</string>
|
||||
<string name="aged">Aged</string>
|
||||
<string name="last_update_check">最新の更新を確認</string>
|
||||
<string name="path">パス</string>
|
||||
<string name="artist">アーティスト</string>
|
||||
<string name="characters">キャラクター</string>
|
||||
<string name="group">グループ</string>
|
||||
<string name="media_id">メディア ID</string>
|
||||
<string name="japanese_title">日本語タイトル</string>
|
||||
<string name="english_title">英語タイトル</string>
|
||||
<string name="short_title">簡略タイトル</string>
|
||||
<string name="cover_image_file_type">カバー画像ファイルの種類</string>
|
||||
<string name="thumbnail_image_file_type">サムネイル画像ファイルの種類</string>
|
||||
<string name="url">Url</string>
|
||||
<string name="uploader_capital">Uploader Capitalized</string>
|
||||
<string name="uploader">アップローダー</string>
|
||||
<string name="rating_string">Rating string</string>
|
||||
<string name="collection">コレクション</string>
|
||||
<string name="parodies">パロディー</string>
|
||||
<string name="author">著者</string>
|
||||
<string name="last_chapter_number">最後の章番号</string>
|
||||
<string name="follow_status">フォロー状態</string>
|
||||
<string name="anilist_id">Anilist id</string>
|
||||
<string name="kitsu_id">Kitsu id</string>
|
||||
<string name="mal_id">Mal id</string>
|
||||
<string name="manga_updates_id">漫画の更新ID</string>
|
||||
<string name="anime_planet_id">Anime planet id</string>
|
||||
<string name="translated">翻訳済み</string>
|
||||
<!-- Extra gallery info -->
|
||||
<string name="is_visible">表示: %1$s</string>
|
||||
<string name="language_translated">%1$s TR</string>
|
||||
<!-- Merged entry -->
|
||||
<string name="merge_settings">合併設定</string>
|
||||
<string name="fetch_chapter_updates">章の更新情報を取得</string>
|
||||
<string name="delete_merged_entry">本当によろしいですか?</string>
|
||||
<string name="delete_merged_entry_desc">これを使用すると、合併から作品が削除されます。また、合併した作品に適用された未保存の変更も失われます。</string>
|
||||
<string name="chapter_updates_merged_entry">章の更新を切り替え</string>
|
||||
<string name="chapter_updates_merged_entry_desc">これを切り替えると、合併した作品の章の更新が無効または有効になります</string>
|
||||
<string name="download_merged_entry">新しい章のダウンロードの切り替え</string>
|
||||
<string name="download_merged_entry_desc">これを切り替えると、合併した作品の章のダウンロードが無効または有効になります</string>
|
||||
<string name="merged_references_invalid">合併する作品が無効です</string>
|
||||
<string name="merged_chapter_updates_error">章の更新エラーの切り替え</string>
|
||||
<string name="merged_toggle_download_chapters_error">章のダウンロードエラーの切り替え</string>
|
||||
<string name="allow_deduplication">重複除外を許可:</string>
|
||||
<string name="deduplication_mode">重複除外モード:</string>
|
||||
<string name="deduplication_entry_info">情報の入力:</string>
|
||||
<string name="no_dedupe">重複除外なし</string>
|
||||
<string name="dedupe_priority">優先順位順に重複除外</string>
|
||||
<string name="dedupe_most_chapters">ほとんどの章でソースを表示</string>
|
||||
<string name="dedupe_highest_chapter">章番号が最も高いソースを表示</string>
|
||||
<!-- MangaDex -->
|
||||
<string name="md_follows_unfollowed">フォロー解除</string>
|
||||
<string name="mangadex_sync_follows_to_library">MangaDexエントリーをライブラリに同期</string>
|
||||
<string name="mangadex_sync_follows_to_library_summary">まだ追加されていない場合、MangaDexからエントリーをライブラリに取り込みます。</string>
|
||||
<string name="mangadex_preffered_source">優先するMangaDexソース</string>
|
||||
<string name="mangadex_preffered_source_summary">選択したMangaDexソースを設定します。これはアプリの周りに多くの機能を追加するために使用されます。</string>
|
||||
<string name="mangadex_add_to_follows">フォローしているMangaDexに追加</string>
|
||||
<string name="mangadex_follows">MangaDexをフォローする</string>
|
||||
<string name="random">ランダム</string>
|
||||
<string name="mangadex_push_favorites_to_mangadex">ライブラリエントリをMangaDexに同期</string>
|
||||
<string name="mangadex_push_favorites_to_mangadex_summary">MdList以外の項目をMangaDexに同期します。</string>
|
||||
<string name="mangadex_similar">MangaDexに類義</string>
|
||||
<string name="community_recommendations">コミュニティのおすすめ</string>
|
||||
<!-- Scanlator filters -->
|
||||
<string name="select_scanlators">スキャン対象のグループを表示</string>
|
||||
<!-- Similar -->
|
||||
<string name="similar">%1$s と類義</string>
|
||||
<!-- MangaDex relations-->
|
||||
<string name="relation_similar">類似</string>
|
||||
<string name="relation_monochrome">モノクロ</string>
|
||||
<string name="relation_main_story">メインストーリー</string>
|
||||
<string name="relation_adapted_from">Adapted from</string>
|
||||
<string name="relation_based_on">Based on</string>
|
||||
<string name="relation_prequel">Prequel</string>
|
||||
<string name="relation_side_story">Side story</string>
|
||||
<string name="relation_doujinshi">Doujinshi</string>
|
||||
<string name="relation_same_franchise">Same franchise</string>
|
||||
<string name="relation_shared_universe">Shared universe</string>
|
||||
<string name="relation_sequel">Sequel</string>
|
||||
<string name="relation_spin_off">Spin-off</string>
|
||||
<string name="relation_alternate_story">Alternate story</string>
|
||||
<string name="relation_preserialization">Pre-serialization</string>
|
||||
<string name="relation_colored">Colored</string>
|
||||
<string name="relation_serialization">Serialization</string>
|
||||
<string name="relation_alternate_version">他のバージョン</string>
|
||||
<!-- Stats page -->
|
||||
<string name="include_all_read_entries">すべての既読作品を含める</string>
|
||||
<string name="ignore_non_library_entries">ライブラリ以外の作品を無視</string>
|
||||
<!-- Humanize time -->
|
||||
<string name="humanize_fallback">少し前</string>
|
||||
</resources>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Actions -->
|
||||
<string name="action_skip_entry">Не переносить</string>
|
||||
<string name="action_search_manually">Искать вручную</string>
|
||||
@@ -9,24 +8,20 @@
|
||||
<string name="action_clean_titles">Очистить названия</string>
|
||||
<string name="action_start_reading">Начать чтение</string>
|
||||
<string name="action_edit_info">Редактировать сведенья</string>
|
||||
|
||||
<!-- Entry Type -->
|
||||
<string name="entry_type_manga">Манга</string>
|
||||
<string name="entry_type_manhwa">Манхва</string>
|
||||
<string name="entry_type_manhua">Маньхуа</string>
|
||||
<string name="entry_type_comic">Комикс</string>
|
||||
<string name="entry_type_webtoon">Веб-комикс</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<!-- Subsections -->
|
||||
<string name="pref_category_all_sources">Все источники</string>
|
||||
<string name="pref_category_fork">Настройки Fork\'а</string>
|
||||
<string name="pref_ehentai_summary">Вход в E/ExHentai, синхронизация галерей</string>
|
||||
<string name="pref_mangadex_summary">Вход в MangaDex, синхронизация отслеживаемого</string>
|
||||
|
||||
<!-- About -->
|
||||
<string name="changelog_version">Версия %1$s</string>
|
||||
|
||||
<!-- EH Settings -->
|
||||
<string name="ehentai_prefs_account_settings">Настройки учетной записи (E-Hentai)</string>
|
||||
<string name="enable_exhentai">Включить ExHentai</string>
|
||||
@@ -91,7 +86,6 @@
|
||||
<string name="gallery_updater_stats_text">Последний раз программа обновления была запущена %1$s и проверила %2$d из %3$d галерей, которые были готовы к проверке.</string>
|
||||
<string name="gallery_updater_not_ran_yet">Программа обновления ещё не запущена.</string>
|
||||
<string name="gallery_updater_stats_time">Такое количество галерей было проверено за:\n- час: %1$d\n- 6 часов: %2$d\n- 12 часов: %3$d\n- день: %4$d\n- 2 дня: %5$d\n- неделю: %6$d\n- месяц: %7$d\n- год: %8$d</string>
|
||||
|
||||
<!-- EH Settings Upload Dialogs -->
|
||||
<string name="settings_profile_note">Примечание профиля настроек</string>
|
||||
<string name="settings_profile_note_message">Приложение добавит новый профиль настроек на E/ExHentai для оптимизации производительности приложения. Убедитесь, что на обоих сайтах не больше трёх профилей.\n\nНажать кнопку «ОК» если вы понятие не имеете, что такое профили настроек.</string>
|
||||
@@ -101,14 +95,12 @@
|
||||
<string name="eh_settings_uploading_to_server">Загрузка настроек на сервер</string>
|
||||
<string name="eh_settings_uploading_to_server_message">Пожалуйста, подождите, это может занять некоторое время…</string>
|
||||
<string name="eh_settings_out_of_slots_error">Не осталось слотов для профилей на %1$s. Пожалуйста, удалите хотя-бы один профиль!</string>
|
||||
|
||||
<!-- EH Settings Login Activity -->
|
||||
<string name="recheck_login_status">Перепроверить статус авторизации</string>
|
||||
<string name="alternative_login_page">Альтернативная страница для авторизации</string>
|
||||
<string name="skip_page_restyling">Прекратить перерисовывать страницу</string>
|
||||
<string name="custom_igneous_cookie">Пользовательское Igneous Cookie</string>
|
||||
<string name="custom_igneous_cookie_message">Некоторые пользователи не могут получить доступ к ExHentai обычным способом и должны передать определенное значение Igneous Cookie. Эта опция предназначена как раз для таких пользователей.</string>
|
||||
|
||||
<!-- Advanced Settings -->
|
||||
<string name="developer_tools">Инструменты разработчика</string>
|
||||
<string name="toggle_hentai_features">Включить встроенные функции для хентая</string>
|
||||
@@ -145,7 +137,6 @@
|
||||
<string name="bandwidth_data_saver_server">Прокси-сервер Bandwidth Hero</string>
|
||||
<string name="data_saver_server_summary">Поместите в эту область URL-адрес прокси-сервера Bandwidth Hero</string>
|
||||
<string name="clear_db_exclude_read">Оставлять серии с прочитанными главами</string>
|
||||
|
||||
<!-- Log Level -->
|
||||
<string name="log_minimal">Минимально</string>
|
||||
<string name="log_extra">Дополнительно</string>
|
||||
@@ -153,7 +144,6 @@
|
||||
<string name="log_minimal_desc">Только критические ошибки</string>
|
||||
<string name="log_extra_desc">Регистрировать всё</string>
|
||||
<string name="log_extreme_desc">Режим проверки сети</string>
|
||||
|
||||
<!-- General Settings -->
|
||||
<string name="toggle_expand_search_filters">Развернуть все поисковые фильтры</string>
|
||||
<string name="put_recommends_in_overflow">Рекомендации в выпадающем меню</string>
|
||||
@@ -161,13 +151,11 @@
|
||||
<string name="put_merge_in_overflow">Объединение в выпадающем меню</string>
|
||||
<string name="put_merge_in_overflow_summary">Поместить кнопку «Объединение» в выпадающее меню вместо размещения на сведеньях серии</string>
|
||||
<string name="pref_previews_row_count">Размер сетки для предосмотра</string>
|
||||
|
||||
<!-- Appearance Settings -->
|
||||
<string name="pref_category_navbar">Панель навигации</string>
|
||||
<string name="pref_hide_updates_button">Вкладка «Обновления» на панели навигации</string>
|
||||
<string name="pref_hide_history_button">Вкладка «История» на панели навигации</string>
|
||||
<string name="pref_show_bottom_bar_labels">Названия вкладок на панели навигации</string>
|
||||
|
||||
<!-- Library settings -->
|
||||
<string name="pref_sorting_settings">Настройки сортировки</string>
|
||||
<string name="pref_skip_pre_migration_summary">Использовать последние сохранённые предпереносные настройки и источники для массового переноса</string>
|
||||
@@ -182,7 +170,6 @@
|
||||
<string name="update_30min">Каждые 30 минут</string>
|
||||
<string name="update_1hour">Каждый час</string>
|
||||
<string name="update_3hour">Каждые 3 часа</string>
|
||||
|
||||
<!-- Browse settings -->
|
||||
<string name="pref_hide_feed">Скрыть вкладку «Лента»</string>
|
||||
<string name="pref_feed_position">Позиция вкладки (Лента)</string>
|
||||
@@ -193,13 +180,11 @@
|
||||
<string name="pref_source_navigation_summery">Убирает кнопку «Последняя» возле источников. Взамен при нажатии на источник отображаются вкладки «Последняя» и «Поисковик»</string>
|
||||
<string name="pref_local_source_hidden_folders">Просмотр скрытых папок</string>
|
||||
<string name="pref_local_source_hidden_folders_summery">Дать разрешение локальному источнику просматривать скрытые папки</string>
|
||||
|
||||
<!-- Backup settings -->
|
||||
<string name="custom_entry_info">Сведенья пользователя</string>
|
||||
<string name="all_read_entries">Прочитанные серии</string>
|
||||
<string name="label_sync">Синхронизировать</string>
|
||||
<string name="label_triggers">Триггеры</string>
|
||||
|
||||
<!-- Sync settings -->
|
||||
<string name="sync_error">Не удалось синхронизировать библиотеку</string>
|
||||
<string name="sync_complete">Синхронизация библиотеки завершена</string>
|
||||
@@ -238,7 +223,6 @@
|
||||
<string name="sync_on_app_start">Синхронизовать при запуске приложения</string>
|
||||
<string name="sync_on_app_resume">Синхронизовать при возвращении в приложение</string>
|
||||
<string name="sync_library">Синхронизировать библиотеку</string>
|
||||
|
||||
<!-- Security settings -->
|
||||
<string name="biometric_lock_times">Биометрическое время блокировки</string>
|
||||
<string name="action_edit_biometric_lock_times">Изменить биометрическое время блокировки</string>
|
||||
@@ -270,7 +254,6 @@
|
||||
<string name="wrong_cbz_archive_password">Неверный пароль архива CBZ</string>
|
||||
<string name="encryption_type">Тип шифрования</string>
|
||||
<string name="standard_zip_encryption">Обычное ZIP шифрование (быстрое, но небезопасное)</string>
|
||||
|
||||
<!-- Reader Settings -->
|
||||
<string name="page_downloading">Загрузка страниц</string>
|
||||
<string name="download_threads">Потоки загрузки</string>
|
||||
@@ -306,7 +289,6 @@
|
||||
<string name="pref_force_horz_seekbar">Принудительная горизонтальная полоса прокрутки</string>
|
||||
<string name="pref_force_horz_seekbar_summary">Полностью убирает вертикальную полосу прокрутки в пользу горизонтальной</string>
|
||||
<string name="pref_smooth_scroll">Плавная автопрокрутка</string>
|
||||
|
||||
<!-- Reader -->
|
||||
<!-- Reader Actions -->
|
||||
<string name="eh_autoscroll">Автопрокрутка</string>
|
||||
@@ -336,13 +318,10 @@
|
||||
<string name="action_share_second_page">Отправить вторую страницу</string>
|
||||
<string name="action_save_combined_page">Сохранить объединённые страницы</string>
|
||||
<string name="action_share_combined_page">Отправить объединённые страницы</string>
|
||||
|
||||
<!-- Reader Sharing -->
|
||||
<string name="share_pages_info">%1$s: %2$s, страницы %3$s</string>
|
||||
|
||||
<!-- Auto Webtoon Mode -->
|
||||
<string name="eh_auto_webtoon_snack">Режим чтения (Веб-комикс)</string>
|
||||
|
||||
<!-- Double page spread -->
|
||||
<string name="page_layout">Схема страницы</string>
|
||||
<string name="shift_double_pages">Сдвинуть двойные страницы</string>
|
||||
@@ -351,7 +330,6 @@
|
||||
<string name="automatic_orientation">Автоматически (На основе ориентации)</string>
|
||||
<string name="automatic_can_still_switch">При использовании автоматической схемы страниц вы всё ещё можете переключиться между схемами, когда читаете без переопределения этой настройки</string>
|
||||
<string name="invert_double_pages">Двойные страницы наоборот</string>
|
||||
|
||||
<!-- Center margin -->
|
||||
<string name="center_margin">Отступ по центру</string>
|
||||
<string name="center_margin_none">Нет</string>
|
||||
@@ -360,14 +338,12 @@
|
||||
<string name="center_margin_double_and_wide_page">Оба варианта</string>
|
||||
<string name="pref_center_margin">Отступ по центру</string>
|
||||
<string name="pref_center_margin_summary">Вставить проставку для устранения зазоров на складных устройствах.</string>
|
||||
|
||||
<!-- Archive reader mode -->
|
||||
<string name="archive_mode_load_from_file">Загрузить из файла</string>
|
||||
<string name="archive_mode_load_into_memory">Загрузить в память</string>
|
||||
<string name="archive_mode_cache_to_disk">Копировать на диск</string>
|
||||
<string name="pref_archive_reader_mode">Режим чтения для архивов</string>
|
||||
<string name="pref_archive_reader_mode_summary">Способ, благодаря которому, изображения из архивов, таких как CBZ или CBR, будут загружены</string>
|
||||
|
||||
<!-- Entry Page -->
|
||||
<!-- Entry Info -->
|
||||
<string name="az_recommends">Рекомендации</string>
|
||||
@@ -378,7 +354,6 @@
|
||||
<string name="merge_unknown_entry">Неизвестный ID серии: %1$d</string>
|
||||
<string name="merged_already">Эта серия уже объеденена с текущей серией!</string>
|
||||
<string name="merge_duplicate">Эта объеденённая серия является дубликатом!</string>
|
||||
|
||||
<!-- Entry Info Edit -->
|
||||
<string name="reset_tags">Сбросить тэги</string>
|
||||
<string name="add_tag">Добавить тэг</string>
|
||||
@@ -388,18 +363,15 @@
|
||||
<string name="author_hint">Автор: %1$s</string>
|
||||
<string name="artist_hint">Художник: %1$s</string>
|
||||
<string name="thumbnail_url_hint">URL-адрес миниатюры: %1$s</string>
|
||||
|
||||
<!-- Browse -->
|
||||
<!-- Sources Tab -->
|
||||
<string name="find_in_another_source">Найти в других источниках</string>
|
||||
<string name="data_saver_exclude">Исключение из экономии данных</string>
|
||||
<string name="data_saver_stop_exclude">Прекратить исключение из экономии данных</string>
|
||||
|
||||
<!-- Smart Search -->
|
||||
<string name="searching_source">Поиск в источнике…</string>
|
||||
<string name="could_not_find_entry">Не удалось найти серию!</string>
|
||||
<string name="automatic_search_error">Ошибка при выполнении автоматического поиска!</string>
|
||||
|
||||
<!-- Saved Searches -->
|
||||
<string name="saved_searches">Сохраненные запросы</string>
|
||||
<string name="save_search">Сохранить текущий поисковой запрос?</string>
|
||||
@@ -410,18 +382,15 @@
|
||||
<string name="save_search_delete_message">Вы уверены, что хотите удалить сохраненный поисковый запрос: %1$s?</string>
|
||||
<string name="save_search_invalid">Сохраненный поисковый запрос недействителен. Фильтры были изменены</string>
|
||||
<string name="save_search_invalid_name">Недопустимое имя поискового запроса</string>
|
||||
|
||||
<!-- Source Categories -->
|
||||
<string name="no_source_categories">Отсутствуют категории для источников</string>
|
||||
<string name="invalid_category_name">Недопустимое имя категории!</string>
|
||||
|
||||
<!-- Feed Tab -->
|
||||
<string name="feed">Лента</string>
|
||||
<string name="feed_delete">Удалить элемент из ленты?</string>
|
||||
<string name="too_many_in_feed">Слишком большое количество источников в вашей ленте. Количество не должно превышать 10</string>
|
||||
<string name="feed_tab_empty">Ваша лента не имеет отслеживаемых источников. Чтобы добавить источник нажмите «+»</string>
|
||||
<string name="feed_add">Добавить %1$s в ленту?</string>
|
||||
|
||||
<!-- Sort by tags -->
|
||||
<string name="pref_tag_sorting">Сортировка тэгов</string>
|
||||
<string name="tag_sorting">Сортировка тэгов</string>
|
||||
@@ -431,11 +400,9 @@
|
||||
<string name="error_tag_exists">Этот тэг уже существует!</string>
|
||||
<string name="delete_tag">Удалить тэг</string>
|
||||
<string name="delete_tag_confirmation">Хотите ли вы удалить тэг %s?</string>
|
||||
|
||||
<!-- Extension section -->
|
||||
<string name="ext_redundant">Избыточное</string>
|
||||
<string name="redundant_extension_message">Это расширение является избыточным и не будет использоваться внутри этой версии Tachiyomi.</string>
|
||||
|
||||
<!-- Migration -->
|
||||
<string name="select_sources">Выберите источники</string>
|
||||
<string name="select_none">Ничего не выбрано</string>
|
||||
@@ -459,19 +426,15 @@
|
||||
<string name="stop_migrating">Остановить перенос?</string>
|
||||
<string name="action_stop">Остановить</string>
|
||||
<string name="skipping_">(Исключая %1$d)</string>
|
||||
|
||||
<!-- Library -->
|
||||
<!-- Library Actions -->
|
||||
<string name="no_valid_entry">Выбрана недопустимая серия</string>
|
||||
|
||||
<!-- Library Sheet -->
|
||||
<string name="lewd">Для взрослых</string>
|
||||
|
||||
<!-- Library Grouping -->
|
||||
<string name="tracking_status">Статус отслеживания</string>
|
||||
<string name="ungrouped">Не группировать</string>
|
||||
<string name="not_tracked">Не отслеживается</string>
|
||||
|
||||
<!-- Favorites Sync -->
|
||||
<string name="sync_favorites">Синхронизация избранного</string>
|
||||
<string name="favorites_sync_error">Ошибка синхронизации избранного</string>
|
||||
@@ -515,7 +478,6 @@
|
||||
<string name="favorites_sync_reset">Вы уверены?</string>
|
||||
<string name="favorites_sync_reset_message">Сброс состояния синхронизации может привести к тому, что следующая синхронизация будет чрезвычайно медленной.</string>
|
||||
<string name="favorites_sync_conformation_message">Вы уверены, что хотите синхронизировать ваше избранное с E-Hentai?</string>
|
||||
|
||||
<!-- Gallery Adder -->
|
||||
<!-- Batch Add -->
|
||||
<string name="eh_batch_add">Добавить галереи</string>
|
||||
@@ -542,19 +504,16 @@
|
||||
<string name="gallery_adder_chapter_fetch_error">Не удалось обновить главы для галереи: %1$s!</string>
|
||||
<string name="gallery_adder_could_not_add_gallery">Не удалось добавить галерею (URL-адрес: %1$s)!</string>
|
||||
<string name="gallery_adder_could_not_identify_chapter">Не удалось идентифицировать главу (URL-адрес: %1$s)!</string>
|
||||
|
||||
<!-- Intercept Activity -->
|
||||
<string name="launching_app">Запуск приложения…</string>
|
||||
<string name="error_with_reason">Ошибка: %1$s</string>
|
||||
<string name="could_not_open_entry">Не удалось открыть эту серию:\n\n%1$s</string>
|
||||
<string name="loading_entry">Загрузка серии…</string>
|
||||
|
||||
<!-- Page previews -->
|
||||
<string name="page_previews">Предосмотр страниц</string>
|
||||
<string name="more_previews">Просмотреть ещё</string>
|
||||
<string name="pref_clear_page_preview_cache">Очистить кэш предосмотренных страниц</string>
|
||||
<string name="page_preview_page_go_to">Перейти к</string>
|
||||
|
||||
<!-- Rating 0-10 (0, 0.5, 1, 1.5 and so fourth) -->
|
||||
<string name="rating10">Шедевр</string>
|
||||
<string name="rating9">Удивительно</string>
|
||||
@@ -568,7 +527,6 @@
|
||||
<string name="rating1">Невыносимо</string>
|
||||
<string name="rating0">Катастрофа</string>
|
||||
<string name="no_rating">Без рейтинга</string>
|
||||
|
||||
<!-- Gallery types -->
|
||||
<string name="doujinshi">Додзинси</string>
|
||||
<string name="artist_cg">Худож. графика</string>
|
||||
@@ -581,7 +539,6 @@
|
||||
<string name="misc">Разное</string>
|
||||
<string name="artbook">Артбук</string>
|
||||
<string name="video">Видео</string>
|
||||
|
||||
<!-- More Info Menu -->
|
||||
<string name="more_info">Информация</string>
|
||||
<string name="alt_title">Альт. название</string>
|
||||
@@ -626,11 +583,9 @@
|
||||
<string name="manga_updates_id">MangaUpdates ID</string>
|
||||
<string name="anime_planet_id">Anime-Planet ID</string>
|
||||
<string name="translated">Переведено</string>
|
||||
|
||||
<!-- Extra gallery info -->
|
||||
<string name="is_visible">Не скрыто: %1$s</string>
|
||||
<string name="language_translated">%1$s</string>
|
||||
|
||||
<!-- Merged entry -->
|
||||
<string name="merge_settings">Настройки объединения</string>
|
||||
<string name="fetch_chapter_updates">Получить обновления глав</string>
|
||||
@@ -650,7 +605,6 @@
|
||||
<string name="dedupe_priority">Дедупликация по приоритету</string>
|
||||
<string name="dedupe_most_chapters">Показать источник с наибольшим количеством глав</string>
|
||||
<string name="dedupe_highest_chapter">Показать источник с наивысшим номером главы</string>
|
||||
|
||||
<!-- MangaDex -->
|
||||
<string name="md_follows_unfollowed">Без отслеживания</string>
|
||||
<string name="mangadex_sync_follows_to_library">Синхронизировать серии (MangaDex)</string>
|
||||
@@ -664,13 +618,10 @@
|
||||
<string name="mangadex_push_favorites_to_mangadex_summary">Синхронизирует любую не отслеживаемую MDList серию как прочитанную на MangaDex</string>
|
||||
<string name="mangadex_similar">MangaDex похожее</string>
|
||||
<string name="community_recommendations">Рекомендации сообщества</string>
|
||||
|
||||
<!-- Scanlator filters -->
|
||||
<string name="select_scanlators">Группы переводчиков</string>
|
||||
|
||||
<!-- Similar -->
|
||||
<string name="similar">Похожее на %1$s</string>
|
||||
|
||||
<!-- MangaDex relations-->
|
||||
<string name="relation_similar">Похожее</string>
|
||||
<string name="relation_monochrome">Монохром</string>
|
||||
@@ -689,11 +640,13 @@
|
||||
<string name="relation_colored">Цветное</string>
|
||||
<string name="relation_serialization">Сериализация</string>
|
||||
<string name="relation_alternate_version">Альт. версия</string>
|
||||
|
||||
<!-- Stats page -->
|
||||
<string name="include_all_read_entries">Включать все прочитанные серии</string>
|
||||
<string name="ignore_non_library_entries">Игнорировать не-библиотечные серии</string>
|
||||
|
||||
<!-- Humanize time -->
|
||||
<string name="humanize_fallback">мгновение назад</string>
|
||||
</resources>
|
||||
<string name="action_copy_first_page">Копировать первую страницу</string>
|
||||
<string name="action_copy_second_page">Копировать вторую страницу</string>
|
||||
<string name="only_show_updated_entries">Показывать серии только с новыми главами</string>
|
||||
<string name="action_copy_combined_page">Копировать объединенную страницу</string>
|
||||
</resources>
|
||||
@@ -654,4 +654,8 @@
|
||||
<string name="mal_id">Mal id</string>
|
||||
<string name="batch_add_error">[錯誤]</string>
|
||||
<string name="batch_add_ok">[確認]</string>
|
||||
<string name="action_copy_first_page">複製第一頁</string>
|
||||
<string name="action_copy_second_page">複製第二頁</string>
|
||||
<string name="action_copy_combined_page">複製合併頁</string>
|
||||
<string name="only_show_updated_entries">僅顯示包含新章節的條目</string>
|
||||
</resources>
|
||||
@@ -793,7 +793,6 @@
|
||||
<string name="transition_pages_error">Failed to load pages: %1$s</string>
|
||||
<string name="page_list_empty_error">No pages found</string>
|
||||
<string name="loader_not_implemented_error">Source not found</string>
|
||||
<string name="loader_rar5_error">RARv5 format is not supported</string>
|
||||
|
||||
<!-- Updates -->
|
||||
<string name="updating_library">Updating library</string>
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
<resources>
|
||||
<color name="splash">#202125</color>
|
||||
|
||||
<color name="error">#FFB4A9</color>
|
||||
<color name="errorContainer">#930006</color>
|
||||
<color name="onError">#680003</color>
|
||||
<color name="onErrorContainer">#FFDAD4</color>
|
||||
|
||||
<!-- Default Theme -->
|
||||
<color name="divider_default">@color/md_white_1000_12</color>
|
||||
</resources>
|
||||
|
||||
@@ -12,25 +12,38 @@
|
||||
-->
|
||||
<resources>
|
||||
<color name="greenapple_primary">#7ADB8F</color>
|
||||
<color name="greenapple_onPrimary">#003915</color>
|
||||
<color name="greenapple_primaryContainer">#005322</color>
|
||||
<color name="greenapple_onPrimaryContainer">#96F8A9</color>
|
||||
<color name="greenapple_onPrimary">#003917</color>
|
||||
<color name="greenapple_primaryContainer">#017737</color>
|
||||
<color name="greenapple_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="greenapple_secondary">#7ADB8F</color>
|
||||
<color name="greenapple_onSecondary">#003915</color>
|
||||
<color name="greenapple_secondaryContainer">#005322</color>
|
||||
<color name="greenapple_onSecondaryContainer">#96F8A9</color>
|
||||
<color name="greenapple_tertiary">#FFB3AA</color>
|
||||
<color name="greenapple_onTertiary">#680006</color>
|
||||
<color name="greenapple_tertiaryContainer">#93000D</color>
|
||||
<color name="greenapple_onTertiaryContainer">#FFDAD5</color>
|
||||
<color name="greenapple_background">#1A1C19</color>
|
||||
<color name="greenapple_onBackground">#E1E3DD</color>
|
||||
<color name="greenapple_surface">#1A1C19</color>
|
||||
<color name="greenapple_onSurface">#E1E3DD</color>
|
||||
<color name="greenapple_surfaceVariant">#414941</color>
|
||||
<color name="greenapple_onSurfaceVariant">#C1C8BE</color>
|
||||
<color name="greenapple_outline">#8B9389</color>
|
||||
<color name="greenapple_inverseOnSurface">#1A1C19</color>
|
||||
<color name="greenapple_inverseSurface">#E1E3DD</color>
|
||||
<color name="greenapple_primaryInverse">#006D2F</color>
|
||||
<color name="greenapple_onSecondary">#003917</color>
|
||||
<color name="greenapple_secondaryContainer">#017737</color>
|
||||
<color name="greenapple_onSecondaryContainer">#FFFFFF</color>
|
||||
<color name="greenapple_tertiary">#FFB3AC</color>
|
||||
<color name="greenapple_onTertiary">#680008</color>
|
||||
<color name="greenapple_tertiaryContainer">#C7282A</color>
|
||||
<color name="greenapple_onTertiaryContainer">#FFFFFF</color>
|
||||
<color name="greenapple_error">#FFB4AB</color>
|
||||
<color name="greenapple_onError">#690005</color>
|
||||
<color name="greenapple_errorContainer">#93000A</color>
|
||||
<color name="greenapple_onErrorContainer">#FFDAD6</color>
|
||||
<color name="greenapple_background">#0F1510</color>
|
||||
<color name="greenapple_onBackground">#DFE4DB</color>
|
||||
<color name="greenapple_surface">#0F1510</color>
|
||||
<color name="greenapple_onSurface">#DFE4DB</color>
|
||||
<color name="greenapple_surfaceVariant">#3F493F</color>
|
||||
<color name="greenapple_onSurfaceVariant">#BECABC</color>
|
||||
<color name="greenapple_outline">#889487</color>
|
||||
<color name="greenapple_outlineVariant">#3F493F</color>
|
||||
<color name="greenapple_scrim">#000000</color>
|
||||
<color name="greenapple_inverseSurface">#DFE4DB</color>
|
||||
<color name="greenapple_inverseOnSurface">#2C322C</color>
|
||||
<color name="greenapple_inversePrimary">#006D32</color>
|
||||
<color name="greenapple_surfaceDim">#0F1510</color>
|
||||
<color name="greenapple_surfaceBright">#353B35</color>
|
||||
<color name="greenapple_surfaceContainerLowest">#0A0F0B</color>
|
||||
<color name="greenapple_surfaceContainerLow">#181D18</color>
|
||||
<color name="greenapple_surfaceContainer">#1C211C</color>
|
||||
<color name="greenapple_surfaceContainerHigh">#262B26</color>
|
||||
<color name="greenapple_surfaceContainerHighest">#313630</color>
|
||||
</resources>
|
||||
|
||||
@@ -12,26 +12,38 @@
|
||||
-->
|
||||
<resources>
|
||||
<color name="lavender_primary">#A177FF</color>
|
||||
<color name="lavender_onPrimary">#111129</color>
|
||||
<color name="lavender_onPrimary">#3D0090</color>
|
||||
<color name="lavender_primaryContainer">#A177FF</color>
|
||||
<color name="lavender_onPrimaryContainer">#111129</color>
|
||||
<color name="lavender_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="lavender_secondary">#A177FF</color>
|
||||
<color name="lavender_onSecondary">#111129</color>
|
||||
<color name="lavender_onSecondary">#FFFFFF</color>
|
||||
<color name="lavender_secondaryContainer">#423271</color>
|
||||
<color name="lavender_onSecondaryContainer">#111129</color>
|
||||
<color name="lavender_tertiary">#5E25E1</color>
|
||||
<color name="lavender_onTertiary">#E8E8E8</color>
|
||||
<color name="lavender_tertiaryContainer">#111129</color>
|
||||
<color name="lavender_onTertiaryContainer">#DEE8FF</color>
|
||||
<color name="lavender_onSecondaryContainer">#A177FF</color>
|
||||
<color name="lavender_tertiary">#CDBDFF</color>
|
||||
<color name="lavender_onTertiary">#360096</color>
|
||||
<color name="lavender_tertiaryContainer">#5512D8</color>
|
||||
<color name="lavender_onTertiaryContainer">#EFE6FF</color>
|
||||
<color name="lavender_error">#FFB4AB</color>
|
||||
<color name="lavender_onError">#690005</color>
|
||||
<color name="lavender_errorContainer">#93000A</color>
|
||||
<color name="lavender_onErrorContainer">#FFDAD6</color>
|
||||
<color name="lavender_background">#111129</color>
|
||||
<color name="lavender_onBackground">#DEE8FF</color>
|
||||
<color name="lavender_onBackground">#E7E0EC</color>
|
||||
<color name="lavender_surface">#111129</color>
|
||||
<color name="lavender_onSurface">#DEE8FF</color>
|
||||
<color name="lavender_surfaceVariant">#2CB6B6B6</color>
|
||||
<color name="lavender_onSurfaceVariant">#E8E8E8</color>
|
||||
<color name="lavender_outline">#A8905FFF</color>
|
||||
<color name="lavender_inverseOnSurface">#DEE8FF</color>
|
||||
<color name="lavender_inverseSurface">#221247</color>
|
||||
<color name="lavender_primaryInverse">#A177FF</color>
|
||||
<color name="lavender_elevationOverlay">@color/lavender_primary</color>
|
||||
<color name="lavender_onSurface">#E7E0EC</color>
|
||||
<color name="lavender_surfaceVariant">#3D2F6B</color>
|
||||
<color name="lavender_onSurfaceVariant">#CBC3D6</color>
|
||||
<color name="lavender_outline">#958E9F</color>
|
||||
<color name="lavender_outlineVariant">#4A4453</color>
|
||||
<color name="lavender_scrim">#000000</color>
|
||||
<color name="lavender_inverseSurface">#E7E0EC</color>
|
||||
<color name="lavender_inverseOnSurface">#322F38</color>
|
||||
<color name="lavender_inversePrimary">#6D41C8</color>
|
||||
<color name="lavender_surfaceDim">#111129</color>
|
||||
<color name="lavender_surfaceBright">#3B3841</color>
|
||||
<color name="lavender_surfaceContainerLowest">#15132d</color>
|
||||
<color name="lavender_surfaceContainerLow">#171531</color>
|
||||
<color name="lavender_surfaceContainer">#1D193B</color>
|
||||
<color name="lavender_surfaceContainerHigh">#241f41</color>
|
||||
<color name="lavender_surfaceContainerHighest">#282446</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,23 +15,28 @@
|
||||
<color name="midnightdusk_onPrimary">#FFFFFF</color>
|
||||
<color name="midnightdusk_primaryContainer">#BD1C5C</color>
|
||||
<color name="midnightdusk_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="midnightdusk_inversePrimary">#F02475</color>
|
||||
<color name="midnightdusk_secondary">#F02475</color>
|
||||
<color name="midnightdusk_onSecondary">#FFFFFF</color>
|
||||
<color name="midnightdusk_onSecondary">#16151D</color>
|
||||
<color name="midnightdusk_secondaryContainer">#66183C</color>
|
||||
<color name="midnightdusk_onSecondaryContainer">#FFFFFF</color>
|
||||
<color name="midnightdusk_onSecondaryContainer">#F02475</color>
|
||||
<color name="midnightdusk_tertiary">#55971C</color>
|
||||
<color name="midnightdusk_onTertiary">#FFFFFF</color>
|
||||
<color name="midnightdusk_onTertiary">#16151D</color>
|
||||
<color name="midnightdusk_tertiaryContainer">#386412</color>
|
||||
<color name="midnightdusk_onTertiaryContainer">#E5E1E5</color>
|
||||
<color name="midnightdusk_background">#16151D</color>
|
||||
<color name="midnightdusk_onBackground">#E5E1E5</color>
|
||||
<color name="midnightdusk_surface">#16151D</color>
|
||||
<color name="midnightdusk_onSurface">#E5E1E5</color>
|
||||
<color name="midnightdusk_surfaceVariant">#524346</color>
|
||||
<color name="midnightdusk_surfaceVariant">#281624</color>
|
||||
<color name="midnightdusk_onSurfaceVariant">#D6C1C4</color>
|
||||
<color name="midnightdusk_outline">#9F8C8F</color>
|
||||
<color name="midnightdusk_surfaceTint">#F02475</color>
|
||||
<color name="midnightdusk_inverseSurface">#333043</color>
|
||||
<color name="midnightdusk_inverseOnSurface">#FFFFFF</color>
|
||||
<color name="midnightdusk_primaryInverse">#F02475</color>
|
||||
<color name="midnightdusk_elevationOverlay">#2C0013</color>
|
||||
<color name="midnightdusk_outline">#9F8C8F</color>
|
||||
<color name="midnightdusk_surfaceContainerLowest">#221320</color>
|
||||
<color name="midnightdusk_surfaceContainerLow">#251522</color>
|
||||
<color name="midnightdusk_surfaceContainer">#281624</color>
|
||||
<color name="midnightdusk_surfaceContainerHigh">#2D1C2A</color>
|
||||
<color name="midnightdusk_surfaceContainerHighest">#2F1F2C</color>
|
||||
</resources>
|
||||
@@ -5,26 +5,32 @@
|
||||
<color name="nord_onPrimary">#2E3440</color>
|
||||
<color name="nord_primaryContainer">#88C0D0</color>
|
||||
<color name="nord_onPrimaryContainer">#2E3440</color>
|
||||
<color name="nord_inversePrimary">#397E91</color>
|
||||
<color name="nord_secondary">#81A1C1</color>
|
||||
<color name="nord_onSecondary">#2E3440</color>
|
||||
<color name="nord_secondaryContainer">#506275</color>
|
||||
<color name="nord_onSecondaryContainer">#2E3440</color>
|
||||
<color name="nord_onSecondaryContainer">#88C0D0</color>
|
||||
<color name="nord_tertiary">#5E81AC</color>
|
||||
<color name="nord_onTertiary">#000000</color>
|
||||
<color name="nord_tertiaryContainer">#5E81AC</color>
|
||||
<color name="nord_onTertiaryContainer">#000000</color>
|
||||
<color name="nord_background">#2E3440</color>
|
||||
<color name="nord_onBackground">#ECEFF4</color>
|
||||
<color name="nord_surface">#3B4252</color>
|
||||
<color name="nord_surface">#2E3440</color>
|
||||
<color name="nord_onSurface">#ECEFF4</color>
|
||||
<color name="nord_surfaceVariant">#2E3440</color>
|
||||
<color name="nord_surfaceVariant">#414C5C</color>
|
||||
<color name="nord_onSurfaceVariant">#ECEFF4</color>
|
||||
<color name="nord_outline">#D8DEE9</color>
|
||||
<color name="nord_inverseOnSurface">#2E3440</color>
|
||||
<color name="nord_surfaceTint">#88C0D0</color>
|
||||
<color name="nord_inverseSurface">#D8DEE9</color>
|
||||
<color name="nord_primaryInverse">#397E91</color>
|
||||
<color name="nord_elevationOverlay">#434C5E</color>
|
||||
<color name="nord_inverseOnSurface">#2E3440</color>
|
||||
<color name="nord_outline">#6d717b</color>
|
||||
<color name="nord_outlineVariant">#90939a</color>
|
||||
<color name="nord_onError">#2E3440</color>
|
||||
<color name="nord_errorContainer">#BF616A</color>
|
||||
<color name="nord_onErrorContainer">#000000</color>
|
||||
<color name="nord_surfaceContainerLowest">#373F4D</color>
|
||||
<color name="nord_surfaceContainerLow">#3E4756</color>
|
||||
<color name="nord_surfaceContainer">#414C5C</color>
|
||||
<color name="nord_surfaceContainerHigh">#4E5766</color>
|
||||
<color name="nord_surfaceContainerHighest">#505968</color>
|
||||
</resources>
|
||||
|
||||
@@ -11,26 +11,39 @@
|
||||
~ Neutral #655C5C
|
||||
-->
|
||||
<resources>
|
||||
<color name="strawberry_primary">#FFB2B9</color>
|
||||
<color name="strawberry_onPrimary">#67001B</color>
|
||||
<color name="strawberry_primaryContainer">#91002A</color>
|
||||
<color name="strawberry_onPrimaryContainer">#FFDADD</color>
|
||||
<color name="strawberry_secondary">#FFB2B9</color>
|
||||
<color name="strawberry_onSecondary">#67001B</color>
|
||||
<color name="strawberry_primary">#FFB2B8</color>
|
||||
<color name="strawberry_onPrimary">#67001D</color>
|
||||
<color name="strawberry_primaryContainer">#D53855</color>
|
||||
<color name="strawberry_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="strawberry_secondary">#ED4A65</color>
|
||||
<color name="strawberry_onSecondary">#201A1A</color>
|
||||
<color name="strawberry_secondaryContainer">#91002A</color>
|
||||
<color name="strawberry_onSecondaryContainer">#FFDADD</color>
|
||||
<color name="strawberry_onSecondaryContainer">#FFFFFF</color>
|
||||
<color name="strawberry_tertiary">#E8C08E</color>
|
||||
<color name="strawberry_onTertiary">#432C06</color>
|
||||
<color name="strawberry_tertiaryContainer">#5D421B</color>
|
||||
<color name="strawberry_onTertiaryContainer">#FFDDB1</color>
|
||||
<color name="strawberry_onTertiary">#201A1A</color>
|
||||
<color name="strawberry_tertiaryContainer">#775930</color>
|
||||
<color name="strawberry_onTertiaryContainer">#FFF7F1</color>
|
||||
<color name="strawberry_error">#FFB4AB</color>
|
||||
<color name="strawberry_onError">#690005</color>
|
||||
<color name="strawberry_errorContainer">#93000A</color>
|
||||
<color name="strawberry_onErrorContainer">#FFDAD6</color>
|
||||
<color name="strawberry_background">#201A1A</color>
|
||||
<color name="strawberry_onBackground">#ECDFDF</color>
|
||||
<color name="strawberry_onBackground">#F7DCDD</color>
|
||||
<color name="strawberry_surface">#201A1A</color>
|
||||
<color name="strawberry_onSurface">#ECDFDF</color>
|
||||
<color name="strawberry_surfaceVariant">#534344</color>
|
||||
<color name="strawberry_onSurfaceVariant">#D7C1C2</color>
|
||||
<color name="strawberry_outline">#A08C8D</color>
|
||||
<color name="strawberry_inverseOnSurface">#201A1A</color>
|
||||
<color name="strawberry_inverseSurface">#ECDFDF</color>
|
||||
<color name="strawberry_primaryInverse">#B61E40</color>
|
||||
<color name="strawberry_onSurface">#F7DCDD</color>
|
||||
<color name="strawberry_surfaceVariant">#322727</color>
|
||||
<color name="strawberry_onSurfaceVariant">#E1BEC0</color>
|
||||
<color name="strawberry_outline">#A9898B</color>
|
||||
<color name="strawberry_outlineVariant">#594042</color>
|
||||
<color name="strawberry_scrim">#000000</color>
|
||||
<color name="strawberry_inverseSurface">#F7DCDD</color>
|
||||
<color name="strawberry_inverseOnSurface">#3D2C2D</color>
|
||||
<color name="strawberry_inversePrimary">#B61F40</color>
|
||||
<color name="strawberry_surfaceDim">#1D1011</color>
|
||||
<color name="strawberry_surfaceBright">#463536</color>
|
||||
<color name="strawberry_surfaceContainerLowest">#2C2222</color>
|
||||
<color name="strawberry_surfaceContainerLow">#302525</color>
|
||||
<color name="strawberry_surfaceContainer">#322727</color>
|
||||
<color name="strawberry_surfaceContainerHigh">#3C2F2F</color>
|
||||
<color name="strawberry_surfaceContainerHighest">#463737</color>
|
||||
</resources>
|
||||
|
||||
@@ -10,26 +10,37 @@
|
||||
~ Neutral #5E5E62
|
||||
-->
|
||||
<resources>
|
||||
<color name="tachiyomi_primary">#AEC6FF</color>
|
||||
<color name="tachiyomi_onPrimary">#002C71</color>
|
||||
<color name="tachiyomi_primaryContainer">#00419E</color>
|
||||
<color name="tachiyomi_onPrimaryContainer">#D8E2FF</color>
|
||||
<color name="tachiyomi_secondary">#AEC6FF</color>
|
||||
<color name="tachiyomi_onSecondary">#002C71</color>
|
||||
<color name="tachiyomi_secondaryContainer">#00419E</color>
|
||||
<color name="tachiyomi_onSecondaryContainer">#D8E2FF</color>
|
||||
<color name="tachiyomi_primary">#B0C6FF</color>
|
||||
<color name="tachiyomi_onPrimary">#002D6E</color>
|
||||
<color name="tachiyomi_primaryContainer">#00429B</color>
|
||||
<color name="tachiyomi_onPrimaryContainer">#D9E2FF</color>
|
||||
<color name="tachiyomi_inversePrimary">#0058CA</color>
|
||||
<color name="tachiyomi_secondary">#B0C6FF</color>
|
||||
<color name="tachiyomi_onSecondary">#002D6E</color>
|
||||
<color name="tachiyomi_secondaryContainer">#00429B</color>
|
||||
<color name="tachiyomi_onSecondaryContainer">#D9E2FF</color>
|
||||
<color name="tachiyomi_tertiary">#7ADC77</color>
|
||||
<color name="tachiyomi_onTertiary">#003907</color>
|
||||
<color name="tachiyomi_tertiaryContainer">#00530D</color>
|
||||
<color name="tachiyomi_onTertiary">#003909</color>
|
||||
<color name="tachiyomi_tertiaryContainer">#005312</color>
|
||||
<color name="tachiyomi_onTertiaryContainer">#95F990</color>
|
||||
<color name="tachiyomi_background">#1B1B1E</color>
|
||||
<color name="tachiyomi_onBackground">#E4E2E6</color>
|
||||
<color name="tachiyomi_surface">#1B1B1E</color>
|
||||
<color name="tachiyomi_onSurface">#E4E2E6</color>
|
||||
<color name="tachiyomi_surfaceVariant">#44464E</color>
|
||||
<color name="tachiyomi_background">#1B1B1F</color>
|
||||
<color name="tachiyomi_onBackground">#E3E2E6</color>
|
||||
<color name="tachiyomi_surface">#1B1B1F</color>
|
||||
<color name="tachiyomi_onSurface">#E3E2E6</color>
|
||||
<color name="tachiyomi_surfaceVariant">#211F26</color>
|
||||
<color name="tachiyomi_onSurfaceVariant">#C5C6D0</color>
|
||||
<color name="tachiyomi_outline">#8E9099</color>
|
||||
<color name="tachiyomi_inverseOnSurface">#1B1B1E</color>
|
||||
<color name="tachiyomi_inverseSurface">#E4E2E6</color>
|
||||
<color name="tachiyomi_primaryInverse">#0057CE</color>
|
||||
<color name="tachiyomi_surfaceTint">#B0C6FF</color>
|
||||
<color name="tachiyomi_inverseSurface">#E3E2E6</color>
|
||||
<color name="tachiyomi_inverseOnSurface">#1B1B1F</color>
|
||||
<color name="tachiyomi_error">#FFB4AB</color>
|
||||
<color name="tachiyomi_onError">#690005</color>
|
||||
<color name="tachiyomi_errorContainer">#93000A</color>
|
||||
<color name="tachiyomi_onErrorContainer">#FFDAD6</color>
|
||||
<color name="tachiyomi_outline">#8F9099</color>
|
||||
<color name="tachiyomi_outlineVariant">#44464F</color>
|
||||
<color name="tachiyomi_surfaceContainerLowest">#1A181D</color>
|
||||
<color name="tachiyomi_surfaceContainerLow">#1E1C22</color>
|
||||
<color name="tachiyomi_surfaceContainer">#211F26</color>
|
||||
<color name="tachiyomi_surfaceContainerHigh">#292730</color>
|
||||
<color name="tachiyomi_surfaceContainerHighest">#302E38</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
<color name="tako_onPrimary">#38294E</color>
|
||||
<color name="tako_primaryContainer">#F3B375</color>
|
||||
<color name="tako_onPrimaryContainer">#38294E</color>
|
||||
<color name="tako_inversePrimary">#84531E</color>
|
||||
<color name="tako_secondary">#F3B375</color>
|
||||
<color name="tako_onSecondary">#5C4D4B</color>
|
||||
<color name="tako_secondaryContainer">#F3B375</color>
|
||||
<color name="tako_onSecondaryContainer">#38294E</color>
|
||||
<color name="tako_onSecondary">#38294E</color>
|
||||
<color name="tako_secondaryContainer">#5C4D4B</color>
|
||||
<color name="tako_onSecondaryContainer">#F3B375</color>
|
||||
<color name="tako_tertiary">#66577E</color>
|
||||
<color name="tako_onTertiary">#F3B375</color>
|
||||
<color name="tako_tertiaryContainer">#4E4065</color>
|
||||
@@ -27,11 +28,15 @@
|
||||
<color name="tako_onBackground">#E3E0F2</color>
|
||||
<color name="tako_surface">#21212E</color>
|
||||
<color name="tako_onSurface">#E3E0F2</color>
|
||||
<color name="tako_surfaceVariant">#49454E</color>
|
||||
<color name="tako_surfaceVariant">#2A2A3C</color>
|
||||
<color name="tako_onSurfaceVariant">#CBC4CE</color>
|
||||
<color name="tako_outline">#958F99</color>
|
||||
<color name="tako_inverseOnSurface">#1B1B1E</color>
|
||||
<color name="tako_surfaceTint">#66577E</color>
|
||||
<color name="tako_inverseSurface">#E5E1E6</color>
|
||||
<color name="tako_primaryInverse">#84531E</color>
|
||||
<color name="tako_elevationOverlay">@color/tako_tertiary</color>
|
||||
<color name="tako_inverseOnSurface">#1B1B1E</color>
|
||||
<color name="tako_outline">#958F99</color>
|
||||
<color name="tako_surfaceContainerLowest">#20202E</color>
|
||||
<color name="tako_surfaceContainerLow">#262636</color>
|
||||
<color name="tako_surfaceContainer">#2A2A3C</color>
|
||||
<color name="tako_surfaceContainerHigh">#303044</color>
|
||||
<color name="tako_surfaceContainerHighest">#36364D</color>
|
||||
</resources>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<color name="tealturquoise_primary">#40E0D0</color>
|
||||
<color name="tealturquoise_onPrimary">#000000</color>
|
||||
<color name="tealturquoise_primaryContainer">#40E0D0</color>
|
||||
<color name="tealturquoise_onPrimaryContainer">#000000</color>
|
||||
<color name="tealturquoise_inversePrimary">#008080</color>
|
||||
<color name="tealturquoise_secondary">#40E0D0</color>
|
||||
<color name="tealturquoise_onSecondary">#000000</color>
|
||||
<color name="tealturquoise_secondaryContainer">#18544E</color>
|
||||
@@ -17,11 +17,15 @@
|
||||
<color name="tealturquoise_onBackground">#DFDEDA</color>
|
||||
<color name="tealturquoise_surface">#202125</color>
|
||||
<color name="tealturquoise_onSurface">#DFDEDA</color>
|
||||
<color name="tealturquoise_surfaceVariant">#3F4947</color>
|
||||
<color name="tealturquoise_surfaceVariant">#233133</color>
|
||||
<color name="tealturquoise_onSurfaceVariant">#DFDEDA</color>
|
||||
<color name="tealturquoise_outline">#899391</color>
|
||||
<color name="tealturquoise_inverseOnSurface">#202125</color>
|
||||
<color name="tealturquoise_surfaceTint">#40E0D0</color>
|
||||
<color name="tealturquoise_inverseSurface">#DFDEDA</color>
|
||||
<color name="tealturquoise_primaryInverse">#008080</color>
|
||||
<color name="tealturquoise_elevationOverlay">#18544E</color>
|
||||
<color name="tealturquoise_inverseOnSurface">#202125</color>
|
||||
<color name="tealturquoise_outline">#899391</color>
|
||||
<color name="tealturquoise_surfaceContainerLowest">#202C2E</color>
|
||||
<color name="tealturquoise_surfaceContainerLow">#222F31</color>
|
||||
<color name="tealturquoise_surfaceContainer">#233133</color>
|
||||
<color name="tealturquoise_surfaceContainerHigh">#28383A</color>
|
||||
<color name="tealturquoise_surfaceContainerHighest">#2F4244</color>
|
||||
</resources>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<color name="tidalwave_onPrimary">#003544</color>
|
||||
<color name="tidalwave_primaryContainer">#004d61</color>
|
||||
<color name="tidalwave_onPrimaryContainer">#b8eaff</color>
|
||||
<color name="tidalwave_inversePrimary">#a12b03</color>
|
||||
<color name="tidalwave_secondary">#5ed4fc</color>
|
||||
<color name="tidalwave_onSecondary">#003544</color>
|
||||
<color name="tidalwave_secondaryContainer">#004d61</color>
|
||||
@@ -26,11 +27,15 @@
|
||||
<color name="tidalwave_onBackground">#d5e3ff</color>
|
||||
<color name="tidalwave_surface">#001c3b</color>
|
||||
<color name="tidalwave_onSurface">#d5e3ff</color>
|
||||
<color name="tidalwave_surfaceVariant">#40484c</color>
|
||||
<color name="tidalwave_surfaceVariant">#082b4b</color>
|
||||
<color name="tidalwave_onSurfaceVariant">#bfc8cc</color>
|
||||
<color name="tidalwave_outline">#8a9296</color>
|
||||
<color name="tidalwave_inverseOnSurface">#001c3b</color>
|
||||
<color name="tidalwave_surfaceTint">#5ed4fc</color>
|
||||
<color name="tidalwave_inverseSurface">#ffe3c4</color>
|
||||
<color name="tidalwave_primaryInverse">#a12b03</color>
|
||||
|
||||
<color name="tidalwave_inverseOnSurface">#001c3b</color>
|
||||
<color name="tidalwave_outline">#8a9296</color>
|
||||
<color name="tidalwave_surfaceContainerLowest">#072642</color>
|
||||
<color name="tidalwave_surfaceContainerLow">#072947</color>
|
||||
<color name="tidalwave_surfaceContainer">#082b4b</color>
|
||||
<color name="tidalwave_surfaceContainerHigh">#093257</color>
|
||||
<color name="tidalwave_surfaceContainerHighest">#0A3861</color>
|
||||
</resources>
|
||||
@@ -9,6 +9,7 @@
|
||||
<color name="yinyang_onPrimary">#5A5A5A</color>
|
||||
<color name="yinyang_primaryContainer">#FFFFFF</color>
|
||||
<color name="yinyang_onPrimaryContainer">#000000</color>
|
||||
<color name="yinyang_inversePrimary">#CECECE</color>
|
||||
<color name="yinyang_secondary">#FFFFFF</color>
|
||||
<color name="yinyang_onSecondary">#5A5A5A</color>
|
||||
<color name="yinyang_secondaryContainer">#717171</color>
|
||||
@@ -21,10 +22,15 @@
|
||||
<color name="yinyang_onBackground">#E6E6E6</color>
|
||||
<color name="yinyang_surface">#1E1E1E</color>
|
||||
<color name="yinyang_onSurface">#E6E6E6</color>
|
||||
<color name="yinyang_surfaceVariant">#4E4E4E</color>
|
||||
<color name="yinyang_surfaceVariant">#313131</color>
|
||||
<color name="yinyang_onSurfaceVariant">#D1D1D1</color>
|
||||
<color name="yinyang_outline">#999999</color>
|
||||
<color name="yinyang_inverseOnSurface">#1E1E1E</color>
|
||||
<color name="yinyang_surfaceTint">#FFFFFF</color>
|
||||
<color name="yinyang_inverseSurface">#E6E6E6</color>
|
||||
<color name="yinyang_primaryInverse">#CECECE</color>
|
||||
<color name="yinyang_inverseOnSurface">#1E1E1E</color>
|
||||
<color name="yinyang_outline">#999999</color>
|
||||
<color name="yinyang_surfaceContainerLowest">#2A2A2A</color>
|
||||
<color name="yinyang_surfaceContainerLow">#2D2D2D</color>
|
||||
<color name="yinyang_surfaceContainer">#313131</color>
|
||||
<color name="yinyang_surfaceContainerHigh">#383838</color>
|
||||
<color name="yinyang_surfaceContainerHighest">#3F3F3F</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<color name="yotsuba_onPrimary">#5F1600</color>
|
||||
<color name="yotsuba_primaryContainer">#862200</color>
|
||||
<color name="yotsuba_onPrimaryContainer">#FFDBCF</color>
|
||||
<color name="yotsuba_inversePrimary">#AE3200</color>
|
||||
<color name="yotsuba_secondary">#FFB59D</color>
|
||||
<color name="yotsuba_onSecondary">#5F1600</color>
|
||||
<color name="yotsuba_secondaryContainer">#862200</color>
|
||||
@@ -27,10 +28,15 @@
|
||||
<color name="yotsuba_onBackground">#EDE0DD</color>
|
||||
<color name="yotsuba_surface">#211A18</color>
|
||||
<color name="yotsuba_onSurface">#EDE0DD</color>
|
||||
<color name="yotsuba_surfaceVariant">#53433F</color>
|
||||
<color name="yotsuba_surfaceVariant">#332723</color>
|
||||
<color name="yotsuba_onSurfaceVariant">#D8C2BC</color>
|
||||
<color name="yotsuba_outline">#A08C87</color>
|
||||
<color name="yotsuba_inverseOnSurface">#211A18</color>
|
||||
<color name="yotsuba_surfaceTint">#FFB59D</color>
|
||||
<color name="yotsuba_inverseSurface">#EDE0DD</color>
|
||||
<color name="yotsuba_primaryInverse">#AE3200</color>
|
||||
<color name="yotsuba_inverseOnSurface">#211A18</color>
|
||||
<color name="yotsuba_outline">#A08C87</color>
|
||||
<color name="yotsuba_surfaceContainerLowest">#2E221F</color>
|
||||
<color name="yotsuba_surfaceContainerLow">#312521</color>
|
||||
<color name="yotsuba_surfaceContainer">#332723</color>
|
||||
<color name="yotsuba_surfaceContainerHigh">#413531</color>
|
||||
<color name="yotsuba_surfaceContainerHighest">#4C403D</color>
|
||||
</resources>
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
|
||||
<color name="cover_placeholder">#1F888888</color>
|
||||
|
||||
<color name="error">#BA1B1B</color>
|
||||
<color name="errorContainer">#FFDAD4</color>
|
||||
<color name="onError">#FFFFFF</color>
|
||||
<color name="onErrorContainer">#410001</color>
|
||||
|
||||
<!-- Default Theme -->
|
||||
<color name="divider_default">@color/md_black_1000_12</color>
|
||||
|
||||
@@ -16,8 +11,13 @@
|
||||
<color name="accent_blue">#54759E</color>
|
||||
|
||||
<!-- AMOLED Mode -->
|
||||
<color name="surface_amoled">#000001</color>
|
||||
<color name="background_amoled">#000000</color>
|
||||
<color name="amoled_background">#000000</color>
|
||||
<color name="amoled_onBackground">#FFFFFF</color>
|
||||
<color name="amoled_surface">#000000</color>
|
||||
<color name="amoled_onSurface">#FFFFFF</color>
|
||||
<color name="amoled_surfaceContainer">#0C0C0C</color>
|
||||
<color name="amoled_surfaceContainerHigh">#131313</color>
|
||||
<color name="amoled_surfaceContainerHighest">#1B1B1B</color>
|
||||
|
||||
<!-- Material Design Colors -->
|
||||
<color name="md_black_1000_12">#1F000000</color>
|
||||
|
||||
@@ -11,26 +11,39 @@
|
||||
~ Neutral #5D5F5B
|
||||
-->
|
||||
<resources>
|
||||
<color name="greenapple_primary">#006D2F</color>
|
||||
<color name="greenapple_primary">#005927</color>
|
||||
<color name="greenapple_onPrimary">#FFFFFF</color>
|
||||
<color name="greenapple_primaryContainer">#96F8A9</color>
|
||||
<color name="greenapple_onPrimaryContainer">#002109</color>
|
||||
<color name="greenapple_secondary">#006D2F</color>
|
||||
<color name="greenapple_primaryContainer">#188140</color>
|
||||
<color name="greenapple_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="greenapple_secondary">#005927</color>
|
||||
<color name="greenapple_onSecondary">#FFFFFF</color>
|
||||
<color name="greenapple_secondaryContainer">#96F8A9</color>
|
||||
<color name="greenapple_onSecondaryContainer">#002109</color>
|
||||
<color name="greenapple_tertiary">#B91D22</color>
|
||||
<color name="greenapple_secondaryContainer">#97f7a9</color>
|
||||
<color name="greenapple_onSecondaryContainer">#000000</color>
|
||||
<color name="greenapple_tertiary">#9D0012</color>
|
||||
<color name="greenapple_onTertiary">#FFFFFF</color>
|
||||
<color name="greenapple_tertiaryContainer">#FFDAD5</color>
|
||||
<color name="greenapple_onTertiaryContainer">#410003</color>
|
||||
<color name="greenapple_background">#FBFDF7</color>
|
||||
<color name="greenapple_onBackground">#1A1C19</color>
|
||||
<color name="greenapple_surface">#FBFDF7</color>
|
||||
<color name="greenapple_onSurface">#1A1C19</color>
|
||||
<color name="greenapple_surfaceVariant">#DDE5DA</color>
|
||||
<color name="greenapple_onSurfaceVariant">#414941</color>
|
||||
<color name="greenapple_outline">#717970</color>
|
||||
<color name="greenapple_inverseOnSurface">#F0F2EC</color>
|
||||
<color name="greenapple_inverseSurface">#2F312E</color>
|
||||
<color name="greenapple_primaryInverse">#7ADB8F</color>
|
||||
<color name="greenapple_tertiaryContainer">#D33131</color>
|
||||
<color name="greenapple_onTertiaryContainer">#FFFFFF</color>
|
||||
<color name="greenapple_error">#BA1A1A</color>
|
||||
<color name="greenapple_onError">#FFFFFF</color>
|
||||
<color name="greenapple_errorContainer">#FFDAD6</color>
|
||||
<color name="greenapple_onErrorContainer">#410002</color>
|
||||
<color name="greenapple_background">#F6FBF2</color>
|
||||
<color name="greenapple_onBackground">#181D18</color>
|
||||
<color name="greenapple_surface">#F6FBF2</color>
|
||||
<color name="greenapple_onSurface">#181D18</color>
|
||||
<color name="greenapple_surfaceVariant">#DAE6D7</color>
|
||||
<color name="greenapple_onSurfaceVariant">#3F493F</color>
|
||||
<color name="greenapple_outline">#6F7A6E</color>
|
||||
<color name="greenapple_outlineVariant">#BECABC</color>
|
||||
<color name="greenapple_scrim">#000000</color>
|
||||
<color name="greenapple_inverseSurface">#2C322C</color>
|
||||
<color name="greenapple_inverseOnSurface">#EDF2E9</color>
|
||||
<color name="greenapple_inversePrimary">#7ADB8F</color>
|
||||
<color name="greenapple_surfaceDim">#D6DCD3</color>
|
||||
<color name="greenapple_surfaceBright">#F6FBF2</color>
|
||||
<color name="greenapple_surfaceContainerLowest">#FFFFFF</color>
|
||||
<color name="greenapple_surfaceContainerLow">#F0F5EC</color>
|
||||
<color name="greenapple_surfaceContainer">#EAEFE6</color>
|
||||
<color name="greenapple_surfaceContainerHigh">#E4EAE1</color>
|
||||
<color name="greenapple_surfaceContainerHighest">#DFE4DB</color>
|
||||
</resources>
|
||||
|
||||
@@ -10,27 +10,39 @@
|
||||
~ Neutral #EDE2FF
|
||||
-->
|
||||
<resources>
|
||||
<color name="lavender_primary">#7B46AF</color>
|
||||
<color name="lavender_onPrimary">#EDE2FF</color>
|
||||
<color name="lavender_primary">#6D41C8</color>
|
||||
<color name="lavender_onPrimary">#FFFFFF</color>
|
||||
<color name="lavender_primaryContainer">#7B46AF</color>
|
||||
<color name="lavender_onPrimaryContainer">#EDE2FF</color>
|
||||
<color name="lavender_onPrimaryContainer">#130038</color>
|
||||
<color name="lavender_secondary">#7B46AF</color>
|
||||
<color name="lavender_onSecondary">#EDE2FF</color>
|
||||
<color name="lavender_secondaryContainer">#C9B0E6</color>
|
||||
<color name="lavender_onSecondaryContainer">#EDE2FF</color>
|
||||
<color name="lavender_onSecondaryContainer">#7B46AF</color>
|
||||
<color name="lavender_tertiary">#EDE2FF</color>
|
||||
<color name="lavender_onTertiary">#7B46AF</color>
|
||||
<color name="lavender_tertiaryContainer">#EDE2FF</color>
|
||||
<color name="lavender_onTertiaryContainer">#7B46AF</color>
|
||||
<color name="lavender_tertiaryContainer">#6D3BF0</color>
|
||||
<color name="lavender_onTertiaryContainer">#FFFFFF</color>
|
||||
<color name="lavender_error">#BA1A1A</color>
|
||||
<color name="lavender_onError">#FFFFFF</color>
|
||||
<color name="lavender_errorContainer">#FFDAD6</color>
|
||||
<color name="lavender_onErrorContainer">#410002</color>
|
||||
<color name="lavender_background">#EDE2FF</color>
|
||||
<color name="lavender_onBackground">#1B1B22</color>
|
||||
<color name="lavender_onBackground">#1D1A22</color>
|
||||
<color name="lavender_surface">#EDE2FF</color>
|
||||
<color name="lavender_onSurface">#1B1B22</color>
|
||||
<color name="lavender_surfaceVariant">#B9B0CC</color>
|
||||
<color name="lavender_onSurfaceVariant">#D849454E</color>
|
||||
<color name="lavender_outline">#7B46AF</color>
|
||||
<color name="lavender_inverseOnSurface">#F3EFF4</color>
|
||||
<color name="lavender_inverseSurface">#313033</color>
|
||||
<color name="lavender_primaryInverse">#D6BAFF</color>
|
||||
<color name="lavender_elevationOverlay">@color/lavender_primary</color>
|
||||
<color name="lavender_onSurface">#1D1A22</color>
|
||||
<color name="lavender_surfaceVariant">#E4D5F8</color>
|
||||
<color name="lavender_onSurfaceVariant">#4A4453</color>
|
||||
<color name="lavender_outline">#7B7485</color>
|
||||
<color name="lavender_outlineVariant">#CBC3D6</color>
|
||||
<color name="lavender_scrim">#000000</color>
|
||||
<color name="lavender_inverseSurface">#322F38</color>
|
||||
<color name="lavender_inverseOnSurface">#F5EEFA</color>
|
||||
<color name="lavender_inversePrimary">#A177FF</color>
|
||||
<color name="lavender_surfaceDim">#DED7E3</color>
|
||||
<color name="lavender_surfaceBright">#EDE2FF</color>
|
||||
<color name="lavender_surfaceContainerLowest">#DACCEC</color>
|
||||
<color name="lavender_surfaceContainerLow">#DED0F1</color>
|
||||
<color name="lavender_surfaceContainer">#E4D5F8</color>
|
||||
<color name="lavender_surfaceContainerHigh">#EADCFD</color>
|
||||
<color name="lavender_surfaceContainerHighest">#EEE2FF</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
<color name="midnightdusk_onPrimary">#FFFFFF</color>
|
||||
<color name="midnightdusk_primaryContainer">#FFD9E1</color>
|
||||
<color name="midnightdusk_onPrimaryContainer">#3F0017</color>
|
||||
<color name="midnightdusk_inversePrimary">#FFB1C4</color>
|
||||
<color name="midnightdusk_secondary">#BB0054</color>
|
||||
<color name="midnightdusk_onSecondary">#FFFFFF</color>
|
||||
<color name="midnightdusk_secondaryContainer">#FFD9E1</color>
|
||||
<color name="midnightdusk_onSecondaryContainer">#3F0017</color>
|
||||
<color name="midnightdusk_secondaryContainer">#EFBAD4</color>
|
||||
<color name="midnightdusk_onSecondaryContainer">#D1377C</color>
|
||||
<color name="midnightdusk_tertiary">#006638</color>
|
||||
<color name="midnightdusk_onTertiary">#FFFFFF</color>
|
||||
<color name="midnightdusk_tertiaryContainer">#00894b</color>
|
||||
@@ -27,11 +28,15 @@
|
||||
<color name="midnightdusk_onBackground">#1C1B1F</color>
|
||||
<color name="midnightdusk_surface">#FFFBFF</color>
|
||||
<color name="midnightdusk_onSurface">#1C1B1F</color>
|
||||
<color name="midnightdusk_surfaceVariant">#F3DDE0</color>
|
||||
<color name="midnightdusk_surfaceVariant">#F9E6F1</color>
|
||||
<color name="midnightdusk_onSurfaceVariant">#524346</color>
|
||||
<color name="midnightdusk_outline">#847376</color>
|
||||
<color name="midnightdusk_inverseOnSurface">#F4F0F4</color>
|
||||
<color name="midnightdusk_surfaceTint">#BB0054</color>
|
||||
<color name="midnightdusk_inverseSurface">#313033</color>
|
||||
<color name="midnightdusk_primaryInverse">#FFB1C4</color>
|
||||
<color name="midnightdusk_elevationOverlay">@color/midnightdusk_primary</color>
|
||||
<color name="midnightdusk_inverseOnSurface">#F4F0F4</color>
|
||||
<color name="midnightdusk_outline">#847376</color>
|
||||
<color name="midnightdusk_surfaceContainerLowest">#DAC0CD</color>
|
||||
<color name="midnightdusk_surfaceContainerLow">#E8D1DD</color>
|
||||
<color name="midnightdusk_surfaceContainer">#F9E6F1</color>
|
||||
<color name="midnightdusk_surfaceContainerHigh">#FCF3F8</color>
|
||||
<color name="midnightdusk_surfaceContainerHighest">#FEF9FC</color>
|
||||
</resources>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<color name="nord_onPrimary">#000000</color>
|
||||
<color name="nord_primaryContainer">#5E81AC</color>
|
||||
<color name="nord_onPrimaryContainer">#000000</color>
|
||||
<color name="nord_inversePrimary">#8CA8CD</color>
|
||||
<color name="nord_secondary">#81A1C1</color>
|
||||
<color name="nord_onSecondary">#2E3440</color>
|
||||
<color name="nord_secondaryContainer">#91B4D7</color>
|
||||
@@ -18,14 +19,18 @@
|
||||
<color name="nord_onBackground">#2E3440</color>
|
||||
<color name="nord_surface">#E5E9F0</color>
|
||||
<color name="nord_onSurface">#2E3440</color>
|
||||
<color name="nord_surfaceVariant">#ffffff</color>
|
||||
<color name="nord_surfaceVariant">#DAE0EA</color>
|
||||
<color name="nord_onSurfaceVariant">#2E3440</color>
|
||||
<color name="nord_outline">#4C566A</color>
|
||||
<color name="nord_inverseOnSurface">#ECEFF4</color>
|
||||
<color name="nord_surfaceTint">#5E81AC</color>
|
||||
<color name="nord_inverseSurface">#3B4252</color>
|
||||
<color name="nord_primaryInverse">#8CA8CD</color>
|
||||
<color name="nord_elevationOverlay">#D8DEE9</color>
|
||||
<color name="nord_inverseOnSurface">#ECEFF4</color>
|
||||
<color name="nord_outline">#2E3440</color>
|
||||
<color name="nord_onError">#ECEFF4</color>
|
||||
<color name="nord_errorContainer">#BF616A</color>
|
||||
<color name="nord_onErrorContainer">#000000</color>
|
||||
<color name="nord_surfaceContainerLowest">#D1D7E0</color>
|
||||
<color name="nord_surfaceContainerLow">#D6DCE6</color>
|
||||
<color name="nord_surfaceContainer">#DAE0EA</color>
|
||||
<color name="nord_surfaceContainerHigh">#E9EDF3</color>
|
||||
<color name="nord_surfaceContainerHighest">#F2F4F8</color>
|
||||
</resources>
|
||||
|
||||
@@ -11,26 +11,39 @@
|
||||
~ Neutral #655C5C
|
||||
-->
|
||||
<resources>
|
||||
<color name="strawberry_primary">#B61E40</color>
|
||||
<color name="strawberry_primary">#A10833</color>
|
||||
<color name="strawberry_onPrimary">#FFFFFF</color>
|
||||
<color name="strawberry_primaryContainer">#FFDADD</color>
|
||||
<color name="strawberry_onPrimaryContainer">#40000D</color>
|
||||
<color name="strawberry_secondary">#B61E40</color>
|
||||
<color name="strawberry_primaryContainer">#D53855</color>
|
||||
<color name="strawberry_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="strawberry_secondary">#A10833</color>
|
||||
<color name="strawberry_onSecondary">#FFFFFF</color>
|
||||
<color name="strawberry_secondaryContainer">#FFDADD</color>
|
||||
<color name="strawberry_onSecondaryContainer">#40000D</color>
|
||||
<color name="strawberry_tertiary">#775930</color>
|
||||
<color name="strawberry_secondaryContainer">#D53855</color>
|
||||
<color name="strawberry_onSecondaryContainer">#F6EAED</color>
|
||||
<color name="strawberry_tertiary">#5F441D</color>
|
||||
<color name="strawberry_onTertiary">#FFFFFF</color>
|
||||
<color name="strawberry_tertiaryContainer">#FFDDB1</color>
|
||||
<color name="strawberry_onTertiaryContainer">#2A1800</color>
|
||||
<color name="strawberry_background">#FCFCFC</color>
|
||||
<color name="strawberry_onBackground">#201A1A</color>
|
||||
<color name="strawberry_surface">#FCFCFC</color>
|
||||
<color name="strawberry_onSurface">#201A1A</color>
|
||||
<color name="strawberry_surfaceVariant">#F4DDDD</color>
|
||||
<color name="strawberry_onSurfaceVariant">#534344</color>
|
||||
<color name="strawberry_outline">#857374</color>
|
||||
<color name="strawberry_inverseOnSurface">#FBEDED</color>
|
||||
<color name="strawberry_inverseSurface">#362F2F</color>
|
||||
<color name="strawberry_primaryInverse">#FFB2B9</color>
|
||||
<color name="strawberry_tertiaryContainer">#87683D</color>
|
||||
<color name="strawberry_onTertiaryContainer">#FFFFFF</color>
|
||||
<color name="strawberry_error">#BA1A1A</color>
|
||||
<color name="strawberry_onError">#FFFFFF</color>
|
||||
<color name="strawberry_errorContainer">#FFDAD6</color>
|
||||
<color name="strawberry_onErrorContainer">#410002</color>
|
||||
<color name="strawberry_background">#FAFAFA</color>
|
||||
<color name="strawberry_onBackground">#261819</color>
|
||||
<color name="strawberry_surface">#FAFAFA</color>
|
||||
<color name="strawberry_onSurface">#261819</color>
|
||||
<color name="strawberry_surfaceVariant">#F6EAED</color>
|
||||
<color name="strawberry_onSurfaceVariant">#594042</color>
|
||||
<color name="strawberry_outline">#8D7071</color>
|
||||
<color name="strawberry_outlineVariant">#E1BEC0</color>
|
||||
<color name="strawberry_scrim">#000000</color>
|
||||
<color name="strawberry_inverseSurface">#3D2C2D</color>
|
||||
<color name="strawberry_inverseOnSurface">#FFECED</color>
|
||||
<color name="strawberry_inversePrimary">#FFB2B8</color>
|
||||
<color name="strawberry_surfaceDim">#EED4D5</color>
|
||||
<color name="strawberry_surfaceBright">#FFF8F7</color>
|
||||
<color name="strawberry_surfaceContainerLowest">#F7DCDD</color>
|
||||
<color name="strawberry_surfaceContainerLow">#FDE2E3</color>
|
||||
<color name="strawberry_surfaceContainer">#F6EAED</color>
|
||||
<color name="strawberry_surfaceContainerHigh">#FFF0F0</color>
|
||||
<color name="strawberry_surfaceContainerHighest">#FFFFFF</color>
|
||||
</resources>
|
||||
|
||||
@@ -10,26 +10,37 @@
|
||||
~ Neutral #5E5E62
|
||||
-->
|
||||
<resources>
|
||||
<color name="tachiyomi_primary">#0057CE</color>
|
||||
<color name="tachiyomi_primary">#0058CA</color>
|
||||
<color name="tachiyomi_onPrimary">#FFFFFF</color>
|
||||
<color name="tachiyomi_primaryContainer">#D8E2FF</color>
|
||||
<color name="tachiyomi_onPrimaryContainer">#001947</color>
|
||||
<color name="tachiyomi_secondary">#0057CE</color>
|
||||
<color name="tachiyomi_primaryContainer">#D9E2FF</color>
|
||||
<color name="tachiyomi_onPrimaryContainer">#001945</color>
|
||||
<color name="tachiyomi_inversePrimary">#B0C6FF</color>
|
||||
<color name="tachiyomi_secondary">#0058CA</color>
|
||||
<color name="tachiyomi_onSecondary">#FFFFFF</color>
|
||||
<color name="tachiyomi_secondaryContainer">#D8E2FF</color>
|
||||
<color name="tachiyomi_onSecondaryContainer">#001947</color>
|
||||
<color name="tachiyomi_tertiary">#006E17</color>
|
||||
<color name="tachiyomi_secondaryContainer">#D9E2FF</color>
|
||||
<color name="tachiyomi_onSecondaryContainer">#001945</color>
|
||||
<color name="tachiyomi_tertiary">#006E1B</color>
|
||||
<color name="tachiyomi_onTertiary">#FFFFFF</color>
|
||||
<color name="tachiyomi_tertiaryContainer">#95F990</color>
|
||||
<color name="tachiyomi_onTertiaryContainer">#002202</color>
|
||||
<color name="tachiyomi_background">#FDFBFF</color>
|
||||
<color name="tachiyomi_onBackground">#1B1B1E</color>
|
||||
<color name="tachiyomi_surface">#FDFBFF</color>
|
||||
<color name="tachiyomi_onSurface">#1B1B1E</color>
|
||||
<color name="tachiyomi_surfaceVariant">#E1E2EC</color>
|
||||
<color name="tachiyomi_onSurfaceVariant">#44464E</color>
|
||||
<color name="tachiyomi_outline">#757780</color>
|
||||
<color name="tachiyomi_onTertiaryContainer">#002203</color>
|
||||
<color name="tachiyomi_background">#FEFBFF</color>
|
||||
<color name="tachiyomi_onBackground">#1B1B1F</color>
|
||||
<color name="tachiyomi_surface">#FEFBFF</color>
|
||||
<color name="tachiyomi_onSurface">#1B1B1F</color>
|
||||
<color name="tachiyomi_surfaceVariant">#F3EDF7</color>
|
||||
<color name="tachiyomi_onSurfaceVariant">#44464F</color>
|
||||
<color name="tachiyomi_surfaceTint">#0058CA</color>
|
||||
<color name="tachiyomi_inverseSurface">#303034</color>
|
||||
<color name="tachiyomi_inverseOnSurface">#F2F0F4</color>
|
||||
<color name="tachiyomi_inverseSurface">#303033</color>
|
||||
<color name="tachiyomi_primaryInverse">#AEC6FF</color>
|
||||
<color name="tachiyomi_error">#BA1A1A</color>
|
||||
<color name="tachiyomi_onError">#FFFFFF</color>
|
||||
<color name="tachiyomi_errorContainer">#FFDAD6</color>
|
||||
<color name="tachiyomi_onErrorContainer">#410002</color>
|
||||
<color name="tachiyomi_outline">#757780</color>
|
||||
<color name="tachiyomi_outlineVariant">#C5C6D0</color>
|
||||
<color name="tachiyomi_surfaceContainerLowest">#F5F1F8</color>
|
||||
<color name="tachiyomi_surfaceContainerLow">#F7F2FA</color>
|
||||
<color name="tachiyomi_surfaceContainer">#F3EDF7</color>
|
||||
<color name="tachiyomi_surfaceContainerHigh">#FCF7FF</color>
|
||||
<color name="tachiyomi_surfaceContainerHighest">#FCF7FF</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
<color name="tako_onPrimary">#F3B375</color>
|
||||
<color name="tako_primaryContainer">#66577E</color>
|
||||
<color name="tako_onPrimaryContainer">#F3B375</color>
|
||||
<color name="tako_inversePrimary">#D6BAFF</color>
|
||||
<color name="tako_secondary">#66577E</color>
|
||||
<color name="tako_onSecondary">#F3B375</color>
|
||||
<color name="tako_secondaryContainer">#C8BED0</color>
|
||||
<color name="tako_onSecondaryContainer">#F3B375</color>
|
||||
<color name="tako_onSecondaryContainer">#66577E</color>
|
||||
<color name="tako_tertiary">#F3B375</color>
|
||||
<color name="tako_onTertiary">#574360</color>
|
||||
<color name="tako_tertiaryContainer">#FDD6B0</color>
|
||||
@@ -29,9 +30,13 @@
|
||||
<color name="tako_onSurface">#1B1B22</color>
|
||||
<color name="tako_surfaceVariant">#E8E0EB</color>
|
||||
<color name="tako_onSurfaceVariant">#49454E</color>
|
||||
<color name="tako_outline">#7A757E</color>
|
||||
<color name="tako_inverseOnSurface">#F3EFF4</color>
|
||||
<color name="tako_surfaceTint">#66577E</color>
|
||||
<color name="tako_inverseSurface">#313033</color>
|
||||
<color name="tako_primaryInverse">#D6BAFF</color>
|
||||
<color name="tako_elevationOverlay">@color/tako_primary</color>
|
||||
<color name="tako_inverseOnSurface">#F3EFF4</color>
|
||||
<color name="tako_outline">#7A757E</color>
|
||||
<color name="tako_surfaceContainerLowest">#D7D0DA</color>
|
||||
<color name="tako_surfaceContainerLow">#DFD8E2</color>
|
||||
<color name="tako_surfaceContainer">#E8E0EB</color>
|
||||
<color name="tako_surfaceContainerHigh">#EEE6F1</color>
|
||||
<color name="tako_surfaceContainerHighest">#F7EEFA</color>
|
||||
</resources>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<color name="tealturquoise_primary">#008080</color>
|
||||
<color name="tealturquoise_onPrimary">#FFFFFF</color>
|
||||
<color name="tealturquoise_primaryContainer">#008080</color>
|
||||
<color name="tealturquoise_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="tealturquoise_inversePrimary">#40E0D0</color>
|
||||
<color name="tealturquoise_secondary">#008080</color>
|
||||
<color name="tealturquoise_onSecondary">#FFFFFF</color>
|
||||
<color name="tealturquoise_secondaryContainer">#BFDFDF</color>
|
||||
<color name="tealturquoise_secondaryContainer">#CFE5E4</color>
|
||||
<color name="tealturquoise_onSecondaryContainer">#008080</color>
|
||||
<color name="tealturquoise_tertiary">#FF7F7F</color>
|
||||
<color name="tealturquoise_onTertiary">#000000</color>
|
||||
@@ -17,11 +17,15 @@
|
||||
<color name="tealturquoise_onBackground">#050505</color>
|
||||
<color name="tealturquoise_surface">#FAFAFA</color>
|
||||
<color name="tealturquoise_onSurface">#050505</color>
|
||||
<color name="tealturquoise_surfaceVariant">#DAE5E2</color>
|
||||
<color name="tealturquoise_surfaceVariant">#EBF3F1</color>
|
||||
<color name="tealturquoise_onSurfaceVariant">#050505</color>
|
||||
<color name="tealturquoise_outline">#6F7977</color>
|
||||
<color name="tealturquoise_inverseOnSurface">#FAFAFA</color>
|
||||
<color name="tealturquoise_surfaceTint">#BFDFDF</color>
|
||||
<color name="tealturquoise_inverseSurface">#050505</color>
|
||||
<color name="tealturquoise_primaryInverse">#40E0D0</color>
|
||||
<color name="tealturquoise_elevationOverlay">#BFDFDF</color>
|
||||
<color name="tealturquoise_inverseOnSurface">#FAFAFA</color>
|
||||
<color name="tealturquoise_outline">#6F7977</color>
|
||||
<color name="tealturquoise_surfaceContainerLowest">#E1E9E7</color>
|
||||
<color name="tealturquoise_surfaceContainerLow">#E6EEEC</color>
|
||||
<color name="tealturquoise_surfaceContainer">#EBF3F1</color>
|
||||
<color name="tealturquoise_surfaceContainerHigh">#F0F8F6</color>
|
||||
<color name="tealturquoise_surfaceContainerHighest">#F7FFFD</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
<color name="tidalwave_onPrimary">#ffffff</color>
|
||||
<color name="tidalwave_primaryContainer">#B4D4DF</color>
|
||||
<color name="tidalwave_onPrimaryContainer">#001f28</color>
|
||||
<color name="tidalwave_inversePrimary">#ff987f</color>
|
||||
<color name="tidalwave_secondary">#006780</color>
|
||||
<color name="tidalwave_onSecondary">#ffffff</color>
|
||||
<color name="tidalwave_secondaryContainer">#b8eaff</color>
|
||||
<color name="tidalwave_secondaryContainer">#9AE1FF</color>
|
||||
<color name="tidalwave_onSecondaryContainer">#001f28</color>
|
||||
<color name="tidalwave_tertiary">#92f7bc</color>
|
||||
<color name="tidalwave_onTertiary">#001c3b</color>
|
||||
@@ -27,10 +28,15 @@
|
||||
<color name="tidalwave_onBackground">#001c3b</color>
|
||||
<color name="tidalwave_surface">#fdfbff</color>
|
||||
<color name="tidalwave_onSurface">#001c3b</color>
|
||||
<color name="tidalwave_surfaceVariant">#dce4e8</color>
|
||||
<color name="tidalwave_surfaceVariant">#e8eff5</color>
|
||||
<color name="tidalwave_onSurfaceVariant">#40484c</color>
|
||||
<color name="tidalwave_outline">#70787c</color>
|
||||
<color name="tidalwave_inverseOnSurface">#ffe3c4</color>
|
||||
<color name="tidalwave_surfaceTint">#006780</color>
|
||||
<color name="tidalwave_inverseSurface">#020400</color>
|
||||
<color name="tidalwave_primaryInverse">#ff987f</color>
|
||||
<color name="tidalwave_inverseOnSurface">#ffe3c4</color>
|
||||
<color name="tidalwave_outline">#70787c</color>
|
||||
<color name="tidalwave_surfaceContainerLowest">#e2e8ec</color>
|
||||
<color name="tidalwave_surfaceContainerLow">#e5ecf1</color>
|
||||
<color name="tidalwave_surfaceContainer">#e8eff5</color>
|
||||
<color name="tidalwave_surfaceContainerHigh">#edf4fA</color>
|
||||
<color name="tidalwave_surfaceContainerHighest">#f5faff</color>
|
||||
</resources>
|
||||
@@ -9,6 +9,7 @@
|
||||
<color name="yinyang_onPrimary">#FFFFFF</color>
|
||||
<color name="yinyang_primaryContainer">#000000</color>
|
||||
<color name="yinyang_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="yinyang_inversePrimary">#A6A6A6</color>
|
||||
<color name="yinyang_secondary">#000000</color>
|
||||
<color name="yinyang_onSecondary">#FFFFFF</color>
|
||||
<color name="yinyang_secondaryContainer">#DDDDDD</color>
|
||||
@@ -21,10 +22,15 @@
|
||||
<color name="yinyang_onBackground">#222222</color>
|
||||
<color name="yinyang_surface">#FDFDFD</color>
|
||||
<color name="yinyang_onSurface">#222222</color>
|
||||
<color name="yinyang_surfaceVariant">#EDEDED</color>
|
||||
<color name="yinyang_surfaceVariant">#E8E8E8</color>
|
||||
<color name="yinyang_onSurfaceVariant">#515151</color>
|
||||
<color name="yinyang_outline">#838383</color>
|
||||
<color name="yinyang_inverseOnSurface">#F4F4F4</color>
|
||||
<color name="yinyang_surfaceTint">#000000</color>
|
||||
<color name="yinyang_inverseSurface">#333333</color>
|
||||
<color name="yinyang_primaryInverse">#A6A6A6</color>
|
||||
<color name="yinyang_inverseOnSurface">#F4F4F4</color>
|
||||
<color name="yinyang_outline">#838383</color>
|
||||
<color name="yinyang_surfaceContainerLowest">#CFCFCF</color>
|
||||
<color name="yinyang_surfaceContainerLow">#DADADA</color>
|
||||
<color name="yinyang_surfaceContainer">#E8E8E8</color>
|
||||
<color name="yinyang_surfaceContainerHigh">#ECECEC</color>
|
||||
<color name="yinyang_surfaceContainerHighest">#EFEFEF</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
<color name="yotsuba_onPrimary">#FFFFFF</color>
|
||||
<color name="yotsuba_primaryContainer">#FFDBCF</color>
|
||||
<color name="yotsuba_onPrimaryContainer">#3B0A00</color>
|
||||
<color name="yotsuba_inversePrimary">#FFB59D</color>
|
||||
<color name="yotsuba_secondary">#AE3200</color>
|
||||
<color name="yotsuba_onSecondary">#FFFFFF</color>
|
||||
<color name="yotsuba_secondaryContainer">#FFDBCF</color>
|
||||
<color name="yotsuba_secondaryContainer">#EBCDC2</color>
|
||||
<color name="yotsuba_onSecondaryContainer">#3B0A00</color>
|
||||
<color name="yotsuba_tertiary">#6B5E2F</color>
|
||||
<color name="yotsuba_onTertiary">#FFFFFF</color>
|
||||
@@ -27,10 +28,15 @@
|
||||
<color name="yotsuba_onBackground">#211A18</color>
|
||||
<color name="yotsuba_surface">#FCFCFC</color>
|
||||
<color name="yotsuba_onSurface">#211A18</color>
|
||||
<color name="yotsuba_surfaceVariant">#F5DED8</color>
|
||||
<color name="yotsuba_surfaceVariant">#F6EBE7</color>
|
||||
<color name="yotsuba_onSurfaceVariant">#53433F</color>
|
||||
<color name="yotsuba_outline">#85736E</color>
|
||||
<color name="yotsuba_inverseOnSurface">#FBEEEB</color>
|
||||
<color name="yotsuba_surfaceTint">#AE3200</color>
|
||||
<color name="yotsuba_inverseSurface">#362F2D</color>
|
||||
<color name="yotsuba_primaryInverse">#FFB59D</color>
|
||||
<color name="yotsuba_inverseOnSurface">#FBEEEB</color>
|
||||
<color name="yotsuba_outline">#85736E</color>
|
||||
<color name="yotsuba_surfaceContainerLowest">#ECE3E0</color>
|
||||
<color name="yotsuba_surfaceContainerLow">#F1E7E4</color>
|
||||
<color name="yotsuba_surfaceContainer">#F6EBE7</color>
|
||||
<color name="yotsuba_surfaceContainerHigh">#FAF4F2</color>
|
||||
<color name="yotsuba_surfaceContainerHighest">#FBF6F4</color>
|
||||
</resources>
|
||||
|
||||
@@ -15,10 +15,6 @@ kotlin {
|
||||
// SY <--
|
||||
|
||||
implementation(libs.unifile)
|
||||
implementation(libs.bundles.archive)
|
||||
// SY -->
|
||||
implementation(libs.zip4j)
|
||||
// SY <--
|
||||
}
|
||||
}
|
||||
val androidMain by getting {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package tachiyomi.source.local
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
@@ -12,22 +11,18 @@ import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||
import eu.kanade.tachiyomi.util.storage.EpubFile
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import logcat.LogPriority
|
||||
import mihon.core.common.archive.ZipWriter
|
||||
import mihon.core.common.archive.archiveReader
|
||||
import nl.adaptivity.xmlutil.AndroidXmlReader
|
||||
import nl.adaptivity.xmlutil.serialization.XML
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.storage.UniFileTempFileManager
|
||||
import tachiyomi.core.common.storage.addStreamToZip
|
||||
import tachiyomi.core.common.storage.extension
|
||||
import tachiyomi.core.common.storage.getCoverStreamFromZip
|
||||
import tachiyomi.core.common.storage.getZipInputStream
|
||||
import tachiyomi.core.common.storage.isEncryptedZip
|
||||
import tachiyomi.core.common.storage.nameWithoutExtension
|
||||
import tachiyomi.core.common.util.lang.withIOContext
|
||||
import tachiyomi.core.common.util.system.ImageUtil
|
||||
@@ -51,7 +46,6 @@ import uy.kohesive.injekt.injectLazy
|
||||
import java.io.InputStream
|
||||
import java.nio.charset.StandardCharsets
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import com.github.junrar.Archive as JunrarArchive
|
||||
import tachiyomi.domain.source.model.Source as DomainSource
|
||||
|
||||
actual class LocalSource(
|
||||
@@ -65,7 +59,6 @@ actual class LocalSource(
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
private val xml: XML by injectLazy()
|
||||
private val tempFileManager: UniFileTempFileManager by injectLazy()
|
||||
|
||||
private val POPULAR_FILTERS = FilterList(OrderBy.Popular(context))
|
||||
private val LATEST_FILTERS = FilterList(OrderBy.Latest(context))
|
||||
@@ -161,13 +154,14 @@ actual class LocalSource(
|
||||
val mangaDirFiles = fileSystem.getFilesInMangaDirectory(manga.url)
|
||||
val existingFile = mangaDirFiles
|
||||
.firstOrNull { it.name == COMIC_INFO_FILE }
|
||||
val comicInfoArchiveFile = mangaDirFiles
|
||||
.firstOrNull { it.name == COMIC_INFO_ARCHIVE }
|
||||
val existingComicInfo = (existingFile?.openInputStream() ?: comicInfoArchiveFile?.getZipInputStream(COMIC_INFO_FILE))?.use {
|
||||
AndroidXmlReader(it, StandardCharsets.UTF_8.name()).use {
|
||||
xml.decodeFromReader<ComicInfo>(it)
|
||||
val comicInfoArchiveFile = mangaDirFiles.firstOrNull { it.name == COMIC_INFO_ARCHIVE }
|
||||
val comicInfoArchiveReader = comicInfoArchiveFile?.archiveReader(context)
|
||||
val existingComicInfo =
|
||||
(existingFile?.openInputStream() ?: comicInfoArchiveReader?.getInputStream(COMIC_INFO_FILE))?.use {
|
||||
AndroidXmlReader(it, StandardCharsets.UTF_8.name()).use { xmlReader ->
|
||||
xml.decodeFromReader<ComicInfo>(xmlReader)
|
||||
}
|
||||
}
|
||||
}
|
||||
val newComicInfo = if (existingComicInfo != null) {
|
||||
manga.run {
|
||||
existingComicInfo.copy(
|
||||
@@ -188,8 +182,9 @@ actual class LocalSource(
|
||||
fileSystem.getMangaDirectory(manga.url)?.let {
|
||||
copyComicInfoFile(
|
||||
xml.encodeToString(ComicInfo.serializer(), newComicInfo).byteInputStream(),
|
||||
it
|
||||
)
|
||||
it,
|
||||
comicInfoArchiveReader?.encrypted ?: false
|
||||
)
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
@@ -202,8 +197,8 @@ actual class LocalSource(
|
||||
|
||||
// Augment manga details based on metadata files
|
||||
try {
|
||||
val mangaDir by lazy { fileSystem.getMangaDirectory(manga.url) }
|
||||
val mangaDirFiles = fileSystem.getFilesInMangaDirectory(manga.url)
|
||||
val mangaDir = fileSystem.getMangaDirectory(manga.url) ?: error("${manga.url} is not a valid directory")
|
||||
val mangaDirFiles = mangaDir.listFiles().orEmpty()
|
||||
|
||||
val comicInfoFile = mangaDirFiles
|
||||
.firstOrNull { it.name == COMIC_INFO_FILE }
|
||||
@@ -226,7 +221,7 @@ actual class LocalSource(
|
||||
comicInfoArchiveFile != null -> {
|
||||
noXmlFile?.delete()
|
||||
|
||||
comicInfoArchiveFile.getZipInputStream(COMIC_INFO_FILE)
|
||||
comicInfoArchiveFile.archiveReader(context).getInputStream(COMIC_INFO_FILE)
|
||||
?.let { setMangaDetailsFromComicInfoFile(it, manga) }
|
||||
}
|
||||
|
||||
@@ -246,7 +241,7 @@ actual class LocalSource(
|
||||
// Replace with ComicInfo.xml file
|
||||
val comicInfo = manga.getComicInfo()
|
||||
mangaDir
|
||||
?.createFile(COMIC_INFO_FILE)
|
||||
.createFile(COMIC_INFO_FILE)
|
||||
?.openOutputStream()
|
||||
?.use {
|
||||
val comicInfoString = xml.encodeToString(ComicInfo.serializer(), comicInfo)
|
||||
@@ -257,21 +252,20 @@ actual class LocalSource(
|
||||
|
||||
// Copy ComicInfo.xml from chapter archive to top level if found
|
||||
noXmlFile == null -> {
|
||||
val chapterArchives = mangaDirFiles
|
||||
.filter(Archive::isSupported)
|
||||
.toList()
|
||||
val chapterArchives = mangaDirFiles.filter(Archive::isSupported)
|
||||
|
||||
val copiedFile = mangaDir?.let { copyComicInfoFileFromArchive(chapterArchives, it) }
|
||||
val copiedFile = copyComicInfoFileFromArchive(chapterArchives, mangaDir)
|
||||
|
||||
// SY -->
|
||||
if (copiedFile != null && copiedFile.name != COMIC_INFO_ARCHIVE) {
|
||||
setMangaDetailsFromComicInfoFile(copiedFile.openInputStream(), manga)
|
||||
} else if (copiedFile != null && copiedFile.name == COMIC_INFO_ARCHIVE) {
|
||||
copiedFile.getZipInputStream(COMIC_INFO_FILE)?.let { setMangaDetailsFromComicInfoFile(it, manga) }
|
||||
copiedFile.archiveReader(context).getInputStream(COMIC_INFO_FILE)
|
||||
?.let { setMangaDetailsFromComicInfoFile(it, manga) }
|
||||
} // SY <--
|
||||
else {
|
||||
// Avoid re-scanning
|
||||
mangaDir?.createFile(".noxml")
|
||||
mangaDir.createFile(".noxml")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,44 +278,31 @@ actual class LocalSource(
|
||||
|
||||
private fun copyComicInfoFileFromArchive(chapterArchives: List<UniFile>, folder: UniFile): UniFile? {
|
||||
for (chapter in chapterArchives) {
|
||||
when (Format.valueOf(chapter)) {
|
||||
is Format.Zip -> {
|
||||
// SY -->
|
||||
chapter.getZipInputStream(COMIC_INFO_FILE)?.buffered().use { stream ->
|
||||
return stream?.let { copyComicInfoFile(it, folder) }
|
||||
}
|
||||
chapter.archiveReader(context).use { reader ->
|
||||
reader.getInputStream(COMIC_INFO_FILE)?.use { stream ->
|
||||
return copyComicInfoFile(stream, folder, /* SY --> */ reader.encrypted /* SY <-- */)
|
||||
}
|
||||
is Format.Rar -> {
|
||||
val archive = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
JunrarArchive(tempFileManager.createTempFile(chapter))
|
||||
} else {
|
||||
JunrarArchive(chapter.openInputStream())
|
||||
}
|
||||
|
||||
archive.use { rar ->
|
||||
rar.fileHeaders.firstOrNull { it.fileName == COMIC_INFO_FILE }?.let { comicInfoFile ->
|
||||
rar.getInputStream(comicInfoFile).buffered().use { stream ->
|
||||
return copyComicInfoFile(stream, folder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun copyComicInfoFile(comicInfoFileStream: InputStream, folder: UniFile): UniFile? {
|
||||
private fun copyComicInfoFile(
|
||||
comicInfoFileStream: InputStream,
|
||||
folder: UniFile,
|
||||
// SY -->
|
||||
if (
|
||||
CbzCrypto.getPasswordProtectDlPref() &&
|
||||
CbzCrypto.isPasswordSet()
|
||||
) {
|
||||
val comicInfoArchive = folder.createFile(COMIC_INFO_ARCHIVE)
|
||||
comicInfoArchive?.addStreamToZip(comicInfoFileStream, COMIC_INFO_FILE, CbzCrypto.getDecryptedPasswordCbz())
|
||||
|
||||
return comicInfoArchive
|
||||
encrypt: Boolean,
|
||||
// SY <--
|
||||
): UniFile? {
|
||||
// SY -->
|
||||
if (encrypt) {
|
||||
val comicInfoArchiveFile = folder.createFile(COMIC_INFO_ARCHIVE)
|
||||
comicInfoArchiveFile?.let { archive ->
|
||||
ZipWriter(context, archive, encrypt = true).use { writer ->
|
||||
writer.write(comicInfoFileStream.use { it.readBytes() }, COMIC_INFO_FILE)
|
||||
}
|
||||
}
|
||||
return comicInfoArchiveFile
|
||||
} else {
|
||||
// SY <--
|
||||
return folder.createFile(COMIC_INFO_FILE)?.apply {
|
||||
@@ -344,7 +325,7 @@ actual class LocalSource(
|
||||
override suspend fun getChapterList(manga: SManga): List<SChapter> = withIOContext {
|
||||
val chapters = fileSystem.getFilesInMangaDirectory(manga.url)
|
||||
// Only keep supported formats
|
||||
.filter { it.isDirectory || Archive.isSupported(it) }
|
||||
.filter { it.isDirectory || Archive.isSupported(it) || it.extension.equals("epub", true) }
|
||||
.map { chapterFile ->
|
||||
SChapter.create().apply {
|
||||
url = "${manga.url}/${chapterFile.name}"
|
||||
@@ -360,7 +341,7 @@ actual class LocalSource(
|
||||
|
||||
val format = Format.valueOf(chapterFile)
|
||||
if (format is Format.Epub) {
|
||||
EpubFile(format.file, context).use { epub ->
|
||||
EpubFile(format.file.archiveReader(context)).use { epub ->
|
||||
epub.fillMetadata(manga, this)
|
||||
}
|
||||
}
|
||||
@@ -418,43 +399,25 @@ actual class LocalSource(
|
||||
|
||||
entry?.let { coverManager.update(manga, it.openInputStream()) }
|
||||
}
|
||||
is Format.Zip -> {
|
||||
// SY -->
|
||||
format.file.getCoverStreamFromZip()?.let { inputStream ->
|
||||
coverManager.update(
|
||||
manga,
|
||||
inputStream,
|
||||
format.file.isEncryptedZip()
|
||||
)
|
||||
}
|
||||
}
|
||||
is Format.Rar -> {
|
||||
val rarArchive = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
JunrarArchive(tempFileManager.createTempFile(format.file))
|
||||
} else {
|
||||
JunrarArchive(format.file.openInputStream())
|
||||
}
|
||||
rarArchive.use { archive ->
|
||||
// SY <--
|
||||
val entry = archive.fileHeaders
|
||||
.sortedWith { f1, f2 -> f1.fileName.compareToCaseInsensitiveNaturalOrder(f2.fileName) }
|
||||
.find { !it.isDirectory && ImageUtil.isImage(it.fileName) { archive.getInputStream(it) } }
|
||||
is Format.Archive -> {
|
||||
format.file.archiveReader(context).use { reader ->
|
||||
val entry = reader.useEntries { entries ->
|
||||
entries
|
||||
.sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }
|
||||
.find { it.isFile && ImageUtil.isImage(it.name) { reader.getInputStream(it.name)!! } }
|
||||
}
|
||||
|
||||
entry?.let { coverManager.update(manga, archive.getInputStream(it)) }
|
||||
entry?.let { coverManager.update(manga, reader.getInputStream(it.name)!!, reader.encrypted) }
|
||||
}
|
||||
}
|
||||
is Format.Epub -> {
|
||||
// SY -->
|
||||
EpubFile(format.file, context).use { epub ->
|
||||
// SY <--
|
||||
val entry = epub.getImagesFromPages()
|
||||
.firstOrNull()
|
||||
?.let { epub.getEntry(it) }
|
||||
EpubFile(format.file.archiveReader(context)).use { epub ->
|
||||
val entry = epub.getImagesFromPages().firstOrNull()
|
||||
|
||||
entry?.let { coverManager.update(manga, epub.getInputStream(it)) }
|
||||
}
|
||||
entry?.let { coverManager.update(manga, epub.getInputStream(it)!!) }
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e) { "Error updating cover for ${manga.title}" }
|
||||
null
|
||||
|
||||
+4
-3
@@ -3,9 +3,8 @@ package tachiyomi.source.local.image
|
||||
import android.content.Context
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||
import tachiyomi.core.common.storage.addStreamToZip
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import mihon.core.common.archive.ZipWriter
|
||||
import tachiyomi.core.common.storage.nameWithoutExtension
|
||||
import tachiyomi.core.common.util.system.ImageUtil
|
||||
import tachiyomi.source.local.io.LocalSourceFileSystem
|
||||
@@ -58,7 +57,9 @@ actual class LocalCoverManager(
|
||||
inputStream.use { input ->
|
||||
// SY -->
|
||||
if (encrypted) {
|
||||
targetFile.addStreamToZip(inputStream, DEFAULT_COVER_NAME, CbzCrypto.getDecryptedPasswordCbz())
|
||||
ZipWriter(context, targetFile, encrypt = true ).use { writer ->
|
||||
writer.write(inputStream.readBytes(), DEFAULT_COVER_NAME)
|
||||
}
|
||||
DiskUtil.createNoMediaFile(directory, context)
|
||||
|
||||
manga.thumbnail_url = targetFile.uri.toString()
|
||||
|
||||
@@ -5,9 +5,9 @@ import tachiyomi.core.common.storage.extension
|
||||
|
||||
object Archive {
|
||||
|
||||
private val SUPPORTED_ARCHIVE_TYPES = listOf("zip", "cbz", "rar", "cbr", "epub")
|
||||
private val SUPPORTED_ARCHIVE_TYPES = listOf("zip", "cbz", "rar", "cbr", "7z", "cb7", "tar", "cbt")
|
||||
|
||||
fun isSupported(file: UniFile): Boolean {
|
||||
return file.extension in SUPPORTED_ARCHIVE_TYPES
|
||||
return file.extension?.lowercase() in SUPPORTED_ARCHIVE_TYPES
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,25 +2,22 @@ package tachiyomi.source.local.io
|
||||
|
||||
import com.hippo.unifile.UniFile
|
||||
import tachiyomi.core.common.storage.extension
|
||||
import tachiyomi.source.local.io.Archive.isSupported as isArchiveSupported
|
||||
|
||||
sealed interface Format {
|
||||
data class Directory(val file: UniFile) : Format
|
||||
data class Zip(val file: UniFile) : Format
|
||||
data class Rar(val file: UniFile) : Format
|
||||
data class Archive(val file: UniFile) : Format
|
||||
data class Epub(val file: UniFile) : Format
|
||||
|
||||
class UnknownFormatException : Exception()
|
||||
|
||||
companion object {
|
||||
|
||||
fun valueOf(file: UniFile) = with(file) {
|
||||
when {
|
||||
isDirectory -> Directory(this)
|
||||
extension.equals("zip", true) || extension.equals("cbz", true) -> Zip(this)
|
||||
extension.equals("rar", true) || extension.equals("cbr", true) -> Rar(this)
|
||||
extension.equals("epub", true) -> Epub(this)
|
||||
else -> throw UnknownFormatException()
|
||||
}
|
||||
fun valueOf(file: UniFile) = when {
|
||||
file.isDirectory -> Directory(file)
|
||||
file.extension.equals("epub", true) -> Epub(file)
|
||||
isArchiveSupported(file) -> Archive(file)
|
||||
else -> throw UnknownFormatException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user