Add beta label to backups.

This commit is contained in:
Michelle Tang
2025-05-06 10:43:05 -04:00
parent b0aee1db05
commit 1800507604
6 changed files with 172 additions and 17 deletions

View File

@@ -32,6 +32,8 @@ import org.signal.core.ui.compose.Buttons
import org.signal.core.ui.compose.Previews
import org.signal.core.ui.compose.Scaffolds
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.compose.BetaHeader
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
import org.signal.core.ui.R as CoreUiR
/**
@@ -62,6 +64,10 @@ fun MessageBackupsEducationScreen(
.fillMaxWidth()
.weight(1f)
) {
item {
BetaHeader()
}
item {
Image(
painter = painterResource(id = R.drawable.image_signal_backups),
@@ -73,9 +79,9 @@ fun MessageBackupsEducationScreen(
}
item {
Text(
TextWithBetaLabel(
text = stringResource(id = R.string.RemoteBackupsSettingsFragment__signal_backups),
style = MaterialTheme.typography.headlineMedium,
textStyle = MaterialTheme.typography.headlineMedium,
modifier = Modifier.padding(top = 15.dp)
)
}

View File

@@ -0,0 +1,92 @@
package org.thoughtcrime.securesms.components.compose
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import org.signal.core.ui.compose.Previews
import org.signal.core.ui.compose.SignalPreview
import org.thoughtcrime.securesms.R
/**
* Adds a 'Beta' label next to [text] to indicate a feature is in development
*/
@Composable
fun TextWithBetaLabel(
text: String,
textStyle: TextStyle = TextStyle.Default,
modifier: Modifier = Modifier
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
) {
Text(
text = text,
style = textStyle
)
Text(
text = stringResource(R.string.Beta__beta_title).uppercase(),
color = MaterialTheme.colorScheme.onPrimaryContainer,
style = MaterialTheme.typography.labelSmall,
modifier = Modifier
.padding(horizontal = 4.dp)
.background(color = MaterialTheme.colorScheme.surfaceVariant, shape = RoundedCornerShape(28.dp))
.padding(horizontal = 12.dp, vertical = 4.dp)
)
}
}
/**
* 'Beta' header to indicate a feature is currently in development
*/
@Composable
fun BetaHeader(modifier: Modifier = Modifier) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.background(
color = MaterialTheme.colorScheme.surfaceVariant,
shape = RoundedCornerShape(12.dp)
)
.padding(16.dp)
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.symbol_info_24),
contentDescription = stringResource(id = R.string.Beta__info),
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
Text(
text = stringResource(id = R.string.Beta__this_is_beta),
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(start = 12.dp)
)
}
}
@SignalPreview
@Composable
fun BetaLabelPreview() {
Previews.Preview {
TextWithBetaLabel("Signal Backups")
}
}
@SignalPreview
@Composable
fun BetaHeaderPreview() {
Previews.Preview {
BetaHeader()
}
}

View File

