Skip to content

Commit 0bb063a

Browse files
committed
Add TabManager mode to the navigation bar
1 parent 5a5234f commit 0bb063a

File tree

12 files changed

+435
-131
lines changed

12 files changed

+435
-131
lines changed

app/src/main/java/com/duckduckgo/app/appearance/AppearanceActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,9 @@ class AppearanceActivity : DuckDuckGoActivity() {
200200
val subtitle =
201201
getString(
202202
when (omnibarType) {
203-
OmnibarType.SINGLE_TOP, OmnibarType.SPLIT -> R.string.settingsAddressBarPositionTop
203+
OmnibarType.SINGLE_TOP -> R.string.settingsAddressBarPositionTop
204204
OmnibarType.SINGLE_BOTTOM -> R.string.settingsAddressBarPositionBottom
205+
OmnibarType.SPLIT -> throw IllegalStateException("Split omnibar not supported in the position selection settings")
205206
},
206207
)
207208
binding.addressBarPositionSetting.setSecondaryText(subtitle)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,9 @@ open class BrowserActivity : DuckDuckGoActivity() {
765765

766766
val anchorView =
767767
when (settingsDataStore.omnibarType) {
768-
OmnibarType.SINGLE_TOP, OmnibarType.SPLIT -> null
768+
OmnibarType.SINGLE_TOP -> null
769769
OmnibarType.SINGLE_BOTTOM -> currentTab?.getOmnibar()?.omnibarView?.toolbar ?: binding.fragmentContainer
770+
OmnibarType.SPLIT -> currentTab?.getBottomNavigationBar() ?: binding.fragmentContainer
770771
}
771772
DefaultSnackbar(
772773
parentView = binding.fragmentContainer,

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

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ import com.duckduckgo.app.browser.model.BasicAuthenticationRequest
142142
import com.duckduckgo.app.browser.model.LongPressTarget
143143
import com.duckduckgo.app.browser.navigation.bar.BrowserNavigationBarViewIntegration
144144
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarObserver
145+
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarView
145146
import com.duckduckgo.app.browser.newtab.NewTabPageProvider
146147
import com.duckduckgo.app.browser.omnibar.Omnibar
147148
import com.duckduckgo.app.browser.omnibar.Omnibar.FindInPageListener
@@ -1174,18 +1175,6 @@ class BrowserTabFragment :
11741175
onBrowserMenuButtonPressed()
11751176
}
11761177

1177-
override fun onBackButtonClicked() {
1178-
onBackArrowClicked()
1179-
}
1180-
1181-
override fun onBackButtonLongClicked() {
1182-
onBackArrowLongClicked()
1183-
}
1184-
1185-
override fun onForwardButtonClicked() {
1186-
onForwardArrowClicked()
1187-
}
1188-
11891178
override fun onNewTabButtonClicked() {
11901179
viewModel.onNavigationBarNewTabButtonClicked()
11911180
}
@@ -1986,6 +1975,10 @@ class BrowserTabFragment :
19861975
}
19871976
}
19881977

1978+
fun getBottomNavigationBar(): BrowserNavigationBarView {
1979+
return binding.navigationBar
1980+
}
1981+
19891982
private fun processCommand(it: Command?) {
19901983
if (it is NavigationCommand) {
19911984
omnibar.cancelTrackersAnimation()

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,6 @@ interface BrowserNavigationBarObserver {
3535
fun onMenuButtonClicked() {
3636
}
3737

38-
@EmptySuper
39-
fun onBackButtonClicked() {
40-
}
41-
42-
@EmptySuper
43-
fun onBackButtonLongClicked() {
44-
}
45-
46-
@EmptySuper
47-
fun onForwardButtonClicked() {
48-
}
49-
5038
@EmptySuper
5139
fun onNewTabButtonClicked() {
5240
}

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,8 @@ import com.duckduckgo.app.browser.PulseAnimation
3636
import com.duckduckgo.app.browser.databinding.ViewBrowserNavigationBarBinding
3737
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command
3838
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyAutofillButtonClicked
39-
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyBackButtonClicked
40-
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyBackButtonLongClicked
4139
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyBookmarksButtonClicked
4240
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyFireButtonClicked
43-
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyForwardButtonClicked
4441
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyMenuButtonClicked
4542
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyNewTabButtonClicked
4643
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarViewModel.Command.NotifyTabsButtonClicked
@@ -208,9 +205,6 @@ class BrowserNavigationBarView @JvmOverloads constructor(
208205
NotifyTabsButtonClicked -> browserNavigationBarObserver?.onTabsButtonClicked()
209206
NotifyTabsButtonLongClicked -> browserNavigationBarObserver?.onTabsButtonLongClicked()
210207
NotifyMenuButtonClicked -> browserNavigationBarObserver?.onMenuButtonClicked()
211-
NotifyBackButtonClicked -> browserNavigationBarObserver?.onBackButtonClicked()
212-
NotifyBackButtonLongClicked -> browserNavigationBarObserver?.onBackButtonLongClicked()
213-
NotifyForwardButtonClicked -> browserNavigationBarObserver?.onForwardButtonClicked()
214208
NotifyBookmarksButtonClicked -> browserNavigationBarObserver?.onBookmarksButtonClicked()
215209
NotifyNewTabButtonClicked -> browserNavigationBarObserver?.onNewTabButtonClicked()
216210
NotifyAutofillButtonClicked -> browserNavigationBarObserver?.onAutofillButtonClicked()
@@ -232,12 +226,13 @@ class BrowserNavigationBarView @JvmOverloads constructor(
232226
enum class ViewMode {
233227
NewTab,
234228
Browser,
229+
TabManager,
235230
}
236231

237232
/**
238233
* Behavior that offsets the navigation bar proportionally to the offset of the top omnibar.
239234
*/
240-
private class BottomViewBehavior(
235+
inner class BottomViewBehavior(
241236
context: Context,
242237
attrs: AttributeSet?,
243238
) : Behavior<View>(context, attrs) {

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ class BrowserNavigationBarViewModel @Inject constructor(
122122
it.copy(
123123
newTabButtonVisible = false,
124124
autofillButtonVisible = true,
125-
fireButtonVisible = true,
126-
tabsButtonVisible = true,
127125
)
128126
}
129127
}
@@ -133,8 +131,17 @@ class BrowserNavigationBarViewModel @Inject constructor(
133131
it.copy(
134132
newTabButtonVisible = true,
135133
autofillButtonVisible = false,
136-
fireButtonVisible = true,
137-
tabsButtonVisible = true,
134+
)
135+
}
136+
}
137+
138+
ViewMode.TabManager -> {
139+
_viewState.update {
140+
it.copy(
141+
newTabButtonVisible = true,
142+
autofillButtonVisible = false,
143+
tabsButtonVisible = false,
144+
bookmarksButtonVisible = false,
138145
)
139146
}
140147
}
@@ -154,9 +161,6 @@ class BrowserNavigationBarViewModel @Inject constructor(
154161
data object NotifyTabsButtonClicked : Command()
155162
data object NotifyTabsButtonLongClicked : Command()
156163
data object NotifyMenuButtonClicked : Command()
157-
data object NotifyBackButtonClicked : Command()
158-
data object NotifyBackButtonLongClicked : Command()
159-
data object NotifyForwardButtonClicked : Command()
160164
data object NotifyNewTabButtonClicked : Command()
161165
data object NotifyAutofillButtonClicked : Command()
162166
data object NotifyBookmarksButtonClicked : Command()

app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ import com.duckduckgo.app.browser.R
4242
import com.duckduckgo.app.browser.databinding.ActivityTabSwitcherBinding
4343
import com.duckduckgo.app.browser.databinding.PopupTabsMenuBinding
4444
import com.duckduckgo.app.browser.favicon.FaviconManager
45+
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarObserver
46+
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarView
4547
import com.duckduckgo.app.browser.tabpreview.WebViewPreviewPersister
4648
import com.duckduckgo.app.di.AppCoroutineScope
4749
import com.duckduckgo.app.downloads.DownloadsActivity
@@ -50,7 +52,6 @@ import com.duckduckgo.app.global.events.db.UserEventsStore
5052
import com.duckduckgo.app.global.view.ClearDataAction
5153
import com.duckduckgo.app.global.view.FireDialog
5254
import com.duckduckgo.app.onboardingdesignexperiment.OnboardingDesignExperimentManager
53-
import com.duckduckgo.app.pixels.AppPixelName
5455
import com.duckduckgo.app.settings.SettingsActivity
5556
import com.duckduckgo.app.settings.clear.OnboardingExperimentFireAnimationHelper
5657
import com.duckduckgo.app.settings.db.SettingsDataStore
@@ -72,8 +73,8 @@ import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.ShareLinks
7273
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.ShowAnimatedTileDismissalDialog
7374
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.ShowUndoBookmarkMessage
7475
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command.ShowUndoDeleteTabsMessage
75-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.Mode
76-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.Mode.Selection
76+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.Mode
77+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.Mode.Selection
7778
import com.duckduckgo.appbuildconfig.api.AppBuildConfig
7879
import com.duckduckgo.browser.ui.omnibar.OmnibarType
7980
import com.duckduckgo.common.ui.DuckDuckGoActivity
@@ -224,8 +225,7 @@ class TabSwitcherActivity :
224225
null
225226
}
226227
OmnibarType.SPLIT -> {
227-
null
228-
// TODO: add bottom bar
228+
binding.navigationBar
229229
}
230230
}
231231
}
@@ -244,13 +244,32 @@ class TabSwitcherActivity :
244244
configureViewReferences()
245245
setupToolbar(toolbar)
246246
configureRecycler()
247+
configureNavigationBar()
247248

248249
configureObservers()
249250
configureOnBackPressedListener()
250251

251252
initMenuClickListeners()
252253
}
253254

255+
private fun configureNavigationBar() {
256+
binding.navigationBar.browserNavigationBarObserver =
257+
object : BrowserNavigationBarObserver {
258+
override fun onMenuButtonClicked() {
259+
showPopupMenu(binding.navigationBar.popupMenuAnchor.id)
260+
}
261+
262+
override fun onNewTabButtonClicked() {
263+
viewModel.onNewTabRequested()
264+
}
265+
266+
override fun onFireButtonClicked() {
267+
viewModel.onFireButtonTapped()
268+
}
269+
}
270+
binding.navigationBar.setViewMode(BrowserNavigationBarView.ViewMode.TabManager)
271+
}
272+
254273
override fun onSaveInstanceState(outState: Bundle) {
255274
super.onSaveInstanceState(outState)
256275

@@ -267,11 +286,9 @@ class TabSwitcherActivity :
267286
when (settingsDataStore.omnibarType) {
268287
OmnibarType.SINGLE_TOP -> {
269288
binding.root.removeView(binding.tabSwitcherToolbarBottom.root)
270-
// TODO: remove bottom bar
271289
}
272290
OmnibarType.SINGLE_BOTTOM -> {
273291
binding.root.removeView(binding.tabSwitcherToolbarTop.root)
274-
// TODO: remove bottom bar
275292
}
276293
OmnibarType.SPLIT -> {
277294
binding.root.removeView(binding.tabSwitcherToolbarBottom.root)
@@ -392,7 +409,7 @@ class TabSwitcherActivity :
392409

393410
private fun configureObservers() {
394411
lifecycleScope.launch {
395-
viewModel.selectionViewState.flowWithLifecycle(lifecycle).collectLatest {
412+
viewModel.viewState.flowWithLifecycle(lifecycle).collectLatest {
396413
tabsRecycler.invalidateItemDecorations()
397414
tabsAdapter.updateData(it.tabSwitcherItems)
398415

@@ -546,6 +563,7 @@ class TabSwitcherActivity :
546563
is ShowUndoDeleteTabsMessage -> showTabsDeletedSnackbar(command.tabIds)
547564
ShowAnimatedTileDismissalDialog -> showAnimatedTileDismissalDialog()
548565
DismissAnimatedTileDismissalDialog -> tabSwitcherAnimationTileRemovalDialog!!.dismiss()
566+
Command.ShowFireBottomSheet -> onFireButtonClicked()
549567
}
550568
}
551569

@@ -566,14 +584,15 @@ class TabSwitcherActivity :
566584
menuInflater.inflate(R.menu.menu_tab_switcher_activity, menu)
567585

568586
val popupBinding = PopupTabsMenuBinding.bind(popupMenu.contentView)
569-
val viewState = viewModel.selectionViewState.value
587+
val viewState = viewModel.viewState.value
570588

571-
val numSelectedTabs = viewModel.selectionViewState.value.numSelectedTabs
589+
val numSelectedTabs = viewModel.viewState.value.numSelectedTabs
572590
menu.createDynamicInterface(
573591
numSelectedTabs = numSelectedTabs,
574592
popupMenu = popupBinding,
575593
toolbar = toolbar,
576594
dynamicMenu = viewState.dynamicInterface,
595+
navigationBar = binding.navigationBar,
577596
)
578597

579598
return true
@@ -598,7 +617,7 @@ class TabSwitcherActivity :
598617

599618
override fun onOptionsItemSelected(item: MenuItem): Boolean {
600619
when (item.itemId) {
601-
R.id.fireToolbarButton -> onFireButtonClicked()
620+
R.id.fireToolbarButton -> viewModel.onFireButtonTapped()
602621
R.id.popupMenuToolbarButton -> showPopupMenu(item.itemId)
603622
R.id.newTabToolbarButton -> onNewTabRequested(fromOverflowMenu = false)
604623
R.id.duckAIToolbarButton -> viewModel.onDuckAIButtonClicked()
@@ -627,7 +646,6 @@ class TabSwitcherActivity :
627646
}
628647

629648
private fun onFireButtonClicked() {
630-
pixel.fire(AppPixelName.FORGET_ALL_PRESSED_TABSWITCHING)
631649
val dialog =
632650
FireDialog(
633651
context = this,
@@ -932,5 +950,6 @@ class TabSwitcherActivity :
932950
private const val KEY_FIRST_TIME_LOADING = "FIRST_TIME_LOADING"
933951
private const val FAB_SCROLL_THRESHOLD = 7
934952
private const val TABS_CONTENT_PADDING_DP = 56
953+
private const val NAVIGATION_BAR_HEIGHT_DP = 60
935954
}
936955
}

app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherMenuExt.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@ import androidx.appcompat.widget.Toolbar
2222
import androidx.core.view.isVisible
2323
import com.duckduckgo.app.browser.R
2424
import com.duckduckgo.app.browser.databinding.PopupTabsMenuBinding
25-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.BackButtonType.ARROW
26-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.BackButtonType.CLOSE
27-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.DynamicInterface
28-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.LayoutMode.GRID
29-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.LayoutMode.HIDDEN
30-
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.SelectionViewState.LayoutMode.LIST
25+
import com.duckduckgo.app.browser.navigation.bar.view.BrowserNavigationBarView
26+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.BackButtonType.ARROW
27+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.BackButtonType.CLOSE
28+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.DynamicInterface
29+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.LayoutMode.GRID
30+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.LayoutMode.HIDDEN
31+
import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.ViewState.LayoutMode.LIST
3132
import com.duckduckgo.mobile.android.R as commonR
3233

3334
fun Menu.createDynamicInterface(
3435
numSelectedTabs: Int,
3536
popupMenu: PopupTabsMenuBinding,
3637
toolbar: Toolbar,
3738
dynamicMenu: DynamicInterface,
39+
navigationBar: BrowserNavigationBarView,
3840
) {
3941
popupMenu.selectAllMenuItem.isVisible = dynamicMenu.isSelectAllVisible
4042
popupMenu.deselectAllMenuItem.isVisible = dynamicMenu.isDeselectAllVisible
@@ -94,4 +96,7 @@ fun Menu.createDynamicInterface(
9496
findItem(R.id.fireToolbarButton).isVisible = dynamicMenu.isFireButtonVisible
9597
findItem(R.id.duckAIToolbarButton).isVisible = dynamicMenu.isDuckAIButtonVisible
9698
findItem(R.id.newTabToolbarButton).isVisible = dynamicMenu.isNewTabButtonVisible
99+
findItem(R.id.popupMenuToolbarButton).isVisible = dynamicMenu.isMenuButtonVisible
100+
101+
navigationBar.isVisible = dynamicMenu.isBottomBarVisible
97102
}

0 commit comments

Comments
 (0)