Native Material 3 settings screen for Android, plus fixes from a codebase review - #133
Merged
Merged
Conversation
The session store echoes each step change back into the fragment's initialStepIndex prop, so keeping it in the loop effect's dependencies tore down and recreated the animation loop at every step boundary. Capture the mount-time index in a ref instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
setupGuidedBreathingAudio filtered null sources out of an array and then read players back by index, which silently broke for any mode without step cues (e.g. "disabled"). Prepare each source by name and only create the step players when all step cues exist; the ending bell is always created. Add a unit test for the disabled mode. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
onPressIn sat before the {...otherProps} spread, so a caller-supplied
onPressIn would silently replace the haptic handler while onLongPress
and onPressOut sat after it. Move all three wrapper handlers after the
spread; each one already delegates to the caller's handler.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@expo/ui provides the native Jetpack Compose components for the new Android settings screen. expo moves to the 56.0.18 patch (same ~56.0.x range) because @expo/ui 56.0.24 needs the ColorCompat class introduced in a newer expo-modules-core. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The stepper value container was too narrow for two digits and rendered "10" as "1..". Disabled dimming sat on TouchableOpacity, which manages its own animated opacity and ignores dynamic opacity style changes, so enabling the custom pattern did not gray out the presets until an unrelated re-render. The dimming now lives on an inner View, and the stepper icons dim through their own style. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…al 3 The Android settings UI now renders native Compose Material 3 views via @expo/ui, aligned with the stock Android settings app (verified against it on a Pixel emulator, including pixel-exact window/card tokens: surfaceContainer background, surfaceBright cards, 20dp/5dp grouped card corners): - stock-style title bar with a tonal circular back button (native-stack header hidden on Android only) - rows are Material ListItems with ripple; switch rows toggle on row tap - voice keeps the list-preference radio dialog; the two-option theme choice is an inline segmented button row - the exercise timer is a native slider (new clamped setTimeLimit store action); custom pattern durations keep precise stepper buttons - Material You dynamic color on Android 12+, driven by the app theme so the in-app light/dark override wins over the system The previous JS implementation moves to settings-ui.web.tsx so web keeps working. Maestro flows updated: dialog/segmented navigation, scroll steps for the taller Material rows, and a platform-branched timer step (slider drag on Android, steppers on iOS). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bounded ripple under a rounded clip flashed as a square layer; the back button now uses a borderless circular ripple with an explicit radius and a translucent scheme-aware color. The exercise timer goes back to the +/- stepper buttons; the slider, its store setter, and the platform-branched e2e steps are removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- web: build the section class list with a ternary instead of leaking a literal "false" into className - android: align section labels with the card titles (32dp) as stock does - settings-ui.d.ts: real component and prop declarations instead of the unresolvable ones skipLibCheck was hiding; widen the iOS icon prop and type the two picker call sites the new declarations flagged Note: keeping the switches/radios interactive inside their rows is deliberate; a passive control through @expo/ui still consumes taps natively and creates a dead zone on the control itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e stub The base variant must keep the same signature as the Android variant, so the parameter stays and gets an explicit eslint suppression. Caught by CI; the local lint invocations had piped the exit code away. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Bug fixes from a codebase review
initialStepIndexprop, tearing down and recreating the animation loop at every step boundary. The mount-time index now lives in a ref.disabledmode keeps only the ending bell (new unit test).Pressable: all wrapper handlers now sit after the props spread, so a caller-suppliedonPressIncan no longer replace the haptic handler.Android settings screen rebuilt with Jetpack Compose Material 3
Native Compose views via
@expo/ui(production-ready in SDK 56), aligned with the stock Android settings app and verified against it on a Pixel emulator — window/card tokens are pixel-identical (surfaceContainerbackground,surfaceBrightcards, 20dp/5dp grouped card corners, 2dp gaps):ListItems with ripple; switch rows toggle on a tap anywhere in the rowsettings-ui.web.tsx, so web keeps working; iOS is untouchediOS fixes
opacityonTouchableOpacityis ignored by its internal animation; the dimming now lives on an inner view)Dependencies
@expo/ui ~56.0.24added;expobumped to 56.0.18 within its existing range (needs the newerexpo-modules-core)