From c4cc2ad7c434db2bf67e61e4dad6258118a47e20 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Tue, 21 Mar 2023 16:14:22 -0400 Subject: [PATCH] Bug 1823848 - Part 1: Add SearchSelectorBinding to handle updating the search engine displayed in the search selector button --- .../java/org/mozilla/fenix/home/HomeFragment.kt | 63 ++++------------- .../fenix/home/toolbar/SearchSelectorBinding.kt | 82 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 50 deletions(-) create mode 100644 mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/toolbar/SearchSelectorBinding.kt diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 673bdb193c98..834c0348c433 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -7,7 +7,6 @@ package org.mozilla.fenix.home import android.annotation.SuppressLint import android.content.res.ColorStateList import android.content.res.Configuration -import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.ColorDrawable import android.net.Uri import android.os.Bundle @@ -23,7 +22,6 @@ import androidx.annotation.VisibleForTesting import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.toDrawable -import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -53,7 +51,6 @@ 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.store.BrowserStore -import mozilla.components.concept.menu.Orientation import mozilla.components.concept.menu.candidate.DrawableMenuIcon import mozilla.components.concept.menu.candidate.TextMenuCandidate import mozilla.components.concept.storage.FrecencyThresholdOption @@ -113,6 +110,7 @@ import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor import org.mozilla.fenix.home.sessioncontrol.SessionControlView import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder import org.mozilla.fenix.home.toolbar.DefaultToolbarController +import org.mozilla.fenix.home.toolbar.SearchSelectorBinding import org.mozilla.fenix.home.topsites.DefaultTopSitesView import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.onboarding.FenixOnboarding @@ -212,6 +210,7 @@ class HomeFragment : Fragment() { private val recentSyncedTabFeature = ViewBoundFeatureWrapper() private val recentBookmarksFeature = ViewBoundFeatureWrapper() private val historyMetadataFeature = ViewBoundFeatureWrapper() + private val searchSelectorBinding = ViewBoundFeatureWrapper() @VisibleForTesting internal var getMenuButton: () -> MenuButton? = { binding.menuButton } @@ -363,27 +362,6 @@ class HomeFragment : Fragment() { ) } - requireContext().settings().showUnifiedSearchFeature.let { - binding.searchSelectorButton.isVisible = it - binding.searchEngineIcon.isGone = it - } - - binding.searchSelectorButton.apply { - setOnClickListener { - val orientation = if (context.settings().shouldUseBottomToolbar) { - Orientation.UP - } else { - Orientation.DOWN - } - - UnifiedSearch.searchMenuTapped.record(NoExtras()) - searchSelectorMenu.menuController.show( - anchor = it.findViewById(R.id.search_selector), - orientation = orientation, - ) - } - } - _sessionControlInteractor = SessionControlInteractor( controller = DefaultSessionControlController( activity = activity, @@ -557,7 +535,6 @@ class HomeFragment : Fragment() { HomeScreen.homeScreenDisplayed.record(NoExtras()) HomeScreen.homeScreenViewCount.add() - observeSearchEngineChanges() observeSearchEngineNameChanges() observeWallpaperUpdates() @@ -628,6 +605,17 @@ class HomeFragment : Fragment() { } } + searchSelectorBinding.set( + feature = SearchSelectorBinding( + context = view.context, + binding = binding, + browserStore = requireComponents.core.store, + searchSelectorMenu = searchSelectorMenu, + ), + owner = viewLifecycleOwner, + view = binding.root, + ) + consumeFlow(requireComponents.core.store) { flow -> flow.map { state -> state.search } .ifChanged() @@ -665,31 +653,6 @@ class HomeFragment : Fragment() { searchSelectorMenu.menuController.submitList(searchSelectorMenu.menuItems(searchEngineList)) } - private fun observeSearchEngineChanges() { - consumeFlow(store) { flow -> - flow.map { state -> state.search.selectedOrDefaultSearchEngine } - .ifChanged() - .collect { searchEngine -> - val name = searchEngine?.name - val icon = searchEngine?.let { - // Changing dimensions doesn't not affect the icon size, not sure what the - // code is doing: https://github.com/mozilla-mobile/fenix/issues/27763 - val iconSize = - requireContext().resources.getDimensionPixelSize(R.dimen.preference_icon_drawable_size) - BitmapDrawable(requireContext().resources, searchEngine.icon).apply { - setBounds(0, 0, iconSize, iconSize) - } - } - - if (requireContext().settings().showUnifiedSearchFeature) { - binding.searchSelectorButton.setIcon(icon, name) - } else { - binding.searchEngineIcon.setImageDrawable(icon) - } - } - } - } - /** * Method used to listen to search engine name changes and trigger a top sites update accordingly */ diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/toolbar/SearchSelectorBinding.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/toolbar/SearchSelectorBinding.kt new file mode 100644 index 000000000000..1bd687f7c439 --- /dev/null +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/toolbar/SearchSelectorBinding.kt @@ -0,0 +1,82 @@ +/* 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 android.graphics.drawable.BitmapDrawable +import androidx.core.view.isGone +import androidx.core.view.isVisible +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine +import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.menu.Orientation +import mozilla.components.lib.state.helpers.AbstractBinding +import mozilla.components.service.glean.private.NoExtras +import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged +import org.mozilla.fenix.GleanMetrics.UnifiedSearch +import org.mozilla.fenix.R +import org.mozilla.fenix.databinding.FragmentHomeBinding +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.search.toolbar.SearchSelectorMenu + +/** + * A binding that shows the search engine in the search selector button. + */ +class SearchSelectorBinding( + private val context: Context, + private val binding: FragmentHomeBinding, + private val searchSelectorMenu: SearchSelectorMenu, + browserStore: BrowserStore, +) : AbstractBinding(browserStore) { + + override fun start() { + super.start() + + context.settings().showUnifiedSearchFeature.let { + binding.searchSelectorButton.isVisible = it + binding.searchEngineIcon.isGone = it + } + + binding.searchSelectorButton.apply { + setOnClickListener { + val orientation = if (context.settings().shouldUseBottomToolbar) { + Orientation.UP + } else { + Orientation.DOWN + } + + UnifiedSearch.searchMenuTapped.record(NoExtras()) + + searchSelectorMenu.menuController.show( + anchor = it.findViewById(R.id.search_selector), + orientation = orientation, + ) + } + } + } + + override suspend fun onState(flow: Flow) { + flow.map { state -> state.search.selectedOrDefaultSearchEngine } + .ifChanged() + .collect { searchEngine -> + val name = searchEngine?.name + val icon = searchEngine?.let { + val iconSize = + context.resources.getDimensionPixelSize(R.dimen.preference_icon_drawable_size) + BitmapDrawable(context.resources, searchEngine.icon).apply { + setBounds(0, 0, iconSize, iconSize) + } + } + + if (context.settings().showUnifiedSearchFeature) { + binding.searchSelectorButton.setIcon(icon, name) + } else { + binding.searchEngineIcon.setImageDrawable(icon) + } + } + } +} -- 2.11.4.GIT