Issue #21172: Replace BrowserAwesomeBar view with AwesomeBar() composable.

This commit is contained in:
Sebastian Kaspari 2021-09-07 19:41:05 +02:00 committed by mergify[bot]
parent a586d7e6cd
commit 6d99c34f12
10 changed files with 124 additions and 224 deletions

View File

@ -415,6 +415,9 @@ dependencies {
implementation Deps.sentry
implementation Deps.mozilla_compose_awesomebar
implementation Deps.mozilla_concept_awesomebar
implementation Deps.mozilla_concept_base
implementation Deps.mozilla_concept_engine
implementation Deps.mozilla_concept_menu
@ -424,8 +427,6 @@ dependencies {
implementation Deps.mozilla_concept_toolbar
implementation Deps.mozilla_concept_tabstray
implementation Deps.mozilla_browser_awesomebar
implementation Deps.mozilla_feature_downloads
implementation Deps.mozilla_browser_domains
implementation Deps.mozilla_browser_icons
implementation Deps.mozilla_browser_menu
@ -437,9 +438,7 @@ dependencies {
implementation Deps.mozilla_browser_thumbnails
implementation Deps.mozilla_browser_toolbar
implementation Deps.mozilla_support_extensions
implementation Deps.mozilla_feature_addons
implementation Deps.mozilla_feature_accounts
implementation Deps.mozilla_feature_app_links
implementation Deps.mozilla_feature_autofill
@ -484,13 +483,13 @@ dependencies {
implementation Deps.mozilla_service_location
implementation Deps.mozilla_service_nimbus
implementation Deps.mozilla_support_extensions
implementation Deps.mozilla_support_base
implementation Deps.mozilla_support_images
implementation Deps.mozilla_support_ktx
implementation Deps.mozilla_support_rustlog
implementation Deps.mozilla_support_utils
implementation Deps.mozilla_support_locale
implementation Deps.mozilla_support_migration
implementation Deps.mozilla_ui_colors

View File

@ -5,9 +5,9 @@
package org.mozilla.fenix.components.metrics
import androidx.annotation.VisibleForTesting
import mozilla.components.browser.awesomebar.facts.BrowserAwesomeBarFacts
import mozilla.components.browser.menu.facts.BrowserMenuFacts
import mozilla.components.browser.toolbar.facts.ToolbarFacts
import mozilla.components.compose.browser.awesomebar.AwesomeBarFacts as ComposeAwesomeBarFacts
import mozilla.components.concept.awesomebar.AwesomeBar
import mozilla.components.feature.autofill.facts.AutofillFacts
import mozilla.components.feature.awesomebar.facts.AwesomeBarFacts
@ -228,8 +228,8 @@ internal class ReleaseMetricController(
null
}
Component.BROWSER_AWESOMEBAR to BrowserAwesomeBarFacts.Items.PROVIDER_DURATION -> {
metadata?.get(BrowserAwesomeBarFacts.MetadataKeys.DURATION_PAIR)?.let { providerTiming ->
Component.COMPOSE_AWESOMEBAR to ComposeAwesomeBarFacts.Items.PROVIDER_DURATION -> {
metadata?.get(ComposeAwesomeBarFacts.MetadataKeys.DURATION_PAIR)?.let { providerTiming ->
require(providerTiming is Pair<*, *>) { "Expected providerTiming to be a Pair" }
when (val provider = providerTiming.first as AwesomeBar.SuggestionProvider) {
is HistoryStorageSuggestionProvider -> PerfAwesomebar.historySuggestions

View File

@ -196,7 +196,6 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
)
val awesomeBar = binding.awesomeBar
awesomeBar.customizeForBottomToolbar = requireContext().settings().shouldUseBottomToolbar
awesomeBarView = AwesomeBarView(
activity,

View File

@ -8,7 +8,6 @@ import androidx.appcompat.content.res.AppCompatResources.getDrawable
import androidx.core.graphics.BlendModeColorFilterCompat.createBlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat.SRC_IN
import androidx.core.graphics.drawable.toBitmap
import mozilla.components.browser.awesomebar.BrowserAwesomeBar
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.searchEngines
import mozilla.components.concept.awesomebar.AwesomeBar
@ -41,7 +40,7 @@ import org.mozilla.fenix.search.SearchFragmentState
class AwesomeBarView(
private val activity: HomeActivity,
val interactor: AwesomeBarInteractor,
val view: BrowserAwesomeBar,
val view: AwesomeBarWrapper,
private val fromHomeFragment: Boolean
) {
private val sessionProvider: SessionSuggestionProvider
@ -93,8 +92,6 @@ class AwesomeBarView(
}
init {
view.itemAnimator = null
val components = activity.components
val primaryTextColor = activity.getColorFromAttr(R.attr.primaryText)

View File

@ -0,0 +1,102 @@
/* 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.awesomebar
import android.content.Context
import android.util.AttributeSet
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.AbstractComposeView
import mozilla.components.compose.browser.awesomebar.AwesomeBar
import mozilla.components.compose.browser.awesomebar.AwesomeBarDefaults
import mozilla.components.compose.browser.awesomebar.AwesomeBarOrientation
import mozilla.components.concept.awesomebar.AwesomeBar
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.ThemeManager
/**
* This wrapper wraps the `AwesomeBar()` composable and exposes it as a `View` and `concept-awesomebar`
* implementation to be integrated in the view hierarchy of `SearchDialogFragment` until more parts
* of that screen have been refactored to use Jetpack Compose.
*/
class AwesomeBarWrapper @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AbstractComposeView(context, attrs, defStyleAttr), AwesomeBar {
private val providers = mutableStateOf(emptyList<AwesomeBar.SuggestionProvider>())
private val text = mutableStateOf("")
private var onEditSuggestionListener: ((String) -> Unit)? = null
private var onStopListener: (() -> Unit)? = null
@Composable
override fun Content() {
if (providers.value.isEmpty()) {
return
}
val orientation = if (context.settings().shouldUseBottomToolbar) {
AwesomeBarOrientation.BOTTOM
} else {
AwesomeBarOrientation.TOP
}
FirefoxTheme {
AwesomeBar(
text = text.value,
providers = providers.value,
orientation = orientation,
colors = AwesomeBarDefaults.colors(
background = Color.Transparent,
title = ThemeManager.resolveAttributeColor(R.attr.primaryText),
description = ThemeManager.resolveAttributeColor(R.attr.secondaryText),
autocompleteIcon = ThemeManager.resolveAttributeColor(R.attr.secondaryText)
),
onSuggestionClicked = { suggestion ->
suggestion.onSuggestionClicked?.invoke()
onStopListener?.invoke()
},
onAutoComplete = { suggestion ->
onEditSuggestionListener?.invoke(suggestion.editSuggestion!!)
}
)
}
}
override fun addProviders(vararg providers: AwesomeBar.SuggestionProvider) {
val newProviders = this.providers.value.toMutableList()
newProviders.addAll(providers)
this.providers.value = newProviders
}
override fun containsProvider(provider: AwesomeBar.SuggestionProvider): Boolean {
return providers.value.any { current -> current.id == provider.id }
}
override fun onInputChanged(text: String) {
this.text.value = text
}
override fun removeAllProviders() {
providers.value = emptyList()
}
override fun removeProviders(vararg providers: AwesomeBar.SuggestionProvider) {
val newProviders = this.providers.value.toMutableList()
newProviders.removeAll(providers)
this.providers.value = newProviders
}
override fun setOnEditSuggestionListener(listener: (String) -> Unit) {
onEditSuggestionListener = listener
}
override fun setOnStopListener(listener: () -> Unit) {
onStopListener = listener
}
}

View File

@ -14,6 +14,9 @@ import android.os.Build.VERSION.SDK_INT
import android.util.TypedValue
import android.view.Window
import androidx.annotation.StyleRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.view.getWindowInsetsController
import org.mozilla.fenix.HomeActivity
@ -72,6 +75,12 @@ abstract class ThemeManager {
return typedValue.resourceId
}
@Composable
fun resolveAttributeColor(attribute: Int): androidx.compose.ui.graphics.Color {
val resourceId = resolveAttribute(attribute, LocalContext.current)
return colorResource(resourceId)
}
private fun updateLightSystemBars(window: Window, context: Context) {
if (SDK_INT >= Build.VERSION_CODES.M) {
window.statusBarColor = context.getColorFromAttr(android.R.attr.statusBarColor)

View File

@ -1,205 +0,0 @@
<?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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/search_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?foundation"
tools:context=".search.SearchFragment">
<mozilla.components.browser.toolbar.BrowserToolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="@dimen/browser_toolbar_height"
android:background="@drawable/toolbar_background_top"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"
app:browserToolbarClearColor="?primaryText"
app:browserToolbarInsecureColor="?primaryText"
app:browserToolbarMenuColor="?primaryText"
app:browserToolbarProgressBarGravity="bottom"
app:browserToolbarSecureColor="?primaryText"
app:browserToolbarTrackingProtectionAndSecurityIndicatorSeparatorColor="?toolbarDivider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/scrollView"
app:layout_constraintBottom_toBottomOf="@id/search_divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"
android:scrollbars="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/scrollable_area"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<mozilla.components.browser.awesomebar.BrowserAwesomeBar
xmlns:mozac="http://schemas.android.com/apk/res-auto"
android:id="@+id/awesomeBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
android:fadingEdgeLength="40dp"
android:nestedScrollingEnabled="false"
android:requiresFadingEdge="vertical"
app:layout_constraintTop_toBottomOf="@id/search_engine_shortcut"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
mozac:awesomeBarDescriptionTextColor="?secondaryText"
mozac:awesomeBarTitleTextColor="?primaryText" />
<ViewStub
android:id="@+id/search_suggestions_onboarding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inflatedId="@id/search_suggestions_onboarding"
android:layout="@layout/search_suggestions_hint"
app:layout_constraintBottom_toTopOf="@id/awesomeBar_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/search_suggestions_onboarding_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?neutralFaded"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/search_suggestions_onboarding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/fill_link_from_clipboard"
android:layout_width="0dp"
android:layout_height="@dimen/search_fragment_clipboard_item_height"
android:layout_marginStart="@dimen/search_fragment_clipboard_item_horizontal_margin"
android:layout_marginTop="@dimen/search_fragment_clipboard_item_vertical_margin"
android:layout_marginEnd="@dimen/search_fragment_clipboard_item_horizontal_margin"
android:background="?selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="@id/scrollable_area"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/scrollable_area">
<ImageView
android:id="@+id/link_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:importantForAccessibility="no"
app:tint="?primaryText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_link" />
<TextView
android:id="@+id/clipboard_title"
style="@style/SearchClipboardTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/search_fragment_clipboard_item_title_margin_start"
android:text="@string/awesomebar_clipboard_title"
app:layout_constraintBottom_toTopOf="@id/clipboard_url"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/link_icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/clipboard_url"
style="@style/SearchClipboardUrlStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/clipboard_title"
app:layout_constraintTop_toBottomOf="@id/clipboard_title"
app:layout_constraintVertical_chainStyle="packed" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/divider_line"
android:layout_width="match_parent"
android:layout_height="1.5dp"
android:background="?neutralFaded"
app:layout_constraintEnd_toEndOf="@id/fill_link_from_clipboard"
app:layout_constraintStart_toStartOf="@id/fill_link_from_clipboard"
app:layout_constraintTop_toBottomOf="@id/fill_link_from_clipboard" />
<TextView
android:id="@+id/search_engine_shortcut"
style="@style/SearchEngineShortcutsLabelStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/search_fragment_shortcuts_label_margin_horizontal"
android:layout_marginTop="@dimen/search_fragment_shortcuts_label_margin_vertical"
android:layout_marginEnd="@dimen/search_fragment_shortcuts_label_margin_horizontal"
android:visibility="gone"
android:text="@string/search_engines_search_with"
app:layout_constraintStart_toStartOf="@id/scrollable_area"
app:layout_constraintTop_toBottomOf="@id/awesomeBar_barrier"
tools:text="@string/search_engines_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="fill_link_from_clipboard,search_engine_shortcut,search_suggestions_onboarding" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<View
android:id="@+id/search_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?neutralFaded"
app:layout_constraintBottom_toTopOf="@id/pill_wrapper"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<LinearLayout
android:id="@+id/pill_wrapper"
android:layout_width="0dp"
android:layout_height="@dimen/search_fragment_pill_height"
android:background="?foundation"
android:orientation="horizontal"
android:paddingStart="@dimen/search_fragment_pill_padding_start"
android:paddingTop="@dimen/search_fragment_pill_padding_vertical"
android:paddingEnd="@dimen/search_fragment_pill_padding_end"
android:paddingBottom="@dimen/search_fragment_pill_padding_vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ToggleButton
android:id="@+id/search_scan_button"
style="@style/search_pill"
android:layout_marginEnd="@dimen/search_fragment_scan_button_margin_end"
android:textOff="@string/search_scan_button"
android:textOn="@string/search_scan_button"
app:drawableStartCompat="@drawable/ic_qr" />
<ToggleButton
android:id="@+id/search_engines_shortcut_button"
style="@style/search_pill"
android:textOff="@string/search_engine_button"
android:textOn="@string/search_engine_button"
app:drawableStartCompat="@drawable/ic_search" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -59,7 +59,7 @@
app:barrierDirection="top"
app:constraint_referenced_ids="awesome_bar,pill_wrapper"/>
<mozilla.components.browser.awesomebar.BrowserAwesomeBar
<org.mozilla.fenix.search.awesomebar.AwesomeBarWrapper
xmlns:mozac="http://schemas.android.com/apk/res-auto"
android:id="@+id/awesome_bar"
android:layout_width="0dp"
@ -73,9 +73,7 @@
app:layout_constraintBottom_toTopOf="@+id/pill_wrapper"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/search_suggestions_hint"
mozac:awesomeBarDescriptionTextColor="?secondaryText"
mozac:awesomeBarTitleTextColor="?primaryText" />
app:layout_constraintTop_toBottomOf="@id/search_suggestions_hint" />
<View
android:id="@+id/fill_link_from_clipboard"

View File

@ -11,7 +11,6 @@
android:layout_height="match_parent"
android:scrollbars="vertical"
android:fadeScrollbars="false"
app:layout_constraintBottom_toBottomOf="@id/search_divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">

View File

@ -69,6 +69,9 @@ object Deps {
const val allopen = "org.jetbrains.kotlin:kotlin-allopen:${Versions.kotlin}"
const val osslicenses_plugin = "com.google.android.gms:oss-licenses-plugin:${Versions.osslicenses_plugin}"
const val mozilla_compose_awesomebar = "org.mozilla.components:compose-awesomebar:${Versions.mozilla_android_components}"
const val mozilla_concept_awesomebar = "org.mozilla.components:concept-awesomebar:${Versions.mozilla_android_components}"
const val mozilla_concept_base = "org.mozilla.components:concept-base:${Versions.mozilla_android_components}"
const val mozilla_concept_engine = "org.mozilla.components:concept-engine:${Versions.mozilla_android_components}"
const val mozilla_concept_menu = "org.mozilla.components:concept-menu:${Versions.mozilla_android_components}"
@ -78,7 +81,6 @@ object Deps {
const val mozilla_concept_storage = "org.mozilla.components:concept-storage:${Versions.mozilla_android_components}"
const val mozilla_concept_sync = "org.mozilla.components:concept-sync:${Versions.mozilla_android_components}"
const val mozilla_browser_awesomebar = "org.mozilla.components:browser-awesomebar:${Versions.mozilla_android_components}"
const val mozilla_browser_engine_gecko = "org.mozilla.components:browser-engine-gecko:${Versions.mozilla_android_components}"
const val mozilla_browser_domains = "org.mozilla.components:browser-domains:${Versions.mozilla_android_components}"
const val mozilla_browser_icons = "org.mozilla.components:browser-icons:${Versions.mozilla_android_components}"