Reorganize settings

This commit is contained in:
Koitharu
2023-06-05 12:53:12 +03:00
parent e794f84c6f
commit bc3a7fc211
23 changed files with 333 additions and 252 deletions

View File

@@ -9,10 +9,10 @@ import androidx.core.view.updatePadding
import androidx.preference.PreferenceFragmentCompat
import androidx.recyclerview.widget.RecyclerView
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate
import org.koitharu.kotatsu.settings.SettingsActivity
import javax.inject.Inject
@Suppress("LeakingThis")
@@ -44,9 +44,7 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
override fun onResume() {
super.onResume()
if (titleId != 0) {
setTitle(getString(titleId))
}
setTitle(if (titleId != 0) getString(titleId) else null)
}
@CallSuper
@@ -56,11 +54,7 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
)
}
protected fun setTitle(title: CharSequence) {
activity?.let {
if (!it.resources.getBoolean(R.bool.is_tablet)) {
it.title = title
}
}
protected fun setTitle(title: CharSequence?) {
(activity as? SettingsActivity)?.setSectionTitle(title)
}
}

View File

@@ -12,7 +12,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.AlertDialogFragment
import org.koitharu.kotatsu.databinding.DialogImportBinding
import org.koitharu.kotatsu.settings.backup.BackupDialogFragment
import org.koitharu.kotatsu.settings.backup.RestoreDialogFragment
class ImportDialogFragment : AlertDialogFragment<DialogImportBinding>(), View.OnClickListener {
@@ -64,9 +63,10 @@ class ImportDialogFragment : AlertDialogFragment<DialogImportBinding>(), View.On
}
private fun restoreBackup(uri: Uri?) {
RestoreDialogFragment.newInstance(uri ?: return)
.show(parentFragmentManager, BackupDialogFragment.TAG)
dismiss()
if (uri != null) {
RestoreDialogFragment.show(parentFragmentManager, uri)
dismiss()
}
}
companion object {

View File

@@ -3,67 +3,42 @@ package org.koitharu.kotatsu.settings
import android.content.SharedPreferences
import android.os.Bundle
import android.view.View
import androidx.preference.ListPreference
import androidx.preference.Preference
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.cache.ContentCache
import org.koitharu.kotatsu.core.network.DoHProvider
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.ui.dialog.StorageSelectDialog
import org.koitharu.kotatsu.core.util.ext.getStorageName
import org.koitharu.kotatsu.core.util.ext.setDefaultValueCompat
import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.local.data.LocalStorageManager
import org.koitharu.kotatsu.parsers.util.names
import org.koitharu.kotatsu.util.ext.printStackTraceDebug
import java.io.File
import java.net.Proxy
import javax.inject.Inject
@AndroidEntryPoint
class ContentSettingsFragment :
BasePreferenceFragment(R.string.content),
class DownloadsSettingsFragment :
BasePreferenceFragment(R.string.downloads),
SharedPreferences.OnSharedPreferenceChangeListener,
StorageSelectDialog.OnStorageSelectListener {
@Inject
lateinit var storageManager: LocalStorageManager
@Inject
lateinit var contentCache: ContentCache
@Inject
lateinit var downloadsScheduler: DownloadWorker.Scheduler
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_content)
findPreference<Preference>(AppSettings.KEY_PREFETCH_CONTENT)?.isVisible = contentCache.isCachingEnabled
findPreference<ListPreference>(AppSettings.KEY_DOH)?.run {
entryValues = arrayOf(
DoHProvider.NONE,
DoHProvider.GOOGLE,
DoHProvider.CLOUDFLARE,
DoHProvider.ADGUARD,
).names()
setDefaultValueCompat(DoHProvider.NONE.name)
}
addPreferencesFromResource(R.xml.pref_downloads)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
findPreference<Preference>(AppSettings.KEY_LOCAL_STORAGE)?.bindStorageName()
findPreference<Preference>(AppSettings.KEY_SUGGESTIONS)?.setSummary(
if (settings.isSuggestionsEnabled) R.string.enabled else R.string.disabled,
)
bindRemoteSourcesSummary()
bindProxySummary()
settings.subscribe(this)
}
@@ -78,29 +53,9 @@ class ContentSettingsFragment :
findPreference<Preference>(key)?.bindStorageName()
}
AppSettings.KEY_SUGGESTIONS -> {
findPreference<Preference>(AppSettings.KEY_SUGGESTIONS)?.setSummary(
if (settings.isSuggestionsEnabled) R.string.enabled else R.string.disabled,
)
}
AppSettings.KEY_SOURCES_HIDDEN -> {
bindRemoteSourcesSummary()
}
AppSettings.KEY_DOWNLOADS_WIFI -> {
updateDownloadsConstraints()
}
AppSettings.KEY_SSL_BYPASS -> {
Snackbar.make(listView, R.string.settings_apply_restart_required, Snackbar.LENGTH_INDEFINITE).show()
}
AppSettings.KEY_PROXY_TYPE,
AppSettings.KEY_PROXY_ADDRESS,
AppSettings.KEY_PROXY_PORT -> {
bindProxySummary()
}
}
}
@@ -131,26 +86,6 @@ class ContentSettingsFragment :
}
}
private fun bindRemoteSourcesSummary() {
findPreference<Preference>(AppSettings.KEY_REMOTE_SOURCES)?.run {
val total = settings.remoteMangaSources.size
summary = getString(R.string.enabled_d_of_d, total - settings.hiddenSources.size, total)
}
}
private fun bindProxySummary() {
findPreference<Preference>(AppSettings.KEY_PROXY)?.run {
val type = settings.proxyType
val address = settings.proxyAddress
val port = settings.proxyPort
summary = if (type == Proxy.Type.DIRECT || address.isNullOrEmpty() || port == 0) {
context.getString(R.string.disabled)
} else {
"$address:$port"
}
}
}
private fun updateDownloadsConstraints() {
val preference = findPreference<Preference>(AppSettings.KEY_DOWNLOADS_WIFI)
viewLifecycleScope.launch {

View File

@@ -0,0 +1,79 @@
package org.koitharu.kotatsu.settings
import android.content.SharedPreferences
import android.os.Bundle
import android.view.View
import androidx.preference.ListPreference
import androidx.preference.Preference
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.cache.ContentCache
import org.koitharu.kotatsu.core.network.DoHProvider
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.util.ext.setDefaultValueCompat
import org.koitharu.kotatsu.parsers.util.names
import java.net.Proxy
import javax.inject.Inject
@AndroidEntryPoint
class NetworkSettingsFragment :
BasePreferenceFragment(R.string.network),
SharedPreferences.OnSharedPreferenceChangeListener {
@Inject
lateinit var contentCache: ContentCache
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_network)
findPreference<Preference>(AppSettings.KEY_PREFETCH_CONTENT)?.isVisible = contentCache.isCachingEnabled
findPreference<ListPreference>(AppSettings.KEY_DOH)?.run {
entryValues = arrayOf(
DoHProvider.NONE,
DoHProvider.GOOGLE,
DoHProvider.CLOUDFLARE,
DoHProvider.ADGUARD,
).names()
setDefaultValueCompat(DoHProvider.NONE.name)
}
bindProxySummary()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
settings.subscribe(this)
}
override fun onDestroyView() {
settings.unsubscribe(this)
super.onDestroyView()
}
override fun onSharedPreferenceChanged(prefs: SharedPreferences?, key: String?) {
when (key) {
AppSettings.KEY_SSL_BYPASS -> {
Snackbar.make(listView, R.string.settings_apply_restart_required, Snackbar.LENGTH_INDEFINITE).show()
}
AppSettings.KEY_PROXY_TYPE,
AppSettings.KEY_PROXY_ADDRESS,
AppSettings.KEY_PROXY_PORT -> {
bindProxySummary()
}
}
}
private fun bindProxySummary() {
findPreference<Preference>(AppSettings.KEY_PROXY)?.run {
val type = settings.proxyType
val address = settings.proxyAddress
val port = settings.proxyPort
summary = if (type == Proxy.Type.DIRECT || address.isNullOrEmpty() || port == 0) {
context.getString(R.string.disabled)
} else {
"$address:$port"
}
}
}
}

