Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cc04b0f7a | ||
|
|
258dbf3dc3 | ||
|
|
e7af4e8450 | ||
|
|
0c25c61858 | ||
|
|
abc3e45907 | ||
|
|
bd98d8eded | ||
|
|
2e81f41073 | ||
|
|
5cccebc416 | ||
|
|
c668ffd555 | ||
|
|
a0f77b715f | ||
|
|
2831843a25 | ||
|
|
86c1aa11b0 | ||
|
|
d71514ec7a | ||
|
|
92ed320f57 | ||
|
|
2de1fe8b77 | ||
|
|
cebc3cd9e8 | ||
|
|
6c0e2e2b90 | ||
|
|
b4bd923ce8 | ||
|
|
813561fd3b | ||
|
|
4107336132 | ||
|
|
30d9d87c17 | ||
|
|
c4b5be657d | ||
|
|
8a763b2b9f | ||
|
|
c783378022 | ||
|
|
c4355f16e8 | ||
|
|
522dfc2418 | ||
|
|
06d03e3ddd | ||
|
|
9dc8c7959d | ||
|
|
db219020ca | ||
|
|
c04edcb76c | ||
|
|
936fc2e4ae | ||
|
|
cbed866665 | ||
|
|
ac568b6361 | ||
|
|
84157f988d | ||
|
|
6f6339f0f8 | ||
|
|
a7019b9096 | ||
|
|
867e3f10ca | ||
|
|
fb2cf04d75 | ||
|
|
3ed44ba0d6 | ||
|
|
b78104a0f1 | ||
|
|
e4ee93f77c | ||
|
|
c6e8da5f23 | ||
|
|
376de7cce3 | ||
|
|
bec2195971 | ||
|
|
722ac4ecc7 | ||
|
|
516c1c02a6 | ||
|
|
0cb7e71781 |
@@ -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'
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -61,6 +61,8 @@ class WelcomeViewModel @Inject constructor(
|
||||
selectedItems = selectedLocales,
|
||||
isLoading = false,
|
||||
)
|
||||
repository.assimilateNewSources()
|
||||
commit()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -114,7 +114,7 @@ class ReaderControlDelegate(
|
||||
}
|
||||
|
||||
private fun isReaderTapsReversed(): Boolean {
|
||||
return listener.readerMode == ReaderMode.REVERSED
|
||||
return settings.isReaderControlAlwaysLTR && listener.readerMode == ReaderMode.REVERSED
|
||||
}
|
||||
|
||||
interface OnInteractionListener {
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">Дэталі памылкі:<br><tt>%1$s</tt><br><br>1. Паспрабуйце <a href=%2$s>адкрыць мангу ў вэб-браўзеры</a>, каб пераканацца, што яна даступная ў крыніцы<br>2. Упэўніцеся, што вы выкарыстоўваеце <a href=kotatsu://about>апошнюю версію Kotatsu</a><br>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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -327,7 +327,7 @@
|
||||
<string name="manga_error_description_pattern">Сведения об ошибке:<br><tt>%1$s</tt><br><br>1. Попробуйте <a href=%2$s>открыть мангу в веб-браузере</a>, чтобы убедиться, что она доступна в источнике<br>2. Убедитесь, что вы используете <a href=kotatsu://about>последнюю версию Kotatsu</a><br>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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -327,7 +327,7 @@
|
||||
<string name="manga_error_description_pattern">Деталі помилки:<br><tt>%1$s</tt><br><br>1. Спробуйте <a href=%2$s>відкрити манґу у веб-браузері</a>, щоб переконатися, що вона доступна в джерелі<br>2. Переконайтеся, що ви використовуєте <a href=kotatsu://about>останню версію Kotatsu</a><br>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>
|
||||
@@ -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">错误详情:<br><tt>%1$s</tt><br><br>1.尝试<a href=%2$s>在网络浏览器中打开漫画</a>以确保在其图源中可用<br>2.请确保使用的是<a href=kotatsu://about>最新版本的Kotatsu</a><br>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>
|
||||
@@ -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
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user