Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
dca90cc
add config-driven onboarding dialog data model
LukasPaczos Jul 29, 2026
6f618e1
add config-driven dialog binder contracts and content value store
LukasPaczos Jul 29, 2026
b22887b
add config-driven dialog render engine and controller contracts
LukasPaczos Jul 29, 2026
14c2975
add background, step indicator, card anchor and card arrow controllers
LukasPaczos Jul 29, 2026
36654f2
add embellishment controller with decoration fit and choreography
LukasPaczos Jul 29, 2026
401cd08
add card stage owning reveal, morph, fade and cta choreography
LukasPaczos Jul 29, 2026
186c762
add comparison chart and address bar binders with the content controller
LukasPaczos Jul 29, 2026
b026518
add dialog config resolver for the comparison chart and address bar s…
LukasPaczos Jul 29, 2026
b2b21ba
add config-driven onboarding page view model
LukasPaczos Jul 29, 2026
010944f
add config-driven onboarding page fragment
LukasPaczos Jul 29, 2026
543bd1a
select the config-driven onboarding renderer behind a feature flag
LukasPaczos Jul 29, 2026
8e2b85a
baseline the impl module import in the config-driven view model tests
LukasPaczos Jul 29, 2026
578545b
drop the unused default browser detector from the config-driven view …
LukasPaczos Jul 29, 2026
e7e82cf
drop the cta clickability note from the card stage contract
LukasPaczos Jul 29, 2026
7694942
clean ups and comment adjustments
LukasPaczos Jul 30, 2026
6c3a7fa
Add a content-ready hook for non-Animator entrance work
LukasPaczos Jul 30, 2026
7a733ac
comment adjustments
LukasPaczos Jul 30, 2026
25ddb95
apply settled card anchor before bounds transition
LukasPaczos Jul 31, 2026
0400a81
give the card's anchor a single owner
LukasPaczos Jul 31, 2026
91c180f
give screens with no decoration a reserved band
LukasPaczos Jul 31, 2026
1002717
cleanup comments
LukasPaczos Jul 31, 2026
99b3e75
release background controller
LukasPaczos Jul 31, 2026
722e873
fix walking dax entry
LukasPaczos Jul 31, 2026
7fd87f2
fix lambda access
LukasPaczos Jul 31, 2026
713795f
address review comments
LukasPaczos Aug 4, 2026
faae556
rename ConfigDrivenWelcomePage to ConfigDrivenWelcomePageFragment
LukasPaczos Aug 4, 2026
6c49269
escape isLaidOut check loop
LukasPaczos Aug 4, 2026
b4d0f59
fix abrupt background reposition on transition start
LukasPaczos Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/lint-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,17 @@
column="1"/>
</issue>

<issue
id="NoImplImportsInAppModule"
message="Modules should not import from :*-impl modules.&#xA;Consider using the public API instead: com.duckduckgo.onboarding.impl.LinearOnboardingOrchestratorImpl&#xA;If the API doesn&apos;t expose what you need, extend the API module first."
errorLine1="import com.duckduckgo.onboarding.impl.LinearOnboardingOrchestratorImpl"
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/test/java/com/duckduckgo/app/onboarding/ui/page/configdriven/ConfigDrivenOnboardingPageViewModelTest.kt"
line="44"
column="1"/>
</issue>

<issue
id="NoImplImportsInAppModule"
message="Modules should not import from :*-impl modules.&#xA;Consider using the public API instead: com.duckduckgo.duckchat.impl.ui.DuckChatWebViewFragment&#xA;If the API doesn&apos;t expose what you need, extend the API module first."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,20 @@ import com.duckduckgo.app.onboarding.ui.page.BrandDesignUpdateDefaultBrowserPage
import com.duckduckgo.app.onboarding.ui.page.BrandDesignUpdateWelcomePage
import com.duckduckgo.app.onboarding.ui.page.DefaultBrowserPage
import com.duckduckgo.app.onboarding.ui.page.WelcomePage
import com.duckduckgo.app.onboarding.ui.page.configdriven.ConfigDrivenWelcomePageFragment

