fix(uhr): time picker digits clipped, dial haptics; 0.1.1
- the theme mapped displayLarge to the 88sp clock style, which the M3 time picker uses for its hour/minute fields; displayLarge/headline are back to M3 defaults - tick on every value the dial passes, firmer click when hours settle and on OK Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -306,22 +306,49 @@ fun soundName(uri: String?): String {
|
||||
}
|
||||
}
|
||||
|
||||
/** S03: M3 time picker with dial/keyboard switch. */
|
||||
/**
|
||||
* S03: M3 time picker with dial/keyboard switch. The Compose dial has no haptics; like the original we tick
|
||||
* on every value the hand passes and give a firmer click when it settles after release.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun TimeDialog(hour: Int, minute: Int, onDismiss: () -> Unit, onPick: (Int, Int) -> Unit) {
|
||||
val state = rememberTimePickerState(hour, minute, Fmt.is24h)
|
||||
var keyboard by remember { mutableStateOf(false) }
|
||||
val view = androidx.compose.ui.platform.LocalView.current
|
||||
androidx.compose.runtime.LaunchedEffect(state) {
|
||||
var last = state.hour to state.minute
|
||||
androidx.compose.runtime.snapshotFlow { state.hour to state.minute }.collect { now ->
|
||||
if (now != last) {
|
||||
view.performHapticFeedback(android.view.HapticFeedbackConstants.CLOCK_TICK)
|
||||
last = now
|
||||
}
|
||||
}
|
||||
}
|
||||
// the dial switches from hours to minutes when the hour settles: confirm that with a firmer click
|
||||
androidx.compose.runtime.LaunchedEffect(state) {
|
||||
var hourMode = state.selection == androidx.compose.material3.TimePickerSelectionMode.Hour
|
||||
androidx.compose.runtime.snapshotFlow { state.selection }.collect { sel ->
|
||||
val nowHour = sel == androidx.compose.material3.TimePickerSelectionMode.Hour
|
||||
if (hourMode && !nowHour) view.performHapticFeedback(android.view.HapticFeedbackConstants.CONFIRM)
|
||||
hourMode = nowHour
|
||||
}
|
||||
}
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.pick_time)) },
|
||||
text = {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth()) {
|
||||
if (keyboard) TimeInput(state) else TimePicker(state)
|
||||
TextButton(onClick = { keyboard = !keyboard }) { Text(stringResource(if (keyboard) R.string.use_dial else R.string.use_keyboard)) }
|
||||
}
|
||||
},
|
||||
confirmButton = { TextButton(onClick = { onPick(state.hour, state.minute) }) { Text(stringResource(android.R.string.ok)) } },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
view.performHapticFeedback(android.view.HapticFeedbackConstants.CONFIRM)
|
||||
onPick(state.hour, state.minute)
|
||||
}) { Text(stringResource(android.R.string.ok)) }
|
||||
},
|
||||
dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(android.R.string.cancel)) } },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ private val Dark = darkColorScheme(
|
||||
)
|
||||
|
||||
private val AppTypography = Typography(
|
||||
displayLarge = WType.clockBig, headlineLarge = WType.headline, titleLarge = WType.title,
|
||||
// displayLarge/headline stay M3 defaults: the time picker uses them for its hour and minute fields
|
||||
titleLarge = WType.title,
|
||||
bodyLarge = WType.body, bodyMedium = WType.bodySm, labelLarge = WType.label, labelMedium = WType.label, labelSmall = WType.labelSm,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user