From c3c7d495fe24034cf99dbd8953f53f63d153cbd1 Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Thu, 28 May 2020 13:53:18 +0200 Subject: [PATCH 1/9] removing bottom bar from browser screen --- app/src/main/AndroidManifest.xml | 4 - .../app/browser/BrowserTabFragment.kt | 175 +----------------- .../app/statistics/VariantManager.kt | 17 +- 3 files changed, 7 insertions(+), 189 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0a891e013a8e..615cb594fc4f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -234,10 +234,6 @@ android:name="com.duckduckgo.app.tabs.ui.TabSwitcherActivity" android:label="@string/tabActivityTitle" /> - - Date: Thu, 28 May 2020 14:02:07 +0200 Subject: [PATCH 2/9] removing references to bottom navigation layouts --- .../app/browser/BrowserPopupMenu.kt | 12 -- .../app/browser/BrowserTabFragment.kt | 12 -- .../app/browser/ui/BottomNavigationBar.kt | 76 ----------- .../browser/ui/BottomNavigationBehavior.kt | 119 ------------------ .../ui/TabSwitcherBottomBarFeatureActivity.kt | 10 -- .../main/res/layout/fragment_browser_tab.xml | 12 -- .../layout_browser_bottom_navigation_bar.xml | 70 ----------- 7 files changed, 311 deletions(-) delete mode 100644 app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBar.kt delete mode 100644 app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBehavior.kt delete mode 100644 app/src/main/res/layout/layout_browser_bottom_navigation_bar.xml diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt index fdc6992303ee..e4a83b2dd5db 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt @@ -62,19 +62,7 @@ class BrowserPopupMenu(layoutInflater: LayoutInflater, variant: Variant, view: V private const val margin = 30 fun inflate(layoutInflater: LayoutInflater, variant: Variant): View { - return if (variant.hasFeature(VariantManager.VariantFeature.BottomBarNavigation)) { - inflateBottomBarWithSearchFeature(layoutInflater) - } else { - inflateToolbarOnly(layoutInflater) - } - } - - private fun inflateToolbarOnly(layoutInflater: LayoutInflater): View { return layoutInflater.inflate(R.layout.popup_window_browser_menu, null) } - - private fun inflateBottomBarWithSearchFeature(layoutInflater: LayoutInflater): View { - return layoutInflater.inflate(R.layout.popup_window_browser_bottom_tab_menu, null) - } } } 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 74088b020b6d..11e99a24850c 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -110,8 +110,6 @@ import kotlinx.android.synthetic.main.include_omnibar_toolbar.view.browserMenu import kotlinx.android.synthetic.main.include_omnibar_toolbar.view.fireIconMenu import kotlinx.android.synthetic.main.include_omnibar_toolbar.view.privacyGradeButton import kotlinx.android.synthetic.main.include_omnibar_toolbar.view.tabsMenu -import kotlinx.android.synthetic.main.layout_browser_bottom_navigation_bar.* -import kotlinx.android.synthetic.main.popup_window_browser_bottom_tab_menu.view.* import kotlinx.android.synthetic.main.popup_window_browser_menu.view.* import kotlinx.android.synthetic.main.popup_window_browser_menu.view.addBookmarksPopupMenuItem import kotlinx.android.synthetic.main.popup_window_browser_menu.view.addToHome @@ -1261,7 +1259,6 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi createPopupMenuWithToolbarOnly() configureShowTabSwitcherListenerWithToolbarOnly() configureLongClickOpensNewTabListenerWithToolbarOnly() - removeUnnecessaryLayoutBehaviour() } private fun decorateAppBarWithToolbarOnly() { @@ -1326,23 +1323,14 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi } } - private fun removeUnnecessaryLayoutBehaviour() { - val params: CoordinatorLayout.LayoutParams = bottomNavigationBar.layoutParams as CoordinatorLayout.LayoutParams - params.behavior = null - } - fun animateTabsCount() { tabsButton?.animateCount() - bottomBarTabsItem.animateCount() } fun renderTabIcon(tabs: List) { context?.let { tabsButton?.count = tabs.count() tabsButton?.hasUnread = tabs.firstOrNull { !it.viewed } != null - - bottomBarTabsItem.count = tabs.count() - bottomBarTabsItem.hasUnread = tabs.firstOrNull { !it.viewed } != null } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBar.kt b/app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBar.kt deleted file mode 100644 index 944d2f4b2380..000000000000 --- a/app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBar.kt +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2020 DuckDuckGo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.duckduckgo.app.browser.ui - -import android.animation.ValueAnimator -import android.content.Context -import android.content.res.TypedArray -import android.util.AttributeSet -import android.view.View -import android.view.animation.DecelerateInterpolator -import android.widget.LinearLayout -import com.duckduckgo.app.browser.R - -class BottomNavigationBar : LinearLayout { - - constructor(context: Context) : super(context) { - init(context, null) - } - - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { - init(context, attrs) - } - - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super( - context, - attrs, - defStyleAttr - ) { - init(context, attrs) - } - - private fun init(context: Context, attrs: AttributeSet?) { - - val ta: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.BottomNavigationBar) - val resourceId = ta.getResourceId(R.styleable.BottomNavigationBar_layoutResource, R.layout.layout_browser_bottom_navigation_bar) - - ta.recycle() - - View.inflate(context, resourceId, this) - } - - fun onItemClicked(view: View, onClick: () -> Unit) { - view.setOnClickListener { - onClick() - } - } - - fun animateBarVisibility(isVisible: Boolean) { - val offsetAnimator = ValueAnimator().apply { - interpolator = DecelerateInterpolator() - duration = 150L - } - - offsetAnimator.addUpdateListener { - translationY = it.animatedValue as Float - } - - val targetTranslation = if (isVisible) 0f else height.toFloat() - offsetAnimator.setFloatValues(translationY, targetTranslation) - offsetAnimator.start() - } -} diff --git a/app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBehavior.kt b/app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBehavior.kt deleted file mode 100644 index a6192da9924c..000000000000 --- a/app/src/main/java/com/duckduckgo/app/browser/ui/BottomNavigationBehavior.kt +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2020 DuckDuckGo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.duckduckgo.app.browser.ui - -import android.animation.ValueAnimator -import android.content.Context -import android.util.AttributeSet -import android.view.Gravity -import android.view.View -import android.view.animation.DecelerateInterpolator -import androidx.coordinatorlayout.widget.CoordinatorLayout -import androidx.core.view.ViewCompat -import com.google.android.material.snackbar.Snackbar - -class BottomNavigationBehavior(context: Context, attrs: AttributeSet) : - CoordinatorLayout.Behavior(context, attrs) { - - @ViewCompat.NestedScrollType - private var lastStartedType: Int = 0 - - private var offsetAnimator: ValueAnimator? = null - - private var isSnappingEnabled = true - - override fun layoutDependsOn(parent: CoordinatorLayout, child: V, dependency: View): Boolean { - if (dependency is Snackbar.SnackbarLayout) { - updateSnackbar(child, dependency) - } - - return super.layoutDependsOn(parent, child, dependency) - } - - override fun onStartNestedScroll( - coordinatorLayout: CoordinatorLayout, - child: V, - directTargetChild: View, - target: View, - axes: Int, - type: Int - ): Boolean { - if (axes != ViewCompat.SCROLL_AXIS_VERTICAL) - return false - - lastStartedType = type - - offsetAnimator?.cancel() - - return true - } - - override fun onNestedPreScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) { - super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type) - child.translationY = kotlin.math.max(0f, kotlin.math.min(child.height.toFloat(), child.translationY + dy)) - } - - override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, type: Int) { - if (!isSnappingEnabled) - return - - if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) { - // find nearest seam - val currTranslation = child.translationY - val childHalfHeight = child.height * 0.5f - - // translate down - if (currTranslation >= childHalfHeight) { - animateBarVisibility(child, isVisible = false) - } - // translate up - else { - animateBarVisibility(child, isVisible = true) - } - } - } - - private fun animateBarVisibility(child: View, isVisible: Boolean) { - if (offsetAnimator == null) { - offsetAnimator = ValueAnimator().apply { - interpolator = DecelerateInterpolator() - duration = 150L - } - - offsetAnimator?.addUpdateListener { - child.translationY = it.animatedValue as Float - } - } else { - offsetAnimator?.cancel() - } - - val targetTranslation = if (isVisible) 0f else child.height.toFloat() - offsetAnimator?.setFloatValues(child.translationY, targetTranslation) - offsetAnimator?.start() - } - - private fun updateSnackbar(child: View, snackbarLayout: Snackbar.SnackbarLayout) { - if (snackbarLayout.layoutParams is CoordinatorLayout.LayoutParams) { - val params = snackbarLayout.layoutParams as CoordinatorLayout.LayoutParams - - params.anchorId = child.id - params.anchorGravity = Gravity.TOP - params.gravity = Gravity.TOP - snackbarLayout.layoutParams = params - } - } -} diff --git a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt index 1ff2a5e3141c..35a56b71f390 100644 --- a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt @@ -38,8 +38,6 @@ import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.Close import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.DisplayMessage import kotlinx.android.synthetic.main.activity_tab_switcher_bottom_bar_feature.tabsRecycler -import kotlinx.android.synthetic.main.fragment_browser_tab.bottomNavigationBar -import kotlinx.android.synthetic.main.layout_tabs_bottom_navigation_bar.* import kotlinx.android.synthetic.main.popup_window_browser_menu.view.settingsPopupMenuItem import kotlinx.android.synthetic.main.popup_window_tabs_menu.view.closeAllTabs import kotlinx.coroutines.CoroutineScope @@ -92,7 +90,6 @@ class TabSwitcherBottomBarFeatureActivity : DuckDuckGoActivity(), TabSwitcherLis extractIntentExtras() configureRecycler() configureObservers() - configureBottomBar() createPopUpMenu() } @@ -149,13 +146,6 @@ class TabSwitcherBottomBarFeatureActivity : DuckDuckGoActivity(), TabSwitcherLis } } - private fun configureBottomBar() { - bottomNavigationBar.apply { - onItemClicked(bottomBarNewTabItem) { onNewTabRequested() } - onItemClicked(bottomBarFireItem) { onFire() } - onItemClicked(bottomBarOverflowItem) { popupMenu.show(rootView, bottomNavigationBar) } - } - } private fun createPopUpMenu() { popupMenu = TabsPopupMenu(layoutInflater) diff --git a/app/src/main/res/layout/fragment_browser_tab.xml b/app/src/main/res/layout/fragment_browser_tab.xml index ef5f9e496c81..f82c111f81be 100644 --- a/app/src/main/res/layout/fragment_browser_tab.xml +++ b/app/src/main/res/layout/fragment_browser_tab.xml @@ -23,18 +23,6 @@ - - - - - - - - - - - - - - - - \ No newline at end of file From b868106fa49a329f6fe6fb65dbc2636fe66439f2 Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Thu, 28 May 2020 14:08:17 +0200 Subject: [PATCH 3/9] cleaning up decorator methods --- .../app/browser/BrowserTabFragment.kt | 36 +++++++++---------- .../duckduckgo/app/statistics/pixels/Pixel.kt | 1 - 2 files changed, 17 insertions(+), 20 deletions(-) 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 11e99a24850c..b8e198399ecf 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -42,8 +42,6 @@ import android.widget.TextView import androidx.annotation.AnyThread import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog -import androidx.constraintlayout.widget.ConstraintSet -import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.text.HtmlCompat @@ -93,7 +91,6 @@ import com.duckduckgo.app.survey.model.Survey import com.duckduckgo.app.survey.ui.SurveyActivity import com.duckduckgo.app.tabs.model.TabEntity import com.duckduckgo.app.tabs.ui.TabSwitcherActivity -import com.duckduckgo.app.tabs.ui.TabSwitcherBottomBarFeatureActivity import com.duckduckgo.app.widget.ui.AddWidgetInstructionsActivity import com.duckduckgo.widget.SearchWidgetLight import com.google.android.material.snackbar.Snackbar @@ -723,7 +720,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi } private fun decorateWithFeatures() { - decorator.decorateWithToolbar() + decorator.decorate() } private fun configurePrivacyGrade() { @@ -1244,24 +1241,25 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi } inner class BrowserTabFragmentDecorator { - fun decorateToolbar(viewState: BrowserViewState) { - decorator.decorateToolbarActions(viewState) + + fun decorate() { + decorateToolbarWithButtons() + createPopupMenu() + configureShowTabSwitcherListener() + configureLongClickOpensNewTabListener() + } + + fun decorateToolbarMenus(viewState: BrowserViewState) { + decorator.updateToolbarActionsVisibility(viewState) } - private fun decorateToolbarActions(viewState: BrowserViewState) { + private fun updateToolbarActionsVisibility(viewState: BrowserViewState) { tabsButton?.isVisible = viewState.showTabsButton fireMenuButton?.isVisible = viewState.showFireButton menuButton?.isVisible = viewState.showMenuButton } - fun decorateWithToolbar() { - decorateAppBarWithToolbarOnly() - createPopupMenuWithToolbarOnly() - configureShowTabSwitcherListenerWithToolbarOnly() - configureLongClickOpensNewTabListenerWithToolbarOnly() - } - - private fun decorateAppBarWithToolbarOnly() { + private fun decorateToolbarWithButtons() { fireMenuButton?.show() fireMenuButton?.setOnClickListener { browserActivity?.launchFire() @@ -1271,7 +1269,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi tabsButton?.show() } - private fun createPopupMenuWithToolbarOnly() { + private fun createPopupMenu() { popupMenu = BrowserPopupMenu(layoutInflater, variantManager.getVariant()) val view = popupMenu.contentView popupMenu.apply { @@ -1310,13 +1308,13 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi pixel.fire(String.format(Locale.US, Pixel.PixelName.MENU_ACTION_POPUP_OPENED.pixelName, variantManager.getVariant().key)) } - private fun configureShowTabSwitcherListenerWithToolbarOnly() { + private fun configureShowTabSwitcherListener() { tabsButton?.setOnClickListener { launch { viewModel.userLaunchingTabSwitcher() } } } - private fun configureLongClickOpensNewTabListenerWithToolbarOnly() { + private fun configureLongClickOpensNewTabListener() { tabsButton?.setOnLongClickListener { launch { viewModel.userRequestedOpeningNewTab() } return@setOnLongClickListener true @@ -1548,7 +1546,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi searchIcon?.isVisible = true } - decorator.decorateToolbar(viewState) + decorator.decorateToolbarMenus(viewState) } fun renderFindInPageState(viewState: FindInPageViewState) { diff --git a/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt b/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt index 4be178a2d6ff..9f8b18aacd05 100644 --- a/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt +++ b/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt @@ -174,7 +174,6 @@ interface Pixel { MENU_ACTION_REFRESH_PRESSED("m_nav_r_p_%s"), MENU_ACTION_NEW_TAB_PRESSED("m_nav_nt_p_%s"), MENU_ACTION_BOOKMARKS_PRESSED("m_nav_b_p_%s"), - MENU_ACTION_SEARCH_PRESSED("m_nav_s_p_%s"), COOKIE_DATABASE_NOT_FOUND("m_cdb_nf"), COOKIE_DATABASE_OPEN_ERROR("m_cdb_oe"), From 3ae0c3e0868a637bab87fa928bf62974aca52538 Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Thu, 28 May 2020 14:08:37 +0200 Subject: [PATCH 4/9] code cleanup --- .../main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt | 1 - .../main/java/com/duckduckgo/app/statistics/VariantManager.kt | 4 +--- .../app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt index e4a83b2dd5db..499174d6c93a 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserPopupMenu.kt @@ -25,7 +25,6 @@ import android.view.View import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.widget.PopupWindow import com.duckduckgo.app.statistics.Variant -import com.duckduckgo.app.statistics.VariantManager class BrowserPopupMenu(layoutInflater: LayoutInflater, variant: Variant, view: View = inflate(layoutInflater, variant)) : PopupWindow(view, WRAP_CONTENT, WRAP_CONTENT, true) { diff --git a/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt b/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt index d16a921098f2..fb076fbbcd0f 100644 --- a/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt +++ b/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt @@ -27,9 +27,7 @@ import java.util.* interface VariantManager { // variant-dependant features listed here - sealed class VariantFeature { - - } + sealed class VariantFeature companion object { diff --git a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt index 35a56b71f390..e24b311b4afb 100644 --- a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt @@ -146,7 +146,6 @@ class TabSwitcherBottomBarFeatureActivity : DuckDuckGoActivity(), TabSwitcherLis } } - private fun createPopUpMenu() { popupMenu = TabsPopupMenu(layoutInflater) val view = popupMenu.contentView From 9b38f7413654653548a11f813c89f63915d9d68b Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Thu, 28 May 2020 14:13:41 +0200 Subject: [PATCH 5/9] remove unnecessary tests --- .../app/statistics/VariantManagerTest.kt | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt b/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt index dfd7efdac9a6..f21e13bea35a 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt @@ -43,23 +43,6 @@ class VariantManagerTest { assertEquals(0, variant.features.size) } - // Bottom Bar Navigation Experiment - - @Test - fun bottomBarNavigationControlVariantIsActiveAndHasNoFeatures() { - val variant = variants.first { it.key == "mb" } - assertEqualsDouble(1.0, variant.weight) - assertEquals(0, variant.features.size) - } - - @Test - fun bottomBarNavigationVariantIsActiveAndHasBottomBarNavigationFeature() { - val variant = variants.first { it.key == "mk" } - assertEqualsDouble(1.0, variant.weight) - assertEquals(1, variant.features.size) - assertTrue(variant.hasFeature(BottomBarNavigation)) - } - @Test fun verifyNoDuplicateVariantNames() { val existingNames = mutableSetOf() From b6402a8bad85d963fe8e1f3adb16cb0507016142 Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Mon, 1 Jun 2020 10:09:54 +0200 Subject: [PATCH 6/9] this layout is no longer needed --- .../popup_window_browser_bottom_tab_menu.xml | 155 ------------------ 1 file changed, 155 deletions(-) delete mode 100644 app/src/main/res/layout/popup_window_browser_bottom_tab_menu.xml diff --git a/app/src/main/res/layout/popup_window_browser_bottom_tab_menu.xml b/app/src/main/res/layout/popup_window_browser_bottom_tab_menu.xml deleted file mode 100644 index a62062ebee55..000000000000 --- a/app/src/main/res/layout/popup_window_browser_bottom_tab_menu.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From ea7f0735534464e12fccd58f14b02f6d6fc29878 Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Mon, 1 Jun 2020 10:20:01 +0200 Subject: [PATCH 7/9] we no longer need to know the variant when sending this pixel --- .../com/duckduckgo/app/browser/BrowserTabFragment.kt | 10 +++++----- .../java/com/duckduckgo/app/statistics/pixels/Pixel.kt | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) 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 9bbe310c301d..1b81ea4c3953 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -1286,7 +1286,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi fireMenuButton?.show() fireMenuButton?.setOnClickListener { browserActivity?.launchFire() - pixel.fire(String.format(Locale.US, Pixel.PixelName.MENU_ACTION_FIRE_PRESSED.pixelName, variantManager.getVariant().key)) + pixel.fire(Pixel.PixelName.MENU_ACTION_FIRE_PRESSED.pixelName) } tabsButton?.show() @@ -1300,15 +1300,15 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi onMenuItemClicked(view.backPopupMenuItem) { activity?.onBackPressed() } onMenuItemClicked(view.refreshPopupMenuItem) { viewModel.onRefreshRequested() - pixel.fire(String.format(Locale.US, Pixel.PixelName.MENU_ACTION_REFRESH_PRESSED.pixelName, variantManager.getVariant().key)) + pixel.fire(Pixel.PixelName.MENU_ACTION_REFRESH_PRESSED.pixelName) } onMenuItemClicked(view.newTabPopupMenuItem) { viewModel.userRequestedOpeningNewTab() - pixel.fire(String.format(Locale.US, Pixel.PixelName.MENU_ACTION_NEW_TAB_PRESSED.pixelName, variantManager.getVariant().key)) + pixel.fire(Pixel.PixelName.MENU_ACTION_NEW_TAB_PRESSED.pixelName) } onMenuItemClicked(view.bookmarksPopupMenuItem) { browserActivity?.launchBookmarks() - pixel.fire(String.format(Locale.US, Pixel.PixelName.MENU_ACTION_BOOKMARKS_PRESSED.pixelName, variantManager.getVariant().key)) + pixel.fire(Pixel.PixelName.MENU_ACTION_BOOKMARKS_PRESSED.pixelName) } onMenuItemClicked(view.fireproofWebsitePopupMenuItem) { launch { viewModel.onFireproofWebsiteClicked() } } onMenuItemClicked(view.addBookmarksPopupMenuItem) { launch { viewModel.onBookmarkAddRequested() } } @@ -1328,7 +1328,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi private fun launchTopAnchoredPopupMenu() { popupMenu.show(rootView, toolbar) - pixel.fire(String.format(Locale.US, Pixel.PixelName.MENU_ACTION_POPUP_OPENED.pixelName, variantManager.getVariant().key)) + pixel.fire(Pixel.PixelName.MENU_ACTION_POPUP_OPENED.pixelName) } private fun configureShowTabSwitcherListener() { diff --git a/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt b/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt index 9f8b18aacd05..df914befcfbb 100644 --- a/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt +++ b/app/src/main/java/com/duckduckgo/app/statistics/pixels/Pixel.kt @@ -169,11 +169,11 @@ interface Pixel { CHANGE_APP_ICON_OPENED("m_ic"), - MENU_ACTION_POPUP_OPENED("m_nav_pm_o_%s"), - MENU_ACTION_FIRE_PRESSED("m_nav_f_p_%s"), - MENU_ACTION_REFRESH_PRESSED("m_nav_r_p_%s"), - MENU_ACTION_NEW_TAB_PRESSED("m_nav_nt_p_%s"), - MENU_ACTION_BOOKMARKS_PRESSED("m_nav_b_p_%s"), + MENU_ACTION_POPUP_OPENED("m_nav_pm_o"), + MENU_ACTION_FIRE_PRESSED("m_nav_f_p"), + MENU_ACTION_REFRESH_PRESSED("m_nav_r_p"), + MENU_ACTION_NEW_TAB_PRESSED("m_nav_nt_p"), + MENU_ACTION_BOOKMARKS_PRESSED("m_nav_b_p"), COOKIE_DATABASE_NOT_FOUND("m_cdb_nf"), COOKIE_DATABASE_OPEN_ERROR("m_cdb_oe"), From ee6afb412e8e15890d164cb930d01b15cc6af02a Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Wed, 3 Jun 2020 11:40:26 +0200 Subject: [PATCH 8/9] address code review comments --- .../app/browser/BrowserTabFragment.kt | 17 +- .../duckduckgo/app/di/AndroidBindingModule.kt | 1 - .../ui/TabSwitcherBottomBarFeatureActivity.kt | 234 ------------------ .../res/drawable/bottom_navigation_bar_bg.xml | 55 ---- ...tivity_tab_switcher_bottom_bar_feature.xml | 57 ----- .../layout_tabs_bottom_navigation_bar.xml | 74 ------ app/src/main/res/values/attrs.xml | 4 - app/src/main/res/values/dimens.xml | 2 - 8 files changed, 4 insertions(+), 440 deletions(-) delete mode 100644 app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt delete mode 100644 app/src/main/res/drawable/bottom_navigation_bar_bg.xml delete mode 100644 app/src/main/res/layout/activity_tab_switcher_bottom_bar_feature.xml delete mode 100644 app/src/main/res/layout/layout_tabs_bottom_navigation_bar.xml 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 1b81ea4c3953..863be7da1fe0 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -127,7 +127,6 @@ import org.jetbrains.anko.longToast import org.jetbrains.anko.share import timber.log.Timber import java.io.File -import java.util.* import javax.inject.Inject import kotlin.concurrent.thread import kotlin.coroutines.CoroutineContext @@ -294,7 +293,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi configureAutoComplete() configureKeyboardAwareLogoAnimation() - decorateWithFeatures() + decorator.decorateWithFeatures() animatorHelper.setListener(this) @@ -721,10 +720,6 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi autoCompleteSuggestionsList.adapter = autoCompleteSuggestionsAdapter } - private fun decorateWithFeatures() { - decorator.decorate() - } - private fun configurePrivacyGrade() { toolbar.privacyGradeButton.setOnClickListener { browserActivity?.launchPrivacyDashboard() @@ -1265,18 +1260,14 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi inner class BrowserTabFragmentDecorator { - fun decorate() { + fun decorateWithFeatures() { decorateToolbarWithButtons() createPopupMenu() configureShowTabSwitcherListener() configureLongClickOpensNewTabListener() } - fun decorateToolbarMenus(viewState: BrowserViewState) { - decorator.updateToolbarActionsVisibility(viewState) - } - - private fun updateToolbarActionsVisibility(viewState: BrowserViewState) { + fun updateToolbarActionsVisibility(viewState: BrowserViewState) { tabsButton?.isVisible = viewState.showTabsButton fireMenuButton?.isVisible = viewState.showFireButton menuButton?.isVisible = viewState.showMenuButton @@ -1569,7 +1560,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi searchIcon?.isVisible = true } - decorator.decorateToolbarMenus(viewState) + decorator.updateToolbarActionsVisibility(viewState) } fun renderFindInPageState(viewState: FindInPageViewState) { diff --git a/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt b/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt index 1ba4fbff7d64..6de2d9bd13ce 100644 --- a/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt +++ b/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt @@ -45,7 +45,6 @@ import com.duckduckgo.app.settings.SettingsActivity import com.duckduckgo.app.survey.ui.SurveyActivity import com.duckduckgo.app.systemsearch.SystemSearchActivity import com.duckduckgo.app.tabs.ui.TabSwitcherActivity -import com.duckduckgo.app.tabs.ui.TabSwitcherBottomBarFeatureActivity import com.duckduckgo.app.widget.ui.AddWidgetInstructionsActivity import dagger.Module import dagger.android.ContributesAndroidInjector diff --git a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt deleted file mode 100644 index e24b311b4afb..000000000000 --- a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherBottomBarFeatureActivity.kt +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2020 DuckDuckGo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.duckduckgo.app.tabs.ui - -import android.content.Context -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.view.Menu -import android.view.MenuItem -import androidx.lifecycle.Observer -import androidx.recyclerview.widget.GridLayoutManager -import androidx.recyclerview.widget.ItemTouchHelper -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.browser.tabpreview.WebViewPreviewPersister -import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.view.ClearPersonalDataAction -import com.duckduckgo.app.global.view.FireDialog -import com.duckduckgo.app.settings.SettingsActivity -import com.duckduckgo.app.statistics.VariantManager -import com.duckduckgo.app.statistics.pixels.Pixel -import com.duckduckgo.app.tabs.model.TabEntity -import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command -import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.Close -import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.DisplayMessage -import kotlinx.android.synthetic.main.activity_tab_switcher_bottom_bar_feature.tabsRecycler -import kotlinx.android.synthetic.main.popup_window_browser_menu.view.settingsPopupMenuItem -import kotlinx.android.synthetic.main.popup_window_tabs_menu.view.closeAllTabs -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch -import org.jetbrains.anko.longToast -import javax.inject.Inject -import kotlin.coroutines.CoroutineContext - -class TabSwitcherBottomBarFeatureActivity : DuckDuckGoActivity(), TabSwitcherListener, CoroutineScope { - - override val coroutineContext: CoroutineContext - get() = SupervisorJob() + Dispatchers.Main - - @Inject - lateinit var clearPersonalDataAction: ClearPersonalDataAction - - @Inject - lateinit var variantManager: VariantManager - - @Inject - lateinit var gridViewColumnCalculator: GridViewColumnCalculator - - @Inject - lateinit var webViewPreviewPersister: WebViewPreviewPersister - - @Inject - lateinit var pixel: Pixel - - private val viewModel: TabSwitcherViewModel by bindViewModel() - - private val tabsAdapter: TabSwitcherAdapter by lazy { TabSwitcherAdapter(this, webViewPreviewPersister) } - - // we need to scroll to show selected tab, but only if it is the first time loading the tabs. - private var firstTimeLoadingTabsList = true - - private var selectedTabId: String? = null - - private lateinit var popupMenu: TabsPopupMenu - - private lateinit var tabGridItemDecorator: TabGridItemDecorator - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - window.statusBarColor = Color.TRANSPARENT - - setContentView(R.layout.activity_tab_switcher_bottom_bar_feature) - extractIntentExtras() - configureRecycler() - configureObservers() - createPopUpMenu() - - } - - private fun extractIntentExtras() { - selectedTabId = intent.getStringExtra(EXTRA_KEY_SELECTED_TAB) - } - - private fun configureRecycler() { - val numberColumns = gridViewColumnCalculator.calculateNumberOfColumns(TAB_GRID_COLUMN_WIDTH_DP, TAB_GRID_MAX_COLUMN_COUNT) - val layoutManager = GridLayoutManager(this, numberColumns) - tabsRecycler.layoutManager = layoutManager - tabsRecycler.adapter = tabsAdapter - - val swipeListener = ItemTouchHelper(SwipeToCloseTabListener(tabsAdapter, numberColumns, object : SwipeToCloseTabListener.OnTabSwipedListener { - override fun onSwiped(tab: TabEntity) { - onTabDeleted(tab) - } - })) - swipeListener.attachToRecyclerView(tabsRecycler) - - tabGridItemDecorator = TabGridItemDecorator(this, selectedTabId) - tabsRecycler.addItemDecoration(tabGridItemDecorator) - } - - private fun configureObservers() { - viewModel.tabs.observe(this, Observer> { - render(it) - }) - viewModel.command.observe(this, Observer { - processCommand(it) - }) - } - - private fun render(tabs: List) { - tabsAdapter.updateData(tabs) - - if (firstTimeLoadingTabsList) { - firstTimeLoadingTabsList = false - - scrollToShowCurrentTab() - } - } - - private fun scrollToShowCurrentTab() { - val index = tabsAdapter.adapterPositionForTab(selectedTabId) - tabsRecycler.scrollToPosition(index) - } - - private fun processCommand(command: Command?) { - when (command) { - is DisplayMessage -> applicationContext?.longToast(command.messageId) - is Close -> finishAfterTransition() - } - } - - private fun createPopUpMenu() { - popupMenu = TabsPopupMenu(layoutInflater) - val view = popupMenu.contentView - popupMenu.apply { - onMenuItemClicked(view.closeAllTabs) { closeAllTabs() } - onMenuItemClicked(view.settingsPopupMenuItem) { showSettings() } - } - } - - override fun onCreateOptionsMenu(menu: Menu?): Boolean { - menuInflater.inflate(R.menu.menu_tab_switcher_activity, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.fire -> onFire() - R.id.newTab, R.id.newTabOverflow -> onNewTabRequested() - R.id.closeAllTabs -> closeAllTabs() - R.id.settings -> showSettings() - } - return super.onOptionsItemSelected(item) - } - - private fun onFire() { - pixel.fire(Pixel.PixelName.FORGET_ALL_PRESSED_TABSWITCHING) - val dialog = FireDialog(context = this, clearPersonalDataAction = clearPersonalDataAction) - dialog.clearComplete = { viewModel.onClearComplete() } - dialog.show() - } - - override fun onNewTabRequested() { - clearObserversEarlyToStopViewUpdates() - launch { viewModel.onNewTabRequested() } - } - - override fun onTabSelected(tab: TabEntity) { - selectedTabId = tab.tabId - updateTabGridItemDecorator(tab) - launch { viewModel.onTabSelected(tab) } - } - - private fun updateTabGridItemDecorator(tab: TabEntity) { - tabGridItemDecorator.selectedTabId = tab.tabId - tabsRecycler.invalidateItemDecorations() - } - - override fun onTabDeleted(tab: TabEntity) { - launch { viewModel.onTabDeleted(tab) } - } - - private fun closeAllTabs() { - launch { - viewModel.tabs.value?.forEach { - viewModel.onTabDeleted(it) - } - } - } - - private fun showSettings() { - startActivity(SettingsActivity.intent(this)) - } - - override fun finish() { - clearObserversEarlyToStopViewUpdates() - super.finish() - overridePendingTransition(R.anim.slide_from_bottom, R.anim.tab_anim_fade_out) - } - - private fun clearObserversEarlyToStopViewUpdates() { - viewModel.tabs.removeObservers(this) - } - - companion object { - fun intent(context: Context, selectedTabId: String? = null): Intent { - val intent = Intent(context, TabSwitcherBottomBarFeatureActivity::class.java) - intent.putExtra(EXTRA_KEY_SELECTED_TAB, selectedTabId) - return intent - } - - const val EXTRA_KEY_SELECTED_TAB = "selected" - - private const val TAB_GRID_COLUMN_WIDTH_DP = 180 - private const val TAB_GRID_MAX_COLUMN_COUNT = 4 - } -} diff --git a/app/src/main/res/drawable/bottom_navigation_bar_bg.xml b/app/src/main/res/drawable/bottom_navigation_bar_bg.xml deleted file mode 100644 index 79bff523c7a4..000000000000 --- a/app/src/main/res/drawable/bottom_navigation_bar_bg.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_tab_switcher_bottom_bar_feature.xml b/app/src/main/res/layout/activity_tab_switcher_bottom_bar_feature.xml deleted file mode 100644 index e6e198c10774..000000000000 --- a/app/src/main/res/layout/activity_tab_switcher_bottom_bar_feature.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/layout/layout_tabs_bottom_navigation_bar.xml b/app/src/main/res/layout/layout_tabs_bottom_navigation_bar.xml deleted file mode 100644 index 0836958417d1..000000000000 --- a/app/src/main/res/layout/layout_tabs_bottom_navigation_bar.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index af0e95853018..a96851ddc505 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -70,8 +70,4 @@ - - - - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 80b525be6dca..a17b74e8c2ac 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -36,6 +36,4 @@ 4dp 75dp - 48dp - \ No newline at end of file From 95d15701094aa62bf969b74aa09aaf41adc21c12 Mon Sep 17 00:00:00 2001 From: David Gonzalez Date: Wed, 3 Jun 2020 11:47:43 +0200 Subject: [PATCH 9/9] cleaning up missing reference --- .../main/java/com/duckduckgo/app/di/AndroidBindingModule.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt b/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt index 6de2d9bd13ce..2ab2a5da3efa 100644 --- a/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt +++ b/app/src/main/java/com/duckduckgo/app/di/AndroidBindingModule.kt @@ -74,10 +74,6 @@ abstract class AndroidBindingModule { @ContributesAndroidInjector abstract fun tabsActivity(): TabSwitcherActivity - @ActivityScoped - @ContributesAndroidInjector - abstract fun tabsExperimentActivity(): TabSwitcherBottomBarFeatureActivity - @ActivityScoped @ContributesAndroidInjector abstract fun privacyDashboardActivity(): PrivacyDashboardActivity