Harden launch animation (PR #36 review follow-up)#43
Merged
Conversation
Follow-up fixes for the launch animation merged in #36. Build + lint green. - Keep the play icon in PlayButton (restores landscape rotation, the Play->Stop crossfade on the animation-off/reduce-motion path, and the first-frame icon); LaunchOverlay renders only during Crouch/Launch and the button alpha-hides its play icon during flight. - Sequence controller phases by awaiting animations instead of wall-clock delay(), so the state machine no longer desyncs at non-1x animator duration scale; durations now live in one place. - Set phase synchronously and serialize reset()/launch() via cancelAndJoin so same-frame double taps and a pending reset snap can't glitch the run. - Derive the button's a11y contentDescription from the real timer state so TalkBack announces "Stop" while a tap actually stops the running timer. - Read impactPulse/buttonScale/overlay animatables in draw/graphicsLayer lambdas (() -> Float), avoiding full-screen recomposition per frame; evaluate the reduce-motion gate at tap time instead of every recomposition. - Seed launchAnimationEnabled on key-absence (drop the SEEDED key + its overwrite race and per-start write), and guard the seed with try/catch so an IOException can't crash startup. - Nits: use FastOutSlowInEasing and geometry.lerp, read appTheme() inside LaunchOverlay, and move the design docs into docs/plans/ per CLAUDE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <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.
Follow-up to the launch animation merged in #36. This applies the fixes from the post-merge code review — they were prepared but never made it into #36 before it merged.
./gradlew assembleDebug lintis green.Correctness
PlayButton(with its orientationiconRotationand the Play↔Stop crossfade).LaunchOverlaynow renders only during Crouch/Launch; the button alpha-hides its play icon during flight via a newhidePlayIconparam.launch()also takes astartIconRotationDegso the handoff is seamless in landscape.SettingsRepositoryImplnow catchesIOException(best-effort; falls back to theUserSettingsdefault), matching the read path.coroutineScope { launch { animateTo(...) } }) instead of wall-clockdelay(). Durations live in one place.PlayButtongaineddescribesRunning, fed with the real running state, so it announces "Stop timer" while a tap actually stops the timer.launch()setsphasesynchronously (Idle guard now blocks same-frame double-launches),onTogglereadslaunchController.phaselive, andreset()/launch()serialize viacancelAndJoinso a pending reset snap can't cut into a new run.Performance / cleanup
impactPulseandbuttonScaleare now() -> Floatread inside draw/graphicsLayerlambdas; the overlay reads its animatables the same way. Frames are layer updates + redraws, not recomposition. The reduce-motionSettings.Globalread moved intoonToggle(once per tap, and picks up runtime changes).LAUNCH_ANIMATION_SEEDEDkey — the seed gates on key absence, removing both the overwrite-a-user-toggle race and the per-start write transaction.FastOutSlowInEasinginstead of hand-rolled beziers,geometry.lerpfor offset interpolation,appTheme()read insideLaunchOverlay(two color params dropped), and the design docs moved intodocs/plans/per CLAUDE.md.Note
The choreography still deserves one manual pass on a device — especially landscape launch, tap-during-animation, and a 2× animator-scale run — since the repo has no UI tests.
🤖 Generated with Claude Code