Compare commits

...

47 Commits
v6.7 ... v6.7.2

Author SHA1 Message Date
Koitharu
8cc04b0f7a Add Remove from history action on details activity 2024-02-18 10:07:42 +02:00
Koitharu
258dbf3dc3 Fix reader info bar text size 2024-02-18 09:26:57 +02:00
Koitharu
e7af4e8450 Fix backup restore dialog layout #770 2024-02-18 09:20:34 +02:00
Koitharu
0c25c61858 Fix filtering pages by branches 2024-02-18 09:14:49 +02:00
Koitharu
abc3e45907 Fix reader state on changed 2024-02-18 09:08:22 +02:00
Koitharu
bd98d8eded Fix onboarding sources selection 2024-02-18 08:44:13 +02:00
Koitharu
2e81f41073 Update dependencies 2024-02-18 08:44:13 +02:00
Oğuz Ersen
5cccebc416 Translated using Weblate (Turkish)
Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/tr/
Translation: Kotatsu/Strings
2024-02-18 08:43:59 +02:00
Макар Разин
c668ffd555 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Belarusian)

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Макар Разин <makarrazin14@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/be/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/uk/
Translation: Kotatsu/Strings
2024-02-18 08:43:59 +02:00
gekka
a0f77b715f Translated using Weblate (Chinese (Simplified))
Currently translated at 99.6% (589 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (590 of 591 strings)

Co-authored-by: gekka <1778962971@qq.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/zh_Hans/
Translation: Kotatsu/Strings
2024-02-18 08:43:59 +02:00
Anonymous
2831843a25 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.8% (590 of 591 strings)

Co-authored-by: Anonymous <noreply@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/zh_Hans/
Translation: Kotatsu/Strings
2024-02-18 08:43:59 +02:00
Koitharu
86c1aa11b0 Fix crash 2024-02-17 12:45:02 +02:00
Koitharu
d71514ec7a Configurable dir for silent pages saving 2024-02-17 12:31:12 +02:00
Koitharu
92ed320f57 Add compact navbar option 2024-02-17 10:41:55 +02:00
Koitharu
2de1fe8b77 Fix icon tint 2024-02-16 12:29:52 +02:00
vianh
cebc3cd9e8 Adjust search screen ui 2024-02-16 10:40:23 +02:00
vianh
6c0e2e2b90 Fix mirror domain switching 2024-02-16 10:40:23 +02:00
vianh
b4bd923ce8 Improve webtoon zoom fling 2024-02-16 10:39:17 +02:00
Koitharu
813561fd3b Merge remote-tracking branch 'weblate/devel' into devel 2024-02-16 10:37:43 +02:00
Jordan \"Tes\" Michel
4107336132 Translated using Weblate (French)
Currently translated at 100.0% (9 of 9 strings)

Translated using Weblate (French)

Currently translated at 93.4% (552 of 591 strings)

Co-authored-by: Jordan \"Tes\" Michel <jordan.michel13@yahoo.fr>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/fr/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/fr/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2024-02-16 10:35:52 +02:00
Anon
30d9d87c17 Translated using Weblate (Serbian)
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Serbian)

Currently translated at 99.6% (589 of 591 strings)

