mirror of
https://github.com/revanced/revanced-manager.git
synced 2025-04-30 05:54:26 +02:00
feat: Add haptic feedback (#1457)
Co-authored-by: Ushie <ushiekane@gmail.com>
This commit is contained in:
parent
697386c36c
commit
b4c37e6ddc
@ -8,7 +8,6 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.outlined.Source
|
import androidx.compose.material.icons.outlined.Source
|
||||||
import androidx.compose.material.icons.outlined.Update
|
import androidx.compose.material.icons.outlined.Update
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Checkbox
|
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
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.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.haptics.HapticCheckbox
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AutoUpdatesDialog(onSubmit: (Boolean, Boolean) -> Unit) {
|
fun AutoUpdatesDialog(onSubmit: (Boolean, Boolean) -> Unit) {
|
||||||
@ -76,6 +76,6 @@ private fun AutoUpdatesItem(
|
|||||||
) = ListItem(
|
) = ListItem(
|
||||||
leadingContent = { Icon(icon, null) },
|
leadingContent = { Icon(icon, null) },
|
||||||
headlineContent = { Text(stringResource(headline)) },
|
headlineContent = { Text(stringResource(headline)) },
|
||||||
trailingContent = { Checkbox(checked = checked, onCheckedChange = null) },
|
trailingContent = { HapticCheckbox(checked = checked, onCheckedChange = null) },
|
||||||
modifier = Modifier.clickable { onCheckedChange(!checked) }
|
modifier = Modifier.clickable { onCheckedChange(!checked) }
|
||||||
)
|
)
|
@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.haptics.HapticCheckbox
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -70,7 +71,7 @@ fun AvailableUpdateDialog(
|
|||||||
},
|
},
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
|
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
|
||||||
Checkbox(checked = dontShowAgain, onCheckedChange = { dontShowAgain = it })
|
HapticCheckbox(checked = dontShowAgain, onCheckedChange = { dontShowAgain = it })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -23,6 +23,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.TextInputDialog
|
import app.revanced.manager.ui.component.TextInputDialog
|
||||||
|
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BaseBundleDialog(
|
fun BaseBundleDialog(
|
||||||
@ -89,7 +90,7 @@ fun BaseBundleDialog(
|
|||||||
headlineText = stringResource(R.string.bundle_auto_update),
|
headlineText = stringResource(R.string.bundle_auto_update),
|
||||||
supportingText = stringResource(R.string.bundle_auto_update_description),
|
supportingText = stringResource(R.string.bundle_auto_update_description),
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
Switch(
|
HapticSwitch(
|
||||||
checked = autoUpdate,
|
checked = autoUpdate,
|
||||||
onCheckedChange = onAutoUpdateChange
|
onCheckedChange = onAutoUpdateChange
|
||||||
)
|
)
|
||||||
|
@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.size
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.ErrorOutline
|
import androidx.compose.material.icons.outlined.ErrorOutline
|
||||||
import androidx.compose.material.icons.outlined.Warning
|
import androidx.compose.material.icons.outlined.Warning
|
||||||
import androidx.compose.material3.Checkbox
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@ -27,6 +26,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.domain.bundles.PatchBundleSource
|
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 app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ fun BundleItem(
|
|||||||
),
|
),
|
||||||
leadingContent = if (selectable) {
|
leadingContent = if (selectable) {
|
||||||
{
|
{
|
||||||
Checkbox(
|
HapticCheckbox(
|
||||||
checked = isBundleSelected,
|
checked = isBundleSelected,
|
||||||
onCheckedChange = toggleSelection,
|
onCheckedChange = toggleSelection,
|
||||||
)
|
)
|
||||||
|
@ -10,26 +10,9 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Topic
|
import androidx.compose.material.icons.filled.Topic
|
||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.runtime.*
|
||||||
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.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.Role
|
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.R
|
||||||
import app.revanced.manager.ui.component.AlertDialogExtended
|
import app.revanced.manager.ui.component.AlertDialogExtended
|
||||||
import app.revanced.manager.ui.component.TextHorizontalPadding
|
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.ui.model.BundleType
|
||||||
import app.revanced.manager.util.APK_MIMETYPE
|
import app.revanced.manager.util.APK_MIMETYPE
|
||||||
import app.revanced.manager.util.JAR_MIMETYPE
|
import app.revanced.manager.util.JAR_MIMETYPE
|
||||||
@ -170,7 +155,7 @@ fun SelectBundleTypeStep(
|
|||||||
overlineContent = { Text(stringResource(R.string.recommended)) },
|
overlineContent = { Text(stringResource(R.string.recommended)) },
|
||||||
supportingContent = { Text(stringResource(R.string.remote_bundle_description)) },
|
supportingContent = { Text(stringResource(R.string.remote_bundle_description)) },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
RadioButton(
|
HapticRadioButton(
|
||||||
selected = bundleType == BundleType.Remote,
|
selected = bundleType == BundleType.Remote,
|
||||||
onClick = null
|
onClick = null
|
||||||
)
|
)
|
||||||
@ -186,7 +171,7 @@ fun SelectBundleTypeStep(
|
|||||||
supportingContent = { Text(stringResource(R.string.local_bundle_description)) },
|
supportingContent = { Text(stringResource(R.string.local_bundle_description)) },
|
||||||
overlineContent = { },
|
overlineContent = { },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
RadioButton(
|
HapticRadioButton(
|
||||||
selected = bundleType == BundleType.Local,
|
selected = bundleType == BundleType.Local,
|
||||||
onClick = null
|
onClick = null
|
||||||
)
|
)
|
||||||
@ -263,7 +248,7 @@ fun ImportBundleStep(
|
|||||||
headlineContent = { Text(stringResource(R.string.auto_update)) },
|
headlineContent = { Text(stringResource(R.string.auto_update)) },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
|
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
|
||||||
Checkbox(
|
HapticCheckbox(
|
||||||
checked = autoUpdate,
|
checked = autoUpdate,
|
||||||
onCheckedChange = {
|
onCheckedChange = {
|
||||||
onAutoUpdateChange(!autoUpdate)
|
onAutoUpdateChange(!autoUpdate)
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -2,12 +2,7 @@ package app.revanced.manager.ui.component.patcher
|
|||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.*
|
||||||
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.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -17,6 +12,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.data.room.apps.installed.InstallType
|
import app.revanced.manager.data.room.apps.installed.InstallType
|
||||||
|
import app.revanced.manager.ui.component.haptics.HapticRadioButton
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun InstallPickerDialog(
|
fun InstallPickerDialog(
|
||||||
@ -49,7 +45,7 @@ fun InstallPickerDialog(
|
|||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier.clickable { selectedInstallType = it },
|
modifier = Modifier.clickable { selectedInstallType = it },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
RadioButton(
|
HapticRadioButton(
|
||||||
selected = selectedInstallType == it,
|
selected = selectedInstallType == it,
|
||||||
onClick = null
|
onClick = null
|
||||||
)
|
)
|
||||||
|
@ -20,53 +20,31 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.DragHandle
|
import androidx.compose.material.icons.filled.DragHandle
|
||||||
import androidx.compose.material.icons.outlined.Add
|
import androidx.compose.material.icons.outlined.*
|
||||||
import androidx.compose.material.icons.outlined.Delete
|
import androidx.compose.material3.*
|
||||||
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.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisallowComposableCalls
|
import androidx.compose.runtime.DisallowComposableCalls
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
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.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.toMutableStateList
|
import androidx.compose.runtime.toMutableStateList
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.pluralStringResource
|
import androidx.compose.ui.res.pluralStringResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontStyle
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog as ComposeDialog
|
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.data.platform.Filesystem
|
import app.revanced.manager.data.platform.Filesystem
|
||||||
import app.revanced.manager.patcher.patch.Option
|
import app.revanced.manager.patcher.patch.Option
|
||||||
import app.revanced.manager.ui.component.AlertDialogExtended
|
import app.revanced.manager.ui.component.*
|
||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
||||||
import app.revanced.manager.ui.component.FloatInputDialog
|
import app.revanced.manager.ui.component.haptics.HapticRadioButton
|
||||||
import app.revanced.manager.ui.component.IntInputDialog
|
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
||||||
import app.revanced.manager.ui.component.LongInputDialog
|
|
||||||
import app.revanced.manager.util.isScrollingUp
|
import app.revanced.manager.util.isScrollingUp
|
||||||
import app.revanced.manager.util.mutableStateSetOf
|
import app.revanced.manager.util.mutableStateSetOf
|
||||||
import app.revanced.manager.util.saver.snapshotStateListSaver
|
import app.revanced.manager.util.saver.snapshotStateListSaver
|
||||||
@ -80,6 +58,7 @@ import sh.calvin.reorderable.ReorderableItem
|
|||||||
import sh.calvin.reorderable.rememberReorderableLazyColumnState
|
import sh.calvin.reorderable.rememberReorderableLazyColumnState
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
import androidx.compose.ui.window.Dialog as ComposeDialog
|
||||||
|
|
||||||
private class OptionEditorScope<T : Any>(
|
private class OptionEditorScope<T : Any>(
|
||||||
private val editor: OptionEditor<T>,
|
private val editor: OptionEditor<T>,
|
||||||
@ -335,7 +314,7 @@ private object BooleanOptionEditor : OptionEditor<Boolean> {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ListItemTrailingContent(scope: OptionEditorScope<Boolean>) {
|
override fun ListItemTrailingContent(scope: OptionEditorScope<Boolean>) {
|
||||||
Switch(checked = scope.current, onCheckedChange = scope.setValue)
|
HapticSwitch(checked = scope.current, onCheckedChange = scope.setValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -422,7 +401,7 @@ private class PresetOptionEditor<T : Any>(private val innerEditor: OptionEditor<
|
|||||||
headlineContent = { Text(title) },
|
headlineContent = { Text(title) },
|
||||||
supportingContent = value?.toString()?.let { { Text(it) } },
|
supportingContent = value?.toString()?.let { { Text(it) } },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
RadioButton(
|
HapticRadioButton(
|
||||||
selected = selectedPreset == presetKey,
|
selected = selectedPreset == presetKey,
|
||||||
onClick = { selectedPreset = presetKey }
|
onClick = { selectedPreset = presetKey }
|
||||||
)
|
)
|
||||||
@ -568,7 +547,7 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
if (deleteMode) return@Scaffold
|
if (deleteMode) return@Scaffold
|
||||||
|
|
||||||
ExtendedFloatingActionButton(
|
HapticExtendedFloatingActionButton(
|
||||||
text = { Text(stringResource(R.string.add)) },
|
text = { Text(stringResource(R.string.add)) },
|
||||||
icon = {
|
icon = {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -2,13 +2,13 @@ package app.revanced.manager.ui.component.settings
|
|||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.material3.Switch
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import app.revanced.manager.domain.manager.base.Preference
|
import app.revanced.manager.domain.manager.base.Preference
|
||||||
|
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ fun BooleanItem(
|
|||||||
headlineContent = stringResource(headline),
|
headlineContent = stringResource(headline),
|
||||||
supportingContent = stringResource(description),
|
supportingContent = stringResource(description),
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
Switch(
|
HapticSwitch(
|
||||||
checked = value,
|
checked = value,
|
||||||
onCheckedChange = onValueChange,
|
onCheckedChange = onValueChange,
|
||||||
)
|
)
|
||||||
|
@ -33,6 +33,8 @@ import app.revanced.manager.ui.component.AvailableUpdateDialog
|
|||||||
import app.revanced.manager.ui.component.NotificationCard
|
import app.revanced.manager.ui.component.NotificationCard
|
||||||
import app.revanced.manager.ui.component.bundle.BundleItem
|
import app.revanced.manager.ui.component.bundle.BundleItem
|
||||||
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
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.component.bundle.ImportPatchBundleDialog
|
||||||
import app.revanced.manager.ui.viewmodel.DashboardViewModel
|
import app.revanced.manager.ui.viewmodel.DashboardViewModel
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
@ -168,7 +170,7 @@ fun DashboardScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
FloatingActionButton(
|
HapticFloatingActionButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
vm.cancelSourceSelection()
|
vm.cancelSourceSelection()
|
||||||
|
|
||||||
@ -181,7 +183,7 @@ fun DashboardScreen(
|
|||||||
DashboardPage.BUNDLES.ordinal
|
DashboardPage.BUNDLES.ordinal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@FloatingActionButton
|
return@HapticFloatingActionButton
|
||||||
}
|
}
|
||||||
|
|
||||||
onAppSelectorClick()
|
onAppSelectorClick()
|
||||||
@ -201,7 +203,7 @@ fun DashboardScreen(
|
|||||||
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
|
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
|
||||||
) {
|
) {
|
||||||
DashboardPage.entries.forEachIndexed { index, page ->
|
DashboardPage.entries.forEachIndexed { index, page ->
|
||||||
Tab(
|
HapticTab(
|
||||||
selected = pagerState.currentPage == index,
|
selected = pagerState.currentPage == index,
|
||||||
onClick = { composableScope.launch { pagerState.animateScrollToPage(index) } },
|
onClick = { composableScope.launch { pagerState.animateScrollToPage(index) } },
|
||||||
text = { Text(stringResource(page.titleResId)) },
|
text = { Text(stringResource(page.titleResId)) },
|
||||||
|
@ -4,12 +4,7 @@ import androidx.activity.compose.BackHandler
|
|||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
|
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.*
|
||||||
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.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.icons.Icons
|
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.FileDownload
|
||||||
import androidx.compose.material.icons.outlined.PostAdd
|
import androidx.compose.material.icons.outlined.PostAdd
|
||||||
import androidx.compose.material.icons.outlined.Save
|
import androidx.compose.material.icons.outlined.Save
|
||||||
import androidx.compose.material3.BottomAppBar
|
import androidx.compose.material3.*
|
||||||
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.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
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.AppScaffold
|
||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
import app.revanced.manager.ui.component.InstallerStatusDialog
|
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.InstallPickerDialog
|
||||||
import app.revanced.manager.ui.component.patcher.Steps
|
import app.revanced.manager.ui.component.patcher.Steps
|
||||||
import app.revanced.manager.ui.model.State
|
import app.revanced.manager.ui.model.State
|
||||||
@ -121,7 +111,7 @@ fun PatcherScreen(
|
|||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
AnimatedVisibility(visible = canInstall) {
|
AnimatedVisibility(visible = canInstall) {
|
||||||
ExtendedFloatingActionButton(
|
HapticExtendedFloatingActionButton(
|
||||||
text = {
|
text = {
|
||||||
Text(
|
Text(
|
||||||
stringResource(if (vm.installedPackageName == null) R.string.install_app else R.string.open_app)
|
stringResource(if (vm.installedPackageName == null) R.string.install_app else R.string.open_app)
|
||||||
|
@ -35,6 +35,9 @@ import app.revanced.manager.ui.component.AppTopBar
|
|||||||
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.SafeguardDialog
|
import app.revanced.manager.ui.component.SafeguardDialog
|
||||||
import app.revanced.manager.ui.component.SearchView
|
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.component.patches.OptionItem
|
||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
|
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
|
||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_SUPPORTED
|
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_SUPPORTED
|
||||||
@ -293,7 +296,7 @@ fun PatchesSelectorScreen(
|
|||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
if (!showPatchButton) return@Scaffold
|
if (!showPatchButton) return@Scaffold
|
||||||
|
|
||||||
ExtendedFloatingActionButton(
|
HapticExtendedFloatingActionButton(
|
||||||
text = { Text(stringResource(R.string.save)) },
|
text = { Text(stringResource(R.string.save)) },
|
||||||
icon = {
|
icon = {
|
||||||
Icon(
|
Icon(
|
||||||
@ -321,7 +324,7 @@ fun PatchesSelectorScreen(
|
|||||||
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
|
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
|
||||||
) {
|
) {
|
||||||
bundles.forEachIndexed { index, bundle ->
|
bundles.forEachIndexed { index, bundle ->
|
||||||
Tab(
|
HapticTab(
|
||||||
selected = pagerState.currentPage == index,
|
selected = pagerState.currentPage == index,
|
||||||
onClick = {
|
onClick = {
|
||||||
composableScope.launch {
|
composableScope.launch {
|
||||||
@ -438,7 +441,7 @@ private fun PatchItem(
|
|||||||
.clickable(onClick = onToggle)
|
.clickable(onClick = onToggle)
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
Checkbox(
|
HapticCheckbox(
|
||||||
checked = selected,
|
checked = selected,
|
||||||
onCheckedChange = { onToggle() },
|
onCheckedChange = { onToggle() },
|
||||||
enabled = supported
|
enabled = supported
|
||||||
@ -452,7 +455,7 @@ private fun PatchItem(
|
|||||||
Icon(Icons.Outlined.Settings, null)
|
Icon(Icons.Outlined.Settings, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -8,13 +8,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
|
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
|
||||||
import androidx.compose.material.icons.filled.AutoFixHigh
|
import androidx.compose.material.icons.filled.AutoFixHigh
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.*
|
||||||
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.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
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.AppInfo
|
||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
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.destination.SelectedAppInfoDestination
|
||||||
import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow
|
import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow
|
||||||
import app.revanced.manager.ui.model.SelectedApp
|
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.Options
|
||||||
import app.revanced.manager.util.PatchSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
import dev.olshevski.navigation.reimagined.AnimatedNavHost
|
import dev.olshevski.navigation.reimagined.*
|
||||||
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 org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
|
|
||||||
@ -161,7 +152,7 @@ private fun SelectedAppInfoScreen(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
ExtendedFloatingActionButton(
|
HapticExtendedFloatingActionButton(
|
||||||
text = { Text(stringResource(R.string.patch)) },
|
text = { Text(stringResource(R.string.patch)) },
|
||||||
icon = {
|
icon = {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -11,10 +11,8 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Check
|
import androidx.compose.material.icons.filled.Check
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.RadioButton
|
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.GroupHeader
|
||||||
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.LoadingIndicator
|
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.component.NonSuggestedVersionDialog
|
||||||
import app.revanced.manager.ui.model.SelectedApp
|
import app.revanced.manager.ui.model.SelectedApp
|
||||||
import app.revanced.manager.ui.viewmodel.VersionSelectorViewModel
|
import app.revanced.manager.ui.viewmodel.VersionSelectorViewModel
|
||||||
@ -81,7 +81,7 @@ fun VersionSelectorScreen(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
ExtendedFloatingActionButton(
|
HapticExtendedFloatingActionButton(
|
||||||
text = { Text(stringResource(R.string.select_version)) },
|
text = { Text(stringResource(R.string.select_version)) },
|
||||||
icon = {
|
icon = {
|
||||||
Icon(
|
Icon(
|
||||||
@ -170,7 +170,7 @@ fun SelectedAppItem(
|
|||||||
alreadyPatched: Boolean = false,
|
alreadyPatched: Boolean = false,
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
leadingContent = { RadioButton(selected, null) },
|
leadingContent = { HapticRadioButton(selected, null) },
|
||||||
headlineContent = { Text(selectedApp.version) },
|
headlineContent = { Text(selectedApp.version) },
|
||||||
supportingContent = when (selectedApp) {
|
supportingContent = when (selectedApp) {
|
||||||
is SelectedApp.Installed ->
|
is SelectedApp.Installed ->
|
||||||
|
@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material3.Checkbox
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
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.AppTopBar
|
||||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.GroupHeader
|
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.BooleanItem
|
||||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
import app.revanced.manager.ui.component.settings.SettingsListItem
|
||||||
import app.revanced.manager.ui.viewmodel.DownloadsViewModel
|
import app.revanced.manager.ui.viewmodel.DownloadsViewModel
|
||||||
@ -70,7 +70,7 @@ fun DownloadsSettingsScreen(
|
|||||||
modifier = Modifier.clickable { viewModel.toggleItem(app) },
|
modifier = Modifier.clickable { viewModel.toggleItem(app) },
|
||||||
headlineContent = app.packageName,
|
headlineContent = app.packageName,
|
||||||
leadingContent = (@Composable {
|
leadingContent = (@Composable {
|
||||||
Checkbox(
|
HapticCheckbox(
|
||||||
checked = selected,
|
checked = selected,
|
||||||
onCheckedChange = { viewModel.toggleItem(app) }
|
onCheckedChange = { viewModel.toggleItem(app) }
|
||||||
)
|
)
|
||||||
|
@ -28,6 +28,7 @@ import app.revanced.manager.domain.manager.PreferencesManager
|
|||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.GroupHeader
|
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.BooleanItem
|
||||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
import app.revanced.manager.ui.component.settings.SettingsListItem
|
||||||
import app.revanced.manager.ui.theme.Theme
|
import app.revanced.manager.ui.theme.Theme
|
||||||
@ -113,7 +114,7 @@ private fun ThemePicker(
|
|||||||
.clickable { selectedTheme = it },
|
.clickable { selectedTheme = it },
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
RadioButton(
|
HapticRadioButton(
|
||||||
selected = selectedTheme == it,
|
selected = selectedTheme == it,
|
||||||
onClick = { selectedTheme = it })
|
onClick = { selectedTheme = it })
|
||||||
Text(stringResource(it.displayName))
|
Text(stringResource(it.displayName))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user