Skip to content

Commit 0973926

Browse files
authored
Split Omnibar: Address bar integration (#7042)
Task/Issue URL: https://app.asana.com/1/137249556945/project/1207418217763355/task/1211565479656355?focus=true ### Description This PR adds the last integration of the split omnibar to the address bar: - When the split omnibar type is selected, the top omnibar buttons are hidden - The mock toolbar must show the split omnibar when loading ### Steps to test this PR _Omnibar button_ - [ ] Enable the `splitOmnibar` flag - [ ] Go to Settings -> Appearance - [ ] Select the split omnibar - [ ] Go back to the browser - [ ] Notice the buttons next to the address bar are gone _Mock split toolbar_ - [ ] Restart the app - [ ] While the app is loading, notice the mock top bar and bottom navigation bar are displayed until the app's loaded
1 parent 74ddd12 commit 0973926

File tree

14 files changed

+656
-250
lines changed

14 files changed

+656
-250
lines changed

app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ open class BrowserActivity : DuckDuckGoActivity() {
990990
if (this::omnibarToolbarMockupBottomBinding.isInitialized) {
991991
omnibarToolbarMockupBottomBinding.appBarLayoutMockup.visibility = View.GONE
992992
}
993+
binding.navigationBarMockup.root.gone()
993994
},
994995
300,
995996
)
@@ -1399,11 +1400,11 @@ open class BrowserActivity : DuckDuckGoActivity() {
13991400
when (settingsDataStore.omnibarType) {
14001401
OmnibarType.SINGLE_TOP, OmnibarType.SPLIT -> {
14011402
if (Build.VERSION.SDK_INT < 28) {
1402-
binding.topMockupSingleToolbar.mockOmniBarContainerShadow.cardElevation = 2f.toPx(this)
1403+
binding.topMockupToolbar.mockOmniBarContainerShadow.cardElevation = 2f.toPx(this)
14031404
}
14041405

1405-
binding.bottomMockupSingleToolbar.appBarLayoutMockup.gone()
1406-
omnibarToolbarMockupBinding = binding.topMockupSingleToolbar
1406+
binding.bottomMockupToolbar.appBarLayoutMockup.gone()
1407+
omnibarToolbarMockupBinding = binding.topMockupToolbar
14071408

14081409
if (!duckAiFeatureState.showOmnibarShortcutOnNtpAndOnFocus.value) {
14091410
omnibarToolbarMockupBinding.aiChatIconMockup.isVisible = false
@@ -1412,15 +1413,22 @@ open class BrowserActivity : DuckDuckGoActivity() {
14121413
if (Build.VERSION.SDK_INT >= 28) {
14131414
omnibarToolbarMockupBinding.mockOmniBarContainerShadow.addBottomShadow()
14141415
}
1416+
1417+
if (settingsDataStore.omnibarType == OmnibarType.SPLIT) {
1418+
binding.topMockupToolbar.tabsMenu.gone()
1419+
binding.topMockupToolbar.browserMenu.gone()
1420+
binding.topMockupToolbar.fireIconMenu.gone()
1421+
binding.navigationBarMockup.root.show()
1422+
}
14151423
}
14161424

14171425
OmnibarType.SINGLE_BOTTOM -> {
14181426
if (Build.VERSION.SDK_INT < 28) {
1419-
binding.bottomMockupSingleToolbar.mockOmniBarContainerShadow.cardElevation = 0.5f.toPx(this)
1427+
binding.bottomMockupToolbar.mockOmniBarContainerShadow.cardElevation = 0.5f.toPx(this)
14201428
}
14211429

1422-
binding.topMockupSingleToolbar.appBarLayoutMockup.gone()
1423-
omnibarToolbarMockupBottomBinding = binding.bottomMockupSingleToolbar
1430+
binding.topMockupToolbar.appBarLayoutMockup.gone()
1431+
omnibarToolbarMockupBottomBinding = binding.bottomMockupToolbar
14241432

14251433
if (!duckAiFeatureState.showOmnibarShortcutOnNtpAndOnFocus.value) {
14261434
omnibarToolbarMockupBottomBinding.aiChatIconMockup.isVisible = false

app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,10 @@ class BrowserTabFragment :
930930
}
931931

932932
InputScreenActivityResultCodes.MENU_REQUESTED -> {
933-
launchPopupMenu(omnibarFeatureRepository.isSplitOmnibarEnabled)
933+
launchPopupMenu(
934+
anchorToNavigationBar = omnibarFeatureRepository.isSplitOmnibarEnabled,
935+
addExtraDelay = omnibarFeatureRepository.isSplitOmnibarEnabled,
936+
)
934937
}
935938

936939
InputScreenActivityResultCodes.TAB_SWITCHER_REQUESTED -> {
@@ -1425,11 +1428,12 @@ class BrowserTabFragment :
14251428
startActivity(intent)
14261429
}
14271430

1428-
private fun launchPopupMenu(anchorToNavigationBar: Boolean) {
1431+
private fun launchPopupMenu(anchorToNavigationBar: Boolean, addExtraDelay: Boolean = false) {
14291432
val isFocusedNtp = omnibar.viewMode == ViewMode.NewTab && omnibar.getText().isEmpty() && omnibar.omnibarTextInput.hasFocus()
14301433

1434+
val delay = if (addExtraDelay) POPUP_MENU_DELAY * 2 else POPUP_MENU_DELAY
14311435
// small delay added to let keyboard disappear and avoid jarring transition
1432-
binding.rootView.postDelayed(POPUP_MENU_DELAY) {
1436+
binding.rootView.postDelayed(delay) {
14331437
if (isAdded) {
14341438
// Check if VPN menu item will be shown to non-subscribed user and increment count
14351439
val currentViewState = viewModel.browserViewState.value
@@ -1631,7 +1635,7 @@ class BrowserTabFragment :
16311635
.flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED)
16321636
.collectLatest { hasFavorites ->
16331637
binding.includeNewBrowserTab.topNtpOutlineStroke.isVisible = hasFavorites
1634-
binding.includeNewBrowserTab.bottomNtpOutlineStroke.isVisible = hasFavorites
1638+
binding.includeNewBrowserTab.bottomNtpOutlineStroke.isVisible = hasFavorites && !omnibarFeatureRepository.isSplitOmnibarEnabled
16351639
}
16361640
}
16371641

app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarViewModel.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ class BrowserNavigationBarViewModel @Inject constructor(
163163
}
164164

165165
data class ViewState(
166-
val isVisible: Boolean = false,
167-
val newTabButtonVisible: Boolean = false,
168-
val autofillButtonVisible: Boolean = true,
166+
val isVisible: Boolean = true,
167+
val newTabButtonVisible: Boolean = true,
168+
val autofillButtonVisible: Boolean = false,
169169
val bookmarksButtonVisible: Boolean = true,
170170
val fireButtonVisible: Boolean = true,
171171
val fireButtonHighlighted: Boolean = false,

app/src/main/java/com/duckduckgo/app/browser/omnibar/Omnibar.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,16 @@ class Omnibar(
184184
binding.rootView.removeView(binding.singleOmnibarLayoutBottom)
185185

186186
return when (omnibarType) {
187-
OmnibarType.SINGLE_TOP, OmnibarType.SPLIT -> {
187+
OmnibarType.SINGLE_TOP -> {
188188
binding.rootView.removeView(binding.omnibarLayoutBottom)
189189
binding.omnibarLayoutTop
190190
}
191-
191+
OmnibarType.SPLIT -> {
192+
binding.rootView.removeView(binding.omnibarLayoutBottom)
193+
binding.bottomBrowserOutlineStroke.gone()
194+
binding.includeNewBrowserTab.bottomNtpOutlineStroke.gone()
195+
binding.omnibarLayoutTop
196+
}
192197
OmnibarType.SINGLE_BOTTOM -> {
193198
binding.rootView.removeView(binding.omnibarLayoutTop)
194199
adjustCoordinatorLayoutBehaviorForBottomOmnibar()

app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -779,9 +779,12 @@ class OmnibarLayout @JvmOverloads constructor(
779779
showSpacer = viewState.showClearButton || viewState.showVoiceSearch,
780780
)
781781

782-
if (omnibarAnimationManager.isFeatureEnabled() &&
783-
previousTransitionState != null &&
784-
newTransitionState != previousTransitionState
782+
if (omnibarAnimationManager.isFeatureEnabled() && previousTransitionState != null &&
783+
(
784+
newTransitionState.showFireIcon != previousTransitionState?.showFireIcon ||
785+
newTransitionState.showTabsMenu != previousTransitionState?.showTabsMenu ||
786+
newTransitionState.showBrowserMenu != previousTransitionState?.showBrowserMenu
787+
)
785788
) {
786789
TransitionManager.beginDelayedTransition(toolbarContainer, omniBarButtonTransitionSet)
787790
}

app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayoutViewModel.kt

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import com.duckduckgo.app.statistics.pixels.Pixel.PixelType.Unique
5555
import com.duckduckgo.app.tabs.model.TabRepository
5656
import com.duckduckgo.app.trackerdetection.model.Entity
5757
import com.duckduckgo.browser.api.UserBrowserProperties
58+
import com.duckduckgo.browser.ui.omnibar.OmnibarType
5859
import com.duckduckgo.common.utils.DispatcherProvider
5960
import com.duckduckgo.di.scopes.FragmentScope
6061
import com.duckduckgo.duckchat.api.DuckAiFeatureState
@@ -103,9 +104,14 @@ class OmnibarLayoutViewModel @Inject constructor(
103104
private val serpEasterEggLogosToggles: SerpEasterEggLogosToggles,
104105
) : ViewModel() {
105106

107+
private val isSplitOmnibarEnabled = settingsDataStore.omnibarType == OmnibarType.SPLIT
108+
106109
private val _viewState = MutableStateFlow(
107110
ViewState(
108111
showChatMenu = duckAiFeatureState.showOmnibarShortcutInAllStates.value,
112+
showFireIcon = !isSplitOmnibarEnabled,
113+
showTabsMenu = !isSplitOmnibarEnabled,
114+
showBrowserMenu = !isSplitOmnibarEnabled,
109115
),
110116
)
111117

@@ -256,7 +262,7 @@ class OmnibarLayoutViewModel @Inject constructor(
256262
) {
257263
logcat { "Omnibar: onOmnibarFocusChanged" }
258264
val showClearButton = hasFocus && inputFieldText.isNotBlank()
259-
val showControls = inputFieldText.isBlank()
265+
val showControls = inputFieldText.isBlank() && !isSplitOmnibarEnabled
260266

261267
if (hasFocus) {
262268
viewModelScope.launch {
@@ -326,9 +332,9 @@ class OmnibarLayoutViewModel @Inject constructor(
326332
previousLeadingIconState = null,
327333
highlightFireButton = HighlightableButton.Visible(highlighted = false),
328334
showClearButton = false,
329-
showTabsMenu = true,
330-
showFireIcon = true,
331-
showBrowserMenu = true,
335+
showTabsMenu = !isSplitOmnibarEnabled,
336+
showFireIcon = !isSplitOmnibarEnabled,
337+
showBrowserMenu = !isSplitOmnibarEnabled,
332338
showVoiceSearch = shouldShowVoiceSearch(
333339
hasFocus = false,
334340
query = _viewState.value.omnibarText,
@@ -481,17 +487,16 @@ class OmnibarLayoutViewModel @Inject constructor(
481487
AppPixelName.ADDRESS_BAR_SERP_ENTRY_CLEARED,
482488
AppPixelName.ADDRESS_BAR_WEBSITE_ENTRY_CLEARED,
483489
)
484-
val showControls = true
485490

486491
_viewState.update {
487492
it.copy(
488493
omnibarText = "",
489494
updateOmnibarText = true,
490495
expanded = true,
491496
showClearButton = false,
492-
showBrowserMenu = showControls,
493-
showTabsMenu = showControls,
494-
showFireIcon = showControls,
497+
showBrowserMenu = !isSplitOmnibarEnabled,
498+
showTabsMenu = !isSplitOmnibarEnabled,
499+
showFireIcon = !isSplitOmnibarEnabled,
495500
)
496501
}
497502
}
@@ -546,7 +551,7 @@ class OmnibarLayoutViewModel @Inject constructor(
546551
deleteLastCharacter: Boolean,
547552
) {
548553
val showClearButton = hasFocus && query.isNotBlank()
549-
val showControls = !hasFocus || query.isBlank()
554+
val showControls = (!hasFocus || query.isBlank()) && !isSplitOmnibarEnabled
550555

551556
logcat { "Omnibar: onInputStateChanged query $query hasFocus $hasFocus clearQuery $clearQuery deleteLastCharacter $deleteLastCharacter" }
552557

0 commit comments

Comments
 (0)