Skip to content

fix an issue where Dax persists in the NTP onboarding bubble after rotating to landscape#8653

Draft
LukasPaczos wants to merge 13 commits into
developfrom
fix/lpaczos/onboading-brand-design-updates/drop-dax-when-rotated-to-landscape
Draft

fix an issue where Dax persists in the NTP onboarding bubble after rotating to landscape#8653
LukasPaczos wants to merge 13 commits into
developfrom
fix/lpaczos/onboading-brand-design-updates/drop-dax-when-rotated-to-landscape

Conversation

@LukasPaczos
Copy link
Copy Markdown
Contributor

Task/Issue URL: https://app.asana.com/1/137249556945/project/1208671518894266/task/1215002210542681?focus=true

Description

Refreshes the layout of the NTP onboarding bubble to remove Dax and bubble arrow after rotation from portrait to landscape.

Steps to test this PR

See the videos below.

UI changes

before

Screen_recording_20260521_111515.mp4

after

Screen_recording_20260521_150425.mp4

mikescamell and others added 13 commits May 20, 2026 17:51
Adds the infrastructure to animate the speech-bubble tail's depth on the
brand-design bubble card. The tail rendered by DaxBubbleBottomEdgeTreatment
is now scaled by a depthFraction property (0 = flat, 1 = full tail). The
fraction is proxied through AnimatableOffsetEdgeTreatment and exposed on
DaxOnboardingBubbleBrandDesignUpdateCardView via setArrowDepthFraction /
arrowDepthFraction. Includes unit tests.

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

The bubble card now reserves tail space permanently (showArrow=true in XML,
controlled at runtime by arrowDepthFraction) and each brand-design bubble
CTA declares whether it wants the tail visible. On show or content
transition, the depth animates from the current value toward the new CTA's
target (1 if showArrow, 0 otherwise) in sync with the content fade-in.

Also includes:
- First-show flash fix: read live depth at animator-build site so the
  synchronous reset before content fade-in is honoured.
- Layout: keep the bubble card top-anchored on the welcome page rather
  than centring it.
- Align bubble arrow offset with the welcome card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- In-context contextual dialog: enable the bubble tail
  (showArrow=true, arrowOffsetStart=80dp) and animate its depth across
  CTA transitions, mirroring the bubble flow. Per-CTA showArrow flag
  declared on BrandDesignContextualDaxDialogCta; only the site-
  suggestions CTA opts in to depth=1.
- Add a waving Dax Lottie animation to both the bubble and in-context
  layouts, shown when the user lands on the visit-site CTA.
- For the bubble end-of-onboarding dialog reached from the visit-site
  CTA, persist both the tail and the Dax across the transition:
  showArrow is declared per-CTA via the abstract base, and CTAs that
  render the waving Dax opt in via the ShowsWavingDax marker interface
  rather than via an inherited flag. The dax-state apply path skips
  Lottie restarts when the view is already visible.
- Align the bubble's arrowOffsetStart to 80dp so both dialogs use the
  same tail position.
…ntextual CTAs

Adds the bottom-wing Lottie + speech-bubble tail to the trackers-blocked and
no-trackers in-context CTAs per Figma. CTAs that render the wing opt in via
the ShowsWingBottom marker interface instead of through an inherited base-
class flag. The wing plays in (0 -> 0.5) after the banner slides in, persists
at the resting frame across same-wing content transitions, and plays out
(0.5 -> 1.0) when the next CTA doesn't carry a wing. snapWingBottomToResting
handles tap-to-skip / rotation by jumping to the resting frame instead of
leaving the view mid-animation.

The 300 ms play-in delay is gated by a shared generation counter — any
applyWingBottomState or cancelRunningAnimations bumps it, so a runnable
posted by one CTA bails if a subsequent CTA stages or cancels the wing
before the timer fires. The fragment swaps contextual CTAs without calling
hideOnboardingCta on the previous instance, so a per-instance reference
couldn't reach the pending runnable posted on the shared wingBottom view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a rotated Dax to the brand-design subscription onboarding bubble per
Figma 16516:44053. The subscription CTA opts into the waving Dax via the
ShowsWavingDax marker interface and supplies its bottom-left, leaning
orientation by overriding configureWavingDax, while other CTAs inherit
the default orientation. The subscription bubble also enables the
speech-bubble tail (showArrow=true) to match the design.