interface OnboardingPageBuilder {
fun buildWelcomePage(): WelcomePage
fun buildBrandDesignUpdateWelcomePage(): BrandDesignUpdateWelcomePage
fun buildConfigDrivenWelcomePage(): ConfigDrivenWelcomePageFragment
fun buildDefaultBrowserPage(): DefaultBrowserPage
fun buildBrandDesignUpdateDefaultBrowserPage(): BrandDesignUpdateDefaultBrowserPage

sealed class OnboardingPageBlueprint {
data object DefaultBrowserBlueprint : OnboardingPageBlueprint()
data object WelcomePageBlueprint : OnboardingPageBlueprint()
data object BrandDesignUpdateWelcomePageBlueprint : OnboardingPageBlueprint()
data object ConfigDrivenWelcomePageBlueprint : OnboardingPageBlueprint()
data object BrandDesignUpdateDefaultBrowserPageBlueprint : OnboardingPageBlueprint()
}
}
Expand All @@ -39,6 +42,7 @@ class OnboardingFragmentPageBuilder : OnboardingPageBuilder {

override fun buildWelcomePage() = WelcomePage()
override fun buildBrandDesignUpdateWelcomePage() = BrandDesignUpdateWelcomePage()
override fun buildConfigDrivenWelcomePage() = ConfigDrivenWelcomePageFragment()
override fun buildDefaultBrowserPage() = DefaultBrowserPage()
override fun buildBrandDesignUpdateDefaultBrowserPage() = BrandDesignUpdateDefaultBrowserPage()
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,21 @@ import com.duckduckgo.app.global.DefaultRoleBrowserDialog
import com.duckduckgo.app.onboarding.ui.OnboardingPageBuilder.OnboardingPageBlueprint
import com.duckduckgo.app.onboarding.ui.OnboardingPageBuilder.OnboardingPageBlueprint.BrandDesignUpdateDefaultBrowserPageBlueprint
import com.duckduckgo.app.onboarding.ui.OnboardingPageBuilder.OnboardingPageBlueprint.BrandDesignUpdateWelcomePageBlueprint
import com.duckduckgo.app.onboarding.ui.OnboardingPageBuilder.OnboardingPageBlueprint.ConfigDrivenWelcomePageBlueprint
import com.duckduckgo.app.onboarding.ui.OnboardingPageBuilder.OnboardingPageBlueprint.DefaultBrowserBlueprint
import com.duckduckgo.app.onboarding.ui.OnboardingPageBuilder.OnboardingPageBlueprint.WelcomePageBlueprint
import com.duckduckgo.app.onboarding.ui.page.BrandDesignUpdateDefaultBrowserPage
import com.duckduckgo.app.onboarding.ui.page.BrandDesignUpdateWelcomePage
import com.duckduckgo.app.onboarding.ui.page.DefaultBrowserPage
import com.duckduckgo.app.onboarding.ui.page.OnboardingPageFragment
import com.duckduckgo.app.onboarding.ui.page.WelcomePage
import com.duckduckgo.app.onboarding.ui.page.configdriven.ConfigDrivenWelcomePageFragment

interface OnboardingPageManager {
fun pageCount(): Int
fun buildPageBlueprints()
fun buildBrandDesignUpdatePageBlueprints()
fun buildConfigDrivenPageBlueprints()
fun buildPage(position: Int): OnboardingPageFragment?
}

Expand Down Expand Up @@ -64,11 +67,20 @@ class OnboardingPageManagerWithTrackerBlocking(
}
}

override fun buildConfigDrivenPageBlueprints() {
pages.clear()
pages += ConfigDrivenWelcomePageBlueprint
if (shouldShowDefaultBrowserPage()) {
pages += BrandDesignUpdateDefaultBrowserPageBlueprint
}
}

