Skip to content

Onboarding Brand Design Update: Add in-context Fire Button dialog + Inferno fire animation#8482

Draft
mikescamell wants to merge 8 commits into
feature/mike/onboarding-brand-design-updates/contextual-no-trackersfrom
feature/mike/onboarding-brand-design-updates/contextual-fire-button
Draft

Onboarding Brand Design Update: Add in-context Fire Button dialog + Inferno fire animation#8482
mikescamell wants to merge 8 commits into
feature/mike/onboarding-brand-design-updates/contextual-no-trackersfrom
feature/mike/onboarding-brand-design-updates/contextual-fire-button

Conversation

@mikescamell
Copy link
Copy Markdown
Contributor

@mikescamell mikescamell commented May 7, 2026

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

Description

Migrates the Fire Button contextual onboarding dialog to the new brand-design layout introduced in #8439, gated behind the onboardingBrandDesignUpdate feature flag — and ships the new Inferno fire animation behind its own kill-switch.

⚠️ Bigger scope than the other contextual migration PRs in this stack. Beyond the brand-design CTA migration, this PR introduces a brand-new fire animation asset, a dedicated kill-switch toggle, and a single-flag rollout/rollback path through SettingsSharedPreferences. Reviewers — please don't skim past it.

Brand-design Fire Button CTA (with onboardingBrandDesignUpdate on):

New Inferno fire animation (independent kill-switch):

  • Adds the new Inferno fire Lottie asset, enum entry, pixel value, and Classic display string.
  • Adds a dedicated fireAnimationUpdate kill-switch toggle so we can roll the animation forward / back without touching the brand-design toggle.
  • Single-flag rollout/rollback migration in SettingsSharedPreferences — old fire-animation pref values are mapped onto the new enum and back, so flipping the kill-switch off doesn't strand users on a value they can no longer render.
  • DataClearing settings + FireButton screens now resolve their fire animation through the new flag, so internal-build changes preview correctly in both surfaces.
  • Registers the corresponding fire-animation pixels in PixelDefinitions.

Tests: new coverage exercises the fire-animation migration, the new pixel, and ViewState resolution across DataClearing, FireButton, and the brand-design CTA path.

Out of scope (still legacy / stub-only with the flag on, queued in the follow-up PR in this stack): end. Its Dax*BrandDesignUpdateContextualCta class remains as scaffolding.

Steps to test this PR

Designs

Please run all testing steps for in-context dialog changes from the contextual-end branch/PR to ease the testing burden.

Additionally for the fire-animation work, please verify:

  • Fresh install with fireAnimationUpdate ON → DataClearing settings + FireButton screen + onboarding fire CTA all show the new Inferno animation.
  • Toggle fireAnimationUpdate OFF on a build that was previously ON (and had the new animation selected) → the animation falls back cleanly to a legacy value, no crash, no blank lottie.
  • Pixel sanity check on the new fire-animation pixel.

To see these changes patch (Linear onboarding flag included just for continuity)

Index: app/src/main/java/com/duckduckgo/app/onboardingbranddesignupdate/OnboardingBrandDesignUpdateToggles.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/main/java/com/duckduckgo/app/onboardingbranddesignupdate/OnboardingBrandDesignUpdateToggles.kt b/app/src/main/java/com/duckduckgo/app/onboardingbranddesignupdate/OnboardingBrandDesignUpdateToggles.kt
--- a/app/src/main/java/com/duckduckgo/app/onboardingbranddesignupdate/OnboardingBrandDesignUpdateToggles.kt	(revision 6fd565c8894daba16281ae9bcf3452d038ae8d6d)
+++ b/app/src/main/java/com/duckduckgo/app/onboardingbranddesignupdate/OnboardingBrandDesignUpdateToggles.kt	(date 1777967047929)
@@ -34,13 +34,13 @@
      * Main toggle for the onboarding brand design update feature.
      * Default value: false (disabled).
      */
-    @Toggle.DefaultValue(DefaultFeatureValue.FALSE)
+    @Toggle.DefaultValue(DefaultFeatureValue.TRUE)
     fun self(): Toggle
 
     /**
      * Toggle for the brand design update variant.
      * Default value: false (disabled).
      */
-    @Toggle.DefaultValue(DefaultFeatureValue.FALSE)
+    @Toggle.DefaultValue(DefaultFeatureValue.TRUE)
     fun brandDesignUpdate(): Toggle
 }
Index: app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt b/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt
--- a/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt	(revision 6fd565c8894daba16281ae9bcf3452d038ae8d6d)
+++ b/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt	(date 1777657893440)
@@ -45,7 +45,7 @@
     val viewState = _viewState.asStateFlow()
 
     fun initializePages() {
-        pageLayoutManager.buildPageBlueprints()
+        pageLayoutManager.buildBrandDesignUpdatePageBlueprints()
     }
 
     fun pageCount(): Int {
@@ -69,8 +69,8 @@
         }
     }
 