Co-authored-by: Anon <anonymousprivate76@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/sr/
Translation: Kotatsu/Strings
2024-02-16 10:35:52 +02:00
gekka
c4b5be657d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: gekka <1778962971@qq.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/zh_Hans/
Translation: Kotatsu/Strings
2024-02-16 10:35:51 +02:00
Koitharu
8a763b2b9f Bring back adaptive reader control preference 2024-02-16 10:35:27 +02:00
Koitharu
c783378022 Update app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt 2024-02-15 10:26:22 +02:00
Isira Seneviratne
c4355f16e8 Improve serializable extra extension 2024-02-15 10:26:22 +02:00
Isira Seneviratne
522dfc2418 Use SoftwareKeyboardControllerCompat 2024-02-15 10:22:28 +02:00
Koitharu
06d03e3ddd Fix SyncSettings lifecycle 2024-02-14 12:49:46 +02:00
Koitharu
9dc8c7959d Update parsers 2024-02-14 12:19:08 +02:00
Davi Silveira
db219020ca Translated using Weblate (Portuguese)
Currently translated at 100.0% (9 of 9 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Davi Silveira <davilego10@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/pt/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/pt/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2024-02-14 12:00:37 +02:00
Aiman Sara
c04edcb76c Translated using Weblate (Malay)
Currently translated at 53.9% (319 of 591 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (9 of 9 strings)

Co-authored-by: Aiman Sara <aimansara21@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/ms/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/ms/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2024-02-14 12:00:37 +02:00
Anon
936fc2e4ae Translated using Weblate (Serbian)
Currently translated at 99.6% (589 of 591 strings)

Co-authored-by: Anon <anonymousprivate76@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/sr/
Translation: Kotatsu/Strings
2024-02-14 12:00:37 +02:00
gekka
cbed866665 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: gekka <1778962971@qq.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/zh_Hans/
Translation: Kotatsu/Strings
2024-02-14 12:00:37 +02:00
Madaraki
ac568b6361 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Madaraki <115705267+Madaraki-chan@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/uk/
Translation: Kotatsu/Strings
2024-02-14 12:00:37 +02:00
Oğuz Ersen
84157f988d Translated using Weblate (Turkish)
Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/tr/
Translation: Kotatsu/Strings
2024-02-14 12:00:37 +02:00
gallegonovato
6f6339f0f8 Translated using Weblate (Spanish)
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (589 of 589 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/es/
Translation: Kotatsu/Strings
2024-02-14 12:00:37 +02:00
Jordan \"Tes\" Michel
a7019b9096 Translated using Weblate (French)
Currently translated at 100.0% (9 of 9 strings)

Translated using Weblate (French)

Currently translated at 93.4% (552 of 591 strings)

Co-authored-by: Jordan \"Tes\" Michel <jordan.michel13@yahoo.fr>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/fr/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/fr/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2024-02-14 10:33:12 +01:00
Davi Silveira
867e3f10ca Translated using Weblate (Portuguese)
Currently translated at 100.0% (9 of 9 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Davi Silveira <davilego10@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/pt/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/pt/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2024-02-14 10:33:12 +01:00
Aiman Sara
fb2cf04d75 Translated using Weblate (Malay)
Currently translated at 53.9% (319 of 591 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (9 of 9 strings)

Co-authored-by: Aiman Sara <aimansara21@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/ms/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/ms/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2024-02-14 10:33:12 +01:00
Anon
3ed44ba0d6 Translated using Weblate (Serbian)
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Serbian)

Currently translated at 99.6% (589 of 591 strings)

Co-authored-by: Anon <anonymousprivate76@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/sr/
Translation: Kotatsu/Strings
2024-02-14 10:33:12 +01:00
gekka
b78104a0f1 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: gekka <1778962971@qq.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/zh_Hans/
Translation: Kotatsu/Strings
2024-02-14 10:33:12 +01:00
Madaraki
e4ee93f77c Translated using Weblate (Ukrainian)
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Madaraki <115705267+Madaraki-chan@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/ru/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/uk/
Translation: Kotatsu/Strings
2024-02-14 10:33:11 +01:00
Oğuz Ersen
c6e8da5f23 Translated using Weblate (Turkish)
Currently translated at 100.0% (591 of 591 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/tr/
Translation: Kotatsu/Strings
2024-02-14 10:33:11 +01:00
gallegonovato
376de7cce3 Translated using Weblate (Spanish)
Currently translated at 100.0% (591 of 591 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (589 of 589 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/es/
Translation: Kotatsu/Strings
2024-02-14 10:33:11 +01:00
Koitharu
bec2195971 Fix processing tap actions in reader when not resumed 2024-02-13 08:03:09 +02:00
Zakhar Timoshenko
722ac4ecc7 Tweak chapter item 2024-02-12 19:02:23 +03:00
Koitharu
516c1c02a6 Improve chapters list ui accessibility #752 2024-02-12 14:26:20 +02:00
Koitharu
0cb7e71781 Fix chapters selection decoration 2024-02-12 09:07:32 +02:00
58 changed files with 1038 additions and 742 deletions

View File

@@ -16,8 +16,8 @@ android {
applicationId 'org.koitharu.kotatsu'
minSdk = 21
targetSdk = 34
versionCode = 622
versionName = '6.7'
versionCode = 624
versionName = '6.7.2'
generatedDensities = []
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
ksp {
@@ -82,13 +82,13 @@ afterEvaluate {
}
dependencies {
//noinspection GradleDependency
implementation('com.github.KotatsuApp:kotatsu-parsers:014ea5ef49') {
implementation('com.github.KotatsuApp:kotatsu-parsers:3ff028c4e9') {
exclude group: 'org.json', module: 'json'
}
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.22'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.core:core-ktx:1.12.0'
@@ -148,14 +148,14 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.json:json:20240205'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test:core-ktx:1.5.0'
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.5'
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0'
androidTestImplementation 'androidx.room:room-testing:2.6.1'
androidTestImplementation 'com.squareup.moshi:moshi-kotlin:1.15.1'

View File

@@ -227,6 +227,5 @@ class RemoteMangaRepository(
}
}
private fun Result<*>.isValidResult() = exceptionOrNull() !is ParseException
&& (getOrNull() as? Collection<*>)?.isEmpty() != true
private fun Result<*>.isValidResult() = isSuccess && (getOrNull() as? Collection<*>)?.isEmpty() != true
}

View File

@@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.collection.ArraySet
import androidx.core.content.edit
import androidx.core.os.LocaleListCompat
import androidx.documentfile.provider.DocumentFile
import androidx.preference.PreferenceManager
import dagger.hilt.android.qualifiers.ApplicationContext
import org.json.JSONArray
@@ -70,6 +71,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
}
}
val isNavLabelsVisible: Boolean
get() = prefs.getBoolean(KEY_NAV_LABELS, true)
var gridSize: Int
get() = prefs.getInt(KEY_GRID_SIZE, 100)
set(value) = prefs.edit { putInt(KEY_GRID_SIZE, value) }
@@ -111,6 +115,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val isReaderZoomButtonsEnabled: Boolean
get() = prefs.getBoolean(KEY_READER_ZOOM_BUTTONS, false)
val isReaderControlAlwaysLTR: Boolean
get() = prefs.getBoolean(KEY_READER_CONTROL_LTR, false)
val isReaderFullscreenEnabled: Boolean
get() = prefs.getBoolean(KEY_READER_FULLSCREEN, true)
@@ -406,6 +413,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val isReadingTimeEstimationEnabled: Boolean
get() = prefs.getBoolean(KEY_READING_TIME, true)
val isPagesSavingAskEnabled: Boolean
get() = prefs.getBoolean(KEY_PAGES_SAVE_ASK, true)
fun isTipEnabled(tip: String): Boolean {
return prefs.getStringSet(KEY_TIPS_CLOSED, emptySet())?.contains(tip) != true
}
@@ -418,6 +428,15 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
prefs.edit { putStringSet(KEY_TIPS_CLOSED, closedTips + tip) }
}
fun getPagesSaveDir(context: Context): DocumentFile? =
prefs.getString(KEY_PAGES_SAVE_DIR, null)?.toUriOrNull()?.let {
DocumentFile.fromTreeUri(context, it)
}
fun setPagesSaveDir(uri: Uri?) {
prefs.edit { putString(KEY_PAGES_SAVE_DIR, uri?.toString()) }
}
fun subscribe(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
prefs.registerOnSharedPreferenceChangeListener(listener)
}
@@ -488,6 +507,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_LOCAL_STORAGE = "local_storage"
const val KEY_READER_DOUBLE_PAGES = "reader_double_pages"
const val KEY_READER_ZOOM_BUTTONS = "reader_zoom_buttons"
const val KEY_READER_CONTROL_LTR = "reader_taps_ltr"
const val KEY_READER_FULLSCREEN = "reader_fullscreen"
const val KEY_READER_VOLUME_BUTTONS = "reader_volume_buttons"
const val KEY_TRACKER_ENABLED = "tracker_enabled"
@@ -573,6 +593,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_DISABLE_NSFW = "no_nsfw"
const val KEY_RELATED_MANGA = "related_manga"
const val KEY_NAV_MAIN = "nav_main"
const val KEY_NAV_LABELS = "nav_labels"
const val KEY_32BIT_COLOR = "enhanced_colors"
const val KEY_SOURCES_ORDER = "sources_sort_order"
const val KEY_SOURCES_CATALOG = "sources_catalog"
@@ -583,6 +604,8 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_IGNORE_DOZE = "ignore_dose"
const val KEY_DETAILS_TAB = "details_tab"
const val KEY_READING_TIME = "reading_time"
const val KEY_PAGES_SAVE_DIR = "pages_dir"
const val KEY_PAGES_SAVE_ASK = "pages_dir_ask"
// About
const val KEY_APP_UPDATE = "app_update"

View File

@@ -91,7 +91,7 @@ abstract class AbstractSelectionItemDecoration : RecyclerView.ItemDecoration() {
canvas.restoreToCount(checkpoint)
}
protected open fun getItemId(parent: RecyclerView, child: View) = parent.getChildItemId(child)
abstract fun getItemId(parent: RecyclerView, child: View): Long
protected open fun onDrawBackground(
canvas: Canvas,

View File

@@ -7,12 +7,16 @@ import org.koitharu.kotatsu.R
class ReversibleActionObserver(
private val snackbarHost: View,
private val snackbarAnchor: View? = null,
) : FlowCollector<ReversibleAction> {
override suspend fun emit(value: ReversibleAction) {
val handle = value.handle
val length = if (handle == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG
val snackbar = Snackbar.make(snackbarHost, value.stringResId, length)
if (snackbarAnchor?.isShown == true) {
snackbar.anchorView = snackbarAnchor
}
if (handle != null) {
snackbar.setAction(R.string.undo) { handle.reverseAsync() }
}

View File

@@ -24,11 +24,15 @@ inline fun <reified T : Parcelable> Intent.getParcelableExtraCompat(key: String)
}
inline fun <reified T : Serializable> Intent.getSerializableExtraCompat(key: String): T? {
return getSerializableExtra(key) as T?
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
getSerializableExtra(key, T::class.java)
} else {
getSerializableExtra(key) as T?
}
}
inline fun <reified T : Serializable> Bundle.getSerializableCompat(key: String): T? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
getSerializable(key, T::class.java)
} else {
getSerializable(key) as T?

View File

@@ -1,15 +1,14 @@
package org.koitharu.kotatsu.core.util.ext
import android.app.Activity
import android.graphics.Rect
import android.os.Build
import android.view.View
import android.view.View.MeasureSpec
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Checkable
import androidx.appcompat.widget.ActionMenuView
import androidx.appcompat.widget.Toolbar
import androidx.core.view.SoftwareKeyboardControllerCompat
import androidx.core.view.children
import androidx.core.view.descendants
import androidx.core.view.isVisible
@@ -24,13 +23,11 @@ import com.google.android.material.tabs.TabLayout
import kotlin.math.roundToInt
fun View.hideKeyboard() {
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(this.windowToken, 0)
SoftwareKeyboardControllerCompat(this).hide()
}
fun View.showKeyboard() {
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, 0)
SoftwareKeyboardControllerCompat(this).show()
}
fun View.hasGlobalPoint(x: Int, y: Int): Boolean {

View File

@@ -138,7 +138,7 @@ class DetailsActivity :
},
),
)
viewModel.onActionDone.observeEvent(this, ReversibleActionObserver(viewBinding.containerDetails))
viewModel.onActionDone.observeEvent(this, ReversibleActionObserver(viewBinding.containerDetails, viewBinding.layoutBottom))
viewModel.onShowTip.observeEvent(this) { showTip() }
viewModel.historyInfo.observe(this, ::onHistoryChanged)
viewModel.selectedBranch.observe(this) {
@@ -187,6 +187,9 @@ class DetailsActivity :
buttonTip = null
val menu = PopupMenu(v.context, v)
menu.inflate(R.menu.popup_read)
menu.menu.findItem(R.id.action_forget)?.isVisible = viewModel.historyInfo.value.run {
!isIncognitoMode && history != null
}
menu.setOnMenuItemClickListener(this)
menu.setForceShowIcon(true)
menu.show()
@@ -203,6 +206,11 @@ class DetailsActivity :
true
}
R.id.action_forget -> {
viewModel.removeFromHistory()
true
}
R.id.action_pages_thumbs -> {
val history = viewModel.historyInfo.value.history
PagesThumbnailsSheet.show(

View File

@@ -71,8 +71,6 @@ import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
import org.koitharu.kotatsu.scrobbling.common.ui.selector.ScrobblingSelectorSheet
import org.koitharu.kotatsu.search.ui.MangaListActivity
import org.koitharu.kotatsu.search.ui.SearchActivity
import java.text.SimpleDateFormat
import java.util.Date
import javax.inject.Inject
@AndroidEntryPoint

View File

@@ -346,6 +346,13 @@ class DetailsViewModel @Inject constructor(
settings.closeTip(DetailsActivity.TIP_BUTTON)
}
fun removeFromHistory() {
launchJob(Dispatchers.Default) {
val handle = historyRepository.delete(setOf(mangaId))
onActionDone.call(ReversibleAction(R.string.removed_from_history, handle))
}
}
private fun doLoad() = launchLoadingJob(Dispatchers.Default) {
detailsLoadUseCase.invoke(intent)
.onEachWhile {

View File

@@ -5,7 +5,6 @@ import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.formatNumber
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.drawableStart
@@ -14,6 +13,7 @@ import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ItemChapterBinding
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
import org.koitharu.kotatsu.list.ui.model.ListModel
import com.google.android.material.R as MR
fun chapterListItemAD(
clickListener: OnListItemClickListener<ChapterListItem>,
@@ -46,7 +46,7 @@ fun chapterListItemAD(
null
}
binding.textViewTitle.setTextColor(context.getThemeColorStateList(android.R.attr.textColorPrimary))
binding.textViewDescription.setTextColor(context.getThemeColorStateList(android.R.attr.textColorPrimary))
binding.textViewDescription.setTextColor(context.getThemeColorStateList(MR.attr.colorOutline))
binding.textViewTitle.typeface = Typeface.DEFAULT
binding.textViewDescription.typeface = Typeface.DEFAULT
}

View File

@@ -9,7 +9,9 @@ import android.view.View
import androidx.core.graphics.ColorUtils
import androidx.recyclerview.widget.RecyclerView
import org.koitharu.kotatsu.core.ui.list.decor.AbstractSelectionItemDecoration
import org.koitharu.kotatsu.core.util.ext.getItem
import org.koitharu.kotatsu.core.util.ext.getThemeColor
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
import com.google.android.material.R as materialR
class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() {
@@ -25,6 +27,12 @@ class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecor
paint.style = Paint.Style.FILL
}
override fun getItemId(parent: RecyclerView, child: View): Long {
val holder = parent.getChildViewHolder(child) ?: return RecyclerView.NO_ID
val item = holder.getItem(ChapterListItem::class.java) ?: return RecyclerView.NO_ID
return item.chapter.id
}
override fun onDrawBackground(
canvas: Canvas,
parent: RecyclerView,

View File

@@ -234,7 +234,7 @@ class ChaptersFragment :
}
override fun onSelectionChanged(controller: ListSelectionController, count: Int) {
requireViewBinding().recyclerViewChapters.invalidateItemDecorations()
viewBinding?.recyclerViewChapters?.invalidateItemDecorations()
}
override fun onWindowInsetsChanged(insets: Insets) = Unit

View File

@@ -13,7 +13,9 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import coil.ImageLoader
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
import org.koitharu.kotatsu.core.prefs.AppSettings
@@ -65,11 +67,12 @@ class PagesFragment :
detailsViewModel.selectedBranch,
) { details, history, branch ->
if (details != null && (details.isLoaded || details.chapters.isNotEmpty())) {
PagesViewModel.State(details, history, branch)
PagesViewModel.State(details.filterChapters(branch), history, branch)
} else {
null
}
}.observe(this, viewModel::updateState)
}.flowOn(Dispatchers.Default)
.observe(this, viewModel::updateState)
}
override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentPagesBinding {

View File

@@ -68,9 +68,8 @@ class FavouritesCategoryEditActivity :
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
val order = savedInstanceState.getSerializableCompat<ListSortOrder>(KEY_SORT_ORDER)
if (order != null) {
selectedSortOrder = order
savedInstanceState.getSerializableCompat<ListSortOrder>(KEY_SORT_ORDER)?.let {
selectedSortOrder = it
}
}

View File

@@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.navigation.NavigationBarView
import com.google.android.material.transition.MaterialFadeThrough
import kotlinx.coroutines.Dispatchers
@@ -34,6 +35,7 @@ import org.koitharu.kotatsu.local.ui.LocalListFragment
import org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment
import org.koitharu.kotatsu.tracker.ui.feed.FeedFragment
import java.util.LinkedList
import com.google.android.material.R as materialR
private const val TAG_PRIMARY = "primary"
@@ -194,12 +196,15 @@ class MainNavigationDelegate(
private fun observeSettings(lifecycleOwner: LifecycleOwner) {
settings.observe()
.filter { x -> x == AppSettings.KEY_TRACKER_ENABLED || x == AppSettings.KEY_SUGGESTIONS }
.filter { x ->
x == AppSettings.KEY_TRACKER_ENABLED || x == AppSettings.KEY_SUGGESTIONS || x == AppSettings.KEY_NAV_LABELS
}
.onStart { emit("") }
.flowOn(Dispatchers.Default)
.flowOn(Dispatchers.IO)
.onEach {
setItemVisibility(R.id.nav_suggestions, settings.isSuggestionsEnabled)
setItemVisibility(R.id.nav_feed, settings.isTrackerEnabled)
setNavbarIsLabeled(settings.isNavLabelsVisible)
}.launchIn(lifecycleOwner.lifecycleScope)
}
@@ -211,6 +216,23 @@ class MainNavigationDelegate(
return null
}
private fun setNavbarIsLabeled(value: Boolean) {
if (navBar is BottomNavigationView) {
navBar.minimumHeight = navBar.resources.getDimensionPixelSize(
if (value) {
materialR.dimen.m3_bottom_nav_min_height
} else {
R.dimen.nav_bar_height_compact
},
)
}
navBar.labelVisibilityMode = if (value) {
NavigationBarView.LABEL_VISIBILITY_LABELED
} else {
NavigationBarView.LABEL_VISIBILITY_UNLABELED
}
}
interface OnFragmentChangedListener {
fun onFragmentChanged(fragment: Fragment, fromUser: Boolean)

View File

@@ -61,6 +61,8 @@ class WelcomeViewModel @Inject constructor(
selectedItems = selectedLocales,
isLoading = false,
)
repository.assimilateNewSources()
commit()
}
}

View File

@@ -8,19 +8,26 @@ import android.provider.DocumentsContract
import android.webkit.MimeTypeMap
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.net.toUri
import org.koitharu.kotatsu.core.util.ext.toUriOrNull
import java.io.File
class PageSaveContract : ActivityResultContracts.CreateDocument("image/*") {
override fun createIntent(context: Context, input: String): Intent {
val intent = super.createIntent(context, input)
val intent = super.createIntent(context, input.substringAfterLast(File.separatorChar))
intent.type = MimeTypeMap.getSingleton()
.getMimeTypeFromExtension(input.substringAfterLast('.')) ?: "image/*"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val defaultUri = input.toUriOrNull()?.run {
path?.let { p ->
buildUpon().path(p.substringBeforeLast('/')).build()
}
}
intent.putExtra(
DocumentsContract.EXTRA_INITIAL_URI,
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toUri(),
defaultUri ?: Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toUri(),
)
}
return intent
}
}
}

View File

@@ -15,6 +15,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
import okio.IOException
import okio.buffer
import okio.sink
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.ext.source
import org.koitharu.kotatsu.core.util.ext.toFileOrNull
import org.koitharu.kotatsu.core.util.ext.writeAllCancellable
@@ -30,7 +31,8 @@ private const val MAX_FILENAME_LENGTH = 10
private const val EXTENSION_FALLBACK = "png"
class PageSaveHelper @Inject constructor(
@ApplicationContext context: Context,
@ApplicationContext private val context: Context,
private val settings: AppSettings,
) {
private var continuation: Continuation<Uri>? = null
@@ -44,14 +46,7 @@ class PageSaveHelper @Inject constructor(
val pageUrl = pageLoader.getPageUrl(page)
val pageUri = pageLoader.loadPage(page, force = false)
val proposedName = getProposedFileName(pageUrl, pageUri)
val destination = withContext(Dispatchers.Main) {
suspendCancellableCoroutine { cont ->
continuation = cont
saveLauncher.launch(proposedName)
}.also {
continuation = null
}
}
val destination = getDefaultFileUri(proposedName) ?: pickFileUri(saveLauncher, proposedName)
runInterruptible(Dispatchers.IO) {
contentResolver.openOutputStream(destination)?.sink()?.buffer()
}?.use { output ->
@@ -62,12 +57,35 @@ class PageSaveHelper @Inject constructor(
return destination
}
private fun getDefaultFileUri(proposedName: String): Uri? {
if (settings.isPagesSavingAskEnabled) {
return null
}
return settings.getPagesSaveDir(context)?.let {
val ext = proposedName.substringAfterLast('.', "")
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext) ?: return null
it.createFile(mime, proposedName.substringBeforeLast('.'))?.uri
}
}
private suspend fun pickFileUri(saveLauncher: ActivityResultLauncher<String>, proposedName: String): Uri {
val defaultUri = settings.getPagesSaveDir(context)?.uri?.buildUpon()?.appendPath(proposedName)?.toString()
return withContext(Dispatchers.Main) {
suspendCancellableCoroutine { cont ->
continuation = cont
saveLauncher.launch(defaultUri ?: proposedName)
}.also {
continuation = null
}
}
}
fun onActivityResult(uri: Uri): Boolean = continuation?.apply {
resume(uri)
} != null
private suspend fun getProposedFileName(url: String, fileUri: Uri): String {
var name = if (url.startsWith("cbz://")) {
var name = if (url.startsWith("cbz:")) {
requireNotNull(url.toUri().fragment)
} else {
url.toHttpUrl().pathSegments.last()

View File

@@ -206,11 +206,13 @@ class ReaderActivity :
}
override fun onGridTouch(area: TapGridArea): Boolean {
return controlDelegate.onGridTouch(area)
return isReaderResumed() && controlDelegate.onGridTouch(area)
}
override fun onGridLongTouch(area: TapGridArea) {
controlDelegate.onGridLongTouch(area)
if (isReaderResumed()) {
controlDelegate.onGridLongTouch(area)
}
}
override fun onProcessTouch(rawX: Int, rawY: Int): Boolean {

View File

@@ -114,7 +114,7 @@ class ReaderControlDelegate(
}
private fun isReaderTapsReversed(): Boolean {
return listener.readerMode == ReaderMode.REVERSED
return settings.isReaderControlAlwaysLTR && listener.readerMode == ReaderMode.REVERSED
}
interface OnInteractionListener {

View File

@@ -117,6 +117,7 @@ class ReaderConfigSheet :
R.id.button_save_page -> {
val page = viewModel.getCurrentPage() ?: return
viewModel.saveCurrentPage(page, savePageRequest)
dismissAllowingStateLoss()
}
R.id.button_screen_rotate -> {

View File

@@ -108,7 +108,7 @@ abstract class BasePagerReaderFragment : BaseReaderFragment<FragmentReaderPagerB
val axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL)
val withCtrl = event.metaState and KeyEvent.META_CTRL_MASK != 0
if (!withCtrl) {
switchPageBy(-axisValue.sign.toInt())
onWheelScroll(axisValue)
return true
}
}
@@ -172,6 +172,10 @@ abstract class BasePagerReaderFragment : BaseReaderFragment<FragmentReaderPagerB
)
}
protected open fun onWheelScroll(axisValue: Float) {
switchPageBy(-axisValue.sign.toInt())
}
protected open fun onCreateAdvancedTransformer(): PageTransformer = PageAnimTransformer()
protected open fun onInitPager(pager: ViewPager2) {

View File

@@ -22,6 +22,9 @@ abstract class BaseReaderAdapter<H : BasePageHolder<*>>(
private val differ = AsyncListDiffer(this, DiffCallback())
val hasItems: Boolean
get() = itemCount != 0
init {
stateRestorationPolicy = StateRestorationPolicy.PREVENT
}

View File

@@ -29,7 +29,11 @@ abstract class BaseReaderFragment<B : ViewBinding> : BaseFragment<B>(), ZoomCont
readerAdapter = onCreateAdapter()
viewModel.content.observe(viewLifecycleOwner) {
onPagesChanged(it.pages, restoredState ?: it.state)
var pendingState = restoredState ?: it.state
if (pendingState == null && it.pages.isNotEmpty() && readerAdapter?.hasItems != true) {
pendingState = viewModel.getCurrentState()
}
onPagesChanged(it.pages, pendingState)
restoredState = null
}
}

View File

@@ -2,13 +2,18 @@ package org.koitharu.kotatsu.reader.ui.pager.reversed
import androidx.viewpager2.widget.ViewPager2
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.reader.ui.ReaderState
import org.koitharu.kotatsu.reader.ui.pager.BasePagerReaderFragment
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
import javax.inject.Inject
@AndroidEntryPoint
class ReversedReaderFragment : BasePagerReaderFragment() {
@Inject
lateinit var settings: AppSettings
override fun onCreateAdvancedTransformer(): ViewPager2.PageTransformer = ReversedPageAnimTransformer()
override fun onCreateAdapter() = ReversedPagesAdapter(
@@ -19,6 +24,11 @@ class ReversedReaderFragment : BasePagerReaderFragment() {
exceptionResolver = exceptionResolver,
)
override fun onWheelScroll(axisValue: Float) {
val value = if (settings.isReaderControlAlwaysLTR) -axisValue else axisValue
super.onWheelScroll(value)
}
override fun switchPageBy(delta: Int) {
super.switchPageBy(-delta)
}

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager.webtoon
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Matrix
import android.graphics.Point
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
@@ -19,12 +20,16 @@ import android.widget.OverScroller
import androidx.core.animation.doOnEnd
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.ViewConfigurationCompat
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.widgets.ZoomControl
import org.koitharu.kotatsu.core.util.ext.getAnimationDuration
import kotlin.math.roundToInt
private const val MAX_SCALE = 2.5f
private const val MIN_SCALE = 0.5f
private const val FLING_RANGE = 20_000
class WebtoonScalingFrame @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@@ -36,6 +41,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
private val scaleDetector = ScaleGestureDetector(context, this)
private val gestureDetector = GestureDetectorCompat(context, GestureListener())
private val overScroller = OverScroller(context, AccelerateDecelerateInterpolator())
private val transformMatrix = Matrix()
private val matrixValues = FloatArray(9)
private val scale
@@ -49,6 +55,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
private val translateBounds = RectF()
private val targetHitRect = Rect()
private var animator: ValueAnimator? = null
private var pendingScroll = 0
var isZoomEnable = false
set(value) {
@@ -80,7 +87,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
overScroller.forceFinished(true)
}
gestureDetector.onTouchEvent(ev)
val consumed = gestureDetector.onTouchEvent(ev)
scaleDetector.onTouchEvent(ev)
// Offset event to inside the child view
@@ -88,11 +95,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
ev.offsetLocation(halfWidth - ev.x + targetHitRect.width() / 3, 0f)
}
// Send action cancel to avoid recycler jump when scale end
if (scaleDetector.isInProgress) {
ev.action = MotionEvent.ACTION_CANCEL
}
return super.dispatchTouchEvent(ev)
return consumed || scaleDetector.isInProgress || super.dispatchTouchEvent(ev)
}
override fun onGenericMotionEvent(event: MotionEvent): Boolean {
@@ -178,6 +181,10 @@ class WebtoonScalingFrame @JvmOverloads constructor(
scaleY = scale
translationX = transX
translationY = transY
if (pendingScroll != 0) {
nestedScrollBy(0, pendingScroll)
pendingScroll = 0
}
}
val newHeight = if (scale < 1f) (height / scale).toInt() else height
@@ -210,6 +217,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
else -> 0f
}
pendingScroll = if (scale > 1) (dy / scale).roundToInt() else 0
transformMatrix.postTranslate(dx, dy)
syncMatrixValues()
}
@@ -277,6 +285,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
private fun findTargetChild() = getChildAt(0) as WebtoonRecyclerView
private inner class GestureListener : GestureDetector.SimpleOnGestureListener(), Runnable {
private val prevPos = Point()
override fun onScroll(
e1: MotionEvent?,
@@ -294,7 +303,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
val newScale = if (scale != 1f) 1f else MAX_SCALE * 0.8f
ValueAnimator.ofFloat(scale, newScale).run {
interpolator = AccelerateDecelerateInterpolator()
duration = 300
duration = context.getAnimationDuration(R.integer.config_defaultAnimTime)
addUpdateListener {
scaleChild(it.animatedValue as Float, e.x, e.y)
}
@@ -311,15 +320,16 @@ class WebtoonScalingFrame @JvmOverloads constructor(
): Boolean {
if (scale <= 1) return false
prevPos.set(transX.toInt(), transY.toInt())
overScroller.fling(
transX.toInt(),
transY.toInt(),
prevPos.x,
prevPos.y,
velocityX.toInt(),
velocityY.toInt(),
translateBounds.left.toInt(),
translateBounds.right.toInt(),
translateBounds.top.toInt(),
translateBounds.bottom.toInt(),
translateBounds.top.toInt() - FLING_RANGE,
translateBounds.bottom.toInt() + FLING_RANGE,
)
postOnAnimation(this)
return true
@@ -328,9 +338,10 @@ class WebtoonScalingFrame @JvmOverloads constructor(
override fun run() {
if (overScroller.computeScrollOffset()) {
transformMatrix.postTranslate(
overScroller.currX - transX,
overScroller.currY - transY,
overScroller.currX.toFloat() - prevPos.x,
overScroller.currY.toFloat() - prevPos.y
)
prevPos.set(overScroller.currX, overScroller.currY)
invalidateTarget()
postOnAnimation(this)
}

View File

@@ -52,6 +52,7 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>(), SearchView.OnQuery
viewBinding.toolbar.updatePadding(
left = insets.left,
right = insets.right,
top = insets.top
)
viewBinding.container.updatePadding(
bottom = insets.bottom,

View File

@@ -1,9 +1,14 @@
package org.koitharu.kotatsu.settings
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import androidx.preference.Preference
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -12,6 +17,8 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.resolveFile
import org.koitharu.kotatsu.core.util.ext.tryLaunch
import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.local.data.LocalStorageManager
@@ -25,7 +32,7 @@ class DownloadsSettingsFragment :
BasePreferenceFragment(R.string.downloads),
SharedPreferences.OnSharedPreferenceChangeListener {
private val dozeHelper = DozeHelper(this)
private val dozeHelper = DozeHelper(this)
@Inject
lateinit var storageManager: LocalStorageManager
@@ -33,6 +40,10 @@ class DownloadsSettingsFragment :
@Inject
lateinit var downloadsScheduler: DownloadWorker.Scheduler
private val pickFileTreeLauncher = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
if (it != null) onDirectoryPicked(it)
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_downloads)
dozeHelper.updatePreference()
@@ -42,6 +53,7 @@ class DownloadsSettingsFragment :
super.onViewCreated(view, savedInstanceState)
findPreference<Preference>(AppSettings.KEY_LOCAL_STORAGE)?.bindStorageName()
findPreference<Preference>(AppSettings.KEY_LOCAL_MANGA_DIRS)?.bindDirectoriesCount()
findPreference<Preference>(AppSettings.KEY_PAGES_SAVE_DIR)?.bindPagesDirectory()
settings.subscribe(this)
}
@@ -63,6 +75,10 @@ class DownloadsSettingsFragment :
AppSettings.KEY_DOWNLOADS_WIFI -> {
updateDownloadsConstraints()
}
AppSettings.KEY_PAGES_SAVE_DIR -> {
findPreference<Preference>(AppSettings.KEY_PAGES_SAVE_DIR)?.bindPagesDirectory()
}
}
}
@@ -82,10 +98,27 @@ class DownloadsSettingsFragment :
dozeHelper.startIgnoreDoseActivity()
}
AppSettings.KEY_PAGES_SAVE_DIR -> {
if (!pickFileTreeLauncher.tryLaunch(settings.getPagesSaveDir(preference.context)?.uri)) {
Snackbar.make(
requireView(), R.string.operation_not_supported, Snackbar.LENGTH_SHORT,
).show()
}
true
}
else -> super.onPreferenceTreeClick(preference)
}
}
private fun onDirectoryPicked(uri: Uri) {
storageManager.takePermissions(uri)
val doc = DocumentFile.fromTreeUri(requireContext(), uri)?.takeIf {
it.canWrite()
}
settings.setPagesSaveDir(doc?.uri)
}
private fun Preference.bindStorageName() {
viewLifecycleScope.launch {
val storage = storageManager.getDefaultWriteableDir()
@@ -104,6 +137,16 @@ class DownloadsSettingsFragment :
}
}
private fun Preference.bindPagesDirectory() {
viewLifecycleScope.launch {
val df = withContext(Dispatchers.IO) {
settings.getPagesSaveDir(this@bindPagesDirectory.context)
}
summary = df?.getDisplayPath(this@bindPagesDirectory.context)
?: this@bindPagesDirectory.context.getString(androidx.preference.R.string.not_set)
}
}
private fun updateDownloadsConstraints() {
val preference = findPreference<Preference>(AppSettings.KEY_DOWNLOADS_WIFI)
viewLifecycleScope.launch {
@@ -119,4 +162,9 @@ class DownloadsSettingsFragment :
}
}
}
private fun DocumentFile.getDisplayPath(context: Context): String {
return uri.resolveFile(context)?.path ?: uri.toString()
}
}

View File

@@ -157,7 +157,7 @@ class SettingsActivity :
ACTION_SOURCES -> SourcesSettingsFragment()
ACTION_MANAGE_DOWNLOADS -> DownloadsSettingsFragment()
ACTION_SOURCE -> SourceSettingsFragment.newInstance(
intent.getSerializableExtraCompat(EXTRA_SOURCE) as? MangaSource ?: MangaSource.LOCAL,
intent.getSerializableExtraCompat(EXTRA_SOURCE) ?: MangaSource.LOCAL,
)
ACTION_MANAGE_SOURCES -> SourcesManageFragment()

View File

@@ -59,6 +59,7 @@ class RestoreDialogFragment : AlertDialogFragment<DialogRestoreBinding>(), OnLis
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
return super.onBuildDialog(builder)
.setTitle(R.string.restore_backup)
.setCancelable(false)
}

View File

@@ -46,7 +46,7 @@ class SourceAuthActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallba
if (!catchingWebViewUnavailability { setContentView(ActivityBrowserBinding.inflate(layoutInflater)) }) {
return
}
val source = intent?.getSerializableExtraCompat(EXTRA_SOURCE) as? MangaSource
val source = intent?.getSerializableExtraCompat<MangaSource>(EXTRA_SOURCE)
if (source == null) {
finishAfterTransition()
return

View File

@@ -10,7 +10,6 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.ifNullOrEmpty
import javax.inject.Inject
@Reusable
class SyncSettings(
context: Context,
private val account: Account?,

View File

@@ -2,6 +2,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path

View File

@@ -17,8 +17,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:minHeight="16dp"
android:paddingHorizontal="6dp"
android:textSize="12sp"
android:visibility="gone"
tools:visibility="visible" />

View File

@@ -8,8 +8,7 @@
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"

View File

@@ -4,20 +4,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingVertical="?dialogPreferredPadding">
<TextView
android:id="@+id/textView_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="?dialogPreferredPadding"
android:paddingBottom="@dimen/margin_normal"
android:text="@string/restore_backup"
android:textAppearance="?textAppearanceTitleLarge" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="match_parent"
@@ -31,7 +22,8 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:scrollIndicators="top|bottom"
android:visibility="gone"

View File

@@ -42,7 +42,7 @@
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
<TextView
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
@@ -52,12 +52,13 @@
android:ellipsize="end"
android:maxLines="5"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<TextView
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
@@ -67,6 +68,7 @@
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_title"
@@ -172,8 +174,8 @@
android:ellipsize="end"
android:paddingVertical="2dp"
android:singleLine="true"
tools:text="@string/approximate_reading_time"
android:textAppearance="?attr/textAppearanceBodyLarge" />
android:textAppearance="?attr/textAppearanceBodyLarge"
tools:text="@string/approximate_reading_time" />
<TextView
android:id="@+id/approximate_read_time"

View File

@@ -28,7 +28,8 @@
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodyLarge"
tools:text="@tools:sample/lorem[15]" />
tools:text="@tools:sample/lorem[15]"
tools:textColor="?android:textColorPrimary" />
<TextView
android:id="@+id/textView_description"
@@ -38,7 +39,8 @@
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodySmall"
tools:text="05.10.2021 • Scanlator" />
tools:text="05.10.2021 • Scanlator"
tools:textColor="?android:textColorTertiary" />
</LinearLayout>
<ImageView

View File

@@ -12,4 +12,9 @@
android:icon="@drawable/ic_grid"
android:title="@string/pages" />
<item
android:id="@+id/action_forget"
android:icon="@drawable/ic_delete"
android:title="@string/remove_from_history" />
</menu>

View File

@@ -78,15 +78,15 @@
<string name="search_history_cleared">Гісторыя пошуку ачышчана</string>
<string name="clear_search_history">Ачысціць гісторыю пошуку</string>
<string name="gestures_only">Толькі жэсты</string>
<string name="internal_storage">Унутранае сховішча</string>
<string name="internal_storage">Ўнутранае сховішча</string>
<string name="external_storage">Знешняе сховішча</string>
<string name="domain">Дамен</string>
<string name="app_update_available">Даступна абнаўленне праграмы</string>
<string name="open_in_browser">Адкрыць у браўзеры</string>
<string name="large_manga_save_confirm">У гэтай манге %s. Вы ўпэўненыя, што хочаце захаваць іх усё\?</string>
<string name="large_manga_save_confirm">Ў гэтай манге %s. Вы ўпэўненыя, што хочаце захаваць іх усё?</string>
<string name="save_manga">Захаваць мангу</string>
<string name="notifications">Паведамленні</string>
<string name="enabled_d_of_d">Уключана %1$d з %2$d</string>
<string name="enabled_d_of_d">Ўключана %1$d з %2$d</string>
<string name="new_chapters">Новыя раздзелы</string>
<string name="download">Спампаваць</string>
<string name="notifications_settings">Налады апавяшчэнняў</string>
@@ -104,7 +104,7 @@
<string name="other_storage">Іншае сховішча</string>
<string name="done">Гатова</string>
<string name="all_favourites">Усе абраныя</string>
<string name="favourites_category_empty">У гэтай катэгорыі нічога няма</string>
<string name="favourites_category_empty">Ў гэтай катэгорыі нічога няма</string>
<string name="read_later">Прачытаць пазней</string>
<string name="updates">Абнаўленні</string>
<string name="text_feed_holder">Тут паказваюцца новыя раздзелы таго, што вы чытаеце</string>
@@ -118,7 +118,7 @@
<string name="feed_will_update_soon">Абнаўленне хутка пачнецца</string>
<string name="track_sources">Правяраць абнаўленні мангі</string>
<string name="dont_check">Не правяраць</string>
<string name="enter_password">Увядзіце пароль</string>
<string name="enter_password">Ўвядзіце пароль</string>
<string name="wrong_password">Няверны пароль</string>
<string name="protect_application">Абараніць праграму</string>
<string name="protect_application_summary">Запытваць пароль пры запуску праграмы</string>
@@ -131,7 +131,7 @@
<string name="right_to_left">Справа налева</string>
<string name="create_category">Стварыць катэгорыю</string>
<string name="scale_mode">Маштабаванне</string>
<string name="zoom_mode_fit_center">Умясціць у экран</string>
<string name="zoom_mode_fit_center">Ўмясціць ў экран</string>
<string name="zoom_mode_fit_height">Падагнаць па вышыні</string>
<string name="zoom_mode_fit_width">Падагнаць па шырыні</string>
<string name="zoom_mode_keep_start">Зыходны памер</string>
@@ -147,7 +147,7 @@
<string name="data_restored_with_errors">Данныя адноўлены, але ўзніклі некаторыя памылкі</string>
<string name="backup_information">Вы можаце стварыць рэзервовую копію абранага і гісторыі і потым аднавіць іх</string>
<string name="just_now">Толькі што</string>
<string name="yesterday">Учора</string>
<string name="yesterday">Ўчора</string>
<string name="long_ago">Даўно</string>
<string name="group">Групаваць</string>
<string name="today">Сёння</string>
@@ -161,8 +161,8 @@
<string name="clear_feed">Ачысціць стужку</string>
<string name="text_clear_updates_feed_prompt">Уся гісторыя абнаўленняў будзе ачышчана і яе нельга будзе вярнуць. Вы ўпэўненыя\?</string>
<string name="check_for_new_chapters">Праверка новых глаў</string>
<string name="reverse">У адваротным парадку</string>
<string name="sign_in">Увайсці</string>
<string name="reverse">Ў адваротным парадку</string>
<string name="sign_in">Ўвайсці</string>
<string name="auth_required">Для прагляду гэтага кантэнту патрабуецца аўтарызацыя</string>
<string name="default_s">Прадвызначаны: %s</string>
<string name="next">Далей</string>
@@ -181,7 +181,7 @@
<string name="text_search_holder_secondary">Паспрабуйце перафармуляваць запыт.</string>
<string name="text_empty_holder_primary">Неяк тут пуста…</string>
<string name="chapter_is_missing">Глава адсутнічае</string>
<string name="queued">У чарзе</string>
<string name="queued">Ў чарзе</string>
<string name="about_app_translation_summary">Дапамагчы з перакладам праграмы</string>
<string name="about_app_translation">Пераклад</string>
<string name="text_clear_cookies_prompt">Вы выйдзеце з усіх крыніц, у якіх вы аўтарызаваны</string>
@@ -193,7 +193,7 @@
<string name="system_default">Па змаўчанні</string>
<string name="exclude_nsfw_from_history">Выключыць NSFW мангу з гісторыі</string>
<string name="show_pages_numbers">Паказваць нумары старонак</string>
<string name="enabled_sources">Уключаныя крыніцы</string>
<string name="enabled_sources">Ўключаныя крыніцы</string>
<string name="available_sources">Даступныя крыніцы</string>
<string name="computing_">Вылічэнні…</string>
<string name="screenshots_allow">Дазваляць</string>
@@ -202,12 +202,12 @@
<string name="screenshots_block_nsfw">Забараніць для NSFW</string>
<string name="filter_load_error">Немагчыма загрузіць спіс жанраў</string>
<string name="disabled">Адключаны</string>
<string name="enabled">Уключаны</string>
<string name="enabled">Ўключаны</string>
<string name="exclude_nsfw_from_suggestions">Ня прапаноўваць NSFW мангу</string>
<string name="text_suggestion_holder">Пачніце чытаць мангу, і вы атрымаеце персаналізаваныя прапановы</string>
<string name="suggestions_info">Усе даныя аналізуюцца толькі лакальна на гэтай прыладзе і нікуды не адпраўляюцца.</string>
<string name="suggestions_summary">Прапануеце мангу, заснаваную на вашых перавагах</string>
<string name="suggestions_enable">Уключыць прапановы</string>
<string name="suggestions_enable">Ўключыць прапановы</string>
<string name="suggestions">Прапанова</string>
<string name="onboard_text">Выберыце мову, на якой вы хочаце чытаць мангу. Вы зможаце змяніць гэта пазней.</string>
<string name="reset_filter">Скінуць фільтр</string>
@@ -220,7 +220,7 @@
<string name="various_languages">Розныя мовы</string>
<string name="search_chapters">Знайсці главу</string>
<string name="percent_string_pattern">%1$s%%</string>
<string name="chapters_empty">У гэтай манзе няма глаў</string>
<string name="chapters_empty">Ў гэтай манге няма раздзелаў</string>
<string name="hide">Схаваць</string>
<string name="appearance">Знешні выгляд</string>
<string name="disable_all">Выключыць усё</string>
@@ -233,7 +233,7 @@
<string name="check_new_chapters_title">Правяраць новыя главы і паведамляць пра іх</string>
<string name="show_notification_new_chapters_on">Вы будзеце атрымліваць апавяшчэнні пра абнаўленні мангі, якую вы чытаеце</string>
<string name="show_notification_new_chapters_off">Вы не будзеце атрымліваць паведамленні, але новыя главы будуць паказаны ў спісе</string>
<string name="notifications_enable">Уключыць апавяшчэнні</string>
<string name="notifications_enable">Ўключыць апавяшчэнні</string>
<string name="bookmarks">Закладкі</string>
<string name="bookmark_removed">Закладка выдалена</string>
<string name="bookmark_added">Закладка дадазена</string>
@@ -244,7 +244,7 @@
<string name="new_sources_text">Даступныя новыя крыніцы мангі</string>
<string name="download_slowdown">Запавольванне спампоўкі</string>
<string name="suggestions_excluded_genres">Выключыць жанры</string>
<string name="suggestions_excluded_genres_summary">Укажыце жанры, якія вы не хочаце бачыць у рэкамендацыях</string>
<string name="suggestions_excluded_genres_summary">Укажыце жанры, якія вы не хочаце бачыць ў рэкамендацыях</string>
<string name="text_delete_local_manga_batch">Выдаліць выбраныя элементы з прылады назаўжды\?</string>
<string name="removal_completed">Выдаленне завершана</string>
<string name="download_slowdown_summary">Дапамагае пазбегнуць блакіроўкі па IP-адрасе</string>
@@ -303,7 +303,7 @@
<string name="theme_name_dynamic">Дынамічны</string>
<string name="color_theme">Каляровая гама</string>
<string name="language">Мова</string>
<string name="account_already_exists">Уліковы запіс ужо існуе</string>
<string name="account_already_exists">Ўліковы запіс ужо існуе</string>
<string name="back">Назад</string>
<string name="sync">Сінхранізацыя</string>
<string name="sync_title">Сінхранізацыя вашых дадзеных</string>
@@ -313,7 +313,7 @@
<string name="manga_error_description_pattern">Дэталі памылкі:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1. Паспрабуйце &lt;a href=%2$s&gt;адкрыць мангу ў вэб-браўзеры&lt;/a&gt;, каб пераканацца, што яна даступная ў крыніцы&lt;br&gt;2. Упэўніцеся, што вы выкарыстоўваеце &lt;a href=kotatsu://about&gt;апошнюю версію Kotatsu&lt;/a&gt;&lt;br&gt;3. Калі ён даступны, адпраўце распрацоўнікам справаздачу аб памылцы.</string>
<string name="history_shortcuts">Паказаць апошнія ярлыкі мангі</string>
<string name="history_shortcuts_summary">Зрабіце нядаўнюю мангу даступнай, доўга націскаючы на значок праграмы</string>
<string name="reader_control_ltr_summary">Дакрананне да правага краю або націсканне правай клавішы заўсёды пераключае на наступную старонку</string>
<string name="reader_control_ltr_summary">Навігацыя \"Далей\" заўсёды прыводзіць да наступнай старонцы пры выкарыстанні мышы і клавіятуры.</string>
<string name="reader_control_ltr">Эрганамічны упраўленне чытаннем</string>
<string name="color_correction">Карэкцыя колеру</string>
<string name="brightness">Яркасць</string>
@@ -322,9 +322,9 @@
<string name="color_correction_hint">Выбраныя налады колеру будуць запомнены для гэтай мангі</string>
<string name="text_unsaved_changes_prompt">Захаваць ці адхіліць незахаваныя змены\?</string>
<string name="discard">Адмяніць</string>
<string name="enable_logging">Уключыць запіс</string>
<string name="enable_logging">Ўключыць запіс</string>
<string name="share_logs">Падзяліцца логамі</string>
<string name="enable_logging_summary">Запішыце некаторыя дзеянні для адладкі. Уключайце толькі калі ведаеце, што робіце</string>
<string name="enable_logging_summary">Запішыце некаторыя дзеянні для адладкі. Ўключайце толькі калі ведаеце, што робіце</string>
<string name="show_suspicious_content">Паказаць падазроны кантэнт</string>
<string name="text_shelf_holder_primary">Ваша манга будзе адлюстроўвацца тут</string>
<string name="text_shelf_holder_secondary">Знайдзіце, што пачытаць, у раздзеле «Агляд»</string>
@@ -395,7 +395,7 @@
<string name="downloads_wifi_only_summary">Спыніць загрузку пры пераключэнні на мабільную сетку</string>
<string name="suggestions_notifications_summary">Часам паказваць апавяшчэнні з прапанаванай мангай</string>
<string name="more">Больш</string>
<string name="enable">Уключыць</string>
<string name="enable">Ўключыць</string>
<string name="cancel_all_downloads_confirm">Усе актыўныя спампоўкі будуць адменены, часткова спампаваныя даныя будуць страчаны</string>
<string name="suggestions_enable_prompt">Хочаце атрымліваць персаналізаваныя прапановы мангі\?</string>
<string name="suggestion_manga">Прапанова: %s</string>
@@ -431,7 +431,7 @@
<string name="restore_summary">Аднавіць раней створаную рэзервовую копію</string>
<string name="reader_info_bar_summary">Паказаць бягучы час і ход чытання ў верхняй частцы экрана</string>
<string name="pages_animation_summary">Анімацыя перагортвання старонак</string>
<string name="clear_source_cookies_summary">Выдаліць файлы cookie толькі для вызначанага дамена. У большасці выпадкаў гэта робіць аўтарызацыю несапраўднай</string>
<string name="clear_source_cookies_summary">Выдаліць файлы cookie толькі для вызначанага дамена. Ў большасці выпадкаў гэта робіць аўтарызацыю несапраўднай</string>
<string name="download_option_whole_manga">Манга цалкам</string>
<string name="local_manga_directories">Лакальныя каталогі мангі</string>
<string name="download_option_all_chapters">Усе раздзелы з перакладам %s</string>
@@ -456,16 +456,16 @@
<string name="color_black">Чорны</string>
<string name="background">Фон</string>
<string name="data_not_restored_text">Пераканайцеся, што вы выбралі правільны файл рэзервовай копіі</string>
<string name="search_hint">Увядзіце назву мангі, жанр або назву крыніцы</string>
<string name="search_hint">Ўвядзіце назву мангі, жанр або назву крыніцы</string>
<string name="progress">Прагрэс</string>
<string name="manage_categories">Упраўленне катэгорыямі</string>
<string name="manage_categories">Кіраванне катэгорыямі</string>
<string name="order_added">Дададзена</string>
<string name="view_list">Прагляд спісу</string>
<string name="show">Паказаць</string>
<string name="captcha_required_summary">Для правільнай працы %s патрабуецца праверка captcha</string>
<string name="languages">Мовы</string>
<string name="unknown">Невядомы</string>
<string name="in_progress">У працэсе</string>
<string name="in_progress">Ў працэсе</string>
<string name="disable_nsfw">Адключыць NSFW</string>
<string name="too_many_requests_message">Занадта шмат запытаў. Паўтарыце спробу пазней</string>
<string name="related_manga_summary">Паказаць спіс звязанай мангі. У некаторых выпадках ён можа быць недакладным або адсутнічаць</string>
@@ -478,7 +478,7 @@
<string name="items_limit_exceeded">Больш нельга дадаваць элементы</string>
<string name="directories">Каталогі</string>
<string name="main_screen_sections">Раздзелы галоўнага экрана</string>
<string name="to_top">Уверх</string>
<string name="to_top">Ўверх</string>
<string name="zoom_in">Павялічыць</string>
<string name="reader_zoom_buttons_summary">Ці паказваць кнопкі кіравання маштабаваннем у правым ніжнім куце</string>
<string name="reader_zoom_buttons">Паказаць кнопкі маштабавання</string>
@@ -496,7 +496,7 @@
<string name="online_variant">Анлайн варыянт</string>
<string name="frequency_every_day">Кожны дзень</string>
<string name="backup_frequency">Частата стварэння рэзервовых копій</string>
<string name="periodic_backups_enable">Уключыць перыядычнае рэзервовае капіраванне</string>
<string name="periodic_backups_enable">Ўключыць перыядычнае рэзервовае капіраванне</string>
<string name="frequency_every_2_days">Кожныя 2 дні</string>
<string name="frequency_once_per_week">Раз на тыдзень</string>
<string name="periodic_backups">Перыядычнае рэзервовае капіраванне</string>
@@ -514,10 +514,10 @@
<string name="catalog">Каталог</string>
<string name="manage_sources">Кіраванне крыніцамі</string>
<string name="no_manga_sources_found">Па вашаму запыту не знойдзена даступных крыніц мангі</string>
<string name="manual">Уручную</string>
<string name="manual">Ўручную</string>
<string name="source_enabled">Крыніца ўключана</string>
<string name="disable_nsfw_summary">Адключыць крыніцы NSFW і схавайць мангу для дарослых са спісу, калі гэта магчыма</string>
<string name="no_manga_sources_catalog_text">У гэтым раздзеле няма даступных крыніц, ці ўсе яны маглі быць ужо дададзены.
<string name="no_manga_sources_catalog_text">Ў гэтым раздзеле няма даступных крыніц, ці ўсе яны маглі быць ужо дададзены.
\nСачыце за абнаўленнямі</string>
<string name="available_d">Даступна: %1$d</string>
<string name="content_type_other">Іншае</string>
@@ -542,7 +542,7 @@
<string name="welcome_text">Выберыце, якія крыніцы змесціва вы хочаце ўключыць. Гэта таксама можна наладзіць пазней у наладах</string>
<string name="restore">Аднавіць</string>
<string name="backup_date_">Дата стварэння рэзервовай копіі: %s</string>
<string name="sync_auth">Увайдзіце, каб сінхранізаваць уліковы запіс</string>
<string name="sync_auth">Ўвайдзіце, каб сінхранізаваць ўліковы запіс</string>
<string name="by_name_reverse">Імя (зваротнае)</string>
<string name="content_rating">Рэйтынг кантэнту</string>
<string name="genres_exclude">Выключыць жанры</string>
@@ -565,7 +565,7 @@
<string name="prev_page">Папярэдняя старонка</string>
<string name="next_page">Наступная старонка</string>
<string name="reader_actions">Дзеянні ў рэжыме чытання</string>
<string name="switch_pages_volume_buttons">Уключыць кнопкі гучнасці</string>
<string name="switch_pages_volume_buttons">Ўключыць кнопкі гучнасці</string>
<string name="switch_pages_volume_buttons_summary">Выкарыстоўвайце кнопкі гучнасці для гартання старонак</string>
<string name="tap_action">Дзеянне пры націску</string>
<string name="long_tap_action">Дзеянне пры доўгім націску</string>
@@ -584,4 +584,8 @@
<string name="default_webtoon_zoom_out">Аддаленне ў рэжыме манхвы</string>
<string name="fullscreen_mode">Поўнаэкранны рэжым</string>
<string name="reader_fullscreen_summary">Схаваць інтэрфейс сістэмы</string>
<string name="suggestions_unavailable_text">Функцыя прапаноў адключана</string>
<string name="check_for_new_chapters_disabled">Праверка новых раздзелаў адключана</string>
<string name="reading_time_estimation">Паказаць прыблізны час чытання</string>
<string name="reading_time_estimation_summary">Значэнне ацэнкі часу можа быць недакладным</string>
</resources>

View File

@@ -584,4 +584,8 @@
<string name="default_webtoon_zoom_out">Alejar el zoom del webtoon predeterminado</string>
<string name="fullscreen_mode">Modo de pantalla completa</string>
<string name="reader_fullscreen_summary">Ocultar las barras de estado y navegación del sistema</string>
<string name="reading_time_estimation">Mostrar el iempo estimado de lectura</string>
<string name="reading_time_estimation_summary">El valor estimado puede ser inexacto</string>
<string name="check_for_new_chapters_disabled">La búsqueda de nuevos capítulos está desactivada</string>
<string name="suggestions_unavailable_text">Sugerencias desactivadas</string>
</resources>

View File

@@ -35,4 +35,14 @@
<item quantity="many">Il y a %1$d mois</item>
<item quantity="other">Il y a %1$d mois</item>
</plurals>
<plurals name="hours">
<item quantity="one">heure</item>
<item quantity="many">heures</item>
<item quantity="other">heures</item>
</plurals>
<plurals name="minutes">
<item quantity="one">minute</item>
<item quantity="many">minutes</item>
<item quantity="other">minutes</item>
</plurals>
</resources>

View File

@@ -79,7 +79,7 @@
<string name="pages_animation">Animation de page</string>
<string name="recent_manga">Récents</string>
<string name="manga_shelf">Étagère</string>
<string name="text_local_holder_secondary">Enregistrez-le à partir de sources en ligne ou importez des fichiers.</string>
<string name="text_local_holder_secondary">Enregistrez quelque chose à partir d\'un catalogue en ligne ou importez-le à partir d\'un fichier.</string>
<string name="text_local_holder_primary">Sauvegardez d\'abord quelque chose</string>
<string name="text_history_holder_secondary">Trouver quoi lire dans la section « Explorer »</string>
<string name="text_history_holder_primary">Ce que vous lisez sera affiché ici</string>
@@ -112,7 +112,7 @@
<string name="taps_on_edges">Appuis au bord</string>
<string name="switch_pages">Changer de pages</string>
<string name="reader_settings">Paramètres du lecteur</string>
<string name="text_delete_local_manga">Supprimer « %s » de l\'appareil de façon permanente \?</string>
<string name="text_delete_local_manga">Supprimer « %s » de l\'appareil de façon permanente?</string>
<string name="delete_manga">Supprimer le manga</string>
<string name="search_on_s">Rechercher sur %s</string>
<string name="grid_size">Taille de la grille</string>
@@ -528,8 +528,8 @@
<string name="backups_output_directory">Sauvegardes répertoire de sortie</string>
<string name="suggest_new_sources_summary">Prompt pour permettre des sources nouvellement ajoutées après la mise à jour de l\'application</string>
<string name="content_type_other">Autre</string>
<string name="state_upcoming">A venir</string>
<string name="welcome_text">S\'il vous plaît choisissez les sources que vous souhaitez activer. Cela peux aussi être fait plus tard dans les paramètres</string>
<string name="state_upcoming">À venir</string>
<string name="welcome_text">Veuillez choisir les sources que vous souhaitez activer. Cela peut aussi être configuré plus tard dans les paramètres</string>
<string name="sync_auth">Connectez-vous pour synchroniser le compte</string>
<string name="skip">Passer</string>
<string name="restore">Restaurer</string>
@@ -545,9 +545,37 @@
<string name="genres_search_hint">Commence a écrit un nom de genre</string>
<string name="downloads_settings_info">Vous pouvez activer la vitesse de téléchargement réduite individuellement pour chaque source de manga dans les paramètres si vous rencontrez des problèmes de bloquage avec le serveur.</string>
<string name="backup_date_">Date de sauvegarde: %s</string>
<string name="by_name_reverse">Nom réservé</string>
<string name="mark_as_completed">Marque comme terminé</string>
<string name="mark_as_completed_prompt">Marqué le manga sélectionné en terminé?
<string name="by_name_reverse">Nom inversé</string>
<string name="mark_as_completed">Marquer comme terminé</string>
<string name="mark_as_completed_prompt">Marquer le manga sélectionné comme terminé?
\n
\nAttention: la progression actuelle sera perdu.</string>
\nAttention: la progression actuelle sera perdue.</string>
<string name="approximate_reading_time">Temps de lecture approximatif</string>
<string name="incognito_mode_hint">Votre progression de lecture ne sera pas sauvegardée</string>
<string name="last_read">Dernier lu</string>
<string name="vertical">Vertical</string>
<string name="email_password_enter_hint">Entrez votre email et mot de passe pour continuer</string>
<string name="grayscale">Niveaux de gris</string>
<string name="error_filter_locale_genre_not_supported">Le filtrage à la fois par genres et par langues n\'est pas supporté par cette source</string>
<string name="error_filter_states_genre_not_supported">Le filtrage à la fois par genres et par statut n\'est pas supporté par cette source</string>
<string name="approximate_remaining_time">Temps restant approximatif</string>
<string name="volume_">Volume %d</string>
<string name="volume_unknown">Volume inconnu</string>
<string name="show_menu">Afficher le menu</string>
<string name="toggle_ui">Afficher/cacher UI</string>
<string name="prev_chapter">Chapitre précèdent</string>
<string name="next_chapter">Chapitre suivant</string>
<string name="prev_page">Page précédente</string>
<string name="next_page">Page suivante</string>
<string name="switch_pages_volume_buttons">Activer les boutons de volume</string>
<string name="switch_pages_volume_buttons_summary">Utiliser les boutons de volume pour changer de page</string>
<string name="none">Aucun</string>
<string name="config_reset_confirm">Revenir aux paramètres par défaut?
\nCette action ne pourra pas être annulée.</string>
<string name="use_two_pages_landscape">Utiliser la disposition pages doubles en orientation paysage (bêta)</string>
<string name="fullscreen_mode">Mode plein écran</string>
<string name="category_hidden_done">Cette catégorie a été cachée du menu principal et est accessible via Menu → Gérer les catégories</string>
<string name="two_pages">Pages doubles</string>
<string name="reading_time_estimation">Afficher le temps de lecture estimé</string>
<string name="reading_time_estimation_summary">Le temps estimé peut être inexact</string>
</resources>

View File

@@ -21,4 +21,10 @@
<plurals name="items">
<item quantity="other">%1$d item</item>
</plurals>
<plurals name="hours">
<item quantity="other">%1$d jam</item>
</plurals>
<plurals name="minutes">
<item quantity="other">%1$d minit</item>
</plurals>
</resources>

View File

@@ -308,4 +308,10 @@
<string name="update">Kemas kini</string>
<string name="feed_will_update_soon">Kemaskini siaran akan bermula sebentar</string>
<string name="dont_check">Jangan semak</string>
<string name="advanced">lanjutan</string>
<string name="default_section">Bahagian lalai</string>
<string name="manga_list">Senarai manga</string>
<string name="error_corrupted_file">Data tidak sah dikembalikan atau fail rosak</string>
<string name="on_device">Pada peranti</string>
<string name="directories">Panduan</string>
</resources>

View File

@@ -18,7 +18,7 @@
<plurals name="new_chapters">
<item quantity="one">%1$d novo capítulo</item>
<item quantity="many">%1$d novos capítulos</item>
<item quantity="other">%1$d capítulos novos</item>
<item quantity="other">%1$d novos capítulos</item>
</plurals>
<plurals name="months_ago">
<item quantity="one">%1$d mês atrás</item>

View File

@@ -45,7 +45,7 @@
<string name="share_image">Compartilhar imagem</string>
<string name="_import">Importar</string>
<string name="updated">Atualizado</string>
<string name="delete">Delete</string>
<string name="delete">Excluir</string>
<string name="operation_not_supported">Essa operação não é suportada</string>
<string name="clear_pages_cache">Limpar cache de página</string>
<string name="text_file_sizes">B|kB|MB|GB|TB</string>
@@ -164,7 +164,7 @@
<string name="vibration">Vibração</string>
<string name="cannot_find_available_storage">Sem armazenamento disponível</string>
<string name="favourites_categories">Categorias favoritas</string>
<string name="text_history_holder_secondary">Encontre o que ler na aba «Explorar»</string>
<string name="text_history_holder_secondary">Encontre o que ler na seção «Explorar»</string>
<string name="text_local_holder_secondary">Salve-o de catálogos online ou importe de um arquivo.</string>
<string name="recent_manga">Recente</string>
<string name="other_storage">Outro armazenamento</string>
@@ -584,4 +584,8 @@
<string name="default_webtoon_zoom_out">Diminuir para zoom padrão do webtoon</string>
<string name="fullscreen_mode">Modo de tela cheia</string>
<string name="reader_fullscreen_summary">Ocultar a barra de status e navegação</string>
<string name="suggestions_unavailable_text">O recurso de sugestões está desativado</string>
<string name="check_for_new_chapters_disabled">A verificação de novos capítulos está desativada</string>
<string name="reading_time_estimation">Mostrar tempo estimado de leitura</string>
<string name="reading_time_estimation_summary">O valor do tempo estimado pode ser impreciso</string>
</resources>

View File

@@ -327,7 +327,7 @@
<string name="manga_error_description_pattern">Сведения об ошибке:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1. Попробуйте &lt;a href=%2$s&gt;открыть мангу в веб-браузере&lt;/a&gt;, чтобы убедиться, что она доступна в источнике&lt;br&gt;2. Убедитесь, что вы используете &lt;a href=kotatsu://about&gt;последнюю версию Kotatsu&lt;/a&gt;&lt;br&gt;3. Если возможно, отправьте отчёт об ошибке разработчикам.</string>
<string name="history_shortcuts">Показывать ярлыки последней прочитанной манги</string>
<string name="history_shortcuts_summary">Сделать недавно прочитанную мангу доступной по долгому нажатию на иконку приложения</string>
<string name="reader_control_ltr_summary">Нажатие на правый край или нажатие правой клавиши всегда переключает на следующую страницу</string>
<string name="reader_control_ltr_summary">Навигация «Далее» всегда приводит к следующей странице при использовании мыши и клавиатуры.</string>
<string name="reader_control_ltr">Эргономичное управление режимом чтения</string>
<string name="reset">Сбросить</string>
<string name="discard">Отклонить</string>
@@ -586,4 +586,6 @@
<string name="reader_fullscreen_summary">Скрывать интерфейс системы</string>
<string name="reading_time_estimation">Отображать предполагаемое время чтения</string>
<string name="reading_time_estimation_summary">Данное значение может быть неточным</string>
<string name="check_for_new_chapters_disabled">Проверка новых глав отключена</string>
<string name="suggestions_unavailable_text">Функция предложения отключена</string>
</resources>

View File

@@ -4,7 +4,7 @@
<string name="error_occurred">Грешка се појавила</string>
<string name="favourites">Омиљено</string>
<string name="history">Историја</string>
<string name="network_error">Мрежна грешка</string>
<string name="network_error">Грешка на мрежи</string>
<string name="details">Детаљи</string>
<string name="chapters">Поглавља</string>
<string name="list">Листа</string>
@@ -569,7 +569,7 @@
<string name="remaining_time_pattern">%1$s %2$s</string>
<string name="show_menu">Прикажи изборник</string>
<string name="prev_chapter">Претходна поглавља</string>
<string name="tap_action">Радња додира</string>
<string name="tap_action">Радња при додиру</string>
<string name="config_reset_confirm">Вратити подешавања на подразумеване вредности? Ова радња се не може опозвати.</string>
<string name="two_pages">Две стране</string>
<string name="reader_actions_summary">Конфигуриши радње за области екрана које се могу додирнути</string>
@@ -580,4 +580,12 @@
<string name="reader_actions">Радње читаоца</string>
<string name="volume_unknown">Непозната запремина</string>
<string name="last_read">Последње прочитано</string>
<string name="volume_">Количина %d</string>
<string name="default_webtoon_zoom_out">Подразумевано умањивање вебтоон-а</string>
<string name="reader_fullscreen_summary">Сакриј статус система и траке за навигацију</string>
<string name="suggestions_unavailable_text">Предлози су искључени</string>
<string name="reading_time_estimation">Прикажи процењено време читања</string>
<string name="reading_time_estimation_summary">Вредност процене времена може бити нетачна</string>
<string name="check_for_new_chapters_disabled">Провера нових поглавља је искључена</string>
<string name="fullscreen_mode">Режим целог екрана</string>
</resources>

View File

@@ -344,7 +344,7 @@
<string name="server_error">Sunucu hatası (%1$d). Lütfen daha sonra tekrar deneyin</string>
<string name="saved_manga">Kaydedilen mangalar</string>
<string name="history_shortcuts_summary">Uygulama simgesine uzun basarak son mangaları kullanılabilir hale getirin</string>
<string name="reader_control_ltr_summary">Sağ kenara dokunulduğunda veya sağ tuşa basıldığında her zaman bir sonraki sayfaya geçilir</string>
<string name="reader_control_ltr_summary">Fare ve klavye kullanırken sonraki seçeneği sizi her zaman bir sonraki sayfaya götürür.</string>
<string name="source_disabled">Kaynak devre dışı</string>
<string name="prefetch_content">İçerik ön yüklemesi</string>
<string name="mark_as_current">Geçerli olarak işaretle</string>
@@ -584,4 +584,8 @@
<string name="default_webtoon_zoom_out">Öntanımlı webtoon uzaklaştırması</string>
<string name="fullscreen_mode">Tam ekran modu</string>
<string name="reader_fullscreen_summary">Sistem durumunu ve gezinme çubuklarını gizle</string>
<string name="suggestions_unavailable_text">Öneriler özelliği devre dışı</string>
<string name="check_for_new_chapters_disabled">Yeni bölümlerin denetlenmesi devre dışı</string>
<string name="reading_time_estimation">Tahmini okuma süresini göster</string>
<string name="reading_time_estimation_summary">Süre tahmin değeri yanlış olabilir</string>
</resources>

View File

@@ -327,7 +327,7 @@
<string name="manga_error_description_pattern">Деталі помилки:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1. Спробуйте &lt;a href=%2$s&gt;відкрити манґу у веб-браузері&lt;/a&gt;, щоб переконатися, що вона доступна в джерелі&lt;br&gt;2. Переконайтеся, що ви використовуєте &lt;a href=kotatsu://about&gt;останню версію Kotatsu&lt;/a&gt;&lt;br&gt;3. Якщо він доступний, надішліть звіт про помилку розробникам.</string>
<string name="history_shortcuts">Показувати ярлики останньої прочитаної манґи</string>
<string name="history_shortcuts_summary">Зробити нещодавно прочитану манґу доступною за довгим натисканням на іконку застосунку</string>
<string name="reader_control_ltr_summary">Натискання на правий край або натискання правої клавіші завжди переходить на наступну сторінку</string>
<string name="reader_control_ltr_summary">Навігація «Далі» завжди веде до наступної сторінки під час використання миші та клавіатури.</string>
<string name="reader_control_ltr">Ергономічне керування режимом читання</string>
<string name="brightness">Яскравість</string>
<string name="color_correction">Корекція кольору</string>
@@ -586,4 +586,6 @@
<string name="default_webtoon_zoom_out">Віддалення у режимі манхви</string>
<string name="reading_time_estimation">Відображати передбачуваний час читання</string>
<string name="reading_time_estimation_summary">Це значення може бути неточним</string>
<string name="check_for_new_chapters_disabled">Перевірка нових глав вимкнена</string>
<string name="suggestions_unavailable_text">Функція пропозицій вимкнена</string>
</resources>

View File

@@ -15,7 +15,7 @@
<string name="cookies_cleared">已清除所有 Cookies</string>
<string name="data_restored_success">数据已全部恢复</string>
<string name="silent">无声</string>
<string name="preparing_">准备…</string>
<string name="preparing_">准备</string>
<string name="file_not_found">未找到文件</string>
<string name="yesterday">昨天</string>
<string name="backup_information">可创建历史和收藏的备份并开始恢复</string>
@@ -33,13 +33,13 @@
<string name="suggestions_info">所有数据都在本地设备上进行分析,不会发送到其他地方。</string>
<string name="never">从不</string>
<string name="show_notification_new_chapters_on">发送正在阅读漫画的更新通知</string>
<string name="nsfw">18+</string>
<string name="nsfw">R18</string>
<string name="various_languages">多语言</string>
<string name="search_chapters">查找章节</string>
<string name="suggestions_excluded_genres">排除分类</string>
<string name="suggestions_updating">正在更新漫画推荐</string>
<string name="check_new_chapters_title">检查新章节并通知结果</string>
<string name="details">作品详情</string>
<string name="details">详情</string>
<string name="detailed_list">卡片</string>
<string name="grid">网格</string>
<string name="list_mode">视图选项</string>
@@ -147,7 +147,7 @@
<string name="clear_updates_feed">清除订阅更新记录</string>
<string name="updates_feed_cleared">订阅更新已清除</string>
<string name="rotate_screen">旋转屏幕</string>
<string name="update">更新订阅</string>
<string name="update">开始更新</string>
<string name="feed_will_update_soon">即将开始更新订阅</string>
<string name="track_sources">章节更新范围</string>
<string name="dont_check">不检查</string>
@@ -188,7 +188,7 @@
<string name="text_clear_search_history_prompt">要永久删除所有搜索记录吗?</string>
<string name="welcome">欢迎</string>
<string name="backup_saved">备份已保存</string>
<string name="tracker_warning">不同设备导致不同的系统调度可能会杀掉后台任务。</string>
<string name="tracker_warning">不同设备导致不同的系统调度可能会杀掉本应用的后台任务。</string>
<string name="read_more">了解详情</string>
<string name="queued">等待</string>
<string name="chapter_is_missing">该章缺失</string>
@@ -212,7 +212,7 @@
<string name="suggestions">漫画推荐</string>
<string name="suggestions_enable">开启漫画推荐</string>
<string name="text_suggestion_holder">开始阅读漫画,即可获取个性化推荐</string>
<string name="exclude_nsfw_from_suggestions">禁止推荐成人内容漫画</string>
<string name="exclude_nsfw_from_suggestions">禁止推荐成人漫画</string>
<string name="enabled">启用</string>
<string name="disabled">禁用</string>
<string name="filter_load_error">无法加载分类列表</string>
@@ -227,7 +227,7 @@
<string name="suggestions_excluded_genres_summary">输入不希望在推荐中看到的分类</string>
<string name="text_delete_local_manga_batch">要从系统中永久删除所选项目吗?</string>
<string name="removal_completed">删除成功</string>
<string name="download_slowdown">减慢下载速度</string>
<string name="download_slowdown">限速下载</string>
<string name="download_slowdown_summary">有助于避免封禁你的IP地址</string>
<string name="local_manga_processing">正在处理已保存漫画</string>
<string name="chapters_will_removed_background">章节将在后台被删除</string>
@@ -268,7 +268,7 @@
<string name="show_reading_indicators_summary">在历史和收藏中显示阅读百分比</string>
<string name="show_reading_indicators">显示阅读进度</string>
<string name="data_deletion">数据删除</string>
<string name="exclude_nsfw_from_history_summary">标记为成人内容的漫画将不会添加到历史记录,也不会保存阅读记录</string>
<string name="exclude_nsfw_from_history_summary">标记为含有成人内容的漫画将不会添加到历史记录,也不会保存阅读记录</string>
<string name="clear_cookies_summary">能对部分问题起到一些作用。所有网站的授权将会失效</string>
<string name="show_all">显示全部</string>
<string name="manga_error_description_pattern">错误详情:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1.尝试&lt;a href=%2$s&gt;在网络浏览器中打开漫画&lt;/a&gt;以确保在其图源中可用&lt;br&gt;2.请确保使用的是&lt;a href=kotatsu://about&gt;最新版本的Kotatsu&lt;/a&gt;&lt;br&gt;3.若图源没有问题,请向开发人员发送错误报告。</string>
@@ -325,7 +325,7 @@
<string name="feed">订阅</string>
<string name="memory_usage_pattern">%s - %s</string>
<string name="not_found_404">没有章节或已被删除</string>
<string name="reader_control_ltr_summary">点击屏幕右侧或按下右键始终翻到下一页</string>
<string name="reader_control_ltr_summary">当使用鼠标或键盘时,向下导航更改为下一页</string>
<string name="reader_control_ltr">简易控制</string>
<string name="history_shortcuts_summary">长按应用图标显示最近阅读的漫画</string>
<string name="history_shortcuts">显示最近阅读漫画的快捷方式</string>
@@ -343,8 +343,8 @@
<string name="network_unavailable">网络未连接</string>
<string name="network_unavailable_hint">打开 Wi-Fi 或移动网络开始在线阅读漫画</string>
<string name="clear_new_chapters_counters">同时清除新章节信息</string>
<string name="server_error">服务器错误 (%1$d)。请稍后</string>
<string name="compact">紧凑</string>
<string name="server_error">服务器错误 (%1$d)。请稍后</string>
<string name="compact">列表</string>
<string name="source_disabled">图源已禁用</string>
<string name="prefetch_content">内容预加载</string>
<string name="mark_as_current">标为当前</string>
@@ -378,7 +378,7 @@
<string name="show_on_shelf">在书架上显示</string>
<string name="comics_archive_import_description">可选择一个或多个 .cbz 或 .zip 文件,每个文件都将识别为一个单独的漫画。</string>
<string name="folder_with_images_import_description">可选择一个包含压缩包或图片的文件夹。每个压缩包(或子文件夹)都会被识别为一个章节。</string>
<string name="find_similar">寻找类似漫画</string>
<string name="find_similar">搜索相似漫画</string>
<string name="translations">翻译</string>
<string name="web_view_unavailable">WebView不可用检查是否已安装WebView</string>
<string name="sync_host_description">可使用自建同步服务器或默认同步服务器。若不知道有何用处请不要自行修改。</string>
@@ -386,7 +386,7 @@
<string name="mirror_switching_summary">若存在可用的镜像网址,在出错时开始自动切换</string>
<string name="paused">已暂停</string>
<string name="downloads_wifi_only_summary">切换到移动网络时停止下载</string>
<string name="remove_completed">除已完成任务</string>
<string name="remove_completed">除已完成任务</string>
<string name="cancel_all">取消所有下载中的任务</string>
<string name="downloads_wifi_only">仅在连接 Wi-Fi 时下载</string>
<string name="enable">启用</string>
@@ -399,14 +399,14 @@
<string name="text_downloads_list_holder">暂无下载任务</string>
<string name="downloads_resumed">下载已继续</string>
<string name="downloads_paused">下载已暂停</string>
<string name="downloads_removed">下载记录已</string>
<string name="downloads_removed">下载记录已全部清</string>
<string name="downloads_cancelled">下载已取消</string>
<string name="suggestions_enable_prompt">想要接收个性化的漫画推荐吗?</string>
<string name="suggestion_manga">推荐:%s</string>
<string name="suggestions_notifications_summary">偶尔显示漫画推荐通知</string>
<string name="more">更多</string>
<string name="cancel_all_downloads_confirm">将取消所有进行中的下载,部分下载完成的数据将会删除</string>
<string name="remove_completed_downloads_confirm">下载历史将会永久</string>
<string name="remove_completed_downloads_confirm">所有已完成的下载记录将会永久</string>
<string name="sync_auth_hint">可登陆已有账号或创建新账号</string>
<string name="address">地址</string>
<string name="clear_network_cache">清除网络缓存</string>
@@ -436,11 +436,11 @@
<string name="username">用户名</string>
<string name="download_option_all_unread_b">所有未读章节 (%s)</string>
<string name="authorization_optional">授权 (可选)</string>
<string name="download_option_first_n_chapters"> %s</string>
<string name="download_option_first_n_chapters">前%s</string>
<string name="downloaded">下载进度</string>
<string name="custom_directory">自定义目录</string>
<string name="pages_animation_summary">翻页动画</string>
<string name="download_option_next_unread_n_chapters">后 %s</string>
<string name="download_option_next_unread_n_chapters">续未读的 %s</string>
<string name="images_procy_description">尽可能使用 wsrv.nl 代理服务减少流量使用并加快图片加载</string>
<string name="invert_colors">反色</string>
<string name="related_manga">相关漫画</string>
@@ -464,15 +464,15 @@
<string name="manage_categories">管理分类</string>
<string name="color_light">浅色</string>
<string name="search_hint">输入漫画标题、分类或图源名称</string>
<string name="main_screen_sections">底部导航栏</string>
<string name="main_screen_sections">主页底部导航栏</string>
<string name="advanced">高级</string>
<string name="color_dark">深色</string>
<string name="too_many_requests_message">请求次数过多,稍候再尝</string>
<string name="too_many_requests_message">请求次数过多,请稍后重</string>
<string name="suggestions_wifi_only_summary">使用移动网络时停止推荐漫画</string>
<string name="default_section">默认页面</string>
<string name="background">背景颜色</string>
<string name="manga_list">漫画列表</string>
<string name="disable_nsfw">禁用成人内容图源</string>
<string name="disable_nsfw">隐藏成人内容</string>
<string name="color_white">白色</string>
<string name="to_top">置顶</string>
<string name="show">显示</string>
@@ -484,7 +484,7 @@
<string name="keep_screen_on">保持屏幕常亮</string>
<string name="keep_screen_on_summary">阅读时不息屏</string>
<string name="list_options">显示选项</string>
<string name="suggest_new_sources">新增漫画源推荐</string>
<string name="suggest_new_sources">推荐新增图源</string>
<string name="enhanced_colors_summary">减少色带,但可能会影响性能</string>
<string name="enhanced_colors">32位色彩模式</string>
<string name="suggest_new_sources_summary">应用更新后提示开启新增图源</string>
@@ -500,7 +500,7 @@
<string name="frequency_once_per_month">每月一次</string>
<string name="last_successful_backup">上次备份成功:%s</string>
<string name="backups_output_directory">备份保存路径</string>
<string name="download_option_all_chapters">所有已翻译的章节 %s</string>
<string name="download_option_all_chapters">所有已翻译的章节 (%s)</string>
<string name="state_upcoming">即将推出</string>
<string name="by_name_reverse">名称倒序</string>
<string name="manage_sources">管理图源</string>
@@ -513,7 +513,7 @@
<string name="source_enabled">已启用图源</string>
<string name="content_type_hentai">成人</string>
<string name="no_manga_sources_found">本次搜索未发现可用图源</string>
<string name="no_manga_sources_catalog_text">此页面没有可用图源,或可能已添加所有图源。
<string name="no_manga_sources_catalog_text">此页面没有可用图源,或可能已添加所有可用图源。
\n敬请期待后续更新</string>
<string name="welcome_text">请选择需要开启的图源内容。可稍后在设置选项中设定</string>
<string name="sync_auth">网络同步</string>
@@ -526,7 +526,7 @@
<string name="rating_suggestive">R15</string>
<string name="rating_adult">R18</string>
<string name="lock_screen_rotation">锁定屏幕方向</string>
<string name="default_tab">默认导航栏</string>
<string name="default_tab">作品详情页默认界面</string>
<string name="grayscale">灰度</string>
<string name="globally">全局</string>
<string name="this_manga">此漫画</string>
@@ -537,7 +537,7 @@
<string name="state_abandoned">已腰斩</string>
<string name="manual">手动</string>
<string name="available_d">%1$d 个可用</string>
<string name="disable_nsfw_summary">禁用成人内容图源并尽可能从列表中隐藏成人漫画</string>
<string name="disable_nsfw_summary">禁用含有成人内容图源并尽可能从列表中隐藏成人漫画</string>
<string name="speed_value">x%.1f</string>
<string name="error_filter_locale_genre_not_supported">此图源不支持同时按分类和区域筛选</string>
<string name="error_filter_states_genre_not_supported">此图源不支持同时按分类和状态筛选</string>
@@ -584,4 +584,8 @@
<string name="fullscreen_mode">全屏模式</string>
<string name="default_webtoon_zoom_out">条漫默认缩小值</string>
<string name="reader_fullscreen_summary">将系统状态栏与通知栏隐藏</string>
<string name="suggestions_unavailable_text">漫画推荐功能已被禁用</string>
<string name="check_for_new_chapters_disabled">章节更新功能已被禁用</string>
<string name="reading_time_estimation">在作品详情页显示估计阅读时间</string>
<string name="reading_time_estimation_summary">估计阅读时间可能会不准确</string>
</resources>

View File

@@ -10,6 +10,7 @@
<dimen name="list_spacing_large">12dp</dimen>
<!-- Navigation -->
<dimen name="nav_header_logo_size">36dp</dimen>
<dimen name="nav_bar_height_compact">62dp</dimen>
<dimen name="toolbar_height_expanded">172dp</dimen>
<dimen name="grid_spacing">8dp</dimen>

File diff suppressed because it is too large Load Diff

View File

@@ -46,8 +46,7 @@
</PreferenceCategory>
<PreferenceCategory
android:title="@string/details">
<PreferenceCategory android:title="@string/details">
<SwitchPreferenceCompat
android:defaultValue="true"
@@ -71,6 +70,11 @@
android:title="@string/main_screen_sections"
app:allowDividerAbove="true" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="nav_labels"
android:title="@string/show_labels_in_navbar" />
<org.koitharu.kotatsu.settings.utils.ActivityListPreference
android:key="app_locale"
android:title="@string/language" />

View File

@@ -35,4 +35,18 @@
android:summary="@string/downloads_settings_info"
app:allowDividerAbove="true" />
<PreferenceCategory android:title="@string/pages_saving">
<Preference
android:key="pages_dir"
android:persistent="false"
android:title="@string/default_page_save_dir" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="pages_dir_ask"
android:title="@string/ask_for_dest_dir_every_time" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -51,6 +51,12 @@
android:title="@string/reader_actions"
app:allowDividerAbove="true" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="reader_taps_ltr"
android:summary="@string/reader_control_ltr_summary"
android:title="@string/reader_control_ltr" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="reader_volume_buttons"