fix(Compose): Adjusted universal patches safeguard and warnings (#2550)

This commit is contained in:
Brosssh
2025-05-17 21:33:02 +02:00
committed by oSumAtrIX
parent 0030c7a788
commit 663cf2d6b8
8 changed files with 88 additions and 165 deletions

View File

@@ -234,7 +234,7 @@ private fun ReVancedManager(vm: MainViewModel) {
selectedAppInfoVm.updateConfiguration(patches, options)
navController.popBackStack()
},
vm = koinViewModel { parametersOf(data) }
viewModel = koinViewModel { parametersOf(data) }
)
}

View File

@@ -25,7 +25,7 @@ class PreferencesManager(
val disablePatchVersionCompatCheck = booleanPreference("disable_patch_version_compatibility_check", false)
val disableSelectionWarning = booleanPreference("disable_selection_warning", false)
val disableUniversalPatchWarning = booleanPreference("disable_universal_patch_warning", false)
val disableUniversalPatchCheck = booleanPreference("disable_patch_universal_check", false)
val suggestedVersionSafeguard = booleanPreference("suggested_version_safeguard", true)
val acknowledgedDownloaderPlugins = stringSetPreference("acknowledged_downloader_plugins", emptySet())

View File

@@ -1,6 +1,8 @@
package app.revanced.manager.ui.component.settings
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.WarningAmber
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -9,7 +11,9 @@ 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.R
import app.revanced.manager.domain.manager.base.Preference
import app.revanced.manager.ui.component.ConfirmDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -28,13 +32,15 @@ fun SafeguardBooleanItem(
}
if (showSafeguardWarning) {
SafeguardConfirmationDialog(
ConfirmDialog(
onDismiss = { showSafeguardWarning = false },
onConfirm = {
coroutineScope.launch { preference.update(!value) }
showSafeguardWarning = false
},
body = stringResource(confirmationText)
title = stringResource(id = R.string.warning),
description = stringResource(confirmationText),
icon = Icons.Outlined.WarningAmber
)
}

View File

@@ -1,46 +0,0 @@
package app.revanced.manager.ui.component.settings
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)
}
)
}

View File

