For #1019 Add onboarding search suggestion hint panel
parent
5543f3272d
commit
1d36098878
|
@ -14,11 +14,11 @@ import org.mozilla.fenix.BrowserDirection
|
|||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.metrics
|
||||
import org.mozilla.fenix.ext.nav
|
||||
import org.mozilla.fenix.ext.searchEngineManager
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.searchEngineManager
|
||||
|
||||
/**
|
||||
* An interface that handles the view manipulation of the Search, triggered by the Interactor
|
||||
|
@ -69,6 +69,12 @@ class DefaultSearchController(
|
|||
store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(
|
||||
text.isEmpty() && context.settings().shouldShowSearchShortcuts
|
||||
))
|
||||
store.dispatch(SearchFragmentAction.ShowSearchSuggestionsHint(
|
||||
text.isNotEmpty() &&
|
||||
(context as HomeActivity).browsingModeManager.mode.isPrivate &&
|
||||
!context.settings().shouldShowSearchSuggestionsInPrivate &&
|
||||
!context.settings().showSearchSuggestionsInPrivateOnboardingFinished
|
||||
))
|
||||
}
|
||||
|
||||
override fun handleUrlTapped(url: String) {
|
||||
|
|
|
@ -14,13 +14,16 @@ import android.text.style.StyleSpan
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewStub
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.transition.TransitionInflater
|
||||
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.concept.storage.HistoryStorage
|
||||
import mozilla.components.feature.qr.QrFeature
|
||||
|
@ -34,12 +37,13 @@ import org.mozilla.fenix.HomeActivity
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.StoreProvider
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getSpannable
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.search.awesomebar.AwesomeBarView
|
||||
import org.mozilla.fenix.search.toolbar.ToolbarView
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.settings
|
||||
|
||||
@Suppress("TooManyFunctions", "LargeClass")
|
||||
class SearchFragment : Fragment(), BackHandler {
|
||||
|
@ -95,6 +99,7 @@ class SearchFragment : Fragment(), BackHandler {
|
|||
searchEngineSource = currentSearchEngine,
|
||||
defaultEngineSource = currentSearchEngine,
|
||||
showSearchSuggestions = showSearchSuggestions,
|
||||
showSearchSuggestionsHint = false,
|
||||
showSearchShortcuts = requireContext().settings().shouldShowSearchShortcuts && url.isEmpty(),
|
||||
showClipboardSuggestions = requireContext().settings().shouldShowClipboardSuggestions,
|
||||
showHistorySuggestions = requireContext().settings().shouldShowHistorySuggestions,
|
||||
|
@ -184,6 +189,34 @@ class SearchFragment : Fragment(), BackHandler {
|
|||
qrFeature.get()?.scan(R.id.container)
|
||||
}
|
||||
|
||||
val stubListener = ViewStub.OnInflateListener { _, inflated ->
|
||||
inflated.learn_more.setOnClickListener {
|
||||
(activity as HomeActivity)
|
||||
.openToBrowserAndLoad(
|
||||
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic(
|
||||
SupportUtils.SumoTopic.SEARCH_SUGGESTION),
|
||||
newTab = searchStore.state.session == null,
|
||||
from = BrowserDirection.FromSearch
|
||||
)
|
||||
}
|
||||
|
||||
inflated.allow.setOnClickListener {
|
||||
inflated.visibility = View.GONE
|
||||
context?.settings()?.shouldShowSearchSuggestionsInPrivate = true
|
||||
context?.settings()?.showSearchSuggestionsInPrivateOnboardingFinished = true
|
||||
}
|
||||
|
||||
inflated.dismiss.setOnClickListener {
|
||||
inflated.visibility = View.GONE
|
||||
context?.settings()?.shouldShowSearchSuggestionsInPrivate = false
|
||||
context?.settings()?.showSearchSuggestionsInPrivateOnboardingFinished = true
|
||||
}
|
||||
}
|
||||
|
||||
view.search_suggestions_onboarding.setOnInflateListener((stubListener)
|
||||
|
||||
)
|
||||
|
||||
view.toolbar_wrapper.clipToOutline = false
|
||||
|
||||
fill_link_from_clipboard.setOnClickListener {
|
||||
|
@ -200,6 +233,7 @@ class SearchFragment : Fragment(), BackHandler {
|
|||
toolbarView.update(it)
|
||||
updateSearchWithLabel(it)
|
||||
updateClipboardSuggestion(it, requireContext().components.clipboardHandler.url)
|
||||
updateSearchSuggestionsHintVisibility(it)
|
||||
}
|
||||
|
||||
startPostponedEnterTransition()
|
||||
|
@ -287,6 +321,11 @@ class SearchFragment : Fragment(), BackHandler {
|
|||
} else null
|
||||
}
|
||||
|
||||
private fun updateSearchSuggestionsHintVisibility(state: SearchFragmentState) {
|
||||
view?.findViewById<View>(R.id.search_suggestions_onboarding)
|
||||
?.isVisible = state.showSearchSuggestionsHint
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SHARED_TRANSITION_MS = 200L
|
||||
private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1
|
||||
|
|
|
@ -36,6 +36,7 @@ sealed class SearchEngineSource {
|
|||
* @property searchEngineSource The current selected search engine with the context of how it was selected
|
||||
* @property defaultEngineSource The current default search engine source
|
||||
* @property showSearchSuggestions Whether or not to show search suggestions from the search engine in the AwesomeBar
|
||||
* @property showSearchSuggestionsHint Whether or not to show search suggestions in private hint panel
|
||||
* @property showSearchShortcuts Whether or not to show search shortcuts in the AwesomeBar
|
||||
* @property showClipboardSuggestions Whether or not to show clipboard suggestion in the AwesomeBar
|
||||
* @property showHistorySuggestions Whether or not to show history suggestions in the AwesomeBar
|
||||
|
@ -48,6 +49,7 @@ data class SearchFragmentState(
|
|||
val searchEngineSource: SearchEngineSource,
|
||||
val defaultEngineSource: SearchEngineSource.Default,
|
||||
val showSearchSuggestions: Boolean,
|
||||
val showSearchSuggestionsHint: Boolean,
|
||||
val showSearchShortcuts: Boolean,
|
||||
val showClipboardSuggestions: Boolean,
|
||||
val showHistorySuggestions: Boolean,
|
||||
|
@ -63,6 +65,7 @@ sealed class SearchFragmentAction : Action {
|
|||
data class SearchShortcutEngineSelected(val engine: SearchEngine) : SearchFragmentAction()
|
||||
data class SelectNewDefaultSearchEngine(val engine: SearchEngine) : SearchFragmentAction()
|
||||
data class ShowSearchShortcutEnginePicker(val show: Boolean) : SearchFragmentAction()
|
||||
data class ShowSearchSuggestionsHint(val show: Boolean) : SearchFragmentAction()
|
||||
data class UpdateQuery(val query: String) : SearchFragmentAction()
|
||||
}
|
||||
|
||||
|
@ -84,5 +87,7 @@ private fun searchStateReducer(state: SearchFragmentState, action: SearchFragmen
|
|||
state.copy(
|
||||
searchEngineSource = SearchEngineSource.Default(action.engine)
|
||||
)
|
||||
is SearchFragmentAction.ShowSearchSuggestionsHint ->
|
||||
state.copy(showSearchSuggestionsHint = action.show)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ internal fun SearchFragment.setOutOfExperimentConstraints(layout: ConstraintLayo
|
|||
awesomeBar {
|
||||
connect(
|
||||
TOP to TOP of UNSET,
|
||||
TOP to BOTTOM of search_with_shortcuts,
|
||||
TOP to BOTTOM of awesomeBar_barrier,
|
||||
BOTTOM to TOP of pillWrapper
|
||||
)
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ object SupportUtils {
|
|||
WHATS_NEW("whats-new-firefox-preview"),
|
||||
SEND_TABS("send-tab-preview"),
|
||||
SET_AS_DEFAULT_BROWSER("set-firefox-preview-default"),
|
||||
SEARCH_SUGGESTION("how-search-firefox-preview"),
|
||||
CUSTOM_SEARCH_ENGINES("custom-search-engines")
|
||||
}
|
||||
|
||||
|
|
|
@ -263,11 +263,16 @@ class Settings private constructor(
|
|||
default = true
|
||||
)
|
||||
|
||||
val shouldShowSearchSuggestionsInPrivate by booleanPreference(
|
||||
var shouldShowSearchSuggestionsInPrivate by booleanPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_show_search_suggestions_in_private),
|
||||
default = false
|
||||
)
|
||||
|
||||
var showSearchSuggestionsInPrivateOnboardingFinished by booleanPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_show_search_suggestions_in_private_onboarding),
|
||||
default = false
|
||||
)
|
||||
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
internal val trackingProtectionOnboardingCount by intPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_onboarding),
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
app:layout_constraintBottom_toTopOf="@id/search_divider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar_wrapper"
|
||||
app:layout_constraintTop_toBottomOf="@id/awesomeBar_barrier"
|
||||
mozac:awesomeBarDescriptionTextColor="?secondaryText"
|
||||
mozac:awesomeBarTitleTextColor="?primaryText" />
|
||||
|
|
|
@ -11,6 +11,18 @@
|
|||
android:background="?foundation"
|
||||
tools:context=".search.SearchFragment">
|
||||
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/search_suggestions_onboarding"
|
||||
android:inflatedId="@+id/search_suggestions_onboarding"
|
||||
android:layout="@layout/search_suggestions_onboarding"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/awesomeBar_barrier"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar_wrapper"/>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/toolbar_wrapper"
|
||||
android:layout_width="0dp"
|
||||
|
@ -103,11 +115,18 @@
|
|||
android:layout_marginTop="@dimen/search_fragment_shortcuts_label_margin_vertical"
|
||||
android:layout_marginEnd="@dimen/search_fragment_shortcuts_label_margin_horizontal"
|
||||
android:text="@string/search_shortcuts_search_with"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="@id/toolbar_wrapper"
|
||||
app:layout_constraintTop_toBottomOf="@id/fill_link_from_clipboard"
|
||||
app:layout_constraintBottom_toTopOf="@id/awesomeBar_barrier"
|
||||
tools:text="Search with" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/awesomeBar_barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="search_with_shortcuts,search_suggestions_onboarding"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/search_divider"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="20dp"
|
||||
android:paddingBottom="10dp"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/info_button"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/ic_info"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:text="@string/search_suggestions_onboarding_title"
|
||||
android:paddingBottom="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/search_suggestions_onboarding_text"
|
||||
app:layout_constraintStart_toStartOf="@id/title"
|
||||
app:layout_constraintEnd_toEndOf="@id/title"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
app:layout_constraintBottom_toTopOf="@id/learn_more"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/learn_more"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/accentHighContrast"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/exceptions_empty_message_learn_more_link"
|
||||
app:layout_constraintStart_toStartOf="@id/title"
|
||||
app:layout_constraintEnd_toEndOf="@id/title"
|
||||
app:layout_constraintTop_toBottomOf="@id/text"
|
||||
app:layout_constraintBottom_toTopOf="@id/allow"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/allow"
|
||||
style="@style/ThemeIndependentMaterialGreyButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:text="@string/search_suggestions_onboarding_allow_button"
|
||||
app:layout_constraintEnd_toEndOf="@id/title"
|
||||
app:layout_constraintTop_toBottomOf="@id/text"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dismiss"
|
||||
android:textColor="#ffffff"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="20dp"
|
||||
android:text="@string/search_suggestions_onboarding_do_not_allow_button"
|
||||
app:layout_constraintEnd_toStartOf="@id/allow"
|
||||
app:layout_constraintBottom_toBottomOf="@id/allow"
|
||||
app:layout_constraintTop_toTopOf="@id/allow"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -75,6 +75,7 @@
|
|||
<string name="pref_key_search_browsing_history" translatable="false">pref_key_search_browsing_history</string>
|
||||
<string name="pref_key_search_bookmarks" translatable="false">pref_key_search_bookmarks</string>
|
||||
<string name="pref_key_show_search_suggestions_in_private" translatable="false">pref_key_show_search_suggestions_in_private</string>
|
||||
<string name="pref_key_show_search_suggestions_in_private_onboarding" translatable="false">pref_key_show_search_suggestions_in_privateonboarding</string>
|
||||
|
||||
|
||||
<!-- Site Permissions Settings -->
|
||||
|
|
|
@ -116,6 +116,16 @@
|
|||
<string name="search_shortcuts_search_with">Search with</string>
|
||||
<!-- Button in the search view that lets a user navigate to the site in their clipboard -->
|
||||
<string name="awesomebar_clipboard_title">Fill link from clipboard</string>
|
||||
<!-- Button in the search suggestions onboarding that allows search suggestions in private sessions -->
|
||||
<string name="search_suggestions_onboarding_allow_button">Allow</string>
|
||||
<!-- Button in the search suggestions onboarding that does not allow search suggestions in private sessions -->
|
||||
<string name="search_suggestions_onboarding_do_not_allow_button">Don\'t allow</string>
|
||||
<!-- Search suggestion onboarding hint title text -->
|
||||
<string name="search_suggestions_onboarding_title">Allow search suggestions in private sessions?</string>
|
||||
<!-- Search suggestion onboarding hint description text -->
|
||||
<string name="search_suggestions_onboarding_text">Firefox Preview will share everything you type in the address bar with your default search engine.</string>
|
||||
<!-- Search suggestion onboarding hint Learn more link text -->
|
||||
<string name="search_suggestions_onboarding_learn_more_link">Learn more</string>
|
||||
|
||||
<!-- Search Widget -->
|
||||
<!-- Text preview for smaller sized widgets -->
|
||||
|
|
Loading…
Reference in New Issue