Search through settings
This commit is contained in:
@@ -9,7 +9,10 @@ import androidx.annotation.CallSuper
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.get
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -20,9 +23,11 @@ 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.core.util.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeDrawable
|
||||
import org.koitharu.kotatsu.core.util.ext.parentView
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import javax.inject.Inject
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
@AndroidEntryPoint
|
||||
abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
|
||||
@@ -67,6 +72,10 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setTitle(if (titleId != 0) getString(titleId) else null)
|
||||
arguments?.getString(SettingsActivity.ARG_PREF_KEY)?.let {
|
||||
focusPreference(it)
|
||||
arguments?.remove(SettingsActivity.ARG_PREF_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@@ -87,4 +96,31 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
|
||||
Snackbar.make(listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show()
|
||||
false
|
||||
}
|
||||
|
||||
private fun focusPreference(key: String) {
|
||||
val pref = findPreference<Preference>(key)
|
||||
if (pref == null) {
|
||||
scrollToPreference(key)
|
||||
return
|
||||
}
|
||||
scrollToPreference(pref)
|
||||
val prefIndex = preferenceScreen.indexOf(key)
|
||||
val view = if (prefIndex >= 0) {
|
||||
listView.findViewHolderForAdapterPosition(prefIndex)?.itemView ?: return
|
||||
} else {
|
||||
return
|
||||
}
|
||||
view.context.getThemeDrawable(materialR.attr.colorTertiaryContainer)?.let {
|
||||
view.background = it
|
||||
}
|
||||
}
|
||||
|
||||
private fun PreferenceScreen.indexOf(key: String): Int {
|
||||
for (i in 0 until preferenceCount) {
|
||||
if (get(i).key == key) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ class AdapterDelegateClickListenerAdapter<I, O>(
|
||||
|
||||
private fun mappedItem(): O = itemMapper.apply(adapterDelegate.item)
|
||||
|
||||
fun attach() = attach(adapterDelegate.itemView)
|
||||
|
||||
fun attach(itemView: View) {
|
||||
itemView.setOnClickListener(this)
|
||||
itemView.setOnLongClickListener(this)
|
||||
|
||||
@@ -74,6 +74,12 @@ class SearchSuggestionFragment :
|
||||
|
||||
companion object {
|
||||
|
||||
@Deprecated("",
|
||||
ReplaceWith(
|
||||
"SearchSuggestionFragment()",
|
||||
"org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionFragment"
|
||||
)
|
||||
)
|
||||
fun newInstance() = SearchSuggestionFragment()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
@@ -23,11 +25,17 @@ import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.model.MangaSourceInfo
|
||||
import org.koitharu.kotatsu.core.parser.external.ExternalMangaSource
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
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
|
||||
import org.koitharu.kotatsu.settings.about.AboutSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.search.SettingsItem
|
||||
import org.koitharu.kotatsu.settings.search.SettingsSearchFragment
|
||||
import org.koitharu.kotatsu.settings.search.SettingsSearchMenuProvider
|
||||
import org.koitharu.kotatsu.settings.search.SettingsSearchViewModel
|
||||
import org.koitharu.kotatsu.settings.sources.SourceSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.sources.SourcesSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.sources.manage.SourcesManageFragment
|
||||
@@ -48,6 +56,8 @@ class SettingsActivity :
|
||||
|
||||
private var screenPadding = 0
|
||||
|
||||
private val viewModel: SettingsSearchViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(ActivitySettingsBinding.inflate(layoutInflater))
|
||||
@@ -64,6 +74,9 @@ class SettingsActivity :
|
||||
replace(R.id.container_master, RootSettingsFragment())
|
||||
}
|
||||
}
|
||||
viewModel.isSearchActive.observe(this, ::toggleSearchMode)
|
||||
viewModel.onNavigateToPreference.observeEvent(this, ::navigateToPreference)
|
||||
addMenuProvider(SettingsSearchMenuProvider(viewModel))
|
||||
addMenuProvider(SettingsMenuProvider(this))
|
||||
}
|
||||
|
||||
@@ -97,6 +110,7 @@ class SettingsActivity :
|
||||
}
|
||||
|
||||
fun openFragment(fragmentClass: Class<out Fragment>, args: Bundle?, isFromRoot: Boolean) {
|
||||
viewModel.discardSearch()
|
||||
val hasFragment = supportFragmentManager.findFragmentById(R.id.container) != null
|
||||
supportFragmentManager.commit {
|
||||
setReorderingAllowed(true)
|
||||
@@ -108,6 +122,27 @@ class SettingsActivity :
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleSearchMode(isEnabled: Boolean) {
|
||||
viewBinding.containerSearch.isVisible = isEnabled
|
||||
val searchFragment = supportFragmentManager.findFragmentById(R.id.container_search)
|
||||
if (searchFragment != null) {
|
||||
if (!isEnabled) {
|
||||
invalidateOptionsMenu()
|
||||
supportFragmentManager.commit {
|
||||
setReorderingAllowed(true)
|
||||
remove(searchFragment)
|
||||
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)
|
||||
}
|
||||
}
|
||||
} else if (isEnabled) {
|
||||
supportFragmentManager.commit {
|
||||
setReorderingAllowed(true)
|
||||
add(R.id.container_search, SettingsSearchFragment::class.java, null)
|
||||
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun openDefaultFragment() {
|
||||
val fragment = when (intent?.action) {
|
||||
ACTION_READER -> ReaderSettingsFragment()
|
||||
@@ -138,6 +173,12 @@ class SettingsActivity :
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToPreference(item: SettingsItem) {
|
||||
val args = Bundle(1)
|
||||
args.putString(ARG_PREF_KEY, item.key)
|
||||
openFragment(item.fragmentClass, args, true)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ACTION_READER = "${BuildConfig.APPLICATION_ID}.action.MANAGE_READER_SETTINGS"
|
||||
@@ -152,6 +193,7 @@ class SettingsActivity :
|
||||
private const val EXTRA_SOURCE = "source"
|
||||
private const val HOST_ABOUT = "about"
|
||||
private const val HOST_SYNC_SETTINGS = "sync-settings"
|
||||
const val ARG_PREF_KEY = "pref_key"
|
||||
|
||||
fun newIntent(context: Context) = Intent(context, SettingsActivity::class.java)
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.settings.search
|
||||
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
|
||||
data class SettingsItem(
|
||||
val key: String,
|
||||
val title: CharSequence,
|
||||
val breadcrumbs: List<String>,
|
||||
val fragmentClass: Class<out PreferenceFragmentCompat>,
|
||||
) : ListModel {
|
||||
|
||||
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||
return other is SettingsItem && other.key == key
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.koitharu.kotatsu.settings.search
|
||||
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
||||
import org.koitharu.kotatsu.databinding.ItemPreferenceBinding
|
||||
|
||||
fun settingsItemAD(
|
||||
listener: OnListItemClickListener<SettingsItem>,
|
||||
) = adapterDelegateViewBinding<SettingsItem, SettingsItem, ItemPreferenceBinding>(
|
||||
{ layoutInflater, parent -> ItemPreferenceBinding.inflate(layoutInflater, parent, false) },
|
||||
) {
|
||||
|
||||
AdapterDelegateClickListenerAdapter(this, listener).attach()
|
||||
val breadcrumbsSeparator = getString(R.string.breadcrumbs_separator)
|
||||
|
||||
bind {
|
||||
binding.textViewTitle.text = item.title
|
||||
binding.textViewSummary.textAndVisible = item.breadcrumbs.joinToString(breadcrumbsSeparator)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.koitharu.kotatsu.settings.search
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.BaseFragment
|
||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.databinding.FragmentSearchSuggestionBinding
|
||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SettingsSearchFragment : BaseFragment<FragmentSearchSuggestionBinding>(), OnListItemClickListener<SettingsItem> {
|
||||
|
||||
private val viewModel: SettingsSearchViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSearchSuggestionBinding {
|
||||
return FragmentSearchSuggestionBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewBindingCreated(binding: FragmentSearchSuggestionBinding, savedInstanceState: Bundle?) {
|
||||
super.onViewBindingCreated(binding, savedInstanceState)
|
||||
val adapter = BaseListAdapter<SettingsItem>()
|
||||
.addDelegate(ListItemType.NAV_ITEM, settingsItemAD(this))
|
||||
binding.root.adapter = adapter
|
||||
binding.root.setHasFixedSize(true)
|
||||
viewModel.content.observe(viewLifecycleOwner, adapter)
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
val extraPadding = resources.getDimensionPixelOffset(R.dimen.list_spacing)
|
||||
requireViewBinding().root.updatePadding(
|
||||
top = extraPadding,
|
||||
right = insets.right,
|
||||
left = insets.left,
|
||||
bottom = insets.bottom,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onItemClick(item: SettingsItem, view: View) = viewModel.navigateToPreference(item)
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.koitharu.kotatsu.settings.search
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import androidx.annotation.XmlRes
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.get
|
||||
import dagger.Reusable
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.settings.AppearanceSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.DownloadsSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.NetworkSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.ReaderSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.ServicesSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.about.AboutSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.sources.SourcesSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.tracker.TrackerSettingsFragment
|
||||
import org.koitharu.kotatsu.settings.userdata.UserDataSettingsFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
@Reusable
|
||||
@SuppressLint("RestrictedApi")
|
||||
class SettingsSearchHelper @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
) {
|
||||
|
||||
fun inflatePreferences(): List<SettingsItem> {
|
||||
val preferenceManager = PreferenceManager(context)
|
||||
val result = ArrayList<SettingsItem>()
|
||||
preferenceManager.inflateTo(result, R.xml.pref_appearance, emptyList(), AppearanceSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_sources, emptyList(), SourcesSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_reader, emptyList(), ReaderSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_network, emptyList(), NetworkSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_user_data, emptyList(), UserDataSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_downloads, emptyList(), DownloadsSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_tracker, emptyList(), TrackerSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_services, emptyList(), ServicesSettingsFragment::class.java)
|
||||
preferenceManager.inflateTo(result, R.xml.pref_about, emptyList(), AboutSettingsFragment::class.java)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun PreferenceManager.inflateTo(
|
||||
result: MutableList<SettingsItem>,
|
||||
@XmlRes resId: Int,
|
||||
breadcrumbs: List<String>,
|
||||
fragmentClass: Class<out PreferenceFragmentCompat>
|
||||
) {
|
||||
val screen = inflateFromResource(context, resId, null)
|
||||
val screenTitle = screen.title?.toString()
|
||||
screen.inflateTo(
|
||||
result = result,
|
||||
breadcrumbs = if (screenTitle.isNullOrEmpty()) breadcrumbs else breadcrumbs + screenTitle,
|
||||
fragmentClass = fragmentClass,
|
||||
)
|
||||
}
|
||||
|
||||
private fun PreferenceScreen.inflateTo(
|
||||
result: MutableList<SettingsItem>,
|
||||
breadcrumbs: List<String>,
|
||||
fragmentClass: Class<out PreferenceFragmentCompat>
|
||||
): Unit = repeat(preferenceCount) { i ->
|
||||
val pref = this[i]
|
||||
if (pref is PreferenceScreen) {
|
||||
val screenTitle = pref.title?.toString()
|
||||
pref.inflateTo(
|
||||
result = result,
|
||||
breadcrumbs = if (screenTitle.isNullOrEmpty()) breadcrumbs else breadcrumbs + screenTitle,
|
||||
fragmentClass = fragmentClass,
|
||||
)
|
||||
} else {
|
||||
result.add(
|
||||
SettingsItem(
|
||||
key = pref.key ?: return@repeat,
|
||||
title = pref.title ?: return@repeat,
|
||||
breadcrumbs = breadcrumbs,
|
||||
fragmentClass = fragmentClass,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.koitharu.kotatsu.settings.search
|
||||
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.MenuProvider
|
||||
import org.koitharu.kotatsu.R
|
||||
|
||||
class SettingsSearchMenuProvider(
|
||||
private val viewModel: SettingsSearchViewModel,
|
||||
) : MenuProvider, MenuItem.OnActionExpandListener, SearchView.OnQueryTextListener {
|
||||
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.opt_search, menu)
|
||||
val menuItem = menu.findItem(R.id.action_search)
|
||||
menuItem.setOnActionExpandListener(this)
|
||||
val searchView = menuItem.actionView as SearchView
|
||||
searchView.setOnQueryTextListener(this)
|
||||
searchView.queryHint = menuItem.title
|
||||
}
|
||||
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
super.onPrepareMenu(menu)
|
||||
val currentQuery = viewModel.currentQuery
|
||||
if (currentQuery.isNotEmpty()) {
|
||||
val menuItem = menu.findItem(R.id.action_search)
|
||||
menuItem.expandActionView()
|
||||
val searchView = menuItem.actionView as SearchView
|
||||
searchView.setQuery(currentQuery, false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = false
|
||||
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean = true
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
viewModel.discardSearch()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
viewModel.onQueryChanged(newText.orEmpty())
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.koitharu.kotatsu.settings.search
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.plus
|
||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
||||
import org.koitharu.kotatsu.core.util.ext.call
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class SettingsSearchViewModel @Inject constructor(
|
||||
private val searchHelper: SettingsSearchHelper,
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val query = MutableStateFlow("")
|
||||
private val allSettings by lazy {
|
||||
searchHelper.inflatePreferences()
|
||||
}
|
||||
|
||||
val content = query.map { q ->
|
||||
allSettings.filter { it.title.contains(q, ignoreCase = true) }
|
||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Lazily, emptyList())
|
||||
|
||||
val isSearchActive = query.map {
|
||||
it.isNotEmpty()
|
||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Lazily, false)
|
||||
|
||||
val onNavigateToPreference = MutableEventFlow<SettingsItem>()
|
||||
val currentQuery: String
|
||||
get() = query.value
|
||||
|
||||
fun onQueryChanged(value: String) {
|
||||
query.value = value
|
||||
}
|
||||
|
||||
fun discardSearch() = onQueryChanged("")
|
||||
|
||||
fun navigateToPreference(item: SettingsItem) {
|
||||
onNavigateToPreference.call(item)
|
||||
}
|
||||
}
|
||||
@@ -72,4 +72,15 @@
|
||||
app:layout_constraintStart_toEndOf="@id/container_master"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/container_search"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:visibility="gone"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/appbar" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -26,4 +26,11 @@
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/container_search"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
31
app/src/main/res/layout/item_preference.xml
Normal file
31
app/src/main/res/layout/item_preference.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clipToPadding="false"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:orientation="vertical"
|
||||
android:padding="4dp"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
tools:text="@string/too_many_requests_message" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_summary"
|
||||
style="@style/PreferenceSummaryTextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
tools:text="@string/tap_to_try_again" />
|
||||
|
||||
</LinearLayout>
|
||||
4
app/src/main/res/values-ldrtl/strings.xml
Normal file
4
app/src/main/res/values-ldrtl/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="breadcrumbs_separator" translatable="false"><![CDATA[" < "]]></string>
|
||||
</resources>
|
||||
@@ -757,4 +757,5 @@
|
||||
<string name="screen_orientation">Screen orientation</string>
|
||||
<string name="portrait">Portrait</string>
|
||||
<string name="landscape">Landscape</string>
|
||||
<string name="breadcrumbs_separator" translatable="false"><![CDATA[" > "]]></string>
|
||||
</resources>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/about">
|
||||
|
||||
<Preference
|
||||
android:key="app_version"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/appearance">
|
||||
|
||||
<org.koitharu.kotatsu.settings.utils.ThemeChooserPreference
|
||||
android:key="color_theme"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/periodic_backups">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:title="@string/downloads"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Preference
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/network"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<ListPreference
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/notifications">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
@@ -35,4 +36,4 @@
|
||||
app:allowDividerAbove="true"
|
||||
app:isPreferenceVisible="false" />
|
||||
|
||||
</PreferenceScreen>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/proxy">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="DIRECT"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/reader_settings">
|
||||
|
||||
<ListPreference
|
||||
android:entries="@array/reader_modes"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/services">
|
||||
|
||||
<Preference
|
||||
android:enabled="@bool/is_sync_enabled"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/remote_sources">
|
||||
|
||||
<ListPreference
|
||||
android:key="sources_sort_order"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/suggestions">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/check_for_new_chapters">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/data_and_privacy">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="protect_app"
|
||||
|
||||
Reference in New Issue
Block a user