1
0
Fork 0

Add createInitialSearchFragmentState function

master
Tiger Oakes 2020-08-07 15:24:31 -07:00 committed by Jeff Boek
parent 3086d8a694
commit 1fab28f043
4 changed files with 90 additions and 99 deletions

View File

@ -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<SearchFragmentArgs>()
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
}
}

View File

@ -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.
*/

View File

@ -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

View File

@ -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<SearchDialogFragmentArgs>()
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<SearchDialogFragmentArgs>()
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
}
}