diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt index 69134de483..4657a2f673 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt @@ -71,6 +71,7 @@ import org.thoughtcrime.securesms.BiometricDeviceLockContract import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.compose.ComposeFragment import org.thoughtcrime.securesms.linkdevice.LinkDeviceSettingsState.DialogState +import org.thoughtcrime.securesms.util.CommunicationActions import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.navigation.safeNavigate import java.util.Locale @@ -202,6 +203,10 @@ class LinkDeviceFragment : ComposeFragment() { onDeviceRemovalConfirmed = { device -> viewModel.removeDevice(device) }, onSyncFailureRetryRequested = { viewModel.onSyncErrorRetryRequested() }, onSyncFailureIgnored = { viewModel.onSyncErrorIgnored() }, + onSyncFailureLearnMore = { + viewModel.onSyncErrorIgnored() + CommunicationActions.openBrowserLink(requireContext(), requireContext().getString(R.string.LinkDeviceFragment__learn_more_url)) + }, onSyncCancelled = { viewModel.onSyncCancelled() }, onEditDevice = { device -> viewModel.setDeviceToEdit(device) @@ -257,6 +262,7 @@ fun DeviceListScreen( onDeviceRemovalConfirmed: (Device) -> Unit = {}, onSyncFailureRetryRequested: () -> Unit = {}, onSyncFailureIgnored: () -> Unit = {}, + onSyncFailureLearnMore: () -> Unit = {}, onSyncCancelled: () -> Unit = {}, onEditDevice: (Device) -> Unit = {}, onDialogDismissed: () -> Unit = {} @@ -281,7 +287,29 @@ fun DeviceListScreen( onDismiss = onSyncCancelled ) } - is DialogState.SyncingFailed, + is DialogState.SyncingFailed -> { + if (state.dialogState.canRetry) { + Dialogs.SimpleAlertDialog( + title = stringResource(R.string.LinkDeviceFragment__sync_failure_title), + body = stringResource(R.string.LinkDeviceFragment__sync_failure_body), + confirm = stringResource(R.string.LinkDeviceFragment__sync_failure_retry_button), + onConfirm = onSyncFailureRetryRequested, + dismiss = stringResource(R.string.LinkDeviceFragment__sync_failure_dismiss_button), + onDismissRequest = onSyncFailureIgnored, + onDeny = onSyncFailureIgnored + ) + } else { + Dialogs.SimpleAlertDialog( + title = stringResource(R.string.LinkDeviceFragment__sync_failure_title), + body = stringResource(R.string.LinkDeviceFragment__sync_failure_body_unretryable), + confirm = stringResource(R.string.LinkDeviceFragment__continue), + onConfirm = onSyncFailureIgnored, + dismiss = stringResource(R.string.LinkDeviceFragment__learn_more), + onDismissRequest = onSyncFailureIgnored, + onDeny = onSyncFailureLearnMore + ) + } + } DialogState.SyncingTimedOut -> { Dialogs.SimpleAlertDialog( title = stringResource(R.string.LinkDeviceFragment__sync_failure_title), diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt index ec077ff400..bf34cda402 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt @@ -30,7 +30,7 @@ data class LinkDeviceSettingsState( data object Unlinking : DialogState data class SyncingMessages(val deviceId: Int, val deviceCreatedAt: Long) : DialogState data object SyncingTimedOut : DialogState - data class SyncingFailed(val deviceId: Int, val deviceCreatedAt: Long) : DialogState + data class SyncingFailed(val deviceId: Int, val deviceCreatedAt: Long, val canRetry: Boolean) : DialogState data class DeviceUnlinked(val deviceCreatedAt: Long) : DialogState } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt index dd0c7cc38d..4a4b2bfcad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt @@ -313,9 +313,14 @@ class LinkDeviceViewModel : ViewModel() { is LinkDeviceRepository.LinkUploadArchiveResult.BadRequest, is LinkDeviceRepository.LinkUploadArchiveResult.NetworkError -> { Log.w(TAG, "[addDeviceWithSync] Failed to upload the archive! Result: $uploadResult") + val canRetry = uploadResult !is LinkDeviceRepository.LinkUploadArchiveResult.BackupCreationFailure _state.update { it.copy( - dialogState = DialogState.SyncingFailed(waitResult.id, waitResult.created) + dialogState = DialogState.SyncingFailed( + deviceId = waitResult.id, + deviceCreatedAt = waitResult.created, + canRetry = canRetry + ) ) } } @@ -385,6 +390,7 @@ class LinkDeviceViewModel : ViewModel() { Log.i(TAG, "Alerting linked device of sync failure - will not retry") LinkDeviceRepository.sendTransferArchiveError(dialogState.deviceId, dialogState.deviceCreatedAt, TransferArchiveError.CONTINUE_WITHOUT_UPLOAD) } + loadDevices() _state.update { it.copy( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f48671a03a..f07641fa49 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1010,8 +1010,13 @@ Message sync failed Your messages couldn\'t be transferred to your linked device. You can try re-linking and transferring again, or continue without transferring your message history. + + Your device was successfully linked, but your messages could not be transferred. + + Learn more + https://support.signal.org/hc/articles/360007320551 - Try linking again + Retry Continue without transferring