Skip to content

Onboarding Brand Design Update: Dismiss intro bubble on submit#8526

Draft
mikescamell wants to merge 2 commits into
onboarding-design-update-copy-changesfrom
feature/mike/onboarding-brand-design-updates/align-with-new-input-from-oj
Draft

Onboarding Brand Design Update: Dismiss intro bubble on submit#8526
mikescamell wants to merge 2 commits into
onboarding-design-update-copy-changesfrom
feature/mike/onboarding-brand-design-updates/align-with-new-input-from-oj

Conversation

@mikescamell
Copy link
Copy Markdown
Contributor

@mikescamell mikescamell commented May 12, 2026

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

Description

Hides the onboarding intro options bubble ("Try a Search" / "Visit Site") when a user submits a query while native input is enabled. Previously the bubble persisted in ctaViewState and briefly flashed when navigating back to the NTP via the native-input back gesture. Gated on the native-input user setting since the flash only surfaces while native input is overlaying the NTP.

Steps to test this PR

Applying the patch emulates the future state where the new nativeInput is enabled by default after running onboarding. This should be released before onboarding update is completed.

To turn this off for testing flag off state, remove changes to DuckChatDataStore

Index: duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/store/DuckChatDataStore.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/store/DuckChatDataStore.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/store/DuckChatDataStore.kt
--- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/store/DuckChatDataStore.kt	(revision 0120753cfc874900c092861cd767a423c06b88d4)
+++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/store/DuckChatDataStore.kt	(date 1778573552758)
@@ -253,9 +253,9 @@
 
     private val nativeInputFieldUserSettingEnabled: StateFlow<Boolean> =
         store.data
-            .map { prefs -> prefs[DUCK_AI_NATIVE_INPUT_FIELD_SETTING] ?: false }
+            .map { prefs -> prefs[DUCK_AI_NATIVE_INPUT_FIELD_SETTING] ?: true }
             .distinctUntilChanged()
-            .stateIn(appCoroutineScope, SharingStarted.Eagerly, false)
+            .stateIn(appCoroutineScope, SharingStarted.Eagerly, true)
 
     private val duckChatShowInBrowserMenu: StateFlow<Boolean> =
         store.data
@@ -454,7 +454,7 @@
         store.data.firstOrNull()?.let { it[DUCK_AI_AUTOMATIC_CONTEXT_ATTACHMENT] } ?: false
 
     override suspend fun isNativeInputFieldUserSettingEnabled() =
-        store.data.firstOrNull()?.let { it[DUCK_AI_NATIVE_INPUT_FIELD_SETTING] } ?: false
+        store.data.firstOrNull()?.let { it[DUCK_AI_NATIVE_INPUT_FIELD_SETTING] } ?: true
 
     override suspend fun setChatSuggestionsUserSetting(enabled: Boolean) {
         store.edit { prefs -> prefs[DUCK_AI_CHAT_SUGGESTIONS_USER_SETTING] = enabled }
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 0120753cfc874900c092861cd767a423c06b88d4)
+++ b/app/src/main/java/com/duckduckgo/app/onboardingbranddesignupdate/OnboardingBrandDesignUpdateToggles.kt	(date 1778573552750)
@@ -34,14 +34,14 @@
      * 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
 
     /**
@@ -49,6 +49,6 @@
      * Data Clearing settings + bottom-sheet Lottie swap). Default FALSE; flip
      * ON to enable the new fire animation surfaces.
      */
-    @Toggle.DefaultValue(DefaultFeatureValue.FALSE)
+    @Toggle.DefaultValue(DefaultFeatureValue.TRUE)
     fun fireAnimationUpdate(): 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 0120753cfc874900c092861cd767a423c06b88d4)
