From 1fab28f0432aa76e7c370130a47762b3b23d1624 Mon Sep 17 00:00:00 2001 From: Tiger Oakes Date: Fri, 7 Aug 2020 15:24:31 -0700 Subject: [PATCH] Add createInitialSearchFragmentState function --- .../mozilla/fenix/search/SearchFragment.kt | 58 ++++------------- .../fenix/search/SearchFragmentStore.kt | 50 +++++++++++++++ .../fenix/search/ext/SearchEngineProvider.kt | 17 +++++ .../searchdialog/SearchDialogFragment.kt | 64 ++++--------------- 4 files changed, 90 insertions(+), 99 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/search/ext/SearchEngineProvider.kt diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt index bae126a1e..d407a8d91 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt @@ -30,7 +30,6 @@ import kotlinx.android.synthetic.main.fragment_search.* import kotlinx.android.synthetic.main.fragment_search.view.* import kotlinx.android.synthetic.main.search_suggestions_onboarding.view.* import kotlinx.coroutines.ExperimentalCoroutinesApi -import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.concept.storage.HistoryStorage import mozilla.components.feature.qr.QrFeature @@ -55,6 +54,7 @@ import org.mozilla.fenix.ext.hideToolbar import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings import org.mozilla.fenix.search.awesomebar.AwesomeBarView +import org.mozilla.fenix.search.ext.areShortcutsAvailable import org.mozilla.fenix.search.toolbar.ToolbarView import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener @@ -71,14 +71,6 @@ class SearchFragment : Fragment(), UserInteractionHandler { private val speechIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH) - private fun shouldShowSearchSuggestions(isPrivate: Boolean): Boolean = - if (isPrivate) { - requireContext().settings().shouldShowSearchSuggestions && - requireContext().settings().shouldShowSearchSuggestionsInPrivate - } else { - requireContext().settings().shouldShowSearchSuggestions - } - @Suppress("LongMethod") override fun onCreateView( inflater: LayoutInflater, @@ -89,38 +81,18 @@ class SearchFragment : Fragment(), UserInteractionHandler { val settings = activity.settings() val args by navArgs() - val tabId = args.sessionId - val tab = tabId?.let { requireComponents.core.store.state.findTab(it) } - val view = inflater.inflate(R.layout.fragment_search, container, false) - val url = tab?.content?.url.orEmpty() - val currentSearchEngine = SearchEngineSource.Default( - requireComponents.search.provider.getDefaultEngine(requireContext()) - ) val isPrivate = activity.browsingModeManager.mode.isPrivate requireComponents.analytics.metrics.track(Event.InteractWithSearchURLArea) - val areShortcutsAvailable = areShortcutsAvailable() searchStore = StoreProvider.get(this) { SearchFragmentStore( - SearchFragmentState( - query = url, - url = url, - searchTerms = tab?.content?.searchTerms.orEmpty(), - searchEngineSource = currentSearchEngine, - defaultEngineSource = currentSearchEngine, - showSearchSuggestions = shouldShowSearchSuggestions(isPrivate), - showSearchSuggestionsHint = false, - showSearchShortcuts = settings.shouldShowSearchShortcuts && - url.isEmpty() && - areShortcutsAvailable, - areShortcutsAvailable = areShortcutsAvailable, - showClipboardSuggestions = settings.shouldShowClipboardSuggestions, - showHistorySuggestions = settings.shouldShowHistorySuggestions, - showBookmarkSuggestions = settings.shouldShowBookmarkSuggestions, - tabId = tabId, + createInitialSearchFragmentState( + activity, + requireComponents, + tabId = args.sessionId, pastedText = args.pastedText, searchAccessPoint = args.searchAccessPoint ) @@ -165,7 +137,7 @@ class SearchFragment : Fragment(), UserInteractionHandler { ContextCompat.getDrawable(requireContext(), R.drawable.ic_microphone)!!, requireContext().getString(R.string.voice_search_content_description), visible = { - currentSearchEngine.searchEngine.identifier.contains("google") && + searchStore.state.searchEngineSource.searchEngine.identifier.contains("google") && speechIsAvailable() && settings.shouldShowVoiceSearch }, @@ -343,10 +315,11 @@ class SearchFragment : Fragment(), UserInteractionHandler { override fun onResume() { super.onResume() + val provider = requireComponents.search.provider + // The user has the option to go to 'Shortcuts' -> 'Search engine settings' to modify the default search engine. // When returning from that settings screen we need to update it to account for any changes. - val currentDefaultEngine = - requireComponents.search.provider.getDefaultEngine(requireContext()) + val currentDefaultEngine = provider.getDefaultEngine(requireContext()) if (searchStore.state.defaultEngineSource.searchEngine != currentDefaultEngine) { searchStore.dispatch( @@ -356,7 +329,7 @@ class SearchFragment : Fragment(), UserInteractionHandler { } // Users can from this fragment go to install/uninstall search engines and then return. - val areShortcutsAvailable = areShortcutsAvailable() + val areShortcutsAvailable = provider.areShortcutsAvailable(requireContext()) if (searchStore.state.areShortcutsAvailable != areShortcutsAvailable) { searchStore.dispatch(SearchFragmentAction.UpdateShortcutsAvailability(areShortcutsAvailable)) } @@ -367,7 +340,7 @@ class SearchFragment : Fragment(), UserInteractionHandler { updateClipboardSuggestion( searchStore.state, - requireContext().components.clipboardHandler.url + requireComponents.clipboardHandler.url ) permissionDidUpdate = false @@ -470,16 +443,7 @@ class SearchFragment : Fragment(), UserInteractionHandler { } } - /** - * Return if the user has *at least 2* installed search engines. - * Useful to decide whether to show / enable certain functionalities. - */ - private fun areShortcutsAvailable() = - requireContext().components.search.provider.installedSearchEngines(requireContext()) - .list.size >= MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS - companion object { private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1 - private const val MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS = 2 } } diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt b/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt index 4bf57c522..ac5996a91 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt @@ -5,10 +5,15 @@ package org.mozilla.fenix.search import mozilla.components.browser.search.SearchEngine +import mozilla.components.browser.state.selector.findTab import mozilla.components.lib.state.Action import mozilla.components.lib.state.State import mozilla.components.lib.state.Store +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.browser.browsingmode.BrowsingMode +import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.search.ext.areShortcutsAvailable /** * The [Store] for holding the [SearchFragmentState] and applying [SearchFragmentAction]s. @@ -66,6 +71,51 @@ data class SearchFragmentState( val searchAccessPoint: Event.PerformedSearch.SearchAccessPoint? ) : State +fun createInitialSearchFragmentState( + activity: HomeActivity, + components: Components, + tabId: String?, + pastedText: String?, + searchAccessPoint: Event.PerformedSearch.SearchAccessPoint +): SearchFragmentState { + val settings = components.settings + val tab = tabId?.let { components.core.store.state.findTab(it) } + + val url = tab?.content?.url.orEmpty() + val currentSearchEngine = SearchEngineSource.Default( + components.search.provider.getDefaultEngine(activity) + ) + + val browsingMode = activity.browsingModeManager.mode + val areShortcutsAvailable = components.search.provider.areShortcutsAvailable(activity) + + val shouldShowSearchSuggestions = when (browsingMode) { + BrowsingMode.Normal -> settings.shouldShowSearchSuggestions + BrowsingMode.Private -> + settings.shouldShowSearchSuggestions && settings.shouldShowSearchSuggestionsInPrivate + } + + return SearchFragmentState( + query = url, + url = url, + searchTerms = tab?.content?.searchTerms.orEmpty(), + searchEngineSource = currentSearchEngine, + defaultEngineSource = currentSearchEngine, + showSearchSuggestions = shouldShowSearchSuggestions, + showSearchSuggestionsHint = false, + showSearchShortcuts = url.isEmpty() && + areShortcutsAvailable && + settings.shouldShowSearchShortcuts, + areShortcutsAvailable = areShortcutsAvailable, + showClipboardSuggestions = settings.shouldShowClipboardSuggestions, + showHistorySuggestions = settings.shouldShowHistorySuggestions, + showBookmarkSuggestions = settings.shouldShowBookmarkSuggestions, + tabId = tabId, + pastedText = pastedText, + searchAccessPoint = searchAccessPoint + ) +} + /** * Actions to dispatch through the `SearchStore` to modify `SearchState` through the reducer. */ diff --git a/app/src/main/java/org/mozilla/fenix/search/ext/SearchEngineProvider.kt b/app/src/main/java/org/mozilla/fenix/search/ext/SearchEngineProvider.kt new file mode 100644 index 000000000..cbb598fd8 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/search/ext/SearchEngineProvider.kt @@ -0,0 +1,17 @@ +/* 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.search.ext + +import android.content.Context +import org.mozilla.fenix.components.searchengine.FenixSearchEngineProvider + +private const val MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS = 2 + +/** + * Return if the user has *at least 2* installed search engines. + * Useful to decide whether to show / enable certain functionalities. + */ +fun FenixSearchEngineProvider.areShortcutsAvailable(context: Context) = + installedSearchEngines(context).list.size >= MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS diff --git a/app/src/main/java/org/mozilla/fenix/searchdialog/SearchDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/searchdialog/SearchDialogFragment.kt index 41ca59eac..9c869aa81 100644 --- a/app/src/main/java/org/mozilla/fenix/searchdialog/SearchDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/searchdialog/SearchDialogFragment.kt @@ -19,33 +19,22 @@ import androidx.navigation.fragment.navArgs import kotlinx.android.synthetic.main.fragment_search.view.* import kotlinx.android.synthetic.main.fragment_search_dialog.* import kotlinx.coroutines.ExperimentalCoroutinesApi -import mozilla.components.browser.state.selector.findTab import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.ktx.android.view.hideKeyboard import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.toolbar.ToolbarPosition -import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.search.SearchEngineSource -import org.mozilla.fenix.search.SearchFragmentState import org.mozilla.fenix.search.SearchFragmentStore import org.mozilla.fenix.search.SearchInteractor import org.mozilla.fenix.search.awesomebar.AwesomeBarView +import org.mozilla.fenix.search.createInitialSearchFragmentState import org.mozilla.fenix.search.toolbar.ToolbarView -import org.mozilla.fenix.utils.Settings typealias SearchDialogFragmentStore = SearchFragmentStore typealias SearchDialogInteractor = SearchInteractor -fun Settings.shouldShowSearchSuggestions(isPrivate: Boolean): Boolean { - return if (isPrivate) { - shouldShowSearchSuggestions && shouldShowSearchSuggestionsInPrivate - } else { - shouldShowSearchSuggestions - } -} class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { @@ -72,8 +61,18 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { container: ViewGroup?, savedInstanceState: Bundle? ): View? { + val args by navArgs() val view = inflater.inflate(R.layout.fragment_search_dialog, container, false) - store = SearchDialogFragmentStore(setUpState()) + + store = SearchDialogFragmentStore( + createInitialSearchFragmentState( + activity as HomeActivity, + requireComponents, + tabId = args.sessionId, + pastedText = args.pastedText, + searchAccessPoint = args.searchAccessPoint + ) + ) interactor = SearchDialogInteractor( SearchDialogController( @@ -146,43 +145,4 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { return true } - - private fun setUpState(): SearchFragmentState { - val activity = activity as HomeActivity - val settings = activity.settings() - val args by navArgs() - val tabId = args.sessionId - val tab = tabId?.let { requireComponents.core.store.state.findTab(it) } - val url = tab?.content?.url.orEmpty() - val currentSearchEngine = SearchEngineSource.Default( - requireComponents.search.provider.getDefaultEngine(requireContext()) - ) - val isPrivate = activity.browsingModeManager.mode.isPrivate - val areShortcutsAvailable = - requireContext().components.search.provider.installedSearchEngines(requireContext()) - .list.size >= MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS - return SearchFragmentState( - query = url, - url = url, - searchTerms = tab?.content?.searchTerms.orEmpty(), - searchEngineSource = currentSearchEngine, - defaultEngineSource = currentSearchEngine, - showSearchSuggestions = settings.shouldShowSearchSuggestions(isPrivate), - showSearchSuggestionsHint = false, - showSearchShortcuts = settings.shouldShowSearchShortcuts && - url.isEmpty() && - areShortcutsAvailable, - areShortcutsAvailable = areShortcutsAvailable, - showClipboardSuggestions = settings.shouldShowClipboardSuggestions, - showHistorySuggestions = settings.shouldShowHistorySuggestions, - showBookmarkSuggestions = settings.shouldShowBookmarkSuggestions, - tabId = tabId, - pastedText = args.pastedText, - searchAccessPoint = args.searchAccessPoint - ) - } - - companion object { - private const val MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS = 2 - } }