-    fun initializeOnboardingSkipper() {
-        if (!appBuildConfig.canSkipOnboarding) return
+    fun initializeOnboardingSkipper() { 
+        return
 
         // delay showing skip button until privacy config downloaded
         viewModelScope.launch {

UI changes


Note

Medium Risk
Introduces a new fire-animation option and kill-switch that changes default selection, persistence, and UI/pixel behavior across multiple settings and dialog surfaces; rollout/rollback logic in SettingsSharedPreferences could affect saved user state if mis-mapped.

Overview
Adds the brand-design variant of the Fire Button contextual onboarding dialog by switching getFireDialogCta to return DaxFireButtonBrandDesignUpdateContextualCta when the brand-design flag is enabled, including real content wiring (background, include id, primary click listener) and a new regression test.

Introduces a new Inferno fire animation behind a dedicated fireAnimationUpdate kill-switch: adds the new Lottie asset, new FireAnimation.Inferno enum/pixel value, relabels legacy HeroFire as Inferno Classic when enabled, and updates Fire Button + Data Clearing settings UIs to use a new selector and label logic gated by the toggle.

Updates persistence and telemetry for the rollout: SettingsSharedPreferences now defaults to Inferno when the toggle is on and masks saved Inferno back to HeroFire when off (plus new migration tests), SingleTabFireDialog swaps Lottie resources based on the toggle, PixelDefinitions adds m_fas_o/m_fas_s/m_fd_a, and pixel parameter ATB removal lists are expanded accordingly.

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

Comment thread PixelDefinitions/pixels/definitions/fire_animation.json5
Comment thread app/src/main/java/com/duckduckgo/app/firebutton/DataClearingSettingsViewModel.kt Outdated
@mikescamell mikescamell changed the base branch from feature/mike/onboarding-brand-design-updates/contextual-no-trackers to graphite-base/8482 May 7, 2026 14:57
@mikescamell mikescamell force-pushed the graphite-base/8482 branch from fd3becf to 8856449 Compare May 7, 2026 14:57
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from 7da49a0 to 0c5e838 Compare May 7, 2026 14:57
@mikescamell mikescamell changed the base branch from graphite-base/8482 to feature/mike/onboarding-brand-design-updates/contextual-no-trackers May 7, 2026 14:57
Comment thread app/src/main/java/com/duckduckgo/app/firebutton/FireButtonViewModel.kt Outdated
Comment thread app/src/main/java/com/duckduckgo/app/firebutton/FireButtonActivity.kt Outdated
@mikescamell mikescamell changed the base branch from feature/mike/onboarding-brand-design-updates/contextual-no-trackers to graphite-base/8482 May 7, 2026 17:14
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from 0c5e838 to b3ba3e8 Compare May 7, 2026 17:15
@mikescamell mikescamell force-pushed the graphite-base/8482 branch from 8856449 to 2be56dc Compare May 7, 2026 17:15
@mikescamell mikescamell changed the base branch from graphite-base/8482 to feature/mike/onboarding-brand-design-updates/contextual-no-trackers May 7, 2026 17:15
@mikescamell mikescamell changed the base branch from feature/mike/onboarding-brand-design-updates/contextual-no-trackers to graphite-base/8482 May 7, 2026 17:40
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from b3ba3e8 to 1a7b945 Compare May 7, 2026 17:41
@mikescamell mikescamell force-pushed the graphite-base/8482 branch from 2be56dc to 6ddfea5 Compare May 7, 2026 17:41
@mikescamell mikescamell changed the base branch from graphite-base/8482 to feature/mike/onboarding-brand-design-updates/contextual-no-trackers May 7, 2026 17:41
Comment thread app/src/main/java/com/duckduckgo/app/global/view/SingleTabFireDialog.kt Outdated
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch 2 times, most recently from 85dc129 to 3ada1c8 Compare May 8, 2026 16:14
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-no-trackers branch from 6ddfea5 to 4216fc8 Compare May 8, 2026 16:14
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from 3ada1c8 to ffa9439 Compare May 8, 2026 16:24
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from ffa9439 to 32c671c Compare May 11, 2026 09:55
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-no-trackers branch from 4216fc8 to fba4c97 Compare May 11, 2026 11:42
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from 32c671c to 0513f60 Compare May 11, 2026 11:42
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 4 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ 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 0513f60. Configure here.

Comment thread app/src/main/java/com/duckduckgo/app/firebutton/DataClearingSettingsActivity.kt Outdated
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from 0513f60 to b19e377 Compare May 11, 2026 12:06
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-no-trackers branch from fba4c97 to 87c0686 Compare May 11, 2026 12:06
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch 2 times, most recently from a5cbb30 to 931d111 Compare May 12, 2026 08:23
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch 2 times, most recently from e20ae89 to 7f403a9 Compare May 12, 2026 17:14
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-no-trackers branch from 080f06d to 569bb3c Compare May 12, 2026 17:14
… dialog

Populate the Stage-1 stub, replace the CtaViewModel construction-site
sentinel and both BrowserTabViewModel launch-fire-dialog sentinels, and
add the per-dialog unit test.
8 WebP variants (4 densities × light/dark) at 90% quality.
Passes R.drawable.bg_onboarding_fire_button to the contextual base
class so the slide-in / slide-out banner animation lights up behind
the FireButton CTA. The asset itself ships in the preceding banner
commit; this is the one-line constructor wiring.
Independent kill-switch on OnboardingBrandDesignUpdateToggles so the
new Inferno animation can be rolled forward or back without touching
the wider brand-design CTA work.

Default off; gated by self() like every other sub-toggle in this
experiment, so flipping self() off disables Inferno alongside the rest
of the brand-design behaviour.
Adds R.raw.inferno (the new Lottie asset), FireAnimation.Inferno data
object, the INFERNO prefs value mapped through FireAnimationPrefsMapper,
the FIRE_ANIMATION_INFERNO_NEW pixel value, and the
settingsHeroFireAnimationClassic string used by the picker to relabel
the legacy HeroFire option as "Inferno Classic" when the flag is on.

availableFireAnimations(includesInferno) and
FireAnimation.displayLabelResId(includesInferno) are kept here next to
getPixelValue so the canonical option list and the flag-aware label
resolution all live with the model.

HeroFire's storage key, pixel value, and asset filename are
intentionally preserved — the rename is display-only — to keep the
blast radius small if the kill-switch flips off.

Registers fire_animation.json5 declaring m_fas_o, m_fas_s and m_fd_a so
the new INFERNO_NEW value — and the existing legacy values — flow
through the pixel triage validator. PixelParamRemovalInterceptor strips
atb for all three so they match the appVersion-only declaration;
without this the validator fails on first release because atb is
auto-attached to every pixel at runtime.

Per-CTA tests on Granular / NonGranular / SingleTab fire-dialog
ViewModels verify the m_fd_a pixel fires with FIRE_ANIMATION_INFERNO_NEW
when Inferno is the selected animation.
Fresh installs (no saved value) resolve to FireAnimation.Inferno when
fireAnimationUpdate is enabled, and to FireAnimation.HeroFire otherwise.

When the flag is off, a saved "INFERNO" selection is masked back to
HeroFire at the runtime getter so the kill switch fully rolls back the
new animation across playback, the delete-flow pixel, and the picker.
The saved preference string is preserved untouched, so flipping the
flag back on restores the user's Inferno selection without data loss.

Reads the flag via Lazy<OnboardingBrandDesignUpdateToggles> to break
the SettingsSharedPreferences ↔ toggle DI cycle.

SettingsSharedPreferencesFireAnimationMigrationTest covers the default
fallback (null prefs ± flag) and the saved-INFERNO + flag-off masking
(stored string preserved, getter returns HeroFire).
…mation flag

Both screens read fireAnimationUpdate from OnboardingBrandDesignUpdate
toggles on Dispatchers.IO and expose isFireAnimationUpdateEnabled in
their ViewState.

Activities consult the shared availableFireAnimations() helper and the
FireAnimation.displayLabelResId extension when building the picker, so
the option list (with or without Inferno) and the "Inferno Classic"
relabel for legacy HeroFire both stay in one place — no list
propagation through Command, no duplicate companion constants.

DataClearingSettingsViewModelTest and FireButtonViewModelTest verify
isFireAnimationUpdateEnabled is wired through ViewState from the toggle
and that LaunchFireAnimationSettings carries the flag.
…oggle

When fireAnimationUpdate is on, SingleTabFireDialog plays
fire_dialog_animation_brand_design.lottie instead of the legacy
fire_dialog_animation.json for the dialog header icon. Off, it stays
legacy.

self() is intentionally not part of this gate — the new fire-animation
surfaces ship/roll back independently of the wider brand-design
experiment.

The ViewModel resolves fireAnimationUpdate on Dispatchers.IO and
exposes isFireAnimationUpdateEnabled through ViewState; the fragment
maps that boolean to the raw resource at render time.

XML keeps lottie_rawRes pointing at the legacy raw so the still frame
is visible during the IO-bound state resolution, but lottie_autoPlay
is false — render() owns playback. Without this the legacy animation
auto-played on inflate and was then restarted with the brand-design
animation after IO completed, producing a visible flash on the
brand-design path.
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-no-trackers branch from 569bb3c to d6c77f4 Compare May 12, 2026 17:38
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/contextual-fire-button branch from 7f403a9 to 33bacde Compare May 12, 2026 17:38
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.

1 participant