fix: only perform haptics on events

This commit is contained in:
Ax333l 2024-11-12 21:17:02 +01:00
parent b4c37e6ddc
commit cf322147d5
No known key found for this signature in database
GPG Key ID: D2B4D85271127D23
8 changed files with 56 additions and 76 deletions

View File

@ -6,13 +6,12 @@ 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
import app.revanced.manager.util.withHapticFeedback
@Composable
fun HapticCheckbox (
fun HapticCheckbox(
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
@ -20,18 +19,9 @@ fun HapticCheckbox (
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,
onCheckedChange = onCheckedChange?.withHapticFeedback(HapticFeedbackConstants.CLOCK_TICK),
modifier = modifier,
enabled = enabled,
colors = colors,

View File

@ -11,7 +11,7 @@ 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
import app.revanced.manager.util.withHapticFeedback
@Composable
fun HapticExtendedFloatingActionButton (
@ -26,17 +26,10 @@ fun HapticExtendedFloatingActionButton (
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()
},
onClick = onClick.withHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY),
modifier = modifier,
expanded = expanded,
shape = shape,

View File

@ -11,7 +11,7 @@ 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
import app.revanced.manager.util.withHapticFeedback
@Composable
fun HapticFloatingActionButton (
@ -24,15 +24,8 @@ fun HapticFloatingActionButton (
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable () -> Unit,
) {
val view = LocalView.current
FloatingActionButton(
onClick = {
// Perform haptic feedback
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
onClick()
},
onClick = onClick.withHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY),
modifier = modifier,
shape = shape,
containerColor = containerColor,

View File

@ -6,13 +6,12 @@ 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 (
fun HapticRadioButton(
selected: Boolean,
onClick: (() -> Unit)?,
modifier: Modifier = Modifier,
@ -20,20 +19,17 @@ fun HapticRadioButton (
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
}
val view = LocalView.current
RadioButton(
selected = selected,
onClick = onClick,
onClick = onClick?.let {
{
// Perform haptic feedback
if (!selected) view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)
it()
}
},
modifier = modifier,
enabled = enabled,
colors = colors,

View File

@ -1,4 +1,5 @@
package app.revanced.manager.ui.component.haptics
import android.os.Build
import android.view.HapticFeedbackConstants
import androidx.compose.foundation.interaction.MutableInteractionSource
@ -6,37 +7,31 @@ 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),
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,
onCheckedChange = { newChecked ->
val useNewConstants = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
when {
newChecked && useNewConstants -> HapticFeedbackConstants.TOGGLE_ON
newChecked -> HapticFeedbackConstants.VIRTUAL_KEY
!newChecked && useNewConstants -> HapticFeedbackConstants.TOGGLE_OFF
!newChecked -> HapticFeedbackConstants.CLOCK_TICK
}
onCheckedChange(newChecked)
},
modifier = modifier,
thumbContent = thumbContent,
enabled = enabled,

View File

@ -8,7 +8,7 @@ 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
import app.revanced.manager.util.withHapticFeedback
@Composable
fun HapticTab (
@ -22,16 +22,9 @@ fun HapticTab (
unselectedContentColor: Color = selectedContentColor,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
val view = LocalView.current
Tab(
selected = selected,
onClick = {
// Perform haptic feedback
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
onClick()
},
onClick = onClick.withHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY),
modifier = modifier,
enabled = enabled,
text = text,

View File

@ -4,6 +4,7 @@ import android.app.ActivityManager
import android.content.ClipData
import android.content.ClipboardManager
import android.os.Build
import android.view.HapticFeedbackConstants
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.ExperimentalFoundationApi
@ -17,9 +18,7 @@ import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@ -35,6 +34,7 @@ import app.revanced.manager.ui.component.settings.IntegerItem
import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel
import app.revanced.manager.util.toast
import app.revanced.manager.util.withHapticFeedback
import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@ -52,7 +52,6 @@ fun AdvancedSettingsScreen(
activityManager.largeMemoryClass
)
}
val haptics = LocalHapticFeedback.current
Scaffold(
topBar = {
@ -159,13 +158,12 @@ fun AdvancedSettingsScreen(
onClick = { },
onLongClickLabel = stringResource(R.string.copy_to_clipboard),
onLongClick = {
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
clipboard.setPrimaryClip(
ClipData.newPlainText("Device Information", deviceContent)
)
context.toast(context.getString(R.string.toast_copied_to_clipboard))
}
}.withHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
),
headlineContent = stringResource(R.string.about_device),
supportingContent = deviceContent

View File

@ -14,6 +14,7 @@ import androidx.annotation.StringRes
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@ -21,6 +22,7 @@ import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView
import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
@ -218,4 +220,24 @@ fun ScrollState.isScrollingUp(): State<Boolean> {
}
val LazyListState.isScrollingUp: Boolean @Composable get() = this.isScrollingUp().value
val ScrollState.isScrollingUp: Boolean @Composable get() = this.isScrollingUp().value
val ScrollState.isScrollingUp: Boolean @Composable get() = this.isScrollingUp().value
@Composable
@ReadOnlyComposable
fun <R> (() -> R).withHapticFeedback(constant: Int): () -> R {
val view = LocalView.current
return {
view.performHapticFeedback(constant)
this()
}
}
@Composable
@ReadOnlyComposable
fun <T, R> ((T) -> R).withHapticFeedback(constant: Int): (T) -> R {
val view = LocalView.current
return {
view.performHapticFeedback(constant)
this(it)
}
}