diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/EnterBackupKeyFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/EnterBackupKeyFragment.kt index 989eea9d04..76af3c8cd2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/EnterBackupKeyFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/EnterBackupKeyFragment.kt @@ -7,8 +7,12 @@ package org.thoughtcrime.securesms.registration.ui.restore import android.os.Bundle import android.view.View +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels @@ -80,6 +84,7 @@ class EnterBackupKeyFragment : ComposeFragment() { val state by viewModel.state.collectAsStateWithLifecycle() val sharedState by sharedViewModel.state.collectAsStateWithLifecycle() val contactSupportState: ContactSupportViewModel.ContactSupportState by contactSupportViewModel.state.collectAsStateWithLifecycle() + var showSkipRestoreWarning by remember { mutableStateOf(false) } SendSupportEmailEffect( contactSupportState = contactSupportState, @@ -110,10 +115,23 @@ class EnterBackupKeyFragment : ComposeFragment() { }, onLearnMore = { CommunicationActions.openBrowserLink(requireContext(), LEARN_MORE_URL) }, onSkip = { - sharedViewModel.skipRestore() - findNavController().safeNavigate(EnterBackupKeyFragmentDirections.goToEnterPhoneNumber(EnterPhoneNumberMode.RESTART_AFTER_COLLECTION)) + showSkipRestoreWarning = true }, dialogContent = { + if (showSkipRestoreWarning) { + Dialogs.SimpleAlertDialog( + title = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_title), + body = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_warning), + confirm = stringResource(R.string.SelectRestoreMethodFragment__skip_restore), + dismiss = stringResource(android.R.string.cancel), + onConfirm = { + sharedViewModel.skipRestore() + findNavController().safeNavigate(EnterBackupKeyFragmentDirections.goToEnterPhoneNumber(EnterPhoneNumberMode.RESTART_AFTER_COLLECTION)) + }, + onDismiss = { showSkipRestoreWarning = false }, + confirmColor = MaterialTheme.colorScheme.error + ) + } if (contactSupportState.show) { ContactSupportDialog( showInProgress = contactSupportState.showAsProgress, diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt index 12031cfc4e..5b53b17e82 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt @@ -32,6 +32,9 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector @@ -150,6 +153,7 @@ class RemoteRestoreActivity : BaseActivity() { setContent { val state: RemoteRestoreViewModel.ScreenState by viewModel.state.collectAsStateWithLifecycle() val contactSupportState: ContactSupportViewModel.ContactSupportState by contactSupportViewModel.state.collectAsStateWithLifecycle() + var showSkipRestoreWarning by remember { mutableStateOf(false) } SendSupportEmailEffect( contactSupportState = contactSupportState, @@ -178,13 +182,9 @@ class RemoteRestoreActivity : BaseActivity() { onRetryRestoreTier = { viewModel.reload() }, onContactSupport = { contactSupportViewModel.showContactSupport() }, onCancelClick = { - lifecycleScope.launch { - if (state.isRemoteRestoreOnlyOption) { - viewModel.skipRestore() - viewModel.performStorageServiceAccountRestoreIfNeeded() - startActivity(MainActivity.clearTop(this@RemoteRestoreActivity)) - } - + if (state.isRemoteRestoreOnlyOption) { + showSkipRestoreWarning = true + } else { finish() } }, @@ -194,6 +194,25 @@ class RemoteRestoreActivity : BaseActivity() { }, contactSupportCallbacks = contactSupportViewModel ) + + if (showSkipRestoreWarning) { + Dialogs.SimpleAlertDialog( + title = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_title), + body = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_warning), + confirm = stringResource(R.string.SelectRestoreMethodFragment__skip_restore), + dismiss = stringResource(android.R.string.cancel), + onConfirm = { + lifecycleScope.launch { + viewModel.skipRestore() + viewModel.performStorageServiceAccountRestoreIfNeeded() + startActivity(MainActivity.clearTop(this@RemoteRestoreActivity)) + finish() + } + }, + onDismiss = { showSkipRestoreWarning = false }, + confirmColor = MaterialTheme.colorScheme.error + ) + } } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreViewModel.kt index 20b1f330db..1f5d1817df 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreViewModel.kt @@ -134,10 +134,6 @@ class RemoteRestoreViewModel(isOnlyRestoreOption: Boolean) : ViewModel() { store.update { it.copy(restoreProgress = restoreEvent) } } - fun cancel() { - SignalStore.registration.restoreDecisionState = RestoreDecisionState.Skipped - } - fun clearError() { store.update { it.copy(importState = ImportState.None, restoreProgress = null) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/SelectManualRestoreMethodFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/SelectManualRestoreMethodFragment.kt index c7613b0ede..ba9e1a547d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/SelectManualRestoreMethodFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/SelectManualRestoreMethodFragment.kt @@ -8,10 +8,18 @@ package org.thoughtcrime.securesms.registration.ui.restore import android.app.Activity import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.res.stringResource import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController +import org.signal.core.ui.compose.Dialogs import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.compose.ComposeFragment import org.thoughtcrime.securesms.registration.ui.RegistrationViewModel import org.thoughtcrime.securesms.registration.ui.phonenumber.EnterPhoneNumberMode @@ -44,14 +52,30 @@ class SelectManualRestoreMethodFragment : ComposeFragment() { @Composable override fun FragmentContent() { + var showSkipRestoreWarning by remember { mutableStateOf(false) } + SelectRestoreMethodScreen( restoreMethods = listOf(RestoreMethod.FROM_SIGNAL_BACKUPS, RestoreMethod.FROM_LOCAL_BACKUP_V1), onRestoreMethodClicked = this::startRestoreMethod, onSkip = { - sharedViewModel.skipRestore() - findNavController().safeNavigate(SelectManualRestoreMethodFragmentDirections.goToEnterPhoneNumber(EnterPhoneNumberMode.NORMAL)) + showSkipRestoreWarning = true } - ) + ) { + if (showSkipRestoreWarning) { + Dialogs.SimpleAlertDialog( + title = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_title), + body = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_warning), + confirm = stringResource(R.string.SelectRestoreMethodFragment__skip_restore), + dismiss = stringResource(android.R.string.cancel), + onConfirm = { + sharedViewModel.skipRestore() + findNavController().safeNavigate(SelectManualRestoreMethodFragmentDirections.goToEnterPhoneNumber(EnterPhoneNumberMode.NORMAL)) + }, + onDismiss = { showSkipRestoreWarning = false }, + confirmColor = MaterialTheme.colorScheme.error + ) + } + } } private fun startRestoreMethod(method: RestoreMethod) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/restore/selection/SelectRestoreMethodFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/restore/selection/SelectRestoreMethodFragment.kt index e719b923dc..fed9c3d65c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/restore/selection/SelectRestoreMethodFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/restore/selection/SelectRestoreMethodFragment.kt @@ -5,7 +5,13 @@ package org.thoughtcrime.securesms.restore.selection +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.res.stringResource import androidx.fragment.app.activityViewModels import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController @@ -15,6 +21,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.signal.core.ui.compose.Dialogs import org.thoughtcrime.securesms.MainActivity +import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.compose.ComposeFragment import org.thoughtcrime.securesms.registration.data.QuickRegistrationRepository import org.thoughtcrime.securesms.registration.ui.restore.RemoteRestoreActivity @@ -33,25 +40,37 @@ class SelectRestoreMethodFragment : ComposeFragment() { @Composable override fun FragmentContent() { + var showSkipRestoreWarning by remember { mutableStateOf(false) } + SelectRestoreMethodScreen( restoreMethods = viewModel.getAvailableRestoreMethods(), onRestoreMethodClicked = this::startRestoreMethod, - onSkip = { - viewLifecycleOwner.lifecycleScope.launch { - viewModel.skipRestore() - viewModel.performStorageServiceAccountRestoreIfNeeded() - - if (isActive) { - withContext(Dispatchers.Main) { - startActivity(MainActivity.clearTop(requireContext())) - activity?.finish() - } - } - } - } + onSkip = { showSkipRestoreWarning = true } ) { if (viewModel.showStorageAccountRestoreProgress) { Dialogs.IndeterminateProgressDialog() + } else if (showSkipRestoreWarning) { + Dialogs.SimpleAlertDialog( + title = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_title), + body = stringResource(R.string.SelectRestoreMethodFragment__skip_restore_warning), + confirm = stringResource(R.string.SelectRestoreMethodFragment__skip_restore), + dismiss = stringResource(android.R.string.cancel), + onConfirm = { + lifecycleScope.launch { + viewModel.skipRestore() + viewModel.performStorageServiceAccountRestoreIfNeeded() + + if (isActive) { + withContext(Dispatchers.Main) { + startActivity(MainActivity.clearTop(requireContext())) + activity?.finish() + } + } + } + }, + onDismiss = { showSkipRestoreWarning = false }, + confirmColor = MaterialTheme.colorScheme.error + ) } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca51220401..3be339d4f5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8608,6 +8608,12 @@ From your old phone Transfer directly from your old Android + + Skip restore? + + If you skip restore now you will not be able to restore later. If you re-enable backups after skipping restore, your current backup will be replaced with your new messaging history. + + Skip restore Restore local backup