mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-25 05:27:42 +00:00
Backups ui polish.
This commit is contained in:
committed by
Cody Henthorne
parent
0e4c09224c
commit
7ee1b1386b
@@ -43,6 +43,8 @@ import org.thoughtcrime.securesms.R
|
||||
import kotlin.math.roundToInt
|
||||
import org.signal.core.ui.R as CoreUiR
|
||||
|
||||
private val YELLOW_DOT = Color(0xFFFFCC00)
|
||||
|
||||
/**
|
||||
* Backup status displayable as a row on a settings page.
|
||||
*/
|
||||
@@ -106,12 +108,12 @@ fun BackupStatusRow(
|
||||
BackupStatusData.CouldNotCompleteBackup -> {
|
||||
val inlineContentMap = mapOf(
|
||||
"yellow_bullet" to InlineTextContent(
|
||||
Placeholder(12.sp, 12.sp, PlaceholderVerticalAlign.TextCenter)
|
||||
Placeholder(20.sp, 12.sp, PlaceholderVerticalAlign.TextCenter)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(12.dp)
|
||||
.background(color = backupStatusData.iconColors.foreground, shape = CircleShape)
|
||||
.background(color = YELLOW_DOT, shape = CircleShape)
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -129,12 +131,12 @@ fun BackupStatusRow(
|
||||
BackupStatusData.BackupFailed -> {
|
||||
val inlineContentMap = mapOf(
|
||||
"yellow_bullet" to InlineTextContent(
|
||||
Placeholder(12.sp, 12.sp, PlaceholderVerticalAlign.TextCenter)
|
||||
Placeholder(20.sp, 12.sp, PlaceholderVerticalAlign.TextCenter)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(12.dp)
|
||||
.background(color = backupStatusData.iconColors.foreground, shape = CircleShape)
|
||||
.background(color = YELLOW_DOT, shape = CircleShape)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@ import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
@@ -54,6 +55,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.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.colorResource
|
||||
@@ -61,6 +63,7 @@ import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -69,6 +72,7 @@ import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import org.signal.core.ui.compose.Buttons
|
||||
import org.signal.core.ui.compose.Dialogs
|
||||
import org.signal.core.ui.compose.Dividers
|
||||
@@ -101,8 +105,6 @@ 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
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.signalSymbolText
|
||||
import org.thoughtcrime.securesms.help.HelpFragment
|
||||
import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
||||
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
|
||||
@@ -241,6 +243,10 @@ class RemoteBackupsSettingsFragment : ComposeFragment() {
|
||||
// TODO - [backups] Need process here (cancel first?)
|
||||
}
|
||||
|
||||
override fun onCancelUploadClick() {
|
||||
viewModel.cancelUpload()
|
||||
}
|
||||
|
||||
override fun onContactSupport() {
|
||||
requireActivity().finish()
|
||||
requireActivity().startActivity(AppSettingsActivity.help(requireContext(), HelpFragment.REMOTE_BACKUPS_INDEX))
|
||||
@@ -328,6 +334,7 @@ private interface ContentCallbacks {
|
||||
fun onBackupTypeActionClick(tier: MessageBackupTier) = Unit
|
||||
fun onBackUpUsingCellularClick(canUseCellular: Boolean) = Unit
|
||||
fun onBackupNowClick() = Unit
|
||||
fun onCancelUploadClick() = Unit
|
||||
fun onTurnOffAndDeleteBackupsClick() = Unit
|
||||
fun onChangeBackupFrequencyClick() = Unit
|
||||
fun onDialogDismissed() = Unit
|
||||
@@ -445,43 +452,9 @@ private fun RemoteBackupsSettingsContent(
|
||||
}
|
||||
|
||||
if (backupsEnabled) {
|
||||
if (backupRestoreState !is BackupRestoreState.None) {
|
||||
item {
|
||||
Dividers.Default()
|
||||
}
|
||||
|
||||
if (backupRestoreState is BackupRestoreState.FromBackupStatusData) {
|
||||
item {
|
||||
BackupStatusRow(
|
||||
backupStatusData = backupRestoreState.backupStatusData,
|
||||
onCancelClick = contentCallbacks::onCancelMediaRestore,
|
||||
onSkipClick = contentCallbacks::onSkipMediaRestore,
|
||||
onLearnMoreClick = contentCallbacks::onLearnMoreAboutBackupFailure
|
||||
)
|
||||
}
|
||||
|
||||
if (!canRestoreUsingCellular) {
|
||||
item {
|
||||
Rows.TextRow(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__resume_download),
|
||||
icon = painterResource(R.drawable.symbol_arrow_circle_down_24),
|
||||
onClick = contentCallbacks::onRestoreUsingCellularConfirm
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (backupRestoreState is BackupRestoreState.Ready) {
|
||||
item {
|
||||
BackupReadyToDownloadRow(
|
||||
ready = backupRestoreState,
|
||||
backupState = backupState,
|
||||
onDownloadClick = contentCallbacks::onStartMediaRestore
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appendBackupDetailsItems(
|
||||
backupState = backupState,
|
||||
backupRestoreState = backupRestoreState,
|
||||
backupProgress = backupProgress,
|
||||
lastBackupTimestamp = lastBackupTimestamp,
|
||||
backupMediaSize = backupMediaSize,
|
||||
@@ -618,6 +591,7 @@ private fun RemoteBackupsSettingsContent(
|
||||
|
||||
private fun LazyListScope.appendBackupDetailsItems(
|
||||
backupState: RemoteBackupsSettingsState.BackupState,
|
||||
backupRestoreState: BackupRestoreState,
|
||||
backupProgress: ArchiveUploadProgressState?,
|
||||
lastBackupTimestamp: Long,
|
||||
backupMediaSize: Long,
|
||||
@@ -634,6 +608,37 @@ private fun LazyListScope.appendBackupDetailsItems(
|
||||
Texts.SectionHeader(text = stringResource(id = R.string.RemoteBackupsSettingsFragment__backup_details))
|
||||
}
|
||||
|
||||
if (backupRestoreState !is BackupRestoreState.None) {
|
||||
if (backupRestoreState is BackupRestoreState.FromBackupStatusData) {
|
||||
item {
|
||||
BackupStatusRow(
|
||||
backupStatusData = backupRestoreState.backupStatusData,
|
||||
onCancelClick = contentCallbacks::onCancelMediaRestore,
|
||||
onSkipClick = contentCallbacks::onSkipMediaRestore,
|
||||
onLearnMoreClick = contentCallbacks::onLearnMoreAboutBackupFailure
|
||||
)
|
||||
}
|
||||
|
||||
if (!canRestoreUsingCellular) {
|
||||
item {
|
||||
Rows.TextRow(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__resume_download),
|
||||
icon = painterResource(R.drawable.symbol_arrow_circle_down_24),
|
||||
onClick = contentCallbacks::onRestoreUsingCellularConfirm
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (backupRestoreState is BackupRestoreState.Ready) {
|
||||
item {
|
||||
BackupReadyToDownloadRow(
|
||||
ready = backupRestoreState,
|
||||
backupState = backupState,
|
||||
onDownloadClick = contentCallbacks::onStartMediaRestore
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backupProgress == null || backupProgress.state == ArchiveUploadProgressState.State.None) {
|
||||
item {
|
||||
LastBackupRow(
|
||||
@@ -643,7 +648,10 @@ private fun LazyListScope.appendBackupDetailsItems(
|
||||
}
|
||||
} else {
|
||||
item {
|
||||
InProgressBackupRow(archiveUploadProgressState = backupProgress)
|
||||
InProgressBackupRow(
|
||||
archiveUploadProgressState = backupProgress,
|
||||
cancelArchiveUpload = contentCallbacks::onCancelUploadClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -736,10 +744,7 @@ private fun BackupCard(
|
||||
}
|
||||
|
||||
Text(
|
||||
text = signalSymbolText(
|
||||
text = title,
|
||||
glyphStart = if (backupState.isActive()) SignalSymbols.Glyph.CHECK else null
|
||||
),
|
||||
text = title,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
@@ -834,7 +839,7 @@ private fun CallToActionButton(
|
||||
text: String,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Buttons.LargeTonal(
|
||||
Buttons.MediumTonal(
|
||||
onClick = onClick,
|
||||
colors = ButtonDefaults.filledTonalButtonColors().copy(
|
||||
containerColor = SignalTheme.colors.colorTransparent5,
|
||||
@@ -1010,7 +1015,7 @@ private fun SubscriptionNotFoundCard(
|
||||
Row(
|
||||
horizontalArrangement = spacedBy(16.dp)
|
||||
) {
|
||||
Buttons.LargeTonal(
|
||||
Buttons.MediumTonal(
|
||||
onClick = onRenewClick,
|
||||
colors = ButtonDefaults.filledTonalButtonColors().copy(
|
||||
containerColor = SignalTheme.colors.colorTransparent5,
|
||||
@@ -1025,7 +1030,7 @@ private fun SubscriptionNotFoundCard(
|
||||
)
|
||||
}
|
||||
|
||||
Buttons.LargeTonal(
|
||||
Buttons.MediumTonal(
|
||||
onClick = onLearnMoreClick,
|
||||
colors = ButtonDefaults.filledTonalButtonColors().copy(
|
||||
containerColor = SignalTheme.colors.colorTransparent5,
|
||||
@@ -1060,7 +1065,8 @@ private fun SubscriptionMismatchMissingGooglePlayCard(
|
||||
|
||||
@Composable
|
||||
private fun InProgressBackupRow(
|
||||
archiveUploadProgressState: ArchiveUploadProgressState
|
||||
archiveUploadProgressState: ArchiveUploadProgressState,
|
||||
cancelArchiveUpload: () -> Unit = {}
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -1068,26 +1074,23 @@ private fun InProgressBackupRow(
|
||||
.padding(top = 16.dp, bottom = 14.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = spacedBy(12.dp)
|
||||
) {
|
||||
when (archiveUploadProgressState.state) {
|
||||
ArchiveUploadProgressState.State.None -> {
|
||||
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
|
||||
ArchiveProgressIndicator()
|
||||
}
|
||||
ArchiveUploadProgressState.State.Export -> {
|
||||
val progressValue by animateFloatAsState(targetValue = archiveUploadProgressState.frameExportProgress(), animationSpec = tween(durationMillis = 250))
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
progress = { progressValue },
|
||||
drawStopIndicator = {}
|
||||
)
|
||||
ArchiveProgressIndicator(progress = { progressValue })
|
||||
}
|
||||
ArchiveUploadProgressState.State.UploadBackupFile, ArchiveUploadProgressState.State.UploadMedia -> {
|
||||
val progressValue by animateFloatAsState(targetValue = archiveUploadProgressState.uploadProgress(), animationSpec = tween(durationMillis = 250))
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
ArchiveProgressIndicator(
|
||||
progress = { progressValue },
|
||||
drawStopIndicator = {}
|
||||
isCancelable = true,
|
||||
cancel = cancelArchiveUpload
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1101,6 +1104,31 @@ private fun InProgressBackupRow(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ArchiveProgressIndicator(
|
||||
progress: () -> Float = { 0f },
|
||||
isCancelable: Boolean = false,
|
||||
cancel: () -> Unit = {}
|
||||
) {
|
||||
Row {
|
||||
LinearProgressIndicator(
|
||||
trackColor = MaterialTheme.colorScheme.secondaryContainer,
|
||||
progress = progress,
|
||||
drawStopIndicator = {},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
if (isCancelable) {
|
||||
IconButton(onClick = cancel) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.symbol_x_24),
|
||||
contentDescription = stringResource(R.string.RemoteBackupsSettingsFragment__cancel_upload)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getProgressStateMessage(archiveUploadProgressState: ArchiveUploadProgressState): String {
|
||||
return when (archiveUploadProgressState.state) {
|
||||
@@ -1735,13 +1763,6 @@ private fun BackupFrequencyDialogPreview() {
|
||||
}
|
||||
}
|
||||
|
||||
private data class BackupProgress(
|
||||
val completed: Long,
|
||||
val total: Long
|
||||
) {
|
||||
val progress: Float = if (total > 0) completed / total.toFloat() else 0f
|
||||
}
|
||||
|
||||
private fun ArchiveUploadProgressState.frameExportProgress(): Float {
|
||||
return if (this.frameTotalCount == 0L) {
|
||||
0f
|
||||
|
||||
@@ -213,6 +213,10 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
||||
BackupMessagesJob.enqueue()
|
||||
}
|
||||
|
||||
fun cancelUpload() {
|
||||
// TODO [message-backups] -- Perform cancel of media upload.
|
||||
}
|
||||
|
||||
private suspend fun refreshState(lastPurchase: InAppPaymentTable.InAppPayment?) {
|
||||
try {
|
||||
performStateRefresh(lastPurchase)
|
||||
|
||||
@@ -393,7 +393,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
initializeVoiceNotePlayer();
|
||||
initializeBanners();
|
||||
maybeScheduleRefreshProfileJob();
|
||||
ConversationListFragmentExtensionsKt.listenToEventBusWhileResumed(this, mainNavigationViewModel.getDetailLocation());
|
||||
ConversationListFragmentExtensionsKt.listenToEventBusWhileResumed(this, mainNavigationViewModel .getDetailLocation());
|
||||
|
||||
String query = contactSearchMediator.getFilter();
|
||||
if (query != null) {
|
||||
|
||||
@@ -8042,6 +8042,8 @@
|
||||
<string name="BackupsSettingsFragment_set_up">Set up</string>
|
||||
|
||||
<!-- RemoteBackupsSettingsFragment -->
|
||||
<!-- Content description for canceling backup upload -->
|
||||
<string name="RemoteBackupsSettingsFragment__cancel_upload">Cancel upload</string>
|
||||
<!-- Displayed on the title bar -->
|
||||
<string name="RemoteBackupsSettingsFragment__signal_backups">Signal Backups</string>
|
||||
<!-- Text shown in a popup indicating that the user needs to enter their screen lock -->
|
||||
|
||||
Reference in New Issue
Block a user