Pull awesome bar into a component
This commit is contained in:
parent
bacee18344
commit
ed1e563087
|
@ -4,23 +4,23 @@
|
|||
|
||||
package org.mozilla.fenix.search
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.Navigation
|
||||
import kotlinx.android.synthetic.main.fragment_search.*
|
||||
import kotlinx.android.synthetic.main.fragment_search.view.*
|
||||
import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.toolbar.ToolbarIntegration
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.search.awesomebar.AwesomeBarAction
|
||||
import org.mozilla.fenix.search.awesomebar.AwesomeBarChange
|
||||
import org.mozilla.fenix.search.awesomebar.AwesomeBarComponent
|
||||
import org.mozilla.fenix.search.toolbar.*
|
||||
|
||||
class SearchFragment : Fragment() {
|
||||
private lateinit var searchComponent: SearchComponent
|
||||
private lateinit var toolbarComponent: ToolbarComponent
|
||||
private lateinit var awesomeBarComponent: AwesomeBarComponent
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -28,40 +28,54 @@ class SearchFragment : Fragment() {
|
|||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = inflater.inflate(R.layout.fragment_search, container, false)
|
||||
searchComponent = SearchComponent(view.toolbar_wrapper, ActionBusFactory.get(this),
|
||||
{ v -> transitionToBrowser(v) })
|
||||
toolbarComponent = ToolbarComponent(view.toolbar_wrapper, ActionBusFactory.get(this))
|
||||
awesomeBarComponent = AwesomeBarComponent(view.search_layout, ActionBusFactory.get(this))
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
searchComponent.editMode()
|
||||
toolbarComponent.editMode()
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
layoutComponents(view.search_layout)
|
||||
|
||||
lifecycle.addObserver(
|
||||
ToolbarIntegration(
|
||||
requireContext(),
|
||||
searchComponent.getView(),
|
||||
ShippedDomainsProvider().also { it.initialize(requireContext()) },
|
||||
requireComponents.core.historyStorage
|
||||
)
|
||||
)
|
||||
lifecycle.addObserver((toolbarComponent.uiView as ToolbarUIView).toolbarIntegration)
|
||||
|
||||
toolbar_wrapper.clipToOutline = false
|
||||
view.toolbar_wrapper.clipToOutline = false
|
||||
|
||||
toolbarComponent
|
||||
.getModelChangeEvents<SearchChange>()
|
||||
.subscribe {
|
||||
when (it) {
|
||||
is SearchChange.QueryChanged -> {
|
||||
ActionBusFactory.get(this).emit(AwesomeBarChange::class.java, AwesomeBarChange.UpdateQuery(it.query))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun transitionToBrowser(toolbar: View) {
|
||||
Navigation.findNavController(toolbar)
|
||||
toolbarComponent
|
||||
.getUserInteractionEvents<SearchAction>()
|
||||
.subscribe {
|
||||
when (it) {
|
||||
is SearchAction.UrlCommitted -> transitionToBrowser()
|
||||
}
|
||||
}
|
||||
|
||||
awesomeBarComponent
|
||||
.getUserInteractionEvents<AwesomeBarAction>()
|
||||
.subscribe {
|
||||
when (it) {
|
||||
is AwesomeBarAction.ItemSelected -> transitionToBrowser()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun transitionToBrowser() {
|
||||
Navigation.findNavController(view!!.search_layout)
|
||||
.navigate(R.id.action_searchFragment_to_browserFragment, null, null)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val toolbarTextSizeSp = 14f
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
|||
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID
|
||||
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.UNSET
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.android.synthetic.main.component_awesomebar.*
|
||||
import kotlinx.android.synthetic.main.fragment_search.*
|
||||
import mozilla.components.support.base.log.logger.Logger
|
||||
import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.BOTTOM
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package org.mozilla.fenix.search.awesomebar
|
||||
/* 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/. */
|
||||
|
||||
import android.view.ViewGroup
|
||||
import org.mozilla.fenix.mvi.*
|
||||
|
||||
data class AwesomeBarState(val query: String) : ViewState {
|
||||
fun updateQuery(query: String) = AwesomeBarState(query)
|
||||
}
|
||||
|
||||
sealed class AwesomeBarAction: Action {
|
||||
object ItemSelected: AwesomeBarAction()
|
||||
}
|
||||
|
||||
sealed class AwesomeBarChange : Change {
|
||||
data class UpdateQuery(val query: String): AwesomeBarChange()
|
||||
}
|
||||
|
||||
class AwesomeBarComponent(
|
||||
private val container: ViewGroup,
|
||||
override val bus: ActionBusFactory,
|
||||
override var initialState: AwesomeBarState = AwesomeBarState("")
|
||||
) : UIComponent<AwesomeBarState, AwesomeBarAction, AwesomeBarChange>(bus) {
|
||||
override val reducer: Reducer<AwesomeBarState, AwesomeBarChange> = { state, change ->
|
||||
when (change) {
|
||||
is AwesomeBarChange.UpdateQuery -> state.updateQuery(change.query)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() = AwesomeBarUIView(container, bus)
|
||||
|
||||
init {
|
||||
render(reducer)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package org.mozilla.fenix.search.awesomebar
|
||||
/* 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/. */
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import io.reactivex.functions.Consumer
|
||||
import mozilla.components.browser.awesomebar.BrowserAwesomeBar
|
||||
import mozilla.components.feature.awesomebar.provider.ClipboardSuggestionProvider
|
||||
import mozilla.components.feature.awesomebar.provider.SearchSuggestionProvider
|
||||
import mozilla.components.feature.awesomebar.provider.SessionSuggestionProvider
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.mvi.UIView
|
||||
|
||||
class AwesomeBarUIView(container: ViewGroup, bus: ActionBusFactory) :
|
||||
UIView<AwesomeBarState>(container, bus) {
|
||||
override val view: BrowserAwesomeBar = LayoutInflater.from(container.context)
|
||||
.inflate(R.layout.component_awesomebar, container, true)
|
||||
.findViewById(R.id.awesomeBar)
|
||||
|
||||
init {
|
||||
with(container.context) {
|
||||
view.addProviders(ClipboardSuggestionProvider(this, components.useCases.sessionUseCases.loadUrl))
|
||||
view.addProviders(SessionSuggestionProvider(components.core.sessionManager, components.useCases.tabsUseCases.selectTab))
|
||||
view.addProviders(SearchSuggestionProvider(
|
||||
components.search.searchEngineManager.getDefaultSearchEngine(this),
|
||||
components.useCases.searchUseCases.defaultSearch,
|
||||
SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS)
|
||||
)
|
||||
|
||||
view.setOnStopListener { bus.emit(AwesomeBarAction::class.java, AwesomeBarAction.ItemSelected) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateView() = Consumer<AwesomeBarState> {
|
||||
view.onInputChanged(it.query)
|
||||
}
|
||||
}
|
|
@ -2,14 +2,11 @@
|
|||
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
|
||||
package org.mozilla.fenix.search.toolbar
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.fragment_browser.*
|
||||
import mozilla.components.browser.toolbar.BrowserToolbar
|
||||
import mozilla.components.support.base.log.logger.Logger
|
||||
import org.mozilla.fenix.mvi.Action
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.mvi.Change
|
||||
|
@ -17,51 +14,36 @@ import org.mozilla.fenix.mvi.Reducer
|
|||
import org.mozilla.fenix.mvi.UIComponent
|
||||
import org.mozilla.fenix.mvi.ViewState
|
||||
|
||||
class SearchComponent(
|
||||
class ToolbarComponent(
|
||||
private val container: ViewGroup,
|
||||
override val bus: ActionBusFactory,
|
||||
private val onEditComplete: (View) -> Unit,
|
||||
override var initialState: SearchState = SearchState("")
|
||||
) :
|
||||
UIComponent<SearchState, SearchAction, SearchChange>(bus) {
|
||||
|
||||
override val reducer: Reducer<SearchState, SearchChange> = { state, change ->
|
||||
when (change) {
|
||||
is SearchChange.Changed -> state // TODO handle state changes here
|
||||
is SearchChange.QueryChanged -> state.updateQuery(change.query)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() = SearchUIView(container, bus)
|
||||
override fun initView() = ToolbarUIView(container, bus)
|
||||
init {
|
||||
setup()
|
||||
render(reducer)
|
||||
}
|
||||
|
||||
fun getView(): BrowserToolbar = uiView.toolbar
|
||||
fun editMode() = getView().editMode()
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun setup(): SearchComponent {
|
||||
render(reducer)
|
||||
getUserInteractionEvents<SearchAction>()
|
||||
.subscribe {
|
||||
Logger("SearchComponent").debug(it.toString())
|
||||
when (it) {
|
||||
is SearchAction.EditComplete -> {
|
||||
onEditComplete.invoke(getView())
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
data class SearchState(val term: String) : ViewState
|
||||
data class SearchState(val query: String) : ViewState {
|
||||
fun updateQuery(query: String) = SearchState(query)
|
||||
}
|
||||
|
||||
sealed class SearchAction : Action {
|
||||
object UrlClicked : SearchAction()
|
||||
object EditComplete : SearchAction()
|
||||
data class UrlCommitted(val url: String): SearchAction()
|
||||
}
|
||||
|
||||
sealed class SearchChange : Change {
|
||||
object Changed : SearchChange()
|
||||
data class QueryChanged(val query: String) : SearchChange()
|
||||
}
|
|
@ -2,25 +2,27 @@
|
|||
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
|
||||
package org.mozilla.fenix.search.toolbar
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import io.reactivex.functions.Consumer
|
||||
import kotlinx.android.synthetic.main.fragment_search.view.*
|
||||
import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider
|
||||
import mozilla.components.browser.toolbar.BrowserToolbar
|
||||
import mozilla.components.feature.awesomebar.AwesomeBarFeature
|
||||
import mozilla.components.feature.awesomebar.provider.SearchSuggestionProvider
|
||||
import mozilla.components.support.ktx.android.content.res.pxToDp
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.toolbar.ToolbarIntegration
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.mvi.UIView
|
||||
|
||||
class SearchUIView(container: ViewGroup, bus: ActionBusFactory) :
|
||||
class ToolbarUIView(container: ViewGroup, bus: ActionBusFactory) :
|
||||
UIView<SearchState>(container, bus) {
|
||||
|
||||
val toolbarIntegration: ToolbarIntegration
|
||||
|
||||
override val view: BrowserToolbar = LayoutInflater.from(container.context)
|
||||
.inflate(R.layout.component_search, container, true)
|
||||
.findViewById(R.id.toolbar)
|
||||
|
@ -30,10 +32,8 @@ class SearchUIView(container: ViewGroup, bus: ActionBusFactory) :
|
|||
|
||||
init {
|
||||
view.apply {
|
||||
onUrlClicked = {
|
||||
bus.emit(SearchAction::class.java, SearchAction.UrlClicked)
|
||||
false
|
||||
}
|
||||
onUrlClicked = { false }
|
||||
setOnUrlCommitListener { bus.emit(SearchAction::class.java, SearchAction.UrlCommitted(it)) }
|
||||
|
||||
browserActionMargin = resources.pxToDp(browserActionMarginDp)
|
||||
urlBoxView = urlBackground
|
||||
|
@ -43,20 +43,24 @@ class SearchUIView(container: ViewGroup, bus: ActionBusFactory) :
|
|||
textSize = toolbarTextSizeSp
|
||||
hint = context.getString(R.string.search_hint)
|
||||
hintColor = ContextCompat.getColor(context, R.color.searchText)
|
||||
|
||||
setOnEditListener(object : mozilla.components.concept.toolbar.Toolbar.OnEditListener {
|
||||
override fun onTextChanged(text: String) {
|
||||
bus.emit(SearchChange::class.java, SearchChange.QueryChanged(text))
|
||||
}
|
||||
|
||||
with(container.context) {
|
||||
AwesomeBarFeature(container.rootView.awesomeBar, view, null,
|
||||
onEditComplete = { bus.emit(SearchAction::class.java, SearchAction.EditComplete) })
|
||||
.addClipboardProvider(this, components.useCases.sessionUseCases.loadUrl)
|
||||
.addSearchProvider(
|
||||
components.search.searchEngineManager.getDefaultSearchEngine(this),
|
||||
components.useCases.searchUseCases.defaultSearch,
|
||||
SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS
|
||||
)
|
||||
.addSessionProvider(
|
||||
components.core.sessionManager,
|
||||
components.useCases.tabsUseCases.selectTab
|
||||
override fun onStopEditing() {
|
||||
bus.emit(SearchAction::class.java, SearchAction.UrlCommitted("foo"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
with(view.context) {
|
||||
toolbarIntegration = ToolbarIntegration(
|
||||
this,
|
||||
view,
|
||||
ShippedDomainsProvider().also { it.initialize(this) },
|
||||
components.core.historyStorage
|
||||
)
|
||||
}
|
||||
}
|
21
app/src/main/res/layout/component_awesomebar.xml
Normal file
21
app/src/main/res/layout/component_awesomebar.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
<mozilla.components.browser.awesomebar.BrowserAwesomeBar
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:mozac="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/awesomeBar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:padding="4dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar_wrapper"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/pill_wrapper"
|
||||
mozac:awesomeBarTitleTextColor="#212121"
|
||||
mozac:awesomeBarDescriptionTextColor="#6b6b6b"
|
||||
mozac:awesomeBarChipTextColor="#ffffff"
|
||||
mozac:awesomeBarChipBackgroundColor="#444444" />
|
|
@ -24,22 +24,6 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<mozilla.components.browser.awesomebar.BrowserAwesomeBar
|
||||
android:id="@+id/awesomeBar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:padding="4dp"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar_wrapper"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/pill_wrapper"
|
||||
mozac:awesomeBarTitleTextColor="#212121"
|
||||
mozac:awesomeBarDescriptionTextColor="#6b6b6b"
|
||||
mozac:awesomeBarChipTextColor="#ffffff"
|
||||
mozac:awesomeBarChipBackgroundColor="#444444" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/pill_wrapper"
|
||||
android:background="@color/offwhite"
|
||||
|
|
Loading…
Reference in New Issue
Block a user