diff --git a/app/build.gradle b/app/build.gradle index 910cb6708f..22cc3e8a79 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt index 309df950da..5b4cb2e541 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt @@ -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 diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt index 4a0e714fdc..ffd1fce441 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt @@ -196,7 +196,6 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { ) val awesomeBar = binding.awesomeBar - awesomeBar.customizeForBottomToolbar = requireContext().settings().shouldUseBottomToolbar awesomeBarView = AwesomeBarView( activity, diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt index 0d8c288abb..959953f565 100644 --- a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt @@ -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) diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarWrapper.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarWrapper.kt new file mode 100644 index 0000000000..110845b956 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarWrapper.kt @@ -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()) + 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 + } +} diff --git a/app/src/main/java/org/mozilla/fenix/theme/ThemeManager.kt b/app/src/main/java/org/mozilla/fenix/theme/ThemeManager.kt index c67e0368df..4c89e68bba 100644 --- a/app/src/main/java/org/mozilla/fenix/theme/ThemeManager.kt +++ b/app/src/main/java/org/mozilla/fenix/theme/ThemeManager.kt @@ -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) diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml deleted file mode 100644 index da0653431b..0000000000 --- a/app/src/main/res/layout/fragment_search.xml +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_search_dialog.xml b/app/src/main/res/layout/fragment_search_dialog.xml index b41fcf7c19..aa8c8a2d40 100644 --- a/app/src/main/res/layout/fragment_search_dialog.xml +++ b/app/src/main/res/layout/fragment_search_dialog.xml @@ -59,7 +59,7 @@ app:barrierDirection="top" app:constraint_referenced_ids="awesome_bar,pill_wrapper"/> - + app:layout_constraintTop_toBottomOf="@id/search_suggestions_hint" /> diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index c1a11a6995..8cf74fc072 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -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}"