Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
Adds shortcut logic
Browse files Browse the repository at this point in the history
  • Loading branch information
sblatz committed Mar 7, 2019
1 parent 7fce0d8 commit b54e499
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class ToolbarComponent(
override val reducer: Reducer<SearchState, SearchChange> = { state, change ->
when (change) {
is SearchChange.QueryChanged -> state.copy(query = change.query)
is SearchChange.SearchShortcutEngineSelected ->
state.copy(searchShortcutEnginePrefix = change.enginePrefix)
}
}

Expand All @@ -60,7 +62,9 @@ class ToolbarComponent(
}
}

data class SearchState(val query: String, val isEditing: Boolean) : ViewState
data class SearchState(val query: String,
val isEditing: Boolean,
val searchShortcutEnginePrefix: String? = null) : ViewState

sealed class SearchAction : Action {
data class UrlCommitted(val url: String, val session: String?) : SearchAction()
Expand All @@ -71,4 +75,5 @@ sealed class SearchAction : Action {

sealed class SearchChange : Change {
data class QueryChanged(val query: String) : SearchChange()
data class SearchShortcutEngineSelected(val enginePrefix: String) : SearchChange()
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class ToolbarUIView(
} else {
view.displayMode()
}

it.searchShortcutEnginePrefix?.let { prefix -> view.setSearchShortcut(prefix) }
}

companion object {
Expand Down
13 changes: 7 additions & 6 deletions app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ import mozilla.components.support.ktx.kotlin.isUrl
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.toolbar.SearchAction
import org.mozilla.fenix.components.toolbar.SearchState
import org.mozilla.fenix.components.toolbar.ToolbarComponent
import org.mozilla.fenix.components.toolbar.ToolbarUIView
import org.mozilla.fenix.components.toolbar.*
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.mvi.ActionBusFactory
Expand Down Expand Up @@ -79,8 +76,8 @@ class SearchFragment : Fragment() {

search_shortcuts_button.setOnClickListener {
getManagedEmitter<AwesomeBarChange>().onNext(AwesomeBarChange
.SearchShortcutSelected(!(
(awesomeBarComponent.uiView as AwesomeBarUIView).state?.searchShortcutSelected ?: true)))
.SearchShortcutEnginePicker(!(
(awesomeBarComponent.uiView as AwesomeBarUIView).state?.showShortcutEnginePicker ?: true)))
}
}

Expand Down Expand Up @@ -117,6 +114,10 @@ class SearchFragment : Fragment() {
getSearchUseCase(requireContext(), sessionId == null).invoke(it.searchTerms)
transitionToBrowser()
}
is AwesomeBarAction.SearchShortcutTapped -> {
getManagedEmitter<SearchChange>()
.onNext(SearchChange.SearchShortcutEngineSelected(it.enginePrefix))
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@ import org.mozilla.fenix.mvi.Reducer
import org.mozilla.fenix.mvi.UIComponent
import org.mozilla.fenix.mvi.ViewState

data class AwesomeBarState(val query: String, val searchShortcutSelected: Boolean) : ViewState
data class AwesomeBarState(
val query: String,
val showShortcutEnginePicker: Boolean,
val suggestionEngine: String? = null
) : ViewState

sealed class AwesomeBarAction : Action {
data class URLTapped(val url: String) : AwesomeBarAction()
data class SearchTermsTapped(val searchTerms: String) : AwesomeBarAction()
data class SearchShortcutTapped(val enginePrefix: String) : AwesomeBarAction()
}

sealed class AwesomeBarChange : Change {
data class SearchShortcutSelected(val selected: Boolean) : AwesomeBarChange()
data class SearchShortcutEnginePicker(val show: Boolean) : AwesomeBarChange()
data class UpdateQuery(val query: String) : AwesomeBarChange()
}

Expand All @@ -33,8 +38,8 @@ class AwesomeBarComponent(
) {
override val reducer: Reducer<AwesomeBarState, AwesomeBarChange> = { state, change ->
when (change) {
is AwesomeBarChange.SearchShortcutSelected ->
state.copy(searchShortcutSelected = change.selected)
is AwesomeBarChange.SearchShortcutEnginePicker ->
state.copy(showShortcutEnginePicker = change.show)
is AwesomeBarChange.UpdateQuery -> state.copy(query = change.query)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.mozilla.fenix.search.awesomebar
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/. */

import android.content.SearchRecentSuggestionsProvider
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
Expand Down Expand Up @@ -39,22 +40,27 @@ class AwesomeBarUIView(
var clipboardSuggestionProvider: ClipboardSuggestionProvider? = null
var sessionProvider: SessionSuggestionProvider? = null
var historyStorageProvider: HistoryStorageSuggestionProvider? = null
var searchSuggestionProvider: SearchSuggestionProvider? = null
var shortcutsSuggestionProvider: ShortcutsSuggestionProvider? = null

init {
val loadUrlUseCase = object : SessionUseCases.LoadUrlUseCase {
override fun invoke(url: String) {
actionEmitter.onNext(AwesomeBarAction.URLTapped(url))
}
val searchSuggestionProvider: SearchSuggestionProvider?
get() = searchSuggestionFromShortcutProvider ?: defaultSearchSuggestionProvider!!

var defaultSearchSuggestionProvider: SearchSuggestionProvider? = null
var searchSuggestionFromShortcutProvider: SearchSuggestionProvider? = null

val loadUrlUseCase = object : SessionUseCases.LoadUrlUseCase {
override fun invoke(url: String) {
actionEmitter.onNext(AwesomeBarAction.URLTapped(url))
}
}

val searchUseCase = object : SearchUseCases.SearchUseCase {
override fun invoke(searchTerms: String) {
actionEmitter.onNext(AwesomeBarAction.SearchTermsTapped(searchTerms))
}
val searchUseCase = object : SearchUseCases.SearchUseCase {
override fun invoke(searchTerms: String) {
actionEmitter.onNext(AwesomeBarAction.SearchTermsTapped(searchTerms))
}
}

init {
with(container.context) {
clipboardSuggestionProvider = ClipboardSuggestionProvider(
this,
Expand All @@ -75,46 +81,69 @@ class AwesomeBarUIView(
loadUrlUseCase
)

searchSuggestionProvider =
defaultSearchSuggestionProvider =
SearchSuggestionProvider(
components.search.searchEngineManager.getDefaultSearchEngine(this),
searchUseCase,
components.core.client,
SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS
)

shortcutsSuggestionProvider =
ShortcutsSuggestionProvider(components.search.searchEngineManager, this)
ShortcutsSuggestionProvider(components.search.searchEngineManager, this, ::selectShortcutEngine)
}
}

private fun updateShortcutVisibility(selected: Boolean) {
private fun showShortcutEnginePicker() {
with(container.context) {
if (selected) {
search_shortcuts_button.background = getDrawable(R.drawable.search_pill_background)

view.removeAllProviders()
search_shortcuts_button.background = getDrawable(R.drawable.search_pill_background)
view.removeAllProviders()
view.addProviders(shortcutsSuggestionProvider!!)
}
}

view.addProviders(shortcutsSuggestionProvider!!)
} else {
search_shortcuts_button.setBackgroundColor(ContextCompat.getColor(this,
DefaultThemeManager.resolveAttribute(R.attr.pillWrapperBackground, this)))
private fun hideShortcutEnginePicker() {
with(container.context) {
search_shortcuts_button.setBackgroundColor(ContextCompat.getColor(this,
DefaultThemeManager.resolveAttribute(R.attr.pillWrapperBackground, this)))
view.removeProviders(shortcutsSuggestionProvider!!)
}
}

view.removeProviders(shortcutsSuggestionProvider!!)
private fun showSuggestionProviders() {
view.addProviders(
clipboardSuggestionProvider!!,
sessionProvider!!,
historyStorageProvider!!,
searchSuggestionProvider!!
)
}

view.addProviders(
clipboardSuggestionProvider!!,
sessionProvider!!,
historyStorageProvider!!,
searchSuggestionProvider!!
)
}
private fun selectShortcutEngine(engineName: String, enginePrefix: String) {
with(container.context) {
searchSuggestionFromShortcutProvider = SearchSuggestionProvider(
components.search.searchEngineManager.getDefaultSearchEngine(this, engineName),
searchUseCase,
components.core.client,
SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS
)
}

// TODO setting the state here seems clunky, but we have no way to emit an AwesomeBarChange from within this view
// TODO if we could, we would just emit a SearchShortcutEnginePicker change with `false`
state = state?.copy(showShortcutEnginePicker = false)
hideShortcutEnginePicker()
showSuggestionProviders()
}

override fun updateView() = Consumer<AwesomeBarState> {
if (state?.searchShortcutSelected != it.searchShortcutSelected) {
updateShortcutVisibility(it.searchShortcutSelected)
if (it.showShortcutEnginePicker) {
showShortcutEnginePicker()
} else {
hideShortcutEnginePicker()
showSuggestionProviders()
}

view.onInputChanged(it.query)

state = it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import java.util.UUID
*/
class ShortcutsSuggestionProvider(
private val searchEngineManager: SearchEngineManager,
private val context: Context
private val context: Context,
private val selectShortcutEngine: (engineName: String, enginePrefix: String) -> Unit
) : AwesomeBar.SuggestionProvider {
override val id: String = UUID.randomUUID().toString()

Expand All @@ -31,7 +32,8 @@ class ShortcutsSuggestionProvider(
title = it.name,
description = getDescription(it.name),
onSuggestionClicked = {
// TODO pass this data to the awesomeBar
// TODO can we emit an AwesomeBarChange (not action) here?
selectShortcutEngine(it.name, getDescription(it.name))
})
)
}
Expand Down

0 comments on commit b54e499

Please sign in to comment.