@@ -29,12 +29,14 @@ import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.fragment.app.viewModels
@@ -64,6 +66,7 @@ import org.thoughtcrime.securesms.banner.banners.UnauthorizedBanner
import org.thoughtcrime.securesms.banner.ui.compose.Action
import org.thoughtcrime.securesms.banner.ui.compose.DefaultBanner
import org.thoughtcrime.securesms.banner.ui.compose.Importance
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
import org.thoughtcrime.securesms.components.emoji.Emojifier
import org.thoughtcrime.securesms.components.settings.app.subscription.BadgeImageMedium
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
@@ -371,8 +374,19 @@ private fun AppSettingsContent(
if (state.showBackups) {
item {
Rows.TextRow(
text = stringResource(R.string.preferences_chats__backups),
icon = painterResource(R.drawable.symbol_backup_24),
text = {
TextWithBetaLabel(
text = stringResource(R.string.preferences_chats__backups),
textStyle = MaterialTheme.typography.bodyLarge
)
},
icon = {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.symbol_backup_24),
contentDescription = stringResource(R.string.preferences_chats__backups),
tint = MaterialTheme.colorScheme.onSurface
)
},
onClick = {
callbacks.navigate(R.id.action_appSettingsFragment_to_backupsSettingsFragment)
},

View File

@@ -27,10 +27,12 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import androidx.fragment.app.viewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -46,6 +48,7 @@ import org.signal.core.util.money.FiatMoney
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
import org.thoughtcrime.securesms.components.settings.app.subscription.MessageBackupsCheckoutLauncher.createBackupsCheckoutLauncher
import org.thoughtcrime.securesms.compose.ComposeFragment
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
@@ -228,9 +231,7 @@ private fun NeverEnabledBackupsRow(
},
text = {
Column {
Text(
text = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups)
)
TextWithBetaLabel(text = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups))
Text(
text = stringResource(R.string.BackupsSettingsFragment_automatic_backups_with_signals),
@@ -268,9 +269,23 @@ private fun InactiveBackupsRow(
onBackupsRowClick: () -> Unit = {}
) {
Rows.TextRow(
text = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups),
label = stringResource(R.string.preferences_off),
icon = painterResource(R.drawable.symbol_backup_24),
text = {
Column {
TextWithBetaLabel(text = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups))
Text(
text = stringResource(R.string.preferences_off),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
},
icon = {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.symbol_backup_24),
contentDescription = stringResource(R.string.preferences_chats__backups),
tint = MaterialTheme.colorScheme.onSurface
)
},
onClick = onBackupsRowClick
)
}
@@ -297,9 +312,7 @@ private fun ActiveBackupsRow(
},
text = {
Column {
Text(
text = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups)
)
TextWithBetaLabel(text = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups))
when (enabledState.type) {
is MessageBackupsType.Paid -> {

View File

@@ -38,10 +38,12 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
@@ -52,6 +54,7 @@ import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
@@ -93,6 +96,8 @@ import org.thoughtcrime.securesms.backup.v2.ui.status.BackupStatusData
import org.thoughtcrime.securesms.backup.v2.ui.status.BackupStatusRow
import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
import org.thoughtcrime.securesms.billing.launchManageBackupsSubscription
import org.thoughtcrime.securesms.components.compose.BetaHeader
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.components.settings.app.subscription.MessageBackupsCheckoutLauncher.createBackupsCheckoutLauncher
import org.thoughtcrime.securesms.compose.ComposeFragment
@@ -343,6 +348,7 @@ private interface ContentCallbacks {
fun onRedemptionErrorDetailsClick() = Unit
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun RemoteBackupsSettingsContent(
backupsEnabled: Boolean,
@@ -363,10 +369,22 @@ private fun RemoteBackupsSettingsContent(
SnackbarHostState()
}
Scaffolds.Settings(
title = stringResource(id = R.string.RemoteBackupsSettingsFragment__signal_backups),
onNavigationClick = contentCallbacks::onNavigationClick,
navigationIconPainter = painterResource(id = R.drawable.symbol_arrow_start_24),
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
Scaffold(
topBar = {
Scaffolds.DefaultTopAppBar(
title = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups),
titleContent = { _, title ->
TextWithBetaLabel(text = title, textStyle = MaterialTheme.typography.titleLarge)
},
onNavigationClick = contentCallbacks::onNavigationClick,
navigationIconPainter = painterResource(R.drawable.symbol_arrow_start_24),
navigationContentDescription = stringResource(R.string.DefaultTopAppBar__navigate_up_content_description),
scrollBehavior = scrollBehavior
)
},
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
snackbarHost = {
Snackbars.Host(snackbarHostState = snackbarHostState)
}
@@ -375,6 +393,10 @@ private fun RemoteBackupsSettingsContent(
modifier = Modifier
.padding(it)
) {
item {
BetaHeader(modifier = Modifier.padding(horizontal = 16.dp))
}
if (hasRedemptionError) {
item {
RedemptionErrorAlert(onDetailsClick = contentCallbacks::onRedemptionErrorDetailsClick)

View File

@@ -4778,6 +4778,14 @@
<string name="RegistrationActivity_you_have_made_too_many_attempts_please_try_again_later">You\'ve made too many attempts. Please try again later.</string>
<string name="RegistrationActivity_error_connecting_to_service">Error connecting to service</string>
<string name="preferences_chats__backups">Backups</string>
<!-- Button label to indicate that a feature is in beta mode -->
<string name="Beta__beta_title">Beta</string>
<!-- Content description for info icon -->
<string name="Beta__info">Info</string>
<!-- Text in header describing that the feature is a beta feature and prone to frequent changes -->
<string name="Beta__this_is_beta">This is a beta feature that we will be adding functionality to on an ongoing basis.</string>
<!-- Title text shown when Signal is locked and needs to be unlocked -->
<string name="prompt_passphrase_activity__unlock_signal">Unlock Signal</string>
<!-- Description text explaining how to unlock Signal -->