Skip to content

Commit c571fbb

Browse files
authored
Custom Duck.ai Onboarding - comparison chart (#8688)
Task/Issue URL: https://app.asana.com/1/137249556945/project/1208671518894266/task/1214496769534853?focus=true ### Description - Refactors `COMPARISON_CHART` into a data-driven layout: one row template + a `ComparisonChartConfig` data class consumed by the page. Behavior unchanged. - Adds `AI_COMPARISON_CHART` enum value + `Ai` config (4 rows, "Popular AIs" header label, "Give Duck.ai a try!" CTA, title "AI protections activated!"). No navigation trigger yet — reachable only by hardcoding `currentDialog` locally. - Increases size of comparison table column icons to match the spec. ### Steps to test this PR - [x] Clean install the app. - [x] Click through to reach the browser comparison screen. - [x] Verify the content matches what's available on the mainline. - [x] Apply this patch: ```diff diff --git a/app/src/main/java/com/duckduckgo/app/onboarding/ui/page/BrandDesignUpdatePageViewModel.kt b/app/src/main/java/com/duckduckgo/app/onboarding/ui/page/BrandDesignUpdatePageViewModel.kt index 8fd6e77..de64c45aa3 100644 --- a/app/src/main/java/com/duckduckgo/app/onboarding/ui/page/BrandDesignUpdatePageViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/onboarding/ui/page/BrandDesignUpdatePageViewModel.kt @@ -275,7 +275,7 @@ class BrandDesignUpdatePageViewModel @Inject constructor( } INITIAL_REINSTALL_USER, INITIAL -> { - setCurrentDialog(COMPARISON_CHART) + setCurrentDialog(AI_COMPARISON_CHART) } COMPARISON_CHART -> { ``` - [x] Install the app. - [x] Click through to reach the AI comparison screen. - [x] Verify that green checks animate in with a delay. - [x] Rotate the screen and verify the content snaps into place. - [x] Re-open the app. - [x] Click through to reach the AI comparison screen. While the typing animation plays, click the card. - [x] Verify the content snaps into place.. - [x] Re-open the app. - [x] Click through to reach the AI comparison screen. While the typing animation plays, rotate the screen. - [x] Verify the content snaps into place. ### UI changes | Before (browser comp.) | After (browser comp.) | After (AI comp.) | ------ | ----- | ----- | <img width="960" height="2142" alt="old-browser-comp-light" src="https://github.com/user-attachments/assets/72d0c05e-8a31-4f18-be0f-706fcb063e9a" /><img width="960" height="2142" alt="old-browser-comp-dark" src="https://github.com/user-attachments/assets/d5583bf1-befd-40d2-a924-740985301ddb" />|<img width="960" height="2142" alt="new-browser-comp-light" src="https://github.com/user-attachments/assets/ae80a164-28a0-421a-9a36-da9de5ca64c5" /><img width="960" height="2142" alt="new-browser-comp-dark" src="https://github.com/user-attachments/assets/fe29e87b-f961-4a8a-8567-7ed33b05c651" />|<img width="960" height="2142" alt="new-ai-comp-light" src="https://github.com/user-attachments/assets/16533d16-a02c-46a3-9c43-3ad36e8fd55d" /><img width="960" height="2142" alt="new-ai-comp-dark" src="https://github.com/user-attachments/assets/f1106d36-bc51-4c5f-9514-2fbe31b43161" />| <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Onboarding UI and assets only; default path unchanged until AI dialog navigation is enabled. > > **Overview** > Refactors brand-design onboarding’s comparison chart into a **config-driven** screen: rows are inflated from `include_brand_design_comparison_chart_row`, with `ComparisonChartConfig.Default` preserving the existing browser-vs-DDG copy and behavior. > > Adds **`AI_COMPARISON_CHART`** and `ComparisonChartConfig.Ai` (AI-focused title, “Popular AIs” header label, four rows, “Give Duck.ai a try!” CTA) plus new rebrand drawables (`ic_ai_general_16`, `ic_ai_general_color_24_rebrand`, `ic_lock_color_24_rebrand`). The welcome page picks config from `currentDialog` and drives title, CTA, header icons, and check animations from dynamic row checks. > > **Not wired for production yet:** flow still advances to `COMPARISON_CHART` after intro; AI screen is only reachable via local `setCurrentDialog` hacks. Primary CTA and show pixels for the AI chart are TODOs. Legacy `WelcomePage` treats `AI_COMPARISON_CHART` as no-op. Duck.ai settings leading icon updated to `ic_ai_general_color_24`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 43d97bb. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent e75c026 commit c571fbb

14 files changed

Lines changed: 385 additions & 311 deletions
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<!--
2+
~ Copyright (C) 2026 The Android Open Source Project
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
17+
xmlns:aapt="http://schemas.android.com/aapt"
18+
android:width="18dp"
19+
android:height="18dp"
20+
android:viewportWidth="18"
21+
android:viewportHeight="18">
22+
<path
23+
android:pathData="M7.664,1.729C7.866,0.924 9.009,0.924 9.211,1.729L9.656,3.512C10.251,5.891 12.109,7.749 14.488,8.344L16.271,8.789C17.076,8.991 17.076,10.134 16.271,10.335L14.488,10.781L14.377,10.81C12.051,11.434 10.242,13.271 9.656,15.613L9.211,17.396L9.2,17.434C8.978,18.189 7.897,18.189 7.674,17.434L7.664,17.396L7.219,15.613C6.633,13.271 4.824,11.434 2.498,10.81L2.387,10.781L0.604,10.335C-0.201,10.134 -0.201,8.991 0.604,8.789L2.387,8.344C4.729,7.758 6.566,5.949 7.19,3.623L7.219,3.512L7.664,1.729ZM8.438,4.362C7.645,6.832 5.707,8.77 3.237,9.562C5.707,10.355 7.645,12.293 8.438,14.763C9.23,12.293 11.168,10.355 13.638,9.562C11.168,8.77 9.23,6.832 8.438,4.362ZM14.93,0.201C14.997,-0.067 15.378,-0.067 15.445,0.201L15.594,0.796C15.792,1.589 16.411,2.208 17.204,2.406L17.799,2.555C18.067,2.622 18.067,3.003 17.799,3.07L17.204,3.219L17.13,3.239C16.373,3.456 15.786,4.061 15.594,4.829L15.479,5.286L15.445,5.424L15.438,5.448C15.357,5.684 15.018,5.684 14.937,5.448L14.93,5.424L14.895,5.286L14.781,4.829C14.589,4.061 14.002,3.456 13.245,3.239L13.171,3.219L12.576,3.07C12.308,3.003 12.308,2.622 12.576,2.555L12.714,2.52L13.171,2.406C13.939,2.214 14.544,1.627 14.761,0.87L14.781,0.796L14.93,0.201Z"
24+
android:fillAlpha="0.84">
25+
<aapt:attr name="android:fillColor">
26+
<gradient
27+
android:startX="9"
28+
android:startY="0"
29+
android:endX="9"
30+
android:endY="18"
31+
android:type="linear">
32+
<item android:offset="0" android:color="#FFAC33DF"/>
33+
<item android:offset="1" android:color="#FF5881E5"/>
34+
</gradient>
35+
</aapt:attr>
36+
</path>
37+
</vector>

android-design-system/design-system/src/main/res/drawable/ai_general_color_24.xml renamed to android-design-system/design-system/src/main/res/drawable/ic_ai_general_color_24.xml

File renamed without changes.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!--
2+
~ Copyright (C) 2026 The Android Open Source Project
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
17+
android:width="24dp"
18+
android:height="24dp"
19+
android:viewportWidth="24"
20+
android:viewportHeight="24">
21+
<path
22+
android:pathData="M10.631,5.081C10.727,4.694 11.051,4.5 11.375,4.5C11.699,4.5 12.023,4.694 12.119,5.081L12.549,6.799C13.122,9.09 14.91,10.878 17.201,11.451L18.919,11.881C19.309,11.978 19.503,12.306 19.5,12.632C19.497,12.953 19.304,13.273 18.919,13.369L17.201,13.799C14.91,14.372 13.122,16.16 12.549,18.451L12.119,20.169C12.023,20.556 11.699,20.75 11.375,20.75C11.051,20.75 10.727,20.556 10.631,20.169L10.201,18.451C9.628,16.16 7.84,14.372 5.549,13.799L3.831,13.369C3.446,13.273 3.253,12.953 3.25,12.632C3.247,12.306 3.441,11.978 3.831,11.881L5.549,11.451C7.84,10.878 9.628,9.09 10.201,6.799L10.631,5.081Z"
23+
android:fillColor="#75B6EB"/>
24+
<path
25+
android:pathData="M11.529,3.256C12.252,3.312 12.989,3.761 13.277,4.594L13.332,4.778L13.762,6.495C14.223,8.338 15.662,9.777 17.505,10.238L19.222,10.668C20.244,10.924 20.757,11.816 20.75,12.642C20.743,13.458 20.229,14.33 19.222,14.582L17.505,15.012C15.662,15.472 14.223,16.912 13.762,18.755L13.332,20.472C13.078,21.486 12.196,22 11.375,22C10.554,22 9.672,21.486 9.418,20.472L8.988,18.755C8.528,16.912 7.088,15.472 5.245,15.012L3.528,14.582C2.521,14.33 2.007,13.458 2,12.642C1.993,11.816 2.506,10.924 3.528,10.668L5.245,10.238C7.088,9.777 8.528,8.338 8.988,6.495L9.418,4.778L9.473,4.594C9.782,3.701 10.605,3.25 11.375,3.25L11.529,3.256ZM11.375,4.5C11.051,4.5 10.728,4.694 10.631,5.081L10.201,6.799L10.144,7.012C9.516,9.2 7.768,10.896 5.549,11.451L3.831,11.881C3.441,11.979 3.247,12.306 3.25,12.632C3.253,12.953 3.447,13.273 3.831,13.369L5.549,13.799C7.84,14.372 9.628,16.16 10.201,18.451L10.631,20.169C10.716,20.508 10.974,20.699 11.254,20.741L11.375,20.75C11.658,20.75 11.942,20.602 12.073,20.305L12.119,20.169L12.549,18.451C13.104,16.232 14.8,14.484 16.988,13.856L17.201,13.799L18.919,13.369C19.256,13.285 19.446,13.03 19.49,12.752L19.5,12.632C19.502,12.347 19.354,12.06 19.056,11.928L18.919,11.881L17.201,11.451C14.982,10.896 13.234,9.2 12.606,7.012L12.549,6.799L12.119,5.081C12.022,4.694 11.699,4.5 11.375,4.5Z"
26+
android:fillColor="#045EB2"/>
27+
<path
28+
android:pathData="M18.62,2.199C18.686,1.934 19.064,1.934 19.13,2.199L19.435,3.417C19.576,3.982 20.018,4.424 20.583,4.565L21.801,4.87C22.066,4.936 22.066,5.314 21.801,5.38L20.583,5.685C20.018,5.826 19.576,6.268 19.435,6.833L19.13,8.051C19.064,8.316 18.686,8.316 18.62,8.051L18.315,6.833C18.174,6.268 17.732,5.826 17.167,5.685L15.949,5.38C15.684,5.314 15.684,4.936 15.949,4.87L17.167,4.565C17.732,4.424 18.174,3.982 18.315,3.417L18.62,2.199Z"
29+
android:fillColor="#045EB2"/>
30+
</vector>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!--
2+
~ Copyright (C) 2026 The Android Open Source Project
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
17+
android:width="24dp"
18+
android:height="24dp"
19+
android:viewportWidth="24"
20+
android:viewportHeight="24">
21+
<path
22+
android:pathData="M16.25,7.75C16.25,5.403 14.347,3.5 12,3.5C9.653,3.5 7.75,5.403 7.75,7.75V13.75C7.75,14.993 8.757,16 10,16H14C15.243,16 16.25,14.993 16.25,13.75V7.75ZM17.75,13.75C17.75,15.821 16.071,17.5 14,17.5H10C7.929,17.5 6.25,15.821 6.25,13.75V7.75C6.25,4.574 8.824,2 12,2C15.176,2 17.75,4.574 17.75,7.75V13.75Z"
23+
android:fillColor="#783B13"/>
24+
<path
25+
android:pathData="M4,12.75C4,11.093 5.343,9.75 7,9.75H17C18.657,9.75 20,11.093 20,12.75V18.75C20,20.407 18.657,21.75 17,21.75H7C5.343,21.75 4,20.407 4,18.75V12.75Z"
26+
android:fillColor="#FFC95C"/>
27+
<path
28+
android:pathData="M19.25,12.75C19.25,11.507 18.243,10.5 17,10.5H7C5.757,10.5 4.75,11.507 4.75,12.75V18.75C4.75,19.993 5.757,21 7,21H17C18.243,21 19.25,19.993 19.25,18.75V12.75ZM20.75,18.75C20.75,20.821 19.071,22.5 17,22.5H7C4.929,22.5 3.25,20.821 3.25,18.75V12.75C3.25,10.679 4.929,9 7,9H17C19.071,9 20.75,10.679 20.75,12.75V18.75Z"
29+
android:fillColor="#B66A1F"/>
30+
<path
31+
android:pathData="M13.032,10.458C13.215,10.462 13.399,10.467 13.582,10.472C13.669,10.474 13.754,10.507 13.818,10.567C13.883,10.628 13.921,10.71 13.925,10.797C13.929,10.884 13.898,10.969 13.839,11.035C13.78,11.101 13.698,11.141 13.611,11.151C13.43,11.172 13.247,11.193 13.066,11.213C10.99,11.443 8.911,11.611 6.83,11.716C6.701,11.723 6.577,11.757 6.463,11.815C6.21,11.944 6.015,12.184 5.946,12.475C5.843,12.979 5.726,13.482 5.593,13.982C5.546,14.16 5.496,14.338 5.445,14.515C5.42,14.603 5.366,14.683 5.29,14.737C5.214,14.791 5.121,14.814 5.031,14.801C4.941,14.788 4.859,14.739 4.802,14.665C4.744,14.592 4.716,14.499 4.717,14.407C4.719,14.223 4.724,14.039 4.73,13.856C4.746,13.338 4.777,12.823 4.824,12.31C4.888,11.655 5.311,11.036 5.909,10.735C6.177,10.598 6.477,10.519 6.776,10.508C8.859,10.429 10.944,10.412 13.032,10.458Z"
32+
android:fillColor="#FFEAB8"/>
33+
<path
34+
android:pathData="M12,12.75C10.895,12.75 10,13.645 10,14.75C10,15.326 10.246,15.843 10.636,16.208L10.311,17.508C10.153,18.139 10.631,18.75 11.281,18.75H12.719C13.369,18.75 13.847,18.139 13.689,17.508L13.365,16.208C13.755,15.843 14,15.326 14,14.75C14,13.645 13.105,12.75 12,12.75Z"
35+
android:fillColor="#783B13"/>
36+
</vector>

app/src/main/java/com/duckduckgo/app/onboarding/ui/page/BrandDesignUpdatePageViewModel.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import com.duckduckgo.app.onboarding.DuckAiOnboardingExperimentManager.DuckAiOnb
3434
import com.duckduckgo.app.onboarding.store.OnboardingStore
3535
import com.duckduckgo.app.onboarding.ui.page.PreOnboardingDialogType.*
3636
import com.duckduckgo.app.onboarding.ui.page.PreOnboardingDialogType.ADDRESS_BAR_POSITION
37+
import com.duckduckgo.app.onboarding.ui.page.PreOnboardingDialogType.AI_COMPARISON_CHART
3738
import com.duckduckgo.app.onboarding.ui.page.PreOnboardingDialogType.COMPARISON_CHART
3839
import com.duckduckgo.app.onboarding.ui.page.PreOnboardingDialogType.INITIAL
3940
import com.duckduckgo.app.onboarding.ui.page.PreOnboardingDialogType.INITIAL_REINSTALL_USER
@@ -211,6 +212,9 @@ class BrandDesignUpdatePageViewModel @Inject constructor(
211212
INITIAL_REINSTALL_USER -> pixel.fire(PREONBOARDING_INTRO_REINSTALL_USER_SHOWN_UNIQUE, type = Unique())
212213
INITIAL -> pixel.fire(PREONBOARDING_INTRO_SHOWN_UNIQUE, type = Unique())
213214
COMPARISON_CHART -> pixel.fire(PREONBOARDING_COMPARISON_CHART_SHOWN_UNIQUE, type = Unique())
215+
AI_COMPARISON_CHART -> {
216+
// TODO add pixel when trigger is wired
217+
}
214218
SKIP_ONBOARDING_OPTION -> pixel.fire(PREONBOARDING_SKIP_ONBOARDING_SHOWN_UNIQUE, type = Unique())
215219
ADDRESS_BAR_POSITION -> pixel.fire(PREONBOARDING_ADDRESS_BAR_POSITION_SHOWN_UNIQUE, type = Unique())
216220
INPUT_SCREEN -> pixel.fire(PREONBOARDING_CHOOSE_SEARCH_EXPERIENCE_IMPRESSIONS_UNIQUE, type = Unique())
@@ -298,6 +302,10 @@ class BrandDesignUpdatePageViewModel @Inject constructor(
298302
}
299303
}
300304

305+
AI_COMPARISON_CHART -> {
306+
// TODO handle primary CTA when trigger is wired
307+
}
308+
301309
SKIP_ONBOARDING_OPTION -> {
302310
viewModelScope.launch {
303311
_commands.send(Command.OnboardingSkipped)
@@ -395,7 +403,7 @@ class BrandDesignUpdatePageViewModel @Inject constructor(
395403
}
396404
}
397405

398-
INITIAL, COMPARISON_CHART, ADDRESS_BAR_POSITION, INPUT_SCREEN, INPUT_SCREEN_PREVIEW, QUICK_SETUP -> {
406+
INITIAL, COMPARISON_CHART, AI_COMPARISON_CHART, ADDRESS_BAR_POSITION, INPUT_SCREEN, INPUT_SCREEN_PREVIEW, QUICK_SETUP -> {
399407
// no-op
400408
}
401409
}

0 commit comments

Comments
 (0)