mirror of
https://github.com/mihonapp/mihon.git
synced 2025-07-01 13:37:50 +02:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
c87ba6231d | |||
c5ca739b49 | |||
00fe4cdf2d | |||
69be3e1e87 | |||
2cb3984d68 | |||
5901978889 | |||
8bf1cf3cc5 | |||
f6af1184bc | |||
4880741b8b | |||
e8627800fe | |||
907fbb94a2 | |||
fd2028557e | |||
91fa1ec6b2 | |||
628c525599 | |||
bbc00768f0 | |||
5b09461ccf | |||
1a439ecece | |||
836aec4396 | |||
0b5dec9bab | |||
fd56123267 |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
I acknowledge that:
|
I acknowledge that:
|
||||||
|
|
||||||
- I have updated to the latest version of the app (stable is v0.10.5)
|
- I have updated to the latest version of the app (stable is v0.10.7)
|
||||||
- I have updated all extensions
|
- I have updated all extensions
|
||||||
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
|
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
|
||||||
|
|
||||||
|
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -9,7 +9,7 @@ labels: "bug"
|
|||||||
|
|
||||||
I acknowledge that:
|
I acknowledge that:
|
||||||
|
|
||||||
- I have updated to the latest version of the app (stable is v0.10.5)
|
- I have updated to the latest version of the app (stable is v0.10.7)
|
||||||
- I have updated all extensions
|
- I have updated all extensions
|
||||||
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
|
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
|
||||||
|
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -9,7 +9,7 @@ labels: "feature"
|
|||||||
|
|
||||||
I acknowledge that:
|
I acknowledge that:
|
||||||
|
|
||||||
- I have updated to the latest version of the app (stable is v0.10.5)
|
- I have updated to the latest version of the app (stable is v0.10.7)
|
||||||
- I have updated all extensions
|
- I have updated all extensions
|
||||||
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
|
- If this is an issue with an extension, that I should be opening an issue in https://github.com/inorichi/tachiyomi-extensions
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ DON'T: https://github.com/inorichi/tachiyomi/issues/75
|
|||||||
* Write a detailed issue, explaining what it should do or how. Avoid writing just "like X app does"
|
* Write a detailed issue, explaining what it should do or how. Avoid writing just "like X app does"
|
||||||
* Include screenshot (if needed)
|
* Include screenshot (if needed)
|
||||||
|
|
||||||
Catalogue requests should be created at https://github.com/inorichi/tachiyomi-extensions, they do not belong in this repository.
|
Source requests should be created at https://github.com/inorichi/tachiyomi-extensions, they do not belong in this repository.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
@ -5,8 +5,8 @@ import java.text.SimpleDateFormat
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
|
||||||
apply plugin: 'kotlin-kapt'
|
apply plugin: 'kotlin-kapt'
|
||||||
|
apply plugin: 'kotlin-parcelize'
|
||||||
apply plugin: 'kotlinx-serialization'
|
apply plugin: 'kotlinx-serialization'
|
||||||
apply plugin: 'com.github.zellius.shortcut-helper'
|
apply plugin: 'com.github.zellius.shortcut-helper'
|
||||||
|
|
||||||
@ -42,8 +42,8 @@ android {
|
|||||||
minSdkVersion AndroidConfig.minSdk
|
minSdkVersion AndroidConfig.minSdk
|
||||||
targetSdkVersion AndroidConfig.targetSdk
|
targetSdkVersion AndroidConfig.targetSdk
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
versionCode 52
|
versionCode 53
|
||||||
versionName "0.10.6"
|
versionName "0.10.7"
|
||||||
|
|
||||||
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
||||||
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
|
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
|
||||||
@ -67,13 +67,13 @@ android {
|
|||||||
applicationIdSuffix ".debug"
|
applicationIdSuffix ".debug"
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
postprocessing {
|
// postprocessing {
|
||||||
obfuscate false
|
// obfuscate false
|
||||||
optimizeCode true
|
// optimizeCode true
|
||||||
removeUnusedCode false
|
// removeUnusedCode false
|
||||||
removeUnusedResources true
|
// removeUnusedResources true
|
||||||
proguardFiles 'proguard-rules.pro'
|
// proguardFiles 'proguard-rules.pro'
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,10 +123,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
androidExtensions {
|
|
||||||
experimental = true
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
// Source models and interfaces from Tachiyomi 1.x
|
// Source models and interfaces from Tachiyomi 1.x
|
||||||
@ -239,7 +235,6 @@ dependencies {
|
|||||||
implementation 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
|
implementation 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
|
||||||
implementation 'eu.davidea:flexible-adapter:5.1.0'
|
implementation 'eu.davidea:flexible-adapter:5.1.0'
|
||||||
implementation 'eu.davidea:flexible-adapter-ui:1.0.0'
|
implementation 'eu.davidea:flexible-adapter-ui:1.0.0'
|
||||||
implementation 'com.nononsenseapps:filepicker:2.5.2'
|
|
||||||
implementation 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0'
|
implementation 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0'
|
||||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||||
implementation 'com.github.carlosesco:DirectionalViewPager:a844dbca0a'
|
implementation 'com.github.carlosesco:DirectionalViewPager:a844dbca0a'
|
||||||
@ -280,7 +275,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$BuildPluginsVersion.KOTLIN"
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$BuildPluginsVersion.KOTLIN"
|
||||||
|
|
||||||
final coroutines_version = '1.4.1'
|
final coroutines_version = '1.4.2'
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||||
|
|
||||||
|
@ -80,10 +80,6 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ui.webview.WebViewActivity"
|
android:name=".ui.webview.WebViewActivity"
|
||||||
android:configChanges="uiMode|orientation|screenSize" />
|
android:configChanges="uiMode|orientation|screenSize" />
|
||||||
<activity
|
|
||||||
android:name=".widget.CustomLayoutPickerActivity"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/FilePickerTheme" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.setting.track.AnilistLoginActivity"
|
android:name=".ui.setting.track.AnilistLoginActivity"
|
||||||
android:label="Anilist">
|
android:label="Anilist">
|
||||||
|
@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||||||
import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
||||||
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
||||||
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -92,6 +93,7 @@ object Migrations {
|
|||||||
}
|
}
|
||||||
if (oldVersion < 44) {
|
if (oldVersion < 44) {
|
||||||
// Reset sorting preference if using removed sort by source
|
// Reset sorting preference if using removed sort by source
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
if (preferences.librarySortingMode().get() == LibrarySort.SOURCE) {
|
if (preferences.librarySortingMode().get() == LibrarySort.SOURCE) {
|
||||||
preferences.librarySortingMode().set(LibrarySort.ALPHA)
|
preferences.librarySortingMode().set(LibrarySort.ALPHA)
|
||||||
}
|
}
|
||||||
@ -117,7 +119,10 @@ object Migrations {
|
|||||||
|
|
||||||
// Force MAL log out due to login flow change
|
// Force MAL log out due to login flow change
|
||||||
val trackManager = Injekt.get<TrackManager>()
|
val trackManager = Injekt.get<TrackManager>()
|
||||||
|
if (trackManager.myAnimeList.isLogged) {
|
||||||
trackManager.myAnimeList.logout()
|
trackManager.myAnimeList.logout()
|
||||||
|
context.toast(R.string.myanimelist_relogin)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ class BackupNotifier(private val context: Context) {
|
|||||||
val uri = destFile.getUriCompat(context)
|
val uri = destFile.getUriCompat(context)
|
||||||
|
|
||||||
addAction(
|
addAction(
|
||||||
R.drawable.nnf_ic_file_folder,
|
R.drawable.ic_folder_24dp,
|
||||||
context.getString(R.string.action_open_log),
|
context.getString(R.string.action_open_log),
|
||||||
NotificationReceiver.openErrorLogPendingActivity(context, uri)
|
NotificationReceiver.openErrorLogPendingActivity(context, uri)
|
||||||
)
|
)
|
||||||
|
@ -137,7 +137,7 @@ class DownloadPendingDeleter(context: Context) {
|
|||||||
val id: Long,
|
val id: Long,
|
||||||
val url: String,
|
val url: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val scanlator: String?
|
val scanlator: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,7 +109,7 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||||||
|
|
||||||
setContentIntent(errorLogIntent)
|
setContentIntent(errorLogIntent)
|
||||||
addAction(
|
addAction(
|
||||||
R.drawable.nnf_ic_file_folder,
|
R.drawable.ic_folder_24dp,
|
||||||
context.getString(R.string.action_open_log),
|
context.getString(R.string.action_open_log),
|
||||||
errorLogIntent
|
errorLogIntent
|
||||||
)
|
)
|
||||||
|
@ -121,7 +121,9 @@ object PreferenceKeys {
|
|||||||
|
|
||||||
const val automaticExtUpdates = "automatic_ext_updates"
|
const val automaticExtUpdates = "automatic_ext_updates"
|
||||||
|
|
||||||
const val allowNsfwSource = "allow_nsfw_source"
|
const val showNsfwSource = "show_nsfw_source"
|
||||||
|
const val showNsfwExtension = "show_nsfw_extension"
|
||||||
|
const val labelNsfwExtension = "label_nsfw_extension"
|
||||||
|
|
||||||
const val startScreen = "start_screen"
|
const val startScreen = "start_screen"
|
||||||
|
|
||||||
|
@ -37,10 +37,4 @@ object PreferenceValues {
|
|||||||
VERTICAL,
|
VERTICAL,
|
||||||
BOTH
|
BOTH
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class NsfwAllowance {
|
|
||||||
ALLOWED,
|
|
||||||
PARTIAL,
|
|
||||||
BLOCKED
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import com.tfcporciuncula.flow.Preference
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.NsfwAllowance
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
@ -225,7 +224,9 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
|
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
|
||||||
|
|
||||||
fun allowNsfwSource() = flowPrefs.getEnum(Keys.allowNsfwSource, NsfwAllowance.ALLOWED)
|
fun showNsfwSource() = flowPrefs.getBoolean(Keys.showNsfwSource, true)
|
||||||
|
fun showNsfwExtension() = flowPrefs.getBoolean(Keys.showNsfwExtension, true)
|
||||||
|
fun labelNsfwExtension() = prefs.getBoolean(Keys.labelNsfwExtension, true)
|
||||||
|
|
||||||
fun extensionUpdatesCount() = flowPrefs.getInt("ext_updates_count", 0)
|
fun extensionUpdatesCount() = flowPrefs.getInt("ext_updates_count", 0)
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ data class ALUserManga(
|
|||||||
"DROPPED" -> Anilist.DROPPED
|
"DROPPED" -> Anilist.DROPPED
|
||||||
"PLANNING" -> Anilist.PLANNING
|
"PLANNING" -> Anilist.PLANNING
|
||||||
"REPEATING" -> Anilist.REPEATING
|
"REPEATING" -> Anilist.REPEATING
|
||||||
else -> throw NotImplementedError("Unknown status")
|
else -> throw NotImplementedError("Unknown status: $list_status")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ fun Track.toAnilistStatus() = when (status) {
|
|||||||
Anilist.DROPPED -> "DROPPED"
|
Anilist.DROPPED -> "DROPPED"
|
||||||
Anilist.PLANNING -> "PLANNING"
|
Anilist.PLANNING -> "PLANNING"
|
||||||
Anilist.REPEATING -> "REPEATING"
|
Anilist.REPEATING -> "REPEATING"
|
||||||
else -> throw NotImplementedError("Unknown status")
|
else -> throw NotImplementedError("Unknown status: $status")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
private val preferences: PreferencesHelper by injectLazy()
|
||||||
@ -102,5 +102,5 @@ fun Track.toAnilistScore(): String = when (preferences.anilistScoreType().get())
|
|||||||
}
|
}
|
||||||
// 10 point decimal
|
// 10 point decimal
|
||||||
"POINT_10_DECIMAL" -> (score / 10).toString()
|
"POINT_10_DECIMAL" -> (score / 10).toString()
|
||||||
else -> throw Exception("Unknown score type")
|
else -> throw NotImplementedError("Unknown score type")
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ fun Track.toBangumiStatus() = when (status) {
|
|||||||
Bangumi.ON_HOLD -> "on_hold"
|
Bangumi.ON_HOLD -> "on_hold"
|
||||||
Bangumi.DROPPED -> "dropped"
|
Bangumi.DROPPED -> "dropped"
|
||||||
Bangumi.PLANNING -> "wish"
|
Bangumi.PLANNING -> "wish"
|
||||||
else -> throw NotImplementedError("Unknown status")
|
else -> throw NotImplementedError("Unknown status: $status")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toTrackStatus(status: String) = when (status) {
|
fun toTrackStatus(status: String) = when (status) {
|
||||||
@ -17,6 +17,5 @@ fun toTrackStatus(status: String) = when (status) {
|
|||||||
"on_hold" -> Bangumi.ON_HOLD
|
"on_hold" -> Bangumi.ON_HOLD
|
||||||
"dropped" -> Bangumi.DROPPED
|
"dropped" -> Bangumi.DROPPED
|
||||||
"wish" -> Bangumi.PLANNING
|
"wish" -> Bangumi.PLANNING
|
||||||
|
else -> throw NotImplementedError("Unknown status: $status")
|
||||||
else -> throw Exception("Unknown status")
|
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
|
|
||||||
fun ensureLoggedIn() {
|
fun ensureLoggedIn() {
|
||||||
if (isAuthorized) return
|
if (isAuthorized) return
|
||||||
if (!isLogged) throw Exception("MAL login credentials not found")
|
if (!isLogged) throw Exception(context.getString(R.string.myanimelist_creds_missing))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logout() {
|
override fun logout() {
|
||||||
|
@ -9,7 +9,7 @@ fun Track.toShikimoriStatus() = when (status) {
|
|||||||
Shikimori.DROPPED -> "dropped"
|
Shikimori.DROPPED -> "dropped"
|
||||||
Shikimori.PLANNING -> "planned"
|
Shikimori.PLANNING -> "planned"
|
||||||
Shikimori.REPEATING -> "rewatching"
|
Shikimori.REPEATING -> "rewatching"
|
||||||
else -> throw NotImplementedError("Unknown status")
|
else -> throw NotImplementedError("Unknown status: $status")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toTrackStatus(status: String) = when (status) {
|
fun toTrackStatus(status: String) = when (status) {
|
||||||
@ -19,6 +19,5 @@ fun toTrackStatus(status: String) = when (status) {
|
|||||||
"dropped" -> Shikimori.DROPPED
|
"dropped" -> Shikimori.DROPPED
|
||||||
"planned" -> Shikimori.PLANNING
|
"planned" -> Shikimori.PLANNING
|
||||||
"rewatching" -> Shikimori.REPEATING
|
"rewatching" -> Shikimori.REPEATING
|
||||||
|
else -> throw NotImplementedError("Unknown status: $status")
|
||||||
else -> throw Exception("Unknown status")
|
|
||||||
}
|
}
|
||||||
|
@ -124,8 +124,7 @@ class ExtensionManager(
|
|||||||
.map { it.extension }
|
.map { it.extension }
|
||||||
installedExtensions
|
installedExtensions
|
||||||
.flatMap { it.sources }
|
.flatMap { it.sources }
|
||||||
// overwrite is needed until the bundled sources are removed
|
.forEach { sourceManager.registerSource(it) }
|
||||||
.forEach { sourceManager.registerSource(it, true) }
|
|
||||||
|
|
||||||
untrustedExtensions = extensions
|
untrustedExtensions = extensions
|
||||||
.filterIsInstance<LoadResult.Untrusted>()
|
.filterIsInstance<LoadResult.Untrusted>()
|
||||||
|
@ -6,7 +6,6 @@ import android.content.pm.PackageInfo
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import dalvik.system.PathClassLoader
|
import dalvik.system.PathClassLoader
|
||||||
import eu.kanade.tachiyomi.annotations.Nsfw
|
import eu.kanade.tachiyomi.annotations.Nsfw
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.model.LoadResult
|
import eu.kanade.tachiyomi.extension.model.LoadResult
|
||||||
@ -26,8 +25,8 @@ import uy.kohesive.injekt.injectLazy
|
|||||||
internal object ExtensionLoader {
|
internal object ExtensionLoader {
|
||||||
|
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
private val preferences: PreferencesHelper by injectLazy()
|
||||||
private val allowNsfwSource by lazy {
|
private val loadNsfwSource by lazy {
|
||||||
preferences.allowNsfwSource().get()
|
preferences.showNsfwSource().get()
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val EXTENSION_FEATURE = "tachiyomi.extension"
|
private const val EXTENSION_FEATURE = "tachiyomi.extension"
|
||||||
@ -133,7 +132,7 @@ internal object ExtensionLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val isNsfw = appInfo.metaData.getInt(METADATA_NSFW) == 1
|
val isNsfw = appInfo.metaData.getInt(METADATA_NSFW) == 1
|
||||||
if (allowNsfwSource == PreferenceValues.NsfwAllowance.BLOCKED && isNsfw) {
|
if (!loadNsfwSource && isNsfw) {
|
||||||
return LoadResult.Error("NSFW extension $pkgName not allowed")
|
return LoadResult.Error("NSFW extension $pkgName not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +217,7 @@ internal object ExtensionLoader {
|
|||||||
* Checks whether a Source or SourceFactory is annotated with @Nsfw.
|
* Checks whether a Source or SourceFactory is annotated with @Nsfw.
|
||||||
*/
|
*/
|
||||||
private fun isSourceNsfw(clazz: Any): Boolean {
|
private fun isSourceNsfw(clazz: Any): Boolean {
|
||||||
if (allowNsfwSource == PreferenceValues.NsfwAllowance.ALLOWED) {
|
if (loadNsfwSource) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,14 +62,18 @@ interface Source : tachiyomi.source.Source {
|
|||||||
/**
|
/**
|
||||||
* [1.x API] Get the updated details for a manga.
|
* [1.x API] Get the updated details for a manga.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
|
override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
|
||||||
return fetchMangaDetails(manga.toSManga()).awaitSingle()
|
val sManga = manga.toSManga()
|
||||||
.toMangaInfo()
|
val networkManga = fetchMangaDetails(sManga).awaitSingle()
|
||||||
|
sManga.copyFrom(networkManga)
|
||||||
|
return sManga.toMangaInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [1.x API] Get all the available chapters for a manga.
|
* [1.x API] Get all the available chapters for a manga.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
|
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
|
||||||
return fetchChapterList(manga.toSManga()).awaitSingle()
|
return fetchChapterList(manga.toSManga()).awaitSingle()
|
||||||
.map { it.toChapterInfo() }
|
.map { it.toChapterInfo() }
|
||||||
@ -78,6 +82,7 @@ interface Source : tachiyomi.source.Source {
|
|||||||
/**
|
/**
|
||||||
* [1.x API] Get the list of pages a chapter has.
|
* [1.x API] Get the list of pages a chapter has.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
override suspend fun getPageList(chapter: ChapterInfo): List<tachiyomi.source.model.Page> {
|
override suspend fun getPageList(chapter: ChapterInfo): List<tachiyomi.source.model.Page> {
|
||||||
return fetchPageList(chapter.toSChapter()).awaitSingle()
|
return fetchPageList(chapter.toSChapter()).awaitSingle()
|
||||||
.map { it.toPageUrl() }
|
.map { it.toPageUrl() }
|
||||||
|
@ -32,11 +32,11 @@ open class SourceManager(private val context: Context) {
|
|||||||
|
|
||||||
fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
|
fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
|
||||||
|
|
||||||
internal fun registerSource(source: Source, overwrite: Boolean = false) {
|
internal fun registerSource(source: Source) {
|
||||||
if (overwrite || !sourcesMap.containsKey(source.id)) {
|
if (!sourcesMap.containsKey(source.id)) {
|
||||||
sourcesMap[source.id] = source
|
sourcesMap[source.id] = source
|
||||||
}
|
}
|
||||||
if (overwrite || !stubSourcesMap.containsKey(source.id)) {
|
if (!stubSourcesMap.containsKey(source.id)) {
|
||||||
stubSourcesMap[source.id] = StubSource(source.id)
|
stubSourcesMap[source.id] = StubSource(source.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
|
|||||||
import com.bluelinelabs.conductor.ControllerChangeType
|
import com.bluelinelabs.conductor.ControllerChangeType
|
||||||
import com.bluelinelabs.conductor.RestoreViewOnCreateController
|
import com.bluelinelabs.conductor.RestoreViewOnCreateController
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
import kotlinx.android.synthetic.clearFindViewByIdCache
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
||||||
@ -54,11 +53,6 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
|||||||
return inflateView(inflater, container)
|
return inflateView(inflater, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
|
||||||
super.onDestroyView(view)
|
|
||||||
clearFindViewByIdCache()
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun inflateView(inflater: LayoutInflater, container: ViewGroup): View
|
abstract fun inflateView(inflater: LayoutInflater, container: ViewGroup): View
|
||||||
|
|
||||||
open fun onViewCreated(view: View) {}
|
open fun onViewCreated(view: View) {}
|
||||||
|
@ -4,16 +4,23 @@ import android.view.View
|
|||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.databinding.ExtensionCardItemBinding
|
import eu.kanade.tachiyomi.databinding.ExtensionCardItemBinding
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.model.InstallStep
|
import eu.kanade.tachiyomi.extension.model.InstallStep
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class ExtensionHolder(view: View, val adapter: ExtensionAdapter) :
|
class ExtensionHolder(view: View, val adapter: ExtensionAdapter) :
|
||||||
FlexibleViewHolder(view, adapter) {
|
FlexibleViewHolder(view, adapter) {
|
||||||
|
|
||||||
private val binding = ExtensionCardItemBinding.bind(view)
|
private val binding = ExtensionCardItemBinding.bind(view)
|
||||||
|
|
||||||
|
private val shouldLabelNsfw by lazy {
|
||||||
|
Injekt.get<PreferencesHelper>().labelNsfwExtension()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
binding.extButton.setOnClickListener {
|
binding.extButton.setOnClickListener {
|
||||||
adapter.buttonClickListener.onButtonClick(bindingAdapterPosition)
|
adapter.buttonClickListener.onButtonClick(bindingAdapterPosition)
|
||||||
@ -30,7 +37,7 @@ class ExtensionHolder(view: View, val adapter: ExtensionAdapter) :
|
|||||||
extension is Extension.Untrusted -> itemView.context.getString(R.string.ext_untrusted)
|
extension is Extension.Untrusted -> itemView.context.getString(R.string.ext_untrusted)
|
||||||
extension is Extension.Installed && extension.isObsolete -> itemView.context.getString(R.string.ext_obsolete)
|
extension is Extension.Installed && extension.isObsolete -> itemView.context.getString(R.string.ext_obsolete)
|
||||||
extension is Extension.Installed && extension.isUnofficial -> itemView.context.getString(R.string.ext_unofficial)
|
extension is Extension.Installed && extension.isUnofficial -> itemView.context.getString(R.string.ext_unofficial)
|
||||||
extension.isNsfw -> itemView.context.getString(R.string.ext_nsfw_short)
|
extension.isNsfw && shouldLabelNsfw -> itemView.context.getString(R.string.ext_nsfw_short)
|
||||||
else -> ""
|
else -> ""
|
||||||
}.toUpperCase()
|
}.toUpperCase()
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.browse.extension
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
@ -56,7 +55,7 @@ open class ExtensionPresenter(
|
|||||||
private fun toItems(tuple: ExtensionTuple): List<ExtensionItem> {
|
private fun toItems(tuple: ExtensionTuple): List<ExtensionItem> {
|
||||||
val context = Injekt.get<Application>()
|
val context = Injekt.get<Application>()
|
||||||
val activeLangs = preferences.enabledLanguages().get()
|
val activeLangs = preferences.enabledLanguages().get()
|
||||||
val showNsfwExtensions = preferences.allowNsfwSource().get() != PreferenceValues.NsfwAllowance.BLOCKED
|
val showNsfwExtensions = preferences.showNsfwExtension().get()
|
||||||
|
|
||||||
val (installed, untrusted, available) = tuple
|
val (installed, untrusted, available) = tuple
|
||||||
|
|
||||||
|
@ -459,7 +459,6 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
|
|
||||||
preferences.sourceDisplayMode().set(mode)
|
preferences.sourceDisplayMode().set(mode)
|
||||||
presenter.refreshDisplayMode()
|
|
||||||
activity?.invalidateOptionsMenu()
|
activity?.invalidateOptionsMenu()
|
||||||
setupRecycler(view)
|
setupRecycler(view)
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.davidea.flexibleadapter.items.ISectionable
|
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
@ -34,10 +33,13 @@ import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper
|
|||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import eu.kanade.tachiyomi.util.removeCovers
|
import eu.kanade.tachiyomi.util.removeCovers
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asFlow
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.isActive
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
@ -106,11 +108,6 @@ open class BrowseSourcePresenter(
|
|||||||
*/
|
*/
|
||||||
private var pageSubscription: Subscription? = null
|
private var pageSubscription: Subscription? = null
|
||||||
|
|
||||||
/**
|
|
||||||
* Job to initialize manga details.
|
|
||||||
*/
|
|
||||||
private var initializerJob: Job? = null
|
|
||||||
|
|
||||||
override fun onCreate(savedState: Bundle?) {
|
override fun onCreate(savedState: Bundle?) {
|
||||||
super.onCreate(savedState)
|
super.onCreate(savedState)
|
||||||
|
|
||||||
@ -140,8 +137,6 @@ open class BrowseSourcePresenter(
|
|||||||
this.query = query
|
this.query = query
|
||||||
this.appliedFilters = filters
|
this.appliedFilters = filters
|
||||||
|
|
||||||
initializeManga()
|
|
||||||
|
|
||||||
// Create a new pager.
|
// Create a new pager.
|
||||||
pager = createPager(query, filters)
|
pager = createPager(query, filters)
|
||||||
|
|
||||||
@ -193,27 +188,6 @@ open class BrowseSourcePresenter(
|
|||||||
return pager.hasNextPage
|
return pager.hasNextPage
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribes to the initializer of manga details and updates the view if needed.
|
|
||||||
*/
|
|
||||||
private fun initializeManga() {
|
|
||||||
initializerJob?.cancel()
|
|
||||||
initializerJob = launchIO {
|
|
||||||
mangaDetailsFlow
|
|
||||||
.onEach { mangas ->
|
|
||||||
if (!isActive) return@onEach
|
|
||||||
|
|
||||||
try {
|
|
||||||
mangas.filter { it.thumbnail_url == null && !it.initialized }
|
|
||||||
.map { getMangaDetails(it) }
|
|
||||||
.forEach { launchUI { view?.onMangaInitialized(it) } }
|
|
||||||
} catch (error: Exception) {
|
|
||||||
launchUI { Timber.e(error) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a manga from the database for the given manga from network. It creates a new entry
|
* Returns a manga from the database for the given manga from network. It creates a new entry
|
||||||
* if the manga is not yet in the database.
|
* if the manga is not yet in the database.
|
||||||
@ -239,7 +213,19 @@ open class BrowseSourcePresenter(
|
|||||||
* @param mangas the list of manga to initialize.
|
* @param mangas the list of manga to initialize.
|
||||||
*/
|
*/
|
||||||
fun initializeMangas(mangas: List<Manga>) {
|
fun initializeMangas(mangas: List<Manga>) {
|
||||||
launchIO { mangaDetailsFlow.emit(mangas) }
|
launchIO {
|
||||||
|
mangas.asFlow()
|
||||||
|
.filter { it.thumbnail_url == null && !it.initialized }
|
||||||
|
.map { getMangaDetails(it) }
|
||||||
|
.onEach {
|
||||||
|
launchUI {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
view?.onMangaInitialized(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.catch { e -> Timber.e(e) }
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -249,17 +235,15 @@ open class BrowseSourcePresenter(
|
|||||||
* @return the initialized manga
|
* @return the initialized manga
|
||||||
*/
|
*/
|
||||||
private suspend fun getMangaDetails(manga: Manga): Manga {
|
private suspend fun getMangaDetails(manga: Manga): Manga {
|
||||||
return try {
|
try {
|
||||||
source.getMangaDetails(manga.toMangaInfo())
|
val networkManga = source.getMangaDetails(manga.toMangaInfo())
|
||||||
.let { networkManga ->
|
|
||||||
manga.copyFrom(networkManga.toSManga())
|
manga.copyFrom(networkManga.toSManga())
|
||||||
manga.initialized = true
|
manga.initialized = true
|
||||||
db.insertManga(manga).executeAsBlocking()
|
db.insertManga(manga).executeAsBlocking()
|
||||||
manga
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
manga
|
Timber.e(e)
|
||||||
}
|
}
|
||||||
|
return manga
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,13 +267,6 @@ open class BrowseSourcePresenter(
|
|||||||
db.insertManga(manga).executeAsBlocking()
|
db.insertManga(manga).executeAsBlocking()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Refreshes the active display mode.
|
|
||||||
*/
|
|
||||||
fun refreshDisplayMode() {
|
|
||||||
initializeManga()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the filter states for the current source.
|
* Set the filter states for the current source.
|
||||||
*
|
*
|
||||||
@ -321,7 +298,7 @@ open class BrowseSourcePresenter(
|
|||||||
is Filter.Text -> TextSectionItem(it)
|
is Filter.Text -> TextSectionItem(it)
|
||||||
is Filter.Select<*> -> SelectSectionItem(it)
|
is Filter.Select<*> -> SelectSectionItem(it)
|
||||||
else -> null
|
else -> null
|
||||||
} as? ISectionable<*, *>
|
}
|
||||||
}
|
}
|
||||||
subItems.forEach { it.header = group }
|
subItems.forEach { it.header = group }
|
||||||
group.subItems = subItems
|
group.subItems = subItems
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
|
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
|
||||||
import eu.kanade.tachiyomi.util.view.inflate
|
import eu.kanade.tachiyomi.util.view.inflate
|
||||||
import eu.kanade.tachiyomi.widget.RecyclerViewPagerAdapter
|
import eu.kanade.tachiyomi.widget.RecyclerViewPagerAdapter
|
||||||
|
|
||||||
@ -34,8 +35,9 @@ class LibraryAdapter(private val controller: LibraryController) : RecyclerViewPa
|
|||||||
* @return a new view.
|
* @return a new view.
|
||||||
*/
|
*/
|
||||||
override fun createView(container: ViewGroup): View {
|
override fun createView(container: ViewGroup): View {
|
||||||
val view = container.inflate(R.layout.library_category) as LibraryCategoryView
|
val binding = LibraryCategoryBinding.inflate(LayoutInflater.from(container.context), container, false)
|
||||||
view.onCreate(controller)
|
val view: LibraryCategoryView = binding.root
|
||||||
|
view.onCreate(controller, binding)
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,12 +14,11 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
|||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
|
||||||
import eu.kanade.tachiyomi.util.lang.plusAssign
|
import eu.kanade.tachiyomi.util.lang.plusAssign
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.inflate
|
import eu.kanade.tachiyomi.util.view.inflate
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import kotlinx.android.synthetic.main.library_category.view.fast_scroller
|
|
||||||
import kotlinx.android.synthetic.main.library_category.view.swipe_refresh
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -70,15 +69,15 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
|
|
||||||
private var lastClickPosition = -1
|
private var lastClickPosition = -1
|
||||||
|
|
||||||
fun onCreate(controller: LibraryController) {
|
fun onCreate(controller: LibraryController, binding: LibraryCategoryBinding) {
|
||||||
this.controller = controller
|
this.controller = controller
|
||||||
|
|
||||||
recycler = if (preferences.libraryDisplayMode().get() == DisplayMode.LIST) {
|
recycler = if (preferences.libraryDisplayMode().get() == DisplayMode.LIST) {
|
||||||
(swipe_refresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
|
(binding.swipeRefresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(swipe_refresh.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
|
(binding.swipeRefresh.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
|
||||||
spanCount = controller.mangaPerRow
|
spanCount = controller.mangaPerRow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,28 +86,28 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
|
|
||||||
recycler.setHasFixedSize(true)
|
recycler.setHasFixedSize(true)
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
swipe_refresh.addView(recycler)
|
binding.swipeRefresh.addView(recycler)
|
||||||
adapter.fastScroller = fast_scroller
|
adapter.fastScroller = binding.fastScroller
|
||||||
|
|
||||||
recycler.scrollStateChanges()
|
recycler.scrollStateChanges()
|
||||||
.onEach {
|
.onEach {
|
||||||
// Disable swipe refresh when view is not at the top
|
// Disable swipe refresh when view is not at the top
|
||||||
val firstPos = (recycler.layoutManager as LinearLayoutManager)
|
val firstPos = (recycler.layoutManager as LinearLayoutManager)
|
||||||
.findFirstCompletelyVisibleItemPosition()
|
.findFirstCompletelyVisibleItemPosition()
|
||||||
swipe_refresh.isEnabled = firstPos <= 0
|
binding.swipeRefresh.isEnabled = firstPos <= 0
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(scope)
|
||||||
|
|
||||||
// Double the distance required to trigger sync
|
// Double the distance required to trigger sync
|
||||||
swipe_refresh.setDistanceToTriggerSync((2 * 64 * resources.displayMetrics.density).toInt())
|
binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * resources.displayMetrics.density).toInt())
|
||||||
swipe_refresh.refreshes()
|
binding.swipeRefresh.refreshes()
|
||||||
.onEach {
|
.onEach {
|
||||||
if (LibraryUpdateService.start(context, category)) {
|
if (LibraryUpdateService.start(context, category)) {
|
||||||
context.toast(R.string.updating_category)
|
context.toast(R.string.updating_category)
|
||||||
}
|
}
|
||||||
|
|
||||||
// It can be a very long operation, so we disable swipe refresh and show a toast.
|
// It can be a very long operation, so we disable swipe refresh and show a toast.
|
||||||
swipe_refresh.isRefreshing = false
|
binding.swipeRefresh.isRefreshing = false
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(scope)
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ class LibraryController(
|
|||||||
if (preferences.categoryTabs().get()) {
|
if (preferences.categoryTabs().get()) {
|
||||||
currentTitle = resources?.getString(R.string.label_library)
|
currentTitle = resources?.getString(R.string.label_library)
|
||||||
} else {
|
} else {
|
||||||
adapter?.categories?.get(binding.libraryPager.currentItem)?.let {
|
adapter?.categories?.getOrNull(binding.libraryPager.currentItem)?.let {
|
||||||
currentTitle = it.name
|
currentTitle = it.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -923,7 +923,7 @@ class MangaController :
|
|||||||
private fun markPreviousAsRead(chapters: List<ChapterItem>) {
|
private fun markPreviousAsRead(chapters: List<ChapterItem>) {
|
||||||
val adapter = chaptersAdapter ?: return
|
val adapter = chaptersAdapter ?: return
|
||||||
val prevChapters = if (presenter.sortDescending()) adapter.items.reversed() else adapter.items
|
val prevChapters = if (presenter.sortDescending()) adapter.items.reversed() else adapter.items
|
||||||
val chapterPos = prevChapters.indexOf(chapters.last())
|
val chapterPos = prevChapters.indexOf(chapters.lastOrNull())
|
||||||
if (chapterPos != -1) {
|
if (chapterPos != -1) {
|
||||||
markAsRead(prevChapters.take(chapterPos))
|
markAsRead(prevChapters.take(chapterPos))
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,6 @@ import java.util.TimeZone
|
|||||||
|
|
||||||
class AboutController : SettingsController() {
|
class AboutController : SettingsController() {
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks for new releases
|
|
||||||
*/
|
|
||||||
private val updateChecker by lazy { GithubUpdateChecker() }
|
private val updateChecker by lazy { GithubUpdateChecker() }
|
||||||
|
|
||||||
private val dateFormat: DateFormat = preferences.dateFormat()
|
private val dateFormat: DateFormat = preferences.dateFormat()
|
||||||
|
@ -20,7 +20,7 @@ class DirectoryPageLoader(val file: File) : PageLoader() {
|
|||||||
override fun getPages(): Observable<List<ReaderPage>> {
|
override fun getPages(): Observable<List<ReaderPage>> {
|
||||||
return file.listFiles()
|
return file.listFiles()
|
||||||
.filter { !it.isDirectory && ImageUtil.isImage(it.name) { FileInputStream(it) } }
|
.filter { !it.isDirectory && ImageUtil.isImage(it.name) { FileInputStream(it) } }
|
||||||
.sortedWith(Comparator<File> { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) })
|
.sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }
|
||||||
.mapIndexed { i, file ->
|
.mapIndexed { i, file ->
|
||||||
val streamFn = { FileInputStream(file) }
|
val streamFn = { FileInputStream(file) }
|
||||||
ReaderPage(i).apply {
|
ReaderPage(i).apply {
|
||||||
|
@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.util.system.ImageUtil
|
|||||||
import rx.Observable
|
import rx.Observable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.util.zip.ZipEntry
|
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +39,7 @@ class ZipPageLoader(file: File) : PageLoader() {
|
|||||||
override fun getPages(): Observable<List<ReaderPage>> {
|
override fun getPages(): Observable<List<ReaderPage>> {
|
||||||
return zip.entries().toList()
|
return zip.entries().toList()
|
||||||
.filter { !it.isDirectory && ImageUtil.isImage(it.name) { zip.getInputStream(it) } }
|
.filter { !it.isDirectory && ImageUtil.isImage(it.name) { zip.getInputStream(it) } }
|
||||||
.sortedWith(Comparator<ZipEntry> { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) })
|
.sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }
|
||||||
.mapIndexed { i, entry ->
|
.mapIndexed { i, entry ->
|
||||||
val streamFn = { zip.getInputStream(entry) }
|
val streamFn = { zip.getInputStream(entry) }
|
||||||
ReaderPage(i).apply {
|
ReaderPage(i).apply {
|
||||||
|
@ -185,7 +185,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
|
|||||||
* activity of the change and requests the preload of the next chapter if this is the last page.
|
* activity of the change and requests the preload of the next chapter if this is the last page.
|
||||||
*/
|
*/
|
||||||
private fun onReaderPageSelected(page: ReaderPage, allowPreload: Boolean) {
|
private fun onReaderPageSelected(page: ReaderPage, allowPreload: Boolean) {
|
||||||
val pages = page.chapter.pages!! // Won't be null because it's the loaded chapter
|
val pages = page.chapter.pages ?: return
|
||||||
Timber.d("onReaderPageSelected: ${page.number}/${pages.size}")
|
Timber.d("onReaderPageSelected: ${page.number}/${pages.size}")
|
||||||
activity.onPageSelected(page)
|
activity.onPageSelected(page)
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
|
|||||||
* activity of the change and requests the preload of the next chapter if this is the last page.
|
* activity of the change and requests the preload of the next chapter if this is the last page.
|
||||||
*/
|
*/
|
||||||
private fun onPageSelected(page: ReaderPage, allowPreload: Boolean) {
|
private fun onPageSelected(page: ReaderPage, allowPreload: Boolean) {
|
||||||
val pages = page.chapter.pages!! // Won't be null because it's the loaded chapter
|
val pages = page.chapter.pages ?: return
|
||||||
Timber.d("onPageSelected: ${page.number}/${pages.size}")
|
Timber.d("onPageSelected: ${page.number}/${pages.size}")
|
||||||
activity.onPageSelected(page)
|
activity.onPageSelected(page)
|
||||||
|
|
||||||
@ -293,11 +293,11 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
|
|||||||
}
|
}
|
||||||
KeyEvent.KEYCODE_MENU -> if (isUp) activity.toggleMenu()
|
KeyEvent.KEYCODE_MENU -> if (isUp) activity.toggleMenu()
|
||||||
|
|
||||||
KeyEvent.KEYCODE_DPAD_RIGHT,
|
KeyEvent.KEYCODE_DPAD_LEFT,
|
||||||
KeyEvent.KEYCODE_DPAD_UP,
|
KeyEvent.KEYCODE_DPAD_UP,
|
||||||
KeyEvent.KEYCODE_PAGE_UP -> if (isUp) scrollUp()
|
KeyEvent.KEYCODE_PAGE_UP -> if (isUp) scrollUp()
|
||||||
|
|
||||||
KeyEvent.KEYCODE_DPAD_LEFT,
|
KeyEvent.KEYCODE_DPAD_RIGHT,
|
||||||
KeyEvent.KEYCODE_DPAD_DOWN,
|
KeyEvent.KEYCODE_DPAD_DOWN,
|
||||||
KeyEvent.KEYCODE_PAGE_DOWN -> if (isUp) scrollDown()
|
KeyEvent.KEYCODE_PAGE_DOWN -> if (isUp) scrollDown()
|
||||||
else -> return false
|
else -> return false
|
||||||
|
@ -2,26 +2,26 @@ package eu.kanade.tachiyomi.ui.recent
|
|||||||
|
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.databinding.RecentSectionItemBinding
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
class DateSectionItem(val date: Date) : AbstractHeaderItem<DateSectionItem.Holder>() {
|
class DateSectionItem(val date: Date) : AbstractHeaderItem<DateSectionItem.DateSectionItemHolder>() {
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return R.layout.recent_section_item
|
return R.layout.recent_section_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): DateSectionItemHolder {
|
||||||
return Holder(view, adapter)
|
return DateSectionItemHolder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: DateSectionItemHolder, position: Int, payloads: List<Any?>?) {
|
||||||
holder.bind(this)
|
holder.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,14 +37,14 @@ class DateSectionItem(val date: Date) : AbstractHeaderItem<DateSectionItem.Holde
|
|||||||
return date.hashCode()
|
return date.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
class Holder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter, true) {
|
inner class DateSectionItemHolder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter, true) {
|
||||||
|
|
||||||
|
private val binding = RecentSectionItemBinding.bind(view)
|
||||||
|
|
||||||
private val now = Date().time
|
private val now = Date().time
|
||||||
|
|
||||||
val section_text: TextView = view.findViewById(R.id.section_text)
|
|
||||||
|
|
||||||
fun bind(item: DateSectionItem) {
|
fun bind(item: DateSectionItem) {
|
||||||
section_text.text = DateUtils.getRelativeTimeSpanString(item.date.time, now, DateUtils.DAY_IN_MILLIS)
|
binding.sectionText.text = DateUtils.getRelativeTimeSpanString(item.date.time, now, DateUtils.DAY_IN_MILLIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
switchPreference {
|
switchPreference {
|
||||||
key = Keys.enableDoh
|
key = Keys.enableDoh
|
||||||
titleRes = R.string.pref_dns_over_https
|
titleRes = R.string.pref_dns_over_https
|
||||||
summaryRes = R.string.pref_dns_over_https_summary
|
summaryRes = R.string.requires_app_restart
|
||||||
defaultValue = false
|
defaultValue = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,6 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
|||||||
import eu.kanade.tachiyomi.util.preference.summaryRes
|
import eu.kanade.tachiyomi.util.preference.summaryRes
|
||||||
import eu.kanade.tachiyomi.util.preference.switchPreference
|
import eu.kanade.tachiyomi.util.preference.switchPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.titleRes
|
import eu.kanade.tachiyomi.util.preference.titleRes
|
||||||
import eu.kanade.tachiyomi.util.system.getFilePicker
|
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@ -125,13 +124,11 @@ class SettingsBackupController : SettingsController() {
|
|||||||
titleRes = R.string.pref_backup_directory
|
titleRes = R.string.pref_backup_directory
|
||||||
|
|
||||||
onClick {
|
onClick {
|
||||||
val currentDir = preferences.backupsDirectory().get()
|
|
||||||
try {
|
try {
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||||
startActivityForResult(intent, CODE_BACKUP_DIR)
|
startActivityForResult(intent, CODE_BACKUP_DIR)
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
// Fall back to custom picker on error
|
activity?.toast(R.string.file_picker_error)
|
||||||
startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_DIR)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +202,7 @@ class SettingsBackupController : SettingsController() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
CODE_BACKUP_RESTORE -> {
|
CODE_BACKUP_RESTORE -> {
|
||||||
uri?.path?.let { path ->
|
uri?.path?.let {
|
||||||
val fileName = DocumentFile.fromSingleUri(activity, uri)!!.name!!
|
val fileName = DocumentFile.fromSingleUri(activity, uri)!!.name!!
|
||||||
when {
|
when {
|
||||||
fileName.endsWith(".proto.gz") -> {
|
fileName.endsWith(".proto.gz") -> {
|
||||||
@ -258,7 +255,6 @@ class SettingsBackupController : SettingsController() {
|
|||||||
|
|
||||||
fun createBackup(flags: Int, type: Int) {
|
fun createBackup(flags: Int, type: Int) {
|
||||||
backupFlags = flags
|
backupFlags = flags
|
||||||
val currentDir = preferences.backupsDirectory().get()
|
|
||||||
val code = when (type) {
|
val code = when (type) {
|
||||||
BackupConst.BACKUP_TYPE_FULL -> CODE_FULL_BACKUP_CREATE
|
BackupConst.BACKUP_TYPE_FULL -> CODE_FULL_BACKUP_CREATE
|
||||||
else -> CODE_LEGACY_BACKUP_CREATE
|
else -> CODE_LEGACY_BACKUP_CREATE
|
||||||
@ -277,8 +273,7 @@ class SettingsBackupController : SettingsController() {
|
|||||||
|
|
||||||
startActivityForResult(intent, code)
|
startActivityForResult(intent, code)
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
// Handle errors where the Android ROM doesn't support the built in picker
|
activity?.toast(R.string.file_picker_error)
|
||||||
startActivityForResult(preferences.context.getFilePicker(currentDir), code)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,16 @@ package eu.kanade.tachiyomi.ui.setting
|
|||||||
|
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
||||||
import eu.kanade.tachiyomi.util.preference.defaultValue
|
import eu.kanade.tachiyomi.util.preference.defaultValue
|
||||||
|
import eu.kanade.tachiyomi.util.preference.infoPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.onChange
|
import eu.kanade.tachiyomi.util.preference.onChange
|
||||||
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
||||||
|
import eu.kanade.tachiyomi.util.preference.summaryRes
|
||||||
import eu.kanade.tachiyomi.util.preference.switchPreference
|
import eu.kanade.tachiyomi.util.preference.switchPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.titleRes
|
import eu.kanade.tachiyomi.util.preference.titleRes
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||||
|
|
||||||
class SettingsBrowseController : SettingsController() {
|
class SettingsBrowseController : SettingsController() {
|
||||||
@ -41,27 +45,29 @@ class SettingsBrowseController : SettingsController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// preferenceCategory {
|
preferenceCategory {
|
||||||
// titleRes = R.string.pref_category_nsfw_content
|
titleRes = R.string.pref_category_nsfw_content
|
||||||
//
|
|
||||||
// listPreference {
|
switchPreference {
|
||||||
// key = Keys.allowNsfwSource
|
key = Keys.showNsfwSource
|
||||||
// titleRes = R.string.pref_allow_nsfw_sources
|
titleRes = R.string.pref_show_nsfw_source
|
||||||
// entriesRes = arrayOf(
|
summaryRes = R.string.requires_app_restart
|
||||||
// R.string.pref_allow_nsfw_sources_allowed,
|
defaultValue = true
|
||||||
// R.string.pref_allow_nsfw_sources_allowed_multisource,
|
}
|
||||||
// R.string.pref_allow_nsfw_sources_blocked
|
switchPreference {
|
||||||
// )
|
key = Keys.showNsfwExtension
|
||||||
// entryValues = arrayOf(
|
titleRes = R.string.pref_show_nsfw_extension
|
||||||
// PreferenceValues.NsfwAllowance.ALLOWED.name,
|
defaultValue = true
|
||||||
// PreferenceValues.NsfwAllowance.PARTIAL.name,
|
}
|
||||||
// PreferenceValues.NsfwAllowance.BLOCKED.name
|
switchPreference {
|
||||||
// )
|
key = Keys.labelNsfwExtension
|
||||||
// defaultValue = PreferenceValues.NsfwAllowance.ALLOWED.name
|
titleRes = R.string.pref_label_nsfw_extension
|
||||||
// summary = "%s"
|
defaultValue = true
|
||||||
// }
|
|
||||||
//
|
preferences.showNsfwExtension().asImmediateFlow { isVisible = it }.launchIn(scope)
|
||||||
// infoPreference(R.string.parental_controls_info)
|
}
|
||||||
// }
|
|
||||||
|
infoPreference(R.string.parental_controls_info)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import eu.kanade.tachiyomi.util.preference.preference
|
|||||||
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
||||||
import eu.kanade.tachiyomi.util.preference.switchPreference
|
import eu.kanade.tachiyomi.util.preference.switchPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.titleRes
|
import eu.kanade.tachiyomi.util.preference.titleRes
|
||||||
import eu.kanade.tachiyomi.util.system.getFilePicker
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -155,12 +155,12 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
preferences.downloadsDirectory().set(path.toString())
|
preferences.downloadsDirectory().set(path.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun customDirectorySelected(currentDir: String) {
|
fun customDirectorySelected() {
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||||
try {
|
try {
|
||||||
startActivityForResult(intent, DOWNLOAD_DIR)
|
startActivityForResult(intent, DOWNLOAD_DIR)
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
startActivityForResult(preferences.context.getFilePicker(currentDir), DOWNLOAD_DIR)
|
activity?.toast(R.string.file_picker_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
) { _, position, text ->
|
) { _, position, text ->
|
||||||
val target = targetController as? SettingsDownloadController
|
val target = targetController as? SettingsDownloadController
|
||||||
if (position == externalDirs.lastIndex) {
|
if (position == externalDirs.lastIndex) {
|
||||||
target?.customDirectorySelected(currentDir)
|
target?.customDirectorySelected()
|
||||||
} else {
|
} else {
|
||||||
target?.predefinedDirectorySelected(text.toString())
|
target?.predefinedDirectorySelected(text.toString())
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ object SettingsSearchHelper {
|
|||||||
(pref.title != null) -> {
|
(pref.title != null) -> {
|
||||||
// Is an actual preference
|
// Is an actual preference
|
||||||
val title = pref.title.toString()
|
val title = pref.title.toString()
|
||||||
val summary = if (pref.summary != null) pref.summary.toString() else ""
|
val summary = pref.summary?.toString() ?: ""
|
||||||
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
|
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
|
||||||
|
|
||||||
prefSearchResultList.add(
|
prefSearchResultList.add(
|
||||||
|
@ -31,15 +31,17 @@ open class BaseWebViewActivity : BaseActivity<WebviewActivityBinding>() {
|
|||||||
if (!WebViewUtil.supportsWebView(this)) {
|
if (!WebViewUtil.supportsWebView(this)) {
|
||||||
toast(R.string.information_webview_required, Toast.LENGTH_LONG)
|
toast(R.string.information_webview_required, Toast.LENGTH_LONG)
|
||||||
finish()
|
finish()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
binding = WebviewActivityBinding.inflate(layoutInflater)
|
binding = WebviewActivityBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
} catch (e: Exception) {
|
} catch (e: Throwable) {
|
||||||
// Potentially throws errors like "Error inflating class android.webkit.WebView"
|
// Potentially throws errors like "Error inflating class android.webkit.WebView"
|
||||||
toast(R.string.information_webview_required, Toast.LENGTH_LONG)
|
toast(R.string.information_webview_required, Toast.LENGTH_LONG)
|
||||||
finish()
|
finish()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
title = intent.extras?.getString(TITLE_KEY)
|
title = intent.extras?.getString(TITLE_KEY)
|
||||||
|
@ -29,10 +29,8 @@ import androidx.core.graphics.green
|
|||||||
import androidx.core.graphics.red
|
import androidx.core.graphics.red
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
import com.nononsenseapps.filepicker.FilePickerActivity
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.lang.truncateCenter
|
import eu.kanade.tachiyomi.util.lang.truncateCenter
|
||||||
import eu.kanade.tachiyomi.widget.CustomLayoutPickerActivity
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,19 +96,6 @@ fun Context.notification(channelId: String, block: (NotificationCompat.Builder.(
|
|||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to construct an Intent to use a custom file picker.
|
|
||||||
* @param currentDir the path the file picker will open with.
|
|
||||||
* @return an Intent to start the file picker activity.
|
|
||||||
*/
|
|
||||||
fun Context.getFilePicker(currentDir: String): Intent {
|
|
||||||
return Intent(this, CustomLayoutPickerActivity::class.java)
|
|
||||||
.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false)
|
|
||||||
.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, true)
|
|
||||||
.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_DIR)
|
|
||||||
.putExtra(FilePickerActivity.EXTRA_START_PATH, currentDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the give permission is granted.
|
* Checks if the give permission is granted.
|
||||||
*
|
*
|
||||||
|
@ -13,7 +13,7 @@ object WebViewUtil {
|
|||||||
|
|
||||||
const val REQUESTED_WITH = "com.android.browser"
|
const val REQUESTED_WITH = "com.android.browser"
|
||||||
|
|
||||||
const val MINIMUM_WEBVIEW_VERSION = 84
|
const val MINIMUM_WEBVIEW_VERSION = 86
|
||||||
|
|
||||||
fun supportsWebView(context: Context): Boolean {
|
fun supportsWebView(context: Context): Boolean {
|
||||||
try {
|
try {
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.widget
|
|
||||||
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.nononsenseapps.filepicker.AbstractFilePickerFragment
|
|
||||||
import com.nononsenseapps.filepicker.FilePickerActivity
|
|
||||||
import com.nononsenseapps.filepicker.FilePickerFragment
|
|
||||||
import com.nononsenseapps.filepicker.LogicHandler
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.util.view.inflate
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class CustomLayoutPickerActivity : FilePickerActivity() {
|
|
||||||
|
|
||||||
override fun getFragment(startPath: String?, mode: Int, allowMultiple: Boolean, allowCreateDir: Boolean):
|
|
||||||
AbstractFilePickerFragment<File> {
|
|
||||||
val fragment = CustomLayoutFilePickerFragment()
|
|
||||||
fragment.setArgs(startPath, mode, allowMultiple, allowCreateDir)
|
|
||||||
return fragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CustomLayoutFilePickerFragment : FilePickerFragment() {
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
|
||||||
return when (viewType) {
|
|
||||||
LogicHandler.VIEWTYPE_DIR -> {
|
|
||||||
val view = parent.inflate(R.layout.common_listitem_dir)
|
|
||||||
DirViewHolder(view)
|
|
||||||
}
|
|
||||||
else -> super.onCreateViewHolder(parent, viewType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
9
app/src/main/res/drawable/ic_folder_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_folder_24dp.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z" />
|
||||||
|
</vector>
|
@ -1,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/nnf_item_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?android:listPreferredItemHeight"
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
android:focusable="true"
|
|
||||||
android:minHeight="?android:listPreferredItemHeight"
|
|
||||||
android:nextFocusLeft="@+id/nnf_button_cancel"
|
|
||||||
android:nextFocusRight="@+id/nnf_button_ok"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/item_icon"
|
|
||||||
android:layout_width="?android:listPreferredItemHeight"
|
|
||||||
android:layout_height="?android:listPreferredItemHeight"
|
|
||||||
android:adjustViewBounds="true"
|
|
||||||
android:scaleType="center"
|
|
||||||
android:src="@drawable/nnf_ic_file_folder"
|
|
||||||
android:visibility="visible"
|
|
||||||
app:tint="?attr/colorAccent"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@android:id/text1"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="@string/nnf_name" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@ -601,7 +601,7 @@
|
|||||||
<string name="action_start">ابدأ</string>
|
<string name="action_start">ابدأ</string>
|
||||||
<string name="action_sort_date_added">تاريخ الاضافة</string>
|
<string name="action_sort_date_added">تاريخ الاضافة</string>
|
||||||
<string name="whats_new">ما الجديد</string>
|
<string name="whats_new">ما الجديد</string>
|
||||||
<string name="pref_dns_over_https_summary">يتطلب إعادة تشغيل التطبيق ليتم تفعيله</string>
|
<string name="requires_app_restart">يتطلب إعادة تشغيل التطبيق ليتم تفعيله</string>
|
||||||
<string name="label_network">شبكة الاتصال</string>
|
<string name="label_network">شبكة الاتصال</string>
|
||||||
<string name="backup_restore_missing_trackers">أجهزة التتبع التي لم يتم تسجيل الدخول إليها:</string>
|
<string name="backup_restore_missing_trackers">أجهزة التتبع التي لم يتم تسجيل الدخول إليها:</string>
|
||||||
<string name="pref_remove_bookmarked_chapters">حذف الفصول ذات العلامة المرجعية</string>
|
<string name="pref_remove_bookmarked_chapters">حذف الفصول ذات العلامة المرجعية</string>
|
||||||
|
@ -375,7 +375,7 @@
|
|||||||
<string name="pref_clear_chapter_cache">Borrar caché de los capítulos</string>
|
<string name="pref_clear_chapter_cache">Borrar caché de los capítulos</string>
|
||||||
<string name="label_data">Datos</string>
|
<string name="label_data">Datos</string>
|
||||||
<string name="cookies_cleared">Cookies borradas</string>
|
<string name="cookies_cleared">Cookies borradas</string>
|
||||||
<string name="pref_dns_over_https_summary">Requiere el reinicio de la aplicación para que surta efecto</string>
|
<string name="requires_app_restart">Requiere el reinicio de la aplicación para que surta efecto</string>
|
||||||
<string name="battery_optimization_disabled">La optimización de la batería ya está desactivada</string>
|
<string name="battery_optimization_disabled">La optimización de la batería ya está desactivada</string>
|
||||||
<string name="pref_disable_battery_optimization_summary">Ayuda con las actualizaciones y las copias de seguridad de biblioteca en segundo plano</string>
|
<string name="pref_disable_battery_optimization_summary">Ayuda con las actualizaciones y las copias de seguridad de biblioteca en segundo plano</string>
|
||||||
<string name="pref_disable_battery_optimization">Desactivar optimización de batería</string>
|
<string name="pref_disable_battery_optimization">Desactivar optimización de batería</string>
|
||||||
|
@ -581,7 +581,7 @@
|
|||||||
<string name="tabs_header">Раздели</string>
|
<string name="tabs_header">Раздели</string>
|
||||||
<string name="badges_header">Значки</string>
|
<string name="badges_header">Значки</string>
|
||||||
<string name="label_data">Данни</string>
|
<string name="label_data">Данни</string>
|
||||||
<string name="pref_dns_over_https_summary">Изисква рестартиране на приложението, за да влезе в сила</string>
|
<string name="requires_app_restart">Изисква рестартиране на приложението, за да влезе в сила</string>
|
||||||
<string name="label_network">Мрежа</string>
|
<string name="label_network">Мрежа</string>
|
||||||
<string name="backup_restore_missing_sources">Липсващи източници:</string>
|
<string name="backup_restore_missing_sources">Липсващи източници:</string>
|
||||||
<string name="invalid_backup_file_missing_manga">Резервното копие не съдържа манга.</string>
|
<string name="invalid_backup_file_missing_manga">Резервното копие не съдържа манга.</string>
|
||||||
|
@ -464,7 +464,7 @@
|
|||||||
<string name="set_chapter_settings_as_default">প্রকৃত হিসেবে সংরক্ষণ করুন</string>
|
<string name="set_chapter_settings_as_default">প্রকৃত হিসেবে সংরক্ষণ করুন</string>
|
||||||
<string name="confirm_set_chapter_settings">আপনি কি নিশ্চিত সেটিংসগুলো প্রকৃত হিসেবে সংরক্ষণ করবেন\?</string>
|
<string name="confirm_set_chapter_settings">আপনি কি নিশ্চিত সেটিংসগুলো প্রকৃত হিসেবে সংরক্ষণ করবেন\?</string>
|
||||||
<string name="label_data">তথ্য</string>
|
<string name="label_data">তথ্য</string>
|
||||||
<string name="pref_dns_over_https_summary">কার্যকর করতে অ্যাপ পুনরারম্ভ করতে হবে</string>
|
<string name="requires_app_restart">কার্যকর করতে অ্যাপ পুনরারম্ভ করতে হবে</string>
|
||||||
<string name="label_network">নেটওয়ার্ক</string>
|
<string name="label_network">নেটওয়ার্ক</string>
|
||||||
<string name="restoring_backup_canceled">পুনরুদ্ধার বাতিল করা হয়েছে</string>
|
<string name="restoring_backup_canceled">পুনরুদ্ধার বাতিল করা হয়েছে</string>
|
||||||
<string name="restoring_backup_error">ব্যাকআপ পুনরুদ্ধার ব্যর্থ হয়েছে</string>
|
<string name="restoring_backup_error">ব্যাকআপ পুনরুদ্ধার ব্যর্থ হয়েছে</string>
|
||||||
|
@ -573,7 +573,7 @@
|
|||||||
<string name="action_global_search_query">Cerca \"%1$s\" globalment</string>
|
<string name="action_global_search_query">Cerca \"%1$s\" globalment</string>
|
||||||
<string name="updated_version">S\'ha actualitzat a la v%1$s</string>
|
<string name="updated_version">S\'ha actualitzat a la v%1$s</string>
|
||||||
<string name="whats_new">Novetats</string>
|
<string name="whats_new">Novetats</string>
|
||||||
<string name="pref_dns_over_https_summary">Cal reiniciar l\'aplicació perquè s\'apliqui</string>
|
<string name="requires_app_restart">Cal reiniciar l\'aplicació perquè s\'apliqui</string>
|
||||||
<string name="label_network">Xarxa</string>
|
<string name="label_network">Xarxa</string>
|
||||||
<string name="pref_category_reading_mode">Mode de lectura</string>
|
<string name="pref_category_reading_mode">Mode de lectura</string>
|
||||||
<string name="pref_show_reading_mode_summary">Mostra breument el mode actual en obrir el lector</string>
|
<string name="pref_show_reading_mode_summary">Mostra breument el mode actual en obrir el lector</string>
|
||||||
|
@ -558,7 +558,7 @@
|
|||||||
<string name="cache_deleted">Кеша тастнӑ. %1$d файла катертнӗ</string>
|
<string name="cache_deleted">Кеша тастнӑ. %1$d файла катертнӗ</string>
|
||||||
<string name="pref_clear_chapter_cache">Сыпӑксен кешне тасат</string>
|
<string name="pref_clear_chapter_cache">Сыпӑксен кешне тасат</string>
|
||||||
<string name="label_data">Пӗлӗмсем</string>
|
<string name="label_data">Пӗлӗмсем</string>
|
||||||
<string name="pref_dns_over_https_summary">Вӑя кӗрес тесен хушӑма сӳнтерсе ҫутмалла</string>
|
<string name="requires_app_restart">Вӑя кӗрес тесен хушӑма сӳнтерсе ҫутмалла</string>
|
||||||
<string name="restoring_backup_canceled">Тавӑрнине пӑрахӑҫланӑ</string>
|
<string name="restoring_backup_canceled">Тавӑрнине пӑрахӑҫланӑ</string>
|
||||||
<string name="restoring_backup_error">Янтӑв тавӑрни йӑнӑшӗ</string>
|
<string name="restoring_backup_error">Янтӑв тавӑрни йӑнӑшӗ</string>
|
||||||
<string name="restoring_backup">Янтӑв тавӑрни</string>
|
<string name="restoring_backup">Янтӑв тавӑрни</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
<item quantity="other">%1$s Kapitel</item>
|
<item quantity="other">%1$s Kapitel</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_open_in_settings">In den Einstellungen öffnen</string>
|
<string name="action_open_in_settings">In den Einstellungen öffnen</string>
|
||||||
<string name="pref_dns_over_https_summary">App muss neu gestartet werden, um die Einstellung zu übernehmen</string>
|
<string name="requires_app_restart">App muss neu gestartet werden, um die Einstellung zu übernehmen</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS über HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS über HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Netzwerk</string>
|
<string name="label_network">Netzwerk</string>
|
||||||
<string name="pref_jump_to_chapters">Beim Öffnen zu den Kapiteln springen</string>
|
<string name="pref_jump_to_chapters">Beim Öffnen zu den Kapiteln springen</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
<item quantity="other">%1$s κεφάλαια</item>
|
<item quantity="other">%1$s κεφάλαια</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_open_in_settings">Άνοιγμα στις Ρυθμίσεις</string>
|
<string name="action_open_in_settings">Άνοιγμα στις Ρυθμίσεις</string>
|
||||||
<string name="pref_dns_over_https_summary">Απαιτείται επανεκκίνηση της εφαρμογής για να τεθεί σε ισχύ</string>
|
<string name="requires_app_restart">Απαιτείται επανεκκίνηση της εφαρμογής για να τεθεί σε ισχύ</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS μέσω HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS μέσω HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Δίκτυο</string>
|
<string name="label_network">Δίκτυο</string>
|
||||||
<string name="pref_jump_to_chapters">Μετάβαση στα κεφάλαια κατά το άνοιγμα</string>
|
<string name="pref_jump_to_chapters">Μετάβαση στα κεφάλαια κατά το άνοιγμα</string>
|
||||||
|
@ -599,7 +599,7 @@
|
|||||||
<string name="action_sort_descending">Descendente</string>
|
<string name="action_sort_descending">Descendente</string>
|
||||||
<string name="action_disable">Desactivar</string>
|
<string name="action_disable">Desactivar</string>
|
||||||
<string name="action_open_in_settings">Abrir en Configuración</string>
|
<string name="action_open_in_settings">Abrir en Configuración</string>
|
||||||
<string name="pref_dns_over_https_summary">Requiere el reinicio de la aplicación para que surta efecto</string>
|
<string name="requires_app_restart">Requiere el reinicio de la aplicación para que surta efecto</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS sobre HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS sobre HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Red</string>
|
<string name="label_network">Red</string>
|
||||||
<string name="pref_jump_to_chapters">Saltar a los capítulos abiertos</string>
|
<string name="pref_jump_to_chapters">Saltar a los capítulos abiertos</string>
|
||||||
|
@ -581,7 +581,7 @@
|
|||||||
<string name="no_pinned_sources">شما هیچ منبع پینشدهای ندارید</string>
|
<string name="no_pinned_sources">شما هیچ منبع پینشدهای ندارید</string>
|
||||||
<string name="action_global_search_query">«%1$s» در همه منابع جستجو شود</string>
|
<string name="action_global_search_query">«%1$s» در همه منابع جستجو شود</string>
|
||||||
<string name="whats_new">اخبار</string>
|
<string name="whats_new">اخبار</string>
|
||||||
<string name="pref_dns_over_https_summary">برای اعمال تغییرات برنامه نیاز به راه اندازی مجدد دارد</string>
|
<string name="requires_app_restart">برای اعمال تغییرات برنامه نیاز به راه اندازی مجدد دارد</string>
|
||||||
<string name="label_network">شبکه</string>
|
<string name="label_network">شبکه</string>
|
||||||
<string name="backup_restore_missing_trackers">ردیابیهایی که به سیستم وارد نشده اند:</string>
|
<string name="backup_restore_missing_trackers">ردیابیهایی که به سیستم وارد نشده اند:</string>
|
||||||
<string name="pref_category_reading_mode">حالت خواندن</string>
|
<string name="pref_category_reading_mode">حالت خواندن</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
<item quantity="other">%1$s lukua</item>
|
<item quantity="other">%1$s lukua</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_open_in_settings">Avaa Asetuksissa</string>
|
<string name="action_open_in_settings">Avaa Asetuksissa</string>
|
||||||
<string name="pref_dns_over_https_summary">Edellyttää sovelluksen käynnistämistä uudelleen</string>
|
<string name="requires_app_restart">Edellyttää sovelluksen käynnistämistä uudelleen</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS HTTPS:n kautta (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS HTTPS:n kautta (Cloudflare)</string>
|
||||||
<string name="label_network">Verkko</string>
|
<string name="label_network">Verkko</string>
|
||||||
<string name="pref_jump_to_chapters">Siirry lukuihin avatessa</string>
|
<string name="pref_jump_to_chapters">Siirry lukuihin avatessa</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
<string name="pref_clear_chapter_cache">Linisin ang cache ng kabanata</string>
|
<string name="pref_clear_chapter_cache">Linisin ang cache ng kabanata</string>
|
||||||
<string name="label_data">Data</string>
|
<string name="label_data">Data</string>
|
||||||
<string name="cookies_cleared">Nalinis na ang mga cookie</string>
|
<string name="cookies_cleared">Nalinis na ang mga cookie</string>
|
||||||
<string name="pref_dns_over_https_summary">Nangangailangang buksan muli ang app para gumana</string>
|
<string name="requires_app_restart">Nangangailangang buksan muli ang app para gumana</string>
|
||||||
<string name="pref_clear_cookies">Linisin ang mga cookie</string>
|
<string name="pref_clear_cookies">Linisin ang mga cookie</string>
|
||||||
<string name="label_network">Network</string>
|
<string name="label_network">Network</string>
|
||||||
<string name="restoring_backup_error">Pumalya sa pagbalik sa backup</string>
|
<string name="restoring_backup_error">Pumalya sa pagbalik sa backup</string>
|
||||||
|
@ -602,7 +602,7 @@
|
|||||||
<string name="action_sort_descending">Décroissant</string>
|
<string name="action_sort_descending">Décroissant</string>
|
||||||
<string name="action_disable">Désactiver</string>
|
<string name="action_disable">Désactiver</string>
|
||||||
<string name="action_open_in_settings">Ouvrir dans les paramètres</string>
|
<string name="action_open_in_settings">Ouvrir dans les paramètres</string>
|
||||||
<string name="pref_dns_over_https_summary">Nécessite un redémarrage de l\'application pour prendre effet</string>
|
<string name="requires_app_restart">Nécessite un redémarrage de l\'application pour prendre effet</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS sur HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS sur HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Réseau</string>
|
<string name="label_network">Réseau</string>
|
||||||
<string name="tapping_inverted_both">Les deux</string>
|
<string name="tapping_inverted_both">Les deux</string>
|
||||||
|
@ -578,7 +578,7 @@
|
|||||||
<string name="pref_read_with_tapping_inverted">उलटा दोहन</string>
|
<string name="pref_read_with_tapping_inverted">उलटा दोहन</string>
|
||||||
<string name="unknown_status">अज्ञात स्थिति</string>
|
<string name="unknown_status">अज्ञात स्थिति</string>
|
||||||
<string name="unknown_author">अज्ञात लेखक</string>
|
<string name="unknown_author">अज्ञात लेखक</string>
|
||||||
<string name="pref_dns_over_https_summary">प्रभावी होने के लिए ऐप पुनः आरंभ करने की आवश्यकता है</string>
|
<string name="requires_app_restart">प्रभावी होने के लिए ऐप पुनः आरंभ करने की आवश्यकता है</string>
|
||||||
<string name="action_download_unread">अपठित अध्याय डाउनलोड करें</string>
|
<string name="action_download_unread">अपठित अध्याय डाउनलोड करें</string>
|
||||||
<string name="whats_new">नया क्या है</string>
|
<string name="whats_new">नया क्या है</string>
|
||||||
<string name="download_insufficient_space">कम डिस्क स्पेस के कारण अध्याय डाउनलोड नहीं कर सका</string>
|
<string name="download_insufficient_space">कम डिस्क स्पेस के कारण अध्याय डाउनलोड नहीं कर सका</string>
|
||||||
|
@ -578,7 +578,7 @@
|
|||||||
<item quantity="few">%1$s poglavlja</item>
|
<item quantity="few">%1$s poglavlja</item>
|
||||||
<item quantity="other">%1$s poglavlja</item>
|
<item quantity="other">%1$s poglavlja</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_dns_over_https_summary">Za preuzimanje postavke, ponovo pokreni program</string>
|
<string name="requires_app_restart">Za preuzimanje postavke, ponovo pokreni program</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS preko HTTPS-a (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS preko HTTPS-a (Cloudflare)</string>
|
||||||
<string name="label_network">Mreža</string>
|
<string name="label_network">Mreža</string>
|
||||||
<string name="tapping_inverted_both">Oboje</string>
|
<string name="tapping_inverted_both">Oboje</string>
|
||||||
|
@ -555,7 +555,7 @@
|
|||||||
<plurals name="manga_num_chapters">
|
<plurals name="manga_num_chapters">
|
||||||
<item quantity="other">%1$s bab</item>
|
<item quantity="other">%1$s bab</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_dns_over_https_summary">Mulai ulang aplikasi untuk menerapkan pengaturan</string>
|
<string name="requires_app_restart">Mulai ulang aplikasi untuk menerapkan pengaturan</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS melalui HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS melalui HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Jaringan</string>
|
<string name="label_network">Jaringan</string>
|
||||||
<string name="pref_jump_to_chapters">Lompat ke bab saat dibuka</string>
|
<string name="pref_jump_to_chapters">Lompat ke bab saat dibuka</string>
|
||||||
|
@ -604,7 +604,7 @@
|
|||||||
<string name="unknown_author">Autore sconosciuto</string>
|
<string name="unknown_author">Autore sconosciuto</string>
|
||||||
<string name="updated_version">Aggiornato verso v%1$s</string>
|
<string name="updated_version">Aggiornato verso v%1$s</string>
|
||||||
<string name="whats_new">Le novità</string>
|
<string name="whats_new">Le novità</string>
|
||||||
<string name="pref_dns_over_https_summary">Richiede il riavvio dell\'applicazione per avere effetto</string>
|
<string name="requires_app_restart">Richiede il riavvio dell\'applicazione per avere effetto</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS via HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS via HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Rete</string>
|
<string name="label_network">Rete</string>
|
||||||
<string name="pref_show_reading_mode_summary">Mostra brevemente la modalità corrente all\'apertura del lettore</string>
|
<string name="pref_show_reading_mode_summary">Mostra brevemente la modalità corrente all\'apertura del lettore</string>
|
||||||
|
@ -564,7 +564,7 @@
|
|||||||
<string name="tapping_inverted_none">なし</string>
|
<string name="tapping_inverted_none">なし</string>
|
||||||
<string name="unknown_status">不明なステータス</string>
|
<string name="unknown_status">不明なステータス</string>
|
||||||
<string name="unknown_author">作者不明</string>
|
<string name="unknown_author">作者不明</string>
|
||||||
<string name="pref_dns_over_https_summary">変更を適用するためには再起動してください</string>
|
<string name="requires_app_restart">変更を適用するためには再起動してください</string>
|
||||||
<string name="label_network">ネットワーク</string>
|
<string name="label_network">ネットワーク</string>
|
||||||
<string name="pref_jump_to_chapters">起動時にチャプターを表示</string>
|
<string name="pref_jump_to_chapters">起動時にチャプターを表示</string>
|
||||||
<string name="pref_read_with_tapping_inverted">タップでのページめくりを反転</string>
|
<string name="pref_read_with_tapping_inverted">タップでのページめくりを反転</string>
|
||||||
|
@ -563,7 +563,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="updated_version">განახლებულია v%1$s-მდე</string>
|
<string name="updated_version">განახლებულია v%1$s-მდე</string>
|
||||||
<string name="whats_new">რა არის ახალი</string>
|
<string name="whats_new">რა არის ახალი</string>
|
||||||
<string name="pref_dns_over_https_summary">ასამოქმედებლად საჭიროა აპლიკაციის გადატვირთვა</string>
|
<string name="requires_app_restart">ასამოქმედებლად საჭიროა აპლიკაციის გადატვირთვა</string>
|
||||||
<string name="label_network">ქსელი</string>
|
<string name="label_network">ქსელი</string>
|
||||||
<plurals name="restore_completed_message">
|
<plurals name="restore_completed_message">
|
||||||
<item quantity="one">გაკეთებულია %1$s %2$s შეცდომით</item>
|
<item quantity="one">გაკეთებულია %1$s %2$s შეცდომით</item>
|
||||||
|
@ -578,7 +578,7 @@
|
|||||||
<string name="action_global_search_query">\"%1$s\" ಅನ್ನು ಗ್ಲೋಬಲ್ ಸರ್ಚ್ ಮಾಡಿ</string>
|
<string name="action_global_search_query">\"%1$s\" ಅನ್ನು ಗ್ಲೋಬಲ್ ಸರ್ಚ್ ಮಾಡಿ</string>
|
||||||
<string name="updated_version">v%1$s ಗೆ ಅಪ್ಡೇಟ್ ಆಗಿದೆ</string>
|
<string name="updated_version">v%1$s ಗೆ ಅಪ್ಡೇಟ್ ಆಗಿದೆ</string>
|
||||||
<string name="whats_new">ಹೊಸತೇನಿದೆ</string>
|
<string name="whats_new">ಹೊಸತೇನಿದೆ</string>
|
||||||
<string name="pref_dns_over_https_summary">ಜಾರಿಗೆ ಬರಲು ಅಪ್ಲಿಕೇಶನ್ ಮರುಪ್ರಾರಂಭದ ಅಗತ್ಯವಿದೆ</string>
|
<string name="requires_app_restart">ಜಾರಿಗೆ ಬರಲು ಅಪ್ಲಿಕೇಶನ್ ಮರುಪ್ರಾರಂಭದ ಅಗತ್ಯವಿದೆ</string>
|
||||||
<string name="label_network">ಅಡ್ವಾನ್ಸ್ಡ್ ಸೆಕ್ಷನ್</string>
|
<string name="label_network">ಅಡ್ವಾನ್ಸ್ಡ್ ಸೆಕ್ಷನ್</string>
|
||||||
<string name="pref_category_reading_mode">ಓದುವ ಮೊಡ್</string>
|
<string name="pref_category_reading_mode">ಓದುವ ಮೊಡ್</string>
|
||||||
<string name="pref_jump_to_chapters">ಓಪನ್ ಮಾಡಿದ ಮೇಲೆ ಅಧ್ಯಯಕ್ಕೆ ಹೋಗಿ</string>
|
<string name="pref_jump_to_chapters">ಓಪನ್ ಮಾಡಿದ ಮೇಲೆ ಅಧ್ಯಯಕ್ಕೆ ಹೋಗಿ</string>
|
||||||
|
@ -558,7 +558,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_sort_descending">Menurun</string>
|
<string name="action_sort_descending">Menurun</string>
|
||||||
<string name="action_disable">Matikan</string>
|
<string name="action_disable">Matikan</string>
|
||||||
<string name="pref_dns_over_https_summary">Mula semula diperlukan untuk berkesan</string>
|
<string name="requires_app_restart">Mula semula diperlukan untuk berkesan</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS melalui HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS melalui HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Rangkaian</string>
|
<string name="label_network">Rangkaian</string>
|
||||||
<string name="pref_jump_to_chapters">Terus ke bab bila buka</string>
|
<string name="pref_jump_to_chapters">Terus ke bab bila buka</string>
|
||||||
|
@ -523,7 +523,7 @@
|
|||||||
<string name="battery_optimization_disabled">Batterioptimalisering er allerede deaktivert</string>
|
<string name="battery_optimization_disabled">Batterioptimalisering er allerede deaktivert</string>
|
||||||
<string name="pref_disable_battery_optimization">Deaktiver batterioptimalisering</string>
|
<string name="pref_disable_battery_optimization">Deaktiver batterioptimalisering</string>
|
||||||
<string name="label_data">Data</string>
|
<string name="label_data">Data</string>
|
||||||
<string name="pref_dns_over_https_summary">Krever omstart for å tre i kraft</string>
|
<string name="requires_app_restart">Krever omstart for å tre i kraft</string>
|
||||||
<string name="label_network">Nettverk</string>
|
<string name="label_network">Nettverk</string>
|
||||||
<string name="restoring_backup_canceled">Avbrutt gjenoppretting</string>
|
<string name="restoring_backup_canceled">Avbrutt gjenoppretting</string>
|
||||||
<string name="restore_in_progress">Gjenoppretting er allerede i gang</string>
|
<string name="restore_in_progress">Gjenoppretting er allerede i gang</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_sort_descending">Aflopend</string>
|
<string name="action_sort_descending">Aflopend</string>
|
||||||
<string name="action_open_in_settings">In Instellingen openen</string>
|
<string name="action_open_in_settings">In Instellingen openen</string>
|
||||||
<string name="pref_dns_over_https_summary">Herstart van de app nodig om van kracht te worden</string>
|
<string name="requires_app_restart">Herstart van de app nodig om van kracht te worden</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Netwerk</string>
|
<string name="label_network">Netwerk</string>
|
||||||
<string name="pref_jump_to_chapters">Ga naar de hoofdstukken bij openen</string>
|
<string name="pref_jump_to_chapters">Ga naar de hoofdstukken bij openen</string>
|
||||||
|
@ -581,7 +581,7 @@
|
|||||||
<string name="action_disable">Wyłącz</string>
|
<string name="action_disable">Wyłącz</string>
|
||||||
<string name="action_open_in_settings">Otwórz w ustawieniach</string>
|
<string name="action_open_in_settings">Otwórz w ustawieniach</string>
|
||||||
<string name="action_start">Start</string>
|
<string name="action_start">Start</string>
|
||||||
<string name="pref_dns_over_https_summary">Wymaga ponownego uruchomienia aplikacji</string>
|
<string name="requires_app_restart">Wymaga ponownego uruchomienia aplikacji</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS przez HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS przez HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Sieć</string>
|
<string name="label_network">Sieć</string>
|
||||||
<string name="pref_jump_to_chapters">Przeskocz do rozdziałów przy otwarciu</string>
|
<string name="pref_jump_to_chapters">Przeskocz do rozdziałów przy otwarciu</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
<item quantity="other">%1$s capítulos</item>
|
<item quantity="other">%1$s capítulos</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_open_in_settings">Abrir nas Configurações</string>
|
<string name="action_open_in_settings">Abrir nas Configurações</string>
|
||||||
<string name="pref_dns_over_https_summary">Requer o reinício do aplicativo para ter efeito</string>
|
<string name="requires_app_restart">Requer o reinício do aplicativo para ter efeito</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS sob HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS sob HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Rede</string>
|
<string name="label_network">Rede</string>
|
||||||
<string name="pref_jump_to_chapters">Pular para os capítulos ao abrir</string>
|
<string name="pref_jump_to_chapters">Pular para os capítulos ao abrir</string>
|
||||||
|
@ -606,7 +606,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="unknown_status">Estado desconhecido</string>
|
<string name="unknown_status">Estado desconhecido</string>
|
||||||
<string name="unknown_author">Autor desconhecido</string>
|
<string name="unknown_author">Autor desconhecido</string>
|
||||||
<string name="pref_dns_over_https_summary">Requer reinício da app para ter efeito</string>
|
<string name="requires_app_restart">Requer reinício da app para ter efeito</string>
|
||||||
<string name="label_network">Rede</string>
|
<string name="label_network">Rede</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS por HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS por HTTPS (Cloudflare)</string>
|
||||||
<string name="updated_version">Atualizado para v%1$s</string>
|
<string name="updated_version">Atualizado para v%1$s</string>
|
||||||
|
@ -575,7 +575,7 @@
|
|||||||
<item quantity="few">%1$s capitole</item>
|
<item quantity="few">%1$s capitole</item>
|
||||||
<item quantity="other">%1$s de capitole</item>
|
<item quantity="other">%1$s de capitole</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_dns_over_https_summary">Necesită restartarea aplicației pentru a avea efect</string>
|
<string name="requires_app_restart">Necesită restartarea aplicației pentru a avea efect</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS prin HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS prin HTTPS (Cloudflare)</string>
|
||||||
<string name="action_sort_descending">Descrescător</string>
|
<string name="action_sort_descending">Descrescător</string>
|
||||||
<string name="action_disable">Dezactivați</string>
|
<string name="action_disable">Dezactivați</string>
|
||||||
|
@ -586,7 +586,7 @@
|
|||||||
<item quantity="other">%1$s глав</item>
|
<item quantity="other">%1$s глав</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_sort_descending">По убыванию</string>
|
<string name="action_sort_descending">По убыванию</string>
|
||||||
<string name="pref_dns_over_https_summary">Требуется перезапуск приложения для вступления в силу</string>
|
<string name="requires_app_restart">Требуется перезапуск приложения для вступления в силу</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS по HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS по HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Сеть</string>
|
<string name="label_network">Сеть</string>
|
||||||
<string name="pref_jump_to_chapters">Переходить к главам при запуске</string>
|
<string name="pref_jump_to_chapters">Переходить к главам при запуске</string>
|
||||||
|
@ -345,7 +345,7 @@
|
|||||||
<string name="pref_remove_after_marked_as_read">Ааҕыллыбыт диэн суруллубутун кэннэ</string>
|
<string name="pref_remove_after_marked_as_read">Ааҕыллыбыт диэн суруллубутун кэннэ</string>
|
||||||
<string name="pref_download_only_over_wifi">Wi-Fi эрэ баар буоллаҕына хачайдаа</string>
|
<string name="pref_download_only_over_wifi">Wi-Fi эрэ баар буоллаҕына хачайдаа</string>
|
||||||
<string name="pref_download_directory">Хачайдааһын сурунаала</string>
|
<string name="pref_download_directory">Хачайдааһын сурунаала</string>
|
||||||
<string name="pref_dns_over_https_summary">Уларыйыы киирэрин гына эбилиги хос холбоо</string>
|
<string name="requires_app_restart">Уларыйыы киирэрин гына эбилиги хос холбоо</string>
|
||||||
<string name="cache_delete_error">Кээс сотторуутугар сыыһааһын буолла</string>
|
<string name="cache_delete_error">Кээс сотторуутугар сыыһааһын буолла</string>
|
||||||
<string name="cache_deleted">Кээс ыраастанна. %1$d билэ сотторуллубут этэ</string>
|
<string name="cache_deleted">Кээс ыраастанна. %1$d билэ сотторуллубут этэ</string>
|
||||||
<string name="used_cache">Туттуллубут: %1$s</string>
|
<string name="used_cache">Туттуллубут: %1$s</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
<item quantity="one">1 capìtulu</item>
|
<item quantity="one">1 capìtulu</item>
|
||||||
<item quantity="other">%1$s capìtulos</item>
|
<item quantity="other">%1$s capìtulos</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_dns_over_https_summary">Tenet bisòngiu chi torres a allùghere s\'aplicatzione pro tènnere efetu</string>
|
<string name="requires_app_restart">Tenet bisòngiu chi torres a allùghere s\'aplicatzione pro tènnere efetu</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS pro mèdiu de HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS pro mèdiu de HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Retza</string>
|
<string name="label_network">Retza</string>
|
||||||
<string name="pref_jump_to_chapters">Brinca a sos capìtulos a s\'abertura</string>
|
<string name="pref_jump_to_chapters">Brinca a sos capìtulos a s\'abertura</string>
|
||||||
|
@ -572,7 +572,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="unknown_status">Okänd status</string>
|
<string name="unknown_status">Okänd status</string>
|
||||||
<string name="unknown_author">Okänd författare</string>
|
<string name="unknown_author">Okänd författare</string>
|
||||||
<string name="pref_dns_over_https_summary">Kräver omstart av appen för att börja gälla</string>
|
<string name="requires_app_restart">Kräver omstart av appen för att börja gälla</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS över HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS över HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Nätverk</string>
|
<string name="label_network">Nätverk</string>
|
||||||
<string name="pref_jump_to_chapters">Hoppa till kapitel vid öppning</string>
|
<string name="pref_jump_to_chapters">Hoppa till kapitel vid öppning</string>
|
||||||
|
@ -568,7 +568,7 @@
|
|||||||
<item quantity="other">%1$s bölüm</item>
|
<item quantity="other">%1$s bölüm</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_open_in_settings">Ayarlarda aç</string>
|
<string name="action_open_in_settings">Ayarlarda aç</string>
|
||||||
<string name="pref_dns_over_https_summary">Etkili olması için uygulama yeniden başlatılmalıdır</string>
|
<string name="requires_app_restart">Etkili olması için uygulama yeniden başlatılmalıdır</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">HTTPS ile DNS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">HTTPS ile DNS (Cloudflare)</string>
|
||||||
<string name="label_network">Ağ</string>
|
<string name="label_network">Ağ</string>
|
||||||
<string name="pref_jump_to_chapters">Açınca bölümlere git</string>
|
<string name="pref_jump_to_chapters">Açınca bölümlere git</string>
|
||||||
|
@ -591,7 +591,7 @@
|
|||||||
<string name="pref_read_with_tapping_inverted">Інвертувати тицяння</string>
|
<string name="pref_read_with_tapping_inverted">Інвертувати тицяння</string>
|
||||||
<string name="unknown_status">Невідомий статус</string>
|
<string name="unknown_status">Невідомий статус</string>
|
||||||
<string name="unknown_author">Невідомий автор</string>
|
<string name="unknown_author">Невідомий автор</string>
|
||||||
<string name="pref_dns_over_https_summary">Потрібен перезапуск, щоб зміни вступили в дію</string>
|
<string name="requires_app_restart">Потрібен перезапуск, щоб зміни вступили в дію</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS понад HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS понад HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">Мережа</string>
|
<string name="label_network">Мережа</string>
|
||||||
<string name="pref_jump_to_chapters">Перейти до глав при відкритті</string>
|
<string name="pref_jump_to_chapters">Перейти до глав при відкритті</string>
|
||||||
|
@ -558,7 +558,7 @@
|
|||||||
<item quantity="other">%1$s 个章节</item>
|
<item quantity="other">%1$s 个章节</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="action_open_in_settings">在设置中打开</string>
|
<string name="action_open_in_settings">在设置中打开</string>
|
||||||
<string name="pref_dns_over_https_summary">需要重启应用才能生效</string>
|
<string name="requires_app_restart">需要重启应用才能生效</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">网络</string>
|
<string name="label_network">网络</string>
|
||||||
<string name="pref_jump_to_chapters">打开时跳转到阅读章节</string>
|
<string name="pref_jump_to_chapters">打开时跳转到阅读章节</string>
|
||||||
|
@ -525,7 +525,7 @@
|
|||||||
<plurals name="num_categories">
|
<plurals name="num_categories">
|
||||||
<item quantity="other">%d 個分類</item>
|
<item quantity="other">%d 個分類</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="pref_dns_over_https_summary">需要重新啟動應用程式以套用</string>
|
<string name="requires_app_restart">需要重新啟動應用程式以套用</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
||||||
<string name="label_network">網路</string>
|
<string name="label_network">網路</string>
|
||||||
<string name="tapping_inverted_both">全部</string>
|
<string name="tapping_inverted_both">全部</string>
|
||||||
|
@ -172,11 +172,10 @@
|
|||||||
<string name="secure_screen_summary">Hide app contents when switching apps and block screenshots</string>
|
<string name="secure_screen_summary">Hide app contents when switching apps and block screenshots</string>
|
||||||
<string name="hide_notification_content">Hide notification content</string>
|
<string name="hide_notification_content">Hide notification content</string>
|
||||||
|
|
||||||
<string name="pref_category_nsfw_content">18+ content</string>
|
<string name="pref_category_nsfw_content">NSFW (18+) sources</string>
|
||||||
<string name="pref_allow_nsfw_sources">18+ sources</string>
|
<string name="pref_show_nsfw_source">Show in sources list</string>
|
||||||
<string name="pref_allow_nsfw_sources_allowed">Show</string>
|
<string name="pref_show_nsfw_extension">Show in extensions list</string>
|
||||||
<string name="pref_allow_nsfw_sources_allowed_multisource">Hide in sources but show in extensions list</string>
|
<string name="pref_label_nsfw_extension">Label in extensions list</string>
|
||||||
<string name="pref_allow_nsfw_sources_blocked">Hide</string>
|
|
||||||
<string name="parental_controls_info">This does not prevent unofficial or potentially incorrectly flagged extensions from surfacing 18+ content within the app.</string>
|
<string name="parental_controls_info">This does not prevent unofficial or potentially incorrectly flagged extensions from surfacing 18+ content within the app.</string>
|
||||||
|
|
||||||
<!-- Library section -->
|
<!-- Library section -->
|
||||||
@ -390,7 +389,7 @@
|
|||||||
<string name="label_network">Network</string>
|
<string name="label_network">Network</string>
|
||||||
<string name="pref_clear_cookies">Clear cookies</string>
|
<string name="pref_clear_cookies">Clear cookies</string>
|
||||||
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
<string name="pref_dns_over_https" translatable="false">DNS over HTTPS (Cloudflare)</string>
|
||||||
<string name="pref_dns_over_https_summary">Requires app restart to take effect</string>
|
<string name="requires_app_restart">Requires app restart to take effect</string>
|
||||||
<string name="cookies_cleared">Cookies cleared</string>
|
<string name="cookies_cleared">Cookies cleared</string>
|
||||||
<string name="label_data">Data</string>
|
<string name="label_data">Data</string>
|
||||||
<string name="pref_clear_chapter_cache">Clear chapter cache</string>
|
<string name="pref_clear_chapter_cache">Clear chapter cache</string>
|
||||||
@ -570,6 +569,8 @@
|
|||||||
<string name="track_type">Type</string>
|
<string name="track_type">Type</string>
|
||||||
<string name="track_author">Author</string>
|
<string name="track_author">Author</string>
|
||||||
<string name="error_invalid_date_supplied">Invalid date supplied</string>
|
<string name="error_invalid_date_supplied">Invalid date supplied</string>
|
||||||
|
<string name="myanimelist_creds_missing">MAL login credentials not found</string>
|
||||||
|
<string name="myanimelist_relogin">Please login to MAL again</string>
|
||||||
|
|
||||||
<!-- Category activity -->
|
<!-- Category activity -->
|
||||||
<string name="error_category_exists">A category with this name already exists!</string>
|
<string name="error_category_exists">A category with this name already exists!</string>
|
||||||
@ -666,6 +667,7 @@
|
|||||||
<!-- File Picker Titles -->
|
<!-- File Picker Titles -->
|
||||||
<string name="file_select_cover">Select cover image</string>
|
<string name="file_select_cover">Select cover image</string>
|
||||||
<string name="file_select_backup">Select backup file</string>
|
<string name="file_select_backup">Select backup file</string>
|
||||||
|
<string name="file_picker_error">No file picker app found</string>
|
||||||
|
|
||||||
<!--UpdateCheck-->
|
<!--UpdateCheck-->
|
||||||
<string name="update_check_confirm">Download</string>
|
<string name="update_check_confirm">Download</string>
|
||||||
|
@ -325,22 +325,4 @@
|
|||||||
<item name="android:textSize">15sp</item>
|
<item name="android:textSize">15sp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<!--===-->
|
|
||||||
<!--OLD-->
|
|
||||||
<!--===-->
|
|
||||||
<style name="FilePickerTheme" parent="NNF_BaseTheme.Light">
|
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
|
||||||
<item name="colorPrimaryDark">@color/colorPrimary</item>
|
|
||||||
<item name="colorAccent">@color/colorAccentLight</item>
|
|
||||||
<item name="colorButtonNormal">@color/colorPrimary</item>
|
|
||||||
<item name="android:textSize">14sp</item>
|
|
||||||
|
|
||||||
<item name="alertDialogTheme">@style/FilePickerAlertDialogTheme</item>
|
|
||||||
|
|
||||||
<item name="nnf_toolbarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="FilePickerAlertDialogTheme" parent="Theme.MaterialComponents.Light.Dialog.Alert" />
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -27,7 +27,7 @@ buildscript {
|
|||||||
dependencies {
|
dependencies {
|
||||||
classpath("com.github.zellius:android-shortcut-gradle-plugin:0.1.2")
|
classpath("com.github.zellius:android-shortcut-gradle-plugin:0.1.2")
|
||||||
classpath("com.google.gms:google-services:4.3.4")
|
classpath("com.google.gms:google-services:4.3.4")
|
||||||
classpath("com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:" + BuildPluginsVersion.ABOUTLIB_PLUGIN)
|
classpath("com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${BuildPluginsVersion.ABOUTLIB_PLUGIN}")
|
||||||
classpath(kotlin("serialization", version = BuildPluginsVersion.KOTLIN))
|
classpath(kotlin("serialization", version = BuildPluginsVersion.KOTLIN))
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
|
Reference in New Issue
Block a user