2019-07-13 01:32:00 +02:00
|
|
|
/* 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.toolbar
|
|
|
|
|
|
|
|
import android.view.LayoutInflater
|
|
|
|
import android.view.View
|
|
|
|
import android.view.ViewGroup
|
|
|
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
|
|
import androidx.core.content.ContextCompat
|
|
|
|
import kotlinx.android.extensions.LayoutContainer
|
|
|
|
import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider
|
|
|
|
import mozilla.components.browser.toolbar.BrowserToolbar
|
|
|
|
import mozilla.components.concept.storage.HistoryStorage
|
|
|
|
import mozilla.components.feature.toolbar.ToolbarAutocompleteFeature
|
2019-07-31 20:43:49 +02:00
|
|
|
import mozilla.components.support.ktx.android.util.dpToPx
|
2019-07-13 01:32:00 +02:00
|
|
|
import org.mozilla.fenix.R
|
2019-07-22 22:59:24 +02:00
|
|
|
import org.mozilla.fenix.ext.getColorFromAttr
|
2019-08-30 15:21:34 +02:00
|
|
|
import org.mozilla.fenix.search.SearchFragmentState
|
2019-07-13 01:32:00 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface for the Toolbar Interactor. This interface is implemented by objects that want
|
2019-07-29 21:39:36 +02:00
|
|
|
* to respond to user interaction on the [BrowserToolbarView]
|
2019-07-13 01:32:00 +02:00
|
|
|
*/
|
|
|
|
interface ToolbarInteractor {
|
|
|
|
|
|
|
|
/**
|
2019-07-29 21:39:36 +02:00
|
|
|
* Called when a user hits the return key while [BrowserToolbarView] has focus.
|
|
|
|
* @param url the text inside the [BrowserToolbarView] when committed
|
2019-07-13 01:32:00 +02:00
|
|
|
*/
|
|
|
|
fun onUrlCommitted(url: String)
|
|
|
|
|
|
|
|
/**
|
2019-07-29 21:39:36 +02:00
|
|
|
* Called when a user removes focus from the [BrowserToolbarView]
|
2019-07-13 01:32:00 +02:00
|
|
|
*/
|
|
|
|
fun onEditingCanceled()
|
|
|
|
|
|
|
|
/**
|
2019-07-29 21:39:36 +02:00
|
|
|
* Called whenever the text inside the [BrowserToolbarView] changes
|
|
|
|
* @param text the current text displayed by [BrowserToolbarView]
|
2019-07-13 01:32:00 +02:00
|
|
|
*/
|
|
|
|
fun onTextChanged(text: String)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* View that contains and configures the BrowserToolbar to only be used in its editing mode.
|
|
|
|
*/
|
|
|
|
class ToolbarView(
|
|
|
|
private val container: ViewGroup,
|
|
|
|
private val interactor: ToolbarInteractor,
|
2019-07-30 00:00:48 +02:00
|
|
|
private val historyStorage: HistoryStorage?,
|
|
|
|
private val isPrivate: Boolean
|
2019-07-13 01:32:00 +02:00
|
|
|
) : LayoutContainer {
|
|
|
|
|
|
|
|
override val containerView: View?
|
|
|
|
get() = container
|
|
|
|
|
|
|
|
val view: BrowserToolbar = LayoutInflater.from(container.context)
|
|
|
|
.inflate(R.layout.component_search, container, true)
|
|
|
|
.findViewById(R.id.toolbar)
|
|
|
|
|
|
|
|
private var isInitialized = false
|
|
|
|
|
|
|
|
init {
|
|
|
|
view.apply {
|
|
|
|
editMode()
|
|
|
|
|
2019-07-31 20:43:49 +02:00
|
|
|
elevation = TOOLBAR_ELEVATION_IN_DP.dpToPx(resources.displayMetrics).toFloat()
|
2019-07-13 01:32:00 +02:00
|
|
|
|
|
|
|
setOnUrlCommitListener {
|
|
|
|
interactor.onUrlCommitted(it)
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
|
|
|
background = null
|
|
|
|
|
|
|
|
layoutParams.height = CoordinatorLayout.LayoutParams.MATCH_PARENT
|
|
|
|
|
|
|
|
hint = context.getString(R.string.search_hint)
|
|
|
|
|
2019-07-22 22:59:24 +02:00
|
|
|
textColor = container.context.getColorFromAttr(R.attr.primaryText)
|
2019-07-13 01:32:00 +02:00
|
|
|
|
2019-07-22 22:59:24 +02:00
|
|
|
hintColor = container.context.getColorFromAttr(R.attr.secondaryText)
|
2019-07-13 01:32:00 +02:00
|
|
|
|
|
|
|
suggestionBackgroundColor = ContextCompat.getColor(
|
|
|
|
container.context,
|
|
|
|
R.color.suggestion_highlight_color
|
|
|
|
)
|
|
|
|
|
2019-07-30 00:00:48 +02:00
|
|
|
private = isPrivate
|
|
|
|
|
2019-07-13 01:32:00 +02:00
|
|
|
setOnEditListener(object : mozilla.components.concept.toolbar.Toolbar.OnEditListener {
|
|
|
|
override fun onCancelEditing(): Boolean {
|
|
|
|
interactor.onEditingCanceled()
|
2019-08-22 01:29:45 +02:00
|
|
|
// We need to return false to not show display mode
|
2019-07-13 01:32:00 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
override fun onTextChanged(text: String) {
|
|
|
|
url = text
|
|
|
|
this@ToolbarView.interactor.onTextChanged(text)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
ToolbarAutocompleteFeature(view).apply {
|
|
|
|
addDomainProvider(ShippedDomainsProvider().also { it.initialize(view.context) })
|
|
|
|
historyStorage?.also(::addHistoryStorageProvider)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-30 15:21:34 +02:00
|
|
|
fun update(searchState: SearchFragmentState) {
|
2019-07-13 01:32:00 +02:00
|
|
|
if (!isInitialized) {
|
2019-09-04 22:56:39 +02:00
|
|
|
view.url = searchState.pastedText ?: searchState.query
|
|
|
|
|
|
|
|
/* Only set the search terms if pasted text is null so that the search term doesn't
|
|
|
|
overwrite pastedText when view enters `editMode` */
|
|
|
|
if (searchState.pastedText.isNullOrEmpty()) {
|
2019-09-14 20:10:11 +02:00
|
|
|
view.setSearchTerms(searchState.session?.searchTerms.orEmpty())
|
2019-09-04 22:56:39 +02:00
|
|
|
}
|
|
|
|
|
2019-07-13 01:32:00 +02:00
|
|
|
view.editMode()
|
|
|
|
isInitialized = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
private const val TOOLBAR_ELEVATION_IN_DP = 16
|
|
|
|
}
|
|
|
|
}
|