Refactor backup creation failures, add case for file too large.

This commit is contained in:
Greyson Parrelli
2025-11-07 13:52:37 -05:00
committed by Michelle Tang
parent ad0b240550
commit 945453cb81
12 changed files with 154 additions and 177 deletions

View File

@@ -207,10 +207,6 @@ object ArchiveUploadProgress {
resetState()
}
fun onValidationFailure() {
resetState()
}
fun onMainBackupFileUploadFailure() {
resetState()
}

View File

@@ -116,6 +116,7 @@ import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob
import org.thoughtcrime.securesms.jobs.StorageForcePushJob
import org.thoughtcrime.securesms.jobs.Svr2MirrorJob
import org.thoughtcrime.securesms.jobs.UploadAttachmentToArchiveJob
import org.thoughtcrime.securesms.keyvalue.BackupValues
import org.thoughtcrime.securesms.keyvalue.BackupValues.ArchiveServiceCredentials
import org.thoughtcrime.securesms.keyvalue.KeyValueStore
import org.thoughtcrime.securesms.keyvalue.SignalStore
@@ -389,8 +390,8 @@ object BackupRepository {
CancelRestoreMediaJob.enqueue()
}
fun markBackupFailure() {
SignalStore.backup.markMessageBackupFailure()
fun markBackupCreationFailed(error: BackupValues.BackupCreationError) {
SignalStore.backup.markBackupCreationFailed(error)
ArchiveUploadProgress.onMainBackupFileUploadFailure()
if (!SignalStore.backup.hasBackupBeenUploaded) {
@@ -416,7 +417,7 @@ object BackupRepository {
}
fun clearBackupFailure() {
SignalStore.backup.clearMessageBackupFailure()
SignalStore.backup.clearBackupCreationFailed()
ServiceUtil.getNotificationManager(AppDependencies.application).cancel(NotificationIds.INITIAL_BACKUP_FAILED)
}
@@ -467,7 +468,7 @@ object BackupRepository {
*/
@JvmStatic
fun shouldDisplayBackupFailedIndicator(): Boolean {
if (shouldNotDisplayBackupFailedMessaging() || !SignalStore.backup.hasBackupFailure) {
if (shouldNotDisplayBackupFailedMessaging() || !SignalStore.backup.hasBackupCreationError) {
return false
}
@@ -482,30 +483,6 @@ object BackupRepository {
return !(shouldNotDisplayBackupFailedMessaging() || !SignalStore.backup.hasBackupAlreadyRedeemedError)
}
/**
* Whether the "Backup Failed" row should be displayed in settings.
* Shown when the initial backup creation has failed
*/
fun shouldDisplayBackupFailedSettingsRow(): Boolean {
if (shouldNotDisplayBackupFailedMessaging()) {
return false
}
return !SignalStore.backup.hasBackupBeenUploaded && SignalStore.backup.hasBackupFailure
}
/**
* Whether the "Could not complete backup" row should be displayed in settings.
* Shown when a new backup could not be created but there is an existing one already
*/
fun shouldDisplayCouldNotCompleteBackupSettingsRow(): Boolean {
if (shouldNotDisplayBackupFailedMessaging()) {
return false
}
return SignalStore.backup.hasBackupBeenUploaded && SignalStore.backup.hasBackupFailure
}
/**
* Displayed when the user falls out of the grace period for backups after their subscription
* expires.
@@ -554,7 +531,7 @@ object BackupRepository {
return false
}
return (!SignalStore.backup.hasBackupBeenUploaded || SignalStore.backup.hasValidationError) && SignalStore.backup.hasBackupFailure && System.currentTimeMillis().milliseconds > SignalStore.backup.nextBackupFailureSheetSnoozeTime
return SignalStore.backup.hasBackupCreationError && SignalStore.backup.backupCreationError != BackupValues.BackupCreationError.TRANSIENT && System.currentTimeMillis().milliseconds > SignalStore.backup.nextBackupFailureSheetSnoozeTime
}
/**
@@ -675,7 +652,7 @@ object BackupRepository {
}
}
private fun shouldNotDisplayBackupFailedMessaging(): Boolean {
fun shouldNotDisplayBackupFailedMessaging(): Boolean {
return !SignalStore.account.isRegistered || !SignalStore.backup.areBackupsEnabled
}

View File

@@ -7,6 +7,8 @@ package org.thoughtcrime.securesms.backup.v2.ui.status
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
@@ -19,7 +21,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.AnnotatedString.Builder
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
@@ -32,6 +34,7 @@ import androidx.compose.ui.unit.sp
import org.signal.core.ui.compose.DayNightPreviews
import org.signal.core.ui.compose.Previews
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.keyvalue.BackupValues
import org.signal.core.ui.R as CoreUiR
private val YELLOW_DOT = Color(0xFFFFCC00)
@@ -41,27 +44,18 @@ private val YELLOW_DOT = Color(0xFFFFCC00)
*/
@Composable
fun BackupCreateErrorRow(
showCouldNotComplete: Boolean,
showBackupFailed: Boolean,
error: BackupValues.BackupCreationError,
onLearnMoreClick: () -> Unit = {}
) {
if (showBackupFailed) {
val inlineContentMap = mapOf(
"yellow_bullet" to InlineTextContent(
Placeholder(20.sp, 12.sp, PlaceholderVerticalAlign.TextCenter)
) {
Box(
modifier = Modifier
.size(12.dp)
.background(color = YELLOW_DOT, shape = CircleShape)
)
when (error) {
BackupValues.BackupCreationError.TRANSIENT -> {
BackupAlertText {
append(stringResource(R.string.BackupStatusRow__your_last_backup))
}
)
}
BackupAlertText(
text = buildAnnotatedString {
appendInlineContent("yellow_bullet")
append(" ")
BackupValues.BackupCreationError.VALIDATION -> {
BackupAlertText {
append(stringResource(R.string.BackupStatusRow__your_last_backup_latest_version))
append(" ")
withLink(
@@ -74,11 +68,29 @@ fun BackupCreateErrorRow(
) {
append(stringResource(R.string.BackupStatusRow__learn_more))
}
},
inlineContent = inlineContentMap
)
} else if (showCouldNotComplete) {
val inlineContentMap = mapOf(
}
}
BackupValues.BackupCreationError.BACKUP_FILE_TOO_LARGE -> {
BackupAlertText {
append(stringResource(R.string.BackupStatusRow__backup_file_too_large))
}
}
}
}
@Composable
private fun BackupAlertText(stringBuilder: @Composable Builder.() -> Unit) {
Text(
text = buildAnnotatedString {
appendInlineContent("yellow_bullet")
append(" ")
stringBuilder()
},
color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(horizontal = dimensionResource(CoreUiR.dimen.gutter)),
inlineContent = mapOf(
"yellow_bullet" to InlineTextContent(
Placeholder(20.sp, 12.sp, PlaceholderVerticalAlign.TextCenter)
) {
@@ -89,26 +101,6 @@ fun BackupCreateErrorRow(
)
}
)
BackupAlertText(
text = buildAnnotatedString {
appendInlineContent("yellow_bullet")
append(" ")
append(stringResource(R.string.BackupStatusRow__your_last_backup))
},
inlineContent = inlineContentMap
)
}
}
@Composable
private fun BackupAlertText(text: AnnotatedString, inlineContent: Map<String, InlineTextContent>) {
Text(
text = text,
color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(horizontal = dimensionResource(CoreUiR.dimen.gutter)),
inlineContent = inlineContent
)
}
@@ -116,14 +108,12 @@ private fun BackupAlertText(text: AnnotatedString, inlineContent: Map<String, In
@Composable
fun BackupStatusRowCouldNotCompleteBackupPreview() {
Previews.Preview {
BackupCreateErrorRow(showCouldNotComplete = true, showBackupFailed = false)
}
}
@DayNightPreviews
@Composable
fun BackupStatusRowBackupFailedPreview() {
Previews.Preview {
BackupCreateErrorRow(showCouldNotComplete = false, showBackupFailed = true)
Column {
for (error in BackupValues.BackupCreationError.entries) {
Text(error.name)
BackupCreateErrorRow(error = error, onLearnMoreClick = {})
Spacer(modifier = Modifier.size(8.dp))
}
}
}
}