Skip to content

Onboarding Brand Design Update: Fix in-context dialog click handling#8341

Open
mikescamell wants to merge 5 commits intodevelopfrom
feature/mike/onboarding-brand-design-updates/better-incontext-click-handling
Open

Onboarding Brand Design Update: Fix in-context dialog click handling#8341
mikescamell wants to merge 5 commits intodevelopfrom
feature/mike/onboarding-brand-design-updates/better-incontext-click-handling

Conversation

@mikescamell
Copy link
Copy Markdown
Contributor

@mikescamell mikescamell commented Apr 23, 2026

Task/Issue URL: https://app.asana.com/1/137249556945/task/1214123398861719

Description

Fixes several touch and click handling issues in the brand design update onboarding dialogs that occurred during or immediately after animations.

  • Replaced the LinearLayout card container with TouchInterceptingLinearLayout so the layout can block child touch events while an animation is running — prevents accidental button taps mid-transition.
  • Intercept child touches during in-context CTA dialog animations to stop buttons being pressed before the new card has finished animating in.
  • Title now fades out alongside the description and content during in-context CTA transitions instead of staying visible independently.
  • Cancel any in-progress fade-out animation when tap-to-skip is detected, preventing the Dax typing animation from restarting in a loop.

Steps to test this PR

In-context click handling

  • Enable brandDesignUpdate and self toggles; go through onboarding to a card with in-context CTAs (e.g. visit-site-options or end-CTA).
  • Tap a CTA button immediately as the card is animating in — verify no action fires during the transition.
  • On a card with typing animation, tap to skip mid-way through, then tap again immediately — verify the typing does not restart in a loop.
  • Trigger an in-context CTA transition and confirm the title fades out cleanly with the rest of the card contents.

UI changes

Before After
!(Upload before screenshot) (Upload after screenshot)

Note

Medium Risk
Touches core onboarding CTA animation/click handling; regressions could block CTA buttons or cause dialogs to get stuck if animation state is mishandled, but there are no security or data risks.

Overview
Improves the Brand Design Update onboarding CTA dialog animation flow to prevent user interactions from firing while the card is transitioning/typing.

Replaces the dialog card container with TouchInterceptingLinearLayout and toggles child-touch interception via a new shared isAnimating state, ensuring taps during animations only trigger the tap-to-skip behavior.

Refines transition logic by fading out the title with other content, adding an applySettledState snap path, and cancelling any in-progress fade-out animator on tap-to-skip to avoid re-triggering typing/animation loops.

Reviewed by Cursor Bugbot for commit 3138ceb. Bugbot is set up for automated code reviews on this repo. Configure here.

@mikescamell mikescamell changed the title refactor(onboarding): swap card container to TouchInterceptingLinearLayout Onboarding Brand Design Update: Fix in-context dialog click handling Apr 23, 2026
@mikescamell mikescamell marked this pull request as ready for review April 23, 2026 16:35
Comment thread app/src/main/java/com/duckduckgo/app/cta/ui/Cta.kt Outdated
@mikescamell mikescamell changed the base branch from feature/mike/onboarding-brand-design-updates/subscription to graphite-base/8341 April 27, 2026 16:34
mikescamell and others added 4 commits April 28, 2026 09:36
…ayout

Prepares the brand-design-update in-context dialog to intercept child
touches during intro/transition animations so that tap-to-skip cannot
leak through to option/primary/secondary buttons or to stale listeners
on reused views.
…mation

Taps on the brand-design-update in-context CTA during its intro/transition
animation previously reached option/primary/secondary buttons, including
stale listeners on option views reused from the previous CTA. The
cardContainer is now a TouchInterceptingLinearLayout and intercepts
child touches while animating; taps route to snapToFinished() as
intended. Intercepting is cleared both on natural animation end and on
tap-to-skip, so the fully settled card is fully interactive again.

Asana: https://app.asana.com/1/137249556945/task/1214123398861719
…ransitions

The in-context CTA→CTA transition previously animated only the description
and visible includes to alpha 0, leaving the previous CTA's title at full
alpha until typing re-started. Users saw the old title held in place while
the rest of the card faded out, then snap to blank and re-type the new text.

titleView is now part of the fade-out AnimatorSet so it fades alongside the
rest of the content, and the title is explicitly blanked at fade-out end so
the next typing pass starts from a clean slate instead of flashing the stale
text for a frame.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…loop

The content-transition fade-out AnimatorSet was fire-and-forget, so a
tap-to-skip during fade-out couldn't cancel it. snapToFinished set
animationsSettled=true and cleared interceptChildTouches, but the
uncancelled fade-out's onAnimationEnd then unconditionally ran
typeAndFadeIn() — starting a fresh typing animation that had no intercept
protection. Users reported needing multiple taps to skip and seeing the
new title flash in full before re-typing.

The fade-out AnimatorSet is now hoisted to a closure var and cancelled by
snapToFinished. Its onAnimationEnd branches on animationsSettled: if a
tap-to-skip fired, the branch invokes a new applySettledState helper that
snaps content to final state; otherwise it runs typeAndFadeIn as before.
AnimatorSet.cancel() dispatches onAnimationEnd synchronously, so setting
animationsSettled=true before the cancel is load-bearing — a comment
records the ordering invariant.

A second comment at the top of showCta records the broader invariant that
only one showCta is active at a time; overlapping invocations would let
stale closure callbacks clobber shared view state.

Asana: https://app.asana.com/1/137249556945/task/1214123398861719

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/better-incontext-click-handling branch from 3309142 to 17407a4 Compare April 28, 2026 08:40
@mikescamell mikescamell changed the base branch from graphite-base/8341 to develop April 28, 2026 08:41
…tter

Mirrors the pattern in BrandDesignUpdateWelcomePage so toggling the
animating flag automatically updates cardContainer.interceptChildTouches.
Prevents future drift between the two values.
Copy link
Copy Markdown
Contributor

@LukasPaczos LukasPaczos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Comment on lines +881 to +882
// Assumes one active showCta at a time — the intercept flag gates user advances until settled.
// Overlapping calls would let stale closure callbacks clobber shared view state.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems misplaced now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants