2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-17 15:26:23 +00:00

Bug 1823848 - Part 2: Add SearchSelectorMenuBinding to handle updating the menu items of the search selector menu

This commit is contained in:
Gabriel Luong 2023-03-22 02:17:21 -04:00 committed by mergify[bot]
parent 951e02b6fe
commit 0938c42e41
2 changed files with 74 additions and 35 deletions

View File

@ -21,7 +21,6 @@ import android.widget.PopupWindow
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
@ -42,17 +41,13 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.components.browser.menu.view.MenuButton import mozilla.components.browser.menu.view.MenuButton
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.selector.normalTabs import mozilla.components.browser.state.selector.normalTabs
import mozilla.components.browser.state.selector.privateTabs import mozilla.components.browser.state.selector.privateTabs
import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.state.searchEngines
import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.menu.candidate.DrawableMenuIcon
import mozilla.components.concept.menu.candidate.TextMenuCandidate
import mozilla.components.concept.storage.FrecencyThresholdOption import mozilla.components.concept.storage.FrecencyThresholdOption
import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.AuthType
@ -66,12 +61,10 @@ import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.service.glean.private.NoExtras import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.Config import org.mozilla.fenix.Config
import org.mozilla.fenix.GleanMetrics.HomeScreen import org.mozilla.fenix.GleanMetrics.HomeScreen
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcutCfr import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcutCfr
import org.mozilla.fenix.GleanMetrics.UnifiedSearch
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.addons.showSnackBar import org.mozilla.fenix.addons.showSnackBar
@ -111,6 +104,7 @@ import org.mozilla.fenix.home.sessioncontrol.SessionControlView
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder
import org.mozilla.fenix.home.toolbar.DefaultToolbarController import org.mozilla.fenix.home.toolbar.DefaultToolbarController
import org.mozilla.fenix.home.toolbar.SearchSelectorBinding import org.mozilla.fenix.home.toolbar.SearchSelectorBinding
import org.mozilla.fenix.home.toolbar.SearchSelectorMenuBinding
import org.mozilla.fenix.home.topsites.DefaultTopSitesView import org.mozilla.fenix.home.topsites.DefaultTopSitesView
import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.onboarding.FenixOnboarding import org.mozilla.fenix.onboarding.FenixOnboarding
@ -211,6 +205,7 @@ class HomeFragment : Fragment() {
private val recentBookmarksFeature = ViewBoundFeatureWrapper<RecentBookmarksFeature>() private val recentBookmarksFeature = ViewBoundFeatureWrapper<RecentBookmarksFeature>()
private val historyMetadataFeature = ViewBoundFeatureWrapper<RecentVisitsFeature>() private val historyMetadataFeature = ViewBoundFeatureWrapper<RecentVisitsFeature>()
private val searchSelectorBinding = ViewBoundFeatureWrapper<SearchSelectorBinding>() private val searchSelectorBinding = ViewBoundFeatureWrapper<SearchSelectorBinding>()
private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>()
@VisibleForTesting @VisibleForTesting
internal var getMenuButton: () -> MenuButton? = { binding.menuButton } internal var getMenuButton: () -> MenuButton? = { binding.menuButton }
@ -616,13 +611,16 @@ class HomeFragment : Fragment() {
view = binding.root, view = binding.root,
) )
consumeFlow(requireComponents.core.store) { flow -> searchSelectorMenuBinding.set(
flow.map { state -> state.search } feature = SearchSelectorMenuBinding(
.ifChanged() context = view.context,
.collect { search -> interactor = sessionControlInteractor,
updateSearchSelectorMenu(search.searchEngines) searchSelectorMenu = searchSelectorMenu,
} browserStore = requireComponents.core.store,
} ),
owner = viewLifecycleOwner,
view = view,
)
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL! // DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
requireComponents.core.engine.profiler?.addMarker( requireComponents.core.engine.profiler?.addMarker(
@ -632,27 +630,6 @@ class HomeFragment : Fragment() {
) )
} }
private fun updateSearchSelectorMenu(searchEngines: List<SearchEngine>) {
val searchEngineList = searchEngines
.map {
TextMenuCandidate(
text = it.name,
start = DrawableMenuIcon(
drawable = it.icon.toDrawable(resources),
tint = if (it.type == SearchEngine.Type.APPLICATION) {
requireContext().getColorFromAttr(R.attr.textPrimary)
} else {
null
},
),
) {
sessionControlInteractor.onMenuItemTapped(SearchSelectorMenu.Item.SearchEngine(it))
}
}
searchSelectorMenu.menuController.submitList(searchSelectorMenu.menuItems(searchEngineList))
}
/** /**
* Method used to listen to search engine name changes and trigger a top sites update accordingly * Method used to listen to search engine name changes and trigger a top sites update accordingly
*/ */

View File

@ -0,0 +1,62 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.home.toolbar
import android.content.Context
import androidx.core.graphics.drawable.toDrawable
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.searchEngines
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.menu.candidate.DrawableMenuIcon
import mozilla.components.concept.menu.candidate.TextMenuCandidate
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.search.toolbar.SearchSelectorInteractor
import org.mozilla.fenix.search.toolbar.SearchSelectorMenu
/**
* A binding that updates the search engine menu items in the search selector menu.
*/
class SearchSelectorMenuBinding(
private val context: Context,
private val interactor: SearchSelectorInteractor,
private val searchSelectorMenu: SearchSelectorMenu,
browserStore: BrowserStore,
) : AbstractBinding<BrowserState>(browserStore) {
override suspend fun onState(flow: Flow<BrowserState>) {
flow.map { state -> state.search }
.ifChanged()
.collect { search ->
updateSearchSelectorMenu(search.searchEngines)
}
}
private fun updateSearchSelectorMenu(searchEngines: List<SearchEngine>) {
val searchEngineList = searchEngines
.map {
TextMenuCandidate(
text = it.name,
start = DrawableMenuIcon(
drawable = it.icon.toDrawable(context.resources),
tint = if (it.type == SearchEngine.Type.APPLICATION) {
context.getColorFromAttr(R.attr.textPrimary)
} else {
null
},
),
) {
interactor.onMenuItemTapped(SearchSelectorMenu.Item.SearchEngine(it))
}
}
searchSelectorMenu.menuController.submitList(searchSelectorMenu.menuItems(searchEngineList))
}
}