From daa182b9775f9957ab2626e20a3f33e910f98de7 Mon Sep 17 00:00:00 2001 From: aAbed Date: Sat, 20 Jul 2024 20:33:06 +0545 Subject: [PATCH 1/5] feat: Add confirm dialogs when toggling dangerous settings --- .../component/SafeguardConfirmationDialog.kt | 46 +++++++++++++++++++ .../ui/component/settings/BooleanItem.kt | 30 +++++++++++- .../screen/settings/AdvancedSettingsScreen.kt | 20 ++++++-- app/src/main/res/values/strings.xml | 6 +++ 4 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/app/revanced/manager/ui/component/SafeguardConfirmationDialog.kt diff --git a/app/src/main/java/app/revanced/manager/ui/component/SafeguardConfirmationDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/SafeguardConfirmationDialog.kt new file mode 100644 index 0000000000..72abf4d75a --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/SafeguardConfirmationDialog.kt @@ -0,0 +1,46 @@ +package app.revanced.manager.ui.component + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.WarningAmber +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import app.revanced.manager.R + +@Composable +fun SafeguardConfirmationDialog( + onDismiss: () -> Unit, + onConfirm: () -> Unit, + body: String, +) { + AlertDialog( + onDismissRequest = onDismiss, + confirmButton = { + TextButton(onClick = onConfirm) { + Text(stringResource(R.string.yes)) + } + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text(stringResource(R.string.no)) + } + }, + icon = { + Icon(Icons.Outlined.WarningAmber, null) + }, + title = { + Text( + text = stringResource(id = R.string.warning), + style = MaterialTheme.typography.headlineSmall.copy(textAlign = TextAlign.Center) + ) + }, + text = { + Text(body) + } + ) +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt index 42e9a83e2f..e40cc2d14b 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt @@ -5,27 +5,53 @@ import androidx.compose.foundation.clickable import androidx.compose.material3.Switch import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import app.revanced.manager.domain.manager.base.Preference +import app.revanced.manager.ui.component.SafeguardConfirmationDialog import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @Composable fun BooleanItem( modifier: Modifier = Modifier, + isSafeguard: Boolean = false, + suggestedValue: Boolean = false, preference: Preference, coroutineScope: CoroutineScope = rememberCoroutineScope(), @StringRes headline: Int, - @StringRes description: Int + @StringRes description: Int, + @StringRes confirmationText: Int = 0 ) { val value by preference.getAsState() + var showSafeguardWarning by rememberSaveable { + mutableStateOf(false) + } + + if (showSafeguardWarning) { + SafeguardConfirmationDialog( + onDismiss = { showSafeguardWarning = false }, + onConfirm = { + coroutineScope.launch { preference.update(!value) } + showSafeguardWarning = false + }, + body = stringResource(confirmationText) + ) + } BooleanItem( modifier = modifier, value = value, - onValueChange = { coroutineScope.launch { preference.update(it) } }, + onValueChange = { + if (isSafeguard && it != suggestedValue) { + showSafeguardWarning = true + } else { + coroutineScope.launch { preference.update(it) } + }}, headline = headline, description = description ) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt index 4c3be2a400..672af52654 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt @@ -122,28 +122,40 @@ fun AdvancedSettingsScreen( GroupHeader(stringResource(R.string.safeguards)) BooleanItem( + isSafeguard = true, + suggestedValue = false, preference = vm.prefs.disablePatchVersionCompatCheck, coroutineScope = vm.viewModelScope, headline = R.string.patch_compat_check, - description = R.string.patch_compat_check_description + description = R.string.patch_compat_check_description, + confirmationText = R.string.patch_compat_check_confirmation ) BooleanItem( + isSafeguard = true, + suggestedValue = false, preference = vm.prefs.disableUniversalPatchWarning, coroutineScope = vm.viewModelScope, headline = R.string.universal_patches_safeguard, - description = R.string.universal_patches_safeguard_description + description = R.string.universal_patches_safeguard_description, + confirmationText = R.string.universal_patches_safeguard_confirmation ) BooleanItem( + isSafeguard = true, + suggestedValue = true, preference = vm.prefs.suggestedVersionSafeguard, coroutineScope = vm.viewModelScope, headline = R.string.suggested_version_safeguard, - description = R.string.suggested_version_safeguard_description + description = R.string.suggested_version_safeguard_description, + confirmationText = R.string.suggested_version_safeguard_confirmation ) BooleanItem( + isSafeguard = true, + suggestedValue = false, preference = vm.prefs.disableSelectionWarning, coroutineScope = vm.viewModelScope, headline = R.string.patch_selection_safeguard, - description = R.string.patch_selection_safeguard_description + description = R.string.patch_selection_safeguard_description, + confirmationText = R.string.patch_selection_safeguard_confirmation ) GroupHeader(stringResource(R.string.debugging)) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 36cbea3aa8..733de07c2e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,12 +74,16 @@ Safeguards Disable version compatibility check The check restricts patches to supported app versions + The check restricts patches to supported app versions Require suggested app version Enforce selection of the suggested app version + Enforce selection of the suggested app version Allow changing patch selection Do not prevent selecting or deselecting patches + Do not prevent selecting or deselecting patches Disable universal patch warning Disables the warning that appears when you try to select universal patches + Disables the warning that appears when you try to select universal patches Import keystore Import a custom keystore Enter keystore credentials @@ -125,6 +129,8 @@ Options OK + Yes + No Edit Value Reset From 6b1aa3999667e5d416d17e2e00b709d939a057d9 Mon Sep 17 00:00:00 2001 From: aAbed Date: Sat, 20 Jul 2024 21:09:39 +0545 Subject: [PATCH 2/5] refactor: Apply changes from suggestions --- .../manager/base/BasePreferencesManager.kt | 2 +- .../ui/component/settings/BooleanItem.kt | 30 +------- .../settings/SafeguardBooleanItem.kt | 77 +++++++++++++++++++ .../SafeguardConfirmationDialog.kt | 2 +- .../screen/settings/AdvancedSettingsScreen.kt | 17 ++-- 5 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt rename app/src/main/java/app/revanced/manager/ui/component/{ => settings}/SafeguardConfirmationDialog.kt (96%) diff --git a/app/src/main/java/app/revanced/manager/domain/manager/base/BasePreferencesManager.kt b/app/src/main/java/app/revanced/manager/domain/manager/base/BasePreferencesManager.kt index 57810a05e4..2b04bd41c7 100644 --- a/app/src/main/java/app/revanced/manager/domain/manager/base/BasePreferencesManager.kt +++ b/app/src/main/java/app/revanced/manager/domain/manager/base/BasePreferencesManager.kt @@ -56,7 +56,7 @@ class EditorContext(private val prefs: MutablePreferences) { abstract class Preference( private val dataStore: DataStore, - protected val default: T + val default: T ) { internal abstract fun Preferences.read(): T internal abstract fun MutablePreferences.write(value: T) diff --git a/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt index e40cc2d14b..d010d679f9 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt @@ -5,53 +5,29 @@ import androidx.compose.foundation.clickable import androidx.compose.material3.Switch import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import app.revanced.manager.domain.manager.base.Preference -import app.revanced.manager.ui.component.SafeguardConfirmationDialog import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @Composable fun BooleanItem( modifier: Modifier = Modifier, - isSafeguard: Boolean = false, - suggestedValue: Boolean = false, preference: Preference, coroutineScope: CoroutineScope = rememberCoroutineScope(), @StringRes headline: Int, - @StringRes description: Int, - @StringRes confirmationText: Int = 0 + @StringRes description: Int ) { val value by preference.getAsState() - var showSafeguardWarning by rememberSaveable { - mutableStateOf(false) - } - - if (showSafeguardWarning) { - SafeguardConfirmationDialog( - onDismiss = { showSafeguardWarning = false }, - onConfirm = { - coroutineScope.launch { preference.update(!value) } - showSafeguardWarning = false - }, - body = stringResource(confirmationText) - ) - } BooleanItem( modifier = modifier, value = value, onValueChange = { - if (isSafeguard && it != suggestedValue) { - showSafeguardWarning = true - } else { - coroutineScope.launch { preference.update(it) } - }}, + coroutineScope.launch { preference.update(it) } + }, headline = headline, description = description ) diff --git a/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt new file mode 100644 index 0000000000..dcf5cfd555 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt @@ -0,0 +1,77 @@ +package app.revanced.manager.ui.component.settings + +import androidx.annotation.StringRes +import androidx.compose.foundation.clickable +import androidx.compose.material3.Switch +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import app.revanced.manager.domain.manager.base.Preference +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +@Composable +fun SafeguardBooleanItem( + modifier: Modifier = Modifier, + preference: Preference, + coroutineScope: CoroutineScope = rememberCoroutineScope(), + @StringRes headline: Int, + @StringRes description: Int, + @StringRes confirmationText: Int = 0 +) { + val value by preference.getAsState() + var showSafeguardWarning by rememberSaveable { + mutableStateOf(false) + } + + if (showSafeguardWarning) { + SafeguardConfirmationDialog( + onDismiss = { showSafeguardWarning = false }, + onConfirm = { + coroutineScope.launch { preference.update(!value) } + showSafeguardWarning = false + }, + body = stringResource(confirmationText) + ) + } + + SafeguardBooleanItem( + modifier = modifier, + value = value, + onValueChange = { + if (it != preference.default) { + showSafeguardWarning = true + } else { + coroutineScope.launch { preference.update(it) } + } + }, + headline = headline, + description = description + ) +} + +@Composable +fun SafeguardBooleanItem( + modifier: Modifier = Modifier, + value: Boolean, + onValueChange: (Boolean) -> Unit, + @StringRes headline: Int, + @StringRes description: Int +) = SettingsListItem( + modifier = Modifier + .clickable { onValueChange(!value) } + .then(modifier), + headlineContent = stringResource(headline), + supportingContent = stringResource(description), + trailingContent = { + Switch( + checked = value, + onCheckedChange = onValueChange, + ) + } +) \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/component/SafeguardConfirmationDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardConfirmationDialog.kt similarity index 96% rename from app/src/main/java/app/revanced/manager/ui/component/SafeguardConfirmationDialog.kt rename to app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardConfirmationDialog.kt index 72abf4d75a..d3b6d0e818 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/SafeguardConfirmationDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardConfirmationDialog.kt @@ -1,4 +1,4 @@ -package app.revanced.manager.ui.component +package app.revanced.manager.ui.component.settings import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.WarningAmber diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt index 672af52654..7cfaf26715 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt @@ -39,6 +39,7 @@ import app.revanced.manager.ui.component.ColumnWithScrollbar import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.settings.BooleanItem import app.revanced.manager.ui.component.settings.IntegerItem +import app.revanced.manager.ui.component.settings.SafeguardBooleanItem import app.revanced.manager.ui.component.settings.SettingsListItem import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel import org.koin.androidx.compose.koinViewModel @@ -121,36 +122,28 @@ fun AdvancedSettingsScreen( ) GroupHeader(stringResource(R.string.safeguards)) - BooleanItem( - isSafeguard = true, - suggestedValue = false, + SafeguardBooleanItem( preference = vm.prefs.disablePatchVersionCompatCheck, coroutineScope = vm.viewModelScope, headline = R.string.patch_compat_check, description = R.string.patch_compat_check_description, confirmationText = R.string.patch_compat_check_confirmation ) - BooleanItem( - isSafeguard = true, - suggestedValue = false, + SafeguardBooleanItem( preference = vm.prefs.disableUniversalPatchWarning, coroutineScope = vm.viewModelScope, headline = R.string.universal_patches_safeguard, description = R.string.universal_patches_safeguard_description, confirmationText = R.string.universal_patches_safeguard_confirmation ) - BooleanItem( - isSafeguard = true, - suggestedValue = true, + SafeguardBooleanItem( preference = vm.prefs.suggestedVersionSafeguard, coroutineScope = vm.viewModelScope, headline = R.string.suggested_version_safeguard, description = R.string.suggested_version_safeguard_description, confirmationText = R.string.suggested_version_safeguard_confirmation ) - BooleanItem( - isSafeguard = true, - suggestedValue = false, + SafeguardBooleanItem( preference = vm.prefs.disableSelectionWarning, coroutineScope = vm.viewModelScope, headline = R.string.patch_selection_safeguard, From 4636affc045806ed17294bf9673f041978449ccb Mon Sep 17 00:00:00 2001 From: aAbed Date: Sat, 20 Jul 2024 21:11:05 +0545 Subject: [PATCH 3/5] refactor: revert code --- .../app/revanced/manager/ui/component/settings/BooleanItem.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt index d010d679f9..42e9a83e2f 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/BooleanItem.kt @@ -25,9 +25,7 @@ fun BooleanItem( BooleanItem( modifier = modifier, value = value, - onValueChange = { - coroutineScope.launch { preference.update(it) } - }, + onValueChange = { coroutineScope.launch { preference.update(it) } }, headline = headline, description = description ) From 016fbecdf01858ffb5d52893b9ee9792421bc956 Mon Sep 17 00:00:00 2001 From: aAbed Date: Sat, 20 Jul 2024 21:36:23 +0545 Subject: [PATCH 4/5] refactor: remove duplicate function --- .../settings/SafeguardBooleanItem.kt | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt index dcf5cfd555..b9d5fd6dee 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt @@ -1,8 +1,6 @@ package app.revanced.manager.ui.component.settings import androidx.annotation.StringRes -import androidx.compose.foundation.clickable -import androidx.compose.material3.Switch import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -40,7 +38,7 @@ fun SafeguardBooleanItem( ) } - SafeguardBooleanItem( + BooleanItem( modifier = modifier, value = value, onValueChange = { @@ -53,25 +51,4 @@ fun SafeguardBooleanItem( headline = headline, description = description ) -} - -@Composable -fun SafeguardBooleanItem( - modifier: Modifier = Modifier, - value: Boolean, - onValueChange: (Boolean) -> Unit, - @StringRes headline: Int, - @StringRes description: Int -) = SettingsListItem( - modifier = Modifier - .clickable { onValueChange(!value) } - .then(modifier), - headlineContent = stringResource(headline), - supportingContent = stringResource(description), - trailingContent = { - Switch( - checked = value, - onCheckedChange = onValueChange, - ) - } -) \ No newline at end of file +} \ No newline at end of file From 189b90126c7e1abe12c6ae1255f6499b609f1616 Mon Sep 17 00:00:00 2001 From: aAbed <39409020+TheAabedKhan@users.noreply.github.com> Date: Sat, 20 Jul 2024 21:41:11 +0545 Subject: [PATCH 5/5] Update app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt Co-authored-by: Ax333l --- .../manager/ui/component/settings/SafeguardBooleanItem.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt index b9d5fd6dee..b48d80d1e8 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/SafeguardBooleanItem.kt @@ -20,7 +20,7 @@ fun SafeguardBooleanItem( coroutineScope: CoroutineScope = rememberCoroutineScope(), @StringRes headline: Int, @StringRes description: Int, - @StringRes confirmationText: Int = 0 + @StringRes confirmationText: Int ) { val value by preference.getAsState() var showSafeguardWarning by rememberSaveable {