+++ b/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt	(date 1778573552744)
@@ -45,7 +45,7 @@
     val viewState = _viewState.asStateFlow()
 
     fun initializePages() {
-        pageLayoutManager.buildPageBlueprints()
+        pageLayoutManager.buildBrandDesignUpdatePageBlueprints()
     }
 
     fun pageCount(): Int {
@@ -70,7 +70,7 @@
     }
 
     fun initializeOnboardingSkipper() {
-        if (!appBuildConfig.canSkipOnboarding) return
+        return
 
         // delay showing skip button until privacy config downloaded
         viewModelScope.launch {

Bubble flash on option tap

  • Fresh install (patch applied), walk through onboarding until the "Try a Search" bubble appears on the NTP
  • Tap a suggested search option; wait for the SERP to load
  • Navigate back to the NTP using the native-input back gesture
  • Confirm the bubble does NOT flash on return to the NTP
  • Repeat for the "Visit Site" bubble (suggested-site options)

Bubble flash on custom typed query

  • When either bubble is visible, type a custom query into the omnibar (instead of tapping a suggestion) and submit
  • Confirm the bubble is dismissed and does not flash on return to the NTP

Regression — native input OFF

  • Remove changes to DuckChatDataStore
  • Fresh install / clear data, run through onboarding to the same bubbles
  • Submit a query (option tap or custom)
  • Confirm behaviour matches develop (bubble lifecycle unchanged — this path goes through InputScreenActivity, no flash to fix)

UI changes

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

Note

Low Risk
Low risk: scoped to onboarding CTA UI state cleanup and a new one-off command, gated behind the native-input user setting and covered by unit tests.

Overview
Fixes an onboarding UI glitch where the intro Dax bubble could persist and briefly flash after navigation by dismissing the bubble on query submit when the native-input setting is enabled.

Adds a new HideDaxBubbleCtaOnSubmit command, wires it through BrowserTabViewModel (clearing ctaViewState for the relevant intro/search/visit-site bubbles) and handles it in BrowserTabFragment, with unit tests covering enabled vs disabled behavior.

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

@mikescamell mikescamell changed the title feat(onboarding): wire DataClearing + FireButton settings to fire-animation flag Onboarding Brand Design Update: Dismiss intro bubble on submit May 12, 2026
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 1 potential issue.

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 0120753. Configure here.

private var isCustomTabScreen: Boolean = false
private var alreadyShownKeyboard: Boolean = false
private var pendingDuckChatAuthUpdate: Boolean = false
private var nativeInputFieldEnabled: Boolean = false
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.

Missing @volatile on cross-thread boolean field

Medium Severity

nativeInputFieldEnabled is written on the IO thread (the onEach lambda is upstream of flowOn(dispatchers.io())) but read on the Main thread in dismissDaxBubbleCtaOnSubmit. Without @Volatile, the JVM memory model does not guarantee the Main thread sees the updated value. The analogous field isSerpLogoInMenuEnabled declared just two lines below correctly uses @Volatile for the same cross-thread write/read pattern. The consequence is that dismissDaxBubbleCtaOnSubmit may intermittently read a stale false and skip dismissing the bubble CTA.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0120753. Configure here.

@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/align-with-new-input-from-oj branch from 0120753 to f38fe2f Compare May 12, 2026 16:44
@mikescamell mikescamell force-pushed the onboarding-design-update-copy-changes branch from c74e5de to 6387c02 Compare May 12, 2026 17:14
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/align-with-new-input-from-oj branch from f38fe2f to 0004eae Compare May 12, 2026 17:14
…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.
…nput enabled

The bubble persisted in ctaViewState after a Try-a-Search / Visit-Site
submission and briefly flashed when returning to the NTP via
native-input back, because its parent is a sibling of newTabRootLayout
and neither hideNewTab() nor NativeInputManager.showNtp() touches it.
Gated on the user setting since the flash only surfaces when native
input is overlaying the NTP.
@mikescamell mikescamell force-pushed the onboarding-design-update-copy-changes branch from 6387c02 to d55233b Compare May 12, 2026 17:38
@mikescamell mikescamell force-pushed the feature/mike/onboarding-brand-design-updates/align-with-new-input-from-oj branch from 0004eae to d041daa 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