View File

@@ -4,7 +4,7 @@ import android.os.Bundle
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
class RootSettingsFragment : BasePreferenceFragment(R.string.settings) {
class RootSettingsFragment : BasePreferenceFragment(0) {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_root)

View File

@@ -3,8 +3,10 @@ package org.koitharu.kotatsu.settings
import android.accounts.AccountManager
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.preference.Preference
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
@@ -27,7 +29,8 @@ import org.koitharu.kotatsu.util.ext.printStackTraceDebug
import javax.inject.Inject
@AndroidEntryPoint
class ServicesSettingsFragment : BasePreferenceFragment(R.string.services) {
class ServicesSettingsFragment : BasePreferenceFragment(R.string.services),
SharedPreferences.OnSharedPreferenceChangeListener {
@Inject
lateinit var shikimoriRepository: ShikimoriRepository
@@ -43,6 +46,17 @@ class ServicesSettingsFragment : BasePreferenceFragment(R.string.services) {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_services)
bindSuggestionsSummary()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
settings.subscribe(this)
}
override fun onDestroyView() {
settings.unsubscribe(this)
super.onDestroyView()
}
override fun onResume() {
@@ -53,6 +67,13 @@ class ServicesSettingsFragment : BasePreferenceFragment(R.string.services) {
bindSyncSummary()
}
override fun onSharedPreferenceChanged(prefs: SharedPreferences?, key: String?) {
when (key) {
AppSettings.KEY_SUGGESTIONS -> bindSuggestionsSummary()
}
}
override fun onPreferenceTreeClick(preference: Preference): Boolean {
return when (preference.key) {
AppSettings.KEY_SHIKIMORI -> {
@@ -156,4 +177,10 @@ class ServicesSettingsFragment : BasePreferenceFragment(R.string.services) {
findPreference<Preference>(AppSettings.KEY_SYNC_SETTINGS)?.isEnabled = account != null
}
}
private fun bindSuggestionsSummary() {
findPreference<Preference>(AppSettings.KEY_SUGGESTIONS)?.setSummary(
if (settings.isSuggestionsEnabled) R.string.enabled else R.string.disabled,
)
}
}

View File

@@ -24,6 +24,7 @@ import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat
import org.koitharu.kotatsu.core.util.ext.isScrolledToTop
import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ActivitySettingsBinding
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
import org.koitharu.kotatsu.parsers.model.MangaSource
@@ -121,6 +122,12 @@ class SettingsActivity :
}
}
fun setSectionTitle(title: CharSequence?) {
viewBinding.textViewHeader?.apply {
textAndVisible = title
} ?: setTitle(title ?: getString(R.string.settings))
}
fun openFragment(fragment: Fragment, isFromRoot: Boolean) {
val hasFragment = supportFragmentManager.findFragmentById(R.id.container) != null
val isMasterDetail = viewBinding.containerMaster != null
@@ -139,7 +146,7 @@ class SettingsActivity :
val fragment = when (intent?.action) {
ACTION_READER -> ReaderSettingsFragment()
ACTION_SUGGESTIONS -> SuggestionsSettingsFragment()
ACTION_HISTORY -> HistorySettingsFragment()
ACTION_HISTORY -> UserDataSettingsFragment()
ACTION_TRACKER -> TrackerSettingsFragment()
ACTION_SOURCE -> SourceSettingsFragment.newInstance(
intent.getSerializableExtraCompat(EXTRA_SOURCE) as? MangaSource ?: MangaSource.LOCAL,

View File

@@ -1,7 +1,11 @@
package org.koitharu.kotatsu.settings
import android.content.ActivityNotFoundException
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.Lifecycle
import androidx.preference.Preference
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -24,11 +28,14 @@ import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope
import org.koitharu.kotatsu.local.data.CacheDir
import org.koitharu.kotatsu.local.data.LocalStorageManager
import org.koitharu.kotatsu.search.domain.MangaSearchRepository
import org.koitharu.kotatsu.settings.backup.BackupDialogFragment
import org.koitharu.kotatsu.settings.backup.RestoreDialogFragment
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import org.koitharu.kotatsu.util.ext.printStackTraceDebug
import javax.inject.Inject
@AndroidEntryPoint
class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cache) {
class UserDataSettingsFragment : BasePreferenceFragment(R.string.data_and_privacy), ActivityResultCallback<Uri?> {
@Inject
lateinit var trackerRepo: TrackingRepository
@@ -48,8 +55,13 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
@Inject
lateinit var shortcutsUpdater: ShortcutsUpdater
private val backupSelectCall = registerForActivityResult(
ActivityResultContracts.OpenDocument(),
this,
)
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_history)
addPreferencesFromResource(R.xml.pref_user_data)
findPreference<Preference>(AppSettings.KEY_SHORTCUTS)?.isVisible =
shortcutsUpdater.isDynamicShortcutsAvailable()
}
@@ -116,10 +128,33 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
true
}
AppSettings.KEY_BACKUP -> {
BackupDialogFragment.show(childFragmentManager)
true
}
AppSettings.KEY_RESTORE -> {
try {
backupSelectCall.launch(arrayOf("*/*"))
} catch (e: ActivityNotFoundException) {
e.printStackTraceDebug()
Snackbar.make(
listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT,
).show()
}
true
}
else -> super.onPreferenceTreeClick(preference)
}
}
override fun onActivityResult(result: Uri?) {
if (result != null) {
RestoreDialogFragment.show(childFragmentManager, result)
}
}
private fun clearCache(preference: Preference, cache: CacheDir) {
val ctx = preference.context.applicationContext
viewLifecycleScope.launch {

View File

@@ -7,6 +7,7 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
@@ -101,6 +102,10 @@ class BackupDialogFragment : AlertDialogFragment<DialogProgressBinding>() {
companion object {
const val TAG = "BackupDialogFragment"
private const val TAG = "BackupDialogFragment"
fun show(fm: FragmentManager) {
BackupDialogFragment().show(fm, TAG)
}
}
}

View File

@@ -1,55 +0,0 @@
package org.koitharu.kotatsu.settings.backup
import android.content.ActivityNotFoundException
import android.net.Uri
import android.os.Bundle
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts
import androidx.preference.Preference
import com.google.android.material.snackbar.Snackbar
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.util.ext.printStackTraceDebug
class BackupSettingsFragment :
BasePreferenceFragment(R.string.backup_restore),
ActivityResultCallback<Uri?> {
private val backupSelectCall = registerForActivityResult(
ActivityResultContracts.OpenDocument(),
this,
)
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_backup)
}
override fun onPreferenceTreeClick(preference: Preference): Boolean {
return when (preference.key) {
AppSettings.KEY_BACKUP -> {
BackupDialogFragment().show(childFragmentManager, BackupDialogFragment.TAG)
true
}
AppSettings.KEY_RESTORE -> {
try {
backupSelectCall.launch(arrayOf("*/*"))
} catch (e: ActivityNotFoundException) {
e.printStackTraceDebug()
Snackbar.make(
listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT,
).show()
}
true
}
else -> super.onPreferenceTreeClick(preference)
}
}
override fun onActivityResult(result: Uri?) {
RestoreDialogFragment.newInstance(result ?: return)
.show(childFragmentManager, BackupDialogFragment.TAG)
}
}

View File

@@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
@@ -87,10 +88,12 @@ class RestoreDialogFragment : AlertDialogFragment<DialogProgressBinding>() {
companion object {
const val ARG_FILE = "file"
const val TAG = "RestoreDialogFragment"
private const val TAG = "RestoreDialogFragment"
fun newInstance(uri: Uri) = RestoreDialogFragment().withArgs(1) {
putString(ARG_FILE, uri.toString())
fun show(fm: FragmentManager, uri: Uri) {
RestoreDialogFragment().withArgs(1) {
putString(ARG_FILE, uri.toString())
}.show(fm, TAG)
}
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
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
android:fillColor="#000000"
android:pathData="M17 14.4C17.6 14.4 18.1 14.9 18.1 15.5S17.6 16.6 17 16.6 15.9 16.1 15.9 15.5 16.4 14.4 17 14.4M17 17.5C16.3 17.5 14.8 17.9 14.8 18.6C15.3 19.3 16.1 19.8 17 19.8S18.7 19.3 19.2 18.6C19.2 17.9 17.7 17.5 17 17.5M18 11.1V6.3L10.5 3L3 6.3V11.2C3 15.7 6.2 20 10.5 21C11.1 20.9 11.6 20.7 12.1 20.5C13.2 22 15 23 17 23C20.3 23 23 20.3 23 17C23 14 20.8 11.6 18 11.1M11 17C11 17.6 11.1 18.1 11.2 18.6C11 18.7 10.7 18.8 10.5 18.9C7.3 17.9 5 14.7 5 11.2V7.6L10.5 5.2L16 7.6V11.1C13.2 11.6 11 14 11 17M17 21C14.8 21 13 19.2 13 17S14.8 13 17 13 21 14.8 21 17 19.2 21 17 21Z" />
</vector>

View File

@@ -2,10 +2,10 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:tint="?colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M20 8H17V6C17 4.9 16.1 4 15 4H9C7.9 4 7 4.9 7 6V8H4C2.9 8 2 8.9 2 10V20H22V10C22 8.9 21.1 8 20 8M9 6H15V8H9V6M20 18H4V15H6V16H8V15H16V16H18V15H20V18M18 13V12H16V13H8V12H6V13H4V10H20V13H18Z" />
android:pathData="M22,13.5C22,15.26 20.7,16.72 19,16.96V20A2,2 0 0,1 17,22H13.2V21.7A2.7,2.7 0 0,0 10.5,19C9,19 7.8,20.21 7.8,21.7V22H4A2,2 0 0,1 2,20V16.2H2.3C3.79,16.2 5,15 5,13.5C5,12 3.79,10.8 2.3,10.8H2V7A2,2 0 0,1 4,5H7.04C7.28,3.3 8.74,2 10.5,2C12.26,2 13.72,3.3 13.96,5H17A2,2 0 0,1 19,7V10.04C20.7,10.28 22,11.74 22,13.5M17,15H18.5A1.5,1.5 0 0,0 20,13.5A1.5,1.5 0 0,0 18.5,12H17V7H12V5.5A1.5,1.5 0 0,0 10.5,4A1.5,1.5 0 0,0 9,5.5V7H4V9.12C5.76,9.8 7,11.5 7,13.5C7,15.5 5.75,17.2 4,17.88V20H6.12C6.8,18.25 8.5,17 10.5,17C12.5,17 14.2,18.25 14.88,20H17V15Z" />
</vector>

View File

@@ -2,6 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -50,10 +51,29 @@
app:layout_constraintStart_toEndOf="@id/container_master"
app:layout_constraintTop_toBottomOf="@id/appbar">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/container"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="?listPreferredItemPaddingStart"
android:layout_marginEnd="?listPreferredItemPaddingEnd"
android:gravity="center_vertical|start"
android:padding="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader"
tools:text="@string/appearance" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@@ -433,4 +433,11 @@
<string name="password">Password</string>
<string name="authorization_optional">Authorization (optional)</string>
<string name="invalid_port_number">Invalid port number</string>
<string name="network">Network</string>
<string name="data_and_privacy">Data and privacy</string>
<string name="restore_summary">Restore previously created backup</string>
<string name="webtoon_zoom_summary">Allow zoom in gesture in webtoon mode</string>
<string name="reader_info_bar_summary">Show the current time and reading progress at the top of the screen</string>
<string name="show_pages_numbers_summary">Show page numbers in bottom corner</string>
<string name="pages_animation_summary">Animate page switching</string>
</resources>

View File

@@ -3,6 +3,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<org.koitharu.kotatsu.settings.utils.ThemeChooserPreference
android:key="color_theme"
android:title="@string/color_theme"
app:isPreferenceVisible="@bool/is_color_themes_available" />
<ListPreference
android:defaultValue="-1"
android:entries="@array/themes"
@@ -11,11 +16,6 @@
android:title="@string/theme"
app:useSimpleSummaryProvider="true" />
<org.koitharu.kotatsu.settings.utils.ThemeChooserPreference
android:key="color_theme"
android:title="@string/color_theme"
app:isPreferenceVisible="@bool/is_color_themes_available" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="amoled_theme"
@@ -46,6 +46,15 @@
</PreferenceCategory>
<PreferenceCategory android:title="@string/remote_sources">
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="sources_grid"
android:title="@string/show_in_grid_view" />
</PreferenceCategory>
<org.koitharu.kotatsu.settings.utils.ActivityListPreference
android:key="app_locale"
android:title="@string/language"
@@ -55,13 +64,6 @@
android:defaultValue="false"
android:key="exit_confirm"
android:summary="@string/exit_confirmation_summary"
android:title="@string/exit_confirmation"
app:allowDividerAbove="true" />
<SwitchPreferenceCompat
android:key="protect_app"
android:persistent="false"
android:summary="@string/protect_application_summary"
android:title="@string/protect_application" />
android:title="@string/exit_confirmation" />
</PreferenceScreen>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
android:key="backup"
android:persistent="false"
android:title="@string/create_backup" />
<Preference
android:key="restore"
android:persistent="false"
android:title="@string/restore_backup" />
<Preference
android:icon="@drawable/ic_info_outline"
android:persistent="false"
android:selectable="false"
android:summary="@string/backup_information"
app:allowDividerAbove="true" />
</PreferenceScreen>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:key="local_storage"
android:persistent="false"
android:title="@string/manga_save_location" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="downloads_wifi"
android:summary="@string/downloads_wifi_only_summary"
android:title="@string/downloads_wifi_only" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="downloads_slowdown"
android:summary="@string/download_slowdown_summary"
android:title="@string/download_slowdown" />
</PreferenceScreen>

View File

@@ -4,22 +4,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.sources.SourcesListFragment"
android:key="remote_sources"
android:title="@string/remote_sources" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="sources_grid"
android:title="@string/show_in_grid_view" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.SuggestionsSettingsFragment"
android:key="suggestions"
android:title="@string/suggestions"
app:allowDividerAbove="true" />
<ListPreference
android:defaultValue="0"
android:entries="@array/network_policy"
@@ -30,11 +14,24 @@
app:useSimpleSummaryProvider="true"
tools:isPreferenceVisible="true" />
<ListPreference
android:defaultValue="2"
android:entries="@array/network_policy"
android:entryValues="@array/values_network_policy"
android:key="pages_preload"
android:title="@string/preload_pages"
app:useSimpleSummaryProvider="true" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.ProxySettingsFragment"
android:key="proxy"
android:title="@string/proxy"
app:allowDividerAbove="true" />
<ListPreference
android:entries="@array/doh_providers"
android:key="doh"
android:title="@string/dns_over_https"
app:allowDividerAbove="true"
app:useSimpleSummaryProvider="true" />
<SwitchPreferenceCompat
@@ -43,40 +40,14 @@
android:summary="@string/images_procy_description"
android:title="@string/images_proxy_title" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.ProxySettingsFragment"
android:key="proxy"
android:title="@string/proxy" />
<SwitchPreferenceCompat
android:key="ssl_bypass"
android:title="@string/ignore_ssl_errors" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="mirror_switching"
android:summary="@string/mirror_switching_summary"
android:title="@string/mirror_switching" />
<PreferenceCategory android:title="@string/downloads">
<Preference
android:key="local_storage"
android:persistent="false"
android:title="@string/manga_save_location" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="downloads_wifi"
android:summary="@string/downloads_wifi_only_summary"
android:title="@string/downloads_wifi_only" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="downloads_slowdown"
android:summary="@string/download_slowdown_summary"
android:title="@string/download_slowdown" />
</PreferenceCategory>
<SwitchPreferenceCompat
android:key="ssl_bypass"
android:title="@string/ignore_ssl_errors" />
</PreferenceScreen>

View File

@@ -19,8 +19,15 @@
android:entries="@array/zoom_modes"
android:key="zoom_mode"
android:title="@string/scale_mode"
app:allowDividerAbove="true"
app:useSimpleSummaryProvider="true" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="webtoon_zoom"
android:summary="@string/webtoon_zoom_summary"
android:title="@string/webtoon_zoom" />
<MultiSelectListPreference
android:defaultValue="@array/values_reader_switchers_default"
android:entries="@array/reader_switchers"
@@ -38,17 +45,15 @@
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="reader_animation"
android:summary="@string/pages_animation_summary"
android:title="@string/pages_animation" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="webtoon_zoom"
android:title="@string/webtoon_zoom" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="reader_bar"
android:title="@string/reader_info_bar" />
android:summary="@string/reader_info_bar_summary"
android:title="@string/reader_info_bar"
app:allowDividerAbove="true" />
<SwitchPreferenceCompat
android:defaultValue="true"
@@ -58,6 +63,7 @@
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="pages_numbers"
android:summary="@string/show_pages_numbers_summary"
android:title="@string/show_pages_numbers" />
<ListPreference
@@ -66,6 +72,7 @@
android:entryValues="@array/values_screenshots_policy"
android:key="screenshots_policy"
android:title="@string/screenshots_policy"
app:allowDividerAbove="true"
app:useSimpleSummaryProvider="true" />
<ListPreference

View File

@@ -9,15 +9,10 @@
android:title="@string/appearance" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.ContentSettingsFragment"
android:fragment="org.koitharu.kotatsu.settings.sources.SourcesListFragment"
android:icon="@drawable/ic_manga_source"
android:key="content"
android:title="@string/content" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.HistorySettingsFragment"
android:icon="@drawable/ic_history"
android:title="@string/history_and_cache" />
android:title="@string/remote_sources" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.ReaderSettingsFragment"
@@ -25,9 +20,19 @@
android:title="@string/reader_settings" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.ServicesSettingsFragment"
android:icon="@drawable/ic_services"
android:title="@string/services" />
android:fragment="org.koitharu.kotatsu.settings.NetworkSettingsFragment"
android:icon="@drawable/ic_web"
android:title="@string/network" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.UserDataSettingsFragment"
android:icon="@drawable/ic_data_privacy"
android:title="@string/data_and_privacy" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.DownloadsSettingsFragment"
android:icon="@drawable/ic_download"
android:title="@string/downloads" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.tracker.TrackerSettingsFragment"
@@ -35,9 +40,9 @@
android:title="@string/check_for_new_chapters" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.backup.BackupSettingsFragment"
android:icon="@drawable/ic_backup_restore"
android:title="@string/backup_restore" />
android:fragment="org.koitharu.kotatsu.settings.ServicesSettingsFragment"
android:icon="@drawable/ic_services"
android:title="@string/services" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.about.AboutSettingsFragment"

View File

@@ -16,6 +16,12 @@
android:key="sync_settings"
android:title="@string/sync_settings" />
<PreferenceScreen
android:fragment="org.koitharu.kotatsu.settings.SuggestionsSettingsFragment"
android:key="suggestions"
android:title="@string/suggestions"
app:allowDividerAbove="true" />
<PreferenceCategory android:title="@string/tracking">
<Preference

View File

@@ -2,6 +2,12 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreferenceCompat
android:key="protect_app"
android:persistent="false"
android:summary="@string/protect_application_summary"
android:title="@string/protect_application" />
<SwitchPreferenceCompat
android:key="history_exclude_nsfw"
android:summary="@string/exclude_nsfw_from_history_summary"
@@ -13,6 +19,22 @@
android:summary="@string/history_shortcuts_summary"
android:title="@string/history_shortcuts" />
<PreferenceCategory android:title="@string/backup_restore">
<Preference
android:key="backup"
android:persistent="false"
android:summary="@string/backup_information"
android:title="@string/create_backup" />
<Preference
android:key="restore"
android:persistent="false"
android:summary="@string/restore_summary"
android:title="@string/restore_backup" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/data_deletion">
<Preference