You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
11 KiB
Kotlin
268 lines
11 KiB
Kotlin
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.fenix.settings
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.os.Build
|
|
import android.os.Build.VERSION.SDK_INT
|
|
import android.os.Bundle
|
|
import androidx.appcompat.app.AppCompatDelegate
|
|
import androidx.core.content.edit
|
|
import androidx.preference.EditTextPreference
|
|
import androidx.preference.Preference
|
|
import androidx.preference.PreferenceCategory
|
|
import androidx.preference.PreferenceFragmentCompat
|
|
import androidx.preference.SwitchPreference
|
|
import org.mozilla.fenix.FeatureFlags
|
|
import org.mozilla.fenix.R
|
|
import org.mozilla.fenix.components.metrics.Event
|
|
import org.mozilla.fenix.components.toolbar.ToolbarPosition
|
|
import org.mozilla.fenix.ext.components
|
|
import org.mozilla.fenix.ext.requireComponents
|
|
import org.mozilla.fenix.ext.settings
|
|
import org.mozilla.fenix.ext.showToolbar
|
|
import org.mozilla.fenix.utils.view.addToRadioGroup
|
|
|
|
/**
|
|
* Lets the user customize the UI.
|
|
*/
|
|
|
|
@Suppress("LargeClass", "TooManyFunctions")
|
|
class CustomizationFragment : PreferenceFragmentCompat() {
|
|
private lateinit var radioLightTheme: RadioButtonPreference
|
|
private lateinit var radioDarkTheme: RadioButtonPreference
|
|
private lateinit var radioAutoBatteryTheme: RadioButtonPreference
|
|
private lateinit var radioFollowDeviceTheme: RadioButtonPreference
|
|
|
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
setPreferencesFromResource(R.xml.customization_preferences, rootKey)
|
|
|
|
requirePreference<SwitchPreference>(R.string.pref_key_strip_url).apply {
|
|
isChecked = context.settings().shouldStripUrl
|
|
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
}
|
|
|
|
override fun onResume() {
|
|
super.onResume()
|
|
showToolbar(getString(R.string.preferences_customize))
|
|
setupPreferences()
|
|
}
|
|
|
|
private fun setupPreferences() {
|
|
bindFollowDeviceTheme()
|
|
bindDarkTheme()
|
|
bindLightTheme()
|
|
bindAutoBatteryTheme()
|
|
setupRadioGroups()
|
|
setupToolbarCategory()
|
|
setupTabsTrayCategory()
|
|
setupFabCategory()
|
|
setupHomeCategory()
|
|
setupGesturesCategory()
|
|
setupAddonsCustomizationCategory()
|
|
setupSystemBehaviorCategory()
|
|
}
|
|
|
|
private fun setupRadioGroups() {
|
|
addToRadioGroup(
|
|
radioLightTheme,
|
|
radioDarkTheme,
|
|
if (SDK_INT >= Build.VERSION_CODES.P) {
|
|
radioFollowDeviceTheme
|
|
} else {
|
|
radioAutoBatteryTheme
|
|
}
|
|
)
|
|
}
|
|
|
|
private fun bindLightTheme() {
|
|
radioLightTheme = requirePreference(R.string.pref_key_light_theme)
|
|
radioLightTheme.onClickListener {
|
|
setNewTheme(AppCompatDelegate.MODE_NIGHT_NO)
|
|
}
|
|
}
|
|
|
|
@SuppressLint("WrongConstant")
|
|
// Suppressing erroneous lint warning about using MODE_NIGHT_AUTO_BATTERY, a likely library bug
|
|
private fun bindAutoBatteryTheme() {
|
|
radioAutoBatteryTheme = requirePreference(R.string.pref_key_auto_battery_theme)
|
|
radioAutoBatteryTheme.onClickListener {
|
|
setNewTheme(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY)
|
|
}
|
|
}
|
|
|
|
private fun bindDarkTheme() {
|
|
radioDarkTheme = requirePreference(R.string.pref_key_dark_theme)
|
|
radioDarkTheme.onClickListener {
|
|
requireContext().components.analytics.metrics.track(
|
|
Event.DarkThemeSelected(
|
|
Event.DarkThemeSelected.Source.SETTINGS
|
|
)
|
|
)
|
|
setNewTheme(AppCompatDelegate.MODE_NIGHT_YES)
|
|
}
|
|
}
|
|
|
|
private fun bindFollowDeviceTheme() {
|
|
radioFollowDeviceTheme = requirePreference(R.string.pref_key_follow_device_theme)
|
|
if (SDK_INT >= Build.VERSION_CODES.P) {
|
|
radioFollowDeviceTheme.onClickListener {
|
|
setNewTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun setNewTheme(mode: Int) {
|
|
if (AppCompatDelegate.getDefaultNightMode() == mode) return
|
|
AppCompatDelegate.setDefaultNightMode(mode)
|
|
activity?.recreate()
|
|
with(requireComponents.core) {
|
|
engine.settings.preferredColorScheme = getPreferredColorScheme()
|
|
}
|
|
requireComponents.useCases.sessionUseCases.reload.invoke()
|
|
}
|
|
|
|
private fun setupToolbarCategory() {
|
|
val topPreference = requirePreference<RadioButtonPreference>(R.string.pref_key_toolbar_top)
|
|
topPreference.onClickListener {
|
|
requireContext().components.analytics.metrics.track(Event.ToolbarPositionChanged(
|
|
Event.ToolbarPositionChanged.Position.TOP
|
|
))
|
|
}
|
|
|
|
val bottomPreference = requirePreference<RadioButtonPreference>(R.string.pref_key_toolbar_bottom)
|
|
bottomPreference.onClickListener {
|
|
requireContext().components.analytics.metrics.track(Event.ToolbarPositionChanged(
|
|
Event.ToolbarPositionChanged.Position.BOTTOM
|
|
))
|
|
}
|
|
|
|
val toolbarPosition = requireContext().settings().toolbarPosition
|
|
topPreference.setCheckedWithoutClickListener(toolbarPosition == ToolbarPosition.TOP)
|
|
bottomPreference.setCheckedWithoutClickListener(toolbarPosition == ToolbarPosition.BOTTOM)
|
|
|
|
addToRadioGroup(topPreference, bottomPreference)
|
|
}
|
|
|
|
private fun setupTabsTrayCategory() {
|
|
requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_top_tray).apply {
|
|
isChecked = context.settings().useTopTabsTray
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
|
|
requirePreference<SwitchPreference>(R.string.pref_key_use_fullscreen_tabs_screen).apply {
|
|
isChecked = context.settings().useFullScreenTabScreen
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
|
|
val reverseOrderPref = requirePreference<SwitchPreference>(
|
|
R.string.pref_key_tabs_tray_reverse_tab_order).apply {
|
|
if (context.settings().enableCompactTabs) {
|
|
isChecked = false
|
|
isEnabled = false
|
|
} else {
|
|
isChecked = context.settings().reverseTabOrderInTabsTray
|
|
isEnabled = true
|
|
}
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
|
|
requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_compact_tab).apply {
|
|
isChecked = context.settings().enableCompactTabs
|
|
|
|
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, newValue ->
|
|
val newValueBoolean = newValue as Boolean
|
|
preference.context.settings().preferences.edit {
|
|
putBoolean(preference.key, newValueBoolean)
|
|
if (newValueBoolean) {
|
|
reverseOrderPref.isChecked = false
|
|
putBoolean(getString(R.string.pref_key_tabs_tray_reverse_tab_order), false)
|
|
}
|
|
reverseOrderPref.isEnabled = !newValueBoolean
|
|
}
|
|
true
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun setupFabCategory() {
|
|
val fabPositionTop = requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_fab_top_position).apply {
|
|
if (context.settings().useNewTabFloatingActionButton) {
|
|
isChecked = context.settings().placeNewTabFloatingActionButtonAtTop
|
|
isEnabled = true
|
|
} else {
|
|
isChecked = false
|
|
isEnabled = false
|
|
}
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
|
|
requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_use_fab).apply {
|
|
isChecked = context.settings().useNewTabFloatingActionButton
|
|
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, newValue ->
|
|
val newValueBoolean = newValue as Boolean
|
|
preference.context.settings().preferences.edit {
|
|
putBoolean(preference.key, newValueBoolean)
|
|
if (!newValueBoolean) {
|
|
fabPositionTop.isChecked = false
|
|
putBoolean(getString(R.string.pref_key_tabs_tray_fab_top_position), false)
|
|
}
|
|
fabPositionTop.isEnabled = newValueBoolean
|
|
}
|
|
true
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun setupHomeCategory() {
|
|
requirePreference<PreferenceCategory>(R.string.pref_home_category).apply {
|
|
isVisible = FeatureFlags.topFrecentSite
|
|
}
|
|
|
|
requirePreference<SwitchPreference>(R.string.pref_key_enable_top_frecent_sites).apply {
|
|
isVisible = FeatureFlags.topFrecentSite
|
|
isChecked = context.settings().showTopFrecentSites
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
}
|
|
|
|
private fun setupGesturesCategory() {
|
|
requirePreference<SwitchPreference>(R.string.pref_key_website_pull_to_refresh).apply {
|
|
isVisible = FeatureFlags.pullToRefreshEnabled
|
|
isChecked = context.settings().isPullToRefreshEnabledInBrowser
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
requirePreference<SwitchPreference>(R.string.pref_key_dynamic_toolbar).apply {
|
|
isChecked = context.settings().isDynamicToolbarEnabled
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
requirePreference<SwitchPreference>(R.string.pref_key_swipe_toolbar_switch_tabs).apply {
|
|
isChecked = context.settings().isSwipeToolbarToSwitchTabsEnabled
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
}
|
|
|
|
private fun setupAddonsCustomizationCategory() {
|
|
requirePreference<EditTextPreference>(R.string.pref_key_addons_custom_account).apply {
|
|
text = context.settings().customAddonsAccount
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
|
|
requirePreference<EditTextPreference>(R.string.pref_key_addons_custom_collection).apply {
|
|
text = context.settings().customAddonsCollection
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
}
|
|
|
|
private fun setupSystemBehaviorCategory() {
|
|
requirePreference<SwitchPreference>(R.string.pref_key_relinquish_memory_under_pressure).apply {
|
|
isChecked = context.settings().shouldRelinquishMemoryUnderPressure
|
|
onPreferenceChangeListener = SharedPreferenceUpdater()
|
|
}
|
|
}
|
|
}
|