Onboarding Design Update: Input choice screen#8223
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
2ff2148 to
bd70043
Compare
…date Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… screen The dax was animated in during the address bar step but had no exit animation. Now it slides left and fades out in sync with the background, using EXIT_DURATION and exitAlpha() exposed from OnboardingBackgroundAnimator. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ctions Replaces inline animation blocks with animateBobbingDaxIn() and animateBobbingDaxOut() to reduce duplication and make call sites readable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tapping the dialog card during animations completes them instantly. The card tap flows through the ViewModel (onDialogTapped → SkipDialogAnimation command) to skipCurrentDialogAnimation() which finishes any active typing, ends running fade-in AnimatorSets, and snaps comparison chart check icons to their final state. Invisible-but-clickable child views (option containers, CTA button) are disabled during animation to prevent them from consuming touch events meant for the skip handler, and re-enabled when the fade-in completes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…delTest Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ewModelTest Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…atePageViewModelTest Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… to prevent stacking Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d remove unused dismissLeftWingAnimation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ner to match other screens Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…troyView cleanup Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gleState for improved toggle handling
…add onDialogTapped test Align two remaining tablet checks in INPUT_SCREEN with the rest of the file, and add unit test for the SkipDialogAnimation command. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8b2079b to
edbd008
Compare
0bfe881 to
7bc45f8
Compare
…rotation The showDialogWithoutAnimation INPUT_SCREEN path was missing setArrowAnimationTarget/Fraction and translationZ that COMPARISON_CHART and ADDRESS_BAR_POSITION both set on rotation restore. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…_SCREEN AutoTransition runs Fade OUT + ChangeBounds + Fade IN sequentially, tripling the 400ms duration to 1200ms. Use ChangeBounds to match the other dialog steps. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
1 issue from previous review remains unresolved.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 95e17a2. Configure here.
LukasPaczos
left a comment
There was a problem hiding this comment.
Works as expected! Two things I wanted to discuss before we merge:
Click management
Generally (beside the comment below), skipping works but it's ~30 scattered isClickable = false/true calls across 5 dialog types, with unlock logic buried in nested animation callbacks. It seems to be correct now but very fragile and hard to extend/update if we ever need to touch the layouts.
The root cause of the complexity seems to be that each child view individually opts out of touches so that the card can handle them. What if we flip that - have the top level card (or screen) container that blocks touches from reaching children during animation?
For example, replace cardContainer's LinearLayout with a small custom subclass:
class TouchInterceptingLinearLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null,
) : LinearLayout(context, attrs) {
var interceptChildTouches = false
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
return interceptChildTouches || super.onInterceptTouchEvent(ev)
}
}When interceptChildTouches = true, children never receive touches. Touches go to the LinearLayout's own onTouchEvent, which fires the existing skip click listener
(viewModel.onDialogTapped()).
I generated a POC in #8241 - feel free to check it out and merge back here if you also think it'd be an improvement.
Dax wing during rotation
Minor issue - when screen is rotated mid-transition, the wing is gone on the resulting input selection screen. Rotating back again make it appear. Not a big deal but let's double-check there aren't any other issue this could cause.
Screen_recording_20260410_091534.mp4
I actually attempted something like you mentioned in regards to blocking touches but it broke some animations and in the interest of time i abandoned it. Let me get a look at your POC 👍 |
…ation Aligns with production onboarding behavior where tapping anywhere on screen skips the animation, not just tapping on the dialog card. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nterceptingLinearLayout Replace ~28 individual isClickable = false/true calls across 5 dialog types with a single TouchInterceptingLinearLayout that intercepts child touches when isAnimating is true. Based on POC from #8241. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Thanks Lukasz, great suggestion! I've adopted your
I'll take a look at this one separately. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5ef9d9e. Configure here.
…T_SCREEN The left wing was invisible after rotating mid-transition to the input screen. Two issues: the landscape layout anchored the wing to the parent bottom (behind the dialog) instead of below it, and the Lottie view needed its min/max progress set and a parent requestLayout() to render after going from GONE to VISIBLE inside the landscape ScrollView. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mand Remove dispatchers.io() from INPUT_SCREEN branch in onPrimaryCtaClicked so both Finish and SkipDialogAnimation dispatch on Main, eliminating the race where DROP_OLDEST could discard Finish if a background tap arrived while the IO-dispatched coroutine was still running. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>


Task/Issue URL: https://app.asana.com/1/137249556945/project/488551667048375/task/1212699261164265?focus=true
Description
Implements the AI chat toggle (input screen) for the onboarding brand design update and adds left wing animation support. This is the third dialog step in the redesigned onboarding flow, allowing users to choose between AI-enhanced search or search-only mode.
Key changes:
BrandDesignUpdatePageViewModelTestSteps to test this PR
Designs
Apply patch
AI chat toggle screen
Left wing animation
Tap-to-skip dialog animations
Bobbing Dax exit
Pixel testing
Setup
./gradlew installInternalDebug)Pixelto observe pixel fire eventsNew user flow - dialog shown pixels
m_preonboarding_intro_shown_uniquefires in logcatm_preonboarding_comparison_chart_shown_uniquefiresNew user flow - default browser pixels
m_preonboarding_choose_browser_pressedfires withdefaultBrowserparameterm_db_sfires withfo=truem_db_nsfires withfo=trueNew user flow - address bar position pixels
m_preonboarding_address_bar_position_dialog_shown_uniquefires when address bar screen appearsm_preonboarding_bottom_address_bar_selected_uniquefiresm_preonboarding_split_address_bar_selected_uniquefiresNew user flow - input screen pixels (if feature enabled)
m_preonboarding_choose_search_experience_impressions_uniquefires when input screen appearsm_preonboarding_aichat_selectedfiresm_preonboarding_search_only_selectedfiresReinstall user flow
m_preonboarding_intro_reinstall_user_shown_uniquefiresm_preonboarding_skip-onboarding-pressedfiresm_preonboarding_skip_onboarding_shown_uniquefires when skip confirmation appearsm_preonboarding_confirm-skip-onboarding-pressedfiresm_preonboarding_resume-onboarding-pressedfiresNotification permission pixels
m_notification_runtime_permission_shownfires when notification permission dialog is shownmnot_efires withfromOnboarding=trueUI changes
See here for demoes
Note
Medium Risk
Touches core onboarding flow and adds new animation/interaction paths (including touch interception), which could affect navigation, state restore, and visual correctness across devices/orientations.
Overview
Adds a new Input Screen step to the brand design update onboarding flow, letting users choose between search-only and AI-enhanced input with animated crossfade toggles and persisted selection.
Updates onboarding visuals and motion: introduces a new
OnboardingBackgroundStep.InputType, adds a left-wing Lottie decoration, animates bobbing Dax out when transitioning to the new step, and adds tap-to-skip support that snaps typing/fade/checkmark animations to their end state.Extends onboarding theming/resources to support the new UI (new alpha colors and onboarding attrs), refactors omnibar option images to crossfade via front/back
ImageViews, and adds tests for missing default-browser pixel cases and the new skip-animation command.Reviewed by Cursor Bugbot for commit 58bfeb9. Bugbot is set up for automated code reviews on this repo. Configure here.