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)