@@ -58,7 +58,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R
@@ -88,9 +87,9 @@ import kotlinx.coroutines.launch
fun PatchesSelectorScreen(
onSave: (PatchSelection?, Options) -> Unit,
onBackClick: () -> Unit,
vm: PatchesSelectorViewModel
viewModel: PatchesSelectorViewModel
) {
val bundles by vm.bundlesFlow.collectAsStateWithLifecycle(initialValue = emptyList())
val bundles by viewModel.bundlesFlow.collectAsStateWithLifecycle(initialValue = emptyList())
val pagerState = rememberPagerState(
initialPage = 0,
initialPageOffsetFraction = 0f
@@ -106,15 +105,15 @@ fun PatchesSelectorScreen(
}
var showBottomSheet by rememberSaveable { mutableStateOf(false) }
val showSaveButton by remember {
derivedStateOf { vm.selectionIsValid(bundles) }
derivedStateOf { viewModel.selectionIsValid(bundles) }
}
val defaultPatchSelectionCount by vm.defaultSelectionCount
val defaultPatchSelectionCount by viewModel.defaultSelectionCount
.collectAsStateWithLifecycle(initialValue = 0)
val selectedPatchCount by remember {
derivedStateOf {
vm.customPatchSelection?.values?.sumOf { it.size } ?: defaultPatchSelectionCount
viewModel.customPatchSelection?.values?.sumOf { it.size } ?: defaultPatchSelectionCount
}
}
@@ -146,14 +145,14 @@ fun PatchesSelectorScreen(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
CheckedFilterChip(
selected = vm.filter and SHOW_INCOMPATIBLE == 0,
onClick = { vm.toggleFlag(SHOW_INCOMPATIBLE) },
selected = viewModel.filter and SHOW_INCOMPATIBLE == 0,
onClick = { viewModel.toggleFlag(SHOW_INCOMPATIBLE) },
label = { Text(stringResource(R.string.this_version)) }
)
CheckedFilterChip(
selected = vm.filter and SHOW_UNIVERSAL != 0,
onClick = { vm.toggleFlag(SHOW_UNIVERSAL) },
selected = viewModel.filter and SHOW_UNIVERSAL != 0,
onClick = { viewModel.toggleFlag(SHOW_UNIVERSAL) },
label = { Text(stringResource(R.string.universal)) },
)
}
@@ -161,43 +160,39 @@ fun PatchesSelectorScreen(
}
}
if (vm.compatibleVersions.isNotEmpty())
if (viewModel.compatibleVersions.isNotEmpty())
IncompatiblePatchDialog(
appVersion = vm.appVersion ?: stringResource(R.string.any_version),
compatibleVersions = vm.compatibleVersions,
onDismissRequest = vm::dismissDialogs
appVersion = viewModel.appVersion ?: stringResource(R.string.any_version),
compatibleVersions = viewModel.compatibleVersions,
onDismissRequest = viewModel::dismissDialogs
)
var showIncompatiblePatchesDialog by rememberSaveable {
mutableStateOf(false)
}
if (showIncompatiblePatchesDialog)
IncompatiblePatchesDialog(
appVersion = vm.appVersion ?: stringResource(R.string.any_version),
appVersion = viewModel.appVersion ?: stringResource(R.string.any_version),
onDismissRequest = { showIncompatiblePatchesDialog = false }
)
vm.optionsDialog?.let { (bundle, patch) ->
viewModel.optionsDialog?.let { (bundle, patch) ->
OptionsDialog(
onDismissRequest = vm::dismissDialogs,
onDismissRequest = viewModel::dismissDialogs,
patch = patch,
values = vm.getOptions(bundle, patch),
reset = { vm.resetOptions(bundle, patch) },
set = { key, value -> vm.setOption(bundle, patch, key, value) }
values = viewModel.getOptions(bundle, patch),
reset = { viewModel.resetOptions(bundle, patch) },
set = { key, value -> viewModel.setOption(bundle, patch, key, value) }
)
}
var showSelectionWarning by rememberSaveable {
mutableStateOf(false)
}
if (showSelectionWarning) {
var showSelectionWarning by rememberSaveable { mutableStateOf(false) }
var showUniversalWarning by rememberSaveable { mutableStateOf(false) }
if (showSelectionWarning)
SelectionWarningDialog(onDismiss = { showSelectionWarning = false })
}
vm.pendingUniversalPatchAction?.let {
UniversalPatchWarningDialog(
onCancel = vm::dismissUniversalPatchWarning,
onConfirm = vm::confirmUniversalPatchWarning
)
}
if (showUniversalWarning)
UniversalPatchWarningDialog(onDismiss = { showUniversalWarning = false })
fun LazyListScope.patchList(
uid: Int,
@@ -221,27 +216,25 @@ fun PatchesSelectorScreen(
PatchItem(
patch = patch,
onOptionsDialog = {
vm.optionsDialog = uid to patch
viewModel.optionsDialog = uid to patch
},
selected = compatible && vm.isSelected(
selected = compatible && viewModel.isSelected(
uid,
patch
),
onToggle = {
when {
// Open incompatible dialog if the patch is not supported
!compatible -> vm.openIncompatibleDialog(patch)
!compatible -> viewModel.openIncompatibleDialog(patch)
// Show selection warning if enabled
vm.selectionWarningEnabled -> showSelectionWarning = true
viewModel.selectionWarningEnabled -> showSelectionWarning = true
// Set pending universal patch action if the universal patch warning is enabled and there are no compatible packages
vm.universalPatchWarningEnabled && patch.compatiblePackages == null -> {
vm.pendingUniversalPatchAction = { vm.togglePatch(uid, patch) }
}
// Show universal warning if enabled
viewModel.universalPatchWarningEnabled -> showUniversalWarning = true
// Toggle the patch otherwise
else -> vm.togglePatch(uid, patch)
else -> viewModel.togglePatch(uid, patch)
}
},
compatible = compatible
@@ -327,7 +320,7 @@ fun PatchesSelectorScreen(
patchList(
uid = bundle.uid,
patches = bundle.universal.searched(),
visible = vm.filter and SHOW_UNIVERSAL != 0,
visible = viewModel.filter and SHOW_UNIVERSAL != 0,
compatible = true
) {
ListHeader(
@@ -338,8 +331,8 @@ fun PatchesSelectorScreen(
patchList(
uid = bundle.uid,
patches = bundle.incompatible.searched(),
visible = vm.filter and SHOW_INCOMPATIBLE != 0,
compatible = vm.allowIncompatiblePatches
visible = viewModel.filter and SHOW_INCOMPATIBLE != 0,
compatible = viewModel.allowIncompatiblePatches
) {
ListHeader(
title = stringResource(R.string.incompatible_patches),
@@ -362,7 +355,7 @@ fun PatchesSelectorScreen(
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
SmallFloatingActionButton(
onClick = vm::reset,
onClick = viewModel::reset,
containerColor = MaterialTheme.colorScheme.tertiaryContainer
) {
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
@@ -385,7 +378,7 @@ fun PatchesSelectorScreen(
expanded = patchLazyListStates.getOrNull(pagerState.currentPage)?.isScrollingUp
?: true,
onClick = {
onSave(vm.getCustomSelection(), vm.getOptions())
onSave(viewModel.getCustomSelection(), viewModel.getOptions())
}
)
}
@@ -453,7 +446,7 @@ fun PatchesSelectorScreen(
patchList(
uid = bundle.uid,
patches = bundle.universal,
visible = vm.filter and SHOW_UNIVERSAL != 0,
visible = viewModel.filter and SHOW_UNIVERSAL != 0,
compatible = true
) {
ListHeader(
@@ -463,8 +456,8 @@ fun PatchesSelectorScreen(
patchList(
uid = bundle.uid,
patches = bundle.incompatible,
visible = vm.filter and SHOW_INCOMPATIBLE != 0,
compatible = vm.allowIncompatiblePatches
visible = viewModel.filter and SHOW_INCOMPATIBLE != 0,
compatible = viewModel.allowIncompatiblePatches
) {
ListHeader(
title = stringResource(R.string.incompatible_patches),
@@ -479,7 +472,9 @@ fun PatchesSelectorScreen(
}
@Composable
private fun SelectionWarningDialog(onDismiss: () -> Unit) {
private fun SelectionWarningDialog(
onDismiss: () -> Unit
) {
SafeguardDialog(
onDismiss = onDismiss,
title = R.string.warning,
@@ -489,33 +484,12 @@ private fun SelectionWarningDialog(onDismiss: () -> Unit) {
@Composable
private fun UniversalPatchWarningDialog(
onCancel: () -> Unit,
onConfirm: () -> Unit
onDismiss: () -> Unit
) {
AlertDialog(
onDismissRequest = onCancel,
confirmButton = {
TextButton(onClick = onConfirm) {
Text(stringResource(R.string.continue_))
}
},
dismissButton = {
TextButton(onClick = onCancel) {
Text(stringResource(R.string.cancel))
}
},
icon = {
Icon(Icons.Outlined.WarningAmber, null)
},
title = {
Text(
text = stringResource(R.string.warning),
style = MaterialTheme.typography.headlineSmall.copy(textAlign = TextAlign.Center)
)
},
text = {
Text(stringResource(R.string.universal_patch_warning_description))
}
SafeguardDialog(
onDismiss = onDismiss,
title = R.string.warning,
body = stringResource(R.string.universal_patch_warning_description),
)
}

View File

@@ -61,7 +61,7 @@ import org.koin.androidx.compose.koinViewModel
@Composable
fun AdvancedSettingsScreen(
onBackClick: () -> Unit,
vm: AdvancedSettingsViewModel = koinViewModel()
viewModel: AdvancedSettingsViewModel = koinViewModel()
) {
val context = LocalContext.current
val memoryLimit = remember {
@@ -91,16 +91,16 @@ fun AdvancedSettingsScreen(
) {
GroupHeader(stringResource(R.string.manager))
val apiUrl by vm.prefs.api.getAsState()
val apiUrl by viewModel.prefs.api.getAsState()
var showApiUrlDialog by rememberSaveable { mutableStateOf(false) }
if (showApiUrlDialog) {
APIUrlDialog(
currentUrl = apiUrl,
defaultUrl = vm.prefs.api.default,
defaultUrl = viewModel.prefs.api.default,
onSubmit = {
showApiUrlDialog = false
it?.let(vm::setApiUrl)
it?.let(viewModel::setApiUrl)
}
)
}
@@ -114,44 +114,44 @@ fun AdvancedSettingsScreen(
GroupHeader(stringResource(R.string.safeguards))
SafeguardBooleanItem(
preference = vm.prefs.disablePatchVersionCompatCheck,
coroutineScope = vm.viewModelScope,
preference = viewModel.prefs.disablePatchVersionCompatCheck,
coroutineScope = viewModel.viewModelScope,
headline = R.string.patch_compat_check,
description = R.string.patch_compat_check_description,
confirmationText = R.string.patch_compat_check_confirmation
)
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
)
SafeguardBooleanItem(
preference = vm.prefs.suggestedVersionSafeguard,
coroutineScope = vm.viewModelScope,
preference = viewModel.prefs.suggestedVersionSafeguard,
coroutineScope = viewModel.viewModelScope,
headline = R.string.suggested_version_safeguard,
description = R.string.suggested_version_safeguard_description,
confirmationText = R.string.suggested_version_safeguard_confirmation
)
SafeguardBooleanItem(
preference = vm.prefs.disableSelectionWarning,
coroutineScope = vm.viewModelScope,
preference = viewModel.prefs.disableSelectionWarning,
coroutineScope = viewModel.viewModelScope,
headline = R.string.patch_selection_safeguard,
description = R.string.patch_selection_safeguard_description,
confirmationText = R.string.patch_selection_safeguard_confirmation
)
SafeguardBooleanItem(
preference = viewModel.prefs.disableUniversalPatchCheck,
coroutineScope = viewModel.viewModelScope,
headline = R.string.universal_patches_safeguard,
description = R.string.universal_patches_safeguard_description,
confirmationText = R.string.universal_patches_safeguard_confirmation
)
GroupHeader(stringResource(R.string.patcher))
BooleanItem(
preference = vm.prefs.useProcessRuntime,
coroutineScope = vm.viewModelScope,
preference = viewModel.prefs.useProcessRuntime,
coroutineScope = viewModel.viewModelScope,
headline = R.string.process_runtime,
description = R.string.process_runtime_description,
)
IntegerItem(
preference = vm.prefs.patcherProcessMemoryLimit,
coroutineScope = vm.viewModelScope,
preference = viewModel.prefs.patcherProcessMemoryLimit,
coroutineScope = viewModel.viewModelScope,
headline = R.string.process_runtime_memory_limit,
description = R.string.process_runtime_memory_limit_description,
)
@@ -159,11 +159,11 @@ fun AdvancedSettingsScreen(
GroupHeader(stringResource(R.string.debugging))
val exportDebugLogsLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) {
it?.let(vm::exportDebugLogs)
it?.let(viewModel::exportDebugLogs)
}
SettingsListItem(
headlineContent = stringResource(R.string.debug_logs_export),
modifier = Modifier.clickable { exportDebugLogsLauncher.launch(vm.debugLogFileName) }
modifier = Modifier.clickable { exportDebugLogsLauncher.launch(viewModel.debugLogFileName) }
)
val clipboard = remember { context.getSystemService<ClipboardManager>()!! }
val deviceContent = """

View File

@@ -55,8 +55,6 @@ class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.Vi
private val packageName = input.app.packageName
val appVersion = input.app.version
var pendingUniversalPatchAction by mutableStateOf<(() -> Unit)?>(null)
var selectionWarningEnabled by mutableStateOf(true)
private set
var universalPatchWarningEnabled by mutableStateOf(true)
@@ -69,7 +67,9 @@ class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.Vi
init {
viewModelScope.launch {
universalPatchWarningEnabled = !prefs.disableUniversalPatchWarning.get()
if (prefs.disableUniversalPatchCheck.get()) {
universalPatchWarningEnabled = false
}
if (prefs.disableSelectionWarning.get()) {
selectionWarningEnabled = false
@@ -160,17 +160,6 @@ class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.Vi
customPatchSelection = selection.put(bundle, newPatches)
}
fun confirmUniversalPatchWarning() {
universalPatchWarningEnabled = false
pendingUniversalPatchAction?.invoke()
pendingUniversalPatchAction = null
}
fun dismissUniversalPatchWarning() {
pendingUniversalPatchAction = null
}
fun reset() {
patchOptions.clear()
customPatchSelection = null