diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/MainActivity.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/MainActivity.kt index d6e9c995..56af3971 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/MainActivity.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/MainActivity.kt @@ -129,6 +129,7 @@ import com.zaneschepke.wireguardautotunnel.ui.theme.OffWhite import com.zaneschepke.wireguardautotunnel.ui.theme.SilverTree import com.zaneschepke.wireguardautotunnel.ui.theme.Straw import com.zaneschepke.wireguardautotunnel.ui.theme.WireguardAutoTunnelTheme +import com.zaneschepke.wireguardautotunnel.util.FileUtils import com.zaneschepke.wireguardautotunnel.util.LocaleUtil import com.zaneschepke.wireguardautotunnel.util.StringValue import com.zaneschepke.wireguardautotunnel.util.extensions.installApk @@ -139,6 +140,10 @@ import com.zaneschepke.wireguardautotunnel.viewmodel.ConfigEditViewModel import com.zaneschepke.wireguardautotunnel.viewmodel.SharedAppViewModel import com.zaneschepke.wireguardautotunnel.viewmodel.SplitTunnelViewModel import com.zaneschepke.wireguardautotunnel.viewmodel.TunnelViewModel +import de.raphaelebner.roomdatabasebackup.core.OnCompleteListener.Companion.EXIT_CODE_ERROR +import de.raphaelebner.roomdatabasebackup.core.OnCompleteListener.Companion.EXIT_CODE_ERROR_DECRYPTION_ERROR +import de.raphaelebner.roomdatabasebackup.core.OnCompleteListener.Companion.EXIT_CODE_ERROR_RESTORE_BACKUP_IS_ENCRYPTED +import de.raphaelebner.roomdatabasebackup.core.OnCompleteListener.Companion.EXIT_CODE_ERROR_WRONG_DECRYPTION_PASSWORD import de.raphaelebner.roomdatabasebackup.core.RoomBackup import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.awaitCancellation @@ -150,6 +155,7 @@ import org.koin.androidx.compose.koinViewModel import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.orbitmvi.orbit.compose.collectAsState +import timber.log.Timber import xyz.teamgravity.pin_lock_compose.PinManager class MainActivity : AppCompatActivity() { @@ -173,9 +179,9 @@ class MainActivity : AppCompatActivity() { } super.onCreate(savedInstanceState) - handleIncomingIntent(intent) + roomBackup = RoomBackup(this).database(appDatabase).enableLogDebug(true).maxFileCount(5) - roomBackup = RoomBackup(this) + handleIncomingIntent(intent) installSplashScreen().apply { setKeepOnScreenCondition { !viewModel.container.stateFlow.value.isAppLoaded } @@ -591,62 +597,76 @@ class MainActivity : AppCompatActivity() { } } - fun performBackup() = lifecycleScope.launch { + fun performBackup(encrypt: Boolean = false, password: String? = null) { roomBackup - .database(appDatabase) .backupLocation(RoomBackup.BACKUP_FILE_LOCATION_CUSTOM_DIALOG) - .enableLogDebug(true) - .maxFileCount(5) .apply { - onCompleteListener { success, _, _ -> - lifecycleScope.launch { - val sideEffect = - if (success) { - GlobalSideEffect.Snackbar( - StringValue.StringResource( - R.string.backup_success, - getString(R.string.restarting_app), - ), - ToastType.Success, - ) - } else { - GlobalSideEffect.Snackbar( - StringValue.StringResource(R.string.backup_failed), - ToastType.Error, - ) - } - viewModel.postSideEffect(sideEffect) - } + if (encrypt && !password.isNullOrBlank()) { + backupIsEncrypted(true) + customEncryptPassword(password) + } + } + .onCompleteListener { success, _, _ -> + lifecycleScope.launch { + val sideEffect = + if (success) { + GlobalSideEffect.Snackbar( + StringValue.StringResource(R.string.backup_success), + ToastType.Success, + ) + } else { + GlobalSideEffect.Snackbar( + StringValue.StringResource(R.string.backup_failed), + ToastType.Error, + ) + } + viewModel.postSideEffect(sideEffect) } } .backup() } - fun performRestore() = lifecycleScope.launch { + fun performRestore(encrypt: Boolean = false, password: String? = null) { roomBackup - .database(appDatabase) - .enableLogDebug(true) .backupLocation(RoomBackup.BACKUP_FILE_LOCATION_CUSTOM_DIALOG) .apply { - onCompleteListener { success, _, _ -> - lifecycleScope.launch { - val sideEffect = - if (success) { - GlobalSideEffect.Snackbar( - StringValue.StringResource( - R.string.restore_success, - getString(R.string.restarting_app), - ), - ToastType.Success, - ) - } else { - GlobalSideEffect.Snackbar( - StringValue.StringResource(R.string.restore_failed), - ToastType.Error, - ) + if (encrypt && !password.isNullOrBlank()) { + backupIsEncrypted(true) + customEncryptPassword(password) + } + } + .onCompleteListener { success, message, exitCode -> + lifecycleScope.launch { + if (success) { + viewModel.postSideEffect( + GlobalSideEffect.Snackbar( + StringValue.StringResource(R.string.restore_success), + ToastType.Success, + ) + ) + roomBackup.restartApp(Intent(this@MainActivity, MainActivity::class.java)) + } else { + Timber.w("Restore failed, exitCode=$exitCode, message=$message") + + val errorMessage = + when (exitCode) { + EXIT_CODE_ERROR_WRONG_DECRYPTION_PASSWORD -> + getString(R.string.restore_failed_wrong_password) + + EXIT_CODE_ERROR, + EXIT_CODE_ERROR_DECRYPTION_ERROR, + EXIT_CODE_ERROR_RESTORE_BACKUP_IS_ENCRYPTED -> + getString(R.string.restore_failed_invalid_file) + + else -> getString(R.string.restore_failed) } - viewModel.postSideEffect(sideEffect) - if (success) restartApp() + + viewModel.postSideEffect( + GlobalSideEffect.Snackbar( + StringValue.DynamicString(errorMessage), + ToastType.Error, + ) + ) } } } @@ -666,13 +686,20 @@ class MainActivity : AppCompatActivity() { private fun handleIncomingIntent(intent: Intent?) { intent ?: return - when (intent.action) { Intent.ACTION_VIEW, Intent.ACTION_EDIT, Intent.ACTION_SEND -> { - val uri: Uri? = intent.data - uri?.let { viewModel.importFromUri(it) } + val uri: Uri? = intent.data ?: return + val name = uri?.lastPathSegment?.lowercase() ?: return + if ( + !name.endsWith(FileUtils.CONF_FILE_EXTENSION) && + !name.endsWith(FileUtils.ZIP_FILE_EXTENSION) + ) { + Timber.d("Ignoring non-config URI in handleIncomingIntent: $uri") + return + } + viewModel.importFromUri(uri) } } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt index 930d9897..709d91e1 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt @@ -52,6 +52,7 @@ import com.zaneschepke.wireguardautotunnel.ui.common.label.GroupLabel import com.zaneschepke.wireguardautotunnel.ui.common.text.DescriptionText import com.zaneschepke.wireguardautotunnel.ui.navigation.Route import com.zaneschepke.wireguardautotunnel.ui.screens.settings.components.BackupBottomSheet +import com.zaneschepke.wireguardautotunnel.ui.screens.settings.components.BackupEncryptionDialog import com.zaneschepke.wireguardautotunnel.ui.screens.settings.proxy.compoents.AppModeBottomSheet import com.zaneschepke.wireguardautotunnel.util.StringValue import com.zaneschepke.wireguardautotunnel.util.extensions.asString @@ -88,6 +89,9 @@ fun SettingsScreen( } var showBackupSheet by rememberSaveable { mutableStateOf(false) } + var showEncryptionDialog by rememberSaveable { mutableStateOf(false) } + var isRestoreAction by remember { mutableStateOf(false) } + var showAppModeSheet by rememberSaveable { mutableStateOf(false) } val appMode = uiState.settings.tunnelMode @@ -110,13 +114,42 @@ fun SettingsScreen( action() } - if (showBackupSheet) + if (showBackupSheet) { BackupBottomSheet( - { performBackupRestore { (context as? MainActivity)?.performBackup() } }, - { performBackupRestore { (context as? MainActivity)?.performRestore() } }, - ) { - showBackupSheet = false - } + onBackup = { + showBackupSheet = false + isRestoreAction = false + showEncryptionDialog = true + }, + onRestore = { + showBackupSheet = false + isRestoreAction = true + showEncryptionDialog = true + }, + onDismiss = { showBackupSheet = false }, + ) + } + + if (showEncryptionDialog) { + BackupEncryptionDialog( + isRestore = isRestoreAction, + onConfirm = { encrypt, password -> + showEncryptionDialog = false + + if (isRestoreAction) { + performBackupRestore { + (context as? MainActivity)?.performRestore(encrypt, password) + } + } else { + performBackupRestore { + (context as? MainActivity)?.performBackup(encrypt, password) + } + } + }, + onDismiss = { showEncryptionDialog = false }, + ) + } + if (showAppModeSheet) AppModeBottomSheet(sharedViewModel::setAppMode, uiState.settings.tunnelMode) { showAppModeSheet = false diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/components/BackupEncryptedDialog.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/components/BackupEncryptedDialog.kt new file mode 100644 index 00000000..8117010a --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/components/BackupEncryptedDialog.kt @@ -0,0 +1,146 @@ +package com.zaneschepke.wireguardautotunnel.ui.screens.settings.components + +import androidx.compose.foundation.layout.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Visibility +import androidx.compose.material.icons.outlined.VisibilityOff +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.dp +import com.zaneschepke.wireguardautotunnel.R +import com.zaneschepke.wireguardautotunnel.ui.common.button.ThemedSwitch +import com.zaneschepke.wireguardautotunnel.ui.common.dialog.InfoDialog +import com.zaneschepke.wireguardautotunnel.ui.common.textbox.CustomTextField + +@Composable +fun BackupEncryptionDialog( + isRestore: Boolean, + onConfirm: (encrypt: Boolean, password: String?) -> Unit, + onDismiss: () -> Unit, +) { + var encrypt by remember { mutableStateOf(false) } + var password by remember { mutableStateOf("") } + var confirmPassword by remember { mutableStateOf("") } + var showPasswordError by remember { mutableStateOf(false) } + var passwordVisible by remember { mutableStateOf(false) } + var confirmPasswordVisible by remember { mutableStateOf(false) } + + InfoDialog( + title = + if (isRestore) { + stringResource(R.string.restore) + } else { + stringResource(R.string.backup) + }, + confirmText = + if (isRestore) { + stringResource(R.string.restore) + } else { + stringResource(R.string.backup) + }, + onAttest = { + if (!isRestore && encrypt && password != confirmPassword) { + showPasswordError = true + return@InfoDialog + } + if (encrypt && password.isBlank()) { + return@InfoDialog + } + + val finalPassword = if (encrypt) password else null + onConfirm(encrypt, finalPassword) + }, + onDismiss = onDismiss, + body = { + Column( + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier.fillMaxWidth(), + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text(stringResource(R.string.encrypted)) + ThemedSwitch(checked = encrypt, onClick = { encrypt = it }) + } + + if (encrypt) { + CustomTextField( + value = password, + onValueChange = { + password = it + showPasswordError = false + }, + containerColor = MaterialTheme.colorScheme.surface, + label = { Text(stringResource(R.string.password)) }, + visualTransformation = + if (passwordVisible) VisualTransformation.None + else PasswordVisualTransformation(), + trailing = { + IconButton(onClick = { passwordVisible = !passwordVisible }) { + Icon( + imageVector = + if (passwordVisible) Icons.Outlined.VisibilityOff + else Icons.Outlined.Visibility, + contentDescription = + if (passwordVisible) stringResource(R.string.hide_password) + else stringResource(R.string.show_password), + ) + } + }, + modifier = Modifier.fillMaxWidth(), + ) + + if (!isRestore) { + CustomTextField( + value = confirmPassword, + onValueChange = { + confirmPassword = it + showPasswordError = false + }, + label = { Text(stringResource(R.string.confirm_password)) }, + visualTransformation = + if (confirmPasswordVisible) VisualTransformation.None + else PasswordVisualTransformation(), + trailing = { + IconButton( + onClick = { confirmPasswordVisible = !confirmPasswordVisible } + ) { + Icon( + imageVector = + if (confirmPasswordVisible) Icons.Outlined.VisibilityOff + else Icons.Outlined.Visibility, + contentDescription = + if (confirmPasswordVisible) + stringResource(R.string.hide_password) + else stringResource(R.string.show_password), + ) + } + }, + containerColor = MaterialTheme.colorScheme.surface, + modifier = Modifier.fillMaxWidth(), + isError = showPasswordError, + ) + } + + if (showPasswordError) { + Text( + text = stringResource(R.string.passwords_do_not_match), + color = MaterialTheme.colorScheme.error, + style = MaterialTheme.typography.bodySmall, + ) + } + } + } + }, + ) +} diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index eddc5adc..e245baca 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -58,7 +58,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index dc89c8e6..9219b357 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -245,7 +245,7 @@ %1$s (vyžaduje root) %1$s (doporučeno) (%1$s) - Úspěšně zazálohováno. %1$s + Úspěšně zazálohováno Špatná konfigurace. %1$s v umístění: %2$s. Jako jediný vývojář neúnavně pracuji na tom, aby se WG Tunnel stal nejlepším bezplatným a open-source WireGuard klientem pro Android, ale to je možné pouze s vaší podporou. Bohužel, kvůli pravidlům společnosti Google nejsou odkazy na darování povoleny ve verzi této aplikace z Obchodu Play. Projděte si prosím webové stránky projektu, abyste zjistili, kde můžete přispět. diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 4aa7d2c6..4e206cc9 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -60,7 +60,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 0dc2f928..7b48f1c2 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -202,7 +202,7 @@ Auto-Tunnel läuft Auto-Tunnel läuft nicht Tunnelüberwachung - Backuperfolg. %1$s + Backuperfolg Wiederherstellerfolg. %1$s Starte App neu, um Änderungen anzuwenden … Wiederherstellung aus Backup fehlgeschlagen. diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 123a3a8b..ee66c16e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -202,7 +202,7 @@ El túnel automático está activo El túnel automático no está activo Monitoreo del túnel - Copia de seguridad realizada con éxito. %1$s + Copia de seguridad realizada con éxito Restauración completada. %1$s Reiniciando la app para aplicar los cambios… No se pudo restaurar la copia de seguridad. diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 0418427a..5390ecf4 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -194,7 +194,7 @@ %1$s (soovitatav) (%1$s) Tunnelo monitooring - Varundus õnnestus. %1$s + Varundus õnnestus Taastamine õnnestus. %1$s Muudatuste jõustamiseks taaskäivitan rakenduse… Varukoopiast taastamine ei õnnestunud. diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index f232190b..67249e7b 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -70,7 +70,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 8d12dcfe..191a7f71 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -136,7 +136,7 @@ Show QR Wi-Fi settings Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Failed to create backup. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 5b498d29..1c1642a9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -171,7 +171,7 @@ Imiter QUIC Afficher le QR Paramètres Wi-Fi - Sauvegarde réussie. %1$s + Sauvegarde réussie Info Échec de la création de la sauvegarde. Permissions de localisation diff --git a/app/src/main/res/values-gsw/strings.xml b/app/src/main/res/values-gsw/strings.xml index 7f010e65..7a80effd 100644 --- a/app/src/main/res/values-gsw/strings.xml +++ b/app/src/main/res/values-gsw/strings.xml @@ -58,7 +58,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 1bc548e3..8ac98af8 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -60,7 +60,7 @@ Wi-Fi beállítások Alagút Wi-Fi-n Peer hozzáadása - Sikeres mentés. %1$s + Sikeres mentés Kapcsolatmegőrzés Infó Kizárás diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 1b801dd9..83e15274 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -116,7 +116,7 @@ Saluran untuk notifikasi status terowongan otomatis Tampilkan QR Pengaturan Wi-Fi - Pencadangan berhasil. %1$s + Pencadangan berhasil Info Kecualikan Gagal membuat cadangan. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index fec95ee7..dddd330c 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -206,7 +206,7 @@ Impossibile ripristinare dal backup. Riavviando l\'app per applicare le modifiche… Ripristino riuscito. %1$s - Bakcup riuscito. %1$s + Bakcup riuscito Corrente: %1$s %1$s (root richiesto) %1$s (raccomandato) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c0859976..4f72aa19 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -107,7 +107,7 @@ A channel for auto-tunnel state notifications Show QR Wi-Fi settings - Backup success. %1$s + Backup success Info Failed to create backup. Junk packet minimum size diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 378dd9eb..1cc8a04d 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -166,7 +166,7 @@ A channel for auto-tunnel state notifications Show QR Wi-Fi settings - Backup success. %1$s + Backup success Info Failed to create backup. Junk packet minimum size diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 2d95472c..332a04a3 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -58,7 +58,7 @@ Wi-Fi 설정 Wi-Fi에서 터널 사용 피어 추가 - 백업 성공. %1$s + 백업 성공 지속적 연결 유지 정보 제외 diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index e47dba52..0862ea85 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -60,7 +60,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index ef50be59..196f2331 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -222,7 +222,7 @@ App website Mimic QUIC Wi-Fi instellingen - Backup succesvol. %1$s + Backup succesvol Info Backup maken mislukt. Onbekend diff --git a/app/src/main/res/values-nod/strings.xml b/app/src/main/res/values-nod/strings.xml index 7f010e65..7a80effd 100644 --- a/app/src/main/res/values-nod/strings.xml +++ b/app/src/main/res/values-nod/strings.xml @@ -58,7 +58,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index ebc4016b..f551bcbb 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -203,7 +203,7 @@ Autotunel jest uruchomiony Autotunel nie jest uruchomiony Monitorowanie tunelu - Powodzenie tworzenia kopii zapasowej. %1$s + Powodzenie tworzenia kopii zapasowej Powodzenie przywracania. %1$s Ponowne uruchomienie aplikacji w celu zastosowania zmian… Nie udało się przywrócić danych z kopii zapasowej. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index d085b88a..ebca6a1d 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -157,7 +157,7 @@ A channel for auto-tunnel state notifications Show QR Wi-Fi settings - Backup success. %1$s + Backup success Info Failed to create backup. Location Permissions diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 969fabde..94ec0c91 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -158,7 +158,7 @@ A channel for auto-tunnel state notifications Show QR Wi-Fi settings - Backup success. %1$s + Backup success Info Failed to create backup. Location Permissions diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ae2ea930..f7c67d40 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -207,7 +207,7 @@ Резервирование данных Восстановление данных Отслеживание туннеля - Резервное копирование выполнено. %1$s + Резервное копирование выполнено Восстановление выполнено. %1$s %1$s (требуется root) %1$s (рекомендуется) diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index e1f16ece..cff1d5dc 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -108,7 +108,7 @@ A channel for auto-tunnel state notifications Show QR Wi-Fi settings - Backup success. %1$s + Backup success Info Failed to create backup. Junk packet minimálna veľkosť diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index eddc5adc..e245baca 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -58,7 +58,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 040155d6..9b11464f 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -198,7 +198,7 @@ Mimic QUIC Show QR Wi-Fi settings - Backup success. %1$s + Backup success Info Failed to create backup. Location Permissions diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index cdd65226..2abb43bc 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -58,7 +58,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Exclude diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 9d919cdc..663ac0a6 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -176,7 +176,7 @@ Mimic QUIC Show QR Wi-Fi settings - Backup success. %1$s + Backup success Info Failed to create backup. Location Permissions diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 2db75ffc..69e28a14 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -165,7 +165,7 @@ Імітація QUIC Показати QR-код Параметри Wi-Fi - Рез. копіювання успішне. %1$s + Рез. копіювання успішне Інформація Не вдалося створити резервну копію. Дозволи на доступ до геолокації diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 154554a8..33cc4295 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -202,7 +202,7 @@ آٹو ٹنل چل رہا ہے آٹو ٹنل نہیں چل رہا ہے ٹنل کی نگرانی - بیک اپ کامیاب۔ %1$s + بیک اپ کامیاب۔ بحالی کامیاب۔ %1$s تبدیلیاں لاگو کرنے کے لیے ایپ کو دوبارہ شروع کیا جا رہا ہے… بیک اپ سے بحالی ناکام۔ diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 34b60b5d..8d7ea4c3 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -60,7 +60,7 @@ Wi-Fi settings Tunnel on Wi-Fi Add peer - Backup success. %1$s + Backup success Persistent keepalive Info Loại trừ diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f56d1a6c..362423f9 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -202,7 +202,7 @@ 自动隧道运行中 自动隧道未运行 隧道监控 - 成功备份:%1$s + 成功备份 成功恢复:%1$s 正重启应用来应用更改… 未能从备份恢复。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 919da53f..c7ce24be 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -179,7 +179,7 @@ 正在重啟應用程式以應用變更… 從備份還原 還原成功。 %1$s - 備份成功。%1$s + 備份成功 備份應用程式資料 還原備份失敗。 建立備份失敗。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 542cdf70..82c75268 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -231,8 +231,8 @@ Auto-tunnel is running Auto-tunnel is not running Tunnel monitoring - Backup success. %1$s - Restore success. %1$s + Backup success + Restore success Restarting app to apply changes… Failed to restore from backup. Failed to create backup. @@ -525,4 +525,14 @@ Remote control Allow other apps (like Tasker) to control tunnels endpoint: %1$s + + Encrypted + Confirm password + Passwords do not match + + Backup + Restore + Hide password + Restore failed. Wrong password + Restore failed. Select a valid backup file (.sqlite3 or .sqlite3.aes)