Compare commits
2 commits
47d5c3881c
...
5f0dbe3098
Author | SHA1 | Date | |
---|---|---|---|
5f0dbe3098 | |||
efa9b8bfa4 |
6 changed files with 114 additions and 8 deletions
|
@ -3,23 +3,48 @@ package im.angry.openeuicc.ui
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.CheckBoxPreference
|
import androidx.preference.CheckBoxPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceCategory
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import im.angry.openeuicc.common.R
|
import im.angry.openeuicc.common.R
|
||||||
import im.angry.openeuicc.util.*
|
import im.angry.openeuicc.util.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
class SettingsFragment: PreferenceFragmentCompat() {
|
class SettingsFragment: PreferenceFragmentCompat() {
|
||||||
|
private lateinit var developerPref: PreferenceCategory
|
||||||
|
|
||||||
|
// Hidden developer options switch
|
||||||
|
private var numClicks = 0
|
||||||
|
private var lastClickTimestamp = -1L
|
||||||
|
private var lastToast: Toast? = null
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
setPreferencesFromResource(R.xml.pref_settings, rootKey)
|
setPreferencesFromResource(R.xml.pref_settings, rootKey)
|
||||||
|
|
||||||
|
developerPref = findPreference("pref_developer")!!
|
||||||
|
|
||||||
|
// Show / hide developer preference based on whether it is enabled
|
||||||
|
lifecycleScope.launch {
|
||||||
|
preferenceRepository.developerOptionsEnabledFlow.onEach {
|
||||||
|
developerPref.isVisible = it
|
||||||
|
}.collect()
|
||||||
|
}
|
||||||
|
|
||||||
findPreference<Preference>("pref_info_app_version")
|
findPreference<Preference>("pref_info_app_version")
|
||||||
?.summary = requireContext().selfAppVersion
|
?.apply {
|
||||||
|
summary = requireContext().selfAppVersion
|
||||||
|
|
||||||
|
// Enable developer options when this is clicked for 7 times
|
||||||
|
setOnPreferenceClickListener(this@SettingsFragment::onAppVersionClicked)
|
||||||
|
}
|
||||||
|
|
||||||
findPreference<Preference>("pref_info_source_code")
|
findPreference<Preference>("pref_info_source_code")
|
||||||
?.setOnPreferenceClickListener {
|
?.setOnPreferenceClickListener {
|
||||||
|
@ -48,7 +73,7 @@ class SettingsFragment: PreferenceFragmentCompat() {
|
||||||
findPreference<CheckBoxPreference>("pref_advanced_verbose_logging")
|
findPreference<CheckBoxPreference>("pref_advanced_verbose_logging")
|
||||||
?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow, PreferenceKeys.VERBOSE_LOGGING)
|
?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow, PreferenceKeys.VERBOSE_LOGGING)
|
||||||
|
|
||||||
findPreference<CheckBoxPreference>("pref_advanced_experimental_download_wizard")
|
findPreference<CheckBoxPreference>("pref_developer_experimental_download_wizard")
|
||||||
?.bindBooleanFlow(preferenceRepository.experimentalDownloadWizardFlow, PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD)
|
?.bindBooleanFlow(preferenceRepository.experimentalDownloadWizardFlow, PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +82,44 @@ class SettingsFragment: PreferenceFragmentCompat() {
|
||||||
setupRootViewInsets(requireView().requireViewById(androidx.preference.R.id.recycler_view))
|
setupRootViewInsets(requireView().requireViewById(androidx.preference.R.id.recycler_view))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
|
private fun onAppVersionClicked(pref: Preference): Boolean {
|
||||||
|
if (developerPref.isVisible) return false
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
if (now - lastClickTimestamp >= 1000) {
|
||||||
|
numClicks = 1
|
||||||
|
} else {
|
||||||
|
numClicks++
|
||||||
|
}
|
||||||
|
lastClickTimestamp = now
|
||||||
|
|
||||||
|
if (numClicks == 7) {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
preferenceRepository.updatePreference(
|
||||||
|
PreferenceKeys.DEVELOPER_OPTIONS_ENABLED,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
lastToast?.cancel()
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
R.string.developer_options_enabled,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
} else if (numClicks > 1) {
|
||||||
|
lastToast?.cancel()
|
||||||
|
lastToast = Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
getString(R.string.developer_options_steps, 7 - numClicks),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
lastToast!!.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun CheckBoxPreference.bindBooleanFlow(flow: Flow<Boolean>, key: Preferences.Key<Boolean>) {
|
private fun CheckBoxPreference.bindBooleanFlow(flow: Flow<Boolean>, key: Preferences.Key<Boolean>) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
flow.collect { isChecked = it }
|
flow.collect { isChecked = it }
|
||||||
|
|
|
@ -2,6 +2,7 @@ package im.angry.openeuicc.ui.wizard
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.ProgressBar
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
|
@ -11,6 +12,8 @@ import im.angry.openeuicc.common.R
|
||||||
import im.angry.openeuicc.ui.BaseEuiccAccessActivity
|
import im.angry.openeuicc.ui.BaseEuiccAccessActivity
|
||||||
|
|
||||||
class DownloadWizardActivity: BaseEuiccAccessActivity() {
|
class DownloadWizardActivity: BaseEuiccAccessActivity() {
|
||||||
|
private lateinit var progressBar: ProgressBar
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -21,6 +24,8 @@ class DownloadWizardActivity: BaseEuiccAccessActivity() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
progressBar = requireViewById(R.id.progress)
|
||||||
|
|
||||||
val navigation = requireViewById<View>(R.id.download_wizard_navigation)
|
val navigation = requireViewById<View>(R.id.download_wizard_navigation)
|
||||||
val origHeight = navigation.layoutParams.height
|
val origHeight = navigation.layoutParams.height
|
||||||
|
|
||||||
|
@ -38,6 +43,6 @@ class DownloadWizardActivity: BaseEuiccAccessActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onInit() {
|
override fun onInit() {
|
||||||
|
progressBar.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,7 @@ object PreferenceKeys {
|
||||||
val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch")
|
val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch")
|
||||||
val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim")
|
val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim")
|
||||||
val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging")
|
val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging")
|
||||||
|
val DEVELOPER_OPTIONS_ENABLED = booleanPreferencesKey("developer_options_enabled")
|
||||||
val EXPERIMENTAL_DOWNLOAD_WIZARD = booleanPreferencesKey("experimental_download_wizard")
|
val EXPERIMENTAL_DOWNLOAD_WIZARD = booleanPreferencesKey("experimental_download_wizard")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +50,10 @@ class PreferenceRepository(context: Context) {
|
||||||
val verboseLoggingFlow: Flow<Boolean> =
|
val verboseLoggingFlow: Flow<Boolean> =
|
||||||
dataStore.data.map { it[PreferenceKeys.VERBOSE_LOGGING] ?: false }
|
dataStore.data.map { it[PreferenceKeys.VERBOSE_LOGGING] ?: false }
|
||||||
|
|
||||||
|
// ---- Developer Options ----
|
||||||
|
val developerOptionsEnabledFlow: Flow<Boolean> =
|
||||||
|
dataStore.data.map { it[PreferenceKeys.DEVELOPER_OPTIONS_ENABLED] ?: false }
|
||||||
|
|
||||||
val experimentalDownloadWizardFlow: Flow<Boolean> =
|
val experimentalDownloadWizardFlow: Flow<Boolean> =
|
||||||
dataStore.data.map { it[PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD] ?: false }
|
dataStore.data.map { it[PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD] ?: false }
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,27 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/guideline"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/download_wizard_navigation"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/guideline"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/download_wizard_navigation"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/download_wizard_navigation"
|
android:id="@+id/download_wizard_navigation"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -101,6 +101,9 @@
|
||||||
<string name="logs_save">Save</string>
|
<string name="logs_save">Save</string>
|
||||||
<string name="logs_filename_template">Logs at %s</string>
|
<string name="logs_filename_template">Logs at %s</string>
|
||||||
|
|
||||||
|
<string name="developer_options_steps">You are %d steps away from being a developer.</string>
|
||||||
|
<string name="developer_options_enabled">You are now a developer!</string>
|
||||||
|
|
||||||
<string name="pref_settings">Settings</string>
|
<string name="pref_settings">Settings</string>
|
||||||
<string name="pref_notifications">Notifications</string>
|
<string name="pref_notifications">Notifications</string>
|
||||||
<string name="pref_notifications_desc">eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here.</string>
|
<string name="pref_notifications_desc">eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here.</string>
|
||||||
|
@ -117,8 +120,9 @@
|
||||||
<string name="pref_advanced_verbose_logging_desc">Enable verbose logs, which may contain sensitive information. Only share your logs with someone you trust after turning this on.</string>
|
<string name="pref_advanced_verbose_logging_desc">Enable verbose logs, which may contain sensitive information. Only share your logs with someone you trust after turning this on.</string>
|
||||||
<string name="pref_advanced_logs">Logs</string>
|
<string name="pref_advanced_logs">Logs</string>
|
||||||
<string name="pref_advanced_logs_desc">View recent debug logs of the application</string>
|
<string name="pref_advanced_logs_desc">View recent debug logs of the application</string>
|
||||||
<string name="pref_advanced_experimental_download_wizard">Experimental Download Wizard</string>
|
<string name="pref_developer">Developer Options</string>
|
||||||
<string name="pref_advanced_experimental_download_wizard_desc">Enable the experimental new download wizard. Note that it is not fully working yet.</string>
|
<string name="pref_developer_experimental_download_wizard">Experimental Download Wizard</string>
|
||||||
|
<string name="pref_developer_experimental_download_wizard_desc">Enable the experimental new download wizard. Note that it is not fully working yet.</string>
|
||||||
<string name="pref_info">Info</string>
|
<string name="pref_info">Info</string>
|
||||||
<string name="pref_info_app_version">App Version</string>
|
<string name="pref_info_app_version">App Version</string>
|
||||||
<string name="pref_info_source_code">Source Code</string>
|
<string name="pref_info_source_code">Source Code</string>
|
||||||
|
|
|
@ -42,11 +42,19 @@
|
||||||
app:title="@string/pref_advanced_logs"
|
app:title="@string/pref_advanced_logs"
|
||||||
app:summary="@string/pref_advanced_logs_desc" />
|
app:summary="@string/pref_advanced_logs_desc" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
app:key="pref_developer"
|
||||||
|
app:title="@string/pref_developer"
|
||||||
|
app:iconSpaceReserved="false">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
app:key="pref_advanced_experimental_download_wizard"
|
app:key="pref_developer_experimental_download_wizard"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:title="@string/pref_advanced_experimental_download_wizard"
|
app:title="@string/pref_developer_experimental_download_wizard"
|
||||||
app:summary="@string/pref_advanced_experimental_download_wizard_desc" />
|
app:summary="@string/pref_developer_experimental_download_wizard_desc" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|
Loading…
Add table
Reference in a new issue