feat: Add haptic feedback for buttons

This commit is contained in:
Nishant Mishra
2025-09-15 15:59:53 +05:30
parent 6fd8ee43be
commit a8b7dae476
2 changed files with 15 additions and 10 deletions

View File

@@ -28,14 +28,11 @@ import androidx.compose.material3.ShortNavigationBarItem
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -69,14 +66,9 @@ fun AppScreen(
val progress by rememberUpdatedState((uiState.totalTime.toFloat() - remainingTime) / uiState.totalTime) val progress by rememberUpdatedState((uiState.totalTime.toFloat() - remainingTime) / uiState.totalTime)
val layoutDirection = LocalLayoutDirection.current val layoutDirection = LocalLayoutDirection.current
val haptic = LocalHapticFeedback.current
val motionScheme = motionScheme val motionScheme = motionScheme
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
LaunchedEffect(uiState.timerMode) {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
}
val backStack = rememberNavBackStack<Screen>(Screen.Timer) val backStack = rememberNavBackStack<Screen>(Screen.Timer)
Scaffold( Scaffold(

View File

@@ -63,7 +63,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@@ -89,6 +91,7 @@ fun TimerScreen(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val motionScheme = motionScheme val motionScheme = motionScheme
val haptic = LocalHapticFeedback.current
val color by animateColorAsState( val color by animateColorAsState(
if (timerState.timerMode == TimerMode.FOCUS) colorScheme.primary if (timerState.timerMode == TimerMode.FOCUS) colorScheme.primary
@@ -301,6 +304,10 @@ fun TimerScreen(
FilledIconToggleButton( FilledIconToggleButton(
onCheckedChange = { checked -> onCheckedChange = { checked ->
onAction(TimerAction.ToggleTimer) onAction(TimerAction.ToggleTimer)
if (checked) haptic.performHapticFeedback(HapticFeedbackType.ToggleOn)
else haptic.performHapticFeedback(HapticFeedbackType.ToggleOff)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && checked) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && checked) {
permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
} }
@@ -358,7 +365,10 @@ fun TimerScreen(
customItem( customItem(
{ {
FilledTonalIconButton( FilledTonalIconButton(
onClick = { onAction(TimerAction.ResetTimer) }, onClick = {
onAction(TimerAction.ResetTimer)
haptic.performHapticFeedback(HapticFeedbackType.VirtualKey)
},
colors = IconButtonDefaults.filledTonalIconButtonColors( colors = IconButtonDefaults.filledTonalIconButtonColors(
containerColor = colorContainer containerColor = colorContainer
), ),
@@ -395,7 +405,10 @@ fun TimerScreen(
customItem( customItem(
{ {
FilledTonalIconButton( FilledTonalIconButton(
onClick = { onAction(TimerAction.SkipTimer(fromButton = true)) }, onClick = {
onAction(TimerAction.SkipTimer(fromButton = true))
haptic.performHapticFeedback(HapticFeedbackType.VirtualKey)
},
colors = IconButtonDefaults.filledTonalIconButtonColors( colors = IconButtonDefaults.filledTonalIconButtonColors(
containerColor = colorContainer containerColor = colorContainer
), ),