diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/BackupsIconColors.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/BackupsIconColors.kt index 16e8396066..d2f69ffd41 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/BackupsIconColors.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/BackupsIconColors.kt @@ -20,7 +20,7 @@ sealed interface BackupsIconColors { @get:Composable val background: Color - object Normal : BackupsIconColors { + data object Normal : BackupsIconColors { override val foreground: Brush @Composable get() = remember { Brush.linearGradient( diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/CreateBackupBottomSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/CreateBackupBottomSheet.kt new file mode 100644 index 0000000000..b802df6bf0 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ui/CreateBackupBottomSheet.kt @@ -0,0 +1,133 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.backup.v2.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +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.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import org.signal.core.ui.BottomSheets +import org.signal.core.ui.Buttons +import org.signal.core.ui.Icons +import org.signal.core.ui.Previews +import org.signal.core.ui.SignalPreview +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity +import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment +import org.thoughtcrime.securesms.jobs.BackupMessagesJob + +/** + * Bottom sheet allowing the user to immediately start a backup or delay. + */ +class CreateBackupBottomSheet : ComposeBottomSheetDialogFragment() { + @Composable + override fun SheetContent() { + CreateBackupBottomSheetContent( + onBackupNowClick = { + BackupMessagesJob.enqueue() + startActivity(AppSettingsActivity.remoteBackups(requireContext())) + dismissAllowingStateLoss() + }, + onBackupLaterClick = { + dismissAllowingStateLoss() + } + ) + } +} + +@Composable +private fun CreateBackupBottomSheetContent( + onBackupNowClick: () -> Unit, + onBackupLaterClick: () -> Unit +) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.fillMaxWidth() + ) { + BottomSheets.Handle() + + Icons.BrushedForeground( + painter = painterResource(id = R.drawable.symbol_backup_light), + foregroundBrush = BackupsIconColors.Normal.foreground, + contentDescription = null, + modifier = Modifier + .padding(top = 18.dp, bottom = 11.dp) + .size(88.dp) + .background( + color = BackupsIconColors.Normal.background, + shape = CircleShape + ) + .padding(20.dp) + ) + + Text( + text = stringResource(id = R.string.CreateBackupBottomSheet__create_backup), + style = MaterialTheme.typography.titleLarge + ) + + Text( + text = stringResource(id = R.string.CreateBackupBottomSheet__depending_on_the_size), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center, + modifier = Modifier + .padding(top = 8.dp, bottom = 64.dp) + .padding(horizontal = dimensionResource(id = R.dimen.core_ui__gutter)) + ) + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 31.dp) + ) { + TextButton( + onClick = onBackupLaterClick, + modifier = Modifier.padding(start = dimensionResource(id = R.dimen.core_ui__gutter)) + ) { + Text( + text = stringResource(id = R.string.CreateBackupBottomSheet__back_up_later) + ) + } + + Spacer(modifier = Modifier.weight(1f)) + + Buttons.LargeTonal( + onClick = onBackupNowClick, + modifier = Modifier.padding(end = dimensionResource(id = R.dimen.core_ui__gutter)) + ) { + Text( + text = stringResource(id = R.string.CreateBackupBottomSheet__back_up_now) + ) + } + } + } +} + +@SignalPreview +@Composable +private fun CreateBackupBottomSheetContentPreview() { + Previews.BottomSheetPreview { + CreateBackupBottomSheetContent( + onBackupNowClick = {}, + onBackupLaterClick = {} + ) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt index 83c38b552d..2a292ecbfe 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt @@ -67,6 +67,7 @@ class AppSettingsActivity : DSLSettingsActivity(), InAppPaymentComponent { StartLocation.LINKED_DEVICES -> AppSettingsFragmentDirections.actionDirectToDevices() StartLocation.USERNAME_LINK -> AppSettingsFragmentDirections.actionDirectToUsernameLinkSettings() StartLocation.RECOVER_USERNAME -> AppSettingsFragmentDirections.actionDirectToUsernameRecovery() + StartLocation.REMOTE_BACKUPS -> AppSettingsFragmentDirections.actionDirectToRemoteBackupsSettingsFragment() } } @@ -194,6 +195,9 @@ class AppSettingsActivity : DSLSettingsActivity(), InAppPaymentComponent { @JvmStatic fun usernameRecovery(context: Context): Intent = getIntentForStartLocation(context, StartLocation.RECOVER_USERNAME) + @JvmStatic + fun remoteBackups(context: Context): Intent = getIntentForStartLocation(context, StartLocation.REMOTE_BACKUPS) + private fun getIntentForStartLocation(context: Context, startLocation: StartLocation): Intent { return Intent(context, AppSettingsActivity::class.java) .putExtra(ARG_NAV_GRAPH, R.navigation.app_settings_with_change_number) @@ -217,7 +221,8 @@ class AppSettingsActivity : DSLSettingsActivity(), InAppPaymentComponent { PRIVACY(12), LINKED_DEVICES(13), USERNAME_LINK(14), - RECOVER_USERNAME(15); + RECOVER_USERNAME(15), + REMOTE_BACKUPS(16); companion object { fun fromCode(code: Int?): StartLocation { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/InAppPaymentCheckoutDelegate.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/InAppPaymentCheckoutDelegate.kt index 8cb92d5837..c19909753c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/InAppPaymentCheckoutDelegate.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/InAppPaymentCheckoutDelegate.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate +import android.app.Activity import android.content.Context import android.content.DialogInterface import androidx.fragment.app.Fragment @@ -127,6 +128,7 @@ class InAppPaymentCheckoutDelegate( if (result.action == InAppPaymentProcessorAction.CANCEL_SUBSCRIPTION) { callback.onSubscriptionCancelled(result.inAppPaymentType) } else { + fragment.requireActivity().setResult(Activity.RESULT_OK) callback.onPaymentComplete(result.inAppPayment!!) } } diff --git a/app/src/main/res/navigation/app_settings.xml b/app/src/main/res/navigation/app_settings.xml index 015405d2bc..78d3ec0d81 100644 --- a/app/src/main/res/navigation/app_settings.xml +++ b/app/src/main/res/navigation/app_settings.xml @@ -617,6 +617,14 @@ app:argType="org.thoughtcrime.securesms.profiles.manage.UsernameEditMode" /> + + diff --git a/app/src/main/res/navigation/app_settings_with_change_number.xml b/app/src/main/res/navigation/app_settings_with_change_number.xml index d6c0bbcc79..ed2e7e39a6 100644 --- a/app/src/main/res/navigation/app_settings_with_change_number.xml +++ b/app/src/main/res/navigation/app_settings_with_change_number.xml @@ -617,6 +617,14 @@ app:argType="org.thoughtcrime.securesms.profiles.manage.UsernameEditMode" /> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2214777347..336d9856eb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -792,6 +792,16 @@ Backup has a bad extension. + + + Create backup + + Depending on the size of your backup, this could take a long time. You can use your phone as you normally do while the backup takes place. + + Back up later + + Back up now + Chat backups Backups are encrypted with a passphrase and stored on your device.