SettingsFragment.kt 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package im.angry.openeuicc.ui
  2. import android.content.Intent
  3. import android.net.Uri
  4. import android.os.Bundle
  5. import android.widget.Toast
  6. import androidx.datastore.preferences.core.Preferences
  7. import androidx.lifecycle.lifecycleScope
  8. import androidx.preference.CheckBoxPreference
  9. import androidx.preference.Preference
  10. import androidx.preference.PreferenceCategory
  11. import androidx.preference.PreferenceFragmentCompat
  12. import im.angry.openeuicc.common.R
  13. import im.angry.openeuicc.util.*
  14. import kotlinx.coroutines.flow.Flow
  15. import kotlinx.coroutines.flow.collect
  16. import kotlinx.coroutines.flow.onEach
  17. import kotlinx.coroutines.launch
  18. import kotlinx.coroutines.runBlocking
  19. class SettingsFragment: PreferenceFragmentCompat() {
  20. private lateinit var developerPref: PreferenceCategory
  21. // Hidden developer options switch
  22. private var numClicks = 0
  23. private var lastClickTimestamp = -1L
  24. private var lastToast: Toast? = null
  25. override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
  26. setPreferencesFromResource(R.xml.pref_settings, rootKey)
  27. developerPref = findPreference("pref_developer")!!
  28. // Show / hide developer preference based on whether it is enabled
  29. lifecycleScope.launch {
  30. preferenceRepository.developerOptionsEnabledFlow.onEach {
  31. developerPref.isVisible = it
  32. }.collect()
  33. }
  34. findPreference<Preference>("pref_info_app_version")
  35. ?.apply {
  36. summary = requireContext().selfAppVersion
  37. // Enable developer options when this is clicked for 7 times
  38. setOnPreferenceClickListener(this@SettingsFragment::onAppVersionClicked)
  39. }
  40. findPreference<Preference>("pref_info_source_code")
  41. ?.setOnPreferenceClickListener {
  42. startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(it.summary.toString())))
  43. true
  44. }
  45. findPreference<Preference>("pref_advanced_logs")
  46. ?.setOnPreferenceClickListener {
  47. startActivity(Intent(requireContext(), LogsActivity::class.java))
  48. true
  49. }
  50. findPreference<CheckBoxPreference>("pref_notifications_download")
  51. ?.bindBooleanFlow(preferenceRepository.notificationDownloadFlow, PreferenceKeys.NOTIFICATION_DOWNLOAD)
  52. findPreference<CheckBoxPreference>("pref_notifications_delete")
  53. ?.bindBooleanFlow(preferenceRepository.notificationDeleteFlow, PreferenceKeys.NOTIFICATION_DELETE)
  54. findPreference<CheckBoxPreference>("pref_notifications_switch")
  55. ?.bindBooleanFlow(preferenceRepository.notificationSwitchFlow, PreferenceKeys.NOTIFICATION_SWITCH)
  56. findPreference<CheckBoxPreference>("pref_advanced_disable_safeguard_removable_esim")
  57. ?.bindBooleanFlow(preferenceRepository.disableSafeguardFlow, PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM)
  58. findPreference<CheckBoxPreference>("pref_advanced_verbose_logging")
  59. ?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow, PreferenceKeys.VERBOSE_LOGGING)
  60. findPreference<CheckBoxPreference>("pref_developer_experimental_download_wizard")
  61. ?.bindBooleanFlow(preferenceRepository.experimentalDownloadWizardFlow, PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD)
  62. findPreference<CheckBoxPreference>("pref_developer_unfiltered_profile_list")
  63. ?.bindBooleanFlow(preferenceRepository.unfilteredProfileListFlow, PreferenceKeys.UNFILTERED_PROFILE_LIST)
  64. findPreference<CheckBoxPreference>("pref_ignore_tls_certificate")
  65. ?.bindBooleanFlow(preferenceRepository.ignoreTLSCertificateFlow, PreferenceKeys.IGNORE_TLS_CERTIFICATE)
  66. }
  67. override fun onStart() {
  68. super.onStart()
  69. setupRootViewInsets(requireView().requireViewById(R.id.recycler_view))
  70. }
  71. @Suppress("UNUSED_PARAMETER")
  72. private fun onAppVersionClicked(pref: Preference): Boolean {
  73. if (developerPref.isVisible) return false
  74. val now = System.currentTimeMillis()
  75. if (now - lastClickTimestamp >= 1000) {
  76. numClicks = 1
  77. } else {
  78. numClicks++
  79. }
  80. lastClickTimestamp = now
  81. if (numClicks == 7) {
  82. lifecycleScope.launch {
  83. preferenceRepository.updatePreference(
  84. PreferenceKeys.DEVELOPER_OPTIONS_ENABLED,
  85. true
  86. )
  87. lastToast?.cancel()
  88. Toast.makeText(
  89. requireContext(),
  90. R.string.developer_options_enabled,
  91. Toast.LENGTH_SHORT
  92. ).show()
  93. }
  94. } else if (numClicks > 1) {
  95. lastToast?.cancel()
  96. lastToast = Toast.makeText(
  97. requireContext(),
  98. getString(R.string.developer_options_steps, 7 - numClicks),
  99. Toast.LENGTH_SHORT
  100. )
  101. lastToast!!.show()
  102. }
  103. return true
  104. }
  105. private fun CheckBoxPreference.bindBooleanFlow(flow: Flow<Boolean>, key: Preferences.Key<Boolean>) {
  106. lifecycleScope.launch {
  107. flow.collect { isChecked = it }
  108. }
  109. setOnPreferenceChangeListener { _, newValue ->
  110. runBlocking {
  111. preferenceRepository.updatePreference(key, newValue as Boolean)
  112. }
  113. true
  114. }
  115. }
  116. }