diff --git a/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/Dialog.kt b/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/Dialog.kt index da3144e2..7cb3dca2 100644 --- a/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/Dialog.kt +++ b/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/Dialog.kt @@ -3,16 +3,15 @@ package com.twofasapp.designsystem.dialog import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.sizeIn import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.verticalScroll import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -49,6 +48,7 @@ fun BaseDialog( bodyAnnotated: AnnotatedString? = null, positive: String? = null, negative: String? = null, + onBodyClick: ((Int) -> Unit)? = null, onPositiveClick: (() -> Unit)? = null, onNegativeClick: (() -> Unit)? = null, positiveEnabled: Boolean = true, @@ -90,6 +90,7 @@ fun BaseDialog( Body( text = body, textAnnotated = bodyAnnotated, + onBodyClick = onBodyClick, ) } @@ -138,6 +139,7 @@ private fun Title( private fun ColumnScope.Body( text: String?, textAnnotated: AnnotatedString?, + onBodyClick: ((Int) -> Unit)? = null, ) { if (text != null) { Text( @@ -151,14 +153,15 @@ private fun ColumnScope.Body( ) } else if (textAnnotated != null) { - Text( + ClickableText( text = textAnnotated, - style = MaterialTheme.typography.bodyMedium, - color = TwTheme.color.onSurfaceTertiary, + onClick = { onBodyClick?.invoke(it) }, + style = MaterialTheme.typography.bodyMedium.copy(color = TwTheme.color.onSurfaceTertiary), modifier = Modifier .padding(horizontal = DialogPadding) - .padding(TitlePadding) - ) + .padding(TitlePadding), + + ) } } diff --git a/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/PasswordDialog.kt b/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/PasswordDialog.kt index 462e6a18..10bbe39d 100644 --- a/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/PasswordDialog.kt +++ b/core/designsystem/src/main/java/com/twofasapp/designsystem/dialog/PasswordDialog.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.window.DialogProperties @@ -26,10 +27,12 @@ fun PasswordDialog( onDismissRequest: () -> Unit, title: String? = null, body: String? = null, + bodyAnnotated: AnnotatedString? = null, error: String? = null, enabled: Boolean = true, positive: String? = TwLocale.strings.commonSave, negative: String? = TwLocale.strings.commonCancel, + onBodyClick: ((Int) -> Unit)? = null, onPositive: ((String) -> Unit)? = null, onNegative: (() -> Unit)? = null, validation: ((String) -> Boolean)? = null, @@ -57,8 +60,10 @@ fun PasswordDialog( onDismissRequest = onDismissRequest, title = title, body = body, + bodyAnnotated = bodyAnnotated, positive = positive, negative = negative, + onBodyClick = onBodyClick, onPositiveClick = { onPositive?.invoke(password.trim()) }, onNegativeClick = onNegative, positiveEnabled = positiveEnabledState, diff --git a/core/locale/src/main/java/com/twofasapp/locale/Strings.kt b/core/locale/src/main/java/com/twofasapp/locale/Strings.kt index 20d05a1b..8d359161 100644 --- a/core/locale/src/main/java/com/twofasapp/locale/Strings.kt +++ b/core/locale/src/main/java/com/twofasapp/locale/Strings.kt @@ -317,7 +317,8 @@ class Strings(c: Context) { val backupRemoveCloudPasswordTitle = c.getString(R.string.backup__enter_password_dialog_title) val backupRemoveCloudPasswordMsg = c.getString(R.string.backup__remove_password_msg) val backupEnterCloudPasswordTitle = c.getString(R.string.backup__enter_password_dialog_title) - val backupEnterCloudPasswordMsg = c.getString(R.string.backup__enter_password_title) + val backupEnterCloudPasswordMsg1 = c.getString(R.string.backup__enter_password_google_drive_msg1) + val backupEnterCloudPasswordMsg2 = c.getString(R.string.backup__enter_password_google_drive_msg2) val backupIncorrectPassword = c.getString(R.string.backup__incorrect_password) val backupExportShareCta = c.getString(R.string.export_backup_share_cta) diff --git a/core/locale/src/main/res/values-de-rDE/strings.xml b/core/locale/src/main/res/values-de-rDE/strings.xml index bc1ceb05..37f6d765 100644 --- a/core/locale/src/main/res/values-de-rDE/strings.xml +++ b/core/locale/src/main/res/values-de-rDE/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: de-DE, German (Germany) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-es-rES/strings.xml b/core/locale/src/main/res/values-es-rES/strings.xml index 0c84e350..3938d906 100644 --- a/core/locale/src/main/res/values-es-rES/strings.xml +++ b/core/locale/src/main/res/values-es-rES/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: es-ES, Spanish (Spain) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-fr-rFR/strings.xml b/core/locale/src/main/res/values-fr-rFR/strings.xml index 7422857b..26cae94a 100644 --- a/core/locale/src/main/res/values-fr-rFR/strings.xml +++ b/core/locale/src/main/res/values-fr-rFR/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: fr-FR, French (France) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-in/strings.xml b/core/locale/src/main/res/values-in/strings.xml index 549ad264..7dcef95b 100644 --- a/core/locale/src/main/res/values-in/strings.xml +++ b/core/locale/src/main/res/values-in/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: id-ID, Indonesian (Indonesia) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> - 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. - Learn more about backup + 2FAS menggunakan iCloud untuk pencadangan aman dan sinkronisasi token 2FA anda. Data cadangan **terenkripsi** disimpan di iCloud, dapat diakses **hanya melalui aplikasi 2FAS**. Selain itu, fitur ini membantu **pemulihan dan sinkronisasi** token di seluruh perangkat iOS. Ini diaktifkan secara default dan dapat dinonaktifkan kapan saja di pengaturan cadangan aplikasi. + Pelajari lebih lanjut tentang pencadangan + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-it-rIT/strings.xml b/core/locale/src/main/res/values-it-rIT/strings.xml index 958eaf09..4c034106 100644 --- a/core/locale/src/main/res/values-it-rIT/strings.xml +++ b/core/locale/src/main/res/values-it-rIT/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: it-IT, Italian (Italy) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-nl-rNL/strings.xml b/core/locale/src/main/res/values-nl-rNL/strings.xml index 19beeeb7..1ce899d3 100644 --- a/core/locale/src/main/res/values-nl-rNL/strings.xml +++ b/core/locale/src/main/res/values-nl-rNL/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: nl-NL, Dutch (Netherlands) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:30 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-pl-rPL/strings.xml b/core/locale/src/main/res/values-pl-rPL/strings.xml index 6bd6d14a..766d0db0 100644 --- a/core/locale/src/main/res/values-pl-rPL/strings.xml +++ b/core/locale/src/main/res/values-pl-rPL/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: pl-PL, Polish (Poland) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-pt-rBR/strings.xml b/core/locale/src/main/res/values-pt-rBR/strings.xml index f55bdd4d..7a2066bf 100644 --- a/core/locale/src/main/res/values-pt-rBR/strings.xml +++ b/core/locale/src/main/res/values-pt-rBR/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: pt-BR, Brazilian Portuguese Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> \"**2Fas**\" usa o icloud para backup seguro Leia mais sobre a cópia de segurança\u0020 + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-pt-rPT/strings.xml b/core/locale/src/main/res/values-pt-rPT/strings.xml index b58c5bca..ccce7490 100644 --- a/core/locale/src/main/res/values-pt-rPT/strings.xml +++ b/core/locale/src/main/res/values-pt-rPT/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: pt-PT, Portuguese (Portugal) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-tr-rTR/strings.xml b/core/locale/src/main/res/values-tr-rTR/strings.xml index 1742d2e3..945ea043 100644 --- a/core/locale/src/main/res/values-tr-rTR/strings.xml +++ b/core/locale/src/main/res/values-tr-rTR/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: tr-TR, Turkish (Turkey) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:30 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values-uk-rUA/strings.xml b/core/locale/src/main/res/values-uk-rUA/strings.xml index 565cdad4..676c94f4 100644 --- a/core/locale/src/main/res/values-uk-rUA/strings.xml +++ b/core/locale/src/main/res/values-uk-rUA/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: uk-UA, Ukrainian (Ukraine) Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS використовує iCloud для безпечного резервного копіювання та синхронізації ваших 2FA токенів. *Зашифровані* дані резервної копії зберігаються в iCloud, доступні *тільки за допомогою програми 2FAS*. Крім того, ця функція допомагає *відновлювати та синхронізувати* токени на пристроях iOS.\\n\\nЇЇ увімкнено за умовчанням і можна будь-коли вимкнути в налаштуваннях резервного копіювання програми. Дізнайтеся більше про резервне копіювання + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/core/locale/src/main/res/values/strings.xml b/core/locale/src/main/res/values/strings.xml index 0f513fb9..da77c69a 100644 --- a/core/locale/src/main/res/values/strings.xml +++ b/core/locale/src/main/res/values/strings.xml @@ -5,7 +5,7 @@ Release: Working copy Locale: en, English Exported by: rafakob - Exported at: Sat, 25 Nov 2023 08:22:33 -0800 + Exported at: Sun, 26 Nov 2023 03:22:29 -0800 --> 2FAS uses iCloud for secure backup and sync of your 2FA tokens. The **encrypted** backup data is stored in iCloud, accessible **only by the 2FAS app**. Additionally, this feature aids with token **recovery and syncing** across iOS devices.\n\nIt\'s enabled by default and can disabled at any time in the app\'s backup settings. Learn more about backup + It looks like your Google Drive backup file is password-protected. Type in the correct password to proceed. If you’d like to wipe your Google Drive backup file, + tap here to see how diff --git a/feature/backup/src/main/java/com/twofasapp/feature/backup/ui/backup/BackupScreen.kt b/feature/backup/src/main/java/com/twofasapp/feature/backup/ui/backup/BackupScreen.kt index 615f2c56..4d2d29e1 100644 --- a/feature/backup/src/main/java/com/twofasapp/feature/backup/ui/backup/BackupScreen.kt +++ b/feature/backup/src/main/java/com/twofasapp/feature/backup/ui/backup/BackupScreen.kt @@ -20,13 +20,16 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.window.DialogProperties import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.twofasapp.data.services.domain.CloudSyncError -import com.twofasapp.data.services.domain.CloudSyncStatus import com.twofasapp.designsystem.TwIcons import com.twofasapp.designsystem.TwTheme import com.twofasapp.designsystem.common.TwSwitch @@ -34,6 +37,7 @@ import com.twofasapp.designsystem.common.TwTopAppBar import com.twofasapp.designsystem.dialog.InfoDialog import com.twofasapp.designsystem.dialog.PasswordDialog import com.twofasapp.designsystem.ktx.currentActivity +import com.twofasapp.designsystem.ktx.openSafely import com.twofasapp.designsystem.ktx.strings import com.twofasapp.designsystem.ktx.toastLong import com.twofasapp.designsystem.settings.SettingsDivider @@ -81,6 +85,7 @@ private fun ScreenContent( ) { val context = LocalContext.currentActivity val strings = LocalContext.strings + val uriHandler = LocalUriHandler.current var showPasswordDialog by remember { mutableStateOf(false) } var showPasswordError by remember { mutableStateOf(false) } var showErrorDialog by remember { mutableStateOf(false) } @@ -239,6 +244,20 @@ private fun ScreenContent( } if (showPasswordDialog) { + val passText = buildAnnotatedString { + append("${strings.backupEnterCloudPasswordMsg1} ") + + pushStringAnnotation( + tag = "link", + annotation = "https://2fas.com/support/2fas-mobile-app/how-to-wipe-remove-a-google-drive-backup-file/" + ) + withStyle(style = SpanStyle(TwTheme.color.primary)) { + append(strings.backupEnterCloudPasswordMsg2) + } + pop() + append(".") + } + PasswordDialog( onDismissRequest = { showPasswordDialog = false @@ -246,7 +265,13 @@ private fun ScreenContent( }, confirmRequired = false, title = strings.backupEnterCloudPasswordTitle, - body = strings.backupEnterCloudPasswordMsg, + bodyAnnotated = passText, + onBodyClick = { offset -> + passText.getStringAnnotations(tag = "link", start = offset, end = offset).firstOrNull()?.let { + uriHandler.openSafely(it.item) + showPasswordDialog = false + } + }, error = if (showPasswordError) strings.backupIncorrectPassword else null, positive = strings.commonContinue, onPositive = { onEnterPassword(it) },