mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-08-06 13:31:18 +01:00
Show backups information on linked devices and allow on-device backups.
This commit is contained in:
committed by
Greyson Parrelli
parent
df4afe4e92
commit
4f6c1c4647
@@ -1675,6 +1675,19 @@ object BackupRepository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the remote backup's last-modified time in [BackupValues.lastBackupTime], (404/401 clear it to 0).
|
||||
*/
|
||||
fun refreshBackupFileTimestamp(): NetworkResult<ZonedDateTime> {
|
||||
return getBackupFileLastModified().also { result ->
|
||||
when (result) {
|
||||
is NetworkResult.Success -> SignalStore.backup.lastBackupTime = result.result.toMillis()
|
||||
is NetworkResult.StatusCodeError if (result.code == 404 || result.code == 401) -> SignalStore.backup.lastBackupTime = 0L
|
||||
else -> Log.w(TAG, "Failed to refresh last backup time from remote: ${result::class.simpleName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object with details about the remote backup state.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.thoughtcrime.securesms.backup.v2
|
||||
|
||||
import org.signal.core.util.LongSerializer
|
||||
import org.signal.libsignal.zkgroup.backups.BackupLevel
|
||||
|
||||
/**
|
||||
* Serializable enum value for what we think a user's current backup tier is.
|
||||
@@ -18,6 +19,13 @@ enum class MessageBackupTier(val value: Int) {
|
||||
FREE(0),
|
||||
PAID(1);
|
||||
|
||||
fun toBackupLevel(): Long {
|
||||
return when (this) {
|
||||
FREE -> BackupLevel.FREE.value.toLong()
|
||||
PAID -> BackupLevel.PAID.value.toLong()
|
||||
}
|
||||
}
|
||||
|
||||
companion object Serializer : LongSerializer<MessageBackupTier?> {
|
||||
override fun serialize(data: MessageBackupTier?): Long {
|
||||
return data?.value?.toLong() ?: -1
|
||||
@@ -26,5 +34,13 @@ enum class MessageBackupTier(val value: Int) {
|
||||
override fun deserialize(data: Long): MessageBackupTier? {
|
||||
return entries.firstOrNull { it.value == data.toInt() }
|
||||
}
|
||||
|
||||
fun fromBackupLevel(backupLevel: Long?): MessageBackupTier? {
|
||||
return when (backupLevel) {
|
||||
BackupLevel.FREE.value.toLong() -> FREE
|
||||
BackupLevel.PAID.value.toLong() -> PAID
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-19
@@ -16,7 +16,6 @@ import org.signal.core.models.database.AttachmentId
|
||||
import org.signal.core.util.UuidUtil
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.toByteArray
|
||||
import org.signal.libsignal.zkgroup.backups.BackupLevel
|
||||
import org.signal.mediasend.SentMediaQuality
|
||||
import org.thoughtcrime.securesms.backup.v2.ExportState
|
||||
import org.thoughtcrime.securesms.backup.v2.ImportState
|
||||
@@ -127,7 +126,7 @@ object AccountDataArchiveProcessor {
|
||||
hasCompletedUsernameOnboarding = signalStore.uiHintValues.hasCompletedUsernameOnboarding(),
|
||||
customChatColors = db.chatColorsTable.getSavedChatColors().toRemoteChatColors().also { colors -> exportState.customChatColorIds.addAll(colors.map { it.id }) },
|
||||
optimizeOnDeviceStorage = signalStore.backupValues.optimizeStorage && signalStore.backupValues.backupTier == MessageBackupTier.PAID,
|
||||
backupTier = signalStore.backupValues.backupTier.toRemoteBackupTier(),
|
||||
backupTier = signalStore.backupValues.backupTier?.toBackupLevel(),
|
||||
defaultSentMediaQuality = signalStore.settingsValues.sentMediaQuality.toRemoteSentMediaQuality(),
|
||||
autoDownloadSettings = AccountData.AutoDownloadSettings(
|
||||
images = getRemoteAutoDownloadOption("image", mobileAutoDownload, wifiAutoDownload),
|
||||
@@ -277,7 +276,7 @@ object AccountDataArchiveProcessor {
|
||||
SignalStore.story.userHasSeenGroupStoryEducationSheet = settings.hasSeenGroupStoryEducationSheet
|
||||
SignalStore.story.viewedReceiptsEnabled = settings.storyViewReceiptsEnabled ?: settings.readReceipts
|
||||
SignalStore.backup.optimizeStorage = settings.optimizeOnDeviceStorage
|
||||
SignalStore.backup.backupTier = settings.backupTier?.toLocalBackupTier()
|
||||
SignalStore.backup.backupTier = MessageBackupTier.fromBackupLevel(settings.backupTier)
|
||||
SignalStore.settings.sentMediaQuality = settings.defaultSentMediaQuality.toLocalSentMediaQuality()
|
||||
SignalStore.settings.setTheme(settings.appTheme.toLocalTheme())
|
||||
SignalStore.settings.setCallDataMode(settings.callsUseLessDataSetting.toLocalCallDataMode())
|
||||
@@ -456,22 +455,6 @@ object AccountDataArchiveProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private fun MessageBackupTier?.toRemoteBackupTier(): Long? {
|
||||
return when (this) {
|
||||
MessageBackupTier.FREE -> BackupLevel.FREE.value.toLong()
|
||||
MessageBackupTier.PAID -> BackupLevel.PAID.value.toLong()
|
||||
null -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun Long?.toLocalBackupTier(): MessageBackupTier? {
|
||||
return when (this) {
|
||||
BackupLevel.FREE.value.toLong() -> MessageBackupTier.FREE
|
||||
BackupLevel.PAID.value.toLong() -> MessageBackupTier.PAID
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun SentMediaQuality.toRemoteSentMediaQuality(): AccountData.SentMediaQuality {
|
||||
return when (this) {
|
||||
SentMediaQuality.STANDARD -> AccountData.SentMediaQuality.STANDARD
|
||||
|
||||
+14
-14
@@ -417,20 +417,20 @@ private fun AppSettingsContent(
|
||||
)
|
||||
}
|
||||
|
||||
if (state.isPrimaryDevice) {
|
||||
item {
|
||||
Rows.TextRow(
|
||||
icon = SignalIcons.Backup.imageVector,
|
||||
text = stringResource(R.string.preferences_chats__backups),
|
||||
onClick = {
|
||||
callbacks.navigate(AppSettingsRoute.BackupsRoute.Backups())
|
||||
},
|
||||
onLongClick = {
|
||||
callbacks.copyRemoteBackupsSubscriberIdToClipboard()
|
||||
},
|
||||
enabled = isRegisteredAndUpToDate
|
||||
)
|
||||
}
|
||||
item {
|
||||
Rows.TextRow(
|
||||
icon = SignalIcons.Backup.imageVector,
|
||||
text = stringResource(R.string.preferences_chats__backups),
|
||||
onClick = {
|
||||
callbacks.navigate(AppSettingsRoute.BackupsRoute.Backups())
|
||||
},
|
||||
onLongClick = if (state.isPrimaryDevice) {
|
||||
{ callbacks.copyRemoteBackupsSubscriberIdToClipboard() }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
enabled = isRegisteredAndUpToDate
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+145
-44
@@ -35,6 +35,11 @@ import androidx.compose.ui.platform.LocalLocale
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.LinkAnnotation
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withLink
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
@@ -58,6 +63,7 @@ import org.thoughtcrime.securesms.backup.v2.ui.subscription.MessageBackupsType
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.MessageBackupsCheckoutLauncher.createBackupsCheckoutLauncher
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.thoughtcrime.securesms.util.Environment
|
||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
@@ -86,7 +92,7 @@ class BackupsSettingsFragment : ComposeFragment() {
|
||||
findNavController().safeNavigate(R.id.action_backupsSettingsFragment_to_remoteBackupsSettingsFragment)
|
||||
}
|
||||
|
||||
if (savedInstanceState == null && args.launchCheckoutFlow) {
|
||||
if (savedInstanceState == null && args.launchCheckoutFlow && SignalStore.account.isPrimaryDevice) {
|
||||
checkoutLauncher.launch(null)
|
||||
}
|
||||
}
|
||||
@@ -103,7 +109,9 @@ class BackupsSettingsFragment : ComposeFragment() {
|
||||
is BackupState.Error -> Unit
|
||||
|
||||
BackupState.None -> {
|
||||
checkoutLauncher.launch(null)
|
||||
if (!state.isLinkedDevice) {
|
||||
checkoutLauncher.launch(null)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
@@ -112,13 +120,14 @@ class BackupsSettingsFragment : ComposeFragment() {
|
||||
}
|
||||
},
|
||||
onOnDeviceBackupsRowClick = {
|
||||
if (SignalStore.backup.newLocalBackupsEnabled || (Environment.Backups.isNewFormatSupportedForLocalBackup() && !SignalStore.settings.isBackupEnabled)) {
|
||||
if (state.isLinkedDevice || SignalStore.backup.newLocalBackupsEnabled || (Environment.Backups.isNewFormatSupportedForLocalBackup() && !SignalStore.settings.isBackupEnabled)) {
|
||||
findNavController().safeNavigate(R.id.action_backupsSettingsFragment_to_localBackupsFragment)
|
||||
} else {
|
||||
findNavController().safeNavigate(R.id.action_backupsSettingsFragment_to_backupsPreferenceFragment)
|
||||
}
|
||||
},
|
||||
onBackupTierInternalOverrideChanged = { viewModel.onBackupTierInternalOverrideChanged(it) }
|
||||
onBackupTierInternalOverrideChanged = { viewModel.onBackupTierInternalOverrideChanged(it) },
|
||||
onLearnMoreClick = { CommunicationActions.openBrowserLink(requireContext(), "https://support.signal.org/hc/articles/360007059752") }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -129,7 +138,8 @@ private fun BackupsSettingsContent(
|
||||
onNavigationClick: () -> Unit = {},
|
||||
onBackupsRowClick: () -> Unit = {},
|
||||
onOnDeviceBackupsRowClick: () -> Unit = {},
|
||||
onBackupTierInternalOverrideChanged: (MessageBackupTier?) -> Unit = {}
|
||||
onBackupTierInternalOverrideChanged: (MessageBackupTier?) -> Unit = {},
|
||||
onLearnMoreClick: () -> Unit = {}
|
||||
) {
|
||||
Scaffolds.Settings(
|
||||
title = stringResource(R.string.preferences_chats__backups),
|
||||
@@ -166,21 +176,29 @@ private fun BackupsSettingsContent(
|
||||
}
|
||||
|
||||
item {
|
||||
val displayActionButton = !backupsSettingsState.isLinkedDevice
|
||||
|
||||
when (backupsSettingsState.backupState) {
|
||||
is BackupState.LocalStore -> {
|
||||
LocalStoreBackupRow(
|
||||
backupState = backupsSettingsState.backupState,
|
||||
lastBackupAt = backupsSettingsState.lastBackupAt,
|
||||
onBackupsRowClick = onBackupsRowClick
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
displayActionButton = displayActionButton
|
||||
)
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
}
|
||||
|
||||
is BackupState.Inactive -> {
|
||||
InactiveBackupsRow(
|
||||
onBackupsRowClick = onBackupsRowClick
|
||||
)
|
||||
if (backupsSettingsState.isLinkedDevice) {
|
||||
BackupsOffLinkedDeviceRow(onLearnMoreClick = onLearnMoreClick)
|
||||
} else {
|
||||
InactiveBackupsRow(
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
displayActionButton = true
|
||||
)
|
||||
}
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
}
|
||||
@@ -189,23 +207,30 @@ private fun BackupsSettingsContent(
|
||||
ActiveBackupsRow(
|
||||
backupState = backupsSettingsState.backupState,
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
lastBackupAt = backupsSettingsState.lastBackupAt
|
||||
lastBackupAt = backupsSettingsState.lastBackupAt,
|
||||
displayActionButton = true
|
||||
)
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
}
|
||||
|
||||
BackupState.None -> {
|
||||
NeverEnabledBackupsRow(
|
||||
onBackupsRowClick = onBackupsRowClick
|
||||
)
|
||||
if (backupsSettingsState.isLinkedDevice) {
|
||||
BackupsOffLinkedDeviceRow(onLearnMoreClick = onLearnMoreClick)
|
||||
} else {
|
||||
NeverEnabledBackupsRow(
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
displayActionButton = true
|
||||
)
|
||||
}
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
}
|
||||
|
||||
is BackupState.Error -> {
|
||||
WaitingForNetworkRow(
|
||||
onBackupsRowClick = onBackupsRowClick
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
displayActionButton = displayActionButton
|
||||
)
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
@@ -213,7 +238,8 @@ private fun BackupsSettingsContent(
|
||||
|
||||
BackupState.NotFound -> {
|
||||
NotFoundBackupRow(
|
||||
onBackupsRowClick = onBackupsRowClick
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
displayActionButton = displayActionButton
|
||||
)
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
@@ -221,7 +247,8 @@ private fun BackupsSettingsContent(
|
||||
|
||||
is BackupState.Pending -> {
|
||||
PendingBackupRow(
|
||||
onBackupsRowClick = onBackupsRowClick
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
displayActionButton = displayActionButton
|
||||
)
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
@@ -231,7 +258,8 @@ private fun BackupsSettingsContent(
|
||||
ActiveBackupsRow(
|
||||
backupState = backupsSettingsState.backupState,
|
||||
lastBackupAt = backupsSettingsState.lastBackupAt,
|
||||
onBackupsRowClick = onBackupsRowClick
|
||||
onBackupsRowClick = onBackupsRowClick,
|
||||
displayActionButton = displayActionButton
|
||||
)
|
||||
|
||||
OtherWaysToBackUpHeading()
|
||||
@@ -262,7 +290,8 @@ private fun OtherWaysToBackUpHeading() {
|
||||
|
||||
@Composable
|
||||
private fun NeverEnabledBackupsRow(
|
||||
onBackupsRowClick: () -> Unit = {}
|
||||
onBackupsRowClick: () -> Unit = {},
|
||||
displayActionButton: Boolean = true
|
||||
) {
|
||||
Rows.TextRow(
|
||||
modifier = Modifier.wrapContentHeight(),
|
||||
@@ -291,13 +320,15 @@ private fun NeverEnabledBackupsRow(
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
|
||||
Buttons.MediumTonal(
|
||||
onClick = onBackupsRowClick,
|
||||
modifier = Modifier.padding(top = 12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.BackupsSettingsFragment_set_up)
|
||||
)
|
||||
if (displayActionButton) {
|
||||
Buttons.MediumTonal(
|
||||
onClick = onBackupsRowClick,
|
||||
modifier = Modifier.padding(top = 12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.BackupsSettingsFragment_set_up)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,12 +336,57 @@ private fun NeverEnabledBackupsRow(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WaitingForNetworkRow(onBackupsRowClick: () -> Unit = {}) {
|
||||
private fun BackupsOffLinkedDeviceRow(
|
||||
onLearnMoreClick: () -> Unit = {}
|
||||
) {
|
||||
val description = buildAnnotatedString {
|
||||
append(stringResource(R.string.BackupsSettingsFragment__automatic_backups_get_started_on_your_phone))
|
||||
append(" ")
|
||||
withLink(LinkAnnotation.Clickable(tag = "learn-more") { onLearnMoreClick() }) {
|
||||
withStyle(SpanStyle(color = MaterialTheme.colorScheme.primary)) {
|
||||
append(stringResource(R.string.RemoteBackupsSettingsFragment__learn_more))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rows.TextRow(
|
||||
modifier = Modifier.wrapContentHeight(),
|
||||
icon = {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(top = 12.dp)
|
||||
.align(Alignment.Top)
|
||||
) {
|
||||
Icon(
|
||||
painter = SignalIcons.Backup.painter,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__signal_backups),
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
|
||||
Text(
|
||||
text = description,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WaitingForNetworkRow(onBackupsRowClick: () -> Unit = {}, displayActionButton: Boolean = true) {
|
||||
Rows.TextRow(
|
||||
text = {
|
||||
Column {
|
||||
Text(text = stringResource(R.string.RemoteBackupsSettingsFragment__waiting_for_network))
|
||||
ViewSettingsButton(onBackupsRowClick)
|
||||
ViewSettingsButton(onBackupsRowClick, displayActionButton)
|
||||
}
|
||||
},
|
||||
icon = {
|
||||
@@ -321,7 +397,8 @@ private fun WaitingForNetworkRow(onBackupsRowClick: () -> Unit = {}) {
|
||||
|
||||
@Composable
|
||||
private fun InactiveBackupsRow(
|
||||
onBackupsRowClick: () -> Unit = {}
|
||||
onBackupsRowClick: () -> Unit = {},
|
||||
displayActionButton: Boolean = true
|
||||
) {
|
||||
Rows.TextRow(
|
||||
text = {
|
||||
@@ -336,7 +413,7 @@ private fun InactiveBackupsRow(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
ViewSettingsButton(onBackupsRowClick)
|
||||
ViewSettingsButton(onBackupsRowClick, displayActionButton)
|
||||
}
|
||||
},
|
||||
icon = {
|
||||
@@ -354,7 +431,8 @@ private fun InactiveBackupsRow(
|
||||
|
||||
@Composable
|
||||
private fun NotFoundBackupRow(
|
||||
onBackupsRowClick: () -> Unit = {}
|
||||
onBackupsRowClick: () -> Unit = {},
|
||||
displayActionButton: Boolean = true
|
||||
) {
|
||||
Rows.TextRow(
|
||||
modifier = Modifier.wrapContentHeight(),
|
||||
@@ -382,7 +460,7 @@ private fun NotFoundBackupRow(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
ViewSettingsButton(onBackupsRowClick)
|
||||
ViewSettingsButton(onBackupsRowClick, displayActionButton)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -390,7 +468,8 @@ private fun NotFoundBackupRow(
|
||||
|
||||
@Composable
|
||||
private fun PendingBackupRow(
|
||||
onBackupsRowClick: () -> Unit = {}
|
||||
onBackupsRowClick: () -> Unit = {},
|
||||
displayActionButton: Boolean = true
|
||||
) {
|
||||
Rows.TextRow(
|
||||
modifier = Modifier.wrapContentHeight(),
|
||||
@@ -418,14 +497,18 @@ private fun PendingBackupRow(
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
|
||||
ViewSettingsButton(onBackupsRowClick)
|
||||
ViewSettingsButton(onBackupsRowClick, displayActionButton)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ViewSettingsButton(onClick: () -> Unit) {
|
||||
private fun ViewSettingsButton(onClick: () -> Unit, visible: Boolean = true) {
|
||||
if (!visible) {
|
||||
return
|
||||
}
|
||||
|
||||
Buttons.MediumTonal(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.padding(top = 12.dp)
|
||||
@@ -440,7 +523,8 @@ private fun ViewSettingsButton(onClick: () -> Unit) {
|
||||
private fun LocalStoreBackupRow(
|
||||
backupState: BackupState.LocalStore,
|
||||
lastBackupAt: Duration,
|
||||
onBackupsRowClick: () -> Unit
|
||||
onBackupsRowClick: () -> Unit,
|
||||
displayActionButton: Boolean = true
|
||||
) {
|
||||
Rows.TextRow(
|
||||
modifier = Modifier.wrapContentHeight(),
|
||||
@@ -475,7 +559,7 @@ private fun LocalStoreBackupRow(
|
||||
)
|
||||
|
||||
LastBackedUpText(lastBackupAt)
|
||||
ViewSettingsButton(onBackupsRowClick)
|
||||
ViewSettingsButton(onBackupsRowClick, displayActionButton)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -485,7 +569,8 @@ private fun LocalStoreBackupRow(
|
||||
private fun ActiveBackupsRow(
|
||||
backupState: BackupState.WithTypeAndRenewalTime,
|
||||
lastBackupAt: Duration,
|
||||
onBackupsRowClick: () -> Unit = {}
|
||||
onBackupsRowClick: () -> Unit = {},
|
||||
displayActionButton: Boolean = true
|
||||
) {
|
||||
Rows.TextRow(
|
||||
modifier = Modifier.wrapContentHeight(),
|
||||
@@ -552,7 +637,7 @@ private fun ActiveBackupsRow(
|
||||
|
||||
LastBackedUpText(lastBackupAt)
|
||||
|
||||
ViewSettingsButton(onBackupsRowClick)
|
||||
ViewSettingsButton(onBackupsRowClick, displayActionButton)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -644,7 +729,8 @@ private fun BackupsSettingsContentPreview() {
|
||||
renewalTime = 0.seconds,
|
||||
price = FiatMoney(BigDecimal.valueOf(4), Currency.getInstance("CAD"))
|
||||
),
|
||||
lastBackupAt = 0.seconds
|
||||
lastBackupAt = 0.seconds,
|
||||
isLinkedDevice = false
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -652,14 +738,21 @@ private fun BackupsSettingsContentPreview() {
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun BackupsSettingsContentBackupTierInternalOverridePreview() {
|
||||
private fun BackupsSettingsContentLinkedDevicePreview() {
|
||||
Previews.Preview {
|
||||
BackupsSettingsContent(
|
||||
backupsSettingsState = BackupsSettingsState(
|
||||
backupState = BackupState.None,
|
||||
showBackupTierInternalOverride = true,
|
||||
backupTierInternalOverride = null,
|
||||
lastBackupAt = 0.seconds
|
||||
backupState = BackupState.ActivePaid(
|
||||
messageBackupsType = MessageBackupsType.Paid(
|
||||
pricePerMonth = FiatMoney(BigDecimal.valueOf(2.99), Currency.getInstance("USD")),
|
||||
storageAllowanceBytes = 1_000_000,
|
||||
mediaTtl = 30.days
|
||||
),
|
||||
renewalTime = 0.seconds,
|
||||
price = FiatMoney(BigDecimal.valueOf(2.99), Currency.getInstance("USD"))
|
||||
),
|
||||
lastBackupAt = 0.seconds,
|
||||
isLinkedDevice = true
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -758,3 +851,11 @@ private fun NeverEnabledBackupsRowPreview() {
|
||||
NeverEnabledBackupsRow()
|
||||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun BackupsOffLinkedDeviceRowPreview() {
|
||||
Previews.Preview {
|
||||
BackupsOffLinkedDeviceRow()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -17,5 +17,6 @@ data class BackupsSettingsState(
|
||||
val backupState: BackupState,
|
||||
val lastBackupAt: Duration = SignalStore.backup.lastBackupTime.milliseconds,
|
||||
val showBackupTierInternalOverride: Boolean = false,
|
||||
val backupTierInternalOverride: MessageBackupTier? = null
|
||||
val backupTierInternalOverride: MessageBackupTier? = null,
|
||||
val isLinkedDevice: Boolean = SignalStore.account.isLinkedDevice
|
||||
)
|
||||
|
||||
+8
-1
@@ -15,6 +15,7 @@ import kotlinx.coroutines.launch
|
||||
import org.signal.core.util.concurrent.SignalDispatchers
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.backup.DeletionState
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
||||
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
@@ -44,7 +45,7 @@ class BackupsSettingsViewModel : ViewModel() {
|
||||
it.copy(
|
||||
backupState = enabledState,
|
||||
lastBackupAt = SignalStore.backup.lastBackupTime.milliseconds,
|
||||
showBackupTierInternalOverride = Environment.IS_STAGING,
|
||||
showBackupTierInternalOverride = Environment.IS_STAGING && SignalStore.account.isPrimaryDevice,
|
||||
backupTierInternalOverride = SignalStore.backup.backupTierInternalOverride
|
||||
)
|
||||
}
|
||||
@@ -59,6 +60,12 @@ class BackupsSettingsViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SignalStore.account.isLinkedDevice) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
BackupRepository.refreshBackupFileTimestamp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onBackupTierInternalOverrideChanged(tier: MessageBackupTier?) {
|
||||
|
||||
+171
-38
@@ -452,7 +452,8 @@ private fun RemoteBackupsSettingsContent(
|
||||
state = state.backupState,
|
||||
onLearnMoreClick = contentCallbacks::onLearnMoreAboutLostSubscription,
|
||||
onRenewClick = contentCallbacks::onRenewLostSubscription,
|
||||
isRenewEnabled = backupDeleteState.isIdle()
|
||||
isRenewEnabled = backupDeleteState.isIdle(),
|
||||
isLinkedDevice = state.isLinkedDevice
|
||||
)
|
||||
}
|
||||
|
||||
@@ -464,7 +465,8 @@ private fun RemoteBackupsSettingsContent(
|
||||
onBackupTypeActionButtonClicked = contentCallbacks::onBackupTypeActionClick,
|
||||
isPaidTierPricingAvailable = state.isPaidTierPricingAvailable,
|
||||
isGooglePlayServicesAvailable = state.isGooglePlayServicesAvailable,
|
||||
buttonsEnabled = backupDeleteState.isIdle()
|
||||
buttonsEnabled = backupDeleteState.isIdle(),
|
||||
isLinkedDevice = state.isLinkedDevice
|
||||
)
|
||||
}
|
||||
|
||||
@@ -473,13 +475,16 @@ private fun RemoteBackupsSettingsContent(
|
||||
title = stringResource(R.string.RemoteBackupsSettingsFragment__your_subscription_was_not_found),
|
||||
onRenewClick = contentCallbacks::onRenewLostSubscription,
|
||||
onLearnMoreClick = contentCallbacks::onLearnMoreAboutLostSubscription,
|
||||
isRenewEnabled = backupDeleteState.isIdle()
|
||||
isRenewEnabled = backupDeleteState.isIdle(),
|
||||
isLinkedDevice = state.isLinkedDevice
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backupDeleteState != DeletionState.NONE && backupDeleteState != DeletionState.CLEAR_LOCAL_STATE) {
|
||||
if (state.isLinkedDevice) {
|
||||
appendReducedBackupDetailsItems(state)
|
||||
} else if (backupDeleteState != DeletionState.NONE && backupDeleteState != DeletionState.CLEAR_LOCAL_STATE) {
|
||||
appendBackupDeletionItems(
|
||||
backupDeleteState = backupDeleteState,
|
||||
backupRestoreState = backupRestoreState,
|
||||
@@ -973,12 +978,58 @@ private fun LazyListScope.appendBackupDetailsItems(
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.appendReducedBackupDetailsItems(
|
||||
state: RemoteBackupsSettingsState
|
||||
) {
|
||||
item {
|
||||
Dividers.Default()
|
||||
}
|
||||
|
||||
item {
|
||||
Texts.SectionHeader(text = stringResource(id = R.string.RemoteBackupsSettingsFragment__backup_details))
|
||||
}
|
||||
|
||||
item {
|
||||
ReadOnlyLastBackupRow(lastBackupTimestamp = state.lastBackupTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ReadOnlyLastBackupRow(
|
||||
lastBackupTimestamp: Long
|
||||
) {
|
||||
val label = if (lastBackupTimestamp > 0) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val day = remember(lastBackupTimestamp) {
|
||||
DateUtils.getDayPrecisionTimeString(context, Locale.getDefault(), lastBackupTimestamp)
|
||||
}
|
||||
|
||||
val time = remember(lastBackupTimestamp) {
|
||||
DateUtils.getOnlyTimeString(context, lastBackupTimestamp)
|
||||
}
|
||||
|
||||
stringResource(
|
||||
id = R.string.RemoteBackupsSettingsFragment__your_phone_s,
|
||||
stringResource(id = R.string.RemoteBackupsSettingsFragment__s_at_s, day, time)
|
||||
)
|
||||
} else {
|
||||
stringResource(id = R.string.RemoteBackupsSettingsFragment__never)
|
||||
}
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.RemoteBackupsSettingsFragment__last_backup),
|
||||
label = label
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BackupCard(
|
||||
backupState: BackupState.WithTypeAndRenewalTime,
|
||||
isPaidTierPricingAvailable: Boolean,
|
||||
isGooglePlayServicesAvailable: Boolean,
|
||||
buttonsEnabled: Boolean,
|
||||
isLinkedDevice: Boolean = false,
|
||||
onBackupTypeActionButtonClicked: (MessageBackupTier) -> Unit = {}
|
||||
) {
|
||||
val messageBackupsType = backupState.messageBackupsType
|
||||
@@ -1070,7 +1121,21 @@ private fun BackupCard(
|
||||
)
|
||||
}
|
||||
|
||||
if (backupState.isActive() && isPaidTierPricingAvailable && isGooglePlayServicesAvailable) {
|
||||
if (isLinkedDevice) {
|
||||
val primaryDeviceText = when (backupState) {
|
||||
is BackupState.ActivePaid -> stringResource(R.string.RemoteBackupsSettingsFragment__you_can_manage_or_cancel_your_subscription_on_your_primary_device)
|
||||
is BackupState.Canceled -> stringResource(R.string.RemoteBackupsSettingsFragment__you_can_manage_or_renew_your_subscription_on_your_primary_device)
|
||||
is BackupState.ActiveFree -> stringResource(R.string.RemoteBackupsSettingsFragment__you_can_manage_or_upgrade_your_subscription_on_your_primary_device)
|
||||
else -> stringResource(R.string.RemoteBackupsSettingsFragment__you_can_manage_or_upgrade_backups_on_your_primary_device)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = primaryDeviceText,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.padding(top = 12.dp)
|
||||
)
|
||||
} else if (backupState.isActive() && isPaidTierPricingAvailable && isGooglePlayServicesAvailable) {
|
||||
val buttonText = when (messageBackupsType) {
|
||||
is MessageBackupsType.Paid -> stringResource(R.string.RemoteBackupsSettingsFragment__manage_or_cancel)
|
||||
is MessageBackupsType.Free -> stringResource(R.string.RemoteBackupsSettingsFragment__upgrade)
|
||||
@@ -1270,6 +1335,7 @@ private fun PendingCard(
|
||||
private fun SubscriptionNotFoundCard(
|
||||
title: String,
|
||||
isRenewEnabled: Boolean,
|
||||
isLinkedDevice: Boolean = false,
|
||||
onRenewClick: () -> Unit = {},
|
||||
onLearnMoreClick: () -> Unit = {}
|
||||
) {
|
||||
@@ -1308,38 +1374,47 @@ private fun SubscriptionNotFoundCard(
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
horizontalArrangement = spacedBy(16.dp)
|
||||
) {
|
||||
Buttons.MediumTonal(
|
||||
onClick = onRenewClick,
|
||||
colors = ButtonDefaults.filledTonalButtonColors().copy(
|
||||
containerColor = SignalTheme.colors.colorTransparent5,
|
||||
contentColor = colorResource(CoreUiR.color.signal_light_colorOnSurface)
|
||||
),
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp)
|
||||
.weight(1f)
|
||||
if (isLinkedDevice) {
|
||||
Text(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__you_can_manage_or_upgrade_backups_on_your_primary_device),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.padding(top = 12.dp)
|
||||
)
|
||||
} else {
|
||||
Row(
|
||||
horizontalArrangement = spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__renew)
|
||||
)
|
||||
}
|
||||
Buttons.MediumTonal(
|
||||
onClick = onRenewClick,
|
||||
colors = ButtonDefaults.filledTonalButtonColors().copy(
|
||||
containerColor = SignalTheme.colors.colorTransparent5,
|
||||
contentColor = colorResource(CoreUiR.color.signal_light_colorOnSurface)
|
||||
),
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp)
|
||||
.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__renew)
|
||||
)
|
||||
}
|
||||
|
||||
Buttons.MediumTonal(
|
||||
onClick = onLearnMoreClick,
|
||||
enabled = isRenewEnabled,
|
||||
colors = ButtonDefaults.filledTonalButtonColors().copy(
|
||||
containerColor = SignalTheme.colors.colorTransparent5,
|
||||
contentColor = colorResource(CoreUiR.color.signal_light_colorOnSurface)
|
||||
),
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp)
|
||||
.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__learn_more)
|
||||
)
|
||||
Buttons.MediumTonal(
|
||||
onClick = onLearnMoreClick,
|
||||
enabled = isRenewEnabled,
|
||||
colors = ButtonDefaults.filledTonalButtonColors().copy(
|
||||
containerColor = SignalTheme.colors.colorTransparent5,
|
||||
contentColor = colorResource(CoreUiR.color.signal_light_colorOnSurface)
|
||||
),
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp)
|
||||
.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.RemoteBackupsSettingsFragment__learn_more)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1349,6 +1424,7 @@ private fun SubscriptionNotFoundCard(
|
||||
private fun SubscriptionMismatchMissingGooglePlayCard(
|
||||
state: BackupState.SubscriptionMismatchMissingGooglePlay,
|
||||
isRenewEnabled: Boolean,
|
||||
isLinkedDevice: Boolean = false,
|
||||
onRenewClick: () -> Unit = {},
|
||||
onLearnMoreClick: () -> Unit = {}
|
||||
) {
|
||||
@@ -1357,6 +1433,7 @@ private fun SubscriptionMismatchMissingGooglePlayCard(
|
||||
SubscriptionNotFoundCard(
|
||||
title = pluralStringResource(R.plurals.RemoteBackupsSettingsFragment__your_subscription_on_this_device_is_valid, days.toInt(), days),
|
||||
isRenewEnabled = isRenewEnabled,
|
||||
isLinkedDevice = isLinkedDevice,
|
||||
onRenewClick = onRenewClick,
|
||||
onLearnMoreClick = onLearnMoreClick
|
||||
)
|
||||
@@ -1847,6 +1924,64 @@ private fun RemoteBackupsSettingsInternalUserContentPreview() {
|
||||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun RemoteBackupsSettingsLinkedDevicePaidContentPreview() {
|
||||
Previews.Preview {
|
||||
RemoteBackupsSettingsContent(
|
||||
state = RemoteBackupsSettingsState(
|
||||
backupsEnabled = true,
|
||||
isLinkedDevice = true,
|
||||
lastBackupTimestamp = -1,
|
||||
canBackUpUsingCellular = false,
|
||||
canRestoreUsingCellular = false,
|
||||
dialog = RemoteBackupsSettingsState.Dialog.NONE,
|
||||
snackbar = RemoteBackupsSettingsState.Snackbar.NONE,
|
||||
backupMediaSize = 2300000,
|
||||
backupState = BackupState.ActivePaid(
|
||||
messageBackupsType = MessageBackupsType.Paid(
|
||||
pricePerMonth = FiatMoney(BigDecimal.valueOf(2.99), Currency.getInstance("USD")),
|
||||
storageAllowanceBytes = 1_000_000,
|
||||
mediaTtl = 30.days
|
||||
),
|
||||
price = FiatMoney(BigDecimal.valueOf(2.99), Currency.getInstance("USD")),
|
||||
renewalTime = 1_752_710_400.seconds
|
||||
)
|
||||
),
|
||||
statusBarColorNestedScrollConnection = null,
|
||||
backupDeleteState = DeletionState.NONE,
|
||||
backupRestoreState = BackupRestoreState.None,
|
||||
contentCallbacks = ContentCallbacks.Empty,
|
||||
backupProgress = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun RemoteBackupsSettingsLinkedDeviceNotFoundContentPreview() {
|
||||
Previews.Preview {
|
||||
RemoteBackupsSettingsContent(
|
||||
state = RemoteBackupsSettingsState(
|
||||
backupsEnabled = true,
|
||||
isLinkedDevice = true,
|
||||
lastBackupTimestamp = -1,
|
||||
canBackUpUsingCellular = false,
|
||||
canRestoreUsingCellular = false,
|
||||
dialog = RemoteBackupsSettingsState.Dialog.NONE,
|
||||
snackbar = RemoteBackupsSettingsState.Snackbar.NONE,
|
||||
backupMediaSize = 2300000,
|
||||
backupState = BackupState.NotFound
|
||||
),
|
||||
statusBarColorNestedScrollConnection = null,
|
||||
backupDeleteState = DeletionState.NONE,
|
||||
backupRestoreState = BackupRestoreState.None,
|
||||
contentCallbacks = ContentCallbacks.Empty,
|
||||
backupProgress = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun RedemptionErrorAlertPreview() {
|
||||
@@ -1875,10 +2010,8 @@ private fun ErrorCardPreview() {
|
||||
@Composable
|
||||
private fun PendingCardPreview() {
|
||||
Previews.Preview {
|
||||
val locale = LocalLocale.current.platformLocale
|
||||
|
||||
PendingCard(
|
||||
price = FiatMoney(BigDecimal.TEN, Currency.getInstance(locale))
|
||||
price = FiatMoney(BigDecimal.TEN, Currency.getInstance(Locale.US))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -35,7 +35,8 @@ data class RemoteBackupsSettingsState(
|
||||
val backupCreationError: BackupValues.BackupCreationError? = null,
|
||||
val lastMessageCutoffTime: Long = 0,
|
||||
val freeTierMediaRetentionDays: Int = -1,
|
||||
val isGooglePlayServicesAvailable: Boolean = false
|
||||
val isGooglePlayServicesAvailable: Boolean = false,
|
||||
val isLinkedDevice: Boolean = false
|
||||
) {
|
||||
|
||||
data class BackupMediaDetails(
|
||||
|
||||
+37
-1
@@ -79,7 +79,8 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
||||
internalUser = RemoteConfig.internalUser,
|
||||
includeDebuglog = SignalStore.internal.includeDebuglogInBackup.takeIf { RemoteConfig.internalUser },
|
||||
backupCreationError = SignalStore.backup.backupCreationError,
|
||||
lastMessageCutoffTime = SignalStore.backup.lastUsedMessageCutoffTime
|
||||
lastMessageCutoffTime = SignalStore.backup.lastUsedMessageCutoffTime,
|
||||
isLinkedDevice = SignalStore.account.isLinkedDevice
|
||||
)
|
||||
)
|
||||
|
||||
@@ -92,6 +93,14 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
||||
private var forQuickRestore = false
|
||||
|
||||
init {
|
||||
if (state.value.isLinkedDevice) {
|
||||
initLinkedDevice()
|
||||
} else {
|
||||
initPrimaryDevice()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initPrimaryDevice() {
|
||||
ArchiveUploadProgress.triggerUpdate()
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
@@ -199,6 +208,29 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render remote backups as read-only and refresh the last-backup time from the CDN.
|
||||
*/
|
||||
private fun initLinkedDevice() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
BackupStateObserver(viewModelScope, useDatabaseFallbackOnNetworkError = true).backupState.collect { backupState ->
|
||||
_state.update {
|
||||
it.copy(backupState = backupState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
SignalStore.backup.lastBackupTimeFlow.collect { lastBackupTime ->
|
||||
_state.update { it.copy(lastBackupTimestamp = lastBackupTime) }
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
BackupRepository.refreshBackupFileTimestamp()
|
||||
}
|
||||
}
|
||||
|
||||
fun setCanBackUpUsingCellular(canBackUpUsingCellular: Boolean) {
|
||||
SignalStore.backup.backupWithCellular = canBackUpUsingCellular
|
||||
_state.update {
|
||||
@@ -259,6 +291,10 @@ class RemoteBackupsSettingsViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
if (state.value.isLinkedDevice) {
|
||||
return
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val id = SignalDatabase.inAppPayments.getLatestInAppPaymentByType(InAppPaymentType.RECURRING_BACKUP)?.id
|
||||
|
||||
|
||||
@@ -183,8 +183,8 @@ object StorageSyncHelper {
|
||||
|
||||
backupTier = when {
|
||||
SignalStore.account.isLinkedDevice -> null
|
||||
SignalStore.backup.areBackupsEnabled && SignalStore.backup.backupTier != null -> getBackupLevelValue(SignalStore.backup.backupTier!!)
|
||||
SignalStore.backup.backupTierInternalOverride != null -> getBackupLevelValue(SignalStore.backup.backupTierInternalOverride!!)
|
||||
SignalStore.backup.areBackupsEnabled && SignalStore.backup.backupTier != null -> SignalStore.backup.backupTier!!.toBackupLevel()
|
||||
SignalStore.backup.backupTierInternalOverride != null -> SignalStore.backup.backupTierInternalOverride!!.toBackupLevel()
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -213,14 +213,6 @@ object StorageSyncHelper {
|
||||
return accountRecord.toSignalAccountRecord(StorageId.forAccount(storageId)).toSignalStorageRecord()
|
||||
}
|
||||
|
||||
// TODO: Currently we don't have access to the private values of the BackupLevel. Update when it becomes available.
|
||||
private fun getBackupLevelValue(tier: MessageBackupTier): Long {
|
||||
return when (tier) {
|
||||
MessageBackupTier.FREE -> 200
|
||||
MessageBackupTier.PAID -> 201
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNotificationProfileManualOverride(): AccountRecord.NotificationProfileManualOverride? {
|
||||
val profile = SignalDatabase.notificationProfiles.getProfile(SignalStore.notificationProfile.manuallyEnabledProfile)
|
||||
return if (profile != null && profile.deletedTimestampMs == 0L) {
|
||||
@@ -296,6 +288,13 @@ object StorageSyncHelper {
|
||||
setSubscriber(remoteBackupsSubscriber)
|
||||
}
|
||||
|
||||
if (SignalStore.account.isLinkedDevice) {
|
||||
val remoteBackupTier = MessageBackupTier.fromBackupLevel(update.new.proto.backupTier)
|
||||
if (remoteBackupTier != SignalStore.backup.backupTier) {
|
||||
SignalStore.backup.backupTier = remoteBackupTier
|
||||
}
|
||||
}
|
||||
|
||||
if (update.new.proto.subscriptionManuallyCancelled && !update.old.proto.subscriptionManuallyCancelled) {
|
||||
SignalStore.inAppPayments.updateLocalStateForManualCancellation(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user