diff --git a/app/src/main/java/app/revanced/manager/ui/component/bundle/ImportBundleDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/bundle/ImportBundleDialog.kt index 2de48a56..e7388642 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/bundle/ImportBundleDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/bundle/ImportBundleDialog.kt @@ -10,26 +10,9 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Topic -import androidx.compose.material3.Checkbox -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.ListItem -import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.RadioButton -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.material3.* +import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role @@ -37,6 +20,8 @@ import androidx.compose.ui.unit.dp import app.revanced.manager.R import app.revanced.manager.ui.component.AlertDialogExtended import app.revanced.manager.ui.component.TextHorizontalPadding +import app.revanced.manager.ui.component.haptics.HapticCheckbox +import app.revanced.manager.ui.component.haptics.HapticRadioButton import app.revanced.manager.ui.model.BundleType import app.revanced.manager.util.APK_MIMETYPE import app.revanced.manager.util.JAR_MIMETYPE @@ -45,7 +30,7 @@ import app.revanced.manager.util.JAR_MIMETYPE fun ImportPatchBundleDialog( onDismiss: () -> Unit, onRemoteSubmit: (String, Boolean) -> Unit, - onLocalSubmit: (Uri, Uri?) -> Unit + onLocalSubmit: (Uri, Uri?) -> Unit, ) { var currentStep by rememberSaveable { mutableIntStateOf(0) } var bundleType by rememberSaveable { mutableStateOf(BundleType.Remote) } @@ -72,31 +57,32 @@ fun ImportPatchBundleDialog( integrationsActivityLauncher.launch(APK_MIMETYPE) } - val steps = listOf<@Composable () -> Unit>( - { - SelectBundleTypeStep(bundleType) { selectedType -> - bundleType = selectedType - } - }, - { - ImportBundleStep( - bundleType, - patchBundle, - integrations, - remoteUrl, - autoUpdate, - { launchPatchActivity() }, - { launchIntegrationsActivity() }, - { remoteUrl = it }, - { autoUpdate = it } - ) - } - ) + val steps = + listOf<@Composable () -> Unit>( + { + SelectBundleTypeStep(bundleType) { selectedType -> + bundleType = selectedType + } + }, + { + ImportBundleStep( + bundleType, + patchBundle, + integrations, + remoteUrl, + autoUpdate, + { launchPatchActivity() }, + { launchIntegrationsActivity() }, + { remoteUrl = it }, + { autoUpdate = it }, + ) + }, + ) val inputsAreValid by remember { derivedStateOf { (bundleType == BundleType.Local && patchBundle != null) || - (bundleType == BundleType.Remote && remoteUrl.isNotEmpty()) + (bundleType == BundleType.Remote && remoteUrl.isNotEmpty()) } } @@ -114,16 +100,17 @@ fun ImportPatchBundleDialog( enabled = inputsAreValid, onClick = { when (bundleType) { - BundleType.Local -> patchBundle?.let { - onLocalSubmit( - it, - integrations - ) - } + BundleType.Local -> + patchBundle?.let { + onLocalSubmit( + it, + integrations, + ) + } BundleType.Remote -> onRemoteSubmit(remoteUrl, autoUpdate) } - } + }, ) { Text(stringResource(R.string.add)) } @@ -144,53 +131,55 @@ fun ImportPatchBundleDialog( } } }, - textHorizontalPadding = PaddingValues(0.dp) + textHorizontalPadding = PaddingValues(0.dp), ) } @Composable fun SelectBundleTypeStep( bundleType: BundleType, - onBundleTypeSelected: (BundleType) -> Unit + onBundleTypeSelected: (BundleType) -> Unit, ) { Column( - verticalArrangement = Arrangement.spacedBy(24.dp) + verticalArrangement = Arrangement.spacedBy(24.dp), ) { Text( modifier = Modifier.padding(horizontal = 24.dp), - text = stringResource(R.string.select_bundle_type_dialog_description) + text = stringResource(R.string.select_bundle_type_dialog_description), ) Column { ListItem( - modifier = Modifier.clickable( - role = Role.RadioButton, - onClick = { onBundleTypeSelected(BundleType.Remote) } - ), + modifier = + Modifier.clickable( + role = Role.RadioButton, + onClick = { onBundleTypeSelected(BundleType.Remote) }, + ), headlineContent = { Text(stringResource(R.string.enter_url)) }, overlineContent = { Text(stringResource(R.string.recommended)) }, supportingContent = { Text(stringResource(R.string.remote_bundle_description)) }, leadingContent = { - RadioButton( + HapticRadioButton( selected = bundleType == BundleType.Remote, - onClick = null + onClick = null, ) - } + }, ) HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp)) ListItem( - modifier = Modifier.clickable( - role = Role.RadioButton, - onClick = { onBundleTypeSelected(BundleType.Local) } - ), + modifier = + Modifier.clickable( + role = Role.RadioButton, + onClick = { onBundleTypeSelected(BundleType.Local) }, + ), headlineContent = { Text(stringResource(R.string.select_from_storage)) }, supportingContent = { Text(stringResource(R.string.local_bundle_description)) }, overlineContent = { }, leadingContent = { - RadioButton( + HapticRadioButton( selected = bundleType == BundleType.Local, - onClick = null + onClick = null, ) - } + }, ) } } @@ -207,67 +196,92 @@ fun ImportBundleStep( launchPatchActivity: () -> Unit, launchIntegrationsActivity: () -> Unit, onRemoteUrlChange: (String) -> Unit, - onAutoUpdateChange: (Boolean) -> Unit + onAutoUpdateChange: (Boolean) -> Unit, ) { Column { when (bundleType) { BundleType.Local -> { Column( - modifier = Modifier.padding(horizontal = 8.dp) + modifier = Modifier.padding(horizontal = 8.dp), ) { ListItem( headlineContent = { Text(stringResource(R.string.patch_bundle_field)) }, - supportingContent = { Text(stringResource(if (patchBundle != null) R.string.file_field_set else R.string.file_field_not_set)) }, + supportingContent = { + Text( + stringResource( + if (patchBundle != + null + ) { + R.string.file_field_set + } else { + R.string.file_field_not_set + }, + ), + ) + }, trailingContent = { IconButton(onClick = launchPatchActivity) { Icon(imageVector = Icons.Default.Topic, contentDescription = null) } }, - modifier = Modifier.clickable { launchPatchActivity() } + modifier = Modifier.clickable { launchPatchActivity() }, ) ListItem( headlineContent = { Text(stringResource(R.string.integrations_field)) }, - supportingContent = { Text(stringResource(if (integrations != null) R.string.file_field_set else R.string.file_field_not_set)) }, + supportingContent = { + Text( + stringResource( + if (integrations != + null + ) { + R.string.file_field_set + } else { + R.string.file_field_not_set + }, + ), + ) + }, trailingContent = { IconButton(onClick = launchIntegrationsActivity) { Icon(imageVector = Icons.Default.Topic, contentDescription = null) } }, - modifier = Modifier.clickable { launchIntegrationsActivity() } + modifier = Modifier.clickable { launchIntegrationsActivity() }, ) } } BundleType.Remote -> { Column( - modifier = Modifier.padding(TextHorizontalPadding) + modifier = Modifier.padding(TextHorizontalPadding), ) { OutlinedTextField( value = remoteUrl, onValueChange = onRemoteUrlChange, - label = { Text(stringResource(R.string.bundle_url)) } + label = { Text(stringResource(R.string.bundle_url)) }, ) } Column( - modifier = Modifier.padding(horizontal = 8.dp) + modifier = Modifier.padding(horizontal = 8.dp), ) { ListItem( - modifier = Modifier.clickable( - role = Role.Checkbox, - onClick = { onAutoUpdateChange(!autoUpdate) } - ), + modifier = + Modifier.clickable( + role = Role.Checkbox, + onClick = { onAutoUpdateChange(!autoUpdate) }, + ), headlineContent = { Text(stringResource(R.string.auto_update)) }, leadingContent = { CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { - Checkbox( + HapticCheckbox( checked = autoUpdate, onCheckedChange = { onAutoUpdateChange(!autoUpdate) - } + }, ) } }, @@ -276,4 +290,4 @@ fun ImportBundleStep( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticRadioButton.kt b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticRadioButton.kt index daa5acd8..751ecad2 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticRadioButton.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticRadioButton.kt @@ -1,29 +1,24 @@ package app.revanced.manager.ui.component.haptics import android.view.HapticFeedbackConstants -import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.RowScope import androidx.compose.material3.RadioButton import androidx.compose.material3.RadioButtonColors import androidx.compose.material3.RadioButtonDefaults import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalView @Composable -fun HapticRadioButton ( +fun HapticRadioButton( selected: Boolean, onClick: (() -> Unit)?, modifier: Modifier = Modifier, enabled: Boolean = true, colors: RadioButtonColors = RadioButtonDefaults.colors(), - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, ) { val selectedState = remember { mutableStateOf(selected) } @@ -42,6 +37,6 @@ fun HapticRadioButton ( modifier = modifier, enabled = enabled, colors = colors, - interactionSource = interactionSource + interactionSource = interactionSource, ) } diff --git a/app/src/main/java/app/revanced/manager/ui/component/patcher/InstallPickerDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/patcher/InstallPickerDialog.kt index ec3cf979..402b7cd2 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/patcher/InstallPickerDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/patcher/InstallPickerDialog.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ListItem -import androidx.compose.material3.RadioButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -16,11 +15,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import app.revanced.manager.R import app.revanced.manager.data.room.apps.installed.InstallType +import app.revanced.manager.ui.component.haptics.HapticRadioButton @Composable fun InstallPickerDialog( onDismiss: () -> Unit, - onConfirm: (InstallType) -> Unit + onConfirm: (InstallType) -> Unit, ) { var selectedInstallType by rememberSaveable { mutableStateOf(InstallType.DEFAULT) } @@ -36,7 +36,7 @@ fun InstallPickerDialog( onClick = { onConfirm(selectedInstallType) onDismiss() - } + }, ) { Text(stringResource(R.string.install_app)) } @@ -44,19 +44,19 @@ fun InstallPickerDialog( title = { Text(stringResource(R.string.select_install_type)) }, text = { Column { - InstallType.values().forEach { + InstallType.entries.forEach { ListItem( modifier = Modifier.clickable { selectedInstallType = it }, leadingContent = { - RadioButton( + HapticRadioButton( selected = selectedInstallType == it, - onClick = null + onClick = null, ) }, - headlineContent = { Text(stringResource(it.stringResource)) } + headlineContent = { Text(stringResource(it.stringResource)) }, ) } } - } + }, ) -} \ No newline at end of file +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt b/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt index 0c6ff77f..a9db0bac 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt @@ -31,13 +31,11 @@ import androidx.compose.material3.AlertDialog import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ExtendedFloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -65,6 +63,8 @@ import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.FloatInputDialog import app.revanced.manager.ui.component.IntInputDialog import app.revanced.manager.ui.component.LongInputDialog +import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton +import app.revanced.manager.ui.component.haptics.HapticRadioButton import app.revanced.manager.ui.component.haptics.HapticSwitch import app.revanced.manager.util.isScrollingUp import app.revanced.manager.util.mutableStateSetOf @@ -443,7 +443,7 @@ private class PresetOptionEditor( headlineContent = { Text(title) }, supportingContent = value?.toString()?.let { { Text(it) } }, leadingContent = { - RadioButton( + HapticRadioButton( selected = selectedPreset == presetKey, onClick = { selectedPreset = presetKey }, ) @@ -601,7 +601,7 @@ private class ListOptionEditor( floatingActionButton = { if (deleteMode) return@Scaffold - ExtendedFloatingActionButton( + HapticExtendedFloatingActionButton( text = { Text(stringResource(R.string.add)) }, icon = { Icon(Icons.Outlined.Add, null) }, expanded = lazyListState.isScrollingUp, diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt index 7f900219..fa200b78 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt @@ -35,6 +35,7 @@ import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.LazyColumnWithScrollbar import app.revanced.manager.ui.component.SafeguardDialog import app.revanced.manager.ui.component.SearchView +import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton import app.revanced.manager.ui.component.patches.OptionItem import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_SUPPORTED @@ -50,15 +51,16 @@ import kotlinx.coroutines.launch fun PatchesSelectorScreen( onSave: (PatchSelection?, Options) -> Unit, onBackClick: () -> Unit, - vm: PatchesSelectorViewModel + vm: PatchesSelectorViewModel, ) { val bundles by vm.bundlesFlow.collectAsStateWithLifecycle(initialValue = emptyList()) - val pagerState = rememberPagerState( - initialPage = 0, - initialPageOffsetFraction = 0f - ) { - bundles.size - } + val pagerState = + rememberPagerState( + initialPage = 0, + initialPageOffsetFraction = 0f, + ) { + bundles.size + } val composableScope = rememberCoroutineScope() var search: String? by rememberSaveable { mutableStateOf(null) @@ -74,30 +76,30 @@ fun PatchesSelectorScreen( ModalBottomSheet( onDismissRequest = { showBottomSheet = false - } + }, ) { Column( - modifier = Modifier.padding(horizontal = 24.dp) + modifier = Modifier.padding(horizontal = 24.dp), ) { Text( text = stringResource(R.string.patch_selector_sheet_filter_title), style = MaterialTheme.typography.headlineSmall, - modifier = Modifier.padding(bottom = 16.dp) + modifier = Modifier.padding(bottom = 16.dp), ) Text( text = stringResource(R.string.patch_selector_sheet_filter_compat_title), - style = MaterialTheme.typography.titleMedium + style = MaterialTheme.typography.titleMedium, ) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(5.dp) + horizontalArrangement = Arrangement.spacedBy(5.dp), ) { FilterChip( selected = vm.filter and SHOW_SUPPORTED != 0, onClick = { vm.toggleFlag(SHOW_SUPPORTED) }, - label = { Text(stringResource(R.string.supported)) } + label = { Text(stringResource(R.string.supported)) }, ) FilterChip( @@ -116,12 +118,13 @@ fun PatchesSelectorScreen( } } - if (vm.compatibleVersions.isNotEmpty()) + if (vm.compatibleVersions.isNotEmpty()) { UnsupportedDialog( appVersion = vm.appVersion, supportedVersions = vm.compatibleVersions, - onDismissRequest = vm::dismissDialogs + onDismissRequest = vm::dismissDialogs, ) + } vm.optionsDialog?.let { (bundle, patch) -> OptionsDialog( @@ -129,7 +132,7 @@ fun PatchesSelectorScreen( patch = patch, values = vm.getOptions(bundle, patch), reset = { vm.resetOptions(bundle, patch) }, - set = { key, value -> vm.setOption(bundle, patch, key, value) } + set = { key, value -> vm.setOption(bundle, patch, key, value) }, ) } @@ -142,7 +145,7 @@ fun PatchesSelectorScreen( vm.pendingUniversalPatchAction?.let { UniversalPatchWarningDialog( onCancel = vm::dismissUniversalPatchWarning, - onConfirm = vm::confirmUniversalPatchWarning + onConfirm = vm::confirmUniversalPatchWarning, ) } @@ -151,7 +154,7 @@ fun PatchesSelectorScreen( patches: List, filterFlag: Int, supported: Boolean, - header: (@Composable () -> Unit)? = null + header: (@Composable () -> Unit)? = null, ) { if (patches.isNotEmpty() && (vm.filter and filterFlag) != 0 || vm.filter == 0) { header?.let { @@ -162,17 +165,19 @@ fun PatchesSelectorScreen( items( items = patches, - key = { it.name } + key = { it.name }, ) { patch -> PatchItem( patch = patch, onOptionsDialog = { vm.optionsDialog = uid to patch }, - selected = supported && vm.isSelected( - uid, - patch - ), + selected = + supported && + vm.isSelected( + uid, + patch, + ), onToggle = { if (vm.selectionWarningEnabled) { showSelectionWarning = true @@ -182,7 +187,7 @@ fun PatchesSelectorScreen( vm.togglePatch(uid, patch) } }, - supported = supported + supported = supported, ) } } @@ -193,28 +198,29 @@ fun PatchesSelectorScreen( query = query, onQueryChange = { search = it }, onActiveChange = { if (!it) search = null }, - placeholder = { Text(stringResource(R.string.search_patches)) } + placeholder = { Text(stringResource(R.string.search_patches)) }, ) { val bundle = bundles[pagerState.currentPage] LazyColumnWithScrollbar( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize(), ) { - fun List.searched() = filter { - it.name.contains(query, true) - } + fun List.searched() = + filter { + it.name.contains(query, true) + } patchList( uid = bundle.uid, patches = bundle.supported.searched(), filterFlag = SHOW_SUPPORTED, - supported = true + supported = true, ) patchList( uid = bundle.uid, patches = bundle.universal.searched(), filterFlag = SHOW_UNIVERSAL, - supported = true + supported = true, ) { ListHeader( title = stringResource(R.string.universal_patches), @@ -226,11 +232,11 @@ fun PatchesSelectorScreen( uid = bundle.uid, patches = bundle.unsupported.searched(), filterFlag = SHOW_UNSUPPORTED, - supported = true + supported = true, ) { ListHeader( title = stringResource(R.string.unsupported_patches), - onHelpClick = { vm.openUnsupportedDialog(bundle.unsupported) } + onHelpClick = { vm.openUnsupportedDialog(bundle.unsupported) }, ) } } @@ -252,11 +258,11 @@ fun PatchesSelectorScreen( IconButton( onClick = { search = "" - } + }, ) { Icon(Icons.Outlined.Search, stringResource(R.string.search)) } - } + }, ) }, floatingActionButton = { @@ -269,19 +275,19 @@ fun PatchesSelectorScreen( onClick = { // TODO: only allow this if all required options have been set. onSave(vm.getCustomSelection(), vm.getOptions()) - } + }, ) - } + }, ) { paddingValues -> Column( Modifier .fillMaxSize() - .padding(paddingValues) + .padding(paddingValues), ) { if (bundles.size > 1) { ScrollableTabRow( selectedTabIndex = pagerState.currentPage, - containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp) + containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp), ) { bundles.forEachIndexed { index, bundle -> HapticTab( @@ -289,13 +295,13 @@ fun PatchesSelectorScreen( onClick = { composableScope.launch { pagerState.animateScrollToPage( - index + index, ) } }, text = { Text(bundle.name) }, selectedContentColor = MaterialTheme.colorScheme.primary, - unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant + unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant, ) } } @@ -311,19 +317,19 @@ fun PatchesSelectorScreen( LazyColumnWithScrollbar( modifier = Modifier.fillMaxSize(), - state = patchLazyListStates[index] + state = patchLazyListStates[index], ) { patchList( uid = bundle.uid, patches = bundle.supported, filterFlag = SHOW_SUPPORTED, - supported = true + supported = true, ) patchList( uid = bundle.uid, patches = bundle.universal, filterFlag = SHOW_UNIVERSAL, - supported = true + supported = true, ) { ListHeader( title = stringResource(R.string.universal_patches), @@ -333,15 +339,15 @@ fun PatchesSelectorScreen( uid = bundle.uid, patches = bundle.unsupported, filterFlag = SHOW_UNSUPPORTED, - supported = vm.allowIncompatiblePatches + supported = vm.allowIncompatiblePatches, ) { ListHeader( title = stringResource(R.string.unsupported_patches), - onHelpClick = { vm.openUnsupportedDialog(bundle.unsupported) } + onHelpClick = { vm.openUnsupportedDialog(bundle.unsupported) }, ) } } - } + }, ) } } @@ -359,7 +365,7 @@ fun SelectionWarningDialog(onDismiss: () -> Unit) { @Composable fun UniversalPatchWarningDialog( onCancel: () -> Unit, - onConfirm: () -> Unit + onConfirm: () -> Unit, ) { AlertDialog( onDismissRequest = onCancel, @@ -379,12 +385,12 @@ fun UniversalPatchWarningDialog( title = { Text( text = stringResource(R.string.warning), - style = MaterialTheme.typography.headlineSmall.copy(textAlign = TextAlign.Center) + style = MaterialTheme.typography.headlineSmall.copy(textAlign = TextAlign.Center), ) }, text = { Text(stringResource(R.string.universal_patch_warning_description)) - } + }, ) } @@ -394,17 +400,18 @@ fun PatchItem( onOptionsDialog: () -> Unit, selected: Boolean, onToggle: () -> Unit, - supported: Boolean = true -) = ListItem ( - modifier = Modifier - .let { if (!supported) it.alpha(0.5f) else it } - .clickable(enabled = supported, onClick = onToggle) - .fillMaxSize(), + supported: Boolean = true, +) = ListItem( + modifier = + Modifier + .let { if (!supported) it.alpha(0.5f) else it } + .clickable(enabled = supported, onClick = onToggle) + .fillMaxSize(), leadingContent = { HapticCheckbox( checked = selected, onCheckedChange = { onToggle() }, - enabled = supported + enabled = supported, ) }, headlineContent = { Text(patch.name) }, @@ -421,26 +428,27 @@ fun PatchItem( @Composable fun ListHeader( title: String, - onHelpClick: (() -> Unit)? = null + onHelpClick: (() -> Unit)? = null, ) { ListItem( headlineContent = { Text( text = title, color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.labelLarge + style = MaterialTheme.typography.labelLarge, ) }, - trailingContent = onHelpClick?.let { - { - IconButton(onClick = it) { - Icon( - Icons.AutoMirrored.Outlined.HelpOutline, - stringResource(R.string.help) - ) + trailingContent = + onHelpClick?.let { + { + IconButton(onClick = it) { + Icon( + Icons.AutoMirrored.Outlined.HelpOutline, + stringResource(R.string.help), + ) + } } - } - } + }, ) } @@ -448,7 +456,7 @@ fun ListHeader( fun UnsupportedDialog( appVersion: String, supportedVersions: List, - onDismissRequest: () -> Unit + onDismissRequest: () -> Unit, ) = AlertDialog( onDismissRequest = onDismissRequest, confirmButton = { @@ -462,10 +470,10 @@ fun UnsupportedDialog( stringResource( R.string.app_not_supported, appVersion, - supportedVersions.joinToString(", ") - ) + supportedVersions.joinToString(", "), + ), ) - } + }, ) @OptIn(ExperimentalMaterial3Api::class) @@ -478,10 +486,11 @@ fun OptionsDialog( onDismissRequest: () -> Unit, ) = Dialog( onDismissRequest = onDismissRequest, - properties = DialogProperties( - usePlatformDefaultWidth = false, - dismissOnBackPress = true - ) + properties = + DialogProperties( + usePlatformDefaultWidth = false, + dismissOnBackPress = true, + ), ) { Scaffold( topBar = { @@ -492,12 +501,12 @@ fun OptionsDialog( IconButton(onClick = reset) { Icon(Icons.Outlined.Restore, stringResource(R.string.reset)) } - } + }, ) - } + }, ) { paddingValues -> LazyColumnWithScrollbar( - modifier = Modifier.padding(paddingValues) + modifier = Modifier.padding(paddingValues), ) { if (patch.options == null) return@LazyColumnWithScrollbar @@ -511,4 +520,4 @@ fun OptionsDialog( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt index 0dd786d7..e0b4aef0 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt @@ -9,7 +9,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.ArrowRight import androidx.compose.material.icons.filled.AutoFixHigh import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ExtendedFloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme @@ -28,6 +27,7 @@ import app.revanced.manager.R import app.revanced.manager.ui.component.AppInfo import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.ColumnWithScrollbar +import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton import app.revanced.manager.ui.destination.SelectedAppInfoDestination import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow import app.revanced.manager.ui.model.SelectedApp @@ -48,7 +48,7 @@ import org.koin.core.parameter.parametersOf fun SelectedAppInfoScreen( onPatchClick: (SelectedApp, PatchSelection, Options) -> Unit, onBackClick: () -> Unit, - vm: SelectedAppInfoViewModel + vm: SelectedAppInfoViewModel, ) { val context = LocalContext.current @@ -82,67 +82,71 @@ fun SelectedAppInfoScreen( AnimatedNavHost(controller = navController) { destination -> when (destination) { - is SelectedAppInfoDestination.Main -> SelectedAppInfoScreen( - onPatchClick = patchClick@{ - if (selectedPatchCount == 0) { - context.toast(context.getString(R.string.no_patches_selected)) + is SelectedAppInfoDestination.Main -> + SelectedAppInfoScreen( + onPatchClick = patchClick@{ + if (selectedPatchCount == 0) { + context.toast(context.getString(R.string.no_patches_selected)) - return@patchClick - } - onPatchClick( - vm.selectedApp, - patches, - vm.getOptionsFiltered(bundles) - ) - }, - onPatchSelectorClick = { - navController.navigate( - SelectedAppInfoDestination.PatchesSelector( + return@patchClick + } + onPatchClick( vm.selectedApp, - vm.getCustomPatches( - bundles, - allowIncompatiblePatches + patches, + vm.getOptionsFiltered(bundles), + ) + }, + onPatchSelectorClick = { + navController.navigate( + SelectedAppInfoDestination.PatchesSelector( + vm.selectedApp, + vm.getCustomPatches( + bundles, + allowIncompatiblePatches, + ), + vm.options, ), - vm.options ) - ) - }, - onVersionSelectorClick = { - navController.navigate(SelectedAppInfoDestination.VersionSelector) - }, - onBackClick = onBackClick, - availablePatchCount = availablePatchCount, - selectedPatchCount = selectedPatchCount, - packageName = packageName, - version = version, - packageInfo = vm.selectedAppInfo, - ) + }, + onVersionSelectorClick = { + navController.navigate(SelectedAppInfoDestination.VersionSelector) + }, + onBackClick = onBackClick, + availablePatchCount = availablePatchCount, + selectedPatchCount = selectedPatchCount, + packageName = packageName, + version = version, + packageInfo = vm.selectedAppInfo, + ) - is SelectedAppInfoDestination.VersionSelector -> VersionSelectorScreen( - onBackClick = navController::pop, - onAppClick = { - vm.selectedApp = it - navController.pop() - }, - viewModel = koinViewModel { parametersOf(packageName) } - ) + is SelectedAppInfoDestination.VersionSelector -> + VersionSelectorScreen( + onBackClick = navController::pop, + onAppClick = { + vm.selectedApp = it + navController.pop() + }, + viewModel = koinViewModel { parametersOf(packageName) }, + ) - is SelectedAppInfoDestination.PatchesSelector -> PatchesSelectorScreen( - onSave = { patches, options -> - vm.updateConfiguration(patches, options, bundles) - navController.pop() - }, - onBackClick = navController::pop, - vm = koinViewModel { - parametersOf( - PatchesSelectorViewModel.Params( - destination.app, - destination.currentSelection, - destination.options, - ) - ) - } - ) + is SelectedAppInfoDestination.PatchesSelector -> + PatchesSelectorScreen( + onSave = { patches, options -> + vm.updateConfiguration(patches, options, bundles) + navController.pop() + }, + onBackClick = navController::pop, + vm = + koinViewModel { + parametersOf( + PatchesSelectorViewModel.Params( + destination.app, + destination.currentSelection, + destination.options, + ), + ) + }, + ) } } } @@ -164,21 +168,22 @@ private fun SelectedAppInfoScreen( topBar = { AppTopBar( title = stringResource(R.string.app_info), - onBackClick = onBackClick + onBackClick = onBackClick, ) }, floatingActionButton = { - ExtendedFloatingActionButton( + HapticExtendedFloatingActionButton( text = { Text(stringResource(R.string.patch)) }, icon = { Icon(Icons.Default.AutoFixHigh, null) }, - onClick = onPatchClick + onClick = onPatchClick, ) - } + }, ) { paddingValues -> ColumnWithScrollbar( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) + modifier = + Modifier + .fillMaxSize() + .padding(paddingValues), ) { AppInfo(packageInfo, placeholderLabel = packageName) { Text( @@ -191,39 +196,44 @@ private fun SelectedAppInfoScreen( PageItem( R.string.patch_selector_item, stringResource(R.string.patch_selector_item_description, selectedPatchCount), - onPatchSelectorClick + onPatchSelectorClick, ) PageItem( R.string.version_selector_item, stringResource(R.string.version_selector_item_description, version), - onVersionSelectorClick + onVersionSelectorClick, ) } } } @Composable -private fun PageItem(@StringRes title: Int, description: String, onClick: () -> Unit) { +private fun PageItem( + @StringRes title: Int, + description: String, + onClick: () -> Unit, +) { ListItem( - modifier = Modifier - .clickable(onClick = onClick) - .padding(start = 8.dp), + modifier = + Modifier + .clickable(onClick = onClick) + .padding(start = 8.dp), headlineContent = { Text( stringResource(title), color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.titleLarge + style = MaterialTheme.typography.titleLarge, ) }, supportingContent = { Text( description, color = MaterialTheme.colorScheme.outline, - style = MaterialTheme.typography.bodyMedium + style = MaterialTheme.typography.bodyMedium, ) }, trailingContent = { Icon(Icons.AutoMirrored.Outlined.ArrowRight, null) - } + }, ) -} \ No newline at end of file +} diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt index 432c4808..19f232c1 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete -import androidx.compose.material3.Checkbox import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -20,6 +19,7 @@ import app.revanced.manager.R import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.ColumnWithScrollbar import app.revanced.manager.ui.component.GroupHeader +import app.revanced.manager.ui.component.haptics.HapticCheckbox import app.revanced.manager.ui.component.settings.BooleanItem import app.revanced.manager.ui.component.settings.SettingsListItem import app.revanced.manager.ui.viewmodel.DownloadsViewModel @@ -29,7 +29,7 @@ import org.koin.androidx.compose.koinViewModel @Composable fun DownloadsSettingsScreen( onBackClick: () -> Unit, - viewModel: DownloadsViewModel = koinViewModel() + viewModel: DownloadsViewModel = koinViewModel(), ) { val prefs = viewModel.prefs @@ -46,14 +46,15 @@ fun DownloadsSettingsScreen( Icon(Icons.Default.Delete, stringResource(R.string.delete)) } } - } + }, ) - } + }, ) { paddingValues -> ColumnWithScrollbar( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) + modifier = + Modifier + .fillMaxSize() + .padding(paddingValues), ) { BooleanItem( preference = prefs.preferSplits, @@ -69,16 +70,21 @@ fun DownloadsSettingsScreen( SettingsListItem( modifier = Modifier.clickable { viewModel.toggleItem(app) }, headlineContent = app.packageName, - leadingContent = (@Composable { - Checkbox( - checked = selected, - onCheckedChange = { viewModel.toggleItem(app) } - ) - }).takeIf { viewModel.selection.isNotEmpty() }, + leadingContent = + { + ( + @Composable { + HapticCheckbox( + checked = selected, + onCheckedChange = { viewModel.toggleItem(app) }, + ) + } + ).takeIf { viewModel.selection.isNotEmpty() } + }, supportingContent = app.version, - tonalElevation = if (selected) 8.dp else 0.dp + tonalElevation = if (selected) 8.dp else 0.dp, ) } } } -} \ No newline at end of file +}