Position lives on the interface (not configureContentViews) so the show
flow can reset transforms on the shared wavingDax view every time it
plays — otherwise subscription's rotation/translation persists on the
view instance and bleeds into earlier CTAs after an onboarding reset.
Subscription's centered title/description gravity is reset for the same
reason via resetTextAlignment in the dialog show flow.

Because the Dax position differs from the previous CTA's, the
subscription CTA also overrides restartWavingDax=true. A content
transition landing on a restart-Dax CTA fades the existing Dax out
alongside the dialog content, then re-plays it from frame 0 at the new
orientation — without that, the Dax would jump-cut between positions.
CTAs that share an orientation (visit-site → end) still persist the Dax
with no replay.

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

Hide wavingDax + wingBottom Lottie views and force arrowDepthFraction=0
on brand-design onboarding CTAs in phone landscape (smallestScreenWidthDp
< 600 AND ORIENTATION_LANDSCAPE). Tablet landscape and phone portrait
render unchanged.

Single internal View.isPhoneLandscape() extension in Cta.kt, consulted
at three gating points: applyWavingDaxState (bubble), the wingBottom
entry points (contextual), and the arrow-depth derivation in both
BrandDesignContextualDaxDialogCta and BrandDesignUpdateBubbleCta.
Subscription's configureWavingDax override is bypassed cleanly via the
gate sitting before the call.

Also null-safe the wavingDax findViewById in DaxSiteSuggestions's
configureContentViews — the layout-land variant of the in-context
dialog omits the view, so the existing non-null .apply NPE'd on phone
landscape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On tablet (smallestScreenWidthDp >= 600), wavingDax (bubble) and
wingBottom (in-context portrait) anchor startToStart to their respective
dialog card view instead of parent, so the animations track the centred
/ max-width-capped card rather than the screen edge. Phone behaviour
unchanged.

Subscription bubble keeps its "lean in from device edge" treatment on
every form factor — its configureWavingDax override explicitly resets
startToStart to PARENT_ID to neutralise the shared-view leak from prior
non-subscription shows.

The in-context site-suggestions CTA (the only contextual CTA that shows
wavingDax) applies the same anchor flip inline in configureContentViews,
plus a tablet-only translationX adjustment so the Dax's head aligns with
the card's bottom-left corner rather than sitting inside it.

Tablet landscape in-context dialog is unchanged — the existing
layout-land/ variant omits both wavingDax and wingBottom; this commit
does not introduce them.

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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…factor

Removes restate-the-code comments and marker-interface KDocs from the
waving Dax + wing animation additions. Keeps comments that explain real
gotchas (Lottie isShown gate, stale-snapshot timing, intentional empty
branches, Mockito workaround).

Routes form-factor detection through the DeviceInfo abstraction. The
two abstract CTA base classes (BrandDesignContextualDaxDialogCta,
BrandDesignUpdateBubbleCta) now take a DeviceInfo and expose member
extensions for isTablet() / isPhoneLandscape(); CtaViewModel injects
DeviceInfo and threads it through every brand-design CTA construction.
Replaces the bespoke View.isTablet() / View.isPhoneLandscape()
extensions that read smallestScreenWidthDp directly.

Adds a regression test that verifies a pending wing play-in posted by
one CTA bails when a subsequent CTA stages the wing before the timer
fires, and relaxes startWingBottomPlayIn from private to internal so
the test can drive it directly (matches applyWingBottomState's
visibility).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@LukasPaczos LukasPaczos changed the title fix an issue where Dax persist in the NTP onboarding bubble after rotating to landscape fix an issue where Dax persists in the NTP onboarding bubble after rotating to landscape May 21, 2026
Base automatically changed from feature/mike/onboading-brand-design-updates/in-context-dax-animations to develop May 21, 2026 16:07
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