override fun buildPage(position: Int): OnboardingPageFragment? {
return when (pages.getOrNull(position)) {
is WelcomePageBlueprint -> buildWelcomePage()
is DefaultBrowserBlueprint -> buildDefaultBrowserPage()
is BrandDesignUpdateWelcomePageBlueprint -> buildBrandDesignUpdateWelcomePage()
is ConfigDrivenWelcomePageBlueprint -> buildConfigDrivenWelcomePage()
is BrandDesignUpdateDefaultBrowserPageBlueprint -> buildBrandDesignUpdateDefaultBrowserPage()
else -> null
}
Expand All @@ -92,6 +104,10 @@ class OnboardingPageManagerWithTrackerBlocking(
return onboardingPageBuilder.buildBrandDesignUpdateWelcomePage()
}

private fun buildConfigDrivenWelcomePage(): ConfigDrivenWelcomePageFragment {
return onboardingPageBuilder.buildConfigDrivenWelcomePage()
}

private fun buildBrandDesignUpdateDefaultBrowserPage(): BrandDesignUpdateDefaultBrowserPage {
return onboardingPageBuilder.buildBrandDesignUpdateDefaultBrowserPage()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,20 @@ class OnboardingViewModel @Inject constructor(
val viewState = _viewState.asStateFlow()

suspend fun initializePages() {
val isBrandDesignUpdateEnabled = withContext(dispatchers.io()) {
onboardingBrandDesignUpdateToggles.brandDesignUpdate().isEnabled()
}
if (isBrandDesignUpdateEnabled) {
pageLayoutManager.buildBrandDesignUpdatePageBlueprints()
} else {
pageLayoutManager.buildPageBlueprints()
val renderer = withContext(dispatchers.io()) { resolveRenderer() }
when (renderer) {
OnboardingRenderer.ConfigDriven -> pageLayoutManager.buildConfigDrivenPageBlueprints()
OnboardingRenderer.BrandDesignUpdate -> pageLayoutManager.buildBrandDesignUpdatePageBlueprints()
OnboardingRenderer.Legacy -> pageLayoutManager.buildPageBlueprints()
}
}

private fun resolveRenderer(): OnboardingRenderer = when {
!onboardingBrandDesignUpdateToggles.brandDesignUpdate().isEnabled() -> OnboardingRenderer.Legacy
onboardingBrandDesignUpdateToggles.configDrivenDialogs().isEnabled() -> OnboardingRenderer.ConfigDriven
else -> OnboardingRenderer.BrandDesignUpdate
}

fun pageCount(): Int {
return pageLayoutManager.pageCount()
}
Expand Down Expand Up @@ -154,4 +158,6 @@ class OnboardingViewModel @Inject constructor(
DUCK_AI_FOCUSED,
DEFAULT_WITHOUT_INTRO_CTA,
}

private enum class OnboardingRenderer { Legacy, BrandDesignUpdate, ConfigDriven }
}
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,14 @@ class BrandDesignUpdateWelcomePage : OnboardingPageFragment(R.layout.content_onb
root = binding.root,
dialog = binding.daxDialogCta.root,
cardContainer = binding.daxDialogCta.cardContainer,
onDecorationHidden = { binding.daxDialogCta.cardView.setArrowDepthFraction(0f) },
onDecorationHidden = {
binding.daxDialogCta.cardView.setArrowDepthFraction(0f)
binding.daxDialogCta.root.updateLayoutParams<ConstraintLayout.LayoutParams> {
verticalBias = 0f
bottomToTop = ConstraintLayout.LayoutParams.UNSET
bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
}
},
Comment on lines +549 to +556

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Refs https://github.com/duckduckgo/Android/pull/9365/changes#r3690849481, this is the only change to production codebase, just a moved functional call.

cardBottomInsetPx = { cardBottomInsetPx },
).also { it.attach() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,6 @@ class OnboardingDecorationFitCorrector(

if (target == null) {
deco.isGone = true
dialog.updateLayoutParams<ConstraintLayout.LayoutParams> {
verticalBias = 0f
bottomToTop = ConstraintLayout.LayoutParams.UNSET
bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
}
Comment on lines -119 to -123

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the only change to the "flag off" code path. This code is moved directly to BrandDesignUpdateWelcomePage, so no behavior change.

onDecorationHidden()
return false
}
Expand Down
Loading
Loading