From 02775c7c99dbba971782a631deeeba69bd65432e Mon Sep 17 00:00:00 2001 From: Shamicen <84282253+Shamicen@users.noreply.github.com> Date: Sat, 16 Mar 2024 16:59:00 +0100 Subject: [PATCH] implement mihonapp/mihon#326 (#1104) * implement mihonapp/mihon#326 Archives are now being read from channels Co-authored-by: FooIbar <118464521+FooIbar@users.noreply.github.com> Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> * disable parallelisms for loading into memory * switched to mutex * detekt changes * more detekt baseline changes --------- Co-authored-by: FooIbar <118464521+FooIbar@users.noreply.github.com> Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> --- app/build.gradle.kts | 2 +- app/proguard-rules.pro | 3 + .../settings/screen/SettingsReaderScreen.kt | 12 +- .../tachiyomi/data/download/Downloader.kt | 6 +- .../tachiyomi/ui/reader/ReaderViewModel.kt | 1 - .../ui/reader/loader/ChapterLoader.kt | 21 +- .../ui/reader/loader/DownloadPageLoader.kt | 6 +- .../ui/reader/loader/EpubPageLoader.kt | 9 +- .../ui/reader/loader/RarPageLoader.kt | 71 +- .../ui/reader/loader/ZipPageLoader.kt | 172 ++- .../tachiyomi/ui/reader/model/ReaderPage.kt | 5 - .../ui/reader/setting/ReaderPreferences.kt | 16 +- .../ui/reader/viewer/pager/PagerPageHolder.kt | 24 +- .../viewer/webtoon/WebtoonPageHolder.kt | 16 +- app/src/main/java/exh/EXHMigrations.kt | 6 + .../exh/ui/intercept/InterceptActivity.kt | 1 - config/detekt/baseline.xml | 1337 ++++++++++++++--- core/common/build.gradle.kts | 1 + .../tachiyomi/util/storage/CbzCrypto.kt | 167 +- .../kanade/tachiyomi/util/storage/EpubFile.kt | 26 +- .../core/common/storage/UniFileExtensions.kt | 213 +++ .../core/common/util/system/ImageUtil.kt | 66 +- gradle/libs.versions.toml | 2 + .../commonMain/resources/MR/base/strings.xml | 10 +- source-local/build.gradle.kts | 2 +- .../tachiyomi/source/local/LocalSource.kt | 42 +- .../source/local/image/LocalCoverManager.kt | 2 +- 27 files changed, 1656 insertions(+), 583 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8f5254bbf..1292fbb3e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -215,7 +215,7 @@ dependencies { // Disk implementation(libs.disklrucache) implementation(libs.unifile) - implementation(libs.junrar) + implementation(libs.bundles.archive) // SY --> implementation(libs.zip4j) // SY <-- diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f4445d017..94692d207 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -122,6 +122,9 @@ # XmlUtil -keep public enum nl.adaptivity.xmlutil.EventType { *; } +# Apache Commons Compress +-keep class * extends org.apache.commons.compress.archivers.zip.ZipExtraField { (); } + # Firebase -keep class com.google.firebase.installations.** { *; } -keep interface com.google.firebase.installations.** { *; } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt index 3acc668c3..49788eb7a 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt @@ -570,10 +570,14 @@ object SettingsReaderScreen : SearchableSettings { .toMap() .toImmutableMap(), ), - Preference.PreferenceItem.SwitchPreference( - pref = readerPreferences.cacheArchiveMangaOnDisk(), - title = stringResource(SYMR.strings.cache_archived_manga_to_disk), - subtitle = stringResource(SYMR.strings.cache_archived_manga_to_disk_subtitle), + Preference.PreferenceItem.ListPreference( + pref = readerPreferences.archiveReaderMode(), + title = stringResource(SYMR.strings.pref_archive_reader_mode), + subtitle = stringResource(SYMR.strings.pref_archive_reader_mode_summary), + entries = ReaderPreferences.archiveModeTypes + .mapIndexed { index, it -> index to stringResource(it) } + .toMap() + .toImmutableMap(), ), ), ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index 577adbdeb..90ef63638 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -13,7 +13,6 @@ import eu.kanade.tachiyomi.source.UnmeteredSource import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.util.storage.CbzCrypto -import eu.kanade.tachiyomi.util.storage.CbzCrypto.addFilesToZip import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil.NOMEDIA_FILE import eu.kanade.tachiyomi.util.storage.saveTo @@ -46,6 +45,7 @@ import logcat.LogPriority 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 @@ -572,10 +572,6 @@ class Downloader( tmpDir, imageFile, filenamePrefix, - // SY --> - zip4jFile = null, - zip4jEntry = null, - // SY <-- ) } catch (e: Exception) { logcat(LogPriority.ERROR, e) { "Failed to split downloaded image" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt index 52ca44179..38ffb1ace 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt @@ -389,7 +389,6 @@ class ReaderViewModel @JvmOverloads constructor( context = context, downloadManager = downloadManager, downloadProvider = downloadProvider, - tempFileManager = tempFileManager, manga = manga, source = source, /* SY --> */ sourceManager = sourceManager, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt index 0778e75b8..c05563f63 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt @@ -10,7 +10,6 @@ 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 tachiyomi.core.common.i18n.stringResource -import tachiyomi.core.common.storage.UniFileTempFileManager import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.system.logcat import tachiyomi.domain.manga.model.Manga @@ -28,7 +27,6 @@ class ChapterLoader( private val context: Context, private val downloadManager: DownloadManager, private val downloadProvider: DownloadProvider, - private val tempFileManager: UniFileTempFileManager, private val manga: Manga, private val source: Source, // SY --> @@ -121,36 +119,39 @@ class ChapterLoader( source = source, downloadManager = downloadManager, downloadProvider = downloadProvider, - tempFileManager = tempFileManager, ) source is HttpSource -> HttpPageLoader(chapter, source) source is LocalSource -> source.getFormat(chapter.chapter).let { format -> when (format) { is Format.Directory -> DirectoryPageLoader(format.file) - is Format.Zip -> ZipPageLoader(tempFileManager.createTempFile(format.file)) + is Format.Zip -> ZipPageLoader(format.file, context) is Format.Rar -> try { - RarPageLoader(tempFileManager.createTempFile(format.file)) + RarPageLoader(format.file) } catch (e: UnsupportedRarV5Exception) { error(context.stringResource(MR.strings.loader_rar5_error)) } - is Format.Epub -> EpubPageLoader(tempFileManager.createTempFile(format.file)) + is Format.Epub -> EpubPageLoader(format.file, context) } } else -> error(context.stringResource(MR.strings.loader_not_implemented_error)) } } // SY <-- - isDownloaded -> DownloadPageLoader(chapter, manga, source, downloadManager, downloadProvider, tempFileManager) + isDownloaded -> DownloadPageLoader(chapter, manga, source, downloadManager, downloadProvider) source is LocalSource -> source.getFormat(chapter.chapter).let { format -> when (format) { is Format.Directory -> DirectoryPageLoader(format.file) - is Format.Zip -> ZipPageLoader(tempFileManager.createTempFile(format.file)) + // SY --> + is Format.Zip -> ZipPageLoader(format.file, context) is Format.Rar -> try { - RarPageLoader(tempFileManager.createTempFile(format.file)) + RarPageLoader(format.file) + // SY <-- } catch (e: UnsupportedRarV5Exception) { error(context.stringResource(MR.strings.loader_rar5_error)) } - is Format.Epub -> EpubPageLoader(tempFileManager.createTempFile(format.file)) + // SY --> + is Format.Epub -> EpubPageLoader(format.file, context) + // SY <-- } } source is HttpSource -> HttpPageLoader(chapter, source) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt index d0af290f2..ff70fec7f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt @@ -10,7 +10,6 @@ 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 tachiyomi.core.common.storage.UniFileTempFileManager import tachiyomi.domain.manga.model.Manga import uy.kohesive.injekt.injectLazy @@ -23,7 +22,6 @@ internal class DownloadPageLoader( private val source: Source, private val downloadManager: DownloadManager, private val downloadProvider: DownloadProvider, - private val tempFileManager: UniFileTempFileManager, ) : PageLoader() { private val context: Application by injectLazy() @@ -48,7 +46,9 @@ internal class DownloadPageLoader( } private suspend fun getPagesFromArchive(file: UniFile): List { - val loader = ZipPageLoader(tempFileManager.createTempFile(file)).also { zipPageLoader = it } + // SY --> + val loader = ZipPageLoader(file, context).also { zipPageLoader = it } + // SY <-- return loader.getPages() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt index 324af51bf..3a4d7388c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt @@ -1,16 +1,19 @@ 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 java.io.File /** * Loader used to load a chapter from a .epub file. */ -internal class EpubPageLoader(file: File) : PageLoader() { +// SY --> +internal class EpubPageLoader(file: UniFile, context: Context) : PageLoader() { - private val epub = EpubFile(file) + private val epub = EpubFile(file, context) + // SY <-- override var isLocal: Boolean = true diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt index 9ca277f78..04c357a0e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt @@ -1,6 +1,7 @@ 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 @@ -8,6 +9,14 @@ 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 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 tachiyomi.core.common.storage.UniFileTempFileManager import tachiyomi.core.common.util.system.ImageUtil import uy.kohesive.injekt.injectLazy import java.io.File @@ -19,11 +28,17 @@ import java.util.concurrent.Executors /** * Loader used to load a chapter from a .rar or .cbr file. */ -internal class RarPageLoader(file: File) : PageLoader() { - - private val rar = Archive(file) +internal class RarPageLoader(file: UniFile) : 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 context: Application by injectLazy() private val readerPreferences: ReaderPreferences by injectLazy() private val tmpDir = File(context.externalCacheDir, "reader_${file.hashCode()}").also { @@ -31,20 +46,21 @@ internal class RarPageLoader(file: File) : PageLoader() { } init { - if (readerPreferences.cacheArchiveMangaOnDisk().get()) { + if (readerPreferences.archiveReaderMode().get() == ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK) { tmpDir.mkdirs() - Archive(file).use { rar -> - rar.fileHeaders.asSequence() - .filterNot { it.isDirectory } - .forEach { header -> - val pageOutputStream = File(tmpDir, header.fileName.substringAfterLast("/")) - .also { it.createNewFile() } - .outputStream() - getStream(header).use { - it.copyTo(pageOutputStream) + 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) + } } - } - } + } } } // SY <-- @@ -58,16 +74,37 @@ internal class RarPageLoader(file: File) : PageLoader() { override suspend fun getPages(): List { // SY --> - if (readerPreferences.cacheArchiveMangaOnDisk().get()) { + 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 -> + // SY --> + val imageBytesDeferred: Deferred? = + when (readerPreferences.archiveReaderMode().get()) { + ReaderPreferences.ArchiveReaderMode.LOAD_INTO_MEMORY -> { + CoroutineScope(Dispatchers.IO).async { + mutex.withLock { + getStream(header).buffered().use { stream -> + stream.readBytes() + } + } + } + } + + else -> null + } + + val imageBytes by lazy { runBlocking { imageBytesDeferred?.await() } } + // SY <-- ReaderPage(i).apply { - stream = { getStream(header) } + // SY --> + stream = { imageBytes?.copyOf()?.inputStream() ?: getStream(header) } + // SY <-- status = Page.State.READY } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt index 6b5b6ec01..049018ffb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt @@ -1,6 +1,6 @@ package eu.kanade.tachiyomi.ui.reader.loader -import android.app.Application +import android.content.Context import android.os.Build import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.source.model.Page @@ -8,107 +8,155 @@ 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.charset.StandardCharsets -import java.util.zip.ZipFile +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: File) : PageLoader() { +internal class ZipPageLoader(file: UniFile, context: Context) : PageLoader() { // SY --> - private val context: Application by injectLazy() + 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 zip4j: Zip4jFile = Zip4jFile(file) - private val zip: ZipFile? = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - if (!zip4j.isEncrypted) ZipFile(file, StandardCharsets.ISO_8859_1) else null + + private val apacheZip: ZipFile? = if (!file.isEncryptedZip() && Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { + ZipFile(channel) + } else { + null + } + + private val tmpFile = + if ( + apacheZip == null && + readerPreferences.archiveReaderMode().get() != ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK + ) { + tempFileManager.createTempFile(file) } else { - if (!zip4j.isEncrypted) ZipFile(file) else null + null + } + + private val zip4j = + if (apacheZip == null && tmpFile != null) { + Zip4jFile(tmpFile) + } else { + null } init { - Zip4jFile(file).use { zip -> - if (zip.isEncrypted) { - if (!CbzCrypto.checkCbzPassword(zip, CbzCrypto.getDecryptedPasswordCbz())) { - this.recycle() - throw IllegalStateException(context.stringResource(SYMR.strings.wrong_cbz_archive_password)) - } - zip4j.setPassword(CbzCrypto.getDecryptedPasswordCbz()) - if (readerPreferences.cacheArchiveMangaOnDisk().get()) { - unzip() - } - } else { - if (readerPreferences.cacheArchiveMangaOnDisk().get()) { - unzip() - } + 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() - zip?.close() + apacheZip?.close() // SY --> - zip4j.close() + zip4j?.close() tmpDir.deleteRecursively() } - private fun unzip() { - tmpDir.mkdirs() - zip4j.fileHeaders.asSequence() - .filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { zip4j.getInputStream(it) } } - .forEach { entry -> - zip4j.extractFile(entry, tmpDir.absolutePath) - } - } override var isLocal: Boolean = true override suspend fun getPages(): List { - if (readerPreferences.cacheArchiveMangaOnDisk().get()) { + if (readerPreferences.archiveReaderMode().get() == ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK) { return DirectoryPageLoader(UniFile.fromFile(tmpDir)!!).getPages() } - - if (zip == null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - zip4j.charset = StandardCharsets.ISO_8859_1 - } - - 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 -> - ReaderPage(i).apply { - stream = { zip4j.getInputStream(entry) } - status = Page.State.READY - zip4jFile = zip4j - zip4jEntry = entry - } - }.toList() + return if (apacheZip == null) { + loadZip4j() } else { - // SY <-- - 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 -> - ReaderPage(i).apply { - stream = { zip.getInputStream(entry) } - status = Page.State.READY - } - }.toList() + loadApacheZip(apacheZip) } } + private fun loadZip4j(): List { + 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? = + 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 { + 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? = + 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 */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt index 20b99d9cb..0a6f2d414 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/model/ReaderPage.kt @@ -1,8 +1,6 @@ package eu.kanade.tachiyomi.ui.reader.model import eu.kanade.tachiyomi.source.model.Page -import net.lingala.zip4j.ZipFile -import net.lingala.zip4j.model.FileHeader import java.io.InputStream open class ReaderPage( @@ -10,9 +8,6 @@ open class ReaderPage( url: String = "", imageUrl: String? = null, // SY --> - /** zip4j inputStreams do not support mark() and release(), so they must be passed to ImageUtil */ - var zip4jFile: ZipFile? = null, - var zip4jEntry: FileHeader? = null, /** Value to check if this page is used to as if it was too wide */ var shiftedPage: Boolean = false, /** Value to check if a page is can be doubled up, but can't because the next page is too wide */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt index 9203ed1b0..149027acc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt @@ -180,9 +180,9 @@ class ReaderPreferences( fun centerMarginType() = preferenceStore.getInt("center_margin_type", PagerConfig.CenterMarginType.NONE) - fun cacheArchiveMangaOnDisk() = preferenceStore.getBoolean("cache_archive_manga_on_disk", false) + fun archiveReaderMode() = preferenceStore.getInt("archive_reader_mode", ArchiveReaderMode.LOAD_FROM_FILE) - fun markReadDupe() = preferenceStore.getBoolean("mark_read_dupe", false) + fun markReadDupe() = preferenceStore.getBoolean("mark_read_dupe", false) // SY <-- enum class TappingInvertMode( @@ -203,6 +203,12 @@ class ReaderPreferences( LOWEST(47), } + object ArchiveReaderMode { + const val LOAD_FROM_FILE = 0 + const val LOAD_INTO_MEMORY = 1 + const val CACHE_TO_DISK = 2 + } + companion object { const val WEBTOON_PADDING_MIN = 0 const val WEBTOON_PADDING_MAX = 25 @@ -264,6 +270,12 @@ class ReaderPreferences( SYMR.strings.center_margin_wide_page, SYMR.strings.center_margin_double_and_wide_page, ) + + val archiveModeTypes = listOf( + SYMR.strings.archive_mode_load_from_file, + SYMR.strings.archive_mode_load_into_memory, + SYMR.strings.archive_mode_cache_to_disk + ) // SY <-- } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 9cb629736..4f5636779 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -230,13 +230,7 @@ class PagerPageHolder( return splitInHalf(imageStream) } - val isDoublePage = ImageUtil.isWideImage( - imageStream, - // SY --> - page.zip4jFile, - page.zip4jEntry, - // SY <-- - ) + val isDoublePage = ImageUtil.isWideImage(imageStream) if (!isDoublePage) { return imageStream } @@ -247,13 +241,7 @@ class PagerPageHolder( } private fun rotateDualPage(imageStream: BufferedInputStream): InputStream { - val isDoublePage = ImageUtil.isWideImage( - imageStream, - // SY --> - page.zip4jFile, - page.zip4jEntry, - // SY <-- - ) + val isDoublePage = ImageUtil.isWideImage(imageStream) return if (isDoublePage) { val rotation = if (viewer.config.dualPageRotateToFitInvert) -90f else 90f ImageUtil.rotateImage(imageStream, rotation) @@ -267,13 +255,7 @@ class PagerPageHolder( if (imageStream2 == null) { return if (imageStream is BufferedInputStream && !ImageUtil.isAnimatedAndSupported(imageStream) && - ImageUtil.isWideImage( - imageStream, - // SY --> - page.zip4jFile, - page.zip4jEntry, - // SY <-- - ) && + ImageUtil.isWideImage(imageStream) && viewer.config.centerMarginType and PagerConfig.CenterMarginType.WIDE_PAGE_CENTER_MARGIN > 0 && !viewer.config.imageCropBorders ) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt index 2dcf62723..a192f7853 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt @@ -224,13 +224,7 @@ class WebtoonPageHolder( } if (viewer.config.dualPageSplit) { - val isDoublePage = ImageUtil.isWideImage( - imageStream, - // SY --> - page?.zip4jFile, - page?.zip4jEntry, - // SY <-- - ) + val isDoublePage = ImageUtil.isWideImage(imageStream) if (isDoublePage) { val upperSide = if (viewer.config.dualPageInvert) ImageUtil.Side.LEFT else ImageUtil.Side.RIGHT return ImageUtil.splitAndMerge(imageStream, upperSide) @@ -241,13 +235,7 @@ class WebtoonPageHolder( } private fun rotateDualPage(imageStream: BufferedInputStream): InputStream { - val isDoublePage = ImageUtil.isWideImage( - imageStream, - // SY --> - page?.zip4jFile, - page?.zip4jEntry, - // SY <-- - ) + val isDoublePage = ImageUtil.isWideImage(imageStream) return if (isDoublePage) { val rotation = if (viewer.config.dualPageRotateToFitInvert) -90f else 90f ImageUtil.rotateImage(imageStream, rotation) diff --git a/app/src/main/java/exh/EXHMigrations.kt b/app/src/main/java/exh/EXHMigrations.kt index fe3e513cc..f1e57fbb3 100644 --- a/app/src/main/java/exh/EXHMigrations.kt +++ b/app/src/main/java/exh/EXHMigrations.kt @@ -656,6 +656,12 @@ object EXHMigrations { remove(Preference.appStateKey("trusted_signatures")) } } + if (oldVersion under 66) { + val cacheImagesToDisk = prefs.getBoolean("cache_archive_manga_on_disk", false) + if (cacheImagesToDisk) { + readerPreferences.archiveReaderMode().set(ReaderPreferences.ArchiveReaderMode.CACHE_TO_DISK) + } + } if (oldVersion under 66) { if (prefs.getBoolean(Preference.privateKey("encrypt_database"), false)) { diff --git a/app/src/main/java/exh/ui/intercept/InterceptActivity.kt b/app/src/main/java/exh/ui/intercept/InterceptActivity.kt index ba6c2d145..7effc5d81 100644 --- a/app/src/main/java/exh/ui/intercept/InterceptActivity.kt +++ b/app/src/main/java/exh/ui/intercept/InterceptActivity.kt @@ -187,7 +187,6 @@ class InterceptActivity : BaseActivity() { lifecycleScope.launchIO { loadGalleryEnd(gallery, sources[index]) } - } .show() } else { diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index 1845cae53..f185da8d9 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -2,10 +2,188 @@ + ArgumentListWrapping:AnnotatedString.kt$(SpanStyle(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic), start, end) + ArgumentListWrapping:AnnotatedString.kt$(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic) + ArgumentListWrapping:ApiMangaParser.kt$ApiMangaParser$("Content Rating", it.capitalize(Locale.US), MangaDexSearchMetadata.TAG_TYPE_DEFAULT) + ArgumentListWrapping:ApiMangaParser.kt$ApiMangaParser$("Demographic", it.capitalize(Locale.US), MangaDexSearchMetadata.TAG_TYPE_DEFAULT) + ArgumentListWrapping:ApiMangaParser.kt$ApiMangaParser$(Locale.US) + ArgumentListWrapping:BatchAddScreen.kt$BatchAddScreen$(SYMR.strings.eh_batch_add_adding_galleries) + ArgumentListWrapping:BatchAddScreen.kt$BatchAddScreen$(SYMR.strings.eh_batch_add_title) + ArgumentListWrapping:BatchAddScreen.kt$BatchAddScreen$(text = stringResource(SYMR.strings.eh_batch_add_adding_galleries), style = MaterialTheme.typography.titleLarge) + ArgumentListWrapping:BatchAddScreen.kt$BatchAddScreen$(text = stringResource(SYMR.strings.eh_batch_add_title), style = MaterialTheme.typography.titleLarge) + ArgumentListWrapping:BiometricTimesScreen.kt$BiometricTimesScreen$(SYMR.strings.delete_time_range_confirmation, dialog.timeRange.formattedString) + ArgumentListWrapping:BiometricTimesScreen.kt$BiometricTimesScreen$(context) + ArgumentListWrapping:BiometricTimesScreen.kt$BiometricTimesScreen$(if (startTime == null) SYMR.strings.biometric_lock_start_time.getString(context) else SYMR.strings.biometric_lock_end_time.getString(context)) + ArgumentListWrapping:ChapterLoader.kt$ChapterLoader$(chapter, manga, source, downloadManager, downloadProvider, tempFileManager) + ArgumentListWrapping:DataSaver.kt$BandwidthHeroDataSaver$(imageUrl) + ArgumentListWrapping:DataSaver.kt$WsrvNlDataSaver$(imageUrl) + ArgumentListWrapping:DownloadPageLoader.kt$DownloadPageLoader$(dbChapter.name, dbChapter.scanlator, /* SY --> */ manga.ogTitle /* SY <-- */, source) + ArgumentListWrapping:EHConfigurator.kt$EHConfigurator$(SYMR.strings.eh_settings_out_of_slots_error, source.name) + ArgumentListWrapping:EHConfigurator.kt$EHConfigurator$(context.stringResource(SYMR.strings.eh_settings_out_of_slots_error, source.name)) + ArgumentListWrapping:EditMergedSettingsDialog.kt$(factoryContext, binding, mergedData.manga.values.toList(), mergedData.references) + ArgumentListWrapping:EnhancedFilePrinter.kt$EnhancedFilePrinter$(!(newFileName == null || newFileName.trim { it <= ' ' }.isEmpty())) + ArgumentListWrapping:ExtensionManager.kt$ExtensionManager$("Removing blacklisted extension: (name: %s, pkgName: %s)!", extension.name, extension.pkgName) + ArgumentListWrapping:FavoritesSyncHelper.kt$FavoritesSyncHelper$(SYMR.strings.favorites_sync_gallery_multiple_categories_error, manga.id) + ArgumentListWrapping:FavoritesSyncHelper.kt$FavoritesSyncHelper$(context.stringResource(SYMR.strings.favorites_sync_gallery_multiple_categories_error, manga.id)) + ArgumentListWrapping:FavoritesSyncHelper.kt$FavoritesSyncStatus.BadLibraryState.MangaInMultipleCategories$( SYMR.strings.favorites_sync_gallery_in_multiple_categories, manga.title, categories.joinToString { it.name }, ) + ArgumentListWrapping:GalleryAdder.kt$GalleryAddEvent.Fail.UnknownSource$(SYMR.strings.batch_add_unknown_source_log_message, galleryUrl) + ArgumentListWrapping:GalleryAdder.kt$GalleryAddEvent.Fail.UnknownType$(SYMR.strings.batch_add_unknown_type_log_message, galleryUrl) + ArgumentListWrapping:GalleryAdder.kt$GalleryAdder$(SYMR.strings.gallery_adder_chapter_fetch_error, url) + ArgumentListWrapping:GalleryAdder.kt$GalleryAdder$(SYMR.strings.gallery_adder_could_not_identify_chapter, url) + ArgumentListWrapping:GalleryAdder.kt$GalleryAdder$(SYMR.strings.gallery_adder_importing_gallery, url, fav.toString(), forceSource?.toString().orEmpty()) + ArgumentListWrapping:GalleryAdder.kt$GalleryAdder$(context.stringResource(SYMR.strings.gallery_adder_importing_gallery, url, fav.toString(), forceSource?.toString().orEmpty())) + ArgumentListWrapping:GalleryAdder.kt$GalleryAdder$(url, context.stringResource(SYMR.strings.gallery_adder_chapter_fetch_error, url)) + ArgumentListWrapping:GalleryAdder.kt$GalleryAdder$(url, context.stringResource(SYMR.strings.gallery_adder_could_not_identify_chapter, url)) + ArgumentListWrapping:LibraryScreenModel.kt$LibraryScreenModel$("\\(.*?\\)".toRegex(), "") + ArgumentListWrapping:LibraryScreenModel.kt$LibraryScreenModel$("\\[.*?]".toRegex(), "") + ArgumentListWrapping:LibraryScreenModel.kt$LibraryScreenModel$("\\{.*?\\}".toRegex(), "") + ArgumentListWrapping:LibraryScreenModel.kt$LibraryScreenModel$(MR.strings.publishing_finished) + ArgumentListWrapping:LibraryScreenModel.kt$LibraryScreenModel$(it.source) + ArgumentListWrapping:LibraryTab.kt$LibraryTab$(state.categories.lastIndex) + ArgumentListWrapping:LibraryTab.kt$LibraryTab$(state.categories[screenModel.activeCategoryIndex.coerceAtMost(state.categories.lastIndex)]) + ArgumentListWrapping:LibraryUpdateJob.kt$LibraryUpdateJob$( listOf(Manga.create().copy(ogTitle = networkManga.title)), count, size, ) + ArgumentListWrapping:LibraryUpdateJob.kt$LibraryUpdateJob$(manga.id) + ArgumentListWrapping:LocalSource.kt$LocalSource$(COMIC_INFO_FILE) + ArgumentListWrapping:LocalSource.kt$LocalSource$(it, manga) + ArgumentListWrapping:MangaScreen.kt$MangaScreen$(context, navigator, screenModel.source?.getMainSource(), successState.manga) + ArgumentListWrapping:MangaScreen.kt$MangaScreen$(navigator, context, successState.manga, screenModel::smartSearchMerge) + ArgumentListWrapping:MangaScreenModel.kt$MangaScreenModel$(getTracks.await(mangaId).first { it.trackerId == trackerManager.mdList.id }, trackerManager.mdList) + ArgumentListWrapping:MangaScreenModel.kt$MangaScreenModel$(manga.source, chapters) + ArgumentListWrapping:MangaScreenModel.kt$MangaScreenModel$(mangaId) + ArgumentListWrapping:MangaScreenModel.kt$MangaScreenModel$(mangaId, applyScanlatorFilter = true) + ArgumentListWrapping:MigrationListScreenModel.kt$MigrationListScreenModel$(localManga.toSManga(), throttleManager::throttle) + ArgumentListWrapping:ReaderActivity.kt$ReaderActivity$(SYMR.strings.share_pages_info, manga.title, chapter.name, if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) "${page.number}-${page.number + 1}" else "${page.number + 1}-${page.number}") + ArgumentListWrapping:ReaderPreferences.kt$ReaderPreferences$("reader_bottom_buttons", ReaderBottomButton.BUTTONS_DEFAULTS) + ArgumentListWrapping:SimilarHandler.kt$SimilarHandler$( mangaList, false, List(mangaList.size) { MangaDexSearchMetadata().also { it.relation = MangaDexRelation.SIMILAR } }, ) + ArgumentListWrapping:SourcesScreenModel.kt$SourcesScreenModel$(CATEGORY_KEY_PREFIX) + ArgumentListWrapping:SourcesScreenModel.kt$SourcesScreenModel$(it.key.removePrefix(CATEGORY_KEY_PREFIX), it.value.firstOrNull()?.category != null) + CommentSpacing:ChapterCache.kt$ChapterCache$//S Y <-- + CommentSpacing:LibraryUpdateJob.kt$LibraryUpdateJob$//SY <-- + CommentWrapping:BackupCreator.kt$BackupCreator$/* SY --> */ + CommentWrapping:BackupRestorer.kt$BackupRestorer$/* SY --> */ + CommentWrapping:BackupRestorer.kt$BackupRestorer$/* SY <-- */ + CommentWrapping:BrowseSourceComfortableGrid.kt$/* SY --> */ + CommentWrapping:BrowseSourceComfortableGrid.kt$/* SY <-- */ + CommentWrapping:BrowseSourceCompactGrid.kt$/* SY --> */ + CommentWrapping:BrowseSourceCompactGrid.kt$/* SY <-- */ + CommentWrapping:BrowseSourceEHentaiList.kt$/* SY --> */ + CommentWrapping:BrowseSourceEHentaiList.kt$/* SY <-- */ + CommentWrapping:BrowseSourceList.kt$/* SY --> */ + CommentWrapping:BrowseSourceList.kt$/* SY <-- */ + CommentWrapping:BrowseSourceScreen.kt$/* SY --> */ + CommentWrapping:BrowseSourceScreen.kt$/* SY <-- */ + CommentWrapping:BrowseSourceScreen.kt$BrowseSourceScreen$/* SY --> */ + CommentWrapping:BrowseSourceScreen.kt$BrowseSourceScreen$/* SY <-- */ + CommentWrapping:BuildConfig.kt$/* SY --> */ + CommentWrapping:BuildConfig.kt$/* SY <-- */ + CommentWrapping:ChapterFilter.kt$/* SY --> */ + CommentWrapping:ChapterFilter.kt$/* SY <-- */ + CommentWrapping:ChapterFilterDownloaded.kt$/* SY --> */ + CommentWrapping:ChapterGetNextUnread.kt$/* SY --> */ + CommentWrapping:ChapterGetNextUnread.kt$/* SY <-- */ + CommentWrapping:ChapterLoader.kt$ChapterLoader$/* --> EH */ + CommentWrapping:ChapterLoader.kt$ChapterLoader$/* SY --> */ + CommentWrapping:ChapterLoader.kt$ChapterLoader$/* SY <-- */ + CommentWrapping:ClearDatabaseScreen.kt$ClearDatabaseScreenModel$/* SY --> */ + CommentWrapping:ClearDatabaseScreen.kt$ClearDatabaseScreenModel$/* SY <-- */ + CommentWrapping:CollapsibleBox.kt$/* SY --> */ + CommentWrapping:CollapsibleBox.kt$/* SY <-- */ + CommentWrapping:CreateCategoryWithName.kt$CreateCategoryWithName$/* SY --> */ + CommentWrapping:CreateCategoryWithName.kt$CreateCategoryWithName$/* SY <-- */ + CommentWrapping:DownloadCache.kt$DownloadCache$/* SY --> */ + CommentWrapping:DownloadCache.kt$DownloadCache$/* SY <-- */ + CommentWrapping:DownloadManager.kt$DownloadManager$/* SY --> */ + CommentWrapping:DownloadManager.kt$DownloadManager$/* SY <-- */ + CommentWrapping:DownloadPageLoader.kt$DownloadPageLoader$/* SY --> */ + CommentWrapping:DownloadPageLoader.kt$DownloadPageLoader$/* SY <-- */ + CommentWrapping:DownloadPendingDeleter.kt$DownloadPendingDeleter$/* SY --> */ + CommentWrapping:DownloadPendingDeleter.kt$DownloadPendingDeleter$/* SY <-- */ + CommentWrapping:DownloadProvider.kt$DownloadProvider$/* SY --> */ + CommentWrapping:DownloadProvider.kt$DownloadProvider$/* SY <-- */ + CommentWrapping:Downloader.kt$Downloader$/* SY --> */ + CommentWrapping:Downloader.kt$Downloader$/* SY <-- */ + CommentWrapping:EXHMigrations.kt$EXHMigrations$/* ALPHABETICAL */ + CommentWrapping:GetExtensionsByType.kt$GetExtensionsByType$/* SY --> */ + CommentWrapping:GetExtensionsByType.kt$GetExtensionsByType$/* SY <-- */ + CommentWrapping:HistoryScreenModelStateProvider.kt$HistoryScreenModelStateProvider.HistoryUiModelExamples$/* SY --> */ + CommentWrapping:HistoryScreenModelStateProvider.kt$HistoryScreenModelStateProvider.HistoryUiModelExamples$/* SY <-- */ + CommentWrapping:HomeScreen.kt$HomeScreen$/* SY --> */ + CommentWrapping:HomeScreen.kt$HomeScreen$/* SY <-- */ + CommentWrapping:HttpPageLoader.kt$HttpPageLoader$/* SY --> */ + CommentWrapping:HttpSource.kt$HttpSource$/* SY <-- */ + CommentWrapping:LibraryScreenModel.kt$LibraryScreenModel$/* SY --> */ + CommentWrapping:LibraryScreenModel.kt$LibraryScreenModel$/* SY <-- */ + CommentWrapping:LibrarySortMode.kt$LibrarySort.Companion$/* SY -->*/ + CommentWrapping:LibrarySortMode.kt$LibrarySort.Companion$/* SY <--*/ + CommentWrapping:LocalSource.kt$LocalSource$/* SY --> */ + CommentWrapping:LocalSource.kt$LocalSource$/* SY <-- */ + CommentWrapping:MangaBackupCreator.kt$/* SY --> */ + CommentWrapping:MangaBackupCreator.kt$/* SY <-- */ + CommentWrapping:MangaBackupCreator.kt$MangaBackupCreator$/* SY <-- */ + CommentWrapping:MangaBottomActionMenu.kt$/* SY --> */ + CommentWrapping:MangaBottomActionMenu.kt$/* SY <-- */ + CommentWrapping:MangaChapterListItem.kt$/* SY --> */ + CommentWrapping:MangaChapterListItem.kt$/* SY <-- */ + CommentWrapping:MangaScreen.kt$/* SY --> */ + CommentWrapping:MangaScreen.kt$/* SY <-- */ + CommentWrapping:MangaScreenModel.kt$MangaScreenModel$/* SY --> */ + CommentWrapping:MangaScreenModel.kt$MangaScreenModel$/* SY <-- */ + CommentWrapping:MangasPage.kt$MangasPage$/* SY <-- */ + CommentWrapping:NetworkHelper.kt$NetworkHelper$/* SY <-- */ + CommentWrapping:NetworkToLocalManga.kt$NetworkToLocalManga$/* SY --> */ + CommentWrapping:NetworkToLocalManga.kt$NetworkToLocalManga$/* SY <-- */ + CommentWrapping:Page.kt$Page$/* SY <-- */ + CommentWrapping:PagePreviewScreen.kt$/* TODO support unknown pageCount || state.hasNextPage*/ + CommentWrapping:ReaderActivity.kt$ReaderActivity$/* SY --> */ + CommentWrapping:ReaderActivity.kt$ReaderActivity$/* SY <-- */ + CommentWrapping:ReaderActivity.kt$ReaderActivity$/*else if (page.status == Page.LOAD_PAGE || page.status == Page.DOWNLOAD_IMAGE) { // Do nothing }*/ + CommentWrapping:ReaderActivity.kt$ReaderActivity.Companion$/* SY --> */ + CommentWrapping:ReaderActivity.kt$ReaderActivity.Companion$/* SY <-- */ + CommentWrapping:ReaderAppBars.kt$/*SY --> */ + CommentWrapping:ReaderAppBars.kt$/*SY <-- */ + CommentWrapping:ReaderTransitionView.kt$ReaderTransitionView$/* SY --> */ + CommentWrapping:ReaderTransitionView.kt$ReaderTransitionView$/* SY <-- */ + CommentWrapping:ReaderViewModel.kt$ReaderViewModel$/* SY --> */ + CommentWrapping:ReaderViewModel.kt$ReaderViewModel$/* SY <-- */ + CommentWrapping:ReaderViewModel.kt$ReaderViewModel.Dialog.PageActions$/* SY --> */ + CommentWrapping:ReaderViewModel.kt$ReaderViewModel.Dialog.PageActions$/* SY <-- */ + CommentWrapping:ReaderViewModel.kt$ReaderViewModel.Event.ShareImage$/* SY --> */ + CommentWrapping:ReaderViewModel.kt$ReaderViewModel.Event.ShareImage$/* SY <-- */ + CommentWrapping:RestoreOptions.kt$RestoreOptions$/* SY --> */ + CommentWrapping:RestoreOptions.kt$RestoreOptions$/* SY <-- */ + CommentWrapping:SecureActivityDelegate.kt$SecureActivityDelegate.Companion$/* SY --> */ + CommentWrapping:SecureActivityDelegate.kt$SecureActivityDelegate.Companion$/* SY <-- */ + CommentWrapping:SourceFilterDialog.kt$/* SY --> */ + CommentWrapping:SourceFilterDialog.kt$/* SY <-- */ + CommentWrapping:SourcePagingSource.kt$SourcePagingSource$/*SY --> */ + CommentWrapping:SourcePagingSource.kt$SourcePagingSource$/*SY <-- */ + CommentWrapping:SourceRepository.kt$/*SY --> */ + CommentWrapping:SourceRepository.kt$/*SY <-- */ + CommentWrapping:SourcesScreen.kt$/* SY --> */ + CommentWrapping:SourcesScreen.kt$/* SY <-- */ + CommentWrapping:SyncChaptersWithSource.kt$SyncChaptersWithSource$/* SY --> */ + CommentWrapping:SyncChaptersWithSource.kt$SyncChaptersWithSource$/* SY <-- */ + CommentWrapping:TrackChapter.kt$TrackChapter$/* SY --> */ + CommentWrapping:TrackChapter.kt$TrackChapter$/* SY <-- */ + CommentWrapping:UpdatesUiItem.kt$/* SY --> */ + CommentWrapping:UpdatesUiItem.kt$/* SY <-- */ + ComplexCondition:CustomMangaRepositoryImpl.kt$CustomMangaRepositoryImpl$mangaInfo.title == null && mangaInfo.author == null && mangaInfo.artist == null && mangaInfo.thumbnailUrl == null && mangaInfo.description == null && mangaInfo.genre == null && mangaInfo.status == null + ComplexCondition:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$(new.isNotEmpty() && manga.id == acceptedRoot.manga.id) || (hasNew && updatedManga.none { it.first.id == acceptedRoot.manga.id }) + ComplexCondition:LibraryUpdateJob.kt$LibraryUpdateJob$group == LibraryGroup.BY_DEFAULT || groupLibraryUpdateType == GroupLibraryMode.GLOBAL || (groupLibraryUpdateType == GroupLibraryMode.ALL_BUT_UNGROUPED && group == LibraryGroup.UNGROUPED) + ComplexCondition:MangaRestorer.kt$MangaRestorer$customTitle != null || customArtist != null || customAuthor != null || customThumbnailUrl != null || customDescription != null || customGenre != null || customStatus != 0 ComplexCondition:MangaScreenModel.kt$MangaScreenModel$(selectedItem.selected && selected) || (!selectedItem.selected && !selected) + ComplexCondition:PagerPageHolder.kt$PagerPageHolder$imageStream is BufferedInputStream && !ImageUtil.isAnimatedAndSupported(imageStream) && ImageUtil.isWideImage(imageStream) && viewer.config.centerMarginType and PagerConfig.CenterMarginType.WIDE_PAGE_CENTER_MARGIN > 0 && !viewer.config.imageCropBorders + ComplexCondition:PagerViewerAdapter.kt$PagerViewerAdapter$items[itemIndex]?.fullPage == true && itemIndex > 0 && items[itemIndex - 1] != null && (itemIndex - 1) % 2 == 0 + ComplexCondition:ReaderActivity.kt$ReaderActivity$readerPreferences.useAutoWebtoon().get() && (manga?.readingMode?.toInt() ?: ReadingMode.DEFAULT.flagValue) == ReadingMode.DEFAULT.flagValue && defaultReaderType != null && defaultReaderType == ReadingMode.WEBTOON.flagValue ComplexCondition:ReaderNavigationOverlayView.kt$ReaderNavigationOverlayView$isVisible || (!showOnStart && firstLaunch) || navigation is DisabledNavigation ComplexCondition:ReaderPageImageView.kt$ReaderPageImageView$config != null && config!!.landscapeZoom && config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE && sWidth > sHeight && scale == minScale + ComplexCondition:SearchEngine.kt$SearchEngine$char == '-' && !inQuotes && (queuedRawText.isBlank() || queuedRawText.last() == ' ') + ComplexCondition:SourceTagsUtil.kt$SourceTagsUtil$sourceId == EXH_SOURCE_ID || sourceId == EH_SOURCE_ID || sourceId in nHentaiSourceIds || sourceId in mangaDexSourceIds || sourceId == PURURIN_SOURCE_ID || sourceId == TSUMINO_SOURCE_ID + ComplexCondition:TrackChapter.kt$TrackChapter$service == null || !service.isLoggedIn || chapterNumber <= track.lastChapterRead /* SY --> */ || (service is MdList && track.status == FollowStatus.UNFOLLOWED.long) + ComposableParamOrder:AutoCompleteItem.kt$AutoCompleteTextField ComposableParamOrder:ChapterSettingsDialog.kt$ChapterSettingsDialog + ComposableParamOrder:FeedScreen.kt$RadioSelector + ComposableParamOrder:GlobalSearchResultItems.kt$GlobalSearchResultItem ComposableParamOrder:LazyLibraryGrid.kt$LazyLibraryGrid ComposableParamOrder:SwitchPreferenceWidget.kt$SwitchPreferenceWidget ComposableParamOrder:TrackingPreferenceWidget.kt$TrackingPreferenceWidget @@ -50,45 +228,94 @@ ConstructorParameterNaming:MyAnimeListModels.kt$OAuth$val expires_in: Long ConstructorParameterNaming:MyAnimeListModels.kt$OAuth$val refresh_token: String ConstructorParameterNaming:MyAnimeListModels.kt$OAuth$val token_type: String + ConstructorParameterNaming:PagePreviewSource.kt$PagePreviewInfo$@Transient private val _progress: MutableStateFlow<Int> = MutableStateFlow(-1) ConstructorParameterNaming:ShikimoriModels.kt$OAuth$val access_token: String ConstructorParameterNaming:ShikimoriModels.kt$OAuth$val created_at: Long ConstructorParameterNaming:ShikimoriModels.kt$OAuth$val expires_in: Long ConstructorParameterNaming:ShikimoriModels.kt$OAuth$val refresh_token: String? ConstructorParameterNaming:ShikimoriModels.kt$OAuth$val token_type: String CyclomaticComplexMethod:AnilistModels.kt$fun DomainTrack.toAnilistScore(): String - CyclomaticComplexMethod:BrowseSourceScreen.kt$@Composable fun BrowseSourceContent( source: Source?, mangaList: LazyPagingItems<StateFlow<Manga>>, columns: GridCells, displayMode: LibraryDisplayMode, snackbarHostState: SnackbarHostState, contentPadding: PaddingValues, onWebViewClick: () -> Unit, onHelpClick: () -> Unit, onLocalSourceHelpClick: () -> Unit, onMangaClick: (Manga) -> Unit, onMangaLongClick: (Manga) -> Unit, ) + CyclomaticComplexMethod:ApiMangaParser.kt$ApiMangaParser$fun parseIntoMetadata( metadata: MangaDexSearchMetadata, mangaDto: MangaDto, simpleChapters: List<String>, statistics: StatisticsMangaDto?, ) + CyclomaticComplexMethod:BottomReaderBar.kt$@Composable fun BottomReaderBar( // SY --> enabledButtons: ImmutableSet<String>, // SY <-- backgroundColor: Color, readingMode: ReadingMode, onClickReadingMode: () -> Unit, orientation: ReaderOrientation, onClickOrientation: () -> Unit, cropEnabled: Boolean, onClickCropBorder: () -> Unit, onClickSettings: () -> Unit, // SY --> currentReadingMode: ReadingMode, dualPageSplitEnabled: Boolean, doublePages: Boolean, onClickChapterList: () -> Unit, onClickWebView: (() -> Unit)?, onClickShare: (() -> Unit)?, onClickPageLayout: () -> Unit, onClickShiftPage: () -> Unit, // SY <-- ) + CyclomaticComplexMethod:BrowseSourceEHentaiList.kt$@Composable fun BrowseSourceEHentaiListItem( manga: Manga, // SY --> metadata: RaisedSearchMetadata?, // SY <-- onClick: () -> Unit = {}, onLongClick: () -> Unit = onClick, ) + CyclomaticComplexMethod:BrowseSourceScreen.kt$@Composable fun BrowseSourceContent( source: Source?, mangaList: LazyPagingItems<StateFlow</* SY --> */Pair<Manga, RaisedSearchMetadata?>/* SY <-- */>>, columns: GridCells, // SY --> ehentaiBrowseDisplayMode: Boolean, // SY <-- displayMode: LibraryDisplayMode, snackbarHostState: SnackbarHostState, contentPadding: PaddingValues, // SY --> onWebViewClick: (() -> Unit)?, onHelpClick: (() -> Unit)?, onLocalSourceHelpClick: (() -> Unit)?, // SY <-- onMangaClick: (Manga) -> Unit, onMangaLongClick: (Manga) -> Unit, ) CyclomaticComplexMethod:BrowseSourceScreen.kt$BrowseSourceScreen$@Composable override fun Content() CyclomaticComplexMethod:BrowseSourceScreenModel.kt$BrowseSourceScreenModel$fun searchGenre(genreName: String) CyclomaticComplexMethod:Button.kt$ButtonElevation$@Composable private fun animateElevation( enabled: Boolean, interactionSource: InteractionSource, ): State<Dp> + CyclomaticComplexMethod:ChapterLoader.kt$ChapterLoader$private fun getPageLoader(chapter: ReaderChapter): PageLoader + CyclomaticComplexMethod:Chip.kt$ChipElevation$@Composable private fun animateElevation( enabled: Boolean, interactionSource: InteractionSource, ): State<Dp> CyclomaticComplexMethod:DownloadCache.kt$DownloadCache$private fun renewCache() + CyclomaticComplexMethod:EHentai.kt$EHentai$override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request + CyclomaticComplexMethod:EHentai.kt$EHentai$override suspend fun parseIntoMetadata(metadata: EHentaiSearchMetadata, input: Document) + CyclomaticComplexMethod:EHentai.kt$EHentai$private fun extendedGenericMangaParse(doc: Document) + CyclomaticComplexMethod:EHentaiDescriptionAdapter.kt$@Composable fun EHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) + CyclomaticComplexMethod:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$private suspend fun startUpdating() + CyclomaticComplexMethod:EXHMigrations.kt$EXHMigrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, pagePreviewCache: PagePreviewCache, ): Boolean + CyclomaticComplexMethod:EditMangaDialog.kt$private fun onViewCreated(manga: Manga, context: Context, binding: EditMangaDialogBinding, scope: CoroutineScope) + CyclomaticComplexMethod:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter.HeaderViewHolder$fun bind() + CyclomaticComplexMethod:EhUConfigBuilder.kt$EhUConfigBuilder$fun build(hathPerks: EHHathPerksResponse): FormBody CyclomaticComplexMethod:ExtensionLoader.kt$ExtensionLoader$private fun loadExtension(context: Context, extensionInfo: ExtensionInfo): LoadResult CyclomaticComplexMethod:ExtensionsScreen.kt$@Composable private fun ExtensionContent( state: ExtensionsScreenModel.State, contentPadding: PaddingValues, onLongClickItem: (Extension) -> Unit, onClickItemCancel: (Extension) -> Unit, onOpenWebView: (Extension.Available) -> Unit, onInstallExtension: (Extension.Available) -> Unit, onUninstallExtension: (Extension) -> Unit, onUpdateExtension: (Extension.Installed) -> Unit, onTrustExtension: (Extension.Untrusted) -> Unit, onOpenExtension: (Extension.Installed) -> Unit, onClickUpdateAll: () -> Unit, ) CyclomaticComplexMethod:ExtensionsScreen.kt$@Composable private fun ExtensionItemContent( extension: Extension, installStep: InstallStep, modifier: Modifier = Modifier, ) + CyclomaticComplexMethod:FilterHandler.kt$FilterHandler$fun getQueryMap(filters: FilterList): Map<String, Any> + CyclomaticComplexMethod:FilterSerializer.kt$FilterSerializer$fun deserialize(filter: Filter<Any?>, json: JsonObject) + CyclomaticComplexMethod:GalleryAdder.kt$GalleryAdder$suspend fun addGallery( context: Context, url: String, fav: Boolean = false, forceSource: UrlImportableSource? = null, throttleFunc: suspend () -> Unit = {}, retry: Int = 1, ): GalleryAddEvent CyclomaticComplexMethod:GetSourcesWithFavoriteCount.kt$GetSourcesWithFavoriteCount$private fun sortFn( direction: SetMigrateSorting.Direction, sorting: SetMigrateSorting.Mode, ): java.util.Comparator<Pair<Source, Long>> CyclomaticComplexMethod:ImageUtil.kt$ImageUtil$fun chooseBackground(context: Context, imageStream: InputStream): Drawable - CyclomaticComplexMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun LibraryMap.applySort( // Map<MangaId, List<Track>> trackMap: Map<Long, List<Track>>, ): LibraryMap + CyclomaticComplexMethod:LewdMangaChecker.kt$private fun isHentaiSource(source: String): Boolean + CyclomaticComplexMethod:LibraryScreenModel.kt$LibraryScreenModel$fun getCategoryName( context: Context, category: Category?, groupType: Int, categoryName: String, ): String + CyclomaticComplexMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun LibraryMap.applySort( // Map<MangaId, List<Track>> trackMap: Map<Long, List<Track>>, /* SY --> */ groupSort: LibrarySort? = null, /* SY <-- */ ): LibraryMap + CyclomaticComplexMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun filterManga( queries: List<QueryComponent>, libraryManga: LibraryManga, tracks: List<Track>?, source: Source?, checkGenre: Boolean = true, searchTags: List<SearchTag>? = null, searchTitles: List<SearchTitle>? = null, loggedInTrackServices: Map<Long, TriState>, ): Boolean + CyclomaticComplexMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun getGroupedMangaItems( groupType: Int, libraryManga: List<LibraryItem>, ): LibraryMap CyclomaticComplexMethod:LibraryScreenModel.kt$LibraryScreenModel$private suspend fun LibraryMap.applyFilters( trackMap: Map<Long, List<Track>>, loggedInTrackers: Map<Long, TriState>, ): LibraryMap + CyclomaticComplexMethod:LibrarySortMode.kt$LibrarySort.Companion$fun deserialize(serialized: String): LibrarySort CyclomaticComplexMethod:LibraryTab.kt$LibraryTab$@Composable override fun Content() - CyclomaticComplexMethod:LibraryUpdateJob.kt$LibraryUpdateJob$private suspend fun addMangaToQueue(categoryId: Long) + CyclomaticComplexMethod:LibraryUpdateJob.kt$LibraryUpdateJob$private suspend fun addMangaToQueue(categoryId: Long, group: Int, groupExtra: String?) + CyclomaticComplexMethod:LibraryUpdateJob.kt$LibraryUpdateJob$private suspend fun updateChapterList() + CyclomaticComplexMethod:LocalFavoritesStorage.kt$LocalFavoritesStorage$private fun FavoriteEntry.urlEquals(other: FavoriteEntry) CyclomaticComplexMethod:LocalSource.kt$LocalSource$override suspend fun getMangaDetails(manga: SManga): SManga + CyclomaticComplexMethod:LocalSource.kt$LocalSource$override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage CyclomaticComplexMethod:LocalSource.kt$LocalSource$private fun updateCover(chapter: SChapter, manga: SManga): UniFile? CyclomaticComplexMethod:MainActivity.kt$MainActivity$override fun onCreate(savedInstanceState: Bundle?) CyclomaticComplexMethod:MainActivity.kt$MainActivity$private fun handleIntentAction(intent: Intent, navigator: Navigator): Boolean + CyclomaticComplexMethod:MangaBackupCreator.kt$MangaBackupCreator$private suspend fun backupManga(manga: Manga, options: BackupOptions): BackupManga + CyclomaticComplexMethod:MangaChapterListItem.kt$@Composable fun MangaChapterListItem( title: String, date: String?, readProgress: String?, scanlator: String?, // SY --> sourceName: String?, // SY <-- read: Boolean, bookmark: Boolean, selected: Boolean, downloadIndicatorEnabled: Boolean, downloadStateProvider: () -> Download.State, downloadProgressProvider: () -> Int, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onLongClick: () -> Unit, onClick: () -> Unit, onDownloadClick: ((ChapterDownloadAction) -> Unit)?, onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit, modifier: Modifier = Modifier, ) CyclomaticComplexMethod:MangaInfoHeader.kt$@Composable private fun ColumnScope.MangaContentInfo( title: String, doSearch: (query: String, global: Boolean) -> Unit, author: String?, artist: String?, status: Long, sourceName: String, isStubSource: Boolean, textAlign: TextAlign? = LocalTextStyle.current.textAlign, ) CyclomaticComplexMethod:MangaScreen.kt$MangaScreen$@Composable override fun Content() CyclomaticComplexMethod:MangaScreenModel.kt$MangaScreenModel$fun toggleSelection( item: ChapterList.Item, selected: Boolean, userSelected: Boolean = false, fromLongPress: Boolean = false, ) - CyclomaticComplexMethod:MigrateDialog.kt$MigrateDialogScreenModel$private suspend fun migrateMangaInternal( oldSource: Source?, newSource: Source, oldManga: Manga, newManga: Manga, sourceChapters: List<SChapter>, replace: Boolean, flags: Int, ) + CyclomaticComplexMethod:MangaToolbar.kt$@Composable fun MangaToolbar( title: String, titleAlphaProvider: () -> Float, hasFilters: Boolean, onBackClicked: () -> Unit, onClickFilter: () -> Unit, onClickShare: (() -> Unit)?, onClickDownload: ((DownloadAction) -> Unit)?, onClickEditCategory: (() -> Unit)?, onClickRefresh: () -> Unit, onClickMigrate: (() -> Unit)?, // SY --> onClickEditInfo: (() -> Unit)?, onClickRecommend: (() -> Unit)?, onClickMerge: (() -> Unit)?, onClickMergedSettings: (() -> Unit)?, // SY <-- // For action mode actionModeCounter: Int, onSelectAll: () -> Unit, onInvertSelection: () -> Unit, modifier: Modifier = Modifier, backgroundAlphaProvider: () -> Float = titleAlphaProvider, ) + CyclomaticComplexMethod:MangaType.kt$fun Manga.mangaType(sourceName: String? = Injekt.get<SourceManager>().get(source)?.name): MangaType + CyclomaticComplexMethod:MangaType.kt$private fun isComicSource(sourceName: String): Boolean + CyclomaticComplexMethod:MangaType.kt$private fun isManhwaSource(sourceName: String): Boolean + CyclomaticComplexMethod:MetadataUIUtil.kt$MetadataUIUtil$fun getGenreAndColour(context: Context, genre: String) + CyclomaticComplexMethod:MigrationListScreen.kt$MigrationListScreen$@Composable override fun Content() + CyclomaticComplexMethod:MigrationListScreenModel.kt$MigrationListScreenModel$private suspend fun migrateMangaInternal( prevManga: Manga, manga: Manga, replace: Boolean, ) + CyclomaticComplexMethod:MigrationListScreenModel.kt$MigrationListScreenModel$private suspend fun runMigrations(mangas: List<MigratingManga>) + CyclomaticComplexMethod:Migrations.kt$Migrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, ): Boolean + CyclomaticComplexMethod:NHentaiDescriptionAdapter.kt$@Composable fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) + CyclomaticComplexMethod:NHentaiSearchMetadata.kt$NHentaiSearchMetadata$override fun createMangaInfo(manga: SManga): SManga CyclomaticComplexMethod:NotificationReceiver.kt$NotificationReceiver$override fun onReceive(context: Context, intent: Intent) + CyclomaticComplexMethod:PagerPageHolder.kt$PagerPageHolder$private fun mergePages(imageStream: InputStream, imageStream2: InputStream?): InputStream + CyclomaticComplexMethod:PagerPageHolder.kt$PagerPageHolder$private fun splitInHalf(imageStream: InputStream): InputStream CyclomaticComplexMethod:PagerViewer.kt$PagerViewer$override fun handleKeyEvent(event: KeyEvent): Boolean CyclomaticComplexMethod:PagerViewerAdapter.kt$PagerViewerAdapter$fun setChapters(chapters: ViewerChapters, forceTransition: Boolean) + CyclomaticComplexMethod:PagerViewerAdapter.kt$PagerViewerAdapter$private fun setJoinedItems(useSecondPage: Boolean = false) CyclomaticComplexMethod:PreferenceItem.kt$@Composable internal fun PreferenceItem( item: Preference.PreferenceItem<*>, highlightKey: String?, ) + CyclomaticComplexMethod:PururinDescriptionAdapter.kt$@Composable fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) CyclomaticComplexMethod:RateLimitInterceptor.kt$RateLimitInterceptor$override fun intercept(chain: Interceptor.Chain): Response CyclomaticComplexMethod:ReaderActivity.kt$ReaderActivity$override fun onCreate(savedInstanceState: Bundle?) CyclomaticComplexMethod:ReaderActivity.kt$ReaderActivity$private fun initializeMenu() CyclomaticComplexMethod:Scaffold.kt$@Composable private fun ScaffoldLayout( fabPosition: FabPosition, topBar: @Composable () -> Unit, startBar: @Composable () -> Unit, content: @Composable (PaddingValues) -> Unit, snackbar: @Composable () -> Unit, fab: @Composable () -> Unit, contentWindowInsets: WindowInsets, bottomBar: @Composable () -> Unit, ) - CyclomaticComplexMethod:SourcesScreenModel.kt$SourcesScreenModel$private fun collectLatestSources(sources: List<Source>) + CyclomaticComplexMethod:SearchEngine.kt$SearchEngine$fun parseQuery(query: String, enableWildcard: Boolean = true) + CyclomaticComplexMethod:SettingsEhScreen.kt$SettingsEhScreen$private fun getRelativeTimeFromNow(then: Duration): RelativeTime + CyclomaticComplexMethod:SettingsEhScreen.kt$SettingsEhScreen$private fun getRelativeTimeString(relativeTime: RelativeTime, context: Context): String + CyclomaticComplexMethod:SourceTagsUtil.kt$SourceTagsUtil$fun getLocaleSourceUtil(language: String?) + CyclomaticComplexMethod:SourceTagsUtil.kt$SourceTagsUtil$fun getWrappedTag( sourceId: Long?, namespace: String? = null, tag: String? = null, fullTag: String? = null, ): String? + CyclomaticComplexMethod:SourcesScreenModel.kt$SourcesScreenModel$private fun collectLatestSources(sources: List<Source>, categories: List<String>, showLatest: Boolean, showPin: Boolean) CyclomaticComplexMethod:SyncChaptersWithSource.kt$SyncChaptersWithSource$suspend fun await( rawSourceChapters: List<SChapter>, manga: Manga, source: Source, manualFetch: Boolean = false, fetchWindow: Pair<Long, Long> = Pair(0, 0), ): List<Chapter> + CyclomaticComplexMethod:TrackStatus.kt$TrackStatus.Companion$fun parseTrackerStatus(trackerManager: TrackerManager, tracker: Long, status: Long): TrackStatus? CyclomaticComplexMethod:TriStateListDialog.kt$@Composable fun <T> TriStateListDialog( title: String, message: String? = null, items: List<T>, initialChecked: List<T>, initialInversed: List<T>, itemLabel: @Composable (T) -> String, onDismissRequest: () -> Unit, onValueChanged: (newIncluded: List<T>, newExcluded: List<T>) -> Unit, ) + CyclomaticComplexMethod:TsuminoDescriptionAdapter.kt$@Composable fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) CyclomaticComplexMethod:UpdatesScreenModel.kt$UpdatesScreenModel$fun toggleSelection( item: UpdatesItem, selected: Boolean, userSelected: Boolean = false, fromLongPress: Boolean = false, ) CyclomaticComplexMethod:VerticalFastScroller.kt$@Composable fun VerticalFastScroller( listState: LazyListState, modifier: Modifier = Modifier, thumbAllowed: () -> Boolean = { true }, thumbColor: Color = MaterialTheme.colorScheme.primary, topContentPadding: Dp = Dp.Hairline, bottomContentPadding: Dp = Dp.Hairline, endContentPadding: Dp = Dp.Hairline, content: @Composable () -> Unit, ) CyclomaticComplexMethod:VerticalFastScroller.kt$@Composable fun VerticalGridFastScroller( state: LazyGridState, columns: GridCells, arrangement: Arrangement.Horizontal, contentPadding: PaddingValues, modifier: Modifier = Modifier, thumbAllowed: () -> Boolean = { true }, thumbColor: Color = MaterialTheme.colorScheme.primary, topContentPadding: Dp = Dp.Hairline, bottomContentPadding: Dp = Dp.Hairline, endContentPadding: Dp = Dp.Hairline, content: @Composable () -> Unit, ) @@ -96,18 +323,59 @@ CyclomaticComplexMethod:WebtoonViewer.kt$WebtoonViewer$override fun handleKeyEvent(event: KeyEvent): Boolean DestructuringDeclarationWithTooManyEntries:ExtensionsScreenModel.kt$ExtensionsScreenModel$(_updates, _installed, _available, _untrusted) DestructuringDeclarationWithTooManyEntries:MangaInfoHeader.kt$(shrunk, expanded, actual, scrim) + DestructuringDeclarationWithTooManyEntries:MangaScreenModel.kt$MangaScreenModel$(manga, chapters /* SY --> */, flatMetadata, mergedData /* SY <-- */) + DestructuringDeclarationWithTooManyEntries:NamespaceTags.kt$(_, text, search, border) + EmptyCatchBlock:EnhancedFilePrinter.kt$EnhancedFilePrinter.Writer${ } + EmptyCatchBlock:MigrationListScreenModel.kt$MigrationListScreenModel${ } EmptyCatchBlock:RarPageLoader.kt$RarPageLoader${ } + EmptyDefaultConstructor:FavoritesSyncHelper.kt$FavoritesSyncStatus$() + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ImageSize$1280 : ImageSize + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ImageSize$1600 : ImageSize + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ImageSize$2400 : ImageSize + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ImageSize$780 : ImageSize + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ImageSize$980 : ImageSize + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.SearchResultsCount$100 : SearchResultsCount + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.SearchResultsCount$200 : SearchResultsCount + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.SearchResultsCount$25 : SearchResultsCount + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.SearchResultsCount$50 : SearchResultsCount + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ThumbnailRows$10 : ThumbnailRows + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ThumbnailRows$20 : ThumbnailRows + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ThumbnailRows$4 : ThumbnailRows + EnumEntryNameCase:EhUConfigBuilder.kt$Entry.ThumbnailRows$40 : ThumbnailRows + EnumNaming:EhUConfigBuilder.kt$Entry.ImageSize$1280 : ImageSize + EnumNaming:EhUConfigBuilder.kt$Entry.ImageSize$1600 : ImageSize + EnumNaming:EhUConfigBuilder.kt$Entry.ImageSize$2400 : ImageSize + EnumNaming:EhUConfigBuilder.kt$Entry.ImageSize$780 : ImageSize + EnumNaming:EhUConfigBuilder.kt$Entry.ImageSize$980 : ImageSize + EnumNaming:EhUConfigBuilder.kt$Entry.SearchResultsCount$100 : SearchResultsCount + EnumNaming:EhUConfigBuilder.kt$Entry.SearchResultsCount$200 : SearchResultsCount + EnumNaming:EhUConfigBuilder.kt$Entry.SearchResultsCount$25 : SearchResultsCount + EnumNaming:EhUConfigBuilder.kt$Entry.SearchResultsCount$50 : SearchResultsCount + EnumNaming:EhUConfigBuilder.kt$Entry.ThumbnailRows$10 : ThumbnailRows + EnumNaming:EhUConfigBuilder.kt$Entry.ThumbnailRows$20 : ThumbnailRows + EnumNaming:EhUConfigBuilder.kt$Entry.ThumbnailRows$4 : ThumbnailRows + EnumNaming:EhUConfigBuilder.kt$Entry.ThumbnailRows$40 : ThumbnailRows EqualsAlwaysReturnsTrueOrFalse:FilterList.kt$FilterList$override fun equals(other: Any?): Boolean ExplicitItLambdaParameter:ColorFilterPage.kt${ index, it -> FilterChip( selected = colorFilterMode == index, onClick = { screenModel.preferences.colorFilterMode().set(index) }, label = { Text(stringResource(it.first)) }, ) } + ExplicitItLambdaParameter:FavoritesSyncHelper.kt$FavoritesSyncHelper${ index, it -> status.value = FavoritesSyncStatus.Processing( context.stringResource(SYMR.strings.favorites_sync_remove_from_local, index + 1, changeSet.removed.size), title = it.title, ) val url = it.getUrl() // Consider both EX and EH sources listOf( EXH_SOURCE_ID, EH_SOURCE_ID, ).forEach { val manga = getManga.await(url, it) if (manga?.favorite == true) { updateManga.awaitUpdateFavorite(manga.id, false) removedManga += manga } } } + ExplicitItLambdaParameter:FavoritesSyncHelper.kt$FavoritesSyncHelper${ index, it -> status.value = FavoritesSyncStatus.Processing( message = context.stringResource(SYMR.strings.favorites_sync_add_to_local, index + 1, changeSet.added.size), isThrottle = needWarnThrottle(), context = context, title = it.title, ) throttleManager.throttle() // Import using gallery adder val result = galleryAdder.addGallery( context = context, url = "${exh.baseUrl}${it.getUrl()}", fav = true, forceSource = exh, throttleFunc = throttleManager::throttle, retry = 3, ) if (result is GalleryAddEvent.Fail) { if (result is GalleryAddEvent.Fail.NotFound) { logger.e(context.stringResource(SYMR.strings.favorites_sync_remote_not_exist, it.getUrl())) // Skip this gallery, it no longer exists return@forEachIndexed } val errorString = context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) + when (result) { is GalleryAddEvent.Fail.Error -> context.stringResource( SYMR.strings.favorites_sync_failed_to_add_to_local_error, it.title, result.logMessage, ) is GalleryAddEvent.Fail.UnknownType -> context.stringResource( SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, it.title, result.galleryUrl, ) is GalleryAddEvent.Fail.UnknownSource -> context.stringResource( SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, it.title, result.galleryUrl, ) } if (prefs.exhLenientSync().get()) { errorList += errorString } else { status.value = FavoritesSyncStatus.Error(errorString) throw IgnoredException(errorString) } } else if (result is GalleryAddEvent.Success) { insertedMangaCategories += categories[it.category].id to result.manga } } + ExplicitItLambdaParameter:FavoritesSyncHelper.kt$FavoritesSyncHelper${ index, it -> status.value = FavoritesSyncStatus.Processing( message = context.stringResource(SYMR.strings.favorites_sync_adding_to_remote, index + 1, changeSet.added.size), isThrottle = needWarnThrottle(), context = context, title = it.title, ) throttleManager.throttle() addGalleryRemote(errorList, it) } ExplicitItLambdaParameter:LibraryTab.kt$LibraryTab${ it: LibraryManga -> scope.launchIO { val chapter = screenModel.getNextUnreadChapter(it.manga) if (chapter != null) { context.startActivity( ReaderActivity.newIntent(context, chapter.mangaId, chapter.id), ) } else { snackbarHostState.showSnackbar(context.stringResource(MR.strings.no_next_chapter)) } } Unit } + ExplicitItLambdaParameter:ReadingModePage.kt${ index, it -> FilterChip( selected = centerMarginType == index, onClick = { screenModel.preferences.centerMarginType().set(index) }, label = { Text(stringResource(it)) }, ) } ExplicitItLambdaParameter:ReadingModePage.kt${ index, it -> FilterChip( selected = imageScaleType == index + 1, onClick = { screenModel.preferences.imageScaleType().set(index + 1) }, label = { Text(stringResource(it)) }, ) } + ExplicitItLambdaParameter:ReadingModePage.kt${ index, it -> FilterChip( selected = pageLayout == index, onClick = { screenModel.preferences.pageLayout().set(index) }, label = { Text(stringResource(it)) }, ) } ExplicitItLambdaParameter:ReadingModePage.kt${ index, it -> FilterChip( selected = selected == index, onClick = { onSelect(index) }, label = { Text(stringResource(it)) }, ) } ExplicitItLambdaParameter:ReadingModePage.kt${ index, it -> FilterChip( selected = zoomStart == index + 1, onClick = { screenModel.preferences.zoomStart().set(index + 1) }, label = { Text(stringResource(it)) }, ) } ExplicitItLambdaParameter:SettingsReaderScreen.kt$SettingsReaderScreen${ index, it -> index + 1 to stringResource(it) } ExplicitItLambdaParameter:SettingsReaderScreen.kt$SettingsReaderScreen${ index, it -> index to stringResource(it) } + Filename:__Assets.kt$exh.assets.ehassets.exh.__Assets.kt + Filename:__EhAssets.kt$exh.assets.__EhAssets.kt + Filename:__Ehassets.kt$exh.assets.ehassets.exh.assets.__Ehassets.kt + Filename:__Exh.kt$exh.assets.ehassets.__Exh.kt FinalNewline:Commands.kt$.Commands.kt ForEachOnRange:MangaBottomActionMenu.kt$0..<5 ForEachOnRange:MangaBottomActionMenu.kt$0..<7 + ForEachOnRange:PagerViewerAdapter.kt$PagerViewerAdapter$fullPageBeforeIndex until items.size ForEachOnRange:UpdatesWidget.kt$0..<rowCount ForbiddenComment:AddTracks.kt$AddTracks$// TODO: merge into [SyncChapterProgressWithTrack]? ForbiddenComment:AddTracks.kt$AddTracks$// TODO: update all trackers based on common data @@ -132,6 +400,7 @@ ForbiddenComment:Manga.kt$// TODO: move these into the domain model ForbiddenComment:MangaCoverScreenModel.kt$MangaCoverScreenModel$// TODO: Handle animated cover ForbiddenComment:MangaInfoHeader.kt$// TODO: show something better when using custom interval + ForbiddenComment:MigrateSourceTab.kt$// TODO: Jay wtf, need to clean this up sometime ForbiddenComment:PreferenceItem.kt$// TODO: use different composable? ForbiddenComment:ReaderPreferences.kt$ReaderPreferences$// TODO: default this to true if reader long strip ever goes stable ForbiddenComment:SettingsAdvancedScreen.kt$SettingsAdvancedScreen$// TODO: allow private option in stable versions once URL handling is more fleshed out @@ -139,6 +408,7 @@ ForbiddenComment:Tracker.kt$Tracker$// TODO: move this to an interactor, and update all trackers based on common data ForbiddenComment:VerticalFastScroller.kt$// TODO: Sometimes item height is not available when scrolling up FunctionNaming:Downloader.kt$Downloader$private fun _clearQueue() + FunctionNaming:PagePreviews.kt$fun LazyListScope.PagePreviewItems( pagePreviewState: PagePreviewState, onOpenPage: (Int) -> Unit, onMorePreviewsClicked: () -> Unit, maxWidth: Dp, setMaxWidth: (Dp) -> Unit, rowCount: Int, ) FunctionNaming:Pin.kt$fun Pins(vararg pins: Pin) FunctionNaming:PullRefresh.kt$PullToRefreshStateImpl.Companion$fun Saver( extraVerticalOffset: Float, positionalThreshold: Float, enabled: () -> Boolean, onRefresh: () -> Unit, ) FunctionNaming:Requests.kt$fun DELETE( url: String, headers: Headers = DEFAULT_HEADERS, body: RequestBody = DEFAULT_BODY, cache: CacheControl = DEFAULT_CACHE_CONTROL, ): Request @@ -148,194 +418,159 @@ FunctionNaming:Requests.kt$fun PUT( url: String, headers: Headers = DEFAULT_HEADERS, body: RequestBody = DEFAULT_BODY, cache: CacheControl = DEFAULT_CACHE_CONTROL, ): Request FunctionParameterNaming:MangaScreen.kt$MangaScreen$manga_: Manga? FunctionParameterNaming:MangaScreen.kt$MangaScreen$source_: Source? + FunctionParameterNaming:SChapter.kt$SChapter.Companion$chapter_number: Float = -1F + FunctionParameterNaming:SChapter.kt$SChapter.Companion$date_upload: Long = 0 + FunctionParameterNaming:SManga.kt$SManga.Companion$thumbnail_url: String? = null + FunctionParameterNaming:SManga.kt$thumbnail_url: String? = this.originalThumbnailUrl FunctionParameterNaming:WebViewInterceptor.kt$_name: String FunctionParameterNaming:WebViewInterceptor.kt$_value: String + ImplicitDefaultLocale:MetadataUtil.kt$MetadataUtil$String.format("%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre) + ImplicitDefaultLocale:TimeRange.kt$TimeRange$String.format("%02d:%02d - %02d:%02d", startHour, startMinute, endHour, endMinute) ImportOrdering:Commands.kt$import org.gradle.api.Project import java.io.ByteArrayOutputStream import java.text.SimpleDateFormat import java.util.TimeZone import java.util.Date + ImportOrdering:LocalSource.kt$import android.content.Context import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.UnmeteredSource import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage 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.CbzCrypto.addStreamToZip import eu.kanade.tachiyomi.util.storage.CbzCrypto.getCoverStreamFromZip import eu.kanade.tachiyomi.util.storage.CbzCrypto.getZipInputStream import eu.kanade.tachiyomi.util.storage.CbzCrypto.isEncryptedZip 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 kotlinx.serialization.json.encodeToStream import logcat.LogPriority import nl.adaptivity.xmlutil.AndroidXmlReader import nl.adaptivity.xmlutil.serialization.XML import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.metadata.comicinfo.COMIC_INFO_FILE import tachiyomi.core.metadata.comicinfo.ComicInfo import tachiyomi.core.metadata.comicinfo.copyFromComicInfo import tachiyomi.core.metadata.comicinfo.getComicInfo import tachiyomi.core.metadata.tachiyomi.MangaDetails import tachiyomi.core.common.storage.UniFileTempFileManager import tachiyomi.core.common.storage.extension import tachiyomi.core.common.storage.nameWithoutExtension import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.system.ImageUtil import tachiyomi.core.common.util.system.logcat import tachiyomi.domain.chapter.service.ChapterRecognition import tachiyomi.domain.manga.model.Manga import tachiyomi.i18n.MR import tachiyomi.source.local.filter.OrderBy import tachiyomi.source.local.image.LocalCoverManager import tachiyomi.source.local.io.Archive import tachiyomi.source.local.io.Format import tachiyomi.source.local.io.LocalSourceFileSystem import tachiyomi.source.local.metadata.fillMetadata 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 + Indentation:BackupCreator.kt$BackupCreator$ Indentation:LocalesConfigPlugin.kt$ + Indentation:PagerPageHolder.kt$PagerPageHolder$ + Indentation:ReaderPreferences.kt$ReaderPreferences$ InstanceOfCheckForException:AppUpdateDownloadJob.kt$AppUpdateDownloadJob$e is CancellationException InstanceOfCheckForException:AppUpdateDownloadJob.kt$AppUpdateDownloadJob$e is StreamResetException InstanceOfCheckForException:BackupRestoreJob.kt$BackupRestoreJob$e is CancellationException InstanceOfCheckForException:Downloader.kt$Downloader$e is CancellationException InstanceOfCheckForException:Downloader.kt$Downloader$error is CancellationException + InstanceOfCheckForException:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$t is EHentai.GalleryNotFoundException + InstanceOfCheckForException:GalleryAdder.kt$GalleryAdder$e is EHentai.GalleryNotFoundException InstanceOfCheckForException:HttpPageLoader.kt$HttpPageLoader$e is CancellationException InstanceOfCheckForException:LibraryUpdateJob.kt$LibraryUpdateJob$e is CancellationException + InstanceOfCheckForException:MangaScreen.kt$MangaScreen$e is CancellationException InstanceOfCheckForException:MangaScreenModel.kt$MangaScreenModel$e is HttpException InstanceOfCheckForException:MangaScreenModel.kt$MangaScreenModel$e is NoChaptersException + InstanceOfCheckForException:MergedSource.kt$MergedSource$e is CancellationException InstanceOfCheckForException:MetadataUpdateJob.kt$MetadataUpdateJob$e is CancellationException + InstanceOfCheckForException:MigrationListScreenModel.kt$MigrationListScreenModel$e is CancellationException InstanceOfCheckForException:ReaderViewModel.kt$ReaderViewModel$e is CancellationException + InstanceOfCheckForException:RxCoroutineBridge.kt$e !is CancellationException + InstanceOfCheckForException:SmartSearchScreenModel.kt$SmartSearchScreenModel$e is CancellationException InstanceOfCheckForException:UncaughtExceptionInterceptor.kt$UncaughtExceptionInterceptor$e is IOException + LargeClass:Artist.kt$Artist : TagList + LargeClass:Artist2.kt$Artist2 : TagList + LargeClass:Character.kt$Character : TagList + LargeClass:EHentai.kt$EHentai : HttpSourceMetadataSourceUrlImportableSourceNamespaceSourcePagePreviewSource + LargeClass:EXHMigrations.kt$EXHMigrations + LargeClass:Group.kt$Group : TagList + LargeClass:LibraryScreenModel.kt$LibraryScreenModel : StateScreenModel LargeClass:MangaScreenModel.kt$MangaScreenModel : StateScreenModel - LongMethod:AboutScreen.kt$AboutScreen$@Composable override fun Content() - LongMethod:AdaptiveSheet.kt$@Composable fun AdaptiveSheet( isTabletUi: Boolean, tonalElevation: Dp, enableSwipeDismiss: Boolean, onDismissRequest: () -> Unit, modifier: Modifier = Modifier, content: @Composable () -> Unit, ) + LargeClass:Parody.kt$Parody : TagList + LargeClass:ReaderActivity.kt$ReaderActivity : BaseActivity + LargeClass:ReaderViewModel.kt$ReaderViewModel : ViewModel + LargeClass:SettingsAdvancedScreen.kt$SettingsAdvancedScreen : SearchableSettings + LargeClass:SettingsEhScreen.kt$SettingsEhScreen : SearchableSettings LongMethod:AnilistApi.kt$AnilistApi$suspend fun findLibManga(track: Track, userid: Int): Track? - LongMethod:AppBar.kt$@Composable fun AppBarActions( actions: ImmutableList<AppBar.AppBarAction>, ) - LongMethod:AppBar.kt$@Composable fun SearchToolbar( searchQuery: String?, onChangeSearchQuery: (String?) -> Unit, modifier: Modifier = Modifier, titleContent: @Composable () -> Unit = {}, navigateUp: (() -> Unit)? = null, searchEnabled: Boolean = true, placeholderText: String? = null, onSearch: (String) -> Unit = {}, onClickCloseSearch: () -> Unit = { onChangeSearchQuery(null) }, actions: @Composable RowScope.() -> Unit = {}, scrollBehavior: TopAppBarScrollBehavior? = null, visualTransformation: VisualTransformation = VisualTransformation.None, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, ) + LongMethod:ApiMangaParser.kt$ApiMangaParser$fun parseIntoMetadata( metadata: MangaDexSearchMetadata, mangaDto: MangaDto, simpleChapters: List<String>, statistics: StatisticsMangaDto?, ) LongMethod:AppModule.kt$AppModule$override fun InjektRegistrar.registerInjectables() - LongMethod:AppThemePreferenceWidget.kt$@Composable fun AppThemePreviewItem( selected: Boolean, onClick: () -> Unit, ) - LongMethod:BrowseSourceScreen.kt$@Composable fun BrowseSourceContent( source: Source?, mangaList: LazyPagingItems<StateFlow<Manga>>, columns: GridCells, displayMode: LibraryDisplayMode, snackbarHostState: SnackbarHostState, contentPadding: PaddingValues, onWebViewClick: () -> Unit, onHelpClick: () -> Unit, onLocalSourceHelpClick: () -> Unit, onMangaClick: (Manga) -> Unit, onMangaLongClick: (Manga) -> Unit, ) - LongMethod:BrowseSourceScreen.kt$BrowseSourceScreen$@Composable override fun Content() - LongMethod:BrowseSourceToolbar.kt$@Composable fun BrowseSourceToolbar( searchQuery: String?, onSearchQueryChange: (String?) -> Unit, source: Source?, displayMode: LibraryDisplayMode, onDisplayModeChange: (LibraryDisplayMode) -> Unit, navigateUp: () -> Unit, onWebViewClick: () -> Unit, onHelpClick: () -> Unit, onSettingsClick: () -> Unit, onSearch: (String) -> Unit, scrollBehavior: TopAppBarScrollBehavior? = null, ) - LongMethod:Button.kt$ButtonElevation$@Composable private fun animateElevation( enabled: Boolean, interactionSource: InteractionSource, ): State<Dp> - LongMethod:CategoryDialogs.kt$@Composable fun ChangeCategoryDialog( initialSelection: ImmutableList<CheckboxState<Category>>, onDismissRequest: () -> Unit, onEditCategories: () -> Unit, onConfirm: (List<Long>, List<Long>) -> Unit, ) - LongMethod:ChapterDownloadIndicator.kt$@Composable private fun DownloadingIndicator( enabled: Boolean, downloadState: Download.State, downloadProgressProvider: () -> Int, onClick: (ChapterDownloadAction) -> Unit, modifier: Modifier = Modifier, ) - LongMethod:ChapterNavigator.kt$@Composable fun ChapterNavigator( isRtl: Boolean, onNextChapter: () -> Unit, enabledNext: Boolean, onPreviousChapter: () -> Unit, enabledPrevious: Boolean, currentPage: Int, totalPages: Int, onSliderValueChange: (Int) -> Unit, ) - LongMethod:ChapterSettingsDialog.kt$@Composable fun ChapterSettingsDialog( onDismissRequest: () -> Unit, manga: Manga? = null, onDownloadFilterChanged: (TriState) -> Unit, onUnreadFilterChanged: (TriState) -> Unit, onBookmarkedFilterChanged: (TriState) -> Unit, scanlatorFilterActive: Boolean, onScanlatorFilterClicked: (() -> Unit), onSortModeChanged: (Long) -> Unit, onDisplayModeChanged: (Long) -> Unit, onSetAsDefault: (applyToExistingManga: Boolean) -> Unit, onResetToDefault: () -> Unit, ) - LongMethod:ClearDatabaseScreen.kt$ClearDatabaseScreen$@Composable override fun Content() - LongMethod:ColorFilterPage.kt$@Composable internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel) - LongMethod:CreateBackupScreen.kt$CreateBackupScreen$@Composable override fun Content() + LongMethod:Artist.kt$Artist$override fun getTags1(): List<String> + LongMethod:Artist.kt$Artist$override fun getTags2(): List<String> + LongMethod:Artist.kt$Artist$override fun getTags3(): List<String> + LongMethod:Artist2.kt$Artist2$override fun getTags1(): List<String> + LongMethod:Artist2.kt$Artist2$override fun getTags2(): List<String> + LongMethod:Artist2.kt$Artist2$override fun getTags3(): List<String> + LongMethod:BatchAddScreenModel.kt$BatchAddScreenModel$private fun addGalleries(context: Context, galleries: String) + LongMethod:ChapterLoader.kt$ChapterLoader$private fun getPageLoader(chapter: ReaderChapter): PageLoader + LongMethod:Character.kt$Character$override fun getTags1(): List<String> + LongMethod:Character.kt$Character$override fun getTags2(): List<String> + LongMethod:Character.kt$Character$override fun getTags3(): List<String> + LongMethod:Cosplayer.kt$Cosplayer$override fun getTags1(): List<String> LongMethod:DomainModule.kt$DomainModule$override fun InjektRegistrar.registerInjectables() LongMethod:DownloadCache.kt$DownloadCache$private fun renewCache() - LongMethod:DownloadQueueScreen.kt$DownloadQueueScreen$@Composable override fun Content() LongMethod:Downloader.kt$Downloader$private suspend fun downloadChapter(download: Download) - LongMethod:EditTextPreferenceWidget.kt$@Composable fun EditTextPreferenceWidget( title: String, subtitle: String?, icon: ImageVector?, value: String, onConfirm: suspend (String) -> Boolean, ) - LongMethod:ExtensionDetailsScreen.kt$@Composable fun ExtensionDetailsScreen( navigateUp: () -> Unit, state: ExtensionDetailsScreenModel.State, onClickSourcePreferences: (sourceId: Long) -> Unit, onClickEnableAll: () -> Unit, onClickDisableAll: () -> Unit, onClickClearCookies: () -> Unit, onClickUninstall: () -> Unit, onClickSource: (sourceId: Long) -> Unit, ) - LongMethod:ExtensionDetailsScreen.kt$@Composable private fun DetailsHeader( extension: Extension, onClickAgeRating: () -> Unit, onClickUninstall: () -> Unit, onClickAppInfo: (() -> Unit)?, ) + LongMethod:EHentai.kt$EHentai$override suspend fun parseIntoMetadata(metadata: EHentaiSearchMetadata, input: Document) + LongMethod:EHentai.kt$EHentai$private fun extendedGenericMangaParse(doc: Document) + LongMethod:EHentai.kt$EHentai$suspend fun getChapterList(manga: SManga, throttleFunc: suspend () -> Unit): List<SChapter> + LongMethod:EHentaiUpdateHelper.kt$EHentaiUpdateHelper$private fun getChapterList( accepted: ChapterChain, toDiscard: List<ChapterChain>, chainsAsChapters: List<Chapter>, ): Triple<List<ChapterUpdate>, List<Chapter>, Boolean> + LongMethod:EHentaiUpdateHelper.kt$EHentaiUpdateHelper$suspend fun findAcceptedRootAndDiscardOthers( sourceId: Long, chapters: List<Chapter>, ): Triple<ChapterChain, List<ChapterChain>, Boolean> + LongMethod:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$private suspend fun startUpdating() + LongMethod:EXHMigrations.kt$EXHMigrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, pagePreviewCache: PagePreviewCache, ): Boolean + LongMethod:EditMangaDialog.kt$private fun onViewCreated(manga: Manga, context: Context, binding: EditMangaDialogBinding, scope: CoroutineScope) + LongMethod:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter.HeaderViewHolder$fun bind() + LongMethod:EhUConfigBuilder.kt$EhUConfigBuilder$fun build(hathPerks: EHHathPerksResponse): FormBody LongMethod:ExtensionLoader.kt$ExtensionLoader$private fun loadExtension(context: Context, extensionInfo: ExtensionInfo): LoadResult - LongMethod:ExtensionsScreen.kt$@Composable private fun ExtensionContent( state: ExtensionsScreenModel.State, contentPadding: PaddingValues, onLongClickItem: (Extension) -> Unit, onClickItemCancel: (Extension) -> Unit, onOpenWebView: (Extension.Available) -> Unit, onInstallExtension: (Extension.Available) -> Unit, onUninstallExtension: (Extension) -> Unit, onUpdateExtension: (Extension.Installed) -> Unit, onTrustExtension: (Extension.Untrusted) -> Unit, onOpenExtension: (Extension.Installed) -> Unit, onClickUpdateAll: () -> Unit, ) - LongMethod:ExtensionsScreen.kt$@Composable private fun ExtensionItemActions( extension: Extension, installStep: InstallStep, modifier: Modifier = Modifier, onClickItemCancel: (Extension) -> Unit = {}, onClickItemAction: (Extension) -> Unit = {}, onClickItemSecondaryAction: (Extension) -> Unit = {}, ) - LongMethod:GlobalSearchToolbar.kt$@Composable fun GlobalSearchToolbar( searchQuery: String?, progress: Int, total: Int, navigateUp: () -> Unit, onChangeSearchQuery: (String?) -> Unit, onSearch: (String) -> Unit, sourceFilter: SourceFilter, onChangeSearchFilter: (SourceFilter) -> Unit, onlyShowHasResults: Boolean, onToggleResults: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, ) - LongMethod:HomeScreen.kt$HomeScreen$@Composable override fun Content() + LongMethod:FavoritesSyncHelper.kt$FavoritesSyncHelper$private suspend fun applyChangeSetToLocal(errorList: MutableList<String>, changeSet: ChangeSet) + LongMethod:FavoritesSyncHelper.kt$FavoritesSyncHelper$private suspend fun beginSync() + LongMethod:Female.kt$Female$override fun getTags1(): List<String> + LongMethod:FilterHandler.kt$FilterHandler$fun getQueryMap(filters: FilterList): Map<String, Any> + LongMethod:FilterHandler.kt$FilterHandler$internal fun getTags() + LongMethod:GalleryAdder.kt$GalleryAdder$suspend fun addGallery( context: Context, url: String, fav: Boolean = false, forceSource: UrlImportableSource? = null, throttleFunc: suspend () -> Unit = {}, retry: Int = 1, ): GalleryAddEvent + LongMethod:Group.kt$Group$override fun getTags1(): List<String> + LongMethod:Group.kt$Group$override fun getTags2(): List<String> + LongMethod:Group.kt$Group$override fun getTags3(): List<String> + LongMethod:Group2.kt$Group2$override fun getTags1(): List<String> LongMethod:ImageUtil.kt$ImageUtil$fun chooseBackground(context: Context, imageStream: InputStream): Drawable - LongMethod:InfoScreen.kt$@Composable fun InfoScreen( icon: ImageVector, headingText: String, subtitleText: String, acceptText: String, onAcceptClick: () -> Unit, canAccept: Boolean = true, rejectText: String? = null, onRejectClick: (() -> Unit)? = null, content: @Composable ColumnScope.() -> Unit, ) - LongMethod:LibraryContent.kt$@Composable fun LibraryContent( categories: List<Category>, searchQuery: String?, selection: List<LibraryManga>, contentPadding: PaddingValues, currentPage: () -> Int, hasActiveFilters: Boolean, showPageTabs: Boolean, onChangeCurrentPage: (Int) -> Unit, onMangaClicked: (Long) -> Unit, onContinueReadingClicked: ((LibraryManga) -> Unit)?, onToggleSelection: (LibraryManga) -> Unit, onToggleRangeSelection: (LibraryManga) -> Unit, onRefresh: (Category?) -> Boolean, onGlobalSearchClicked: () -> Unit, getNumberOfMangaForCategory: (Category) -> Int?, getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>, getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>, getLibraryForPage: (Int) -> List<LibraryItem>, ) - LongMethod:LibraryPager.kt$@Composable fun LibraryPager( state: PagerState, contentPadding: PaddingValues, hasActiveFilters: Boolean, selectedManga: List<LibraryManga>, searchQuery: String?, onGlobalSearchClicked: () -> Unit, getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>, getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>, getLibraryForPage: (Int) -> List<LibraryItem>, onClickManga: (LibraryManga) -> Unit, onLongClickManga: (LibraryManga) -> Unit, onClickContinueReading: ((LibraryManga) -> Unit)?, ) - LongMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun LibraryMap.applySort( // Map<MangaId, List<Track>> trackMap: Map<Long, List<Track>>, ): LibraryMap + LongMethod:LibraryQuery.kt$LibraryQuery$override fun <R> execute(mapper: (SqlCursor) -> QueryResult<R>): QueryResult<R> + LongMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun LibraryMap.applySort( // Map<MangaId, List<Track>> trackMap: Map<Long, List<Track>>, /* SY --> */ groupSort: LibrarySort? = null, /* SY <-- */ ): LibraryMap + LongMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun filterManga( queries: List<QueryComponent>, libraryManga: LibraryManga, tracks: List<Track>?, source: Source?, checkGenre: Boolean = true, searchTags: List<SearchTag>? = null, searchTitles: List<SearchTitle>? = null, loggedInTrackServices: Map<Long, TriState>, ): Boolean + LongMethod:LibraryScreenModel.kt$LibraryScreenModel$private fun getGroupedMangaItems( groupType: Int, libraryManga: List<LibraryItem>, ): LibraryMap LongMethod:LibraryScreenModel.kt$LibraryScreenModel$private suspend fun LibraryMap.applyFilters( trackMap: Map<Long, List<Track>>, loggedInTrackers: Map<Long, TriState>, ): LibraryMap - LongMethod:LibrarySettingsDialog.kt$@Composable private fun ColumnScope.DisplayPage( screenModel: LibrarySettingsScreenModel, ) - LongMethod:LibrarySettingsDialog.kt$@Composable private fun ColumnScope.FilterPage( screenModel: LibrarySettingsScreenModel, ) - LongMethod:LibraryTab.kt$LibraryTab$@Composable override fun Content() - LongMethod:LibraryUpdateJob.kt$LibraryUpdateJob$private suspend fun addMangaToQueue(categoryId: Long) + LongMethod:LibraryUpdateJob.kt$LibraryUpdateJob$private suspend fun addMangaToQueue(categoryId: Long, group: Int, groupExtra: String?) LongMethod:LibraryUpdateJob.kt$LibraryUpdateJob$private suspend fun updateChapterList() + LongMethod:LocalSource.kt$LocalSource$override suspend fun getMangaDetails(manga: SManga): SManga + LongMethod:LocalSource.kt$LocalSource$override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage LongMethod:MainActivity.kt$MainActivity$override fun onCreate(savedInstanceState: Bundle?) LongMethod:MainActivity.kt$MainActivity$private fun handleIntentAction(intent: Intent, navigator: Navigator): Boolean - LongMethod:MangaBottomActionMenu.kt$@Composable fun LibraryBottomActionMenu( visible: Boolean, onChangeCategoryClicked: () -> Unit, onMarkAsReadClicked: () -> Unit, onMarkAsUnreadClicked: () -> Unit, onDownloadClicked: ((DownloadAction) -> Unit)?, onDeleteClicked: () -> Unit, modifier: Modifier = Modifier, ) - LongMethod:MangaBottomActionMenu.kt$@Composable fun MangaBottomActionMenu( visible: Boolean, modifier: Modifier = Modifier, onBookmarkClicked: (() -> Unit)? = null, onRemoveBookmarkClicked: (() -> Unit)? = null, onMarkAsReadClicked: (() -> Unit)? = null, onMarkAsUnreadClicked: (() -> Unit)? = null, onMarkPreviousAsReadClicked: (() -> Unit)? = null, onDownloadClicked: (() -> Unit)? = null, onDeleteClicked: (() -> Unit)? = null, ) - LongMethod:MangaChapterListItem.kt$@Composable fun MangaChapterListItem( title: String, date: String?, readProgress: String?, scanlator: String?, read: Boolean, bookmark: Boolean, selected: Boolean, downloadIndicatorEnabled: Boolean, downloadStateProvider: () -> Download.State, downloadProgressProvider: () -> Int, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onLongClick: () -> Unit, onClick: () -> Unit, onDownloadClick: ((ChapterDownloadAction) -> Unit)?, onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit, modifier: Modifier = Modifier, ) - LongMethod:MangaCoverDialog.kt$@Composable fun MangaCoverDialog( coverDataProvider: () -> Manga, isCustomCover: Boolean, snackbarHostState: SnackbarHostState, onShareClick: () -> Unit, onSaveClick: () -> Unit, onEditClick: ((EditCoverAction) -> Unit)?, onDismissRequest: () -> Unit, ) - LongMethod:MangaDialogs.kt$@Composable fun SetIntervalDialog( interval: Int, nextUpdate: Instant?, onDismissRequest: () -> Unit, onValueChanged: ((Int) -> Unit)? = null, ) - LongMethod:MangaInfoHeader.kt$@Composable fun ExpandableMangaDescription( defaultExpandState: Boolean, description: String?, tagsProvider: () -> List<String>?, onTagSearch: (String) -> Unit, onCopyTagToClipboard: (tag: String) -> Unit, modifier: Modifier = Modifier, ) - LongMethod:MangaInfoHeader.kt$@Composable private fun ColumnScope.MangaContentInfo( title: String, doSearch: (query: String, global: Boolean) -> Unit, author: String?, artist: String?, status: Long, sourceName: String, isStubSource: Boolean, textAlign: TextAlign? = LocalTextStyle.current.textAlign, ) - LongMethod:MangaInfoHeader.kt$@Composable private fun MangaSummary( expandedDescription: String, shrunkDescription: String, expanded: Boolean, modifier: Modifier = Modifier, ) - LongMethod:MangaScreen.kt$@Composable fun MangaScreen( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, nextUpdate: Instant?, isTabletUi: Boolean, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, onWebViewLongClicked: (() -> Unit)?, onTrackingClicked: () -> Unit, // For tags menu onTagSearch: (String) -> Unit, onFilterButtonClicked: () -> Unit, onRefresh: () -> Unit, onContinueReading: () -> Unit, onSearch: (query: String, global: Boolean) -> Unit, // For cover dialog onCoverClicked: () -> Unit, // For top action menu onShareClicked: (() -> Unit)?, onDownloadActionClicked: ((DownloadAction) -> Unit)?, onEditCategoryClicked: (() -> Unit)?, onEditFetchIntervalClicked: (() -> Unit)?, onMigrateClicked: (() -> Unit)?, // For bottom action menu onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit, onMarkPreviousAsReadClicked: (Chapter) -> Unit, onMultiDeleteClicked: (List<Chapter>) -> Unit, // For chapter swipe onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, // Chapter selection onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onAllChapterSelected: (Boolean) -> Unit, onInvertSelection: () -> Unit, ) - LongMethod:MangaScreen.kt$@Composable fun MangaScreenLargeImpl( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, nextUpdate: Instant?, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, onWebViewLongClicked: (() -> Unit)?, onTrackingClicked: () -> Unit, // For tags menu onTagSearch: (String) -> Unit, onCopyTagToClipboard: (tag: String) -> Unit, onFilterButtonClicked: () -> Unit, onRefresh: () -> Unit, onContinueReading: () -> Unit, onSearch: (query: String, global: Boolean) -> Unit, // For cover dialog onCoverClicked: () -> Unit, // For top action menu onShareClicked: (() -> Unit)?, onDownloadActionClicked: ((DownloadAction) -> Unit)?, onEditCategoryClicked: (() -> Unit)?, onEditIntervalClicked: (() -> Unit)?, onMigrateClicked: (() -> Unit)?, // For bottom action menu onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit, onMarkPreviousAsReadClicked: (Chapter) -> Unit, onMultiDeleteClicked: (List<Chapter>) -> Unit, // For swipe actions onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, // Chapter selection onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onAllChapterSelected: (Boolean) -> Unit, onInvertSelection: () -> Unit, ) - LongMethod:MangaScreen.kt$@Composable private fun MangaScreenSmallImpl( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, nextUpdate: Instant?, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, onWebViewLongClicked: (() -> Unit)?, onTrackingClicked: () -> Unit, // For tags menu onTagSearch: (String) -> Unit, onCopyTagToClipboard: (tag: String) -> Unit, onFilterClicked: () -> Unit, onRefresh: () -> Unit, onContinueReading: () -> Unit, onSearch: (query: String, global: Boolean) -> Unit, // For cover dialog onCoverClicked: () -> Unit, // For top action menu onShareClicked: (() -> Unit)?, onDownloadActionClicked: ((DownloadAction) -> Unit)?, onEditCategoryClicked: (() -> Unit)?, onEditIntervalClicked: (() -> Unit)?, onMigrateClicked: (() -> Unit)?, // For bottom action menu onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit, onMarkPreviousAsReadClicked: (Chapter) -> Unit, onMultiDeleteClicked: (List<Chapter>) -> Unit, // For chapter swipe onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, // Chapter selection onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onAllChapterSelected: (Boolean) -> Unit, onInvertSelection: () -> Unit, ) - LongMethod:MangaScreen.kt$MangaScreen$@Composable override fun Content() - LongMethod:MangaScreen.kt$private fun LazyListScope.sharedChapterItems( manga: Manga, chapters: List<ChapterList>, isAnyChapterSelected: Boolean, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, ) - LongMethod:MangaToolbar.kt$@Composable fun MangaToolbar( title: String, titleAlphaProvider: () -> Float, hasFilters: Boolean, onBackClicked: () -> Unit, onClickFilter: () -> Unit, onClickShare: (() -> Unit)?, onClickDownload: ((DownloadAction) -> Unit)?, onClickEditCategory: (() -> Unit)?, onClickRefresh: () -> Unit, onClickMigrate: (() -> Unit)?, // For action mode actionModeCounter: Int, onSelectAll: () -> Unit, onInvertSelection: () -> Unit, modifier: Modifier = Modifier, backgroundAlphaProvider: () -> Float = titleAlphaProvider, ) - LongMethod:MigrateDialog.kt$@Composable internal fun MigrateDialog( oldManga: Manga, newManga: Manga, screenModel: MigrateDialogScreenModel, onDismissRequest: () -> Unit, onClickTitle: () -> Unit, onPopScreen: () -> Unit, ) - LongMethod:MigrateDialog.kt$MigrateDialogScreenModel$private suspend fun migrateMangaInternal( oldSource: Source?, newSource: Source, oldManga: Manga, newManga: Manga, sourceChapters: List<SChapter>, replace: Boolean, flags: Int, ) - LongMethod:MoreScreen.kt$@Composable fun MoreScreen( downloadQueueStateProvider: () -> DownloadQueueState, downloadedOnly: Boolean, onDownloadedOnlyChange: (Boolean) -> Unit, incognitoMode: Boolean, onIncognitoModeChange: (Boolean) -> Unit, isFDroid: Boolean, onClickDownloadQueue: () -> Unit, onClickCategories: () -> Unit, onClickStats: () -> Unit, onClickDataAndStorage: () -> Unit, onClickSettings: () -> Unit, onClickAbout: () -> Unit, ) + LongMethod:Male.kt$Male$override fun getTags1(): List<String> + LongMethod:MangaScreen.kt$private fun LazyListScope.sharedChapterItems( manga: Manga, chapters: List<ChapterList>, isAnyChapterSelected: Boolean, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, // SY --> alwaysShowReadingProgress: Boolean, // SY <-- onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, ) + LongMethod:MangaScreenModel.kt$MangaScreenModel$suspend fun smartSearchMerge(manga: Manga, originalMangaId: Long): Manga + LongMethod:MigrationListScreenModel.kt$MigrationListScreenModel$private suspend fun migrateMangaInternal( prevManga: Manga, manga: Manga, replace: Boolean, ) + LongMethod:MigrationListScreenModel.kt$MigrationListScreenModel$private suspend fun runMigrations(mangas: List<MigratingManga>) + LongMethod:Migrations.kt$Migrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, ): Boolean LongMethod:Notifications.kt$Notifications$fun createChannels(context: Context) - LongMethod:PreferenceItem.kt$@Composable internal fun PreferenceItem( item: Preference.PreferenceItem<*>, highlightKey: String?, ) + LongMethod:Other.kt$Other$override fun getTags1(): List<String> + LongMethod:PagerPageHolder.kt$PagerPageHolder$private fun mergePages(imageStream: InputStream, imageStream2: InputStream?): InputStream + LongMethod:PagerPageHolder.kt$PagerPageHolder$private suspend fun setImage() + LongMethod:PagerViewerAdapter.kt$PagerViewerAdapter$private fun setJoinedItems(useSecondPage: Boolean = false) + LongMethod:Parody.kt$Parody$override fun getTags1(): List<String> + LongMethod:Parody.kt$Parody$override fun getTags2(): List<String> LongMethod:ReaderActivity.kt$ReaderActivity$override fun onCreate(savedInstanceState: Bundle?) LongMethod:ReaderActivity.kt$ReaderActivity$private fun initializeMenu() - LongMethod:ReaderAppBars.kt$@Composable fun ReaderAppBars( visible: Boolean, fullscreen: Boolean, mangaTitle: String?, chapterTitle: String?, navigateUp: () -> Unit, onClickTopAppBar: () -> Unit, bookmarked: Boolean, onToggleBookmarked: () -> Unit, onOpenInWebView: (() -> Unit)?, onShare: (() -> Unit)?, viewer: Viewer?, onNextChapter: () -> Unit, enabledNext: Boolean, onPreviousChapter: () -> Unit, enabledPrevious: Boolean, currentPage: Int, totalPages: Int, onSliderValueChange: (Int) -> Unit, readingMode: ReadingMode, onClickReadingMode: () -> Unit, orientation: ReaderOrientation, onClickOrientation: () -> Unit, cropEnabled: Boolean, onClickCropBorder: () -> Unit, onClickSettings: () -> Unit, ) - LongMethod:ReadingModePage.kt$@Composable private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenModel) - LongMethod:Scaffold.kt$@Composable private fun ScaffoldLayout( fabPosition: FabPosition, topBar: @Composable () -> Unit, startBar: @Composable () -> Unit, content: @Composable (PaddingValues) -> Unit, snackbar: @Composable () -> Unit, fab: @Composable () -> Unit, contentWindowInsets: WindowInsets, bottomBar: @Composable () -> Unit, ) - LongMethod:ScanlatorFilterDialog.kt$@Composable fun ScanlatorFilterDialog( availableScanlators: Set<String>, excludedScanlators: Set<String>, onDismissRequest: () -> Unit, onConfirm: (Set<String>) -> Unit, ) - LongMethod:SettingsAdvancedScreen.kt$SettingsAdvancedScreen$@Composable private fun getExtensionsGroup( basePreferences: BasePreferences, ): Preference.PreferenceGroup - LongMethod:SettingsAdvancedScreen.kt$SettingsAdvancedScreen$@Composable private fun getNetworkGroup( networkPreferences: NetworkPreferences, ): Preference.PreferenceGroup - LongMethod:SettingsDataScreen.kt$SettingsDataScreen$@Composable private fun getBackupAndRestoreGroup(backupPreferences: BackupPreferences): Preference.PreferenceGroup - LongMethod:SettingsLibraryScreen.kt$SettingsLibraryScreen$@Composable private fun getGlobalUpdateGroup( allCategories: List<Category>, libraryPreferences: LibraryPreferences, ): Preference.PreferenceGroup - LongMethod:SettingsMainScreen.kt$SettingsMainScreen$@Composable fun Content(twoPane: Boolean) - LongMethod:SettingsReaderScreen.kt$SettingsReaderScreen$@Composable private fun getPagedGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup - LongMethod:SettingsReaderScreen.kt$SettingsReaderScreen$@Composable private fun getWebtoonGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup - LongMethod:SettingsSearchScreen.kt$@Composable private fun SearchResult( searchKey: String, modifier: Modifier = Modifier, listState: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(), onItemClick: (SearchResultItem) -> Unit, ) - LongMethod:SettingsSearchScreen.kt$SettingsSearchScreen$@Composable override fun Content() - LongMethod:SettingsTrackingScreen.kt$SettingsTrackingScreen$@Composable override fun getPreferences(): List<Preference> - LongMethod:SettingsTrackingScreen.kt$SettingsTrackingScreen$@Composable private fun TrackingLoginDialog( tracker: Tracker, uNameStringRes: StringResource, onDismissRequest: () -> Unit, ) - LongMethod:SourceFilterDialog.kt$@Composable private fun FilterItem(filter: Filter<*>, onUpdate: () -> Unit) - LongMethod:SourceSearchScreen.kt$SourceSearchScreen$@Composable override fun Content() + LongMethod:ReaderViewModel.kt$ReaderViewModel$suspend fun init(mangaId: Long, initialChapterId: Long /* SY --> */, page: Int?/* SY <-- */): Result<Boolean> + LongMethod:SYDomainModule.kt$SYDomainModule$override fun InjektRegistrar.registerInjectables() LongMethod:SyncChaptersWithSource.kt$SyncChaptersWithSource$suspend fun await( rawSourceChapters: List<SChapter>, manga: Manga, source: Source, manualFetch: Boolean = false, fetchWindow: Pair<Long, Long> = Pair(0, 0), ): List<Chapter> - LongMethod:TrackInfoDialog.kt$TrackInfoDialogHomeScreen$@Composable override fun Content() - LongMethod:TrackInfoDialog.kt$TrackerRemoveScreen$@Composable override fun Content() - LongMethod:TrackInfoDialogHome.kt$@Composable private fun TrackInfoItem( title: String, tracker: Tracker, status: StringResource?, onStatusClick: () -> Unit, chapters: String, onChaptersClick: () -> Unit, score: String?, onScoreClick: (() -> Unit)?, startDate: String?, onStartDateClick: (() -> Unit)?, endDate: String?, onEndDateClick: (() -> Unit)?, onNewSearch: () -> Unit, onOpenInBrowser: () -> Unit, onRemoved: () -> Unit, ) - LongMethod:TrackerSearch.kt$@Composable fun TrackerSearch( query: TextFieldValue, onQueryChange: (TextFieldValue) -> Unit, onDispatchQuery: () -> Unit, queryResult: Result<List<TrackSearch>>?, selected: TrackSearch?, onSelectedChange: (TrackSearch) -> Unit, onConfirmSelection: () -> Unit, onDismissRequest: () -> Unit, ) - LongMethod:TrackerSearch.kt$@Composable private fun SearchResultItem( trackSearch: TrackSearch, selected: Boolean, onClick: () -> Unit, ) - LongMethod:TriStateListDialog.kt$@Composable fun <T> TriStateListDialog( title: String, message: String? = null, items: List<T>, initialChecked: List<T>, initialInversed: List<T>, itemLabel: @Composable (T) -> String, onDismissRequest: () -> Unit, onValueChanged: (newIncluded: List<T>, newExcluded: List<T>) -> Unit, ) - LongMethod:UpdatesScreen.kt$@Composable fun UpdateScreen( state: UpdatesScreenModel.State, snackbarHostState: SnackbarHostState, lastUpdated: Long, onClickCover: (UpdatesItem) -> Unit, onSelectAll: (Boolean) -> Unit, onInvertSelection: () -> Unit, onUpdateLibrary: () -> Boolean, onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit, onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<UpdatesItem>, read: Boolean) -> Unit, onMultiDeleteClicked: (List<UpdatesItem>) -> Unit, onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit, onOpenChapter: (UpdatesItem) -> Unit, ) - LongMethod:UpdatesTab.kt$UpdatesTab$@Composable override fun Content() - LongMethod:UpdatesUiItem.kt$@Composable private fun UpdatesUiItem( update: UpdatesWithRelations, selected: Boolean, readProgress: String?, onClick: () -> Unit, onLongClick: () -> Unit, onClickCover: (() -> Unit)?, onDownloadChapter: ((ChapterDownloadAction) -> Unit)?, // Download Indicator downloadStateProvider: () -> Download.State, downloadProgressProvider: () -> Int, modifier: Modifier = Modifier, ) - LongMethod:UpdatesWidget.kt$@Composable fun UpdatesWidget( data: ImmutableList<Pair<Long, Bitmap?>>?, contentColor: ColorProvider, topPadding: Dp, bottomPadding: Dp, modifier: GlanceModifier = GlanceModifier, ) - LongMethod:VerticalFastScroller.kt$@Composable fun VerticalFastScroller( listState: LazyListState, modifier: Modifier = Modifier, thumbAllowed: () -> Boolean = { true }, thumbColor: Color = MaterialTheme.colorScheme.primary, topContentPadding: Dp = Dp.Hairline, bottomContentPadding: Dp = Dp.Hairline, endContentPadding: Dp = Dp.Hairline, content: @Composable () -> Unit, ) - LongMethod:VerticalFastScroller.kt$@Composable fun VerticalGridFastScroller( state: LazyGridState, columns: GridCells, arrangement: Arrangement.Horizontal, contentPadding: PaddingValues, modifier: Modifier = Modifier, thumbAllowed: () -> Boolean = { true }, thumbColor: Color = MaterialTheme.colorScheme.primary, topContentPadding: Dp = Dp.Hairline, bottomContentPadding: Dp = Dp.Hairline, endContentPadding: Dp = Dp.Hairline, content: @Composable () -> Unit, ) - LongMethod:WebViewScreenContent.kt$@Composable fun WebViewScreenContent( onNavigateUp: () -> Unit, initialTitle: String?, url: String, onShare: (String) -> Unit, onOpenInBrowser: (String) -> Unit, onClearCookies: (String) -> Unit, headers: Map<String, String> = emptyMap(), onUrlChange: (String) -> Unit = {}, ) + LongMethod:Tester.kt$Tester$@Test fun localFavoritesStorageTester(): Unit + LongMethod:TrackStatus.kt$TrackStatus.Companion$fun parseTrackerStatus(trackerManager: TrackerManager, tracker: Long, status: Long): TrackStatus? + LongMethod:Tsumino.kt$Tsumino$override suspend fun parseIntoMetadata(metadata: TsuminoSearchMetadata, input: Document) + LongMethod:UpdatesQuery.kt$UpdatesQuery$override fun <R> execute(mapper: (SqlCursor) -> QueryResult<R>): QueryResult<R> + LongMethod:UpdatesUiItem.kt$internal fun LazyListScope.updatesUiItems( 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, ) LongMethod:WebtoonRecyclerView.kt$WebtoonRecyclerView.Detector$override fun onTouchEvent(ev: MotionEvent): Boolean - LongMethod:WheelPicker.kt$@Composable private fun <T> WheelPicker( items: ImmutableList<T>, modifier: Modifier = Modifier, startIndex: Int = 0, size: DpSize = DpSize(128.dp, 128.dp), onSelectionChanged: (index: Int) -> Unit = {}, manualInputType: KeyboardType? = null, backgroundContent: (@Composable (size: DpSize) -> Unit)? = { WheelPickerDefaults.Background(size = it) }, itemContent: @Composable LazyItemScope.(item: T) -> Unit, ) - LongParameterList:BottomReaderBar.kt$( backgroundColor: Color, readingMode: ReadingMode, onClickReadingMode: () -> Unit, orientation: ReaderOrientation, onClickOrientation: () -> Unit, cropEnabled: Boolean, onClickCropBorder: () -> Unit, onClickSettings: () -> Unit, ) - LongParameterList:BrowseSourceScreen.kt$( source: Source?, mangaList: LazyPagingItems<StateFlow<Manga>>, columns: GridCells, displayMode: LibraryDisplayMode, snackbarHostState: SnackbarHostState, contentPadding: PaddingValues, onWebViewClick: () -> Unit, onHelpClick: () -> Unit, onLocalSourceHelpClick: () -> Unit, onMangaClick: (Manga) -> Unit, onMangaLongClick: (Manga) -> Unit, ) - LongParameterList:BrowseSourceToolbar.kt$( searchQuery: String?, onSearchQueryChange: (String?) -> Unit, source: Source?, displayMode: LibraryDisplayMode, onDisplayModeChange: (LibraryDisplayMode) -> Unit, navigateUp: () -> Unit, onWebViewClick: () -> Unit, onHelpClick: () -> Unit, onSettingsClick: () -> Unit, onSearch: (String) -> Unit, scrollBehavior: TopAppBarScrollBehavior? = null, ) - LongParameterList:CategoryListItem.kt$( category: Category, canMoveUp: Boolean, canMoveDown: Boolean, onMoveUp: (Category) -> Unit, onMoveDown: (Category) -> Unit, onRename: () -> Unit, onDelete: () -> Unit, modifier: Modifier = Modifier, ) - LongParameterList:CategoryScreen.kt$( categories: List<Category>, lazyListState: LazyListState, paddingValues: PaddingValues, onClickRename: (Category) -> Unit, onClickDelete: (Category) -> Unit, onMoveUp: (Category) -> Unit, onMoveDown: (Category) -> Unit, ) - LongParameterList:CategoryScreen.kt$( state: CategoryScreenState.Success, onClickCreate: () -> Unit, onClickSortAlphabetically: () -> Unit, onClickRename: (Category) -> Unit, onClickDelete: (Category) -> Unit, onClickMoveUp: (Category) -> Unit, onClickMoveDown: (Category) -> Unit, navigateUp: () -> Unit, ) - LongParameterList:ChapterNavigator.kt$( isRtl: Boolean, onNextChapter: () -> Unit, enabledNext: Boolean, onPreviousChapter: () -> Unit, enabledPrevious: Boolean, currentPage: Int, totalPages: Int, onSliderValueChange: (Int) -> Unit, ) - LongParameterList:ChapterRepositoryImpl.kt$ChapterRepositoryImpl$( id: Long, mangaId: Long, url: String, name: String, scanlator: String?, read: Boolean, bookmark: Boolean, lastPageRead: Long, chapterNumber: Double, sourceOrder: Long, dateFetch: Long, dateUpload: Long, lastModifiedAt: Long, ) - LongParameterList:ChapterSettingsDialog.kt$( downloadFilter: TriState, onDownloadFilterChanged: ((TriState) -> Unit)?, unreadFilter: TriState, onUnreadFilterChanged: (TriState) -> Unit, bookmarkedFilter: TriState, onBookmarkedFilterChanged: (TriState) -> Unit, scanlatorFilterActive: Boolean, onScanlatorFilterClicked: (() -> Unit), ) - LongParameterList:ChapterSettingsDialog.kt$( onDismissRequest: () -> Unit, manga: Manga? = null, onDownloadFilterChanged: (TriState) -> Unit, onUnreadFilterChanged: (TriState) -> Unit, onBookmarkedFilterChanged: (TriState) -> Unit, scanlatorFilterActive: Boolean, onScanlatorFilterClicked: (() -> Unit), onSortModeChanged: (Long) -> Unit, onDisplayModeChanged: (Long) -> Unit, onSetAsDefault: (applyToExistingManga: Boolean) -> Unit, onResetToDefault: () -> Unit, ) - LongParameterList:ChapterTransition.kt$( topLabel: String, topChapter: Chapter?, topChapterDownloaded: Boolean, bottomLabel: String, bottomChapter: Chapter?, bottomChapterDownloaded: Boolean, fallbackLabel: String, chapterGap: Int, ) - LongParameterList:ExtensionDetailsScreen.kt$( contentPadding: PaddingValues, extension: Extension.Installed, sources: ImmutableList<ExtensionSourceItem>, onClickSourcePreferences: (sourceId: Long) -> Unit, onClickUninstall: () -> Unit, onClickSource: (sourceId: Long) -> Unit, ) - LongParameterList:ExtensionDetailsScreen.kt$( navigateUp: () -> Unit, state: ExtensionDetailsScreenModel.State, onClickSourcePreferences: (sourceId: Long) -> Unit, onClickEnableAll: () -> Unit, onClickDisableAll: () -> Unit, onClickClearCookies: () -> Unit, onClickUninstall: () -> Unit, onClickSource: (sourceId: Long) -> Unit, ) - LongParameterList:ExtensionsScreen.kt$( item: ExtensionUiModel.Item, onClickItem: (Extension) -> Unit, onLongClickItem: (Extension) -> Unit, onClickItemCancel: (Extension) -> Unit, onClickItemAction: (Extension) -> Unit, onClickItemSecondaryAction: (Extension) -> Unit, modifier: Modifier = Modifier, ) - LongParameterList:ExtensionsScreen.kt$( state: ExtensionsScreenModel.State, contentPadding: PaddingValues, onLongClickItem: (Extension) -> Unit, onClickItemCancel: (Extension) -> Unit, onOpenWebView: (Extension.Available) -> Unit, onInstallExtension: (Extension.Available) -> Unit, onUninstallExtension: (Extension) -> Unit, onUpdateExtension: (Extension.Installed) -> Unit, onTrustExtension: (Extension.Untrusted) -> Unit, onOpenExtension: (Extension.Installed) -> Unit, onClickUpdateAll: () -> Unit, ) - LongParameterList:ExtensionsScreen.kt$( state: ExtensionsScreenModel.State, contentPadding: PaddingValues, searchQuery: String?, onLongClickItem: (Extension) -> Unit, onClickItemCancel: (Extension) -> Unit, onOpenWebView: (Extension.Available) -> Unit, onInstallExtension: (Extension.Available) -> Unit, onUninstallExtension: (Extension) -> Unit, onUpdateExtension: (Extension.Installed) -> Unit, onTrustExtension: (Extension.Untrusted) -> Unit, onOpenExtension: (Extension.Installed) -> Unit, onClickUpdateAll: () -> Unit, onRefresh: () -> Unit, ) - LongParameterList:GlobalSearchScreen.kt$( items: Map<CatalogueSource, SearchItemResult>, contentPadding: PaddingValues, getManga: @Composable (Manga) -> State<Manga>, onClickSource: (CatalogueSource) -> Unit, onClickItem: (Manga) -> Unit, onLongClickItem: (Manga) -> Unit, fromSourceId: Long? = null, ) - LongParameterList:GlobalSearchScreen.kt$( state: SearchScreenModel.State, navigateUp: () -> Unit, onChangeSearchQuery: (String?) -> Unit, onSearch: (String) -> Unit, onChangeSearchFilter: (SourceFilter) -> Unit, onToggleResults: () -> Unit, getManga: @Composable (Manga) -> State<Manga>, onClickSource: (CatalogueSource) -> Unit, onClickItem: (Manga) -> Unit, onLongClickItem: (Manga) -> Unit, ) - LongParameterList:GlobalSearchToolbar.kt$( searchQuery: String?, progress: Int, total: Int, navigateUp: () -> Unit, onChangeSearchQuery: (String?) -> Unit, onSearch: (String) -> Unit, sourceFilter: SourceFilter, onChangeSearchFilter: (SourceFilter) -> Unit, onlyShowHasResults: Boolean, onToggleResults: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, ) + LongParameterList:ChapterLoader.kt$ChapterLoader$( private val context: Context, private val downloadManager: DownloadManager, private val downloadProvider: DownloadProvider, private val manga: Manga, private val source: Source, // SY --> private val sourceManager: SourceManager, private val readerPrefs: ReaderPreferences, private val mergedReferences: List<MergedMangaReference>, private val mergedManga: Map<Long, Manga>, // SY <-- ) + LongParameterList:ChapterMapper.kt$ChapterMapper$( id: Long, mangaId: Long, url: String, name: String, scanlator: String?, read: Boolean, bookmark: Boolean, lastPageRead: Long, chapterNumber: Double, sourceOrder: Long, dateFetch: Long, dateUpload: Long, lastModifiedAt: Long, version: Long, @Suppress("UNUSED_PARAMETER") isSyncing: Long, ) + LongParameterList:Chip.kt$ChipColors$( private val containerColor: Color, private val labelColor: Color, private val leadingIconContentColor: Color, private val trailingIconContentColor: Color, private val disabledContainerColor: Color, private val disabledLabelColor: Color, private val disabledLeadingIconContentColor: Color, private val disabledTrailingIconContentColor: Color, ) + LongParameterList:EXHMigrations.kt$EXHMigrations$( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, pagePreviewCache: PagePreviewCache, ) + LongParameterList:FavoritesEntryRepositoryImpl.kt$FavoritesEntryRepositoryImpl$( gid: String, token: String, title: String, category: Long, otherGid: String?, otherToken: String?, ) LongParameterList:HistoryMapper.kt$HistoryMapper$( historyId: Long, mangaId: Long, chapterId: Long, title: String, thumbnailUrl: String?, sourceId: Long, isFavorite: Boolean, coverLastModified: Long, chapterNumber: Double, readAt: Date?, readDuration: Long, ) - LongParameterList:HistoryScreen.kt$( state: HistoryScreenModel.State, snackbarHostState: SnackbarHostState, onSearchQueryChange: (String?) -> Unit, onClickCover: (mangaId: Long) -> Unit, onClickResume: (mangaId: Long, chapterId: Long) -> Unit, onDialogChange: (HistoryScreenModel.Dialog?) -> Unit, ) - LongParameterList:InfoScreen.kt$( icon: ImageVector, headingText: String, subtitleText: String, acceptText: String, onAcceptClick: () -> Unit, canAccept: Boolean = true, rejectText: String? = null, onRejectClick: (() -> Unit)? = null, content: @Composable ColumnScope.() -> Unit, ) - LongParameterList:LibraryComfortableGrid.kt$( items: List<LibraryItem>, columns: Int, contentPadding: PaddingValues, selection: List<LibraryManga>, onClick: (LibraryManga) -> Unit, onLongClick: (LibraryManga) -> Unit, onClickContinueReading: ((LibraryManga) -> Unit)?, searchQuery: String?, onGlobalSearchClicked: () -> Unit, ) - LongParameterList:LibraryCompactGrid.kt$( items: List<LibraryItem>, showTitle: Boolean, columns: Int, contentPadding: PaddingValues, selection: List<LibraryManga>, onClick: (LibraryManga) -> Unit, onLongClick: (LibraryManga) -> Unit, onClickContinueReading: ((LibraryManga) -> Unit)?, searchQuery: String?, onGlobalSearchClicked: () -> Unit, ) - LongParameterList:LibraryContent.kt$( categories: List<Category>, searchQuery: String?, selection: List<LibraryManga>, contentPadding: PaddingValues, currentPage: () -> Int, hasActiveFilters: Boolean, showPageTabs: Boolean, onChangeCurrentPage: (Int) -> Unit, onMangaClicked: (Long) -> Unit, onContinueReadingClicked: ((LibraryManga) -> Unit)?, onToggleSelection: (LibraryManga) -> Unit, onToggleRangeSelection: (LibraryManga) -> Unit, onRefresh: (Category?) -> Boolean, onGlobalSearchClicked: () -> Unit, getNumberOfMangaForCategory: (Category) -> Int?, getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>, getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>, getLibraryForPage: (Int) -> List<LibraryItem>, ) - LongParameterList:LibraryList.kt$( items: List<LibraryItem>, contentPadding: PaddingValues, selection: List<LibraryManga>, onClick: (LibraryManga) -> Unit, onLongClick: (LibraryManga) -> Unit, onClickContinueReading: ((LibraryManga) -> Unit)?, searchQuery: String?, onGlobalSearchClicked: () -> Unit, ) - LongParameterList:LibraryPager.kt$( state: PagerState, contentPadding: PaddingValues, hasActiveFilters: Boolean, selectedManga: List<LibraryManga>, searchQuery: String?, onGlobalSearchClicked: () -> Unit, getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>, getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>, getLibraryForPage: (Int) -> List<LibraryItem>, onClickManga: (LibraryManga) -> Unit, onLongClickManga: (LibraryManga) -> Unit, onClickContinueReading: ((LibraryManga) -> Unit)?, ) - LongParameterList:LibraryToolbar.kt$( hasActiveFilters: Boolean, selectedCount: Int, title: LibraryToolbarTitle, onClickUnselectAll: () -> Unit, onClickSelectAll: () -> Unit, onClickInvertSelection: () -> Unit, onClickFilter: () -> Unit, onClickRefresh: () -> Unit, onClickGlobalUpdate: () -> Unit, onClickOpenRandomManga: () -> Unit, searchQuery: String?, onSearchQueryChange: (String?) -> Unit, scrollBehavior: TopAppBarScrollBehavior?, ) - LongParameterList:LibraryToolbar.kt$( title: LibraryToolbarTitle, hasFilters: Boolean, searchQuery: String?, onSearchQueryChange: (String?) -> Unit, onClickFilter: () -> Unit, onClickRefresh: () -> Unit, onClickGlobalUpdate: () -> Unit, onClickOpenRandomManga: () -> Unit, scrollBehavior: TopAppBarScrollBehavior?, ) - LongParameterList:ListPreferenceWidget.kt$( value: T, title: String, subtitle: String?, icon: ImageVector?, entries: Map<out T, String>, onValueChange: (T) -> Unit, ) - LongParameterList:MangaBottomActionMenu.kt$( visible: Boolean, onChangeCategoryClicked: () -> Unit, onMarkAsReadClicked: () -> Unit, onMarkAsUnreadClicked: () -> Unit, onDownloadClicked: ((DownloadAction) -> Unit)?, onDeleteClicked: () -> Unit, modifier: Modifier = Modifier, ) LongParameterList:MangaChapterListItem.kt$( action: LibraryPreferences.ChapterSwipeAction, read: Boolean, bookmark: Boolean, downloadState: Download.State, background: Color, onSwipe: () -> Unit, ) - LongParameterList:MangaChapterListItem.kt$( title: String, date: String?, readProgress: String?, scanlator: String?, read: Boolean, bookmark: Boolean, selected: Boolean, downloadIndicatorEnabled: Boolean, downloadStateProvider: () -> Download.State, downloadProgressProvider: () -> Int, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onLongClick: () -> Unit, onClick: () -> Unit, onDownloadClick: ((ChapterDownloadAction) -> Unit)?, onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit, modifier: Modifier = Modifier, ) - LongParameterList:MangaCoverDialog.kt$( coverDataProvider: () -> Manga, isCustomCover: Boolean, snackbarHostState: SnackbarHostState, onShareClick: () -> Unit, onSaveClick: () -> Unit, onEditClick: ((EditCoverAction) -> Unit)?, onDismissRequest: () -> Unit, ) LongParameterList:MangaCoverFetcher.kt$MangaCoverFetcher$( private val url: String?, private val isLibraryManga: Boolean, private val options: Options, private val coverFileLazy: Lazy<File?>, private val customCoverFileLazy: Lazy<File>, private val diskCacheKeyLazy: Lazy<String>, private val sourceLazy: Lazy<HttpSource?>, private val callFactoryLazy: Lazy<Call.Factory>, private val diskCacheLazy: Lazy<DiskCache>, ) - LongParameterList:MangaInfoHeader.kt$( appBarPadding: Dp, coverDataProvider: () -> Manga, onCoverClick: () -> Unit, title: String, doSearch: (query: String, global: Boolean) -> Unit, author: String?, artist: String?, status: Long, sourceName: String, isStubSource: Boolean, ) - LongParameterList:MangaInfoHeader.kt$( favorite: Boolean, trackingCount: Int, nextUpdate: Instant?, isUserIntervalMode: Boolean, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, onWebViewLongClicked: (() -> Unit)?, onTrackingClicked: () -> Unit, onEditIntervalClicked: (() -> Unit)?, onEditCategory: (() -> Unit)?, modifier: Modifier = Modifier, ) - LongParameterList:MangaInfoHeader.kt$( isTabletUi: Boolean, appBarPadding: Dp, title: String, author: String?, artist: String?, sourceName: String, isStubSource: Boolean, coverDataProvider: () -> Manga, status: Long, onCoverClick: () -> Unit, doSearch: (query: String, global: Boolean) -> Unit, modifier: Modifier = Modifier, ) - LongParameterList:MangaInfoHeader.kt$( title: String, doSearch: (query: String, global: Boolean) -> Unit, author: String?, artist: String?, status: Long, sourceName: String, isStubSource: Boolean, textAlign: TextAlign? = LocalTextStyle.current.textAlign, ) - LongParameterList:MangaMapper.kt$MangaMapper$( id: Long, source: Long, url: String, artist: String?, author: String?, description: String?, genre: List<String>?, title: String, status: Long, thumbnailUrl: String?, favorite: Boolean, lastUpdate: Long?, nextUpdate: Long?, initialized: Boolean, viewerFlags: Long, chapterFlags: Long, coverLastModified: Long, dateAdded: Long, updateStrategy: UpdateStrategy, calculateInterval: Long, lastModifiedAt: Long, favoriteModifiedAt: Long?, ) - LongParameterList:MangaMapper.kt$MangaMapper$( id: Long, source: Long, url: String, artist: String?, author: String?, description: String?, genre: List<String>?, title: String, status: Long, thumbnailUrl: String?, favorite: Boolean, lastUpdate: Long?, nextUpdate: Long?, initialized: Boolean, viewerFlags: Long, chapterFlags: Long, coverLastModified: Long, dateAdded: Long, updateStrategy: UpdateStrategy, calculateInterval: Long, lastModifiedAt: Long, favoriteModifiedAt: Long?, totalCount: Long, readCount: Double, latestUpload: Long, chapterFetchedAt: Long, lastRead: Long, bookmarkCount: Double, category: Long, ) - LongParameterList:MangaRestorer.kt$MangaRestorer$( manga: Manga, chapters: List<BackupChapter>, categories: List<Long>, backupCategories: List<BackupCategory>, history: List<BackupHistory>, tracks: List<BackupTracking>, excludedScanlators: List<String>, ) - LongParameterList:MangaScreen.kt$( manga: Manga, chapters: List<ChapterList>, isAnyChapterSelected: Boolean, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, ) - LongParameterList:MangaScreen.kt$( selected: List<ChapterList.Item>, onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit, onMarkPreviousAsReadClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onMultiDeleteClicked: (List<Chapter>) -> Unit, fillFraction: Float, modifier: Modifier = Modifier, ) - LongParameterList:MangaScreen.kt$( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, nextUpdate: Instant?, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, onWebViewLongClicked: (() -> Unit)?, onTrackingClicked: () -> Unit, // For tags menu onTagSearch: (String) -> Unit, onCopyTagToClipboard: (tag: String) -> Unit, onFilterButtonClicked: () -> Unit, onRefresh: () -> Unit, onContinueReading: () -> Unit, onSearch: (query: String, global: Boolean) -> Unit, // For cover dialog onCoverClicked: () -> Unit, // For top action menu onShareClicked: (() -> Unit)?, onDownloadActionClicked: ((DownloadAction) -> Unit)?, onEditCategoryClicked: (() -> Unit)?, onEditIntervalClicked: (() -> Unit)?, onMigrateClicked: (() -> Unit)?, // For bottom action menu onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit, onMarkPreviousAsReadClicked: (Chapter) -> Unit, onMultiDeleteClicked: (List<Chapter>) -> Unit, // For swipe actions onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, // Chapter selection onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onAllChapterSelected: (Boolean) -> Unit, onInvertSelection: () -> Unit, ) - LongParameterList:MangaScreen.kt$( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, nextUpdate: Instant?, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, onWebViewLongClicked: (() -> Unit)?, onTrackingClicked: () -> Unit, // For tags menu onTagSearch: (String) -> Unit, onCopyTagToClipboard: (tag: String) -> Unit, onFilterClicked: () -> Unit, onRefresh: () -> Unit, onContinueReading: () -> Unit, onSearch: (query: String, global: Boolean) -> Unit, // For cover dialog onCoverClicked: () -> Unit, // For top action menu onShareClicked: (() -> Unit)?, onDownloadActionClicked: ((DownloadAction) -> Unit)?, onEditCategoryClicked: (() -> Unit)?, onEditIntervalClicked: (() -> Unit)?, onMigrateClicked: (() -> Unit)?, // For bottom action menu onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit, onMarkPreviousAsReadClicked: (Chapter) -> Unit, onMultiDeleteClicked: (List<Chapter>) -> Unit, // For chapter swipe onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, // Chapter selection onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onAllChapterSelected: (Boolean) -> Unit, onInvertSelection: () -> Unit, ) - LongParameterList:MangaScreen.kt$( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, nextUpdate: Instant?, isTabletUi: Boolean, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, onWebViewLongClicked: (() -> Unit)?, onTrackingClicked: () -> Unit, // For tags menu onTagSearch: (String) -> Unit, onFilterButtonClicked: () -> Unit, onRefresh: () -> Unit, onContinueReading: () -> Unit, onSearch: (query: String, global: Boolean) -> Unit, // For cover dialog onCoverClicked: () -> Unit, // For top action menu onShareClicked: (() -> Unit)?, onDownloadActionClicked: ((DownloadAction) -> Unit)?, onEditCategoryClicked: (() -> Unit)?, onEditFetchIntervalClicked: (() -> Unit)?, onMigrateClicked: (() -> Unit)?, // For bottom action menu onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit, onMarkPreviousAsReadClicked: (Chapter) -> Unit, onMultiDeleteClicked: (List<Chapter>) -> Unit, // For chapter swipe onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, // Chapter selection onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onAllChapterSelected: (Boolean) -> Unit, onInvertSelection: () -> Unit, ) - LongParameterList:MangaToolbar.kt$( title: String, titleAlphaProvider: () -> Float, hasFilters: Boolean, onBackClicked: () -> Unit, onClickFilter: () -> Unit, onClickShare: (() -> Unit)?, onClickDownload: ((DownloadAction) -> Unit)?, onClickEditCategory: (() -> Unit)?, onClickRefresh: () -> Unit, onClickMigrate: (() -> Unit)?, // For action mode actionModeCounter: Int, onSelectAll: () -> Unit, onInvertSelection: () -> Unit, modifier: Modifier = Modifier, backgroundAlphaProvider: () -> Float = titleAlphaProvider, ) - LongParameterList:MigrateDialog.kt$( oldManga: Manga, newManga: Manga, screenModel: MigrateDialogScreenModel, onDismissRequest: () -> Unit, onClickTitle: () -> Unit, onPopScreen: () -> Unit, ) - LongParameterList:MigrateDialog.kt$MigrateDialogScreenModel$( oldSource: Source?, newSource: Source, oldManga: Manga, newManga: Manga, sourceChapters: List<SChapter>, replace: Boolean, flags: Int, ) - LongParameterList:MigrateSearchScreen.kt$( state: SearchScreenModel.State, fromSourceId: Long?, navigateUp: () -> Unit, onChangeSearchQuery: (String?) -> Unit, onSearch: (String) -> Unit, onChangeSearchFilter: (SourceFilter) -> Unit, onToggleResults: () -> Unit, getManga: @Composable (Manga) -> State<Manga>, onClickSource: (CatalogueSource) -> Unit, onClickItem: (Manga) -> Unit, onLongClickItem: (Manga) -> Unit, ) - LongParameterList:MigrateSourceScreen.kt$( list: ImmutableList<Pair<Source, Long>>, contentPadding: PaddingValues, onClickItem: (Source) -> Unit, onLongClickItem: (Source) -> Unit, sortingMode: SetMigrateSorting.Mode, onToggleSortingMode: () -> Unit, sortingDirection: SetMigrateSorting.Direction, onToggleSortingDirection: () -> Unit, ) - LongParameterList:MoreScreen.kt$( downloadQueueStateProvider: () -> DownloadQueueState, downloadedOnly: Boolean, onDownloadedOnlyChange: (Boolean) -> Unit, incognitoMode: Boolean, onIncognitoModeChange: (Boolean) -> Unit, isFDroid: Boolean, onClickDownloadQueue: () -> Unit, onClickCategories: () -> Unit, onClickStats: () -> Unit, onClickDataAndStorage: () -> Unit, onClickSettings: () -> Unit, onClickAbout: () -> Unit, ) - LongParameterList:ReaderAppBars.kt$( visible: Boolean, fullscreen: Boolean, mangaTitle: String?, chapterTitle: String?, navigateUp: () -> Unit, onClickTopAppBar: () -> Unit, bookmarked: Boolean, onToggleBookmarked: () -> Unit, onOpenInWebView: (() -> Unit)?, onShare: (() -> Unit)?, viewer: Viewer?, onNextChapter: () -> Unit, enabledNext: Boolean, onPreviousChapter: () -> Unit, enabledPrevious: Boolean, currentPage: Int, totalPages: Int, onSliderValueChange: (Int) -> Unit, readingMode: ReadingMode, onClickReadingMode: () -> Unit, orientation: ReaderOrientation, onClickOrientation: () -> Unit, cropEnabled: Boolean, onClickCropBorder: () -> Unit, onClickSettings: () -> Unit, ) - LongParameterList:Scaffold.kt$( fabPosition: FabPosition, topBar: @Composable () -> Unit, startBar: @Composable () -> Unit, content: @Composable (PaddingValues) -> Unit, snackbar: @Composable () -> Unit, fab: @Composable () -> Unit, contentWindowInsets: WindowInsets, bottomBar: @Composable () -> Unit, ) + LongParameterList:MangaMapper.kt$MangaMapper$( id: Long, source: Long, url: String, artist: String?, author: String?, description: String?, genre: List<String>?, title: String, status: Long, thumbnailUrl: String?, favorite: Boolean, lastUpdate: Long?, nextUpdate: Long?, initialized: Boolean, viewerFlags: Long, chapterFlags: Long, coverLastModified: Long, dateAdded: Long, // SY --> @Suppress("UNUSED_PARAMETER") filteredScanlators: String?, // SY <-- updateStrategy: UpdateStrategy, calculateInterval: Long, lastModifiedAt: Long, favoriteModifiedAt: Long?, ) + LongParameterList:MangaMapper.kt$MangaMapper$( id: Long, source: Long, url: String, artist: String?, author: String?, description: String?, genre: List<String>?, title: String, status: Long, thumbnailUrl: String?, favorite: Boolean, lastUpdate: Long?, nextUpdate: Long?, initialized: Boolean, viewerFlags: Long, chapterFlags: Long, coverLastModified: Long, dateAdded: Long, // SY --> @Suppress("UNUSED_PARAMETER") filteredScanlators: String?, // SY <-- updateStrategy: UpdateStrategy, calculateInterval: Long, lastModifiedAt: Long, favoriteModifiedAt: Long?, totalCount: Long, readCount: Double, latestUpload: Long, chapterFetchedAt: Long, lastRead: Long, bookmarkCount: Double, category: Long, ) + LongParameterList:MangaRestorer.kt$MangaRestorer$( manga: Manga, chapters: List<BackupChapter>, categories: List<Long>, backupCategories: List<BackupCategory>, history: List<BackupHistory>, tracks: List<BackupTracking>, excludedScanlators: List<String>, // SY --> mergedMangaReferences: List<BackupMergedMangaReference>, flatMetadata: BackupFlatMetadata?, customManga: CustomMangaInfo?, // SY <-- ) + LongParameterList:MangaScreen.kt$( manga: Manga, chapters: List<ChapterList>, isAnyChapterSelected: Boolean, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, // SY --> alwaysShowReadingProgress: Boolean, // SY <-- onChapterClicked: (Chapter) -> Unit, onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?, onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit, onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit, ) + LongParameterList:MangaScreenModel.kt$MangaScreenModel$( title: String?, author: String?, artist: String?, thumbnailUrl: String?, description: String?, tags: List<String>?, status: Long?, ) + LongParameterList:MergedMangaMapper.kt$MergedMangaMapper$( id: Long, isInfoManga: Boolean, getChapterUpdates: Boolean, chapterSortMode: Long, chapterPriority: Long, downloadChapters: Boolean, mergeId: Long, mergeUrl: String, mangaId: Long?, mangaUrl: String, mangaSourceId: Long, ) + LongParameterList:Migrations.kt$Migrations$( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, ) + LongParameterList:PageHandler.kt$PageHandler$( private val headers: Headers, private val service: MangaDexService, private val mangaPlusHandler: MangaPlusHandler, private val comikeyHandler: ComikeyHandler, private val bilibiliHandler: BilibiliHandler, private val azukiHandler: AzukiHandler, private val mangaHotHandler: MangaHotHandler, private val preferences: TrackPreferences, private val mdList: MdList, ) + LongParameterList:PagePreviewFetcher.kt$PagePreviewFetcher$( private val page: PagePreview, private val options: Options, private val pagePreviewFile: () -> File, private val isInCache: () -> Boolean, private val writeToCache: (Source) -> Unit, private val diskCacheKeyLazy: Lazy<String>, private val sourceLazy: Lazy<PagePreviewSource?>, private val callFactoryLazy: Lazy<Call.Factory>, private val diskCacheLazy: Lazy<DiskCache>, ) + LongParameterList:PagePreviews.kt$( pagePreviewState: PagePreviewState, onOpenPage: (Int) -> Unit, onMorePreviewsClicked: () -> Unit, maxWidth: Dp, setMaxWidth: (Dp) -> Unit, rowCount: Int, ) + LongParameterList:ReaderViewModel.kt$ReaderViewModel$( page1: ReaderPage, page2: ReaderPage, isLTR: Boolean, @ColorInt bg: Int, location: Location, manga: Manga, ) LongParameterList:Scrollbar.kt$( orientation: Orientation, reverseDirection: Boolean, atEnd: Boolean, showScrollbar: Boolean, thickness: Float, color: Color, alpha: () -> Float, thumbSize: Float, scrollOffset: Float, positionOffset: Float, ) LongParameterList:SetMangaChapterFlags.kt$SetMangaChapterFlags$( mangaId: Long, unreadFilter: Long, downloadedFilter: Long, bookmarkedFilter: Long, sortingMode: Long, sortingDirection: Long, displayMode: Long, ) LongParameterList:SyncChaptersWithSource.kt$SyncChaptersWithSource$( private val downloadManager: DownloadManager, private val downloadProvider: DownloadProvider, private val chapterRepository: ChapterRepository, private val shouldUpdateDbChapter: ShouldUpdateDbChapter, private val updateManga: UpdateManga, private val updateChapter: UpdateChapter, private val getChaptersByMangaId: GetChaptersByMangaId, private val getExcludedScanlators: GetExcludedScanlators, ) - LongParameterList:TrackInfoDialogHome.kt$( title: String, tracker: Tracker, status: StringResource?, onStatusClick: () -> Unit, chapters: String, onChaptersClick: () -> Unit, score: String?, onScoreClick: (() -> Unit)?, startDate: String?, onStartDateClick: (() -> Unit)?, endDate: String?, onEndDateClick: (() -> Unit)?, onNewSearch: () -> Unit, onOpenInBrowser: () -> Unit, onRemoved: () -> Unit, ) - LongParameterList:TrackInfoDialogHome.kt$( trackItems: List<TrackItem>, dateFormat: DateFormat, onStatusClick: (TrackItem) -> Unit, onChapterClick: (TrackItem) -> Unit, onScoreClick: (TrackItem) -> Unit, onStartDateEdit: (TrackItem) -> Unit, onEndDateEdit: (TrackItem) -> Unit, onNewSearch: (TrackItem) -> Unit, onOpenInBrowser: (TrackItem) -> Unit, onRemoved: (TrackItem) -> Unit, ) - LongParameterList:TrackInfoDialogSelector.kt$( title: String, initialSelectedDateMillis: Long, selectableDates: SelectableDates, onConfirm: (Long) -> Unit, onRemove: (() -> Unit)?, onDismissRequest: () -> Unit, ) LongParameterList:TrackMapper.kt$TrackMapper$( id: Long, mangaId: Long, syncId: Long, remoteId: Long, libraryId: Long?, title: String, lastChapterRead: Double, totalChapters: Long, status: Long, score: Double, remoteUrl: String, startDate: Long, finishDate: Long, ) - LongParameterList:TrackerSearch.kt$( query: TextFieldValue, onQueryChange: (TextFieldValue) -> Unit, onDispatchQuery: () -> Unit, queryResult: Result<List<TrackSearch>>?, selected: TrackSearch?, onSelectedChange: (TrackSearch) -> Unit, onConfirmSelection: () -> Unit, onDismissRequest: () -> Unit, ) - LongParameterList:TriStateListDialog.kt$( title: String, message: String? = null, items: List<T>, initialChecked: List<T>, initialInversed: List<T>, itemLabel: @Composable (T) -> String, onDismissRequest: () -> Unit, onValueChanged: (newIncluded: List<T>, newExcluded: List<T>) -> Unit, ) 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, ) - LongParameterList:UpdatesScreen.kt$( onUpdateLibrary: () -> Unit, // For action mode actionModeCounter: Int, onSelectAll: () -> Unit, onInvertSelection: () -> Unit, onCancelActionMode: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, modifier: Modifier = Modifier, ) - LongParameterList:UpdatesScreen.kt$( state: UpdatesScreenModel.State, snackbarHostState: SnackbarHostState, lastUpdated: Long, onClickCover: (UpdatesItem) -> Unit, onSelectAll: (Boolean) -> Unit, onInvertSelection: () -> Unit, onUpdateLibrary: () -> Boolean, onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit, onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<UpdatesItem>, read: Boolean) -> Unit, onMultiDeleteClicked: (List<UpdatesItem>) -> Unit, onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit, onOpenChapter: (UpdatesItem) -> Unit, ) - LongParameterList:UpdatesUiItem.kt$( uiModels: List<UpdatesUiModel>, selectionMode: Boolean, onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit, onClickCover: (UpdatesItem) -> Unit, onClickUpdate: (UpdatesItem) -> Unit, onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit, ) - LongParameterList:UpdatesUiItem.kt$( update: UpdatesWithRelations, selected: Boolean, readProgress: String?, onClick: () -> Unit, onLongClick: () -> Unit, onClickCover: (() -> Unit)?, onDownloadChapter: ((ChapterDownloadAction) -> Unit)?, // Download Indicator downloadStateProvider: () -> Download.State, downloadProgressProvider: () -> Int, modifier: Modifier = Modifier, ) - LongParameterList:WebViewScreenContent.kt$( onNavigateUp: () -> Unit, initialTitle: String?, url: String, onShare: (String) -> Unit, onOpenInBrowser: (String) -> Unit, onClearCookies: (String) -> Unit, headers: Map<String, String> = emptyMap(), onUrlChange: (String) -> Unit = {}, ) + 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, ) LongParameterList:WebtoonRecyclerView.kt$WebtoonRecyclerView$( fromRate: Float, toRate: Float, fromX: Float, toX: Float, fromY: Float, toY: Float, ) LoopWithTooManyJumpStatements:DownloadStore.kt$DownloadStore$for + LoopWithTooManyJumpStatements:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$for LoopWithTooManyJumpStatements:ImageUtil.kt$ImageUtil$for LoopWithTooManyJumpStatements:Kavita.kt$Kavita$for + LoopWithTooManyJumpStatements:MemAutoFlushingLookupTable.kt$MemAutoFlushingLookupTable$while + LoopWithTooManyJumpStatements:MigrationListScreenModel.kt$MigrationListScreenModel$for LoopWithTooManyJumpStatements:RateLimitInterceptor.kt$RateLimitInterceptor$while LoopWithTooManyJumpStatements:UpdatesScreenModel.kt$UpdatesScreenModel$for MagicNumber:AdaptiveSheet.kt$220 @@ -362,6 +597,7 @@ MagicNumber:AnilistModels.kt$90 MagicNumber:App.kt$App$300 MagicNumber:App.kt$App$8 + MagicNumber:AppModule.kt$AppModule$25 MagicNumber:AppThemePreferenceWidget.kt$0.3f MagicNumber:AppThemePreferenceWidget.kt$0.5f MagicNumber:AppThemePreferenceWidget.kt$0.6f @@ -372,10 +608,12 @@ MagicNumber:AppUpdateDownloadJob.kt$AppUpdateDownloadJob.<no name provided>$100 MagicNumber:AppUpdateDownloadJob.kt$AppUpdateDownloadJob.<no name provided>$200 MagicNumber:AppUpdateNotifier.kt$AppUpdateNotifier$100 + MagicNumber:AutoCompleteItem.kt$100 MagicNumber:Backup.kt$Backup$100 MagicNumber:Backup.kt$Backup$101 MagicNumber:Backup.kt$Backup$104 MagicNumber:Backup.kt$Backup$105 + MagicNumber:Backup.kt$Backup$600 MagicNumber:BackupCategory.kt$BackupCategory$100 MagicNumber:BackupChapter.kt$BackupChapter$10 MagicNumber:BackupChapter.kt$BackupChapter$11 @@ -388,6 +626,7 @@ MagicNumber:BackupChapter.kt$BackupChapter$9 MagicNumber:BackupCreateJob.kt$BackupCreateJob.Companion$10 MagicNumber:BackupDecoder.kt$BackupDecoder$0x1f8b + MagicNumber:BackupFlatMetadata.kt$BackupFlatMetadata$3 MagicNumber:BackupHistory.kt$BackupHistory$3 MagicNumber:BackupManga.kt$BackupManga$100 MagicNumber:BackupManga.kt$BackupManga$101 @@ -407,10 +646,30 @@ MagicNumber:BackupManga.kt$BackupManga$4 MagicNumber:BackupManga.kt$BackupManga$5 MagicNumber:BackupManga.kt$BackupManga$6 + MagicNumber:BackupManga.kt$BackupManga$600 + MagicNumber:BackupManga.kt$BackupManga$601 + MagicNumber:BackupManga.kt$BackupManga$602 + MagicNumber:BackupManga.kt$BackupManga$603 MagicNumber:BackupManga.kt$BackupManga$7 MagicNumber:BackupManga.kt$BackupManga$8 + MagicNumber:BackupManga.kt$BackupManga$800 + MagicNumber:BackupManga.kt$BackupManga$801 + MagicNumber:BackupManga.kt$BackupManga$802 + MagicNumber:BackupManga.kt$BackupManga$804 + MagicNumber:BackupManga.kt$BackupManga$805 MagicNumber:BackupManga.kt$BackupManga$9 + MagicNumber:BackupMergedMangaReference.kt$BackupMergedMangaReference$3 + MagicNumber:BackupMergedMangaReference.kt$BackupMergedMangaReference$4 + MagicNumber:BackupMergedMangaReference.kt$BackupMergedMangaReference$5 + MagicNumber:BackupMergedMangaReference.kt$BackupMergedMangaReference$6 + MagicNumber:BackupMergedMangaReference.kt$BackupMergedMangaReference$7 + MagicNumber:BackupMergedMangaReference.kt$BackupMergedMangaReference$8 MagicNumber:BackupPreferences.kt$BackupPreferences$12 + MagicNumber:BackupSavedSearch.kt$BackupSavedSearch$3 + MagicNumber:BackupSavedSearch.kt$BackupSavedSearch$4 + MagicNumber:BackupSearchMetadata.kt$BackupSearchMetadata$3 + MagicNumber:BackupSearchMetadata.kt$BackupSearchMetadata$4 + MagicNumber:BackupSearchTag.kt$BackupSearchTag$3 MagicNumber:BackupTracking.kt$BackupTracking$10 MagicNumber:BackupTracking.kt$BackupTracking$100 MagicNumber:BackupTracking.kt$BackupTracking$11 @@ -429,8 +688,19 @@ MagicNumber:BangumiModels.kt$3600 MagicNumber:BangumiModels.kt$OAuth$1000 MagicNumber:BasePreferenceWidget.kt$200 + MagicNumber:BatchAddScreen.kt$BatchAddScreen$0.15f MagicNumber:BrowseIcons.kt$0x1F888888 + MagicNumber:BrowseSourceEHentaiList.kt$0.5F + MagicNumber:BrowseSourceEHentaiList.kt$0xE1E2ECFF + MagicNumber:BrowseSourceEHentaiList.kt$0xFF005ED7 + MagicNumber:BrowseSourceEHentaiList.kt$5 + MagicNumber:CbzCrypto.kt$CbzCrypto$100 + MagicNumber:CbzCrypto.kt$CbzCrypto$128 + MagicNumber:CbzCrypto.kt$CbzCrypto$32 + MagicNumber:CbzCrypto.kt$CbzCrypto$42 + MagicNumber:ChapterCache.kt$ChapterCache$1024 MagicNumber:ChapterDownloadIndicator.kt$0.5f + MagicNumber:ChapterNavigator.kt$90f MagicNumber:ChapterRecognition.kt$ChapterRecognition$10 MagicNumber:ChapterRecognition.kt$ChapterRecognition$10.0 MagicNumber:ChapterRecognition.kt$ChapterRecognition$2.0 @@ -450,6 +720,8 @@ MagicNumber:DeviceUtil.kt$DeviceUtil$3L MagicNumber:DeviceUtil.kt$DeviceUtil$90000 MagicNumber:DiskUtil.kt$DiskUtil$240 + MagicNumber:DomainSourceHelpers.kt$6900 + MagicNumber:DomainSourceHelpers.kt$6999 MagicNumber:Download.kt$Download.State.DOWNLOADED$3 MagicNumber:Download.kt$Download.State.ERROR$4 MagicNumber:DownloadCache.kt$DownloadCache$1000 @@ -468,13 +740,135 @@ MagicNumber:Downloader.kt$Downloader$3 MagicNumber:Downloader.kt$Downloader$5 MagicNumber:DropdownMenu.kt$56 + MagicNumber:EHConfigurator.kt$EHConfigurator$3 + MagicNumber:EHDebugModeOverlay.kt$0x7F000000 + MagicNumber:EHDebugModeOverlay.kt$FpsState$1000f + MagicNumber:EHentai.kt$EHentai$0.5 + MagicNumber:EHentai.kt$EHentai$14 + MagicNumber:EHentai.kt$EHentai$16 + MagicNumber:EHentai.kt$EHentai$17 + MagicNumber:EHentai.kt$EHentai$200 + MagicNumber:EHentai.kt$EHentai$2007 + MagicNumber:EHentai.kt$EHentai$2099 + MagicNumber:EHentai.kt$EHentai$21 + MagicNumber:EHentai.kt$EHentai$3 + MagicNumber:EHentai.kt$EHentai$4 + MagicNumber:EHentai.kt$EHentai$404 + MagicNumber:EHentai.kt$EHentai$5 + MagicNumber:EHentai.kt$EHentai$8 + MagicNumber:EHentai.kt$EHentai$9 + MagicNumber:EHentai.kt$EHentai.GenreGroup$128 + MagicNumber:EHentai.kt$EHentai.GenreGroup$16 + MagicNumber:EHentai.kt$EHentai.GenreGroup$256 + MagicNumber:EHentai.kt$EHentai.GenreGroup$32 + MagicNumber:EHentai.kt$EHentai.GenreGroup$4 + MagicNumber:EHentai.kt$EHentai.GenreGroup$512 + MagicNumber:EHentai.kt$EHentai.GenreGroup$64 + MagicNumber:EHentai.kt$EHentai.GenreGroup$8 + MagicNumber:EHentai.kt$EHentai.ThumbnailPreviewInterceptor$100 + MagicNumber:EHentai.kt$EHentai.ToplistOption.ALL_TIME$11 + MagicNumber:EHentai.kt$EHentai.ToplistOption.PAST_MONTH$13 + MagicNumber:EHentai.kt$EHentai.ToplistOption.PAST_YEAR$12 + MagicNumber:EHentai.kt$EHentai.ToplistOption.YESTERDAY$15 + MagicNumber:EHentaiUpdateWorker.kt$EHentaiUpdateWorker.Companion$10 + MagicNumber:EXHMigrations.kt$EXHMigrations$0b00100000L + MagicNumber:EXHMigrations.kt$EXHMigrations$0b00111100L + MagicNumber:EXHMigrations.kt$EXHMigrations$10 + MagicNumber:EXHMigrations.kt$EXHMigrations$12 + MagicNumber:EXHMigrations.kt$EXHMigrations$14 + MagicNumber:EXHMigrations.kt$EXHMigrations$16 + MagicNumber:EXHMigrations.kt$EXHMigrations$17 + MagicNumber:EXHMigrations.kt$EXHMigrations$18 + MagicNumber:EXHMigrations.kt$EXHMigrations$20 + MagicNumber:EXHMigrations.kt$EXHMigrations$22 + MagicNumber:EXHMigrations.kt$EXHMigrations$23 + MagicNumber:EXHMigrations.kt$EXHMigrations$24 + MagicNumber:EXHMigrations.kt$EXHMigrations$27 + MagicNumber:EXHMigrations.kt$EXHMigrations$28 + MagicNumber:EXHMigrations.kt$EXHMigrations$29 + MagicNumber:EXHMigrations.kt$EXHMigrations$3 + MagicNumber:EXHMigrations.kt$EXHMigrations$31 + MagicNumber:EXHMigrations.kt$EXHMigrations$32 + MagicNumber:EXHMigrations.kt$EXHMigrations$38 + MagicNumber:EXHMigrations.kt$EXHMigrations$39 + MagicNumber:EXHMigrations.kt$EXHMigrations$4 + MagicNumber:EXHMigrations.kt$EXHMigrations$40 + MagicNumber:EXHMigrations.kt$EXHMigrations$41 + MagicNumber:EXHMigrations.kt$EXHMigrations$42 + MagicNumber:EXHMigrations.kt$EXHMigrations$43 + MagicNumber:EXHMigrations.kt$EXHMigrations$44 + MagicNumber:EXHMigrations.kt$EXHMigrations$45 + MagicNumber:EXHMigrations.kt$EXHMigrations$5 + MagicNumber:EXHMigrations.kt$EXHMigrations$52 + MagicNumber:EXHMigrations.kt$EXHMigrations$56 + MagicNumber:EXHMigrations.kt$EXHMigrations$57 + MagicNumber:EXHMigrations.kt$EXHMigrations$58 + MagicNumber:EXHMigrations.kt$EXHMigrations$59 + MagicNumber:EXHMigrations.kt$EXHMigrations$6 + MagicNumber:EXHMigrations.kt$EXHMigrations$60 + MagicNumber:EXHMigrations.kt$EXHMigrations$66 + MagicNumber:EXHMigrations.kt$EXHMigrations$6907 + MagicNumber:EXHMigrations.kt$EXHMigrations$6907L + MagicNumber:EXHMigrations.kt$EXHMigrations$6909L + MagicNumber:EXHMigrations.kt$EXHMigrations$6912 + MagicNumber:EXHMigrations.kt$EXHMigrations$6912L + MagicNumber:EXHMigrations.kt$EXHMigrations$7 + MagicNumber:EXHMigrations.kt$EXHMigrations$8 + MagicNumber:EXHMigrations.kt$EXHMigrations$9 + MagicNumber:EditMangaDialog.kt$20 + MagicNumber:EditMangaDialog.kt$3 + MagicNumber:EditMangaDialog.kt$4 + MagicNumber:EditMangaDialog.kt$40 + MagicNumber:EditMangaDialog.kt$46 + MagicNumber:EditMangaDialog.kt$5 + MagicNumber:EditMangaDialog.kt$6 + MagicNumber:EditMangaDialog.kt$61 + MagicNumber:EditMangaDialog.kt$62 + MagicNumber:EditMangaDialog.kt$63 + MagicNumber:EditMergedMangaHolder.kt$EditMergedMangaHolder$0.5F + MagicNumber:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter.HeaderViewHolder$0.5F + MagicNumber:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter.HeaderViewHolder$3 + MagicNumber:EhLoginWebViewScreen.kt$0.5F + MagicNumber:EhLoginWebViewScreen.kt$0.8F + MagicNumber:EhLoginWebViewScreen.kt$0xb5000000 + MagicNumber:EhUConfigBuilder.kt$Entry.Categories$3 + MagicNumber:EhUConfigBuilder.kt$Entry.Categories$4 + MagicNumber:EhUConfigBuilder.kt$Entry.Categories$5 + MagicNumber:EhUConfigBuilder.kt$Entry.Categories$6 + MagicNumber:EhUConfigBuilder.kt$Entry.Categories$7 + MagicNumber:EhUConfigBuilder.kt$Entry.Categories$8 + MagicNumber:EhUConfigBuilder.kt$Entry.Categories$9 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$10 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$11 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$12 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$13 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$14 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$15 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$16 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$3 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$4 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$5 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$6 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$7 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$8 + MagicNumber:EhUConfigBuilder.kt$Entry.LanguageSystem$9 + MagicNumber:ExhUtils.kt$0.5f + MagicNumber:ExhUtils.kt$0.75f + MagicNumber:ExhUtils.kt$0.9f + MagicNumber:ExhUtils.kt$3f MagicNumber:ExtensionDetailsScreen.kt$1.5f MagicNumber:ExtensionInstallService.kt$ExtensionInstallService$100 + MagicNumber:FavoritesSyncHelper.kt$FavoritesSyncHelper$10 + MagicNumber:FeedScreenModel.kt$FeedScreenModel$10 MagicNumber:FetchInterval.kt$FetchInterval$10 MagicNumber:FetchInterval.kt$FetchInterval$1000 MagicNumber:FetchInterval.kt$FetchInterval$3 MagicNumber:FetchInterval.kt$FetchInterval$7 MagicNumber:FetchInterval.kt$FetchInterval$8 + MagicNumber:FollowStatus.kt$FollowStatus.DROPPED$5L + MagicNumber:FollowStatus.kt$FollowStatus.ON_HOLD$3L + MagicNumber:FollowStatus.kt$FollowStatus.PLAN_TO_READ$4L + MagicNumber:FollowStatus.kt$FollowStatus.RE_READING$6L MagicNumber:GetApplicationRelease.kt$GetApplicationRelease$3 MagicNumber:GlanceUtils.kt$10 MagicNumber:GlanceUtils.kt$64 @@ -490,6 +884,7 @@ MagicNumber:ImageUtil.kt$ImageUtil$0.0275 MagicNumber:ImageUtil.kt$ImageUtil$100 MagicNumber:ImageUtil.kt$ImageUtil$14 + MagicNumber:ImageUtil.kt$ImageUtil$16384 MagicNumber:ImageUtil.kt$ImageUtil$18 MagicNumber:ImageUtil.kt$ImageUtil$200 MagicNumber:ImageUtil.kt$ImageUtil$22 @@ -503,6 +898,10 @@ MagicNumber:ImageUtil.kt$ImageUtil$6 MagicNumber:ImageUtil.kt$ImageUtil$740 MagicNumber:ImageUtil.kt$ImageUtil$9 + MagicNumber:ImageUtil.kt$ImageUtil$96 + MagicNumber:ImageUtil.kt$ImageUtil$98 + MagicNumber:ImageUtil.kt$ImageUtil$99 + MagicNumber:IsTrackUnfollowed.kt$IsTrackUnfollowed$60L MagicNumber:Kavita.kt$Kavita$0xff MagicNumber:Kavita.kt$Kavita$148 MagicNumber:Kavita.kt$Kavita$198 @@ -524,15 +923,19 @@ MagicNumber:Komga.kt$Komga$37 MagicNumber:Komga.kt$Komga$50 MagicNumber:Komga.kt$Komga$51 + MagicNumber:LewdMangaChecker.kt$6905L + MagicNumber:LewdMangaChecker.kt$6913L MagicNumber:LibraryScreenModel.kt$LibraryScreenModel$10 MagicNumber:LibraryScreenModel.kt$LibraryScreenModel$25 MagicNumber:LibraryScreenModel.kt$LibraryScreenModel$5 + MagicNumber:LibrarySettingsDialog.kt$3 MagicNumber:LibrarySortMode.kt$LibrarySort.Direction.Ascending$0b01000000 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.ChapterFetchDate$0b00011000 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.DateAdded$0b00011100 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.LastRead$0b00000100 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.LastUpdate$0b00001000 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.LatestChapter$0b00010100 + MagicNumber:LibrarySortMode.kt$LibrarySort.Type.TagList$0b00100100 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.TotalChapters$0b00010000 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.TrackerMean$0b000100000 MagicNumber:LibrarySortMode.kt$LibrarySort.Type.UnreadCount$0b00001100 @@ -547,8 +950,11 @@ MagicNumber:MangaBottomActionMenu.kt$6 MagicNumber:MangaBottomActionMenu.kt$7 MagicNumber:MangaCover.kt$MangaCover.Book$3f + MagicNumber:MangaDexAuthInterceptor.kt$MangaDexAuthInterceptor$401 + MagicNumber:MangaDexDescriptionAdapter.kt$100.0 MagicNumber:MangaInfoHeader.kt$0.2f MagicNumber:MangaInfoHeader.kt$0.65f + MagicNumber:MangaPlusHandler.kt$MangaPlusHandler$16 MagicNumber:MangaScreenModel.kt$MangaScreenModel$10 MagicNumber:MangaScreenModel.kt$MangaScreenModel$103 MagicNumber:MangaScreenModel.kt$MangaScreenModel$25 @@ -557,7 +963,70 @@ MagicNumber:MangaUpdates.kt$MangaUpdates$160 MagicNumber:MangaUpdates.kt$MangaUpdates$173 MagicNumber:MangaUpdatesApi.kt$MangaUpdatesApi$200 + MagicNumber:MdList.kt$MdList$3L + MagicNumber:MdList.kt$MdList$43 + MagicNumber:MdList.kt$MdList$48 + MagicNumber:MdList.kt$MdList$4L + MagicNumber:MdList.kt$MdList$53 + MagicNumber:MdList.kt$MdList$5L + MagicNumber:MdList.kt$MdList$6L + MagicNumber:MemAutoFlushingLookupTable.kt$MemAutoFlushingLookupTable$4 + MagicNumber:MemAutoFlushingLookupTable.kt$MemAutoFlushingLookupTable$8 + MagicNumber:MergedSource.kt$MergedSource$5 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$10 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$3 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$4 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$5 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$6 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$7 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$8 + MagicNumber:MetadataUIUtil.kt$MetadataUIUtil$9 MagicNumber:MetadataUpdateJob.kt$MetadataUpdateJob$5 + MagicNumber:MetadataUtil.kt$MetadataUtil$1000 + MagicNumber:MetadataUtil.kt$MetadataUtil$1024 + MagicNumber:MigrationActionIcon.kt$56 + MagicNumber:MigrationItem.kt$0.33f + MagicNumber:MigrationItem.kt$0xAA000000 + MagicNumber:MigrationListScreen.kt$0.2f + MagicNumber:MigrationListScreenModel.kt$MigrationListScreenModel$3 + MagicNumber:Migrations.kt$Migrations$105 + MagicNumber:Migrations.kt$Migrations$106 + MagicNumber:Migrations.kt$Migrations$113 + MagicNumber:Migrations.kt$Migrations$114 + MagicNumber:Migrations.kt$Migrations$116 + MagicNumber:Migrations.kt$Migrations$117 + MagicNumber:Migrations.kt$Migrations$12 + MagicNumber:Migrations.kt$Migrations$15 + MagicNumber:Migrations.kt$Migrations$19 + MagicNumber:Migrations.kt$Migrations$26 + MagicNumber:Migrations.kt$Migrations$3 + MagicNumber:Migrations.kt$Migrations$4 + MagicNumber:Migrations.kt$Migrations$44 + MagicNumber:Migrations.kt$Migrations$5 + MagicNumber:Migrations.kt$Migrations$52 + MagicNumber:Migrations.kt$Migrations$54 + MagicNumber:Migrations.kt$Migrations$57 + MagicNumber:Migrations.kt$Migrations$59 + MagicNumber:Migrations.kt$Migrations$6 + MagicNumber:Migrations.kt$Migrations$60 + MagicNumber:Migrations.kt$Migrations$61 + MagicNumber:Migrations.kt$Migrations$64 + MagicNumber:Migrations.kt$Migrations$7 + MagicNumber:Migrations.kt$Migrations$70 + MagicNumber:Migrations.kt$Migrations$71 + MagicNumber:Migrations.kt$Migrations$72 + MagicNumber:Migrations.kt$Migrations$75 + MagicNumber:Migrations.kt$Migrations$77 + MagicNumber:Migrations.kt$Migrations$8 + MagicNumber:Migrations.kt$Migrations$81 + MagicNumber:Migrations.kt$Migrations$82 + MagicNumber:Migrations.kt$Migrations$84 + MagicNumber:Migrations.kt$Migrations$85 + MagicNumber:Migrations.kt$Migrations$86 + MagicNumber:Migrations.kt$Migrations$92 + MagicNumber:Migrations.kt$Migrations$96 + MagicNumber:Migrations.kt$Migrations$97 + MagicNumber:Migrations.kt$Migrations$99 MagicNumber:Modifier.kt$0.16f MagicNumber:Modifier.kt$0.22f MagicNumber:MonetColorScheme.kt$MonetColorScheme.Companion$128 @@ -566,19 +1035,29 @@ MagicNumber:MyAnimeList.kt$MyAnimeList$81 MagicNumber:MyAnimeListApi.kt$MyAnimeListApi$64 MagicNumber:MyAnimeListInterceptor.kt$MyAnimeListInterceptor$401 - MagicNumber:MyAnimeListModels.kt$1000 MagicNumber:NetworkHelper.kt$NetworkHelper$30 MagicNumber:Page.kt$Page$100 MagicNumber:PageIndicatorText.kt$235 MagicNumber:PageIndicatorText.kt$45 + MagicNumber:PagePreviewCache.kt$PagePreviewCache$1024 + MagicNumber:PagePreviewSource.kt$PagePreviewInfo$100 + MagicNumber:PagerConfig.kt$PagerConfig$0x202125 MagicNumber:PagerConfig.kt$PagerConfig$3 MagicNumber:PagerConfig.kt$PagerConfig$4 MagicNumber:PagerConfig.kt$PagerConfig$5 + MagicNumber:PagerPageHolder.kt$PagerPageHolder$100 MagicNumber:PagerPageHolder.kt$PagerPageHolder$16 + MagicNumber:PagerPageHolder.kt$PagerPageHolder$48 MagicNumber:PagerPageHolder.kt$PagerPageHolder$90f + MagicNumber:PagerPageHolder.kt$PagerPageHolder$95 + MagicNumber:PagerPageHolder.kt$PagerPageHolder$96 + MagicNumber:PagerPageHolder.kt$PagerPageHolder$97 MagicNumber:PagerViewer.kt$PagerViewer$5 + MagicNumber:PagerViewerAdapter.kt$PagerViewerAdapter$100 MagicNumber:PkceUtil.kt$PkceUtil$50 MagicNumber:PullRefresh.kt$PullToRefreshStateImpl$4 + MagicNumber:PururinDescriptionAdapter.kt$100.0 + MagicNumber:ReaderActivity.kt$ReaderActivity$100 MagicNumber:ReaderActivity.kt$ReaderActivity$230 MagicNumber:ReaderActivity.kt$ReaderActivity$242 MagicNumber:ReaderActivity.kt$ReaderActivity.ReaderConfig$0.01f @@ -596,6 +1075,8 @@ MagicNumber:ReaderPageImageView.kt$ReaderPageImageView$180 MagicNumber:ReaderPageImageView.kt$ReaderPageImageView$250 MagicNumber:ReaderPageImageView.kt$ReaderPageImageView$500 + MagicNumber:ReaderPreferences.kt$ReaderPreferences$10 + MagicNumber:ReaderPreferences.kt$ReaderPreferences$3f MagicNumber:ReaderPreferences.kt$ReaderPreferences$500 MagicNumber:ReaderPreferences.kt$ReaderPreferences.ReaderHideThreshold.HIGH$13 MagicNumber:ReaderPreferences.kt$ReaderPreferences.ReaderHideThreshold.HIGHEST$5 @@ -604,6 +1085,7 @@ MagicNumber:ReaderProgressIndicator.kt$ReaderProgressIndicator$100f MagicNumber:ReaderSettingsDialog.kt$0.5f MagicNumber:ReaderViewModel.kt$ReaderViewModel$0.25 + MagicNumber:ReaderViewModel.kt$ReaderViewModel$9999 MagicNumber:ReadingMode.kt$ReadingMode.CONTINUOUS_VERTICAL$0x00000005 MagicNumber:ReadingMode.kt$ReadingMode.VERTICAL$0x00000003 MagicNumber:ReadingMode.kt$ReadingMode.WEBTOON$0x00000004 @@ -621,6 +1103,7 @@ MagicNumber:Scrollbar.kt$100 MagicNumber:Scrollbar.kt$50 MagicNumber:SecureActivityDelegate.kt$SecureActivityDelegate.Companion$60_000 + MagicNumber:SecurityPreferences.kt$SecurityPreferences$0x7F MagicNumber:SettingsDataScreen.kt$SettingsDataScreen$12 MagicNumber:SettingsDataScreen.kt$SettingsDataScreen$168 MagicNumber:SettingsDataScreen.kt$SettingsDataScreen$24 @@ -630,6 +1113,28 @@ MagicNumber:SettingsDownloadScreen.kt$SettingsDownloadScreen$3 MagicNumber:SettingsDownloadScreen.kt$SettingsDownloadScreen$4 MagicNumber:SettingsDownloadScreen.kt$SettingsDownloadScreen$5 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$12 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$24 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$3 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$30 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$365 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$48 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$6 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen$7 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$10 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$11 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$12 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$13 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$14 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$15 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$16 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$3 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$4 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$5 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$6 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$7 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$8 + MagicNumber:SettingsEhScreen.kt$SettingsEhScreen.LanguageDialogState$9 MagicNumber:SettingsItems.kt$0.5f MagicNumber:SettingsItems.kt$1.5f MagicNumber:SettingsLibraryScreen.kt$SettingsLibraryScreen$12 @@ -640,14 +1145,27 @@ MagicNumber:SettingsMainScreen.kt$SettingsMainScreen$0.02f MagicNumber:SettingsMainScreen.kt$SettingsMainScreen$0.05f MagicNumber:SettingsMainScreen.kt$SettingsMainScreen$3 + MagicNumber:SettingsMangadexScreen.kt$SettingsMangadexScreen$5 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$10 MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$100f + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$12 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$14 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$16 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$20 MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$250 MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$3 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$4 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$5 MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$500 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$6 + MagicNumber:SettingsReaderScreen.kt$SettingsReaderScreen$8 MagicNumber:SettingsSearchScreen.kt$10 MagicNumber:Shikimori.kt$Shikimori$40 MagicNumber:ShikimoriModels.kt$1000 MagicNumber:ShikimoriModels.kt$3600 + MagicNumber:SmartSearchEngine.kt$SmartSearchEngine$5 + MagicNumber:SourceFeedScreenModel.kt$SourceFeedScreenModel$10 + MagicNumber:SourcePreferences.kt$SourcePreferences$80 MagicNumber:Surface.kt$100f MagicNumber:Surface.kt$4.5f MagicNumber:Suwayomi.kt$Suwayomi$255 @@ -660,6 +1178,11 @@ MagicNumber:TrackInfoDialogSelector.kt$4L MagicNumber:TrackInfoDialogSelector.kt$5L MagicNumber:TrackInfoDialogSelector.kt$6L + MagicNumber:TrackStatus.kt$TrackStatus.COMPLETED$5 + MagicNumber:TrackStatus.kt$TrackStatus.DROPPED$6 + MagicNumber:TrackStatus.kt$TrackStatus.OTHER$7 + MagicNumber:TrackStatus.kt$TrackStatus.PAUSED$4 + MagicNumber:TrackStatus.kt$TrackStatus.PLAN_TO_READ$3 MagicNumber:TrackerSearchPreviewProvider.kt$TrackerSearchPreviewProvider$10 MagicNumber:TrackerSearchPreviewProvider.kt$TrackerSearchPreviewProvider$100 MagicNumber:TrackerSearchPreviewProvider.kt$TrackerSearchPreviewProvider$1000L @@ -668,6 +1191,8 @@ MagicNumber:TrackerSearchPreviewProvider.kt$TrackerSearchPreviewProvider$365 MagicNumber:TrackerSearchPreviewProvider.kt$TrackerSearchPreviewProvider$40 MagicNumber:TrackingPreferenceWidget.kt$0xFF4CAF50 + MagicNumber:TsuminoDescriptionAdapter.kt$100.0 + MagicNumber:UiPreferences.kt$UiPreferences$4 MagicNumber:UniFileTempFileManager.kt$UniFileTempFileManager$3 MagicNumber:UniFileTempFileManager.kt$UniFileTempFileManager$8192 MagicNumber:UpdatesScreenModel.kt$UpdatesScreenModel$3 @@ -710,33 +1235,249 @@ MagicNumber:WorkManagerExtensions.kt$500 MatchingDeclarationName:ChapterDownloadIndicator.kt$ChapterDownloadAction MatchingDeclarationName:CommonMangaItem.kt$CommonMangaItemDefaults + MatchingDeclarationName:EditMergedSettingsDialog.kt$EditMergedSettingsState : EditMergedMangaItemListener MatchingDeclarationName:EmptyScreen.kt$EmptyScreenAction + MatchingDeclarationName:FeedScreen.kt$FeedItemUI MatchingDeclarationName:LibrarySortMode.kt$LibrarySort : FlagWithMask MatchingDeclarationName:MyAnimeListModels.kt$OAuth MatchingDeclarationName:NetworkStateTracker.kt$NetworkState MatchingDeclarationName:SettingsItems.kt$SettingsItemsPaddings MatchingDeclarationName:ShikimoriModels.kt$OAuth + MatchingDeclarationName:SourceFeedScreen.kt$SourceFeedUI + MatchingDeclarationName:SyncFavoritesProgressDialog.kt$SyncFavoritesProgressProperties MatchingDeclarationName:TabbedDialog.kt$TabbedDialogPaddings + MatchingDeclarationName:__Assets.kt$AssetsGroup + MatchingDeclarationName:__EhAssets.kt$EhAssets + MatchingDeclarationName:__Ehassets.kt$EhassetsGroup + MatchingDeclarationName:__Exh.kt$ExhGroup + MaxLineLength:AnnotatedString.kt$Typeface.BOLD_ITALIC -> addStyle(SpanStyle(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic), start, end) + MaxLineLength:ApiMangaParser.kt$ApiMangaParser$/*private fun isOneShot(chapter: ChapterSerializer, finalChapterNumber: String): Boolean { return chapter.title.equals("oneshot", true) || ((chapter.chapter.isNullOrEmpty() || chapter.chapter == "0") && MdUtil.validOneShotFinalChapters.contains(finalChapterNumber)) }*/ + MaxLineLength:ApiMangaParser.kt$ApiMangaParser$?. + MaxLineLength:AzukiHandler.kt$AzukiHandler$val url = element.jsonObject["image_wm"]!!.jsonObject["webp"]!!.jsonArray[1].jsonObject["url"]!!.jsonPrimitive.content + MaxLineLength:BackupTracking.kt$_: Long, _: Long, syncId: Long, mediaId: Long, libraryId: Long?, title: String, lastChapterRead: Double, totalChapters: Long, status: Long, score: Double, remoteUrl: String, startDate: Long, finishDate: Long + MaxLineLength:BangumiInterceptor.kt$BangumiInterceptor$"jobobby04/TachiyomiSY/v${BuildConfig.VERSION_NAME} (Android) (http://github.com/jobobby04/tachiyomisy)" + MaxLineLength:BatchAddScreen.kt$BatchAddScreen$Text(text = stringResource(SYMR.strings.eh_batch_add_adding_galleries), style = MaterialTheme.typography.titleLarge) + MaxLineLength:BatchAddScreen.kt$BatchAddScreen$Text(text = stringResource(SYMR.strings.eh_batch_add_title), style = MaterialTheme.typography.titleLarge) + MaxLineLength:BiometricTimesScreen.kt$BiometricTimesScreen$. + MaxLineLength:BiometricTimesScreen.kt$BiometricTimesScreen$text = stringResource(SYMR.strings.delete_time_range_confirmation, dialog.timeRange.formattedString) + MaxLineLength:ChapterLoader.kt$ChapterLoader$isDownloaded -> DownloadPageLoader(chapter, manga, source, downloadManager, downloadProvider, tempFileManager) + MaxLineLength:ComikeyHandler.kt$ComikeyHandler$private val urlForbidden = "https://fakeimg.pl/1800x2252/FFFFFF/000000/?font_size=120&text=This%20chapter%20is%20not%20available%20for%20free.%0A%0AIf%20you%20have%20purchased%20this%20chapter%2C%20please%20%0Aopen%20the%20website%20in%20web%20view%20and%20log%20in." MaxLineLength:CoroutinesExtensions.kt$* + MaxLineLength:DataSaver.kt$BandwidthHeroDataSaver$imageUrl.contains(".jpeg", true) || imageUrl.contains(".jpg", true) -> if (ignoreJpg) imageUrl else getUrl(imageUrl) + MaxLineLength:DataSaver.kt$WsrvNlDataSaver$imageUrl.contains(".jpeg", true) || imageUrl.contains(".jpg", true) -> if (ignoreJpg) imageUrl else getUrl(imageUrl) + MaxLineLength:DataSaver.kt$WsrvNlDataSaver$return + MaxLineLength:DebugToggles.kt$DebugToggles.ENABLE_EXH_ROOT_REDIRECT$// Redirect to master version of gallery when encountering a gallery that has a parent/child that is already in the library + MaxLineLength:DownloadPageLoader.kt$DownloadPageLoader$val chapterPath = downloadProvider.findChapterDir(dbChapter.name, dbChapter.scanlator, /* SY --> */ manga.ogTitle /* SY <-- */, source) MaxLineLength:Downloader.kt$Downloader$. - MaxLineLength:LibraryUpdateJob.kt$LibraryUpdateJob$// failedUpdates will already have the source, don't need to copy it into the message + MaxLineLength:Downloader.kt$Downloader$// using ImageUtils isImage and findImageType functions causes IO errors when deleting files to set Exif Metadata + MaxLineLength:EHConfigurator.kt$EHConfigurator$throw IllegalStateException(context.stringResource(SYMR.strings.eh_settings_out_of_slots_error, source.name)) + MaxLineLength:EHHathPerksResponse.kt$EHHathPerksResponse$"EHHathPerksResponse(moreThumbs=$moreThumbs, thumbsUp=$thumbsUp, allThumbs=$allThumbs, pagingEnlargementI=$pagingEnlargementI, pagingEnlargementII=$pagingEnlargementII, pagingEnlargementIII=$pagingEnlargementIII)" + MaxLineLength:EHentaiDescriptionAdapter.kt$binding.rating.text = (ratingFloat ?: 0F).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2)) + MaxLineLength:EHentaiDescriptionAdapter.kt$binding.visible.text = context.stringResource(SYMR.strings.is_visible, meta.visible ?: context.stringResource(MR.strings.unknown)) + MaxLineLength:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$"No chapters found for gallery (manga.id: %s, meta.gId: %s, meta.gToken: %s, failures-so-far: %s)!" + MaxLineLength:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$"Updating gallery (index: %s, manga.id: %s, meta.gId: %s, meta.gToken: %s, failures-so-far: %s, modifiedThisIteration.size: %s)..." + MaxLineLength:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$?: + MaxLineLength:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$if + MaxLineLength:EditMergedMangaItem.kt$EditMergedMangaItem$class + MaxLineLength:EditMergedMangaItem.kt$EditMergedMangaItem$override + MaxLineLength:EditMergedSettingsDialog.kt$EditMergedSettingsState$val isPriorityOrder = mergeReference?.let { it.chapterSortMode == MergedMangaReference.CHAPTER_SORT_PRIORITY } ?: false + MaxLineLength:EditMergedSettingsDialog.kt$state.onViewCreated(factoryContext, binding, mergedData.manga.values.toList(), mergedData.references) + MaxLineLength:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter$class + MaxLineLength:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter$fun canMove() + MaxLineLength:EnhancedFilePrinter.kt$EnhancedFilePrinter$require(!(newFileName == null || newFileName.trim { it <= ' ' }.isEmpty())) { "File name should not be empty." } + MaxLineLength:ExtensionInstaller.kt$ExtensionInstaller$if + MaxLineLength:ExtensionManager.kt$ExtensionManager$if (it) this@ExtensionManager.xLogD("Removing blacklisted extension: (name: %s, pkgName: %s)!", extension.name, extension.pkgName) + MaxLineLength:ExtensionManager.kt$ExtensionManager$private + MaxLineLength:ExtensionsScreenModel.kt$ExtensionsScreenModel$ExtensionUiModel.Header.Text(LocaleHelper.getSourceDisplayName(lang, context)) to exts.map(extensionMapper(downloads)) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$context.stringResource(SYMR.strings.favorites_sync_remove_from_local, index + 1, changeSet.removed.size) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$logger.w(context.stringResource(SYMR.strings.favorites_sync_gallery_multiple_categories_error, manga.id)) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$message = context.stringResource(SYMR.strings.favorites_sync_add_to_local, index + 1, changeSet.added.size) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$message = context.stringResource(SYMR.strings.favorites_sync_adding_to_remote, index + 1, changeSet.added.size) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$status.value = FavoritesSyncStatus.Error(context.stringResource(SYMR.strings.favorites_sync_failed_to_featch)) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$status.value = FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_cleaning_up)) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$status.value = FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_downloading)) + MaxLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$status.value = FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_verifying_library)) + MaxLineLength:FeedScreenModel.kt$FeedScreenModel$private suspend + MaxLineLength:GalleryAdder.kt$GalleryAddEvent.Fail.UnknownSource$override val logMessage = context.stringResource(SYMR.strings.batch_add_unknown_source_log_message, galleryUrl) + MaxLineLength:GalleryAdder.kt$GalleryAddEvent.Fail.UnknownType$override val logMessage = context.stringResource(SYMR.strings.batch_add_unknown_type_log_message, galleryUrl) + MaxLineLength:GalleryAdder.kt$GalleryAdder$GalleryAddEvent.Fail.Error(url, context.stringResource(SYMR.strings.gallery_adder_could_not_identify_chapter, url)) + MaxLineLength:GalleryAdder.kt$GalleryAdder$logger.d(context.stringResource(SYMR.strings.gallery_adder_importing_gallery, url, fav.toString(), forceSource?.toString().orEmpty())) + MaxLineLength:GalleryAdder.kt$GalleryAdder$return GalleryAddEvent.Fail.Error(url, context.stringResource(SYMR.strings.gallery_adder_chapter_fetch_error, url)) + MaxLineLength:HBrowseDescriptionAdapter.kt$binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, meta.length ?: 0, meta.length ?: 0) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$!mangaTag.name.contains(searchedTag, true) || !mangaTag.namespace.equals(queryComponent.namespace, true) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$(it.namespace.equals(queryComponent.namespace, true) && tag?.run { it.name.contains(tag.asQuery(), true) } == true) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$(list.getOrNull(0)?.toIntOrNull() ?: return@mapNotNull null) to (list.getOrNull(1) ?: return@mapNotNull null) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$(loggedInTrackServices.isEmpty() || tracks == null || !filterTracks(query, tracks, context)) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$(loggedInTrackServices.isNotEmpty() && tracks != null && filterTracks(query, tracks, context)) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$SManga.PUBLISHING_FINISHED.toLong() -> context.stringResource(MR.strings.publishing_finished) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$searchTags == null || (queryComponent.namespace.isBlank() && searchedTag.isNullOrBlank()) + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$suspend + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$val + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$val manga1IndexOfTag = listOfTags.indexOfFirst { i1.libraryManga.manga.genre?.contains(it) ?: false } + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$val manga2IndexOfTag = listOfTags.indexOfFirst { i2.libraryManga.manga.genre?.contains(it) ?: false } + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$val mergedSource = sources.firstOrNull { mergedManga.source == it.id } as? HttpSource ?: return@merge + MaxLineLength:LibraryScreenModel.kt$LibraryScreenModel$val sources = mergedMangas.distinctBy { it.source }.map { sourceManager.getOrStub(it.source) } + MaxLineLength:LibraryTab.kt$LibraryTab$onClickRefresh(state.categories[screenModel.activeCategoryIndex.coerceAtMost(state.categories.lastIndex)]) + MaxLineLength:LibraryUpdateJob.kt$LibraryUpdateJob$if + MaxLineLength:LibraryUpdateJob.kt$LibraryUpdateJob$readChapters.any { it.chapterNumber == chapter.chapterNumber } + MaxLineLength:LibraryUpdateJob.kt$LibraryUpdateJob$val readChapters = getChaptersByMangaId.await(manga.id).filter { it.read } + MaxLineLength:LibraryUpdateNotifier.kt$LibraryUpdateNotifier.Companion$const val HELP_WARNING_URL = "https://mihon.app/docs/faq/library#why-am-i-warned-about-large-bulk-updates-and-downloads" + MaxLineLength:LocalFavoritesStorage.kt$LocalFavoritesStorage$(otherGid != null && otherToken != null && other.otherGid != null && other.otherToken != null && otherGid == other.otherGid && otherToken == other.otherToken) + MaxLineLength:LocalSource.kt$LocalSource$copiedFile.getZipInputStream(COMIC_INFO_FILE)?.let { setMangaDetailsFromComicInfoFile(it, manga) } MaxLineLength:MainActivity.kt$MainActivity$// or the Google-specific search intent (triggered by saying or typing "search *query* on *Tachiyomi*" in Google Search/Google Assistant) + MaxLineLength:MangaChapterListItem.kt$if (readProgress != null || scanlator != null/* SY --> */ || sourceName != null/* SY <-- */) DotSeparatorText() + MaxLineLength:MangaDex.kt$MangaDex$override suspend + MaxLineLength:MangaDexDescriptionAdapter.kt$binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + getRatingString(context, ratingFloat) + MaxLineLength:MangaDexFollowsScreenModel.kt$MangaDexFollowsScreenModel$override + MaxLineLength:MangaDexSimilarScreenModel.kt$MangaDexSimilarScreenModel$override + MaxLineLength:MangaScreen.kt$MangaScreen$onMergeWithAnotherClicked = { mergeWithAnother(navigator, context, successState.manga, screenModel::smartSearchMerge) } + MaxLineLength:MangaScreen.kt$MangaScreen$onRecommendClicked = { openRecommends(context, navigator, screenModel.source?.getMainSource(), successState.manga) } + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$/* SY --> */ if (isMergedSource) it.manga.id in mergedIds else /* SY <-- */ it.manga.id == successState?.manga?.id + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$alwaysShowReadingProgress = readerPreferences.preserveReadingPosition().get() && manga.isEhBasedManga() + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$if + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$if (chapters.isEmpty() || !manga.shouldDownloadNewChapters(categories, downloadPreferences) || manga.isEhBasedManga()) return@launchNonCancellable + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$return TrackItem(getTracks.await(mangaId).first { it.trackerId == trackerManager.mdList.id }, trackerManager.mdList) + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$val + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$val (acceptedChain) = updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters) + MaxLineLength:MangaScreenModel.kt$MangaScreenModel$val isUpdateIntervalEnabled = LibraryPreferences.MANGA_OUTSIDE_RELEASE_PERIOD in libraryPreferences.autoUpdateMangaRestrictions().get() + MaxLineLength:MangaScreenModel.kt$MangaScreenModel.State.Success$it.track != null && ((it.tracker is MdList && it.track.status != FollowStatus.UNFOLLOWED.long) || it.tracker !is MdList) + MaxLineLength:MdUtil.kt$MdUtil.Companion$fun + MaxLineLength:MemAutoFlushingLookupTable.kt$MemAutoFlushingLookupTable$* + MaxLineLength:MetadataViewScreen.kt$MetadataViewScreen$contentPadding = paddingValues + WindowInsets.navigationBars.asPaddingValues() + topSmallPaddingValues + MaxLineLength:MigrationListScreen.kt$MigrationListScreen$val mangaId = (items.orEmpty().firstOrNull()?.searchResult?.value as? MigratingManga.SearchResult.Result)?.id + MaxLineLength:MigrationListScreenModel.kt$MigrationListScreenModel$if + MaxLineLength:MigrationListScreenModel.kt$MigrationListScreenModel$manga.progress.value = validSources.size to processedSources.incrementAndGet() + MaxLineLength:MigrationListScreenModel.kt$MigrationListScreenModel$source.getChapterList(localManga.toSManga(), throttleManager::throttle) + MaxLineLength:MigrationListScreenModel.kt$MigrationListScreenModel$val prevChapter = prevMangaChapters.find { it.isRecognizedNumber && it.chapterNumber == chapter.chapterNumber } + MaxLineLength:MigrationSourceItem.kt$MigrationSourceItem$class + MaxLineLength:MigrationSourceItem.kt$MigrationSourceItem$override + MaxLineLength:NotificationExtensions.kt$if + MaxLineLength:PageHandler.kt$PageHandler$suspend + MaxLineLength:PagePreviewScreen.kt$(state.pageCount != null && state.pageCount > 1 /* TODO support unknown pageCount || state.hasNextPage*/) + MaxLineLength:PagerConfig.kt$PagerConfig$var + MaxLineLength:PagerPageHolder.kt$PagerPageHolder$val + MaxLineLength:PagerViewer.kt$PagerViewer$val forceTransition = config.alwaysShowChapterTransition || adapter.joinedItems.getOrNull(pager.currentItem)?.first is ChapterTransition MaxLineLength:PreferenceScreen.kt$* + MaxLineLength:PururinDescriptionAdapter.kt$binding.genre.text + MaxLineLength:PururinDescriptionAdapter.kt$binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2)) + MaxLineLength:ReaderActivity.kt$ReaderActivity$if ((resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) xor invertDoublePage) "${page.number}-${page.number + 1}" else "${page.number + 1}-${page.number}" + MaxLineLength:ReaderActivity.kt$ReaderActivity$stringResource(SYMR.strings.share_pages_info, manga.title, chapter.name, if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) "${page.number}-${page.number + 1}" else "${page.number + 1}-${page.number}") + MaxLineLength:ReaderActivity.kt$ReaderActivity$val currentPage = (((viewer as? PagerViewer)?.currentPage ?: (viewer as? WebtoonViewer)?.currentPage) as? ReaderPage)?.index + MaxLineLength:ReaderActivity.kt$ReaderActivity$val showVerticalSeekbar = !forceHorizontalSeekbar && (verticalSeekbarLandscape || verticalSeekbarHorizontal) && viewerIsVertical + MaxLineLength:ReaderActivity.kt$ReaderActivity$val verticalSeekbarLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && landscapeVerticalSeekbar + MaxLineLength:ReaderActivity.kt$ReaderActivity$windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + MaxLineLength:ReaderActivity.kt$ReaderActivity.Companion$fun + MaxLineLength:ReaderActivity.kt$ReaderActivity.ReaderConfig$PagerConfig.PageLayout.AUTOMATIC -> resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + MaxLineLength:ReaderAppBars.kt$/* SY --> actions = { AppBarActions( listOfNotNull( AppBar.Action( title = stringResource( if (bookmarked) MR.strings.action_remove_bookmark else MR.strings.action_bookmark ), icon = if (bookmarked) Icons.Outlined.Bookmark else Icons.Outlined.BookmarkBorder, onClick = onToggleBookmarked, ), onOpenInWebView?.let { AppBar.OverflowAction( title = stringResource(MR.strings.action_open_in_web_view), onClick = it, ) }, onShare?.let { AppBar.OverflowAction( title = stringResource(MR.strings.action_share), onClick = it, ) }, ), ) }, SY <-- */ + MaxLineLength:ReaderPageImageView.kt$ReaderPageImageView$if + MaxLineLength:ReaderPreferences.kt$ReaderPreferences$fun readerBottomButtons() + MaxLineLength:ReaderViewModel.kt$ReaderViewModel$getMergedChaptersByMangaId.await(manga.id, applyScanlatorFilter = true) MaxLineLength:Scaffold.kt$* + MaxLineLength:SecureActivityDelegate.kt$SecureActivityDelegate.Companion$requireUnlock + MaxLineLength:ShikimoriApi.kt$ShikimoriApi$track.library_id = it["id"]!!.jsonPrimitive.long // save id of the entry for possible future delete request + MaxLineLength:SourceFeedScreen.kt$SourceFeedScreen$fun + MaxLineLength:SourcesScreenModel.kt$SourcesScreenModel$SourceUiModel.Header(it.key.removePrefix(CATEGORY_KEY_PREFIX), it.value.firstOrNull()?.category != null) + MaxLineLength:SourcesScreenModel.kt$SourcesScreenModel$private MaxLineLength:SpecificHostRateLimitInterceptor.kt$* + MaxLineLength:TsuminoDescriptionAdapter.kt$binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, meta.length ?: 0, meta.length ?: 0) + MaxLineLength:TsuminoDescriptionAdapter.kt$binding.rating.text = (round((meta.averageRating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, meta.averageRating?.times(2)) MaxLineLength:WebViewUtil.kt$WebViewUtil$* + MaxLineLength:WebtoonPageHolder.kt$WebtoonPageHolder$cropBorders = (viewer.config.imageCropBorders && viewer.isContinuous) || (viewer.config.continuousCropBorders && !viewer.isContinuous) + MaximumLineLength:AnnotatedString.kt$ + MaximumLineLength:ApiMangaParser.kt$ApiMangaParser$ + MaximumLineLength:AzukiHandler.kt$AzukiHandler$ + MaximumLineLength:BackupTracking.kt$ + MaximumLineLength:BangumiInterceptor.kt$BangumiInterceptor$ + MaximumLineLength:BatchAddScreen.kt$BatchAddScreen$ + MaximumLineLength:BiometricTimesScreen.kt$BiometricTimesScreen$ + MaximumLineLength:ChapterLoader.kt$ChapterLoader$ + MaximumLineLength:ComikeyHandler.kt$ComikeyHandler$ + MaximumLineLength:DataSaver.kt$BandwidthHeroDataSaver$ + MaximumLineLength:DataSaver.kt$WsrvNlDataSaver$ + MaximumLineLength:DownloadPageLoader.kt$DownloadPageLoader$ + MaximumLineLength:EHConfigurator.kt$EHConfigurator$ + MaximumLineLength:EHHathPerksResponse.kt$EHHathPerksResponse$ + MaximumLineLength:EHentaiDescriptionAdapter.kt$ + MaximumLineLength:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$ + MaximumLineLength:EditMergedMangaItem.kt$EditMergedMangaItem$ + MaximumLineLength:EditMergedMangaItem.kt$EditMergedMangaItem$class + MaximumLineLength:EditMergedSettingsDialog.kt$ + MaximumLineLength:EditMergedSettingsDialog.kt$EditMergedSettingsState$ + MaximumLineLength:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter$ + MaximumLineLength:EditMergedSettingsHeaderAdapter.kt$EditMergedSettingsHeaderAdapter$class + MaximumLineLength:EnhancedFilePrinter.kt$EnhancedFilePrinter$ + MaximumLineLength:ExtensionInstaller.kt$ExtensionInstaller$ + MaximumLineLength:ExtensionManager.kt$ExtensionManager$ + MaximumLineLength:ExtensionsScreenModel.kt$ExtensionsScreenModel$ + MaximumLineLength:FavoritesSyncHelper.kt$FavoritesSyncHelper$ + MaximumLineLength:FeedScreenModel.kt$FeedScreenModel$ + MaximumLineLength:GalleryAdder.kt$GalleryAddEvent.Fail.UnknownSource$ + MaximumLineLength:GalleryAdder.kt$GalleryAddEvent.Fail.UnknownType$ + MaximumLineLength:GalleryAdder.kt$GalleryAdder$ + MaximumLineLength:HBrowseDescriptionAdapter.kt$ + MaximumLineLength:LibraryScreenModel.kt$LibraryScreenModel$ + MaximumLineLength:LibraryTab.kt$LibraryTab$ + MaximumLineLength:LibraryUpdateJob.kt$LibraryUpdateJob$ + MaximumLineLength:LibraryUpdateNotifier.kt$LibraryUpdateNotifier.Companion$ + MaximumLineLength:LocalFavoritesStorage.kt$LocalFavoritesStorage$ + MaximumLineLength:LocalSource.kt$LocalSource$ + MaximumLineLength:MangaChapterListItem.kt$ + MaximumLineLength:MangaDex.kt$MangaDex$ + MaximumLineLength:MangaDexDescriptionAdapter.kt$ + MaximumLineLength:MangaDexFollowsScreenModel.kt$MangaDexFollowsScreenModel$ + MaximumLineLength:MangaDexSimilarScreenModel.kt$MangaDexSimilarScreenModel$ + MaximumLineLength:MangaScreen.kt$MangaScreen$ + MaximumLineLength:MangaScreenModel.kt$MangaScreenModel$ + MaximumLineLength:MangaScreenModel.kt$MangaScreenModel.State.Success$ + MaximumLineLength:MdUtil.kt$MdUtil.Companion$ + MaximumLineLength:MetadataViewScreen.kt$MetadataViewScreen$ + MaximumLineLength:MigrationListScreen.kt$MigrationListScreen$ + MaximumLineLength:MigrationListScreenModel.kt$MigrationListScreenModel$ + MaximumLineLength:MigrationSourceItem.kt$MigrationSourceItem$ + MaximumLineLength:MigrationSourceItem.kt$MigrationSourceItem$class + MaximumLineLength:NotificationExtensions.kt$ + MaximumLineLength:PageHandler.kt$PageHandler$ + MaximumLineLength:PagePreviewScreen.kt$ + MaximumLineLength:PagerConfig.kt$PagerConfig$ + MaximumLineLength:PagerPageHolder.kt$PagerPageHolder$ + MaximumLineLength:PagerViewer.kt$PagerViewer$ + MaximumLineLength:PururinDescriptionAdapter.kt$ + MaximumLineLength:ReaderActivity.kt$ReaderActivity$ + MaximumLineLength:ReaderActivity.kt$ReaderActivity.Companion$ + MaximumLineLength:ReaderActivity.kt$ReaderActivity.ReaderConfig$ + MaximumLineLength:ReaderPageImageView.kt$ReaderPageImageView$ + MaximumLineLength:ReaderPreferences.kt$ReaderPreferences$ + MaximumLineLength:ReaderViewModel.kt$ReaderViewModel$ + MaximumLineLength:SecureActivityDelegate.kt$SecureActivityDelegate.Companion$ + MaximumLineLength:ShikimoriApi.kt$ShikimoriApi$ + MaximumLineLength:SourceFeedScreen.kt$SourceFeedScreen$ + MaximumLineLength:SourcesScreenModel.kt$SourcesScreenModel$ + MaximumLineLength:TsuminoDescriptionAdapter.kt$ + MaximumLineLength:WebtoonPageHolder.kt$WebtoonPageHolder$ + MayBeConst:TsuminoSearchMetadata.kt$TsuminoSearchMetadata.Companion$val BASE_URL = "https://www.tsumino.com" MemberNameEqualsClassName:ExtensionInstaller.kt$ExtensionInstaller$private val extensionInstaller = Injekt.get<BasePreferences>().extensionInstaller() ModifierClickableOrder:ScanlatorFilterDialog.kt$clickable { if (isExcluded) { mutableExcludedScanlators.remove(scanlator) } else { mutableExcludedScanlators.add(scanlator) } } ModifierMissing:AppBar.kt$AppBarActions ModifierMissing:AppThemePreferenceWidget.kt$AppThemePreviewItem + ModifierMissing:AutoCompleteItem.kt$AutoCompleteItem + ModifierMissing:AutoCompleteItem.kt$AutoCompleteTextField + ModifierMissing:BiometricTimesContent.kt$BiometricTimesContent + ModifierMissing:BiometricTimesScreen.kt$BiometricTimesScreen ModifierMissing:BottomReaderBar.kt$BottomReaderBar ModifierMissing:BrowseSourceComfortableGrid.kt$BrowseSourceComfortableGrid ModifierMissing:BrowseSourceCompactGrid.kt$BrowseSourceCompactGrid + ModifierMissing:BrowseSourceEHentaiList.kt$BrowseSourceEHentaiList + ModifierMissing:BrowseSourceEHentaiList.kt$BrowseSourceEHentaiListItem ModifierMissing:BrowseSourceList.kt$BrowseSourceList ModifierMissing:BrowseSourceScreen.kt$BrowseSourceContent + ModifierMissing:BrowseSourceSimpleToolbar.kt$BrowseSourceSimpleToolbar ModifierMissing:BrowseSourceToolbar.kt$BrowseSourceToolbar + ModifierMissing:BrowseTabWrapper.kt$BrowseTabWrapper ModifierMissing:CategoryScreen.kt$CategoryScreen + ModifierMissing:ChapterListDialog.kt$ChapterListDialog ModifierMissing:ChapterNavigator.kt$ChapterNavigator + ModifierMissing:ChapterNavigator.kt$ChapterNavigatorVert ModifierMissing:ChapterSettingsDialog.kt$ChapterSettingsDialog ModifierMissing:ChapterSettingsDialog.kt$ScanlatorFilterItem ModifierMissing:CollapsibleBox.kt$CollapsibleBox @@ -744,16 +1485,22 @@ ModifierMissing:CommonMangaItem.kt$MangaCompactGridItem ModifierMissing:CommonMangaItem.kt$MangaListItem ModifierMissing:CrashScreen.kt$CrashScreen + ModifierMissing:EHDebugModeOverlay.kt$DebugModeOverlay + ModifierMissing:EHentaiDescriptionAdapter.kt$EHentaiDescription + ModifierMissing:EhLoginWebViewScreen.kt$EhLoginWebViewScreen + ModifierMissing:EightMusesDescriptionAdapter.kt$EightMusesDescription ModifierMissing:ExtensionDetailsScreen.kt$ExtensionDetailsScreen ModifierMissing:ExtensionFilterScreen.kt$ExtensionFilterScreen ModifierMissing:ExtensionReposScreen.kt$ExtensionReposScreen ModifierMissing:ExtensionsScreen.kt$ExtensionScreen + ModifierMissing:FeedScreen.kt$FeedScreen + ModifierMissing:FeedScreen.kt$RadioSelector ModifierMissing:GlobalSearchCardRow.kt$GlobalSearchCardRow ModifierMissing:GlobalSearchResultItems.kt$GlobalSearchErrorResultItem ModifierMissing:GlobalSearchResultItems.kt$GlobalSearchLoadingResultItem - ModifierMissing:GlobalSearchResultItems.kt$GlobalSearchResultItem ModifierMissing:GlobalSearchScreen.kt$GlobalSearchScreen ModifierMissing:GlobalSearchToolbar.kt$GlobalSearchToolbar + ModifierMissing:HBrowseDescriptionAdapter.kt$HBrowseDescription ModifierMissing:HistoryScreen.kt$HistoryScreen ModifierMissing:HomeScreen.kt$HomeScreen$NavigationRailItem ModifierMissing:InfoScreen.kt$InfoScreen @@ -762,21 +1509,37 @@ ModifierMissing:LibrarySettingsDialog.kt$LibrarySettingsDialog ModifierMissing:LogoHeader.kt$LogoHeader ModifierMissing:MangaCoverDialog.kt$MangaCoverDialog + ModifierMissing:MangaDexDescriptionAdapter.kt$MangaDexDescription + ModifierMissing:MangaDexFilterHeader.kt$MangaDexFilterHeader + ModifierMissing:MangaInfoButtons.kt$MangaInfoButtons ModifierMissing:MangaScreen.kt$MangaScreenLargeImpl ModifierMissing:MigrateMangaScreen.kt$MigrateMangaScreen ModifierMissing:MigrateSearchScreen.kt$MigrateSearchScreen ModifierMissing:MigrateSourceScreen.kt$MigrateSourceScreen + ModifierMissing:MigrationBottomSheetDialog.kt$MigrationBottomSheetDialog + ModifierMissing:MigrationListScreen.kt$MigrationListScreen ModifierMissing:ModeSelectionDialog.kt$ModeSelectionDialog ModifierMissing:MoreScreen.kt$MoreScreen + ModifierMissing:NHentaiDescriptionAdapter.kt$NHentaiDescription + ModifierMissing:NamespaceTags.kt$NamespaceTags ModifierMissing:NewUpdateScreen.kt$NewUpdateScreen ModifierMissing:OnboardingScreen.kt$OnboardingScreen ModifierMissing:PageIndicatorText.kt$PageIndicatorText + ModifierMissing:PagePreviewScreen.kt$PagePreviewScreen + ModifierMissing:PagePreviews.kt$PagePreviews ModifierMissing:PreferenceGroupHeader.kt$PreferenceGroupHeader ModifierMissing:PreferenceScaffold.kt$PreferenceScaffold + ModifierMissing:PururinDescriptionAdapter.kt$PururinDescription ModifierMissing:ReaderAppBars.kt$ReaderAppBars ModifierMissing:ReaderPageActionsDialog.kt$ReaderPageActionsDialog ModifierMissing:ReaderSettingsDialog.kt$ReaderSettingsDialog + ModifierMissing:SavedSearchItem.kt$SavedSearchItem ModifierMissing:SectionCard.kt$SectionCard + ModifierMissing:SettingsDebugScreen.kt$SettingsDebugScreen$FunctionList + ModifierMissing:SettingsEhScreen.kt$SettingsEhScreen$FrontPageCategoriesDialogRow + ModifierMissing:SettingsEhScreen.kt$SettingsEhScreen$LanguageDialogRow + ModifierMissing:SettingsEhScreen.kt$SettingsEhScreen$LanguageDialogRowCheckbox + ModifierMissing:SettingsEhScreen.kt$SettingsEhScreen$UpdaterStatisticsLoadingDialog ModifierMissing:SettingsItems.kt$CheckboxItem ModifierMissing:SettingsItems.kt$HeadingItem ModifierMissing:SettingsItems.kt$IconItem @@ -789,6 +1552,12 @@ ModifierMissing:SettingsItems.kt$TextItem ModifierMissing:SettingsItems.kt$TriStateItem ModifierMissing:SettingsMainScreen.kt$SettingsMainScreen$Content + ModifierMissing:SortTagContent.kt$SortTagContent + ModifierMissing:SortTagScreen.kt$SortTagScreen + ModifierMissing:SourceCategoryContent.kt$SourceCategoryContent + ModifierMissing:SourceCategoryScreen.kt$SourceCategoryScreen + ModifierMissing:SourceFeedScreen.kt$SourceFeedList + ModifierMissing:SourceFeedScreen.kt$SourceFeedScreen ModifierMissing:SourceFilterDialog.kt$SourceFilterDialog ModifierMissing:SourcesFilterScreen.kt$SourcesFilterScreen ModifierMissing:SourcesScreen.kt$SourcesScreen @@ -802,6 +1571,7 @@ ModifierMissing:TrackInfoDialogSelector.kt$TrackStatusSelector ModifierMissing:TrackLogoIcon.kt$TrackLogoIcon ModifierMissing:TrackerSearch.kt$TrackerSearch + ModifierMissing:TsuminoDescriptionAdapter.kt$TsuminoDescription ModifierMissing:UpdatesScreen.kt$UpdateScreen ModifierMissing:WebViewScreenContent.kt$WebViewScreenContent ModifierMissing:WheelPicker.kt$WheelPickerDefaults$Background @@ -809,7 +1579,23 @@ ModifierNotUsedAtRoot:DropdownMenu.kt$modifier = modifier ModifierNotUsedAtRoot:MangaChapterListItem.kt$modifier = modifier .selectedBackground(selected) .combinedClickable( onClick = onClick, onLongClick = onLongClick, ) .padding(start = 16.dp, top = 12.dp, end = 8.dp, bottom = 12.dp) ModifierNotUsedAtRoot:TrackingPreferenceWidget.kt$modifier = modifier .clickable(enabled = onClick != null, onClick = { onClick?.invoke() }) .fillMaxWidth() .padding(horizontal = PrefsHorizontalPadding, vertical = 8.dp) + ModifierWithoutDefault:BiometricTimesListItem.kt$modifier + ModifierWithoutDefault:Chip.kt$modifier + ModifierWithoutDefault:MigrationActionIcon.kt$modifier + ModifierWithoutDefault:MigrationItem.kt$modifier + ModifierWithoutDefault:MigrationItemResult.kt$modifier + ModifierWithoutDefault:PagePreviews.kt$modifier + ModifierWithoutDefault:ReaderAppBars.kt$modifier + ModifierWithoutDefault:SortTagListItem.kt$modifier + ModifierWithoutDefault:SourceCategoryListItem.kt$modifier + ModifierWithoutDefault:SourcesFilterScreen.kt$modifier + MultiLineIfElse:CbzCrypto.kt$CbzCrypto$ZipOutputStream(this.openOutputStream()) + MultiLineIfElse:CbzCrypto.kt$CbzCrypto$ZipOutputStream(this.openOutputStream(), password) + MultiLineIfElse:CbzCrypto.kt$CbzCrypto$throw zipException + MultiLineIfElse:SettingsAppearanceScreen.kt$SettingsAppearanceScreen$pluralStringResource( SYMR.plurals.row_count, previewsRowCount, previewsRowCount, ) + MultiLineIfElse:SettingsAppearanceScreen.kt$SettingsAppearanceScreen$stringResource(MR.strings.disabled) NestedBlockDepth:Anilist.kt$Anilist$override suspend fun update(track: Track, didReadChapter: Boolean): Track + NestedBlockDepth:ApiMangaParser.kt$ApiMangaParser$fun parseIntoMetadata( metadata: MangaDexSearchMetadata, mangaDto: MangaDto, simpleChapters: List<String>, statistics: StatisticsMangaDto?, ) NestedBlockDepth:AppLanguageScreen.kt$AppLanguageScreen$private fun getLangs(context: Context): ImmutableList<Language> NestedBlockDepth:BackupRestorer.kt$BackupRestorer$private fun writeErrorLog(): File NestedBlockDepth:BrowseSourceScreenModel.kt$BrowseSourceScreenModel$fun searchGenre(genreName: String) @@ -818,85 +1604,112 @@ NestedBlockDepth:ContextExtensions.kt$fun Context.openInBrowser(uri: Uri, forceDefaultBrowser: Boolean = false) NestedBlockDepth:DownloadQueueScreenModel.kt$DownloadQueueScreenModel.<no name provided>$override fun onMenuItemClick(position: Int, menuItem: MenuItem) NestedBlockDepth:Downloader.kt$Downloader$private fun archiveChapter( mangaDir: UniFile, dirname: String, tmpDir: UniFile, ) + NestedBlockDepth:EHentai.kt$EHentai$override suspend fun parseIntoMetadata(metadata: EHentaiSearchMetadata, input: Document) + NestedBlockDepth:EHentai.kt$EHentai$private fun extendedGenericMangaParse(doc: Document) + NestedBlockDepth:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$private suspend fun startUpdating() + NestedBlockDepth:EXHMigrations.kt$EXHMigrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, pagePreviewCache: PagePreviewCache, ): Boolean NestedBlockDepth:ExtensionInstaller.kt$ExtensionInstaller$fun installApk(downloadId: Long, uri: Uri) + NestedBlockDepth:FilterHandler.kt$FilterHandler$fun getQueryMap(filters: FilterList): Map<String, Any> + NestedBlockDepth:GalleryAdder.kt$GalleryAdder$suspend fun addGallery( context: Context, url: String, fav: Boolean = false, forceSource: UrlImportableSource? = null, throttleFunc: suspend () -> Unit = {}, retry: Int = 1, ): GalleryAddEvent + NestedBlockDepth:GetMergedChaptersByMangaId.kt$GetMergedChaptersByMangaId$private fun dedupeByPriority( mangaReferences: List<MergedMangaReference>, chapterList: List<Chapter>, ): List<Chapter> + NestedBlockDepth:HBrowse.kt$HBrowse$override suspend fun parseIntoMetadata(metadata: HBrowseSearchMetadata, input: Document) NestedBlockDepth:ImageUtil.kt$ImageUtil$fun chooseBackground(context: Context, imageStream: InputStream): Drawable NestedBlockDepth:KavitaApi.kt$KavitaApi$fun getNewToken(apiUrl: String, apiKey: String): String? NestedBlockDepth:KavitaApi.kt$KavitaApi$private fun getLatestChapterRead(url: String): Double NestedBlockDepth:Kitsu.kt$Kitsu$override suspend fun update(track: Track, didReadChapter: Boolean): Track NestedBlockDepth:LibraryUpdateJob.kt$LibraryUpdateJob$private fun writeErrorFile(errors: List<Pair<Manga, String?>>): File - NestedBlockDepth:LocalSource.kt$LocalSource$private fun copyComicInfoFileFromArchive(chapterArchives: List<UniFile>, folderPath: String?): File? + NestedBlockDepth:LocalSource.kt$LocalSource$private fun copyComicInfoFile(comicInfoFileStream: InputStream, folder: UniFile): UniFile? + NestedBlockDepth:LocalSource.kt$LocalSource$private fun copyComicInfoFileFromArchive(chapterArchives: List<UniFile>, folder: UniFile): UniFile? NestedBlockDepth:LocalSource.kt$LocalSource$private fun updateCover(chapter: SChapter, manga: SManga): UniFile? + NestedBlockDepth:MigrationListScreenModel.kt$MigrationListScreenModel$private suspend fun migrateMangaInternal( prevManga: Manga, manga: Manga, replace: Boolean, ) + NestedBlockDepth:MigrationListScreenModel.kt$MigrationListScreenModel$private suspend fun runMigrations(mangas: List<MigratingManga>) + NestedBlockDepth:Migrations.kt$Migrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, ): Boolean NestedBlockDepth:MyAnimeList.kt$MyAnimeList$override suspend fun update(track: Track, didReadChapter: Boolean): Track + NestedBlockDepth:PagerViewerAdapter.kt$PagerViewerAdapter$private fun setJoinedItems(useSecondPage: Boolean = false) + NestedBlockDepth:Pururin.kt$Pururin$override suspend fun parseIntoMetadata(metadata: PururinSearchMetadata, input: Document) + NestedBlockDepth:RaisedSearchMetadata.kt$RaisedSearchMetadata$fun tagsToDescription() + NestedBlockDepth:SearchEngine.kt$SearchEngine$fun queryToSql(q: List<QueryComponent>): Pair<String, List<String>> + NestedBlockDepth:SmartSearchEngine.kt$SmartSearchEngine$private fun removeTextInBrackets(text: String, readForward: Boolean): String NestedBlockDepth:SyncChaptersWithSource.kt$SyncChaptersWithSource$suspend fun await( rawSourceChapters: List<SChapter>, manga: Manga, source: Source, manualFetch: Boolean = false, fetchWindow: Pair<Long, Long> = Pair(0, 0), ): List<Chapter> + NestedBlockDepth:UniFileExtensions.kt$fun UniFile.unzip(destination: File, onlyCopyImages: Boolean = false) NestedBlockDepth:UniFileTempFileManager.kt$UniFileTempFileManager$fun createTempFile(file: UniFile): File NestedBlockDepth:WebtoonRecyclerView.kt$WebtoonRecyclerView.Detector$override fun onTouchEvent(ev: MotionEvent): Boolean + NestedBlockDepth:WebtoonViewer.kt$WebtoonViewer$fun scrollDown() NewLineAtEndOfFile:Commands.kt$.Commands.kt + NoBlankLineBeforeRbrace:CbzCrypto.kt$CbzCrypto$ + NoConsecutiveBlankLines:CbzCrypto.kt$CbzCrypto$ NoConsecutiveBlankLines:LocalesConfigPlugin.kt$ + NoTrailingSpaces:ReaderViewModel.kt$ReaderViewModel$ + NoUnusedImports:BackupManga.kt$eu.kanade.tachiyomi.data.backup.models.BackupManga.kt + NoUnusedImports:CreateBackupScreen.kt$eu.kanade.presentation.more.settings.screen.data.CreateBackupScreen.kt + NoUnusedImports:SettingsAdvancedScreen.kt$eu.kanade.presentation.more.settings.screen.SettingsAdvancedScreen.kt + NoUnusedImports:TachiyomiImageDecoder.kt$eu.kanade.tachiyomi.data.coil.TachiyomiImageDecoder.kt + PreviewPublic:NamespaceTags.kt$NamespaceTagsPreview PreviewPublic:Scrollbar.kt$LazyListHorizontalScrollbarPreview PreviewPublic:Scrollbar.kt$LazyListScrollbarPreview + PrintStackTrace:EnhancedFilePrinter.kt$EnhancedFilePrinter.Worker$e + PrintStackTrace:EnhancedFilePrinter.kt$EnhancedFilePrinter.Writer$e RethrowCaughtException:LocalSource.kt$LocalSource$throw e - ReturnCount:AndroidDatabaseHandler.kt$AndroidDatabaseHandler$private suspend fun <T> dispatch(inTransaction: Boolean, block: suspend Database.() -> T): T ReturnCount:AndroidSourceManager.kt$AndroidSourceManager$private suspend fun createStubSource(id: Long): StubSource ReturnCount:BackupCreateJob.kt$BackupCreateJob$override suspend fun doWork(): Result + ReturnCount:BrowseSourceScreen.kt$@Composable fun BrowseSourceContent( source: Source?, mangaList: LazyPagingItems<StateFlow</* SY --> */Pair<Manga, RaisedSearchMetadata?>/* SY <-- */>>, columns: GridCells, // SY --> ehentaiBrowseDisplayMode: Boolean, // SY <-- displayMode: LibraryDisplayMode, snackbarHostState: SnackbarHostState, contentPadding: PaddingValues, // SY --> onWebViewClick: (() -> Unit)?, onHelpClick: (() -> Unit)?, onLocalSourceHelpClick: (() -> Unit)?, // SY <-- onMangaClick: (Manga) -> Unit, onMangaLongClick: (Manga) -> Unit, ) ReturnCount:ChapterRecognition.kt$ChapterRecognition$fun parseChapterNumber( mangaTitle: String, chapterName: String, chapterNumber: Double? = null, ): Double ReturnCount:ChapterRecognition.kt$ChapterRecognition$private fun checkForDecimal(decimal: String?, alpha: String?): Double - ReturnCount:Download.kt$Download.Companion$suspend fun fromChapterId( chapterId: Long, getChapter: GetChapter = Injekt.get(), getManga: GetManga = Injekt.get(), sourceManager: SourceManager = Injekt.get(), ): Download? - ReturnCount:DownloadCache.kt$DownloadCache$fun isChapterDownloaded( chapterName: String, chapterScanlator: String?, mangaTitle: String, sourceId: Long, skipCache: Boolean, ): Boolean - ReturnCount:DownloadManager.kt$DownloadManager$fun renameSource(oldSource: Source, newSource: Source) - ReturnCount:Downloader.kt$Downloader$private fun isDownloadSuccessful( download: Download, tmpDir: UniFile, ): Boolean - ReturnCount:ExtensionInstallReceiver.kt$ExtensionInstallReceiver$override fun onReceive(context: Context, intent: Intent?) + ReturnCount:EHentai.kt$EHentai.ThumbnailPreviewInterceptor$override fun intercept(chain: Interceptor.Chain): Response + ReturnCount:EXHMigrations.kt$EXHMigrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, pagePreviewCache: PagePreviewCache, ): Boolean + ReturnCount:EhLoginActivity.kt$EhLoginActivity$private fun applyExHentaiCookies(url: String, customIgneous: String?): Boolean ReturnCount:ExtensionInstallService.kt$ExtensionInstallService$override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int - ReturnCount:ExtensionInstaller.kt$ExtensionInstaller.DownloadCompletionReceiver$override fun onReceive(context: Context, intent: Intent?) ReturnCount:ExtensionInstallerPreference.kt$ExtensionInstallerPreference$private fun check(value: ExtensionInstaller): ExtensionInstaller ReturnCount:ExtensionLoader.kt$ExtensionLoader$fun installPrivateExtensionFile(context: Context, file: File): Boolean ReturnCount:ExtensionLoader.kt$ExtensionLoader$private fun loadExtension(context: Context, extensionInfo: ExtensionInfo): LoadResult ReturnCount:ExtensionLoader.kt$ExtensionLoader$private fun selectExtensionPackage(shared: ExtensionInfo?, private: ExtensionInfo?): ExtensionInfo? + ReturnCount:FavoritesSyncHelper.kt$FavoritesSyncHelper$private suspend fun beginSync() + ReturnCount:GalleryAdder.kt$GalleryAdder$suspend fun addGallery( context: Context, url: String, fav: Boolean = false, forceSource: UrlImportableSource? = null, throttleFunc: suspend () -> Unit = {}, retry: Int = 1, ): GalleryAddEvent ReturnCount:HttpPageLoader.kt$HttpPageLoader$private fun preloadNextPages(currentPage: ReaderPage, amount: Int): List<PriorityPage> ReturnCount:ImageUtil.kt$ImageUtil$fun chooseBackground(context: Context, imageStream: InputStream): Drawable - ReturnCount:ImageUtil.kt$ImageUtil$fun isAnimatedAndSupported(stream: InputStream): Boolean - ReturnCount:ImageUtil.kt$ImageUtil$fun splitTallImage(tmpDir: UniFile, imageFile: UniFile, filenamePrefix: String): Boolean ReturnCount:KavitaApi.kt$KavitaApi$fun getNewToken(apiUrl: String, apiKey: String): String? ReturnCount:KavitaApi.kt$KavitaApi$private fun getLatestChapterRead(url: String): Double - ReturnCount:KitsuDateHelper.kt$KitsuDateHelper$fun parse(dateString: String?): Long ReturnCount:LibraryUpdateJob.kt$LibraryUpdateJob$override suspend fun doWork(): Result - ReturnCount:LocalSource.kt$LocalSource$private fun copyComicInfoFileFromArchive(chapterArchives: List<UniFile>, folderPath: String?): File? + ReturnCount:LibraryUpdateJob.kt$LibraryUpdateJob$private suspend fun updateManga(manga: Manga, fetchWindow: Pair<Long, Long>): List<Chapter> + ReturnCount:LocalCoverManager.kt$LocalCoverManager$actual fun update( manga: SManga, inputStream: InputStream, // SY --> encrypted: Boolean, // SY <-- ): UniFile? + ReturnCount:LocalSource.kt$LocalSource$private fun copyComicInfoFileFromArchive(chapterArchives: List<UniFile>, folder: UniFile): UniFile? ReturnCount:MainActivity.kt$MainActivity$private fun handleIntentAction(intent: Intent, navigator: Navigator): Boolean ReturnCount:MangaCoverFetcher.kt$MangaCoverFetcher$private suspend fun httpLoader(): FetchResult - ReturnCount:MangaExtensions.kt$fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSameUrl: Boolean): Manga - ReturnCount:MangaExtensions.kt$fun Manga.removeCovers(coverCache: CoverCache = Injekt.get()): Manga + ReturnCount:MangaDexAuthInterceptor.kt$MangaDexAuthInterceptor$override fun intercept(chain: Interceptor.Chain): Response ReturnCount:MangaExtensions.kt$fun Manga.shouldDownloadNewChapters(dbCategories: List<Long>, preferences: DownloadPreferences): Boolean - ReturnCount:MangaScreen.kt$MangaScreen$private fun getMangaUrl(manga_: Manga?, source_: Source?): String? - ReturnCount:MissingChapters.kt$fun List<Double>.missingChaptersCount(): Int - ReturnCount:MissingChapters.kt$fun calculateChapterGap(higherChapter: Chapter?, lowerChapter: Chapter?): Int + ReturnCount:MdUtil.kt$MdUtil.Companion$fun getMissingChapterCount(chapters: List<SChapter>, mangaStatus: Int): String? + ReturnCount:Migrations.kt$Migrations$fun upgrade( context: Context, preferenceStore: PreferenceStore, basePreferences: BasePreferences, uiPreferences: UiPreferences, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, securityPreferences: SecurityPreferences, libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, trackerManager: TrackerManager, ): Boolean ReturnCount:MyAnimeList.kt$MyAnimeList$override suspend fun search(query: String): List<TrackSearch> ReturnCount:NetworkExtensions.kt$fun Context.isConnectedToWifi(): Boolean - ReturnCount:NetworkExtensions.kt$fun Context.isOnline(): Boolean - ReturnCount:PagerPageHolder.kt$PagerPageHolder$private fun process(page: ReaderPage, imageStream: BufferedInputStream): InputStream + ReturnCount:PageHandler.kt$PageHandler$@Suppress("UNCHECKED_CAST") private fun updateExtensionVariable(mangadex: Source, atHomeRequestUrl: String) + ReturnCount:PagePreviewFetcher.kt$PagePreviewFetcher$private suspend fun httpLoader(): FetchResult + ReturnCount:PagerPageHolder.kt$PagerPageHolder$private fun mergePages(imageStream: InputStream, imageStream2: InputStream?): InputStream ReturnCount:PagerViewer.kt$PagerViewer$override fun handleKeyEvent(event: KeyEvent): Boolean - ReturnCount:PagerViewer.kt$PagerViewer$private fun checkAllowPreload(page: ReaderPage?): Boolean ReturnCount:PagerViewerAdapter.kt$PagerViewerAdapter$fun onPageSplit(currentPage: Any?, newPage: InsertPage) ReturnCount:ReaderActivity.kt$ReaderActivity$override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean - ReturnCount:ReaderActivity.kt$ReaderActivity$private fun moveToPageIndex(index: Int) - ReturnCount:ReaderViewModel.kt$ReaderViewModel$fun getChapterUrl(): String? - ReturnCount:ReaderViewModel.kt$ReaderViewModel$fun setAsCover() - ReturnCount:ReaderViewModel.kt$ReaderViewModel$private fun downloadNextChapters() - ReturnCount:ReaderViewModel.kt$ReaderViewModel$private fun updateTrackChapterRead(readerChapter: ReaderChapter) - ReturnCount:ReaderViewModel.kt$ReaderViewModel$suspend fun preload(chapter: ReaderChapter) - ReturnCount:ViewExtensions.kt$fun View?.isVisibleOnScreen(): Boolean + ReturnCount:ReaderViewModel.kt$ReaderViewModel$fun saveImages() + ReturnCount:ReaderViewModel.kt$ReaderViewModel$fun setAsCover(useExtraPage: Boolean) + ReturnCount:ReaderViewModel.kt$ReaderViewModel$fun shareImages() + ReturnCount:ReorderSortTag.kt$ReorderSortTag$fun await(tag: String, newPosition: Int): Result + ReturnCount:TimeRange.kt$TimeRange.Companion$fun fromPreferenceString(timeRange: String): TimeRange? ReturnCount:WebViewInterceptor.kt$WebViewInterceptor$override fun intercept(chain: Interceptor.Chain): Response ReturnCount:WebViewInterceptor.kt$private fun isRequestHeaderSafe(_name: String, _value: String): Boolean ReturnCount:WebtoonFrame.kt$WebtoonFrame$override fun dispatchTouchEvent(ev: MotionEvent): Boolean - ReturnCount:WebtoonPageHolder.kt$WebtoonPageHolder$private fun process(imageStream: BufferedInputStream): InputStream ReturnCount:WebtoonRecyclerView.kt$WebtoonRecyclerView.Detector$override fun onTouchEvent(ev: MotionEvent): Boolean ReturnCount:WebtoonViewer.kt$WebtoonViewer$override fun handleKeyEvent(event: KeyEvent): Boolean - ReturnCount:WebtoonViewer.kt$WebtoonViewer$private fun checkAllowPreload(page: ReaderPage?): Boolean SerialVersionUIDInSerializableClass:Category.kt$Category : Serializable SerialVersionUIDInSerializableClass:Manga.kt$Manga : Serializable + SerialVersionUIDInSerializableClass:MigrationProcedureConfig.kt$MigrationProcedureConfig : Serializable + SerialVersionUIDInSerializableClass:SourcesScreen.kt$SourcesScreen$SmartSearchConfig : Serializable + SpreadOperator:App.kt$App$( logConfig, *printers.toTypedArray(), ) SpreadOperator:ChapterRepositoryImpl.kt$ChapterRepositoryImpl$(*chapterUpdates.toTypedArray()) SpreadOperator:ChapterSanitizer.kt$ChapterSanitizer$(*CHAPTER_TRIM_CHARS) SpreadOperator:LibraryScreenModel.kt$LibraryScreenModel$(*prefFlows) + SpreadOperator:LibraryUpdateJob.kt$LibraryUpdateJob$(true, *newReadChapters.toTypedArray()) + SpreadOperator:MangaMergeRepositoryImpl.kt$MangaMergeRepositoryImpl$(*values.toTypedArray()) SpreadOperator:MangaRepositoryImpl.kt$MangaRepositoryImpl$(*mangaUpdates.toTypedArray()) - SpreadOperator:SourcesScreenModel.kt$SourcesScreenModel$( SourceUiModel.Header(it.key), *it.value.map { source -> SourceUiModel.Item(source) }.toTypedArray(), ) + SpreadOperator:ReaderViewModel.kt$ReaderViewModel$(true, *it.toTypedArray()) + SpreadOperator:SourcesScreenModel.kt$SourcesScreenModel$( SourceUiModel.Header(it.key.removePrefix(CATEGORY_KEY_PREFIX), it.value.firstOrNull()?.category != null), *it.value.map { source -> SourceUiModel.Item(source) }.toTypedArray(), ) SpreadOperator:TrackRepositoryImpl.kt$TrackRepositoryImpl$(*tracks.toTypedArray()) SwallowedException:AboutScreen.kt$AboutScreen$e: Exception SwallowedException:AndroidPreference.kt$AndroidPreference$e: ClassCastException @@ -909,18 +1722,30 @@ SwallowedException:Bangumi.kt$Bangumi$e: Exception SwallowedException:Bangumi.kt$Bangumi$e: Throwable SwallowedException:BrowseIcons.kt$e: Exception + SwallowedException:CbzCrypto.kt$CbzCrypto$e: Exception SwallowedException:ChapterCache.kt$ChapterCache$e: IOException SwallowedException:ChapterLoader.kt$ChapterLoader$e: UnsupportedRarV5Exception SwallowedException:ContextExtensions.kt$e: Exception SwallowedException:ContextExtensions.kt$e: PackageManager.NameNotFoundException SwallowedException:CrashLogUtil.kt$CrashLogUtil$e: Throwable SwallowedException:CreateBackupScreen.kt$CreateBackupScreen$e: ActivityNotFoundException + SwallowedException:CustomMangaRepositoryImpl.kt$CustomMangaRepositoryImpl$e: Exception SwallowedException:DeviceUtil.kt$DeviceUtil$e: Exception SwallowedException:DownloadPendingDeleter.kt$DownloadPendingDeleter$e: Exception SwallowedException:DownloadStore.kt$DownloadStore$e: Exception SwallowedException:Downloader.kt$Downloader$e: Throwable + SwallowedException:EHNetworkLogging.kt$ex: Exception + SwallowedException:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$e: Exception + SwallowedException:EXHMigrations.kt$EXHMigrations$e: Exception + SwallowedException:EXHMigrations.kt$EXHMigrations$e: URISyntaxException + SwallowedException:EXHMigrations.kt$EXHMigrations.MangaConfig.Companion$e: Exception + SwallowedException:EnhancedFilePrinter.kt$EnhancedFilePrinter.Writer$e: IOException + SwallowedException:ExceptionUtil.kt$t: Throwable SwallowedException:ExtensionLoader.kt$ExtensionLoader$error: PackageManager.NameNotFoundException + SwallowedException:FeedScreenModel.kt$FeedScreenModel$e: Exception + SwallowedException:GalleryAdder.kt$GalleryAdder$e: Exception SwallowedException:GetChapterByUrlAndMangaId.kt$GetChapterByUrlAndMangaId$e: Exception + SwallowedException:GetPagePreviews.kt$GetPagePreviews$e: Exception SwallowedException:HttpSource.kt$HttpSource$e: URISyntaxException SwallowedException:ImageUtil.kt$ImageUtil$e: Exception SwallowedException:Kavita.kt$Kavita$e: Exception @@ -929,15 +1754,21 @@ SwallowedException:KitsuModels.kt$KitsuSearchManga$e: IllegalArgumentException SwallowedException:Komga.kt$Komga$e: Exception SwallowedException:LibrarySortMode.kt$LibrarySort.Companion$e: Exception + SwallowedException:LibraryUpdateJob.kt$LibraryUpdateJob$e: Exception SwallowedException:LocalSource.kt$LocalSource$e: Format.UnknownFormatException SwallowedException:MangaScreen.kt$MangaScreen$e: Exception SwallowedException:MangaUpdates.kt$MangaUpdates$e: Exception SwallowedException:MangaUpdatesApi.kt$MangaUpdatesApi$e: Exception + SwallowedException:MdUtil.kt$MdUtil.Companion$e: Exception SwallowedException:MetadataUpdateJob.kt$MetadataUpdateJob$e: Exception + SwallowedException:MigrationListScreenModel.kt$MigrationListScreenModel$e: CancellationException + SwallowedException:MigrationListScreenModel.kt$MigrationListScreenModel$e: Exception SwallowedException:MyAnimeList.kt$MyAnimeList$e: Exception SwallowedException:MyAnimeList.kt$MyAnimeList$e: Throwable SwallowedException:MyAnimeListApi.kt$MyAnimeListApi$e: Exception SwallowedException:OkHttpExtensions.kt$ex: Throwable + SwallowedException:PagePreviewCache.kt$PagePreviewCache$e: Exception + SwallowedException:PagePreviewCache.kt$PagePreviewCache$e: IOException SwallowedException:Pager.kt$Pager$e: IllegalArgumentException SwallowedException:Pager.kt$Pager$e: IndexOutOfBoundsException SwallowedException:Pager.kt$Pager$e: NullPointerException @@ -949,24 +1780,30 @@ SwallowedException:SettingsDataScreen.kt$SettingsDataScreen$e: ActivityNotFoundException SwallowedException:Shikimori.kt$Shikimori$e: Exception SwallowedException:Shikimori.kt$Shikimori$e: Throwable + SwallowedException:SourceFeedScreenModel.kt$SourceFeedScreenModel$e: Exception SwallowedException:StorageStep.kt$StorageStep$e: ActivityNotFoundException SwallowedException:Suwayomi.kt$Suwayomi$e: Exception SwallowedException:TrackInfoDialog.kt$TrackInfoDialogHomeScreen.Model$e: Exception + SwallowedException:UrlImportableSource.kt$UrlImportableSource$e: URISyntaxException ThrowingExceptionsWithoutMessageOrCause:MangaScreenModel.kt$MangaScreenModel$IllegalStateException() ThrowingExceptionsWithoutMessageOrCause:OkHttpExtensions.kt$Exception() ThrowingExceptionsWithoutMessageOrCause:PackageInstallerInstaller.kt$PackageInstallerInstaller$IllegalStateException() ThrowingExceptionsWithoutMessageOrCause:ShizukuInstaller.kt$ShizukuInstaller$IllegalStateException() ThrowingExceptionsWithoutMessageOrCause:TrackInfoDialog.kt$TrackInfoDialogHomeScreen.Model$Exception() ThrowsCount:BackupCreator.kt$BackupCreator$suspend fun backup(uri: Uri, options: BackupOptions): String + ThrowsCount:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$private suspend fun updateEntryAndGetChapters(manga: Manga): Pair<List<Chapter>, List<Chapter>> ThrowsCount:FileExtensions.kt$fun File.copyAndSetReadOnlyTo(target: File, overwrite: Boolean = false, bufferSize: Int = DEFAULT_BUFFER_SIZE): File ThrowsCount:KavitaApi.kt$KavitaApi$fun getNewToken(apiUrl: String, apiKey: String): String? ThrowsCount:LocalSource.kt$LocalSource$fun getFormat(chapter: SChapter): Format + ThrowsCount:MangaScreenModel.kt$MangaScreenModel$suspend fun smartSearchMerge(manga: Manga, originalMangaId: Long): Manga + ThrowsCount:MigrationListScreenModel.kt$MigrationListScreenModel$private suspend fun runMigrations(mangas: List<MigratingManga>) TooGenericExceptionCaught:AboutScreen.kt$AboutScreen$e: Exception TooGenericExceptionCaught:AddTracks.kt$AddTracks$e: Exception TooGenericExceptionCaught:AndroidPreference.kt$AndroidPreference.Object$e: Exception TooGenericExceptionCaught:Anilist.kt$Anilist$e: Exception TooGenericExceptionCaught:Anilist.kt$Anilist$e: Throwable TooGenericExceptionCaught:AnilistModels.kt$ALManga$e: Exception + TooGenericExceptionCaught:ApiMangaParser.kt$ApiMangaParser$e: Exception TooGenericExceptionCaught:App.kt$App$e: Exception TooGenericExceptionCaught:AppUpdateDownloadJob.kt$AppUpdateDownloadJob$e: Exception TooGenericExceptionCaught:BackupCreateJob.kt$BackupCreateJob$e: Exception @@ -979,16 +1816,20 @@ TooGenericExceptionCaught:BaseTracker.kt$BaseTracker$e: Exception TooGenericExceptionCaught:BaseTracker.kt$BaseTracker$e: Throwable TooGenericExceptionCaught:BrowseIcons.kt$e: Exception + TooGenericExceptionCaught:CbzCrypto.kt$CbzCrypto$e: Exception TooGenericExceptionCaught:ChapterCache.kt$ChapterCache$e: Exception TooGenericExceptionCaught:ChapterLoader.kt$ChapterLoader$e: Throwable TooGenericExceptionCaught:ChapterRepositoryImpl.kt$ChapterRepositoryImpl$e: Exception TooGenericExceptionCaught:CloseableExtensions.kt$closeException: Throwable TooGenericExceptionCaught:CloseableExtensions.kt$e: Throwable TooGenericExceptionCaught:CloudflareInterceptor.kt$CloudflareInterceptor$e: Exception + TooGenericExceptionCaught:ConfigureExhDialog.kt$e: Exception TooGenericExceptionCaught:ContextExtensions.kt$e: Exception TooGenericExceptionCaught:ContextExtensions.kt$e: Throwable TooGenericExceptionCaught:CrashLogUtil.kt$CrashLogUtil$e: Throwable + TooGenericExceptionCaught:CrashlyticsPrinter.kt$CrashlyticsPrinter$t: Throwable TooGenericExceptionCaught:CreateCategoryWithName.kt$CreateCategoryWithName$e: Exception + TooGenericExceptionCaught:CustomMangaRepositoryImpl.kt$CustomMangaRepositoryImpl$e: Exception TooGenericExceptionCaught:DeleteCategory.kt$DeleteCategory$e: Exception TooGenericExceptionCaught:DeleteTrack.kt$DeleteTrack$e: Exception TooGenericExceptionCaught:DeviceUtil.kt$DeviceUtil$e: Exception @@ -999,6 +1840,13 @@ TooGenericExceptionCaught:Downloader.kt$Downloader$e: Exception TooGenericExceptionCaught:Downloader.kt$Downloader$e: Throwable TooGenericExceptionCaught:Downloader.kt$Downloader$error: Throwable + TooGenericExceptionCaught:EHNetworkLogging.kt$ex: Exception + TooGenericExceptionCaught:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$e: Exception + TooGenericExceptionCaught:EHentaiUpdateWorker.kt$EHentaiUpdateWorker$t: Throwable + TooGenericExceptionCaught:EXHMigrations.kt$EXHMigrations$e: Exception + TooGenericExceptionCaught:EXHMigrations.kt$EXHMigrations.MangaConfig.Companion$e: Exception + TooGenericExceptionCaught:EnhancedFilePrinter.kt$EnhancedFilePrinter.Writer$e: Exception + TooGenericExceptionCaught:ExceptionUtil.kt$t: Throwable TooGenericExceptionCaught:ExtensionApi.kt$ExtensionApi$e: Throwable TooGenericExceptionCaught:ExtensionDetailsScreenModel.kt$ExtensionDetailsScreenModel$e: Exception TooGenericExceptionCaught:ExtensionInstallActivity.kt$ExtensionInstallActivity$error: Exception @@ -1006,16 +1854,30 @@ TooGenericExceptionCaught:ExtensionLoader.kt$ExtensionLoader$e: Exception TooGenericExceptionCaught:ExtensionLoader.kt$ExtensionLoader$e: Throwable TooGenericExceptionCaught:ExtensionManager.kt$ExtensionManager$e: Exception + TooGenericExceptionCaught:FavoritesEntryRepositoryImpl.kt$FavoritesEntryRepositoryImpl$e: Exception + TooGenericExceptionCaught:FavoritesSyncHelper.kt$FavoritesSyncHelper$e: Exception + TooGenericExceptionCaught:FeedScreenModel.kt$FeedScreenModel$e: Exception + TooGenericExceptionCaught:GalleryAdder.kt$GalleryAdder$e: Exception TooGenericExceptionCaught:GetChapter.kt$GetChapter$e: Exception + TooGenericExceptionCaught:GetChapterByUrl.kt$GetChapterByUrl$e: Exception TooGenericExceptionCaught:GetChapterByUrlAndMangaId.kt$GetChapterByUrlAndMangaId$e: Exception TooGenericExceptionCaught:GetChaptersByMangaId.kt$GetChaptersByMangaId$e: Exception + TooGenericExceptionCaught:GetFlatMetadataById.kt$GetFlatMetadataById$e: Exception TooGenericExceptionCaught:GetManga.kt$GetManga$e: Exception + TooGenericExceptionCaught:GetMergedChaptersByMangaId.kt$GetMergedChaptersByMangaId$e: Exception + TooGenericExceptionCaught:GetMergedManga.kt$GetMergedManga$e: Exception + TooGenericExceptionCaught:GetMergedMangaById.kt$GetMergedMangaById$e: Exception + TooGenericExceptionCaught:GetMergedReferencesById.kt$GetMergedReferencesById$e: Exception + TooGenericExceptionCaught:GetPagePreviews.kt$GetPagePreviews$e: Exception TooGenericExceptionCaught:GetTracks.kt$GetTracks$e: Exception TooGenericExceptionCaught:GlobalExceptionHandler.kt$GlobalExceptionHandler.Companion$e: Exception TooGenericExceptionCaught:HistoryRepositoryImpl.kt$HistoryRepositoryImpl$e: Exception TooGenericExceptionCaught:HttpPageLoader.kt$HttpPageLoader$e: Throwable TooGenericExceptionCaught:ImageSaver.kt$ImageSaver$e: Exception TooGenericExceptionCaught:ImageUtil.kt$ImageUtil$e: Exception + TooGenericExceptionCaught:InsertFeedSavedSearch.kt$InsertFeedSavedSearch$e: Exception + TooGenericExceptionCaught:InsertFlatMetadata.kt$InsertFlatMetadata$e: Exception + TooGenericExceptionCaught:InsertSavedSearch.kt$InsertSavedSearch$e: Exception TooGenericExceptionCaught:InsertTrack.kt$InsertTrack$e: Exception TooGenericExceptionCaught:Kavita.kt$Kavita$e: Exception TooGenericExceptionCaught:KavitaApi.kt$KavitaApi$e: Exception @@ -1031,41 +1893,59 @@ TooGenericExceptionCaught:MangaCoverFetcher.kt$MangaCoverFetcher$e: Exception TooGenericExceptionCaught:MangaCoverScreenModel.kt$MangaCoverScreenModel$e: Exception TooGenericExceptionCaught:MangaCoverScreenModel.kt$MangaCoverScreenModel$e: Throwable + TooGenericExceptionCaught:MangaMergeRepositoryImpl.kt$MangaMergeRepositoryImpl$e: Exception TooGenericExceptionCaught:MangaRepositoryImpl.kt$MangaRepositoryImpl$e: Exception TooGenericExceptionCaught:MangaScreen.kt$MangaScreen$e: Exception + TooGenericExceptionCaught:MangaScreenModel.kt$MangaScreenModel$e: Exception TooGenericExceptionCaught:MangaScreenModel.kt$MangaScreenModel$e: Throwable TooGenericExceptionCaught:MangaUpdates.kt$MangaUpdates$e: Exception TooGenericExceptionCaught:MangaUpdatesApi.kt$MangaUpdatesApi$e: Exception + TooGenericExceptionCaught:MdUtil.kt$MdUtil.Companion$e: Exception + TooGenericExceptionCaught:MemAutoFlushingLookupTable.kt$MemAutoFlushingLookupTable$t: Throwable + TooGenericExceptionCaught:MergedSource.kt$MergedSource$e: Exception TooGenericExceptionCaught:MetadataUpdateJob.kt$MetadataUpdateJob$e: Exception TooGenericExceptionCaught:MetadataUpdateJob.kt$MetadataUpdateJob$e: Throwable + TooGenericExceptionCaught:MigrationListScreenModel.kt$MigrationListScreenModel$e: Exception TooGenericExceptionCaught:MyAnimeList.kt$MyAnimeList$e: Exception TooGenericExceptionCaught:MyAnimeList.kt$MyAnimeList$e: Throwable TooGenericExceptionCaught:MyAnimeListApi.kt$MyAnimeListApi$e: Exception TooGenericExceptionCaught:OkHttpExtensions.kt$<no name provided>$e: Exception + TooGenericExceptionCaught:OkHttpExtensions.kt$<no name provided>$error: Throwable TooGenericExceptionCaught:OkHttpExtensions.kt$ex: Throwable + TooGenericExceptionCaught:OkHttpUtil.kt$t: Throwable TooGenericExceptionCaught:OkioExtensions.kt$e: Exception TooGenericExceptionCaught:PackageInstallerInstaller.kt$PackageInstallerInstaller$e: Exception + TooGenericExceptionCaught:PagePreviewCache.kt$PagePreviewCache$e: Exception + TooGenericExceptionCaught:PagePreviewFetcher.kt$PagePreviewFetcher$e: Exception TooGenericExceptionCaught:Pager.kt$Pager$e: IndexOutOfBoundsException TooGenericExceptionCaught:Pager.kt$Pager$e: NullPointerException + TooGenericExceptionCaught:PagerPageHolder.kt$PagerPageHolder$e: Exception TooGenericExceptionCaught:PagerPageHolder.kt$PagerPageHolder$e: Throwable TooGenericExceptionCaught:QueryPagingSource.kt$QueryPagingSource$e: Exception TooGenericExceptionCaught:RarPageLoader.kt$RarPageLoader$e: Exception TooGenericExceptionCaught:ReaderActivity.kt$ReaderActivity$e: ArrayIndexOutOfBoundsException TooGenericExceptionCaught:ReaderViewModel.kt$ReaderViewModel$e: Exception TooGenericExceptionCaught:ReaderViewModel.kt$ReaderViewModel$e: Throwable + TooGenericExceptionCaught:RecommendsPagingSource.kt$RecommendsPagingSource$e: Exception TooGenericExceptionCaught:RefreshTracks.kt$RefreshTracks$e: Throwable TooGenericExceptionCaught:RenameCategory.kt$RenameCategory$e: Exception TooGenericExceptionCaught:ReorderCategory.kt$ReorderCategory$e: Exception TooGenericExceptionCaught:RestoreBackupScreen.kt$RestoreBackupScreenModel$e: Exception + TooGenericExceptionCaught:RxCoroutineBridge.kt$e: Throwable TooGenericExceptionCaught:SearchScreenModel.kt$SearchScreenModel$e: Exception TooGenericExceptionCaught:SetMangaCategories.kt$SetMangaCategories$e: Exception TooGenericExceptionCaught:SetReadStatus.kt$SetReadStatus$e: Exception TooGenericExceptionCaught:SettingsAdvancedScreen.kt$SettingsAdvancedScreen$e: Throwable TooGenericExceptionCaught:SettingsDataScreen.kt$SettingsDataScreen$e: Throwable + TooGenericExceptionCaught:SettingsDebugScreen.kt$SettingsDebugScreen$e: Exception + TooGenericExceptionCaught:SettingsEhScreen.kt$SettingsEhScreen$e: Exception + TooGenericExceptionCaught:SettingsMangadexScreen.kt$SettingsMangadexScreen$e: Exception TooGenericExceptionCaught:SettingsTrackingScreen.kt$SettingsTrackingScreen$e: Throwable TooGenericExceptionCaught:Shikimori.kt$Shikimori$e: Exception TooGenericExceptionCaught:Shikimori.kt$Shikimori$e: Throwable TooGenericExceptionCaught:ShizukuInstaller.kt$ShizukuInstaller$e: Exception + TooGenericExceptionCaught:SmartSearchScreenModel.kt$SmartSearchScreenModel$e: Exception + TooGenericExceptionCaught:SourceFeedScreenModel.kt$SourceFeedScreenModel$e: Exception TooGenericExceptionCaught:SourcePagingSource.kt$SourcePagingSource$e: Exception TooGenericExceptionCaught:Suwayomi.kt$Suwayomi$e: Exception TooGenericExceptionCaught:SyncChapterProgressWithTrack.kt$SyncChapterProgressWithTrack$e: Throwable @@ -1087,10 +1967,16 @@ TooGenericExceptionThrown:AppUpdateDownloadJob.kt$AppUpdateDownloadJob$throw Exception("Unsuccessful response") TooGenericExceptionThrown:BangumiApi.kt$BangumiApi$throw Exception("Null Response") TooGenericExceptionThrown:BangumiInterceptor.kt$BangumiInterceptor$throw Exception("Not authenticated with Bangumi") + TooGenericExceptionThrown:BilibiliHandler.kt$BilibiliHandler$throw Exception("Unknown chapter $chapterNumber") TooGenericExceptionThrown:ChapterLoader.kt$ChapterLoader$throw Exception(context.stringResource(MR.strings.page_list_empty_error)) TooGenericExceptionThrown:DownloadManager.kt$DownloadManager$throw Exception(context.stringResource(MR.strings.page_list_empty_error)) TooGenericExceptionThrown:DownloadProvider.kt$DownloadProvider$throw Exception( context.stringResource( MR.strings.invalid_location, downloadsDir?.displayablePath ?: "", ), ) TooGenericExceptionThrown:Downloader.kt$Downloader$throw Exception(context.stringResource(MR.strings.page_list_empty_error)) + TooGenericExceptionThrown:EHentai.kt$EHentai$throw Exception( "Invalid igneous cookie, try re-logging or finding a correct one to input in the login menu", ) + TooGenericExceptionThrown:EHentai.kt$EHentai$throw Exception("Exceeded page quota") + TooGenericExceptionThrown:EHentai.kt$EHentai$throw Exception("HTTP error ${response.code}", exception) + TooGenericExceptionThrown:EHentai.kt$EHentai$throw Exception("HTTP error ${response.code}", stacktrace) + TooGenericExceptionThrown:EHentai.kt$EHentai$throw Exception(it.text()) TooGenericExceptionThrown:ExtensionLoader.kt$ExtensionLoader$throw Exception("Unknown source class type: ${obj.javaClass}") TooGenericExceptionThrown:HttpSource.kt$HttpSource$throw RuntimeException(e) TooGenericExceptionThrown:KitsuApi.kt$KitsuApi$throw Exception("Could not find manga") @@ -1099,23 +1985,35 @@ TooGenericExceptionThrown:KitsuModels.kt$throw Exception("Unknown status") TooGenericExceptionThrown:LocalSource.kt$LocalSource$throw Exception(context.stringResource(MR.strings.chapter_not_found)) TooGenericExceptionThrown:LocalSource.kt$LocalSource$throw Exception(context.stringResource(MR.strings.local_invalid_format)) + TooGenericExceptionThrown:MangaPlusHandler.kt$MangaPlusHandler$throw Exception("error getting images") TooGenericExceptionThrown:MangaUpdates.kt$MangaUpdates$throw Throwable("Unable to login") + TooGenericExceptionThrown:MdList.kt$MdList$throw Exception("not used") + TooGenericExceptionThrown:PageHandler.kt$PageHandler$throw Exception("${chapter.scanlator} not supported") + TooGenericExceptionThrown:ReaderViewModel.kt$ReaderViewModel$throw Exception("Not an image") + TooGenericExceptionThrown:RecommendsPagingSource.kt$Anilist$throw Exception("'$queryParam' not found") TooGenericExceptionThrown:ShikimoriApi.kt$ShikimoriApi$throw Exception("Too much mangas in response") TooGenericExceptionThrown:ShikimoriInterceptor.kt$ShikimoriInterceptor$throw Exception("Not authenticated with Shikimori") TooGenericExceptionThrown:ShizukuInstaller.kt$ShizukuInstaller$throw RuntimeException("Failed to commit install session $sessionId") TooGenericExceptionThrown:ShizukuInstaller.kt$ShizukuInstaller$throw RuntimeException("Failed to create install session") TooGenericExceptionThrown:ShizukuInstaller.kt$ShizukuInstaller$throw RuntimeException("Failed to write APK to session $sessionId") TooGenericExceptionThrown:TrackInfoDialog.kt$TrackInfoDialogHomeScreen.Model$throw Exception() + TooGenericExceptionThrown:WhatsNewDialog.kt$throw Exception("Exception on ${version.versionName}:$index:$charIndex", e) TooManyFunctions:AndroidDatabaseHandler.kt$AndroidDatabaseHandler : DatabaseHandler + TooManyFunctions:AndroidSourceManager.kt$AndroidSourceManager : SourceManager TooManyFunctions:Anilist.kt$Anilist : BaseTrackerDeletableTracker TooManyFunctions:AnilistApi.kt$AnilistApi TooManyFunctions:Bangumi.kt$Bangumi : BaseTracker TooManyFunctions:BaseTracker.kt$BaseTracker : Tracker + TooManyFunctions:BilibiliHandler.kt$BilibiliHandler TooManyFunctions:BrowseSourceScreenModel.kt$BrowseSourceScreenModel : StateScreenModel TooManyFunctions:CategoryRepositoryImpl.kt$CategoryRepositoryImpl : CategoryRepository + TooManyFunctions:CbzCrypto.kt$CbzCrypto TooManyFunctions:ChapterRepository.kt$ChapterRepository TooManyFunctions:ChapterRepositoryImpl.kt$ChapterRepositoryImpl : ChapterRepository TooManyFunctions:ChapterTransition.kt$eu.kanade.presentation.reader.ChapterTransition.kt + TooManyFunctions:DatabaseHandler.kt$DatabaseHandler + TooManyFunctions:DebugFunctions.kt$DebugFunctions + TooManyFunctions:DelegatedHttpSource.kt$DelegatedHttpSource : HttpSource TooManyFunctions:DohProviders.kt$eu.kanade.tachiyomi.network.DohProviders.kt TooManyFunctions:DownloadCache.kt$DownloadCache TooManyFunctions:DownloadManager.kt$DownloadManager @@ -1123,10 +2021,15 @@ TooManyFunctions:DownloadProvider.kt$DownloadProvider TooManyFunctions:DownloadQueueScreenModel.kt$DownloadQueueScreenModel : ScreenModel TooManyFunctions:Downloader.kt$Downloader + TooManyFunctions:EHentai.kt$EHentai : HttpSourceMetadataSourceUrlImportableSourceNamespaceSourcePagePreviewSource + TooManyFunctions:EnhancedHttpSource.kt$EnhancedHttpSource : HttpSource TooManyFunctions:EpubFile.kt$EpubFile : Closeable TooManyFunctions:ExtensionLoader.kt$ExtensionLoader TooManyFunctions:ExtensionManager.kt$ExtensionManager TooManyFunctions:ExtensionsScreenModel.kt$ExtensionsScreenModel : StateScreenModel + TooManyFunctions:FeedSavedSearchRepository.kt$FeedSavedSearchRepository + TooManyFunctions:FeedSavedSearchRepositoryImpl.kt$FeedSavedSearchRepositoryImpl : FeedSavedSearchRepository + TooManyFunctions:FeedScreenModel.kt$FeedScreenModel : StateScreenModel TooManyFunctions:HttpSource.kt$HttpSource : CatalogueSource TooManyFunctions:ImageUtil.kt$ImageUtil TooManyFunctions:Kavita.kt$Kavita : BaseTrackerEnhancedTracker @@ -1134,36 +2037,61 @@ TooManyFunctions:Komga.kt$Komga : BaseTrackerEnhancedTracker TooManyFunctions:LibraryPreferences.kt$LibraryPreferences TooManyFunctions:LibraryScreenModel.kt$LibraryScreenModel : StateScreenModel + TooManyFunctions:LibraryUpdateJob.kt$LibraryUpdateJob : CoroutineWorker TooManyFunctions:LocalSource.kt$LocalSource : CatalogueSourceUnmeteredSource + TooManyFunctions:Logging.kt$exh.log.Logging.kt TooManyFunctions:MangaCoverFetcher.kt$MangaCoverFetcher : Fetcher + TooManyFunctions:MangaDex.kt$MangaDex : DelegatedHttpSourceMetadataSourceUrlImportableSourceFollowsSourceLoginSourceRandomMangaSourceNamespaceSource + TooManyFunctions:MangaDexAuthService.kt$MangaDexAuthService + TooManyFunctions:MangaDexService.kt$MangaDexService + TooManyFunctions:MangaMergeRepository.kt$MangaMergeRepository + TooManyFunctions:MangaMergeRepositoryImpl.kt$MangaMergeRepositoryImpl : MangaMergeRepository + TooManyFunctions:MangaMetadataRepository.kt$MangaMetadataRepository + TooManyFunctions:MangaMetadataRepositoryImpl.kt$MangaMetadataRepositoryImpl : MangaMetadataRepository TooManyFunctions:MangaRepository.kt$MangaRepository TooManyFunctions:MangaRepositoryImpl.kt$MangaRepositoryImpl : MangaRepository TooManyFunctions:MangaRestorer.kt$MangaRestorer + TooManyFunctions:MangaScreen.kt$MangaScreen : ScreenAssistContentScreen TooManyFunctions:MangaScreenModel.kt$MangaScreenModel : StateScreenModel + TooManyFunctions:MangaType.kt$exh.util.MangaType.kt TooManyFunctions:MangaUpdates.kt$MangaUpdates : BaseTrackerDeletableTracker + TooManyFunctions:MdList.kt$MdList : BaseTracker + TooManyFunctions:MdUtil.kt$MdUtil$Companion + TooManyFunctions:MergedSource.kt$MergedSource : HttpSource + TooManyFunctions:MigrationListScreenModel.kt$MigrationListScreenModel : ScreenModel TooManyFunctions:MyAnimeList.kt$MyAnimeList : BaseTrackerDeletableTracker TooManyFunctions:MyAnimeListApi.kt$MyAnimeListApi TooManyFunctions:NotificationReceiver.kt$NotificationReceiver : BroadcastReceiver TooManyFunctions:NotificationReceiver.kt$NotificationReceiver$Companion + TooManyFunctions:PagePreviewFetcher.kt$PagePreviewFetcher : Fetcher TooManyFunctions:PagerPageHolder.kt$PagerPageHolder : ReaderPageImageViewPositionableView TooManyFunctions:PagerViewer.kt$PagerViewer : Viewer TooManyFunctions:ParsedHttpSource.kt$ParsedHttpSource : HttpSource + TooManyFunctions:RaisedSearchMetadata.kt$RaisedSearchMetadata TooManyFunctions:ReaderActivity.kt$ReaderActivity : BaseActivity TooManyFunctions:ReaderPageImageView.kt$ReaderPageImageView : FrameLayout TooManyFunctions:ReaderPreferences.kt$ReaderPreferences TooManyFunctions:ReaderViewModel.kt$ReaderViewModel : ViewModel + TooManyFunctions:SecurityPreferences.kt$SecurityPreferences + TooManyFunctions:SettingsAdvancedScreen.kt$SettingsAdvancedScreen : SearchableSettings + TooManyFunctions:SettingsEhScreen.kt$SettingsEhScreen : SearchableSettings TooManyFunctions:SettingsItems.kt$tachiyomi.presentation.core.components.SettingsItems.kt + TooManyFunctions:SettingsReaderScreen.kt$SettingsReaderScreen : SearchableSettings TooManyFunctions:SharedPreferencesDataStore.kt$SharedPreferencesDataStore : PreferenceDataStore TooManyFunctions:Shikimori.kt$Shikimori : BaseTrackerDeletableTracker + TooManyFunctions:SourceFeedScreenModel.kt$SourceFeedScreenModel : StateScreenModel TooManyFunctions:SourcePreferences.kt$SourcePreferences TooManyFunctions:Suwayomi.kt$Suwayomi : BaseTrackerEnhancedTracker TooManyFunctions:Tracker.kt$Tracker + TooManyFunctions:UiPreferences.kt$UiPreferences + TooManyFunctions:UnsortedPreferences.kt$UnsortedPreferences TooManyFunctions:UpdatesScreenModel.kt$UpdatesScreenModel : StateScreenModel TooManyFunctions:WebtoonPageHolder.kt$WebtoonPageHolder : WebtoonBaseHolder TooManyFunctions:WebtoonRecyclerView.kt$WebtoonRecyclerView : RecyclerView TooManyFunctions:WebtoonViewer.kt$WebtoonViewer : Viewer TopLevelPropertyNaming:App.kt$private const val ACTION_DISABLE_INCOGNITO_MODE = "tachi.action.DISABLE_INCOGNITO_MODE" TopLevelPropertyNaming:AppBar.kt$const val SEARCH_DEBOUNCE_MILLIS = 250L + TopLevelPropertyNaming:AppModule.kt$// SY --> private const val LEGACY_DATABASE_NAME = "tachiyomi.db" TopLevelPropertyNaming:BackupCreateJob.kt$private const val IS_AUTO_BACKUP_KEY = "is_auto_backup" // Boolean TopLevelPropertyNaming:BackupCreateJob.kt$private const val LOCATION_URI_KEY = "location_uri" // String TopLevelPropertyNaming:BackupCreateJob.kt$private const val OPTIONS_KEY = "options" // BooleanArray @@ -1172,6 +2100,14 @@ TopLevelPropertyNaming:BackupRestoreJob.kt$private const val LOCATION_URI_KEY = "location_uri" // String TopLevelPropertyNaming:BackupRestoreJob.kt$private const val OPTIONS_KEY = "options" // BooleanArray TopLevelPropertyNaming:BackupRestoreJob.kt$private const val SYNC_KEY = "sync" // Boolean + TopLevelPropertyNaming:CbzCrypto.kt$private const val ALIAS_CBZ = "cbzPw" + TopLevelPropertyNaming:CbzCrypto.kt$private const val ALIAS_SQL = "sqlPw" + TopLevelPropertyNaming:CbzCrypto.kt$private const val BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC + TopLevelPropertyNaming:CbzCrypto.kt$private const val BUFFER_SIZE = 2048 + TopLevelPropertyNaming:CbzCrypto.kt$private const val CRYPTO_SETTINGS = "$ALGORITHM/$BLOCK_MODE/$PADDING" + TopLevelPropertyNaming:CbzCrypto.kt$private const val IV_SIZE = 16 + TopLevelPropertyNaming:CbzCrypto.kt$private const val KEY_SIZE = 256 + TopLevelPropertyNaming:CbzCrypto.kt$private const val SQL_PASSWORD_LENGTH = 32 TopLevelPropertyNaming:ChapterCache.kt$/** Application cache version. */ private const val PARAMETER_APP_VERSION = 1 TopLevelPropertyNaming:ChapterCache.kt$/** The maximum number of bytes this cache should use to store. */ private const val PARAMETER_CACHE_SIZE = 100L * 1024 * 1024 TopLevelPropertyNaming:ChapterCache.kt$/** The number of values per cache entry. Must be positive. */ private const val PARAMETER_VALUE_COUNT = 1 @@ -1181,7 +2117,6 @@ TopLevelPropertyNaming:ColorFilterPage.kt$private const val RED_MASK: Long = 0x00FF0000 TopLevelPropertyNaming:ComicInfo.kt$const val COMIC_INFO_FILE = "ComicInfo.xml" TopLevelPropertyNaming:DatabaseAdapter.kt$private const val LIST_OF_STRINGS_SEPARATOR = ", " - TopLevelPropertyNaming:DateExtensions.kt$private const val MILLISECONDS_IN_DAY = 86_400_000L TopLevelPropertyNaming:DisplayExtensions.kt$// make sure icons on the nav rail fit private const val TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP = 600 TopLevelPropertyNaming:DisplayExtensions.kt$// some tablets have screen width like 711dp = 1600px / 2.25 private const val TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP = 700 TopLevelPropertyNaming:DisplayExtensions.kt$private const val TABLET_UI_REQUIRED_SCREEN_WIDTH_DP = 720 @@ -1206,6 +2141,7 @@ TopLevelPropertyNaming:LibraryUpdateNotifier.kt$private const val NOTIF_ICON_SIZE = 192 TopLevelPropertyNaming:LibraryUpdateNotifier.kt$private const val NOTIF_MAX_CHAPTERS = 5 TopLevelPropertyNaming:LibraryUpdateNotifier.kt$private const val NOTIF_TITLE_MAX_LEN = 45 + TopLevelPropertyNaming:LocalCoverManager.kt$private const val COVER_ARCHIVE_NAME = "cover.cbi" TopLevelPropertyNaming:LocalCoverManager.kt$private const val DEFAULT_COVER_NAME = "cover.jpg" TopLevelPropertyNaming:MainActivity.kt$// Splash screen private const val SPLASH_MIN_DURATION = 500 // ms TopLevelPropertyNaming:MainActivity.kt$private const val SPLASH_EXIT_ANIM_DURATION = 400L // ms @@ -1214,6 +2150,15 @@ TopLevelPropertyNaming:ReaderNavigationOverlayView.kt$private const val FADE_DURATION = 1000L TopLevelPropertyNaming:ReaderPageImageView.kt$private const val MAX_ZOOM_SCALE = 5F TopLevelPropertyNaming:ShizukuInstaller.kt$private const val SHIZUKU_PERMISSION_REQUEST_CODE = 14045 + TopLevelPropertyNaming:SourceIds.kt$// Lewd source IDs const val LEWD_SOURCE_SERIES = 6900L + TopLevelPropertyNaming:SourceIds.kt$const val EH_SOURCE_ID = LEWD_SOURCE_SERIES + 1 + TopLevelPropertyNaming:SourceIds.kt$const val EIGHTMUSES_SOURCE_ID = 1802675169972965535 + TopLevelPropertyNaming:SourceIds.kt$const val EXH_SOURCE_ID = LEWD_SOURCE_SERIES + 2 + TopLevelPropertyNaming:SourceIds.kt$const val HBROWSE_SOURCE_ID = 1401584337232758222 + TopLevelPropertyNaming:SourceIds.kt$const val MERGED_SOURCE_ID = LEWD_SOURCE_SERIES + 69 + TopLevelPropertyNaming:SourceIds.kt$const val PURURIN_SOURCE_ID = 2221515250486218861 + TopLevelPropertyNaming:SourceIds.kt$const val TSUMINO_SOURCE_ID = 6707338697138388238 + TopLevelPropertyNaming:StorageManager.kt$// SY --> private const val LOGS_PATH = "logs" TopLevelPropertyNaming:StorageManager.kt$private const val AUTOMATIC_BACKUPS_PATH = "autobackup" TopLevelPropertyNaming:StorageManager.kt$private const val DOWNLOADS_PATH = "downloads" TopLevelPropertyNaming:StorageManager.kt$private const val LOCAL_SOURCE_PATH = "local" @@ -1223,18 +2168,21 @@ TopLevelPropertyNaming:SuwayomiApi.kt$private const val LOGIN_TITLE = "Login (Basic Auth)" TopLevelPropertyNaming:SuwayomiApi.kt$private const val PASSWORD_DEFAULT = "" TopLevelPropertyNaming:SuwayomiApi.kt$private const val PASSWORD_TITLE = "Password (Basic Auth)" + TopLevelPropertyNaming:Version.kt$const val syDebugVersion: String = "0" TopLevelPropertyNaming:WebtoonAdapter.kt$/** * View holder type of a chapter page view. */ private const val PAGE_VIEW = 0 TopLevelPropertyNaming:WebtoonAdapter.kt$/** * View holder type of a chapter transition view. */ private const val TRANSITION_VIEW = 1 TopLevelPropertyNaming:WebtoonRecyclerView.kt$private const val ANIMATOR_DURATION_TIME = 200 TopLevelPropertyNaming:WebtoonRecyclerView.kt$private const val DEFAULT_RATE = 1f TopLevelPropertyNaming:WebtoonRecyclerView.kt$private const val MAX_SCALE_RATE = 3f TopLevelPropertyNaming:WebtoonRecyclerView.kt$private const val MIN_RATE = 0.5f - UnstableCollections:CategoryScreen.kt$List<Category> + TopLevelPropertyNaming:WhatsNewDialog.kt$private const val bullet = "\u2022" + TopLevelPropertyNaming:__Assets.kt$private var __AllAssets: ____KtList<ImageVector>? = null + TopLevelPropertyNaming:__EhAssets.kt$private var __AllAssets: ____KtList<ImageVector>? = null + TopLevelPropertyNaming:__Ehassets.kt$private var __AllAssets: ____KtList<ImageVector>? = null + TopLevelPropertyNaming:__Exh.kt$private var __AllAssets: ____KtList<ImageVector>? = null UnstableCollections:Commons.kt$List<Category> UnstableCollections:Commons.kt$Set<String> UnstableCollections:GlobalSearchCardRow.kt$List<Manga> - UnstableCollections:GlobalSearchScreen.kt$Map<CatalogueSource, SearchItemResult> - UnstableCollections:HistoryScreen.kt$List<HistoryUiModel> UnstableCollections:LibraryComfortableGrid.kt$List<LibraryItem> UnstableCollections:LibraryComfortableGrid.kt$List<LibraryManga> UnstableCollections:LibraryCompactGrid.kt$List<LibraryItem> @@ -1249,7 +2197,6 @@ UnstableCollections:MangaScreen.kt$List<ChapterList.Item> UnstableCollections:MultiSelectListPreferenceWidget.kt$Set<String> UnstableCollections:PreferenceScreen.kt$List<Preference> - UnstableCollections:ScanlatorFilterDialog.kt$Set<String> UnstableCollections:SettingsDownloadScreen.kt$SettingsDownloadScreen$List<Category> UnstableCollections:SettingsLibraryScreen.kt$SettingsLibraryScreen$List<Category> UnstableCollections:TrackInfoDialogHome.kt$List<TrackItem> @@ -1257,6 +2204,9 @@ UnstableCollections:TriStateListDialog.kt$List<T> UnstableCollections:UpdatesScreen.kt$List<UpdatesItem> UnstableCollections:WebViewScreenContent.kt$Map<String, String> + UnusedParameter:EditMangaDialog.kt$context: Context + UnusedParameter:MergedSource.kt$MergedSource$dedupe: Boolean = true + UnusedParameter:MergedSource.kt$MergedSource$editScanlators: Boolean = false UnusedParameter:UpdatesRepositoryImpl.kt$UpdatesRepositoryImpl$dateUpload: Long UnusedPrivateMember:AppThemePreferenceWidget.kt$@PreviewLightDark @Composable private fun AppThemesListPreview() UnusedPrivateMember:ChapterTransition.kt$@PreviewLightDark @Composable private fun TransitionTextLongTitlePreview() @@ -1267,6 +2217,7 @@ UnusedPrivateMember:CrashScreen.kt$@PreviewLightDark @Composable private fun CrashScreenPreview() UnusedPrivateMember:EmptyScreen.kt$@PreviewLightDark @Composable private fun NoActionPreview() UnusedPrivateMember:EmptyScreen.kt$@PreviewLightDark @Composable private fun WithActionPreview() + UnusedPrivateMember:ExhUtils.kt$@Composable @PreviewLightDark private fun ExhUtilsPreview() UnusedPrivateMember:GuidesStep.kt$@PreviewLightDark @Composable private fun GuidesStepPreview() UnusedPrivateMember:HistoryDialogs.kt$@PreviewLightDark @Composable private fun HistoryDeleteDialogPreview() UnusedPrivateMember:HistoryItem.kt$@PreviewLightDark @Composable private fun HistoryItemPreviews( @PreviewParameter(HistoryWithRelationsProvider::class) historyWithRelations: HistoryWithRelations, ) @@ -1280,18 +2231,25 @@ UnusedPrivateMember:PageIndicatorText.kt$@PreviewLightDark @Composable private fun PageIndicatorTextPreview() UnusedPrivateMember:PermissionStep.kt$PermissionStep$@Composable private fun SectionHeader( text: String, modifier: Modifier = Modifier, ) UnusedPrivateMember:ReadingModeSelectDialog.kt$@PreviewLightDark @Composable private fun DialogContentPreview() + UnusedPrivateMember:SettingsAdvancedScreen.kt$SettingsAdvancedScreen$@Composable private fun getDownloaderGroup(): Preference.PreferenceGroup UnusedPrivateMember:SwitchPreferenceWidget.kt$@PreviewLightDark @Composable private fun SwitchPreferenceWidgetPreview() UnusedPrivateMember:TextPreferenceWidget.kt$@PreviewLightDark @Composable private fun TextPreferenceWidgetPreview() UnusedPrivateMember:TrackInfoDialogHome.kt$@PreviewLightDark @Composable private fun TrackInfoDialogHomePreviews( @PreviewParameter(TrackInfoDialogHomePreviewProvider::class) content: @Composable () -> Unit, ) UnusedPrivateMember:TrackInfoDialogSelector.kt$@PreviewLightDark @Composable private fun TrackStatusSelectorPreviews() UnusedPrivateMember:TrackLogoIcon.kt$@PreviewLightDark @Composable private fun TrackLogoIconPreviews( @PreviewParameter(TrackLogoIconPreviewProvider::class) tracker: Tracker, ) UnusedPrivateMember:TrackerSearch.kt$@PreviewLightDark @Composable private fun TrackerSearchPreviews( @PreviewParameter(TrackerSearchPreviewProvider::class) content: @Composable () -> Unit, ) + UnusedPrivateProperty:ChapterCache.kt$/** The maximum number of bytes this cache should use to store. */ private const val PARAMETER_CACHE_SIZE = 100L * 1024 * 1024 + UnusedPrivateProperty:FavoritesSyncHelper.kt$FavoritesSyncHelper$i + UnusedPrivateProperty:FeedScreenModel.kt$FeedScreenModel$private val updateManga: UpdateManga = Injekt.get() + UnusedPrivateProperty:GalleryAdder.kt$GalleryAdder$i UnusedPrivateProperty:JavaScriptEngine.kt$JavaScriptEngine$context: Context UnusedPrivateProperty:LibraryUpdateJob.kt$LibraryUpdateJob.Companion$private const val MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60 - UnusedPrivateProperty:MainActivity.kt$MainActivity$private val sourcePreferences: SourcePreferences by injectLazy() - UnusedPrivateProperty:MainActivity.kt$MainActivity$private val uiPreferences: UiPreferences by injectLazy() UnusedPrivateProperty:MetadataUpdateJob.kt$MetadataUpdateJob.Companion$private const val MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60 + UnusedPrivateProperty:PageHandler.kt$PageHandler$private val mdList: MdList + UnusedPrivateProperty:PageHandler.kt$PageHandler$private val preferences: TrackPreferences + UnusedPrivateProperty:SourceFeedScreenModel.kt$SourceFeedScreenModel$private val updateManga: UpdateManga = Injekt.get() UseCheckOrError:CatalogueSource.kt$CatalogueSource$throw IllegalStateException("Not used") + UseCheckOrError:MainActivity.kt$MainActivity$throw IllegalStateException("Can only be called on main thread!") UseCheckOrError:MangaScreenModel.kt$MangaScreenModel$throw IllegalStateException() UseCheckOrError:PackageInstallerInstaller.kt$PackageInstallerInstaller$throw IllegalStateException() UseCheckOrError:ReadingMode.kt$ReadingMode.Companion$throw IllegalStateException("Preference value must be resolved: $preference") @@ -1299,6 +2257,7 @@ UseCheckOrError:Source.kt$Source$throw IllegalStateException("Not used") UseCheckOrError:SourceFilterDialog.kt$throw IllegalStateException("Unknown TriState state: $this") UseCheckOrError:TransactionContext.kt$TransactionElement$throw IllegalStateException("Transaction was never started or was already released") + UtilityClassWithPublicConstructor:MdUtil.kt$MdUtil VariableNaming:Chapter.kt$Chapter$var date_fetch: Long VariableNaming:Chapter.kt$Chapter$var last_modified: Long VariableNaming:Chapter.kt$Chapter$var last_page_read: Int @@ -1323,5 +2282,7 @@ VariableNaming:TrackSearch.kt$TrackSearch$var publishing_status: String = "" VariableNaming:TrackSearch.kt$TrackSearch$var publishing_type: String = "" VariableNaming:TrackSearch.kt$TrackSearch$var start_date: String = "" + Wrapping:CbzCrypto.kt$CbzCrypto$( + Wrapping:LibraryScreenModel.kt$LibraryScreenModel$-> diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 9b23bda71..d3245202e 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -36,6 +36,7 @@ dependencies { implementation(libs.image.decoder) implementation(libs.unifile) + implementation(libs.bundles.archive) api(kotlinx.coroutines.core) api(kotlinx.serialization.json) diff --git a/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/CbzCrypto.kt b/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/CbzCrypto.kt index c1f442c99..1f8a3f503 100644 --- a/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/CbzCrypto.kt +++ b/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/CbzCrypto.kt @@ -3,25 +3,15 @@ package eu.kanade.tachiyomi.util.storage import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties import android.util.Base64 -import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.core.security.SecurityPreferences -import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -import logcat.LogPriority -import net.lingala.zip4j.ZipFile -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 net.lingala.zip4j.model.enums.AesKeyStrength import net.lingala.zip4j.model.enums.EncryptionMethod -import tachiyomi.core.common.util.system.ImageUtil -import tachiyomi.core.common.util.system.logcat import uy.kohesive.injekt.injectLazy import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream @@ -136,12 +126,15 @@ object CbzCrypto { } fun getDecryptedPasswordCbz(): CharArray { - return decrypt(securityPreferences.cbzPassword().get(), ALIAS_CBZ).toCharArray() + val encryptedPassword = securityPreferences.cbzPassword().get() + if (encryptedPassword.isBlank()) error("This archive is encrypted please set a password") + + return decrypt(encryptedPassword, ALIAS_CBZ).toCharArray() } private fun generateAndEncryptSqlPw() { val charPool: List = ('a'..'z') + ('A'..'Z') + ('0'..'9') - val password = (1..32).map { + val password = (1..SQL_PASSWORD_LENGTH).map { charPool[SecureRandom().nextInt(charPool.size)] }.joinToString("", transform = { it.toString() }) securityPreferences.sqlPassword().set(encrypt(password, encryptionCipherSql)) @@ -152,27 +145,6 @@ object CbzCrypto { return decrypt(securityPreferences.sqlPassword().get(), ALIAS_SQL).toByteArray() } - /** - * Function that returns true when the supplied password - * can Successfully decrypt the supplied zip archive - * not very elegant but this is the solution recommended by the maintainer for checking passwords - * a real password check will likely be implemented in the future though - */ - fun checkCbzPassword(zip4j: ZipFile, password: CharArray): Boolean { - try { - zip4j.setPassword(password) - zip4j.use { zip -> - zip.getInputStream(zip.fileHeaders.firstOrNull()) - } - return true - } catch (e: Exception) { - logcat(LogPriority.WARN) { - "Wrong CBZ archive password for: ${zip4j.file.name} in: ${zip4j.file.parentFile?.name}" - } - } - return false - } - fun isPasswordSet(): Boolean { return securityPreferences.cbzPassword().get().isNotEmpty() } @@ -228,133 +200,6 @@ object CbzCrypto { } return String(bytes).contains(DEFAULT_COVER_NAME, ignoreCase = true) } - - 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(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) setZipParametersEncrypted(zipParameters) - zipOutputStream.putNextEntry(zipParameters) - - zipOutputStream.use { output -> - inputStream.use { input -> - input.copyTo(output) - } - } - } - - - fun UniFile.addFilesToZip(files: List, password: CharArray? = null) { - val zipOutputStream = - if (password != null) ZipOutputStream(this.openOutputStream(), password) - else ZipOutputStream(this.openOutputStream()) - - - files.forEach { - val zipParameters = ZipParameters() - if (password != null) 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(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 = mutableListOf() - - if (this.isEncryptedZip()) zipInputStream.setPassword(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 - } - } } private const val BUFFER_SIZE = 2048 @@ -369,4 +214,6 @@ private const val CRYPTO_SETTINGS = "$ALGORITHM/$BLOCK_MODE/$PADDING" private const val KEYSTORE = "AndroidKeyStore" private const val ALIAS_CBZ = "cbzPw" private const val ALIAS_SQL = "sqlPw" + +private const val SQL_PASSWORD_LENGTH = 32 // SY <-- diff --git a/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/EpubFile.kt b/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/EpubFile.kt index a00ee69e7..8f2e1dcda 100644 --- a/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/EpubFile.kt +++ b/core/common/src/main/kotlin/eu/kanade/tachiyomi/util/storage/EpubFile.kt @@ -1,22 +1,36 @@ 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 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 -import java.util.zip.ZipEntry -import java.util.zip.ZipFile /** * Wrapper over ZipFile to load files in epub format. */ -class EpubFile(file: File) : Closeable { +// SY --> +class EpubFile(file: UniFile, context: Context) : Closeable { + + private val tempFileManager: UniFileTempFileManager by injectLazy() /** * Zip file of this epub. */ - private val zip = ZipFile(file) + private val zip = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + ZipFile(tempFileManager.createTempFile(file)) + } else { + ZipFile(file.openReadOnlyChannel(context)) + } + // SY <-- /** * Path separator used by this epub. @@ -33,14 +47,14 @@ class EpubFile(file: File) : Closeable { /** * Returns an input stream for reading the contents of the specified zip file entry. */ - fun getInputStream(entry: ZipEntry): InputStream { + 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): ZipEntry? { + fun getEntry(name: String): ZipArchiveEntry? { return zip.getEntry(name) } diff --git a/core/common/src/main/kotlin/tachiyomi/core/common/storage/UniFileExtensions.kt b/core/common/src/main/kotlin/tachiyomi/core/common/storage/UniFileExtensions.kt index 8bbd9b3a7..f99ad117c 100644 --- a/core/common/src/main/kotlin/tachiyomi/core/common/storage/UniFileExtensions.kt +++ b/core/common/src/main/kotlin/tachiyomi/core/common/storage/UniFileExtensions.kt @@ -1,6 +1,21 @@ 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('.') @@ -10,3 +25,201 @@ 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, 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 = 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 <-- diff --git a/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt b/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt index 6f207afc8..053a54b41 100644 --- a/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt +++ b/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt @@ -26,8 +26,6 @@ import androidx.core.graphics.red import androidx.exifinterface.media.ExifInterface import com.hippo.unifile.UniFile import logcat.LogPriority -import net.lingala.zip4j.ZipFile -import net.lingala.zip4j.model.FileHeader import tachiyomi.decoder.Format import tachiyomi.decoder.ImageDecoder import java.io.BufferedInputStream @@ -133,20 +131,8 @@ object ImageUtil { * * @return true if the width is greater than the height */ - fun isWideImage( - imageStream: BufferedInputStream, - // SY --> - zip4jFile: ZipFile?, - zip4jEntry: FileHeader?, - // SY <-- - ): Boolean { - val options = extractImageOptions( - imageStream, - // SY --> - zip4jFile, - zip4jEntry, - // SY <-- - ) + fun isWideImage(imageStream: BufferedInputStream): Boolean { + val options = extractImageOptions(imageStream) return options.outWidth > options.outHeight } @@ -271,19 +257,9 @@ object ImageUtil { * * @return true if the height:width ratio is greater than 3. */ - private fun isTallImage( - imageStream: InputStream, - // SY --> - zip4jFile: ZipFile?, - zip4jEntry: FileHeader?, - // SY <-- - ): Boolean { + private fun isTallImage(imageStream: InputStream): Boolean { val options = extractImageOptions( imageStream, - // SY --> - zip4jFile, - zip4jEntry, - // SY <-- resetAfterExtraction = false, ) @@ -297,18 +273,9 @@ object ImageUtil { tmpDir: UniFile, imageFile: UniFile, filenamePrefix: String, - // SY --> - zip4jFile: ZipFile?, - zip4jEntry: FileHeader?, - // SY <-- ): Boolean { - if (isAnimatedAndSupported(imageFile.openInputStream()) || !isTallImage( - imageFile.openInputStream(), - // SY --> - zip4jFile, - zip4jEntry, - // SY <-- - ) + if (isAnimatedAndSupported(imageFile.openInputStream()) || + !isTallImage(imageFile.openInputStream()) ) { return true } @@ -321,10 +288,6 @@ object ImageUtil { val options = extractImageOptions( imageFile.openInputStream(), - // SY --> - zip4jFile, - zip4jEntry, - // SY <-- resetAfterExtraction = false, ).apply { inJustDecodeBounds = false @@ -641,17 +604,8 @@ object ImageUtil { */ private fun extractImageOptions( imageStream: InputStream, - // SY --> - zip4jFile: ZipFile?, - zip4jEntry: FileHeader?, - // SY <-- resetAfterExtraction: Boolean = true, ): BitmapFactory.Options { - // SY --> - // zip4j does currently not support mark() and reset() - if (zip4jFile != null && zip4jEntry != null) return extractImageOptionsZip4j(zip4jFile, zip4jEntry) - // SY <-- - imageStream.mark(Int.MAX_VALUE) val imageBytes = imageStream.readBytes() @@ -661,16 +615,6 @@ object ImageUtil { return options } - // SY --> - private fun extractImageOptionsZip4j(zip4jFile: ZipFile?, zip4jEntry: FileHeader?): BitmapFactory.Options { - zip4jFile?.getInputStream(zip4jEntry).use { imageStream -> - val imageBytes = imageStream?.readBytes() - val options = BitmapFactory.Options().apply { inJustDecodeBounds = true } - imageBytes?.size?.let { BitmapFactory.decodeByteArray(imageBytes, 0, it, options) } - return options - } - } - /** * Creates random exif metadata used as padding to make * the size of files inside CBZ archives unique diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ec8557f6a..a3a8ff728 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -33,6 +33,7 @@ jsoup = "org.jsoup:jsoup:1.17.2" disklrucache = "com.jakewharton:disklrucache:2.0.2" unifile = "com.github.tachiyomiorg:unifile:7c257e1c64" +common-compress = "org.apache.commons:commons-compress:1.26.0" junrar = "com.github.junrar:junrar:7.5.5" zip4j = "net.lingala.zip4j:zip4j:2.11.5" @@ -111,6 +112,7 @@ google-api-client-oauth = "com.google.oauth-client:google-oauth-client:1.34.1" [bundles] acra = ["acra-http", "acra-scheduler"] +archive = ["common-compress", "junrar"] okhttp = ["okhttp-core", "okhttp-logging", "okhttp-brotli", "okhttp-dnsoverhttps"] js-engine = ["quickjs-android"] sqlite = ["sqlite-framework", "sqlite-ktx", "sqlite-android"] diff --git a/i18n-sy/src/commonMain/resources/MR/base/strings.xml b/i18n-sy/src/commonMain/resources/MR/base/strings.xml index a4dcc92d4..773aa60ac 100644 --- a/i18n-sy/src/commonMain/resources/MR/base/strings.xml +++ b/i18n-sy/src/commonMain/resources/MR/base/strings.xml @@ -324,9 +324,13 @@ Center margin type Insert spacer to accommodate deadspace on foldable devices. - - Cache images inside CBZ/CBR archives on disk - Temporarily copy images inside comic book archives to disk while reading \nMay improve reader performance + + Load from file + Load into memory + Copy to disk + Archive reader mode + The way in which images inside archives, such as CBZ or CBR, are being loaded + diff --git a/source-local/build.gradle.kts b/source-local/build.gradle.kts index 727d2a9c3..9409b5207 100644 --- a/source-local/build.gradle.kts +++ b/source-local/build.gradle.kts @@ -15,7 +15,7 @@ kotlin { // SY <-- implementation(libs.unifile) - implementation(libs.junrar) + implementation(libs.bundles.archive) // SY --> implementation(libs.zip4j) // SY <-- diff --git a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt index 6036ab6e3..2859a3d1b 100644 --- a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt +++ b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt @@ -1,6 +1,7 @@ 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 @@ -11,10 +12,6 @@ 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.CbzCrypto.addStreamToZip -import eu.kanade.tachiyomi.util.storage.CbzCrypto.getCoverStreamFromZip -import eu.kanade.tachiyomi.util.storage.CbzCrypto.getZipInputStream -import eu.kanade.tachiyomi.util.storage.CbzCrypto.isEncryptedZip import eu.kanade.tachiyomi.util.storage.EpubFile import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -31,7 +28,11 @@ import tachiyomi.core.metadata.comicinfo.copyFromComicInfo import tachiyomi.core.metadata.comicinfo.getComicInfo import tachiyomi.core.metadata.tachiyomi.MangaDetails 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 @@ -268,7 +269,13 @@ actual class LocalSource( } } is Format.Rar -> { - JunrarArchive(tempFileManager.createTempFile(chapter)).use { 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) @@ -330,7 +337,7 @@ actual class LocalSource( val format = Format.valueOf(chapterFile) if (format is Format.Epub) { - EpubFile(tempFileManager.createTempFile(format.file)).use { epub -> + EpubFile(format.file, context).use { epub -> epub.fillMetadata(manga, this) } } @@ -397,10 +404,15 @@ actual class LocalSource( format.file.isEncryptedZip() ) } - // SY <-- } is Format.Rar -> { - JunrarArchive(tempFileManager.createTempFile(format.file)).use { archive -> + 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) } } @@ -409,15 +421,17 @@ actual class LocalSource( } } is Format.Epub -> { - EpubFile(tempFileManager.createTempFile(format.file)).use { epub -> - val entry = epub.getImagesFromPages() - .firstOrNull() - ?.let { epub.getEntry(it) } + // SY --> + EpubFile(format.file, context).use { epub -> + // SY <-- + val entry = epub.getImagesFromPages() + .firstOrNull() + ?.let { epub.getEntry(it) } - 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 diff --git a/source-local/src/androidMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt b/source-local/src/androidMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt index 0738ce1c4..390e901dc 100644 --- a/source-local/src/androidMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt +++ b/source-local/src/androidMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt @@ -4,7 +4,7 @@ import android.content.Context import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.util.storage.CbzCrypto -import eu.kanade.tachiyomi.util.storage.CbzCrypto.addStreamToZip +import tachiyomi.core.common.storage.addStreamToZip import eu.kanade.tachiyomi.util.storage.DiskUtil import tachiyomi.core.common.storage.nameWithoutExtension import tachiyomi.core.common.util.system.ImageUtil