commit 4e7e6856b97324421e332a86578697a8f0c78093
parent 54d25f5169e652ac6fa46fe988b5749a1c60d8f0
Author: mike a. <mavduevskiy@mozilla.com>
Date: Tue, 9 Dec 2025 21:22:22 +0000
Bug 1996715 - Add a relay ui prompt r=android-reviewers,android-l10n-reviewers,flod,gmalekpour
Differential Revision: https://phabricator.services.mozilla.com/D274366
Diffstat:
6 files changed, 172 insertions(+), 0 deletions(-)
diff --git a/mobile/android/android-components/.buildconfig.yml b/mobile/android/android-components/.buildconfig.yml
@@ -2059,10 +2059,16 @@ projects:
path: components/service/firefox-relay
publish: false
upstream_dependencies:
+ - components:compose-base
- components:concept-base
- components:concept-fetch
+ - components:lib-publicsuffixlist
- components:support-base
+ - components:support-ktx
+ - components:support-utils
- components:tooling-lint
+ - components:ui-colors
+ - components:ui-icons
components:service-glean:
description: A client-side telemetry SDK for collecting metrics and sending them
to the Mozilla telemetry service
diff --git a/mobile/android/android-components/components/service/firefox-relay/build.gradle b/mobile/android/android-components/components/service/firefox-relay/build.gradle
@@ -19,18 +19,34 @@ buildscript {
}
}
+plugins {
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.kotlin.compose)
+}
+
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
android {
+ buildFeatures {
+ compose = true
+ }
+
namespace = 'mozilla.components.service.fxrelay'
}
dependencies {
implementation ComponentsDependencies.mozilla_appservices_fxrelay
implementation project(':components:support-base')
+ implementation project(':components:compose-base')
+ implementation project(":components:ui-icons")
+
implementation libs.kotlinx.coroutines.core
+ implementation libs.androidx.compose.foundation
+ implementation libs.androidx.compose.material3
+ implementation libs.androidx.compose.ui
+ implementation libs.androidx.compose.ui.tooling.preview
}
apply from: '../../../common-config.gradle'
diff --git a/mobile/android/android-components/components/service/firefox-relay/src/main/java/mozilla/components/service/fxrelay/view/RelayPrompt.kt b/mobile/android/android-components/components/service/firefox-relay/src/main/java/mozilla/components/service/fxrelay/view/RelayPrompt.kt
@@ -0,0 +1,94 @@
+/* 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 mozilla.components.service.fxrelay.view
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.material3.minimumInteractiveComponentSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.PreviewLightDark
+import androidx.compose.ui.unit.dp
+import mozilla.components.compose.base.theme.AcornTheme
+import mozilla.components.ui.icons.R
+
+/**
+ * A bar for displaying relay related actions.
+ *
+ * @param onMaskEmailClicked a mask email chip click listener.
+ */
+@Composable
+fun RelayPromptBar(
+ onMaskEmailClicked: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ Row(
+ modifier = modifier
+ .fillMaxWidth()
+ .background(color = MaterialTheme.colorScheme.surface)
+ .padding(horizontal = 16.dp),
+ ) {
+ MaskEmailChip(
+ onClick = onMaskEmailClicked,
+ )
+ }
+}
+
+@Composable
+private fun MaskEmailChip(
+ onClick: () -> Unit,
+) {
+ Surface(
+ modifier = Modifier
+ .clickable(onClick = onClick)
+ .minimumInteractiveComponentSize(),
+ shape = RoundedCornerShape(20.dp),
+ color = MaterialTheme.colorScheme.primaryContainer,
+ ) {
+ Row(
+ modifier = Modifier
+ .padding(horizontal = 12.dp, vertical = 8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Icon(
+ painter = painterResource(R.drawable.mozac_ic_mask_email_24),
+ contentDescription = null, // talkback should focus on the whole element
+ modifier = Modifier.size(16.dp),
+ tint = AcornTheme.colors.iconPrimary,
+ )
+
+ Spacer(modifier = Modifier.size(8.dp))
+
+ Text(
+ text = stringResource(mozilla.components.service.fxrelay.R.string.mozac_feature_relay_chip_text),
+ style = AcornTheme.typography.headline8,
+ color = MaterialTheme.colorScheme.onSurface,
+ )
+ }
+ }
+}
+
+@PreviewLightDark
+@Composable
+private fun RelayPromptBarPreview() {
+ AcornTheme {
+ RelayPromptBar(
+ onMaskEmailClicked = {},
+ )
+ }
+}
diff --git a/mobile/android/android-components/components/service/firefox-relay/src/main/java/mozilla/components/service/fxrelay/view/RelayPromptBarView.kt b/mobile/android/android-components/components/service/firefox-relay/src/main/java/mozilla/components/service/fxrelay/view/RelayPromptBarView.kt
@@ -0,0 +1,31 @@
+/* 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 mozilla.components.service.fxrelay.view
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.AbstractComposeView
+import mozilla.components.compose.base.theme.AcornTheme
+
+/**
+ * The top-level view holder for the Relay Prompt Bar.
+ */
+class RelayPromptBarView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+) : AbstractComposeView(context, attrs, defStyleAttr) {
+ @Composable
+ override fun Content() {
+ AcornTheme {
+ RelayPromptBar(
+ onMaskEmailClicked = {
+ // logic should be added in https://bugzilla.mozilla.org/show_bug.cgi?id=1996725
+ },
+ )
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/service/firefox-relay/src/main/res/values/strings.xml b/mobile/android/android-components/components/service/firefox-relay/src/main/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- 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/. -->
+<resources>
+ <!-- Text for the Relay prompt to allow users to fill the form with with an email alias -->
+ <string name="mozac_feature_relay_chip_text">Use email mask</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_mask_email_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_mask_email_24.xml
@@ -0,0 +1,17 @@
+<!-- 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/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M8.549,14.264C8.549,14.26 8.55,14.255 8.55,14.25H3.913C3.823,14.25 3.75,14.174 3.75,14.081V7.809L8.7,11.806C8.86,11.935 9.056,12 9.25,12C9.444,12 9.64,11.935 9.8,11.806L14.75,7.809V12.215C15.194,12.453 15.62,12.727 15.999,13.077C16.11,12.974 16.232,12.886 16.354,12.798C16.403,12.763 16.452,12.728 16.5,12.692V6.919C16.5,5.861 15.642,5 14.587,5H3.913C2.858,5 2,5.861 2,6.919V14.08C2,15.139 2.858,16 3.913,16H8.541C8.497,15.366 8.487,14.725 8.547,14.279C8.547,14.274 8.548,14.269 8.549,14.264ZM9.25,10L5.224,6.75H13.276L9.25,10Z"
+ android:fillColor="#000000"
+ android:fillType="evenOdd"/>
+ <path
+ android:pathData="M20.996,13.113C21.576,13.247 21.978,13.788 21.948,14.395C22.105,15.002 21.868,17.198 21.738,17.545C21.478,18.946 20.356,20 19.012,20C18.391,20 17.823,19.767 17.36,19.387V19.389L16.921,19.017C16.373,18.553 15.578,18.56 15.037,19.032L14.744,19.288C14.263,19.726 13.655,20 12.984,20C11.64,20 10.519,18.946 10.257,17.544C10.128,17.197 9.899,14.991 10.047,14.394V14.391C10.019,13.786 10.42,13.247 10.999,13.113H11C12.438,12.779 13.945,13.194 15.024,14.22L15.205,14.392C15.42,14.597 15.704,14.711 15.998,14.711C16.292,14.711 16.575,14.597 16.79,14.393L16.975,14.218C18.054,13.193 19.559,12.78 20.996,13.113ZM14.246,17.102C14.409,17.006 14.554,16.886 14.674,16.748C14.842,16.555 14.842,16.25 14.674,16.055C14.354,15.685 13.858,15.448 13.3,15.448C12.882,15.448 12.498,15.582 12.197,15.804C12.137,15.849 12.081,15.897 12.028,15.948C11.992,15.982 11.958,16.018 11.926,16.055C11.758,16.249 11.758,16.554 11.926,16.748C12.246,17.117 12.742,17.355 13.3,17.355C13.649,17.355 13.973,17.262 14.246,17.102ZM20.074,16.748C19.754,17.117 19.258,17.355 18.7,17.355C18.142,17.355 17.646,17.117 17.326,16.748C17.158,16.554 17.158,16.249 17.326,16.055C17.646,15.686 18.142,15.448 18.7,15.448C19.258,15.448 19.754,15.685 20.074,16.055C20.242,16.25 20.242,16.555 20.074,16.748Z"
+ android:fillColor="#000000"
+ android:fillType="evenOdd"/>
+</vector>