diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index 6896515a7ef0..a415ea40bfca 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -2684,18 +2684,26 @@ class BrowserTabFragment : ) } + private fun checkIfCanScroll() { + val canScrollUp = newBrowserTab.newTabContainerScrollView.canScrollVertically(-1) + val canScrollDown = newBrowserTab.newTabContainerScrollView.canScrollVertically(1) + + omnibar.setContentCanScroll(canScrollUp, canScrollDown) + binding.navigationBar.setCanScrollDown(canScrollDown) + } + private fun configureNewTab() { newBrowserTab.newTabContainerScrollView.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY -> if (omnibar.isEditing()) { hideKeyboard() } - // Check if it can scroll up - val canScrollUp = v.canScrollVertically(-1) - val canScrollDown = v.canScrollVertically(1) - val topOfPage = scrollY == 0 + checkIfCanScroll() + } - omnibar.setContentCanScroll(canScrollUp, canScrollDown, topOfPage) + // check if the content can scroll after a delay to allow the view to be fully laid out + view?.postDelayed(SCROLLABILITY_CHECK_STARTUP_DELAY) { + checkIfCanScroll() } } @@ -3657,6 +3665,10 @@ class BrowserTabFragment : recreatePopupMenu() privacyProtectionsPopup.onConfigurationChanged() viewModel.onConfigurationChanged() + + view?.postDelayed(SCROLLABILITY_CHECK_CONFIG_CHANGE_DELAY) { + checkIfCanScroll() + } } fun onBackPressed(isCustomTab: Boolean = false): Boolean { @@ -3952,6 +3964,9 @@ class BrowserTabFragment : private const val MAX_PROGRESS = 100 private const val TRACKERS_INI_DELAY = 500L + + private const val SCROLLABILITY_CHECK_STARTUP_DELAY = 1000L + private const val SCROLLABILITY_CHECK_CONFIG_CHANGE_DELAY = 500L private const val TRACKERS_SECONDARY_DELAY = 200L private const val DEFAULT_CIRCLE_TARGET_TIMES_1_5 = 96 diff --git a/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/BrowserNavigationBarViewIntegration.kt b/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/BrowserNavigationBarViewIntegration.kt index c893eb19080d..d1007a4408dc 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/BrowserNavigationBarViewIntegration.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/BrowserNavigationBarViewIntegration.kt @@ -62,6 +62,7 @@ class BrowserNavigationBarViewIntegration( onDisabled() } navigationBarView.browserNavigationBarObserver = browserNavigationBarObserver + navigationBarView.setOmnibarPosition(omnibar.omnibarPosition) } fun configureCustomTab() { diff --git a/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarView.kt b/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarView.kt index de0770258ec7..289720468b18 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarView.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarView.kt @@ -33,7 +33,6 @@ import androidx.lifecycle.findViewTreeViewModelStoreOwner import androidx.lifecycle.lifecycleScope import com.duckduckgo.anvil.annotations.InjectWith import com.duckduckgo.app.browser.PulseAnimation -import com.duckduckgo.app.browser.R import com.duckduckgo.app.browser.databinding.ViewBrowserNavigationBarBinding import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyAutofillButtonClicked @@ -67,16 +66,6 @@ class BrowserNavigationBarView @JvmOverloads constructor( defStyle: Int = 0, ) : FrameLayout(context, attrs, defStyle), AttachedBehavior { - private var showShadows: Boolean = false - - init { - context.theme.obtainStyledAttributes(attrs, R.styleable.BrowserNavigationBarView, defStyle, 0) - .apply { - showShadows = getBoolean(R.styleable.BrowserNavigationBarView_showShadows, true) - recycle() - } - } - override fun setVisibility(visibility: Int) { val isVisibilityUpdated = this.visibility != visibility @@ -126,6 +115,12 @@ class BrowserNavigationBarView @JvmOverloads constructor( } } + fun setOmnibarPosition(omnibarPosition: OmnibarPosition) { + doOnAttach { + viewModel.setOmnibarPosition(omnibarPosition) + } + } + fun setViewMode(viewMode: ViewMode) { doOnAttach { viewModel.setViewMode(viewMode) @@ -138,6 +133,12 @@ class BrowserNavigationBarView @JvmOverloads constructor( } } + fun setCanScrollDown(canScrollDown: Boolean) { + doOnAttach { + viewModel.onCanScrollDownChanged(canScrollDown) + } + } + override fun onAttachedToWindow() { AndroidSupportInjection.inject(this) super.onAttachedToWindow() @@ -196,7 +197,6 @@ class BrowserNavigationBarView @JvmOverloads constructor( } private fun renderView(viewState: ViewState) { - binding.shadowView.isVisible = showShadows binding.root.isVisible = viewState.isVisible binding.newTabButton.isVisible = viewState.newTabButtonVisible @@ -208,6 +208,7 @@ class BrowserNavigationBarView @JvmOverloads constructor( binding.tabsButton.hasUnread = viewState.hasUnreadTabs renderFireButtonPulseAnimation(enabled = viewState.fireButtonHighlighted) + binding.shadowView.isVisible = viewState.showShadow } private fun processCommands(command: Command) { diff --git a/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarViewModel.kt index 37a4dd832fda..32e2f30c6a98 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/navigation/bar/view/BrowserNavigationBarViewModel.kt @@ -31,6 +31,7 @@ import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewMo import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyNewTabButtonClicked import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyTabsButtonClicked import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyTabsButtonLongClicked +import com.duckduckgo.app.browser.omnibar.model.OmnibarPosition import com.duckduckgo.app.pixels.AppPixelName import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.app.statistics.pixels.Pixel.PixelParameter.FIRE_BUTTON_STATE @@ -124,6 +125,7 @@ class BrowserNavigationBarViewModel @Inject constructor( autofillButtonVisible = true, fireButtonVisible = true, tabsButtonVisible = true, + isNewTab = true, ) } } @@ -135,6 +137,7 @@ class BrowserNavigationBarViewModel @Inject constructor( autofillButtonVisible = false, fireButtonVisible = true, tabsButtonVisible = true, + isNewTab = false, ) } } @@ -149,6 +152,22 @@ class BrowserNavigationBarViewModel @Inject constructor( } } + fun setOmnibarPosition(omnibarPosition: OmnibarPosition) { + _viewState.update { + it.copy( + omnibarPosition = omnibarPosition, + ) + } + } + + fun onCanScrollDownChanged(canScrollDown: Boolean) { + _viewState.update { + it.copy( + canScrollDown = canScrollDown, + ) + } + } + sealed class Command { data object NotifyFireButtonClicked : Command() data object NotifyTabsButtonClicked : Command() @@ -172,5 +191,11 @@ class BrowserNavigationBarViewModel @Inject constructor( val tabsButtonVisible: Boolean = true, val tabsCount: Int = 0, val hasUnreadTabs: Boolean = false, - ) + val isNewTab: Boolean = false, + val canScrollDown: Boolean = false, + val omnibarPosition: OmnibarPosition = OmnibarPosition.BOTTOM, + ) { + val showShadow: Boolean + get() = omnibarPosition == OmnibarPosition.TOP && (!isNewTab || canScrollDown) + } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/omnibar/Omnibar.kt b/app/src/main/java/com/duckduckgo/app/browser/omnibar/Omnibar.kt index 948d5877c50c..0a49f7c2a5ed 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/omnibar/Omnibar.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/omnibar/Omnibar.kt @@ -455,9 +455,8 @@ class Omnibar( fun setContentCanScroll( canScrollUp: Boolean, canScrollDown: Boolean, - topOfPage: Boolean, ) { - newOmnibar.decorate(Decoration.NewTabScrollingState(canScrollUp, canScrollDown, topOfPage)) + newOmnibar.decorate(Decoration.NewTabScrollingState(canScrollUp, canScrollDown)) } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt b/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt index 893564f229aa..c7106f0a7b9f 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt @@ -139,7 +139,6 @@ open class OmnibarLayout @JvmOverloads constructor( data class NewTabScrollingState( val canScrollUp: Boolean, val canScrollDown: Boolean, - val topOfPage: Boolean, ) : Decoration() } diff --git a/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayoutViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayoutViewModel.kt index b5d27faa1662..025d96d99d2a 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayoutViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayoutViewModel.kt @@ -159,7 +159,8 @@ class OmnibarLayoutViewModel @Inject constructor( val isVisualDesignExperimentEnabled: Boolean = false, val trackersBlocked: Int = 0, val previouslyTrackersBlocked: Int = 0, - val showShadows: Boolean = false, + val showTopShadow: Boolean = false, + val showBottomShadow: Boolean = false, val showClickCatcher: Boolean = false, ) { fun shouldUpdateOmnibarText(): Boolean { @@ -341,7 +342,8 @@ class OmnibarLayoutViewModel @Inject constructor( showBrowserMenu = true, showTabsMenu = false, showFireIcon = false, - showShadows = true, + showTopShadow = true, + showBottomShadow = true, ) } } @@ -370,7 +372,8 @@ class OmnibarLayoutViewModel @Inject constructor( hasQueryChanged = false, urlLoaded = _viewState.value.url, ), - showShadows = false, + showTopShadow = viewMode !is NewTab, + showBottomShadow = viewMode !is NewTab, ) } } @@ -742,12 +745,13 @@ class OmnibarLayoutViewModel @Inject constructor( fun onNewTabScrollingStateChanged(scrollingState: Decoration.NewTabScrollingState) { val viewMode = viewState.value.viewMode - // if (viewMode is NewTab) { - // _viewState.update { - // it.copy( - // showShadows = (scrollingState.canScrollUp || scrollingState.canScrollDown) && !scrollingState.topOfPage, - // ) - // } - // } + if (viewMode is NewTab) { + _viewState.update { + it.copy( + showTopShadow = scrollingState.canScrollDown, + showBottomShadow = scrollingState.canScrollUp, + ) + } + } } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/omnibar/experiments/FadeOmnibarLayout.kt b/app/src/main/java/com/duckduckgo/app/browser/omnibar/experiments/FadeOmnibarLayout.kt index 1f7acf3a2b60..60df73aad75c 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/omnibar/experiments/FadeOmnibarLayout.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/omnibar/experiments/FadeOmnibarLayout.kt @@ -48,7 +48,6 @@ import com.duckduckgo.common.ui.experiments.visual.store.VisualDesignExperimentD import com.duckduckgo.common.ui.view.gone import com.duckduckgo.common.ui.view.hide import com.duckduckgo.common.ui.view.show -import com.duckduckgo.common.ui.view.toDp import com.duckduckgo.di.scopes.FragmentScope import com.duckduckgo.duckchat.impl.ui.SearchInterstitialActivityParams import com.duckduckgo.mobile.android.R as CommonR @@ -76,6 +75,10 @@ class FadeOmnibarLayout @JvmOverloads constructor( private val backIcon: ImageView by lazy { findViewById(R.id.backIcon) } private val customTabToolbarContainerWrapper: ViewGroup by lazy { findViewById(R.id.customTabToolbarContainerWrapper) } private val omniBarClickCatcher: View by lazy { findViewById(R.id.omnibarClickCatcher) } + private val shadowTop: View by lazy { findViewById(R.id.shadowViewTop) } + private val shadowLineBottom: View by lazy { findViewById(R.id.shadowLineViewBottom) } + + private val shadowGradientBottom: View by lazy { findViewById(R.id.shadowViewBottom) } override val findInPage: FindInPage by lazy { FindInPageImpl(IncludeFadeOmnibarFindInPageBinding.bind(findViewById(R.id.findInPage))) @@ -129,12 +132,12 @@ class FadeOmnibarLayout @JvmOverloads constructor( AndroidSupportInjection.inject(this) + outlineProvider = null + val rootContainer = root.findViewById(R.id.rootContainer) val navBar = rootContainer.findViewById(R.id.omnibarNavigationBar) if (omnibarPosition == OmnibarPosition.TOP) { rootContainer.removeView(navBar) - - omnibarCard.elevation = 1f.toDp(context) } else { navigationBar = navBar @@ -148,8 +151,6 @@ class FadeOmnibarLayout @JvmOverloads constructor( navBar.findViewById(R.id.barView).updatePadding( top = 0, ) - - omnibarCard.elevation = 0.5f.toDp(context) } omniBarClickCatcher.setOnClickListener { globalActivityStarter.start(context, SearchInterstitialActivityParams) @@ -192,7 +193,7 @@ class FadeOmnibarLayout @JvmOverloads constructor( override fun render(viewState: ViewState) { super.render(viewState) - renderShadows(viewState.showShadows) + renderShadows(viewState.showTopShadow, viewState.showBottomShadow) if (viewState.hasFocus || isFindInPageVisible) { animateOmnibarFocusedState(focused = true) @@ -363,12 +364,16 @@ class FadeOmnibarLayout @JvmOverloads constructor( } } - private fun renderShadows(showShadows: Boolean) { - // outlineProvider = if (showShadows) { - // ViewOutlineProvider.BACKGROUND - // } else { - // null - // } + private fun renderShadows(showTopShadow: Boolean, showBottomShadow: Boolean) { + val isBottomShadowVisible = showBottomShadow && omnibarPosition == OmnibarPosition.TOP + if (viewModel.viewState.value.viewMode == ViewMode.NewTab) { + shadowLineBottom.gone() + shadowGradientBottom.isVisible = isBottomShadowVisible + } else { + shadowLineBottom.isVisible = isBottomShadowVisible + shadowGradientBottom.gone() + } + shadowTop.isVisible = showTopShadow && omnibarPosition == OmnibarPosition.BOTTOM } companion object { diff --git a/app/src/main/res/drawable/background_webview_bottom_shadow.xml b/app/src/main/res/drawable/background_webview_bottom_shadow.xml new file mode 100644 index 000000000000..64c747718cf4 --- /dev/null +++ b/app/src/main/res/drawable/background_webview_bottom_shadow.xml @@ -0,0 +1,23 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_navigation_bar_shadow.xml b/app/src/main/res/drawable/background_webview_top_shadow.xml similarity index 89% rename from app/src/main/res/drawable/background_navigation_bar_shadow.xml rename to app/src/main/res/drawable/background_webview_top_shadow.xml index 6842289aa38d..27f6d13c8e65 100644 --- a/app/src/main/res/drawable/background_navigation_bar_shadow.xml +++ b/app/src/main/res/drawable/background_webview_top_shadow.xml @@ -17,7 +17,7 @@ android:shape="rectangle"> \ No newline at end of file diff --git a/app/src/main/res/layout-w600dp/view_browser_navigation_bar.xml b/app/src/main/res/layout-w600dp/view_browser_navigation_bar.xml index 1fd481d00f67..3abbc7c31e93 100644 --- a/app/src/main/res/layout-w600dp/view_browser_navigation_bar.xml +++ b/app/src/main/res/layout-w600dp/view_browser_navigation_bar.xml @@ -176,8 +176,8 @@ diff --git a/app/src/main/res/layout/fragment_browser_tab.xml b/app/src/main/res/layout/fragment_browser_tab.xml index 455fb9ec4f29..e45d22e9492d 100644 --- a/app/src/main/res/layout/fragment_browser_tab.xml +++ b/app/src/main/res/layout/fragment_browser_tab.xml @@ -157,7 +157,6 @@ android:id="@+id/navigationBar" android:layout_width="match_parent" android:layout_height="wrap_content" - app:showShadows="true" android:layout_gravity="bottom" /> \ No newline at end of file diff --git a/app/src/main/res/layout/view_browser_navigation_bar.xml b/app/src/main/res/layout/view_browser_navigation_bar.xml index 4a7d7c011577..9d0616495604 100644 --- a/app/src/main/res/layout/view_browser_navigation_bar.xml +++ b/app/src/main/res/layout/view_browser_navigation_bar.xml @@ -154,8 +154,8 @@ diff --git a/app/src/main/res/layout/view_fade_omnibar.xml b/app/src/main/res/layout/view_fade_omnibar.xml index c894c7bb5424..7c8cc996f1b8 100644 --- a/app/src/main/res/layout/view_fade_omnibar.xml +++ b/app/src/main/res/layout/view_fade_omnibar.xml @@ -31,6 +31,12 @@ android:orientation="vertical" app:layout_scrollFlags="scroll|enterAlways|snap"> + + + + + + diff --git a/app/src/main/res/values/attrs-omnibar-view.xml b/app/src/main/res/values/attrs-omnibar-view.xml index 4bfd8e65be0a..7ffa40e075c2 100644 --- a/app/src/main/res/values/attrs-omnibar-view.xml +++ b/app/src/main/res/values/attrs-omnibar-view.xml @@ -37,8 +37,4 @@ - - - - \ No newline at end of file diff --git a/common/common-ui/src/main/res/values/design-experiments-colors.xml b/common/common-ui/src/main/res/values/design-experiments-colors.xml index a6bd8d11f063..61e2092a8e25 100644 --- a/common/common-ui/src/main/res/values/design-experiments-colors.xml +++ b/common/common-ui/src/main/res/values/design-experiments-colors.xml @@ -26,6 +26,7 @@ #333538 #404145 #404145 + #202021 #E6FFFFFF @@ -39,6 +40,7 @@ #1FF9F9F9 + #08F9F9F9 #1FF9F9F9 @@ -52,6 +54,7 @@ #F9F9F9 #FFFFFF #FFFFFF + #DEDEE0 #1F1F1F @@ -65,6 +68,7 @@ #171F1F1F + #00000000 #171F1F1F diff --git a/common/common-ui/src/main/res/values/design-experiments-theming.xml b/common/common-ui/src/main/res/values/design-experiments-theming.xml index 48437caba621..6ed737f495dd 100644 --- a/common/common-ui/src/main/res/values/design-experiments-theming.xml +++ b/common/common-ui/src/main/res/values/design-experiments-theming.xml @@ -23,6 +23,7 @@ @color/background_background_dark @color/background_surface_dark @color/background_window_dark + @color/background_shadow_dark @color/text_primary_dark @@ -35,6 +36,7 @@ @color/lines_dark + @color/lines_dark @color/controls_fill_primary_dark @@ -63,6 +65,7 @@ @color/background_background_light @color/background_surface_light @color/background_window_light + @color/background_shadow_light @color/text_primary_light @@ -75,6 +78,7 @@ @color/lines_light + @color/line_shadow_light @color/controls_fill_primary_light diff --git a/common/common-ui/src/main/res/values/design-system-colors.xml b/common/common-ui/src/main/res/values/design-system-colors.xml index 0e9aec62f42e..9ebd543154fc 100644 --- a/common/common-ui/src/main/res/values/design-system-colors.xml +++ b/common/common-ui/src/main/res/values/design-system-colors.xml @@ -48,6 +48,7 @@ + @@ -58,6 +59,7 @@ + diff --git a/common/common-ui/src/main/res/values/design-system-theming.xml b/common/common-ui/src/main/res/values/design-system-theming.xml index 2d204324f2e7..bf5aae2882f1 100644 --- a/common/common-ui/src/main/res/values/design-system-theming.xml +++ b/common/common-ui/src/main/res/values/design-system-theming.xml @@ -127,6 +127,7 @@ ?attr/daxColorSurface ?attr/daxColorSurface ?attr/daxColorSurface + #00000000 false