diff --git a/app/src/main/java/app/revanced/manager/ui/component/AutoUpdatesDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/AutoUpdatesDialog.kt index 9da4f27fcb..1e2234ebf1 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/AutoUpdatesDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/AutoUpdatesDialog.kt @@ -8,7 +8,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Source import androidx.compose.material.icons.outlined.Update import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Checkbox import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.ListItem @@ -24,6 +23,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import app.revanced.manager.R +import app.revanced.manager.ui.component.haptics.HapticCheckbox @Composable fun AutoUpdatesDialog(onSubmit: (Boolean, Boolean) -> Unit) { @@ -76,6 +76,6 @@ private fun AutoUpdatesItem( ) = ListItem( leadingContent = { Icon(icon, null) }, headlineContent = { Text(stringResource(headline)) }, - trailingContent = { Checkbox(checked = checked, onCheckedChange = null) }, + trailingContent = { HapticCheckbox(checked = checked, onCheckedChange = null) }, modifier = Modifier.clickable { onCheckedChange(!checked) } -) \ No newline at end of file +) diff --git a/app/src/main/java/app/revanced/manager/ui/component/AvailableUpdateDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/AvailableUpdateDialog.kt index 7059ad0da9..4a684c1e6f 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/AvailableUpdateDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/AvailableUpdateDialog.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import app.revanced.manager.R +import app.revanced.manager.ui.component.haptics.HapticCheckbox @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -70,7 +71,7 @@ fun AvailableUpdateDialog( }, leadingContent = { CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { - Checkbox(checked = dontShowAgain, onCheckedChange = { dontShowAgain = it }) + HapticCheckbox(checked = dontShowAgain, onCheckedChange = { dontShowAgain = it }) } } ) diff --git a/app/src/main/java/app/revanced/manager/ui/component/bundle/BaseBundleDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/bundle/BaseBundleDialog.kt index 4450ef5cdd..dfc63735b9 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/bundle/BaseBundleDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/bundle/BaseBundleDialog.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.unit.dp import app.revanced.manager.R import app.revanced.manager.ui.component.ColumnWithScrollbar import app.revanced.manager.ui.component.TextInputDialog +import app.revanced.manager.ui.component.haptics.HapticSwitch @Composable fun BaseBundleDialog( @@ -89,7 +90,7 @@ fun BaseBundleDialog( headlineText = stringResource(R.string.bundle_auto_update), supportingText = stringResource(R.string.bundle_auto_update_description), trailingContent = { - Switch( + HapticSwitch( checked = autoUpdate, onCheckedChange = onAutoUpdateChange ) diff --git a/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleItem.kt b/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleItem.kt index 617c384f8a..2fdd8f5d93 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleItem.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleItem.kt @@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ErrorOutline import androidx.compose.material.icons.outlined.Warning -import androidx.compose.material3.Checkbox import androidx.compose.material3.Icon import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme @@ -27,6 +26,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import app.revanced.manager.R import app.revanced.manager.domain.bundles.PatchBundleSource +import app.revanced.manager.ui.component.haptics.HapticCheckbox import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState import kotlinx.coroutines.flow.map @@ -71,7 +71,7 @@ fun BundleItem( ), leadingContent = if (selectable) { { - Checkbox( + HapticCheckbox( checked = isBundleSelected, onCheckedChange = toggleSelection, ) 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 2de48a5651..2de10053b4 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 @@ -170,7 +155,7 @@ fun SelectBundleTypeStep( overlineContent = { Text(stringResource(R.string.recommended)) }, supportingContent = { Text(stringResource(R.string.remote_bundle_description)) }, leadingContent = { - RadioButton( + HapticRadioButton( selected = bundleType == BundleType.Remote, onClick = null ) @@ -186,7 +171,7 @@ fun SelectBundleTypeStep( supportingContent = { Text(stringResource(R.string.local_bundle_description)) }, overlineContent = { }, leadingContent = { - RadioButton( + HapticRadioButton( selected = bundleType == BundleType.Local, onClick = null ) @@ -263,7 +248,7 @@ fun ImportBundleStep( headlineContent = { Text(stringResource(R.string.auto_update)) }, leadingContent = { CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { - Checkbox( + HapticCheckbox( checked = autoUpdate, onCheckedChange = { onAutoUpdateChange(!autoUpdate) diff --git a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticCheckbox.kt b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticCheckbox.kt new file mode 100644 index 0000000000..fb98e40f89 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticCheckbox.kt @@ -0,0 +1,40 @@ +package app.revanced.manager.ui.component.haptics + +import android.view.HapticFeedbackConstants +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxColors +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalView + +@Composable +fun HapticCheckbox ( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true, + colors: CheckboxColors = CheckboxDefaults.colors(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } +) { + val checkedState = remember { mutableStateOf(checked) } + + // Perform haptic feedback + if (checkedState.value != checked) { + val view = LocalView.current + view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK) + checkedState.value = checked + } + + Checkbox( + checked = checked, + onCheckedChange = onCheckedChange, + modifier = modifier, + enabled = enabled, + colors = colors, + interactionSource = interactionSource + ) +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticExtendedFloatingActionButton.kt b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticExtendedFloatingActionButton.kt new file mode 100644 index 0000000000..f9d91caf61 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticExtendedFloatingActionButton.kt @@ -0,0 +1,48 @@ +package app.revanced.manager.ui.component.haptics + +import android.view.HapticFeedbackConstants +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.ExtendedFloatingActionButton +import androidx.compose.material3.FloatingActionButtonDefaults +import androidx.compose.material3.FloatingActionButtonElevation +import androidx.compose.material3.contentColorFor +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.platform.LocalView + +@Composable +fun HapticExtendedFloatingActionButton ( + text: @Composable () -> Unit, + icon: @Composable () -> Unit, + onClick: () -> Unit, + modifier: Modifier = Modifier, + expanded: Boolean = true, + shape: Shape = FloatingActionButtonDefaults.extendedFabShape, + containerColor: Color = FloatingActionButtonDefaults.containerColor, + contentColor: Color = contentColorFor(containerColor), + elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val view = LocalView.current + + ExtendedFloatingActionButton( + text = text, + icon = icon, + onClick = { + // Perform haptic feedback + view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) + + onClick() + }, + modifier = modifier, + expanded = expanded, + shape = shape, + containerColor = containerColor, + contentColor = contentColor, + elevation = elevation, + interactionSource = interactionSource + ) +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticFloatingActionButton.kt b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticFloatingActionButton.kt new file mode 100644 index 0000000000..0268accce4 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticFloatingActionButton.kt @@ -0,0 +1,44 @@ +package app.revanced.manager.ui.component.haptics + +import android.view.HapticFeedbackConstants +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.FloatingActionButtonDefaults +import androidx.compose.material3.FloatingActionButtonElevation +import androidx.compose.material3.contentColorFor +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.platform.LocalView + +@Composable +fun HapticFloatingActionButton ( + onClick: () -> Unit, + modifier: Modifier = Modifier, + shape: Shape = FloatingActionButtonDefaults.shape, + containerColor: Color = FloatingActionButtonDefaults.containerColor, + contentColor: Color = contentColorFor(containerColor), + elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + content: @Composable () -> Unit, +) { + val view = LocalView.current + + FloatingActionButton( + onClick = { + // Perform haptic feedback + view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) + + onClick() + }, + modifier = modifier, + shape = shape, + containerColor = containerColor, + contentColor = contentColor, + elevation = elevation, + interactionSource = interactionSource, + content = content + ) +} 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 new file mode 100644 index 0000000000..7ac6a7a857 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticRadioButton.kt @@ -0,0 +1,42 @@ +package app.revanced.manager.ui.component.haptics + +import android.view.HapticFeedbackConstants +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.RadioButton +import androidx.compose.material3.RadioButtonColors +import androidx.compose.material3.RadioButtonDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalView + +@Composable +fun HapticRadioButton ( + selected: Boolean, + onClick: (() -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true, + colors: RadioButtonColors = RadioButtonDefaults.colors(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } +) { + val selectedState = remember { mutableStateOf(selected) } + + // Perform haptic feedback + if (selectedState.value != selected) { + if (selected) { + val view = LocalView.current + view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK) + } + selectedState.value = selected + } + + RadioButton( + selected = selected, + onClick = onClick, + modifier = modifier, + enabled = enabled, + colors = colors, + interactionSource = interactionSource + ) +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticSwitch.kt b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticSwitch.kt new file mode 100644 index 0000000000..fa3e894b2d --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticSwitch.kt @@ -0,0 +1,46 @@ +package app.revanced.manager.ui.component.haptics +import android.os.Build +import android.view.HapticFeedbackConstants +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.Switch +import androidx.compose.material3.SwitchColors +import androidx.compose.material3.SwitchDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalView + +@Composable +fun HapticSwitch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit), + modifier: Modifier = Modifier, + thumbContent: (@Composable () -> Unit)? = null, + enabled: Boolean = true, + colors: SwitchColors = SwitchDefaults.colors(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val checkedState = remember { mutableStateOf(checked) } + + // Perform haptic feedback + if (checkedState.value != checked) { + val view = LocalView.current + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + view.performHapticFeedback(if (checked) HapticFeedbackConstants.TOGGLE_ON else HapticFeedbackConstants.TOGGLE_OFF) + } else { + view.performHapticFeedback(if (checked) HapticFeedbackConstants.VIRTUAL_KEY else HapticFeedbackConstants.CLOCK_TICK) + } + checkedState.value = checked + } + + Switch( + checked = checked, + onCheckedChange = onCheckedChange, + modifier = modifier, + thumbContent = thumbContent, + enabled = enabled, + colors = colors, + interactionSource = interactionSource, + ) +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticTab.kt b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticTab.kt new file mode 100644 index 0000000000..3b5a11e913 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticTab.kt @@ -0,0 +1,43 @@ +package app.revanced.manager.ui.component.haptics + +import android.view.HapticFeedbackConstants +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Tab +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalView + +@Composable +fun HapticTab ( + selected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + text: @Composable (() -> Unit)? = null, + icon: @Composable (() -> Unit)? = null, + selectedContentColor: Color = LocalContentColor.current, + unselectedContentColor: Color = selectedContentColor, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } +) { + val view = LocalView.current + + Tab( + selected = selected, + onClick = { + // Perform haptic feedback + view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) + + onClick() + }, + modifier = modifier, + enabled = enabled, + text = text, + icon = icon, + selectedContentColor = selectedContentColor, + unselectedContentColor = unselectedContentColor, + interactionSource = interactionSource + ) +} \ No newline at end of file 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 e331db2e72..bb667bad8a 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 @@ -2,12 +2,7 @@ package app.revanced.manager.ui.component.patcher import androidx.compose.foundation.clickable 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.material3.TextButton +import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -17,6 +12,7 @@ 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( @@ -49,7 +45,7 @@ fun InstallPickerDialog( ListItem( modifier = Modifier.clickable { selectedInstallType = it }, leadingContent = { - RadioButton( + HapticRadioButton( selected = selectedInstallType == it, onClick = null ) 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 433c711bf4..993270ea2f 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 @@ -20,53 +20,31 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.DragHandle -import androidx.compose.material.icons.outlined.Add -import androidx.compose.material.icons.outlined.Delete -import androidx.compose.material.icons.outlined.Edit -import androidx.compose.material.icons.outlined.Folder -import androidx.compose.material.icons.outlined.MoreVert -import androidx.compose.material.icons.outlined.Restore -import androidx.compose.material.icons.outlined.SelectAll -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.Switch -import androidx.compose.material3.Text -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.TextButton +import androidx.compose.material.icons.outlined.* +import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.DisallowComposableCalls import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf -import androidx.compose.runtime.setValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.runtime.toMutableStateList import androidx.compose.ui.Modifier import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog as ComposeDialog import androidx.compose.ui.window.DialogProperties import app.revanced.manager.R import app.revanced.manager.data.platform.Filesystem import app.revanced.manager.patcher.patch.Option -import app.revanced.manager.ui.component.AlertDialogExtended -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.* +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 import app.revanced.manager.util.saver.snapshotStateListSaver @@ -80,6 +58,7 @@ import sh.calvin.reorderable.ReorderableItem import sh.calvin.reorderable.rememberReorderableLazyColumnState import java.io.Serializable import kotlin.random.Random +import androidx.compose.ui.window.Dialog as ComposeDialog private class OptionEditorScope( private val editor: OptionEditor, @@ -335,7 +314,7 @@ private object BooleanOptionEditor : OptionEditor { @Composable override fun ListItemTrailingContent(scope: OptionEditorScope) { - Switch(checked = scope.current, onCheckedChange = scope.setValue) + HapticSwitch(checked = scope.current, onCheckedChange = scope.setValue) } @Composable @@ -422,7 +401,7 @@ private class PresetOptionEditor(private val innerEditor: OptionEditor< headlineContent = { Text(title) }, supportingContent = value?.toString()?.let { { Text(it) } }, leadingContent = { - RadioButton( + HapticRadioButton( selected = selectedPreset == presetKey, onClick = { selectedPreset = presetKey } ) @@ -568,7 +547,7 @@ private class ListOptionEditor(private val elementEditor: Opti floatingActionButton = { if (deleteMode) return@Scaffold - ExtendedFloatingActionButton( + HapticExtendedFloatingActionButton( text = { Text(stringResource(R.string.add)) }, icon = { Icon( 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..0be1be91d2 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 @@ -2,13 +2,13 @@ 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.rememberCoroutineScope 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.haptics.HapticSwitch import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -45,7 +45,7 @@ fun BooleanItem( headlineContent = stringResource(headline), supportingContent = stringResource(description), trailingContent = { - Switch( + HapticSwitch( checked = value, onCheckedChange = onValueChange, ) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt index bf310fc71a..157986ec4d 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt @@ -33,6 +33,8 @@ import app.revanced.manager.ui.component.AvailableUpdateDialog import app.revanced.manager.ui.component.NotificationCard import app.revanced.manager.ui.component.bundle.BundleItem import app.revanced.manager.ui.component.bundle.BundleTopBar +import app.revanced.manager.ui.component.haptics.HapticFloatingActionButton +import app.revanced.manager.ui.component.haptics.HapticTab import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog import app.revanced.manager.ui.viewmodel.DashboardViewModel import app.revanced.manager.util.toast @@ -168,7 +170,7 @@ fun DashboardScreen( } }, floatingActionButton = { - FloatingActionButton( + HapticFloatingActionButton( onClick = { vm.cancelSourceSelection() @@ -181,7 +183,7 @@ fun DashboardScreen( DashboardPage.BUNDLES.ordinal ) } - return@FloatingActionButton + return@HapticFloatingActionButton } onAppSelectorClick() @@ -201,7 +203,7 @@ fun DashboardScreen( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp) ) { DashboardPage.entries.forEachIndexed { index, page -> - Tab( + HapticTab( selected = pagerState.currentPage == index, onClick = { composableScope.launch { pagerState.animateScrollToPage(index) } }, text = { Text(stringResource(page.titleResId)) }, diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt index 2c7792d056..6aedde2f02 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt @@ -4,12 +4,7 @@ import androidx.activity.compose.BackHandler import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts.CreateDocument import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons @@ -17,13 +12,7 @@ import androidx.compose.material.icons.automirrored.outlined.OpenInNew import androidx.compose.material.icons.outlined.FileDownload import androidx.compose.material.icons.outlined.PostAdd import androidx.compose.material.icons.outlined.Save -import androidx.compose.material3.BottomAppBar -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ExtendedFloatingActionButton -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.LinearProgressIndicator -import androidx.compose.material3.Text +import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -42,6 +31,7 @@ import app.revanced.manager.data.room.apps.installed.InstallType import app.revanced.manager.ui.component.AppScaffold import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.InstallerStatusDialog +import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton import app.revanced.manager.ui.component.patcher.InstallPickerDialog import app.revanced.manager.ui.component.patcher.Steps import app.revanced.manager.ui.model.State @@ -121,7 +111,7 @@ fun PatcherScreen( }, floatingActionButton = { AnimatedVisibility(visible = canInstall) { - ExtendedFloatingActionButton( + HapticExtendedFloatingActionButton( text = { Text( stringResource(if (vm.installedPackageName == null) R.string.install_app else R.string.open_app) 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 f8109fab45..511ede2150 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,9 @@ 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.HapticCheckbox +import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton +import app.revanced.manager.ui.component.haptics.HapticTab 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 @@ -293,7 +296,7 @@ fun PatchesSelectorScreen( floatingActionButton = { if (!showPatchButton) return@Scaffold - ExtendedFloatingActionButton( + HapticExtendedFloatingActionButton( text = { Text(stringResource(R.string.save)) }, icon = { Icon( @@ -321,7 +324,7 @@ fun PatchesSelectorScreen( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp) ) { bundles.forEachIndexed { index, bundle -> - Tab( + HapticTab( selected = pagerState.currentPage == index, onClick = { composableScope.launch { @@ -432,13 +435,13 @@ private fun PatchItem( selected: Boolean, onToggle: () -> Unit, supported: Boolean = true -) = ListItem( +) = ListItem ( modifier = Modifier .let { if (!supported) it.alpha(0.5f) else it } .clickable(onClick = onToggle) .fillMaxSize(), leadingContent = { - Checkbox( + HapticCheckbox( checked = selected, onCheckedChange = { onToggle() }, enabled = supported @@ -452,7 +455,7 @@ private fun PatchItem( Icon(Icons.Outlined.Settings, null) } } - } + }, ) @Composable 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 c4bfc8418c..9c3f59d469 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 @@ -8,13 +8,7 @@ import androidx.compose.foundation.layout.padding 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 -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text +import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -28,6 +22,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 @@ -36,11 +31,7 @@ import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel import app.revanced.manager.util.Options import app.revanced.manager.util.PatchSelection import app.revanced.manager.util.toast -import dev.olshevski.navigation.reimagined.AnimatedNavHost -import dev.olshevski.navigation.reimagined.NavBackHandler -import dev.olshevski.navigation.reimagined.navigate -import dev.olshevski.navigation.reimagined.pop -import dev.olshevski.navigation.reimagined.rememberNavController +import dev.olshevski.navigation.reimagined.* import org.koin.androidx.compose.koinViewModel import org.koin.core.parameter.parametersOf @@ -161,7 +152,7 @@ private fun SelectedAppInfoScreen( ) }, floatingActionButton = { - ExtendedFloatingActionButton( + HapticExtendedFloatingActionButton( text = { Text(stringResource(R.string.patch)) }, icon = { Icon( diff --git a/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt index 2ca8baa690..cd18dcc7da 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt @@ -11,10 +11,8 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ExtendedFloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.ListItem -import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -34,6 +32,8 @@ import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.LazyColumnWithScrollbar import app.revanced.manager.ui.component.LoadingIndicator +import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton +import app.revanced.manager.ui.component.haptics.HapticRadioButton import app.revanced.manager.ui.component.NonSuggestedVersionDialog import app.revanced.manager.ui.model.SelectedApp import app.revanced.manager.ui.viewmodel.VersionSelectorViewModel @@ -81,7 +81,7 @@ fun VersionSelectorScreen( ) }, floatingActionButton = { - ExtendedFloatingActionButton( + HapticExtendedFloatingActionButton( text = { Text(stringResource(R.string.select_version)) }, icon = { Icon( @@ -170,7 +170,7 @@ fun SelectedAppItem( alreadyPatched: Boolean = false, ) { ListItem( - leadingContent = { RadioButton(selected, null) }, + leadingContent = { HapticRadioButton(selected, null) }, headlineContent = { Text(selectedApp.version) }, supportingContent = when (selectedApp) { is SelectedApp.Installed -> 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 432c4808c1..41e80b403d 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 @@ -70,7 +70,7 @@ fun DownloadsSettingsScreen( modifier = Modifier.clickable { viewModel.toggleItem(app) }, headlineContent = app.packageName, leadingContent = (@Composable { - Checkbox( + HapticCheckbox( checked = selected, onCheckedChange = { viewModel.toggleItem(app) } ) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt index 03eae09fe5..5624267976 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt @@ -28,6 +28,7 @@ import app.revanced.manager.domain.manager.PreferencesManager 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.HapticRadioButton import app.revanced.manager.ui.component.settings.BooleanItem import app.revanced.manager.ui.component.settings.SettingsListItem import app.revanced.manager.ui.theme.Theme @@ -113,7 +114,7 @@ private fun ThemePicker( .clickable { selectedTheme = it }, verticalAlignment = Alignment.CenterVertically ) { - RadioButton( + HapticRadioButton( selected = selectedTheme == it, onClick = { selectedTheme = it }) Text(stringResource(it.displayName))