Merge branch 'master' into master-ios

This commit is contained in:
spaced4ndy
2023-04-14 15:55:38 +04:00
94 changed files with 7608 additions and 2314 deletions
+2 -1
View File
@@ -86,10 +86,11 @@ Join our translators to help SimpleX grow!
|🇫🇷 fr|Français |[ishi_sama](https://github.com/ishi-sama)|[![android app](https://hosted.weblate.org/widgets/simplex-chat/fr/android/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/android/fr/)<br>[![ios app](https://hosted.weblate.org/widgets/simplex-chat/fr/ios/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/ios/fr/)|[![website](https://hosted.weblate.org/widgets/simplex-chat/fr/website/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/website/fr/)|[](https://github.com/simplex-chat/simplex-chat/tree/master/docs/lang/fr)|
|🇮🇹 it|Italiano |[unbranched](https://github.com/unbranched)|[![android app](https://hosted.weblate.org/widgets/simplex-chat/it/android/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/android/it/)<br>[![ios app](https://hosted.weblate.org/widgets/simplex-chat/it/ios/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/ios/it/)|[![website](https://hosted.weblate.org/widgets/simplex-chat/it/website/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/website/it/)||
|🇳🇱 nl|Nederlands|[mika-nl](https://github.com/mika-nl)|[![android app](https://hosted.weblate.org/widgets/simplex-chat/nl/android/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/android/nl/)<br>[![ios app](https://hosted.weblate.org/widgets/simplex-chat/nl/ios/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/ios/nl/)|[![website](https://hosted.weblate.org/widgets/simplex-chat/nl/website/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/website/nl/)||
|🇵🇱 pl|Polski |[BxOxSxS](https://github.com/BxOxSxS)|[![android app](https://hosted.weblate.org/widgets/simplex-chat/pl/android/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/android/ru/)<br>[![ios app](https://hosted.weblate.org/widgets/simplex-chat/ru/ios/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/ios/pl/)|||
|🇷🇺 ru|Русский ||[![android app](https://hosted.weblate.org/widgets/simplex-chat/ru/android/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/android/ru/)<br>[![ios app](https://hosted.weblate.org/widgets/simplex-chat/ru/ios/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/ios/ru/)|||
|🇨🇳 zh-CHS|简体中文|[sith-on-mars](https://github.com/sith-on-mars)<br><br>[Float-hu](https://github.com/Float-hu)|[![android app](https://hosted.weblate.org/widgets/simplex-chat/zh_Hans/android/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/)<br>[![ios app](https://hosted.weblate.org/widgets/simplex-chat/zh_Hans/ios/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/ios/zh_Hans/)<br>&nbsp;|<br><br>[![website](https://hosted.weblate.org/widgets/simplex-chat/zh_Hans/website/svg-badge.svg)](https://hosted.weblate.org/projects/simplex-chat/website/zh_Hans/)||
Languages in progress: Arabic, Hindi, Japanese, Spanish and [many others](https://hosted.weblate.org/projects/simplex-chat/#languages). We will be adding more languages as some of the already added are completed please suggest new languages, review the [translation guide](./docs/TRANSLATIONS.md) and get in touch with us!
Languages in progress: Arabic, Japanese, Korean, Portuguese and [others](https://hosted.weblate.org/projects/simplex-chat/#languages). We will be adding more languages as some of the already added are completed please suggest new languages, review the [translation guide](./docs/TRANSLATIONS.md) and get in touch with us!
## Contribute
+1 -1
View File
@@ -77,7 +77,7 @@ android {
def isBundle = gradle.getStartParameter().taskNames.find({ it.toLowerCase().contains("bundle") }) != null
// if (isRelease) {
// Comma separated list of languages that will be included in the apk
android.defaultConfig.resConfigs("en", "cs", "de", "es", "fr", "it", "nl", "ru", "zh-rCN")
android.defaultConfig.resConfigs("en", "cs", "de", "es", "fr", "it", "nl", "pl", "ru", "zh-rCN")
// }
if (isBundle) {
defaultConfig.ndk.abiFilters 'arm64-v8a', 'armeabi-v7a'
@@ -1,5 +1,6 @@
package chat.simplex.app
import SectionItemView
import android.app.Application
import android.content.Intent
import android.net.Uri
@@ -12,8 +13,7 @@ import androidx.activity.viewModels
import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Lock
import androidx.compose.runtime.*
@@ -21,12 +21,13 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
import chat.simplex.app.model.ChatModel
import chat.simplex.app.model.NtfManager
import chat.simplex.app.MainActivity.Companion.enteredBackground
import chat.simplex.app.model.*
import chat.simplex.app.model.NtfManager.Companion.getUserIdFromIntent
import chat.simplex.app.ui.theme.SimpleButton
import chat.simplex.app.ui.theme.SimpleXTheme
@@ -37,8 +38,11 @@ import chat.simplex.app.views.chat.ChatView
import chat.simplex.app.views.chatlist.*
import chat.simplex.app.views.database.DatabaseErrorView
import chat.simplex.app.views.helpers.*
import chat.simplex.app.views.helpers.DatabaseUtils.ksAppPassword
import chat.simplex.app.views.localauth.SetAppPasscodeView
import chat.simplex.app.views.newchat.*
import chat.simplex.app.views.onboarding.*
import chat.simplex.app.views.usersettings.LAMode
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -93,7 +97,7 @@ class MainActivity: FragmentActivity() {
laFailed,
::runAuthenticate,
::setPerformLA,
showLANotice = { m.controller.showLANotice(this) }
showLANotice = { showLANotice(m.controller.appPrefs.laNoticeShown, this) }
)
}
}
@@ -111,7 +115,8 @@ class MainActivity: FragmentActivity() {
override fun onResume() {
super.onResume()
val enteredBackgroundVal = enteredBackground.value
if (enteredBackgroundVal == null || elapsedRealtime() - enteredBackgroundVal >= 30_000) {
val delay = vm.chatModel.controller.appPrefs.laLockDelay.get()
if (enteredBackgroundVal == null || elapsedRealtime() - enteredBackgroundVal >= delay * 1000) {
runAuthenticate()
}
}
@@ -165,16 +170,27 @@ class MainActivity: FragmentActivity() {
delay(50)
withContext(Dispatchers.Main) {
authenticate(
generalGetString(R.string.auth_unlock),
generalGetString(R.string.auth_log_in_using_credential),
if (m.controller.appPrefs.laMode.get() == LAMode.SYSTEM)
generalGetString(R.string.auth_unlock)
else
generalGetString(R.string.la_enter_app_passcode),
if (m.controller.appPrefs.laMode.get() == LAMode.SYSTEM)
generalGetString(R.string.auth_log_in_using_credential)
else
generalGetString(R.string.auth_unlock),
this@MainActivity,
completed = { laResult ->
when (laResult) {
LAResult.Success ->
userAuthorized.value = true
is LAResult.Error, LAResult.Failed ->
is LAResult.Failed -> { /* Can be called multiple times on every failure */ }
is LAResult.Error -> {
laFailed.value = true
LAResult.Unavailable -> {
if (m.controller.appPrefs.laMode.get() == LAMode.PASSCODE) {
laFailedAlert()
}
}
is LAResult.Unavailable -> {
userAuthorized.value = true
m.performLA.value = false
m.controller.appPrefs.performLA.set(false)
@@ -188,21 +204,116 @@ class MainActivity: FragmentActivity() {
}
}
private fun setPerformLA(on: Boolean) {
vm.chatModel.controller.appPrefs.laNoticeShown.set(true)
if (on) {
enableLA()
} else {
disableLA()
private fun showLANotice(laNoticeShown: SharedPreference<Boolean>, activity: FragmentActivity) {
Log.d(TAG, "showLANotice")
if (!laNoticeShown.get()) {
laNoticeShown.set(true)
AlertManager.shared.showAlertDialog(
title = generalGetString(R.string.la_notice_title_simplex_lock),
text = generalGetString(R.string.la_notice_to_protect_your_information_turn_on_simplex_lock_you_will_be_prompted_to_complete_authentication_before_this_feature_is_enabled),
confirmText = generalGetString(R.string.la_notice_turn_on),
onConfirm = {
withBGApi { // to remove this call, change ordering of onConfirm call in AlertManager
showChooseLAMode(laNoticeShown, activity)
}
}
)
}
}
private fun enableLA() {
private fun showChooseLAMode(laNoticeShown: SharedPreference<Boolean>, activity: FragmentActivity) {
Log.d(TAG, "showLANotice")
laNoticeShown.set(true)
AlertManager.shared.showAlertDialogStacked(
title = generalGetString(R.string.la_lock_mode),
text = null,
confirmText = generalGetString(R.string.la_lock_mode_passcode),
dismissText = generalGetString(R.string.la_lock_mode_system),
onConfirm = {
AlertManager.shared.hideAlert()
setPasscode()
},
onDismiss = {
AlertManager.shared.hideAlert()
initialEnableLA(activity)
}
)
}
private fun initialEnableLA(activity: FragmentActivity) {
val m = vm.chatModel
val appPrefs = m.controller.appPrefs
m.controller.appPrefs.laMode.set(LAMode.SYSTEM)
authenticate(
generalGetString(R.string.auth_enable_simplex_lock),
generalGetString(R.string.auth_confirm_credential),
this@MainActivity,
activity,
completed = { laResult ->
when (laResult) {
LAResult.Success -> {
m.performLA.value = true
appPrefs.performLA.set(true)
laTurnedOnAlert()
}
is LAResult.Failed -> { /* Can be called multiple times on every failure */ }
is LAResult.Error -> {
m.performLA.value = false
appPrefs.performLA.set(false)
laFailedAlert()
}
is LAResult.Unavailable -> {
m.performLA.value = false
appPrefs.performLA.set(false)
m.showAdvertiseLAUnavailableAlert.value = true
}
}
}
)
}
private fun setPasscode() {
val chatModel = vm.chatModel
val appPrefs = chatModel.controller.appPrefs
ModalManager.shared.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
SetAppPasscodeView(
submit = {
chatModel.performLA.value = true
appPrefs.performLA.set(true)
appPrefs.laMode.set(LAMode.PASSCODE)
laTurnedOnAlert()
},
cancel = {
chatModel.performLA.value = false
appPrefs.performLA.set(false)
laPasscodeNotSetAlert()
},
close)
}
}
}
private fun setPerformLA(on: Boolean, activity: FragmentActivity) {
vm.chatModel.controller.appPrefs.laNoticeShown.set(true)
if (on) {
enableLA(activity)
} else {
disableLA(activity)
}
}
private fun enableLA(activity: FragmentActivity) {
val m = vm.chatModel
authenticate(
if (m.controller.appPrefs.laMode.get() == LAMode.SYSTEM)
generalGetString(R.string.auth_enable_simplex_lock)
else
generalGetString(R.string.new_passcode),
if (m.controller.appPrefs.laMode.get() == LAMode.SYSTEM)
generalGetString(R.string.auth_confirm_credential)
else
"",
activity,
completed = { laResult ->
val prefPerformLA = m.controller.appPrefs.performLA
when (laResult) {
@@ -211,11 +322,13 @@ class MainActivity: FragmentActivity() {
prefPerformLA.set(true)
laTurnedOnAlert()
}
is LAResult.Error, LAResult.Failed -> {
is LAResult.Failed -> { /* Can be called multiple times on every failure */ }
is LAResult.Error -> {
m.performLA.value = false
prefPerformLA.set(false)
laFailedAlert()
}
LAResult.Unavailable -> {
is LAResult.Unavailable -> {
m.performLA.value = false
prefPerformLA.set(false)
laUnavailableInstructionAlert()
@@ -225,24 +338,33 @@ class MainActivity: FragmentActivity() {
)
}
private fun disableLA() {
private fun disableLA(activity: FragmentActivity) {
val m = vm.chatModel
authenticate(
generalGetString(R.string.auth_disable_simplex_lock),
generalGetString(R.string.auth_confirm_credential),
this@MainActivity,
if (m.controller.appPrefs.laMode.get() == LAMode.SYSTEM)
generalGetString(R.string.auth_disable_simplex_lock)
else
generalGetString(R.string.la_enter_app_passcode),
if (m.controller.appPrefs.laMode.get() == LAMode.SYSTEM)
generalGetString(R.string.auth_confirm_credential)
else
generalGetString(R.string.auth_disable_simplex_lock),
activity,
completed = { laResult ->
val prefPerformLA = m.controller.appPrefs.performLA
when (laResult) {
LAResult.Success -> {
m.performLA.value = false
prefPerformLA.set(false)
ksAppPassword.remove()
}
is LAResult.Error, LAResult.Failed -> {
is LAResult.Failed -> { /* Can be called multiple times on every failure */ }
is LAResult.Error -> {
m.performLA.value = true
prefPerformLA.set(true)
laFailedAlert()
}
LAResult.Unavailable -> {
is LAResult.Unavailable -> {
m.performLA.value = false
prefPerformLA.set(false)
laUnavailableTurningOffAlert()
@@ -264,7 +386,7 @@ fun MainPage(
userAuthorized: MutableState<Boolean?>,
laFailed: MutableState<Boolean>,
runAuthenticate: () -> Unit,
setPerformLA: (Boolean) -> Unit,
setPerformLA: (Boolean, FragmentActivity) -> Unit,
showLANotice: () -> Unit
) {
var showChatDatabaseError by rememberSaveable {
@@ -392,6 +514,14 @@ fun MainPage(
if (invitation != null) IncomingCallAlertView(invitation, chatModel)
AlertManager.shared.showInView()
}
DisposableEffectOnRotate {
// When using lock delay = 0 and screen rotates, the app will be locked which is not useful.
// Let's prolong the unlocked period to 3 sec for screen rotation to take place
if (chatModel.controller.appPrefs.laLockDelay.get() == 0) {
enteredBackground.value = elapsedRealtime() + 3000
}
}
}
fun processNotificationIntent(intent: Intent?, chatModel: ChatModel) {
@@ -326,4 +326,4 @@ class SimplexService: Service() {
private fun getPreferences(context: Context): SharedPreferences = context.getSharedPreferences(SHARED_PREFS_ID, Context.MODE_PRIVATE)
}
}
}
@@ -20,7 +20,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.fragment.app.FragmentActivity
import chat.simplex.app.*
import chat.simplex.app.R
import chat.simplex.app.ui.theme.*
@@ -84,6 +83,8 @@ class AppPreferences(val context: Context) {
set = fun(action: CallOnLockScreen) { _callOnLockScreen.set(action.name) }
)
val performLA = mkBoolPreference(SHARED_PREFS_PERFORM_LA, false)
val laMode = mkEnumPreference(SHARED_PREFS_LA_MODE, LAMode.SYSTEM) { LAMode.values().firstOrNull { it.name == this } }
val laLockDelay = mkIntPreference(SHARED_PREFS_LA_LOCK_DELAY, 30)
val laNoticeShown = mkBoolPreference(SHARED_PREFS_LA_NOTICE_SHOWN, false)
val webrtcIceServers = mkStrPreference(SHARED_PREFS_WEBRTC_ICE_SERVERS, null)
val privacyProtectScreen = mkBoolPreference(SHARED_PREFS_PRIVACY_PROTECT_SCREEN, true)
@@ -142,6 +143,8 @@ class AppPreferences(val context: Context) {
val initialRandomDBPassphrase = mkBoolPreference(SHARED_PREFS_INITIAL_RANDOM_DB_PASSPHRASE, false)
val encryptedDBPassphrase = mkStrPreference(SHARED_PREFS_ENCRYPTED_DB_PASSPHRASE, null)
val initializationVectorDBPassphrase = mkStrPreference(SHARED_PREFS_INITIALIZATION_VECTOR_DB_PASSPHRASE, null)
val encryptedAppPassphrase = mkStrPreference(SHARED_PREFS_ENCRYPTED_APP_PASSPHRASE, null)
val initializationVectorAppPassphrase = mkStrPreference(SHARED_PREFS_INITIALIZATION_VECTOR_APP_PASSPHRASE, null)
val encryptionStartedAt = mkDatePreference(SHARED_PREFS_ENCRYPTION_STARTED_AT, null, true)
val confirmDBUpgrades = mkBoolPreference(SHARED_PREFS_CONFIRM_DB_UPGRADES, false)
@@ -184,6 +187,12 @@ class AppPreferences(val context: Context) {
set = fun(value) = sharedPreferences.edit().putString(prefName, value).apply()
)
private fun <T> mkEnumPreference(prefName: String, default: T, construct: String.() -> T?): SharedPreference<T> =
SharedPreference(
get = fun() = sharedPreferences.getString(prefName, default.toString())?.construct() ?: default,
set = fun(value) = sharedPreferences.edit().putString(prefName, value.toString()).apply()
)
/**
* Provide `[commit] = true` to save preferences right now, not after some unknown period of time.
* So in case of a crash this value will be saved 100%
@@ -210,6 +219,8 @@ class AppPreferences(val context: Context) {
private const val SHARED_PREFS_WEBRTC_POLICY_RELAY = "WebrtcPolicyRelay"
private const val SHARED_PREFS_WEBRTC_CALLS_ON_LOCK_SCREEN = "CallsOnLockScreen"
private const val SHARED_PREFS_PERFORM_LA = "PerformLA"
private const val SHARED_PREFS_LA_MODE = "LocalAuthenticationMode"
private const val SHARED_PREFS_LA_LOCK_DELAY = "LocalAuthenticationLockDelay"
private const val SHARED_PREFS_LA_NOTICE_SHOWN = "LANoticeShown"
private const val SHARED_PREFS_WEBRTC_ICE_SERVERS = "WebrtcICEServers"
private const val SHARED_PREFS_PRIVACY_PROTECT_SCREEN = "PrivacyProtectScreen"
@@ -246,6 +257,8 @@ class AppPreferences(val context: Context) {
private const val SHARED_PREFS_INITIAL_RANDOM_DB_PASSPHRASE = "InitialRandomDBPassphrase"
private const val SHARED_PREFS_ENCRYPTED_DB_PASSPHRASE = "EncryptedDBPassphrase"
private const val SHARED_PREFS_INITIALIZATION_VECTOR_DB_PASSPHRASE = "InitializationVectorDBPassphrase"
private const val SHARED_PREFS_ENCRYPTED_APP_PASSPHRASE = "EncryptedAppPassphrase"
private const val SHARED_PREFS_INITIALIZATION_VECTOR_APP_PASSPHRASE = "InitializationVectorAppPassphrase"
private const val SHARED_PREFS_ENCRYPTION_STARTED_AT = "EncryptionStartedAt"
private const val SHARED_PREFS_CONFIRM_DB_UPGRADES = "ConfirmDBUpgrades"
private const val SHARED_PREFS_CURRENT_THEME = "CurrentTheme"
@@ -1707,43 +1720,6 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
)
}
fun showLANotice(activity: FragmentActivity) {
Log.d(TAG, "showLANotice")
if (!appPrefs.laNoticeShown.get()) {
appPrefs.laNoticeShown.set(true)
AlertManager.shared.showAlertDialog(
title = generalGetString(R.string.la_notice_title_simplex_lock),
text = generalGetString(R.string.la_notice_to_protect_your_information_turn_on_simplex_lock_you_will_be_prompted_to_complete_authentication_before_this_feature_is_enabled),
confirmText = generalGetString(R.string.la_notice_turn_on),
onConfirm = {
authenticate(
generalGetString(R.string.auth_enable_simplex_lock),
generalGetString(R.string.auth_confirm_credential),
activity,
completed = { laResult ->
when (laResult) {
LAResult.Success -> {
chatModel.performLA.value = true
appPrefs.performLA.set(true)
laTurnedOnAlert()
}
is LAResult.Error, LAResult.Failed -> {
chatModel.performLA.value = false
appPrefs.performLA.set(false)
}
LAResult.Unavailable -> {
chatModel.performLA.value = false
appPrefs.performLA.set(false)
chatModel.showAdvertiseLAUnavailableAlert.value = true
}
}
}
)
}
)
}
}
fun isIgnoringBatteryOptimizations(context: Context): Boolean {
val powerManager = context.getSystemService(Application.POWER_SERVICE) as PowerManager
return powerManager.isIgnoringBatteryOptimizations(context.packageName)
@@ -3422,7 +3398,6 @@ class AutoAccept(val acceptIncognito: Boolean, val autoReply: MsgContent?) {
@Serializable
data class CoreVersionInfo(
val version: String,
val buildTimestamp: String,
val simplexmqVersion: String,
val simplexmqCommit: String
)
@@ -3669,4 +3644,4 @@ sealed class XFTPErrorType {
@Serializable @SerialName("HAS_FILE") object HAS_FILE: XFTPErrorType()
@Serializable @SerialName("FILE_IO") object FILE_IO: XFTPErrorType()
@Serializable @SerialName("INTERNAL") object INTERNAL: XFTPErrorType()
}
}
@@ -8,4 +8,4 @@ val Shapes = Shapes(
small = RoundedCornerShape(4.dp),
medium = RoundedCornerShape(4.dp),
large = RoundedCornerShape(0.dp)
)
)
@@ -74,4 +74,4 @@ fun SimpleXTheme(darkTheme: Boolean? = null, content: @Composable () -> Unit) {
shapes = Shapes,
content = content
)
}
}
@@ -148,4 +148,4 @@ fun ProfileNameField(name: MutableState<String>, focusRequester: FocusRequester?
singleLine = true,
cursorBrush = SolidColor(HighOrLowlight)
)
}
}
@@ -106,4 +106,4 @@ class CallManager(val chatModel: ChatModel) {
chatModel.controller.ntfManager.cancelCallNotification()
}
}
}
}
@@ -48,4 +48,4 @@ class SoundPlayer {
companion object {
val shared = SoundPlayer()
}
}
}
@@ -134,4 +134,4 @@ private fun splitToParts(s: String, length: Int): String {
return (0..(s.length - 1) / length)
.map { s.drop(it * length).take(length) }
.joinToString(separator = "\n")
}
}
@@ -154,4 +154,4 @@ fun AcceptCallButton(cInfo: ChatInfo, acceptCall: (Contact) -> Unit) {
// Image(systemName: "phone.arrow.down.left").foregroundColor(.secondary)
// }
// }
//}
//}
@@ -21,6 +21,7 @@ import androidx.compose.ui.text.capitalize
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.unit.*
import androidx.fragment.app.FragmentActivity
import chat.simplex.app.*
import chat.simplex.app.R
import chat.simplex.app.model.*
@@ -36,7 +37,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
@Composable
fun ChatListView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, stopped: Boolean) {
fun ChatListView(chatModel: ChatModel, setPerformLA: (Boolean, FragmentActivity) -> Unit, stopped: Boolean) {
val newChatSheetState by rememberSaveable(stateSaver = AnimatedViewState.saver()) { mutableStateOf(MutableStateFlow(AnimatedViewState.GONE)) }
val userPickerState by rememberSaveable(stateSaver = AnimatedViewState.saver()) { mutableStateOf(MutableStateFlow(AnimatedViewState.GONE)) }
val showNewChatSheet = {
@@ -42,9 +42,9 @@ fun DatabaseEncryptionView(m: ChatModel) {
val prefs = m.controller.appPrefs
val useKeychain = remember { mutableStateOf(prefs.storeDBPassphrase.get()) }
val initialRandomDBPassphrase = remember { mutableStateOf(prefs.initialRandomDBPassphrase.get()) }
val storedKey = remember { val key = DatabaseUtils.getDatabaseKey(); mutableStateOf(key != null && key != "") }
val storedKey = remember { val key = DatabaseUtils.ksDatabasePassword.get(); mutableStateOf(key != null && key != "") }
// Do not do rememberSaveable on current key to prevent saving it on disk in clear text
val currentKey = remember { mutableStateOf(if (initialRandomDBPassphrase.value) DatabaseUtils.getDatabaseKey() ?: "" else "") }
val currentKey = remember { mutableStateOf(if (initialRandomDBPassphrase.value) DatabaseUtils.ksDatabasePassword.get() ?: "" else "") }
val newKey = rememberSaveable { mutableStateOf("") }
val confirmNewKey = rememberSaveable { mutableStateOf("") }
@@ -89,7 +89,7 @@ fun DatabaseEncryptionView(m: ChatModel) {
prefs.initialRandomDBPassphrase.set(false)
initialRandomDBPassphrase.value = false
if (useKeychain.value) {
DatabaseUtils.setDatabaseKey(newKey.value)
DatabaseUtils.ksDatabasePassword.set(newKey.value)
}
resetFormAfterEncryption(m, initialRandomDBPassphrase, currentKey, newKey, confirmNewKey, storedKey, useKeychain.value)
operationEnded(m, progressIndicator) {
@@ -150,7 +150,7 @@ fun DatabaseEncryptionLayout(
text = generalGetString(R.string.notifications_will_be_hidden) + "\n" + storeSecurelyDanger(),
confirmText = generalGetString(R.string.remove_passphrase),
onConfirm = {
DatabaseUtils.removeDatabaseKey()
DatabaseUtils.ksDatabasePassword.remove()
setUseKeychain(false, useKeychain, prefs)
storedKey.value = false
},
@@ -522,4 +522,4 @@ fun PreviewDatabaseEncryptionLayout() {
onConfirmEncrypt = {},
)
}
}
}
@@ -38,7 +38,7 @@ fun DatabaseErrorView(
) {
val progressIndicator = remember { mutableStateOf(false) }
val dbKey = remember { mutableStateOf("") }
var storedDBKey by remember { mutableStateOf(DatabaseUtils.getDatabaseKey()) }
var storedDBKey by remember { mutableStateOf(DatabaseUtils.ksDatabasePassword.get()) }
var useKeychain by remember { mutableStateOf(appPreferences.storeDBPassphrase.get()) }
val context = LocalContext.current
val restoreDbFromBackup = remember { mutableStateOf(shouldShowRestoreDbButton(appPreferences, context)) }
@@ -49,7 +49,7 @@ fun DatabaseErrorView(
}
fun saveAndRunChatOnClick() {
DatabaseUtils.setDatabaseKey(dbKey.value)
DatabaseUtils.ksDatabasePassword.set(dbKey.value)
storedDBKey = dbKey.value
appPreferences.storeDBPassphrase.set(true)
useKeychain = true
@@ -52,7 +52,7 @@ fun DatabaseView(
) {
val context = LocalContext.current
val progressIndicator = remember { mutableStateOf(false) }
val runChat = remember { mutableStateOf(m.chatRunning.value ?: true) }
val runChat = remember { m.chatRunning }
val prefs = m.controller.appPrefs
val useKeychain = remember { mutableStateOf(prefs.storeDBPassphrase.get()) }
val chatArchiveName = remember { mutableStateOf(prefs.chatArchiveName.get()) }
@@ -76,7 +76,7 @@ fun DatabaseView(
) {
DatabaseLayout(
progressIndicator.value,
runChat.value,
runChat.value != false,
m.chatDbChanged.value,
useKeychain.value,
m.chatDbEncrypted.value,
@@ -388,7 +388,7 @@ fun chatArchiveTitle(chatArchiveTime: Instant, chatLastStart: Instant): String {
return stringResource(if (chatArchiveTime < chatLastStart) R.string.old_database_archive else R.string.new_database_archive)
}
private fun startChat(m: ChatModel, runChat: MutableState<Boolean>, chatLastStart: MutableState<Instant?>, chatDbChanged: MutableState<Boolean>) {
private fun startChat(m: ChatModel, runChat: MutableState<Boolean?>, chatLastStart: MutableState<Instant?>, chatDbChanged: MutableState<Boolean>) {
withApi {
try {
if (chatDbChanged.value) {
@@ -417,7 +417,7 @@ private fun startChat(m: ChatModel, runChat: MutableState<Boolean>, chatLastStar
}
}
private fun stopChatAlert(m: ChatModel, runChat: MutableState<Boolean>, context: Context) {
private fun stopChatAlert(m: ChatModel, runChat: MutableState<Boolean?>, context: Context) {
AlertManager.shared.showAlertDialog(
title = generalGetString(R.string.stop_chat_question),
text = generalGetString(R.string.stop_chat_to_export_import_or_delete_chat_database),
@@ -434,7 +434,7 @@ private fun exportProhibitedAlert() {
)
}
private fun authStopChat(m: ChatModel, runChat: MutableState<Boolean>, context: Context) {
private fun authStopChat(m: ChatModel, runChat: MutableState<Boolean?>, context: Context) {
if (m.controller.appPrefs.performLA.get()) {
authenticate(
generalGetString(R.string.auth_stop_chat),
@@ -442,12 +442,13 @@ private fun authStopChat(m: ChatModel, runChat: MutableState<Boolean>, context:
context as FragmentActivity,
completed = { laResult ->
when (laResult) {
LAResult.Success, LAResult.Unavailable -> {
LAResult.Success, is LAResult.Unavailable -> {
stopChat(m, runChat, context)
}
is LAResult.Error -> {
runChat.value = true
}
LAResult.Failed -> {
is LAResult.Failed -> {
runChat.value = true
}
}
@@ -458,7 +459,7 @@ private fun authStopChat(m: ChatModel, runChat: MutableState<Boolean>, context:
}
}
private fun stopChat(m: ChatModel, runChat: MutableState<Boolean>, context: Context) {
private fun stopChat(m: ChatModel, runChat: MutableState<Boolean?>, context: Context) {
withApi {
try {
m.controller.apiStopChat()
@@ -592,7 +593,7 @@ private fun importArchive(
try {
val config = ArchiveConfig(archivePath, parentTempDirectory = context.cacheDir.toString())
m.controller.apiImportArchive(config)
DatabaseUtils.removeDatabaseKey()
DatabaseUtils.ksDatabasePassword.remove()
appFilesCountAndSize.value = directoryFileCountAndSize(getAppFilesDirectory(context))
operationEnded(m, progressIndicator) {
AlertManager.shared.showAlertMsg(generalGetString(R.string.chat_database_imported), generalGetString(R.string.restart_the_app_to_use_imported_chat_database))
@@ -647,7 +648,7 @@ private fun deleteChat(m: ChatModel, progressIndicator: MutableState<Boolean>) {
try {
m.controller.apiDeleteStorage()
m.chatDbDeleted.value = true
DatabaseUtils.removeDatabaseKey()
DatabaseUtils.ksDatabasePassword.remove()
m.controller.appPrefs.storeDBPassphrase.set(true)
operationEnded(m, progressIndicator) {
AlertManager.shared.showAlertMsg(generalGetString(R.string.chat_database_deleted), generalGetString(R.string.restart_the_app_to_create_a_new_chat_profile))
@@ -3,6 +3,7 @@ package chat.simplex.app.views.helpers
import android.util.Log
import chat.simplex.app.*
import chat.simplex.app.model.AppPreferences
import chat.simplex.app.model.SharedPreference
import chat.simplex.app.views.usersettings.Cryptor
import kotlinx.serialization.*
import java.io.File
@@ -16,30 +17,36 @@ object DatabaseUtils {
}
private const val DATABASE_PASSWORD_ALIAS: String = "databasePassword"
private const val APP_PASSWORD_ALIAS: String = "appPassword"
val ksDatabasePassword = KeyStoreItem(DATABASE_PASSWORD_ALIAS, appPreferences.encryptedDBPassphrase, appPreferences.initializationVectorDBPassphrase)
val ksAppPassword = KeyStoreItem(APP_PASSWORD_ALIAS, appPreferences.encryptedAppPassphrase, appPreferences.initializationVectorAppPassphrase)
class KeyStoreItem(private val alias: String, val passphrase: SharedPreference<String?>, val initVector: SharedPreference<String?>) {
fun get(): String? {
return cryptor.decryptData(
passphrase.get()?.toByteArrayFromBase64() ?: return null,
initVector.get()?.toByteArrayFromBase64() ?: return null,
alias,
)
}
fun set(key: String) {
val data = cryptor.encryptText(key, alias)
passphrase.set(data.first.toBase64String())
initVector.set(data.second.toBase64String())
}
fun remove() {
cryptor.deleteKey(alias)
passphrase.set(null)
initVector.set(null)
}
}
private fun hasDatabase(rootDir: String): Boolean =
File(rootDir + File.separator + "files_chat.db").exists() && File(rootDir + File.separator + "files_agent.db").exists()
fun getDatabaseKey(): String? {
return cryptor.decryptData(
appPreferences.encryptedDBPassphrase.get()?.toByteArrayFromBase64() ?: return null,
appPreferences.initializationVectorDBPassphrase.get()?.toByteArrayFromBase64() ?: return null,
DATABASE_PASSWORD_ALIAS,
)
}
fun setDatabaseKey(key: String) {
val data = cryptor.encryptText(key, DATABASE_PASSWORD_ALIAS)
appPreferences.encryptedDBPassphrase.set(data.first.toBase64String())
appPreferences.initializationVectorDBPassphrase.set(data.second.toBase64String())
}
fun removeDatabaseKey() {
cryptor.deleteKey(DATABASE_PASSWORD_ALIAS)
appPreferences.encryptedDBPassphrase.set(null)
appPreferences.initializationVectorDBPassphrase.set(null)
}
fun useDatabaseKey(): String {
Log.d(TAG, "useDatabaseKey ${appPreferences.storeDBPassphrase.get()}")
var dbKey = ""
@@ -47,10 +54,10 @@ object DatabaseUtils {
if (useKeychain) {
if (!hasDatabase(SimplexApp.context.dataDir.absolutePath)) {
dbKey = randomDatabasePassword()
setDatabaseKey(dbKey)
ksDatabasePassword.set(dbKey)
appPreferences.initialRandomDBPassphrase.set(true)
} else {
dbKey = getDatabaseKey() ?: ""
dbKey = ksDatabasePassword.get() ?: ""
}
}
return dbKey
@@ -101,4 +108,4 @@ data class UpMigration(
sealed class MTRError {
@Serializable @SerialName("noDown") class NoDown(val dbMigrations: List<String>): MTRError()
@Serializable @SerialName("different") class Different(val appMigration: String, val dbMigration: String): MTRError()
}
}
@@ -225,4 +225,4 @@ fun DefaultConfigurableTextField(
}
}
}
}
}
@@ -1,36 +1,66 @@
package chat.simplex.app.views.helpers
import android.content.Context
import android.os.Build.VERSION.SDK_INT
import android.widget.Toast
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.*
import androidx.biometric.BiometricPrompt
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.ui.Modifier
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import chat.simplex.app.R
import chat.simplex.app.SimplexApp
import chat.simplex.app.views.helpers.DatabaseUtils.ksAppPassword
import chat.simplex.app.views.localauth.LocalAuthView
import chat.simplex.app.views.usersettings.LAMode
sealed class LAResult {
object Success: LAResult()
class Error(val errString: CharSequence): LAResult()
object Failed: LAResult()
object Unavailable: LAResult()
class Failed(val errString: CharSequence? = null): LAResult()
class Unavailable(val errString: CharSequence? = null): LAResult()
}
data class LocalAuthRequest (
val title: String?,
val reason: String,
val password: String,
val completed: (LAResult) -> Unit
) {
companion object {
val sample = LocalAuthRequest(generalGetString(R.string.la_enter_app_passcode), generalGetString(R.string.la_authenticate), "") { }
}
}
fun authenticate(
promptTitle: String,
promptSubtitle: String,
activity: FragmentActivity,
usingLAMode: LAMode = SimplexApp.context.chatModel.controller.appPrefs.laMode.get(),
completed: (LAResult) -> Unit
) {
when {
SDK_INT in 28..29 ->
// KeyguardManager.isDeviceSecure()? https://developer.android.com/training/sign-in/biometric-auth#declare-supported-authentication-types
authenticateWithBiometricManager(promptTitle, promptSubtitle, activity, completed, BIOMETRIC_WEAK or DEVICE_CREDENTIAL)
SDK_INT > 29 ->
authenticateWithBiometricManager(promptTitle, promptSubtitle, activity, completed, BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
else ->
completed(LAResult.Unavailable)
when (usingLAMode) {
LAMode.SYSTEM -> when {
SDK_INT in 28..29 ->
// KeyguardManager.isDeviceSecure()? https://developer.android.com/training/sign-in/biometric-auth#declare-supported-authentication-types
authenticateWithBiometricManager(promptTitle, promptSubtitle, activity, completed, BIOMETRIC_WEAK or DEVICE_CREDENTIAL)
SDK_INT > 29 ->
authenticateWithBiometricManager(promptTitle, promptSubtitle, activity, completed, BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
else -> completed(LAResult.Unavailable())
}
LAMode.PASSCODE -> {
val password = ksAppPassword.get() ?: return completed(LAResult.Unavailable(generalGetString(R.string.la_no_app_password)))
ModalManager.shared.showCustomModal(animated = false) { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
LocalAuthView(SimplexApp.context.chatModel, LocalAuthRequest(promptTitle, promptSubtitle, password) {
close()
completed(it)
})
}
}
}
}
}
@@ -66,7 +96,7 @@ private fun authenticateWithBiometricManager(
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
completed(LAResult.Failed)
completed(LAResult.Failed())
}
}
)
@@ -78,9 +108,7 @@ private fun authenticateWithBiometricManager(
.build()
biometricPrompt.authenticate(promptInfo)
}
else -> {
completed(LAResult.Unavailable)
}
else -> completed(LAResult.Unavailable())
}
}
@@ -89,6 +117,18 @@ fun laTurnedOnAlert() = AlertManager.shared.showAlertMsg(
generalGetString(R.string.auth_you_will_be_required_to_authenticate_when_you_start_or_resume)
)
fun laPasscodeNotSetAlert() = AlertManager.shared.showAlertMsg(
generalGetString(R.string.lock_not_enabled),
generalGetString(R.string.you_can_turn_on_lock)
)
fun laFailedAlert() {
AlertManager.shared.showAlertMsg(
title = generalGetString(R.string.la_auth_failed),
text = generalGetString(R.string.la_could_not_be_verified)
)
}
fun laUnavailableInstructionAlert() = AlertManager.shared.showAlertMsg(
generalGetString(R.string.auth_unavailable),
generalGetString(R.string.auth_device_authentication_is_not_enabled_you_can_turn_on_in_settings_once_enabled)
@@ -640,4 +640,20 @@ fun DisposableEffectOnGone(always: () -> Unit = {}, whenDispose: () -> Unit = {}
}
}
}
}
}
@Composable
fun DisposableEffectOnRotate(always: () -> Unit = {}, whenDispose: () -> Unit = {}, whenRotate: () -> Unit) {
val context = LocalContext.current
DisposableEffect(Unit) {
always()
val activity = context as? Activity ?: return@DisposableEffect onDispose {}
val orientation = activity.resources.configuration.orientation
onDispose {
whenDispose()
if (orientation != activity.resources.configuration.orientation) {
whenRotate()
}
}
}
}
@@ -0,0 +1,22 @@
package chat.simplex.app.views.localauth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.res.stringResource
import chat.simplex.app.R
import chat.simplex.app.model.ChatModel
import chat.simplex.app.views.helpers.*
@Composable
fun LocalAuthView(m: ChatModel, authRequest: LocalAuthRequest) {
val passcode = rememberSaveable { mutableStateOf("") }
PasscodeView(passcode, authRequest.title ?: stringResource(R.string.la_enter_app_passcode), authRequest.reason, stringResource(R.string.submit_passcode),
submit = {
val r: LAResult = if (passcode.value == authRequest.password) LAResult.Success else LAResult.Error(generalGetString(R.string.incorrect_passcode))
authRequest.completed(r)
},
cancel = {
authRequest.completed(LAResult.Error(generalGetString(R.string.authentication_cancelled)))
})
}
@@ -0,0 +1,100 @@
package chat.simplex.app.views.localauth
import android.content.res.Configuration
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Done
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import chat.simplex.app.R
import chat.simplex.app.ui.theme.DEFAULT_PADDING
import chat.simplex.app.ui.theme.SimpleButton
import chat.simplex.app.views.helpers.*
@Composable
fun PasscodeView(
passcode: MutableState<String>,
title: String,
reason: String? = null,
submitLabel: String,
submitEnabled: ((String) -> Boolean)? = null,
submit: () -> Unit,
cancel: () -> Unit,
) {
@Composable
fun VerticalLayout() {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(title, style = MaterialTheme.typography.h1)
if (reason != null) {
Text(reason, Modifier.padding(top = 5.dp), style = MaterialTheme.typography.subtitle1)
}
}
PasscodeEntry(passcode, true)
Row {
SimpleButton(generalGetString(R.string.cancel_verb), icon = Icons.Default.Close, click = cancel)
Spacer(Modifier.size(20.dp))
SimpleButton(submitLabel, icon = Icons.Default.Done, disabled = submitEnabled?.invoke(passcode.value) == false || passcode.value.length < 4, click = submit)
}
}
}
@Composable
fun HorizontalLayout() {
Row(Modifier.padding(horizontal = DEFAULT_PADDING), horizontalArrangement = Arrangement.Center) {
Column(
Modifier.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, top = DEFAULT_PADDING * 4),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(title, style = MaterialTheme.typography.h1)
if (reason != null) {
Text(reason, Modifier.padding(top = 5.dp), style = MaterialTheme.typography.subtitle1)
}
}
PasscodeEntry(passcode, false)
}
Column(
Modifier.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, top = DEFAULT_PADDING * 4),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
// Just to fill space to correctly calculate the height
Column {
Text("", style = MaterialTheme.typography.h1)
if (reason != null) {
Text("", Modifier.padding(top = 5.dp), style = MaterialTheme.typography.subtitle1)
}
PasscodeView(remember { mutableStateOf("") })
}
BoxWithConstraints {
val s = minOf(maxWidth, maxHeight) / 3.5f
Column(
Modifier.padding(start = 30.dp).height(s * 3),
verticalArrangement = Arrangement.SpaceEvenly
) {
SimpleButton(generalGetString(R.string.cancel_verb), icon = Icons.Default.Close, click = cancel)
SimpleButton(submitLabel, icon = Icons.Default.Done, disabled = submitEnabled?.invoke(passcode.value) == false || passcode.value.length < 4, click = submit)
}
}
}
}
}
if (LocalContext.current.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
VerticalLayout()
} else {
HorizontalLayout()
}
}
@@ -0,0 +1,183 @@
package chat.simplex.app.views.localauth
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.outlined.Backspace
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.*
import chat.simplex.app.model.ChatModel
import chat.simplex.app.ui.theme.HighOrLowlight
@Composable
fun PasscodeEntry(
password: MutableState<String>,
vertical: Boolean,
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
PasscodeView(password)
BoxWithConstraints {
if (vertical) {
VerticalPasswordGrid(password)
} else {
HorizontalPasswordGrid(password)
}
}
}
}
@Composable
fun PasscodeView(password: MutableState<String>) {
var showPasscode by rememberSaveable { mutableStateOf(false) }
Text(
if (password.value.isEmpty()) " " else remember(password.value, showPasscode) { splitPassword(showPasscode, password.value) },
Modifier.padding(vertical = 10.dp).clickable { showPasscode = !showPasscode },
style = MaterialTheme.typography.body1
)
}
@Composable
private fun BoxWithConstraintsScope.VerticalPasswordGrid(password: MutableState<String>) {
val s = minOf(maxWidth, maxHeight) / 4 - 1.dp
Column(Modifier.width(IntrinsicSize.Min)) {
DigitsRow(s, 1, 2, 3, password)
Divider()
DigitsRow(s, 4, 5, 6, password)
Divider()
DigitsRow(s, 7, 8, 9, password)
Divider()
Row(Modifier.requiredHeight(s)) {
PasswordEdit(s, Icons.Default.Close) {
password.value = ""
}
VerticalDivider()
PasswordDigit(s, 0, password)
VerticalDivider()
PasswordEdit(s, Icons.Outlined.Backspace) {
password.value = password.value.dropLast(1)
}
}
}
}
@Composable
private fun BoxWithConstraintsScope.HorizontalPasswordGrid(password: MutableState<String>) {
val s = minOf(maxWidth, maxHeight) / 3.5f - 1.dp
Column(Modifier.width(IntrinsicSize.Min)) {
Row(Modifier.height(IntrinsicSize.Min)) {
DigitsRow(s, 1, 2, 3, password);
VerticalDivider()
PasswordEdit(s, Icons.Default.Close) {
password.value = ""
}
}
Divider()
Row(Modifier.height(IntrinsicSize.Min)) {
DigitsRow(s, 4, 5, 6, password)
VerticalDivider()
PasswordDigit(s, 0, password)
}
Divider()
Row(Modifier.height(IntrinsicSize.Min)) {
DigitsRow(s, 7, 8, 9, password)
VerticalDivider()
PasswordEdit(s, Icons.Outlined.Backspace) {
password.value = password.value.dropLast(1)
}
}
}
}
private fun splitPassword(showPassword: Boolean, password: String): String {
val n = if (password.length < 8) 8 else 4
return password.mapIndexed { index, c -> (if (showPassword) c.toString() else "") + (if ((index + 1) % n == 0) " " else "") }.joinToString("")
}
@Composable
private fun DigitsRow(size: Dp, d1: Int, d2: Int, d3: Int, password: MutableState<String>) {
Row(Modifier.height(size)) {
PasswordDigit(size, d1, password)
VerticalDivider()
PasswordDigit(size, d2, password)
VerticalDivider()
PasswordDigit(size, d3, password)
}
}
@Composable
private fun PasswordDigit(size: Dp, d: Int, password: MutableState<String>) {
val s = d.toString()
return PasswordButton(size, action = {
if (password.value.length < 16) {
password.value += s
}
}) {
Text(
s,
style = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 30.sp,
letterSpacing = (-0.5).sp
),
color = HighOrLowlight
)
}
}
@Composable
private fun PasswordEdit(size: Dp, image: ImageVector, action: () -> Unit) {
PasswordButton(size, action) {
Icon(image, null, tint = HighOrLowlight)
}
}
@Composable
private fun PasswordButton(size: Dp, action: () -> Unit, content: @Composable BoxScope.() -> Unit) {
return Box(
Modifier.size(size)
.background(MaterialTheme.colors.background, RoundedCornerShape(50))
.clickable { action() },
contentAlignment = Alignment.Center
) {
content()
}
}
@Composable
fun VerticalDivider(
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.onSurface.copy(alpha = DividerAlpha),
thickness: Dp = 1.dp,
startIndent: Dp = 0.dp
) {
val indentMod = if (startIndent.value != 0f) {
Modifier.padding(top = startIndent)
} else {
Modifier
}
val targetThickness = if (thickness == Dp.Hairline) {
(1f / LocalDensity.current.density).dp
} else {
thickness
}
Box(
modifier.then(indentMod)
.fillMaxHeight()
.width(targetThickness)
.background(color = color)
)
}
private const val DividerAlpha = 0.12f
@@ -0,0 +1,48 @@
package chat.simplex.app.views.localauth
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import chat.simplex.app.R
import chat.simplex.app.views.helpers.DatabaseUtils.ksAppPassword
import chat.simplex.app.views.helpers.generalGetString
@Composable
fun SetAppPasscodeView(
submit: () -> Unit,
cancel: () -> Unit,
close: () -> Unit
) {
val passcode = rememberSaveable { mutableStateOf("") }
var enteredPassword by rememberSaveable { mutableStateOf("") }
var confirming by rememberSaveable { mutableStateOf(false) }
@Composable
fun SetPasswordView(title: String, submitLabel: String, submitEnabled: (((String) -> Boolean))? = null, submit: () -> Unit) {
PasscodeView(passcode, title = title, submitLabel = submitLabel, submitEnabled = submitEnabled, submit = submit) {
close()
cancel()
}
}
if (confirming) {
SetPasswordView(
generalGetString(R.string.confirm_passcode),
generalGetString(R.string.confirm_verb),
submitEnabled = { pwd -> pwd == enteredPassword }
) {
if (passcode.value == enteredPassword) {
ksAppPassword.set(passcode.value)
enteredPassword = ""
passcode.value = ""
close()
submit()
}
}
} else {
SetPasswordView(generalGetString(R.string.new_passcode), generalGetString(R.string.save_verb)) {
enteredPassword = passcode.value
passcode.value = ""
confirming = true
}
}
}
@@ -70,4 +70,4 @@ fun PreviewHowItWorks() {
SimpleXTheme {
HowItWorks(user = null)
}
}
}
@@ -236,6 +236,7 @@ private fun LangSelector(state: State<String>, onSelected: (String) -> Unit) {
"fr" to "Français",
"it" to "Italiano",
"nl" to "Nederlands",
"pl" to "Polski",
"ru" to "Русский",
"zh-CN" to "简体中文"
)
@@ -56,4 +56,3 @@ fun DeveloperView(
}
}
}
@@ -87,4 +87,4 @@ private fun HiddenProfileLayout(
}
SectionTextFooter(stringResource(R.string.to_reveal_profile_enter_password))
}
}
}
@@ -7,22 +7,41 @@ import SectionTextFooter
import SectionView
import android.view.WindowManager
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.outlined.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.fragment.app.FragmentActivity
import chat.simplex.app.R
import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.ui.theme.SimplexGreen
import chat.simplex.app.views.helpers.*
import chat.simplex.app.views.helpers.DatabaseUtils.ksAppPassword
import chat.simplex.app.views.localauth.SetAppPasscodeView
enum class LAMode {
SYSTEM,
PASSCODE;
val text: String
get() = when (this) {
SYSTEM -> generalGetString(R.string.la_mode_system)
PASSCODE -> generalGetString(R.string.la_mode_passcode)
}
}
@Composable
fun PrivacySettingsView(
chatModel: ChatModel,
setPerformLA: (Boolean) -> Unit
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
setPerformLA: (Boolean, FragmentActivity) -> Unit
) {
Column(
Modifier.fillMaxWidth(),
@@ -31,7 +50,7 @@ fun PrivacySettingsView(
val simplexLinkMode = chatModel.controller.appPrefs.simplexLinkMode
AppBarTitle(stringResource(R.string.your_privacy))
SectionView(stringResource(R.string.settings_section_title_device)) {
ChatLockItem(chatModel.performLA, setPerformLA)
ChatLockItem(chatModel, showSettingsModal, setPerformLA)
SectionDivider()
val context = LocalContext.current
SettingsPreferenceItem(Icons.Outlined.VisibilityOff, stringResource(R.string.protect_app_screen), chatModel.controller.appPrefs.privacyProtectScreen) { on ->
@@ -52,10 +71,12 @@ fun PrivacySettingsView(
SectionDivider()
SettingsPreferenceItem(Icons.Outlined.TravelExplore, stringResource(R.string.send_link_previews), chatModel.controller.appPrefs.privacyLinkPreviews)
SectionDivider()
SectionItemView { SimpleXLinkOptions(chatModel.simplexLinkMode, onSelected = {
simplexLinkMode.set(it)
chatModel.simplexLinkMode.value = it
}) }
SectionItemView {
SimpleXLinkOptions(chatModel.simplexLinkMode, onSelected = {
simplexLinkMode.set(it)
chatModel.simplexLinkMode.value = it
})
}
}
if (chatModel.simplexLinkMode.value == SimplexLinkMode.BROWSER) {
SectionTextFooter(stringResource(R.string.simplex_link_mode_browser_warning))
@@ -83,3 +104,236 @@ private fun SimpleXLinkOptions(simplexLinkModeState: State<SimplexLinkMode>, onS
onSelected = onSelected
)
}
private val laDelays = listOf(10, 30, 60, 180, 0)
@Composable
fun SimplexLockView(
chatModel: ChatModel,
currentLAMode: SharedPreference<LAMode>,
setPerformLA: (Boolean, FragmentActivity) -> Unit
) {
val performLA = remember { chatModel.performLA }
val laMode = remember { chatModel.controller.appPrefs.laMode.state }
val laLockDelay = remember { chatModel.controller.appPrefs.laLockDelay }
val showChangePasscode = remember { derivedStateOf { performLA.value && currentLAMode.state.value == LAMode.PASSCODE } }
val activity = LocalContext.current as FragmentActivity
fun resetLAEnabled(onOff: Boolean) {
chatModel.controller.appPrefs.performLA.set(onOff)
chatModel.performLA.value = onOff
}
fun disableUnavailableLA() {
resetLAEnabled(false)
currentLAMode.set(LAMode.SYSTEM)
laUnavailableInstructionAlert()
}
fun toggleLAMode(toLAMode: LAMode) {
authenticate(
if (toLAMode == LAMode.SYSTEM) {
generalGetString(R.string.la_enter_app_passcode)
} else {
generalGetString(R.string.chat_lock)
},
generalGetString(R.string.change_lock_mode), activity
) { laResult ->
when (laResult) {
is LAResult.Error -> {
laFailedAlert()
}
is LAResult.Failed -> { /* Can be called multiple times on every failure */ }
LAResult.Success -> {
when (toLAMode) {
LAMode.SYSTEM -> {
authenticate(generalGetString(R.string.auth_enable_simplex_lock), promptSubtitle = "", activity, toLAMode) { laResult ->
when (laResult) {
LAResult.Success -> {
currentLAMode.set(toLAMode)
ksAppPassword.remove()
laTurnedOnAlert()
}
is LAResult.Unavailable, is LAResult.Error -> {
laFailedAlert()
}
is LAResult.Failed -> { /* Can be called multiple times on every failure */ }
}
}
}
LAMode.PASSCODE -> {
ModalManager.shared.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
SetAppPasscodeView(
submit = {
laLockDelay.set(30)
currentLAMode.set(toLAMode)
passcodeAlert(generalGetString(R.string.passcode_set))
},
cancel = {},
close
)
}
}
}
}
}
is LAResult.Unavailable -> disableUnavailableLA()
}
}
}
fun changeLAPassword() {
authenticate(generalGetString(R.string.la_current_app_passcode), generalGetString(R.string.la_change_app_passcode), activity) { laResult ->
when (laResult) {
LAResult.Success -> {
ModalManager.shared.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
SetAppPasscodeView(
submit = {
passcodeAlert(generalGetString(R.string.passcode_changed))
}, cancel = {
passcodeAlert(generalGetString(R.string.passcode_not_changed))
}, close
)
}
}
}
is LAResult.Error -> laFailedAlert()
is LAResult.Failed -> {}
is LAResult.Unavailable -> disableUnavailableLA()
}
}
}
Column(
Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.Start
) {
AppBarTitle(stringResource(R.string.chat_lock))
SectionView {
EnableLock(performLA) { performLAToggle ->
performLA.value = performLAToggle
chatModel.controller.appPrefs.laNoticeShown.set(true)
if (performLAToggle) {
when (currentLAMode.state.value) {
LAMode.SYSTEM -> {
setPerformLA(true, activity)
}
LAMode.PASSCODE -> {
ModalManager.shared.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
SetAppPasscodeView(
submit = {
laLockDelay.set(30)
chatModel.controller.appPrefs.performLA.set(true)
passcodeAlert(generalGetString(R.string.passcode_set))
},
cancel = {
resetLAEnabled(false)
}, close
)
}
}
}
}
} else {
setPerformLA(false, activity)
}
}
SectionDivider()
SectionItemView {
LockModeSelector(laMode) { newLAMode ->
if (laMode.value == newLAMode) return@LockModeSelector
if (chatModel.controller.appPrefs.performLA.get()) {
toggleLAMode(newLAMode)
} else {
currentLAMode.set(newLAMode)
}
}
}
if (performLA.value) {
SectionDivider()
SectionItemView {
LockDelaySelector(remember { laLockDelay.state }) { laLockDelay.set(it) }
}
if (showChangePasscode.value && laMode.value == LAMode.PASSCODE) {
SectionDivider()
SectionItemView({ changeLAPassword() }) {
Text(generalGetString(R.string.la_change_app_passcode))
}
}
}
}
}
}
@Composable
private fun EnableLock(performLA: MutableState<Boolean>, onCheckedChange: (Boolean) -> Unit) {
SectionItemView {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
stringResource(R.string.enable_lock), Modifier
.padding(end = 24.dp)
.fillMaxWidth()
.weight(1F)
)
Switch(
checked = performLA.value,
onCheckedChange = onCheckedChange,
colors = SwitchDefaults.colors(
checkedThumbColor = MaterialTheme.colors.primary,
uncheckedThumbColor = HighOrLowlight
)
)
}
}
}
@Composable
private fun LockModeSelector(state: State<LAMode>, onSelected: (LAMode) -> Unit) {
val values by remember { mutableStateOf(LAMode.values().map { it to it.text }) }
ExposedDropDownSettingRow(
generalGetString(R.string.lock_mode),
values,
state,
icon = null,
enabled = remember { mutableStateOf(true) },
onSelected = onSelected
)
}
@Composable
private fun LockDelaySelector(state: State<Int>, onSelected: (Int) -> Unit) {
val delays = remember { if (laDelays.contains(state.value)) laDelays else listOf(state.value) + laDelays }
val values by remember { mutableStateOf(delays.map { it to laDelayText(it) }) }
ExposedDropDownSettingRow(
generalGetString(R.string.lock_after),
values,
state,
icon = null,
enabled = remember { mutableStateOf(true) },
onSelected = onSelected
)
}
private fun laDelayText(t: Int): String {
val m = t / 60
val s = t % 60
return if (t == 0) {
generalGetString(R.string.la_immediately)
} else if (m == 0 || s != 0) {
// there are no options where both minutes and seconds are needed
generalGetString(R.string.la_seconds).format(s)
} else {
generalGetString(R.string.la_minutes).format(m)
}
}
private fun passcodeAlert(title: String) {
AlertManager.shared.showAlertMsg(
title = title,
text = generalGetString(R.string.la_please_remember_to_store_password)
)
}
@@ -42,7 +42,7 @@ import chat.simplex.app.views.onboarding.SimpleXInfo
import chat.simplex.app.views.onboarding.WhatsNewView
@Composable
fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit) {
fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean, FragmentActivity) -> Unit) {
val user = chatModel.currentUser.value
val stopped = chatModel.chatRunning.value == false
@@ -126,7 +126,7 @@ fun SettingsLayout(
incognito: MutableState<Boolean>,
incognitoPref: SharedPreference<Boolean>,
userDisplayName: String,
setPerformLA: (Boolean) -> Unit,
setPerformLA: (Boolean, FragmentActivity) -> Unit,
showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
showSettingsModalWithSearch: (@Composable (ChatModel, MutableState<String>) -> Unit) -> Unit,
@@ -174,7 +174,7 @@ fun SettingsLayout(
SectionDivider()
SettingsActionItem(Icons.Outlined.Videocam, stringResource(R.string.settings_audio_video_calls), showSettingsModal { CallSettingsView(it, showModal) }, disabled = stopped)
SectionDivider()
SettingsActionItem(Icons.Outlined.Lock, stringResource(R.string.privacy_and_security), showSettingsModal { PrivacySettingsView(it, setPerformLA) }, disabled = stopped)
SettingsActionItem(Icons.Outlined.Lock, stringResource(R.string.privacy_and_security), showSettingsModal { PrivacySettingsView(it, showSettingsModal, setPerformLA) }, disabled = stopped)
SectionDivider()
SettingsActionItem(Icons.Outlined.LightMode, stringResource(R.string.appearance_settings), showSettingsModal { AppearanceView(it) }, disabled = stopped)
SectionDivider()
@@ -294,13 +294,20 @@ fun MaintainIncognitoState(chatModel: ChatModel) {
)
}
@Composable fun ChatLockItem(performLA: MutableState<Boolean>, setPerformLA: (Boolean) -> Unit) {
SectionItemView() {
@Composable
fun ChatLockItem(
chatModel: ChatModel,
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
setPerformLA: (Boolean, FragmentActivity) -> Unit
) {
val performLA = remember { chatModel.performLA }
val currentLAMode = remember { chatModel.controller.appPrefs.laMode }
SectionItemView(showSettingsModal { SimplexLockView(chatModel, currentLAMode, setPerformLA) }) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
Icons.Outlined.Lock,
if (performLA.value) Icons.Filled.Lock else Icons.Outlined.Lock,
contentDescription = stringResource(R.string.chat_lock),
tint = HighOrLowlight,
tint = if (performLA.value) SimplexGreen else HighOrLowlight,
)
Spacer(Modifier.padding(horizontal = 4.dp))
Text(
@@ -309,14 +316,7 @@ fun MaintainIncognitoState(chatModel: ChatModel) {
.fillMaxWidth()
.weight(1F)
)
Switch(
checked = performLA.value,
onCheckedChange = { setPerformLA(it) },
colors = SwitchDefaults.colors(
checkedThumbColor = MaterialTheme.colors.primary,
uncheckedThumbColor = HighOrLowlight
)
)
Text(if (performLA.value) remember { currentLAMode.state }.value.text else generalGetString(androidx.compose.ui.R.string.off), color = HighOrLowlight)
}
}
}
@@ -517,7 +517,7 @@ private fun runAuth(context: Context, onFinish: (success: Boolean) -> Unit) {
generalGetString(R.string.auth_log_in_using_credential),
context as FragmentActivity,
completed = { laResult ->
onFinish(laResult == LAResult.Success || laResult == LAResult.Unavailable)
onFinish(laResult == LAResult.Success || laResult is LAResult.Unavailable)
}
)
}
@@ -538,7 +538,7 @@ fun PreviewSettingsLayout() {
incognito = remember { mutableStateOf(false) },
incognitoPref = SharedPreference({ false }, {}),
userDisplayName = "Alice",
setPerformLA = {},
setPerformLA = { _, _ -> },
showModal = { {} },
showSettingsModal = { {} },
showSettingsModalWithSearch = { },
@@ -388,4 +388,4 @@ private fun showMuteProfileAlert(showMuteProfileAlert: SharedPreference<Boolean>
showMuteProfileAlert.set(false)
},
)
}
}
@@ -23,7 +23,6 @@ fun VersionInfoView(info: CoreVersionInfo) {
Text(String.format(stringResource(R.string.app_version_name), BuildConfig.VERSION_NAME))
Text(String.format(stringResource(R.string.app_version_code), BuildConfig.VERSION_CODE))
Text(String.format(stringResource(R.string.core_version), info.version))
Text(String.format(stringResource(R.string.core_build_timestamp), info.buildTimestamp))
val simplexmqCommit = if (info.simplexmqCommit.length >= 7) info.simplexmqCommit.substring(startIndex = 0, endIndex = 7) else info.simplexmqCommit
Text(String.format(stringResource(R.string.core_simplexmq_version), info.simplexmqVersion, simplexmqCommit))
}
@@ -655,7 +655,6 @@
<string name="app_version_title">Verze aplikace</string>
<string name="app_version_name">Verze aplikace: v%s</string>
<string name="core_version">Verze jádra: v%s</string>
<string name="core_build_timestamp">Jádro sestaveno: %s</string>
<string name="delete_address__question">Smazat adresu\?</string>
<string name="all_your_contacts_will_remain_connected">Všechny vaše kontakty zůstanou připojeny.</string>
<string name="contact_requests">Žádosti o kontakt</string>
@@ -1000,7 +1000,6 @@
<string name="app_version_code">App Build: %s</string>
<string name="app_version_title">App Version</string>
<string name="app_version_name">App Version: v%s</string>
<string name="core_build_timestamp">Core übersetzt am: %s</string>
<string name="core_version">Core Version: v%s</string>
<string name="users_add">Profil hinzufügen</string>
<string name="users_delete_all_chats_deleted">Alle Chats und Nachrichten werden gelöscht! Dies kann nicht rückgängig gemacht werden!</string>
@@ -250,10 +250,9 @@
<string name="icon_descr_email">Email</string>
<string name="connect_button">Conectar</string>
<string name="connect_via_link">Conectar mediante enlace</string>
<string name="database_passphrase_and_export">Base de Datos
\ny Contraseña</string>
<string name="database_passphrase_and_export">Base de Datos y
\nContraseña</string>
<string name="contribute">Contribuye</string>
<string name="core_build_timestamp">Core compilado: %s</string>
<string name="core_version">Core versión: v%s</string>
<string name="contact_requests">Solicitud del contacto</string>
<string name="delete_image">Eliminar imagen</string>
@@ -454,7 +453,7 @@
<string name="invite_to_group_button">Invitar al grupo</string>
<string name="to_verify_compare">Para comprobar el cifrado de extremo a extremo con su contacto compare (o escanee) el código en sus dispositivos.</string>
<string name="database_is_not_encrypted">La base de datos no está cifrada. Escribe una contraseña para protegerla.</string>
<string name="ensure_smp_server_address_are_correct_format_and_unique">Asegúrate de que las direcciones del servidor SMP tienen el formato correcto, están separadas por líneas y no duplicadas.</string>
<string name="ensure_smp_server_address_are_correct_format_and_unique">Asegúrate de que las direcciones del servidor SMP tienen el formato correcto, están separadas por líneas y no están duplicadas.</string>
<string name="icon_descr_instant_notifications">Notificación instantánea</string>
<string name="network_settings_title">Configuración de red</string>
<string name="network_use_onion_hosts_no_desc_in_alert">No se usarán hosts .onion</string>
@@ -547,7 +546,7 @@
<string name="video_call_no_encryption">videollamada (sin cifrado e2e)</string>
<string name="status_no_e2e_encryption">sin cifrado e2e</string>
<string name="import_database">Importar base de datos</string>
<string name="settings_section_title_messages">MENSAJES</string>
<string name="settings_section_title_messages">MENSAJES Y ARCHIVOS</string>
<string name="import_database_question">¿Importar base de datos\?</string>
<string name="no_received_app_files">Sin archivos recibidos o enviados</string>
<string name="messages_section_title">Mensajes</string>
@@ -741,7 +740,7 @@
<string name="la_notice_turn_on">Activar</string>
<string name="share_verb">Compartir</string>
<string name="icon_descr_sent_msg_status_unauthorized_send">envío no autorizado</string>
<string name="set_contact_name">Escribe el nombre del contacto</string>
<string name="set_contact_name">Escribe un nombre para el contacto</string>
<string name="network_socks_toggle">Usar proxy SOCKS (puerto 9050)</string>
<string name="unknown_error">Error desconocido</string>
<string name="member_role_will_be_changed_with_notification">El rol cambiará a \"%s\". Se notificará a todos los miembros del grupo.</string>
@@ -749,7 +748,7 @@
<string name="v4_4_disappearing_messages_desc">Los mensajes enviados se eliminarán una vez transcurrido el tiempo establecido.</string>
<string name="ntf_channel_messages">Mensajes de chat SimpleX</string>
<string name="icon_descr_received_msg_status_unread">no leído</string>
<string name="text_field_set_contact_placeholder">Escribe el nombre del contacto…</string>
<string name="text_field_set_contact_placeholder">Escribe un nombre para el contacto…</string>
<string name="switch_receiving_address_question">¿Cambiar dirección de recepción\?</string>
<string name="use_camera_button">Usar cámara</string>
<string name="contact_you_shared_link_with_wont_be_able_to_connect">¡El contacto con el que has compartido este enlace NO podrá conectarse!</string>
@@ -826,7 +825,7 @@
<string name="rcv_group_event_updated_group_profile">perfil de grupo actualizado</string>
<string name="network_option_tcp_connection_timeout">Tiempo de espera de la conexión TCP agotado</string>
<string name="theme">Tema</string>
<string name="set_group_preferences">Establecer preferencias de grupo</string>
<string name="set_group_preferences">Establece preferencias de grupo</string>
<string name="settings_section_title_support">SOPORTE SIMPLEX CHAT</string>
<string name="set_password_to_export">Escribe la contraseña para exportar</string>
<string name="update_database">Actualizar</string>
@@ -1059,4 +1058,22 @@
<string name="video_will_be_received_when_contact_completes_uploading">El vídeo se recibirá cuando tu contacto termine de subirlo.</string>
<string name="videos_limit_desc">Solo se pueden enviar 10 vídeos de forma simultánea</string>
<string name="icon_descr_waiting_for_video">Esperando el vídeo</string>
<string name="error_saving_xftp_servers">Error guardando servidores SMP</string>
<string name="error_loading_xftp_servers">Error cargando servidores XFTP</string>
<string name="error_loading_smp_servers">Error cargando servidores SMP</string>
<string name="ensure_xftp_server_address_are_correct_format_and_unique">Asegúrate de que las direcciones del servidor XFTP tienen el formato correcto, están separadas por líneas y no están duplicadas.</string>
<string name="error_xftp_test_server_auth">El servidor requiere autorización para subir, comprueba la contraseña</string>
<string name="smp_server_test_compare_file">Comparar archivo</string>
<string name="smp_server_test_create_file">Crear archivo</string>
<string name="smp_server_test_delete_file">Eliminar archivo</string>
<string name="smp_server_test_upload_file">Subir archivo</string>
<string name="xftp_servers">Servidores XFTP</string>
<string name="your_XFTP_servers">Tus servidores XFTP</string>
<string name="port_verb">Puerto</string>
<string name="network_proxy_port">puerto %d</string>
<string name="disable_onion_hosts_when_not_supported">Establece <i>Usar hosts .onion</i> en No si el proxy SOCKS no los admite.</string>
<string name="smp_server_test_download_file">Descargar archivo</string>
<string name="network_socks_toggle_use_socks_proxy">Usar proxy SOCKS</string>
<string name="host_verb">Host</string>
<string name="network_socks_proxy_settings">Configuración proxy SOCKS</string>
</resources>
@@ -549,7 +549,7 @@
<string name="settings_experimental_features">Fonctionnalités expérimentales</string>
<string name="settings_section_title_socks">SOCKS PROXY</string>
<string name="settings_section_title_themes">THEMES</string>
<string name="settings_section_title_messages">MESSAGES</string>
<string name="settings_section_title_messages">MESSAGES ET FICHIERS</string>
<string name="settings_section_title_calls">APPELS</string>
<string name="import_database">Importer la base de données</string>
<string name="new_database_archive">Nouvelle archive de base de données</string>
@@ -925,7 +925,6 @@
<string name="core_simplexmq_version">simplexmq : v%s (%2s)</string>
<string name="app_version_code">Build de l\'app : %s</string>
<string name="app_version_name">Version de l\'app : v%s</string>
<string name="core_build_timestamp">Cœur compilé le : %s</string>
<string name="core_version">Version du cœur : v%s</string>
<string name="network_option_ping_count">Nombre de PING</string>
<string name="users_delete_all_chats_deleted">Toutes les discussions et tous les messages seront supprimés - il est impossible de revenir en arrière !</string>
@@ -1058,4 +1057,22 @@
<string name="video_will_be_received_when_contact_is_online">La vidéo ne sera reçue que lorsque votre contact sera en ligne. Veuillez patienter ou vérifier plus tard !</string>
<string name="icon_descr_video_asked_to_receive">Requête de réception de la vidéo</string>
<string name="videos_limit_desc">Seulement 10 vidéos peuvent être envoyées en même temps</string>
<string name="smp_server_test_create_file">Créer un fichier</string>
<string name="smp_server_test_delete_file">Supprimer le fichier</string>
<string name="error_saving_xftp_servers">Erreur lors de la sauvegarde des serveurs XFTP</string>
<string name="ensure_xftp_server_address_are_correct_format_and_unique">Assurez-vous que les adresses des serveurs XFTP sont au bon format, séparées par des lignes et qu\'elles ne sont pas dupliquées.</string>
<string name="error_xftp_test_server_auth">Le serveur requiert une autorisation pour uploader, vérifiez le mot de passe</string>
<string name="smp_server_test_upload_file">Transférer le fichier</string>
<string name="xftp_servers">Serveurs XFTP</string>
<string name="your_XFTP_servers">Vos serveurs XFTP</string>
<string name="smp_server_test_compare_file">Comparer le fichier</string>
<string name="smp_server_test_download_file">Télécharger le fichier</string>
<string name="error_loading_smp_servers">Erreur lors du chargement des serveurs SMP</string>
<string name="error_loading_xftp_servers">Erreur lors du chargement des serveurs XFTP</string>
<string name="host_verb">Héberger</string>
<string name="port_verb">Port</string>
<string name="network_proxy_port">port %d</string>
<string name="network_socks_proxy_settings">Paramètres de proxy SOCKS</string>
<string name="network_socks_toggle_use_socks_proxy">Utiliser un proxy SOCKS</string>
<string name="disable_onion_hosts_when_not_supported">Définissez <i>Utiliser les hôtes .onion</i> sur Non si le proxy SOCKS ne les prend pas en charge.</string>
</resources>
@@ -180,4 +180,107 @@
<string name="restore_database_alert_confirm">वापस लौटाना</string>
<string name="a_plus_b">ए + बी</string>
<string name="incognito_random_profile">आपका यादृच्छिक प्रोफ़ाइल</string>
<string name="chat_preferences">चैट वरीयताएँ</string>
<string name="ttl_days">%d दिनों</string>
<string name="allow_voice_messages_question">ध्वनि संदेशों की अनुमति दें\?</string>
<string name="clear_chat_menu_action">साफ़</string>
<string name="icon_descr_audio_off">ऑडियो बंद</string>
<string name="icon_descr_audio_on">ऑडियो चालू</string>
<string name="v4_4_disappearing_messages">गायब होने वाले संदेश</string>
<string name="v4_5_reduced_battery_usage_descr">अधिक सुधार जल्द ही आ रहे हैं!</string>
<string name="copy_verb">नकलना</string>
<string name="change_role">भूमिका बदलें</string>
<string name="ttl_hour">%d घंटा</string>
<string name="auth_unavailable">प्रमाणीकरण अनुपलब्ध</string>
<string name="icon_descr_edited">संपादित</string>
<string name="delete_group_question">समूह मिटाएं\?</string>
<string name="contact_already_exists">संपर्क पहले से मौजूद है</string>
<string name="notification_preview_mode_contact">संपर्क नाम</string>
<string name="notification_preview_somebody">संपर्क छुपाया गया:</string>
<string name="delete_verb">मिटाना</string>
<string name="auth_you_will_be_required_to_authenticate_when_you_start_or_resume">जब आप पृष्ठभूमि में 30 सेकंड के बाद ऐप को प्रारंभ या फिर से शुरू करते हैं तो आपको प्रमाणित करने की आवश्यकता होगी।</string>
<string name="icon_descr_asked_to_receive">प्रतिमा प्राप्त करने को कहा</string>
<string name="back">वापस</string>
<string name="icon_descr_close_button">बंद करें बटन</string>
<string name="create_address">पता बनाना</string>
<string name="invite_prohibited">संपर्क आमंत्रित नहीं कर सकते!</string>
<string name="icon_descr_contact_checked">संपर्क जांचा गया</string>
<string name="contact_preferences">संपर्क वरीयताएँ</string>
<string name="rcv_group_event_changed_your_role">आपकी भूमिका को %s में बदल दिया</string>
<string name="clear_contacts_selection_button">साफ़</string>
<string name="timed_messages">गायब होने वाले संदेश</string>
<string name="display_name__field">प्रदर्शित होने वाला नाम:</string>
<string name="theme_dark">अँधेरा</string>
<string name="allow_your_contacts_to_send_voice_messages">अपने संपर्कों को ध्वनि संदेश भेजने की अनुमति दें।</string>
<string name="ttl_day">%d दिन</string>
<string name="ttl_hours">%d घंटे</string>
<string name="v4_6_chinese_spanish_interface">चीनी और स्पेनिश इंटरफ़ेस</string>
<string name="simplex_link_mode_description">विवरण</string>
<string name="notifications_mode_off_desc">ऐप केवल तभी सूचनाएं प्राप्त कर सकता है जब वह चल रहा हो, कोई पृष्ठभूमि सेवा प्रारंभ नहीं की जाएगी</string>
<string name="edit_verb">संपादन करना</string>
<string name="decentralized">विकेन्द्रीकृत</string>
<string name="icon_descr_call_ended">कॉल समाप्त</string>
<string name="icon_descr_call_progress">कॉल चल रहा है</string>
<string name="auto_accept_images">छवियों को स्वत: स्वीकार करें</string>
<string name="chat_archive_header">चैट संग्रह</string>
<string name="chat_is_stopped_indication">चैट रोक दी गई है</string>
<string name="chat_archive_section">चैट संग्रह</string>
<string name="you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved">आप इस समूह से संदेश प्राप्त करना बंद कर देंगे। चैट इतिहास संरक्षित किया जाएगा।</string>
<string name="rcv_group_event_changed_member_role">%s की भूमिका को %s में बदला</string>
<string name="group_member_status_complete">पूर्ण</string>
<string name="disappearing_prohibited_in_this_chat">इस चैट में गायब होने वाले संदेश प्रतिबंधित हैं।</string>
<string name="disappearing_messages_are_prohibited">इस चैट में गायब होने वाले संदेश प्रतिबंधित हैं।</string>
<string name="chat_with_developers">डेवलपर्स के साथ चैट करें</string>
<string name="alert_title_contact_connection_pending">संपर्क अभी तक जुड़ा नहीं है!</string>
<string name="chat_console">चैट कंसोल</string>
<string name="all_your_contacts_will_remain_connected">आपके सभी संपर्क जुड़े रहेंगे।</string>
<string name="network_session_mode_user">चैट प्रोफ़ाइल</string>
<string name="contact_requests">संपर्क अनुरोध</string>
<string name="create_profile_button">बनाएं</string>
<string name="callstatus_error">कॉल त्रुटि</string>
<string name="callstatus_in_progress">कॉल चल रहा है</string>
<string name="always_use_relay">हमेशा रिले का प्रयोग करें</string>
<string name="icon_descr_audio_call">ऑडियो कॉल</string>
<string name="settings_audio_video_calls">ऑडियो और वीडियो कॉल</string>
<string name="call_already_ended">कॉल पहले ही खत्म हो चुकी है!</string>
<string name="no_call_on_lock_screen">अक्षम करना</string>
<string name="status_contact_has_e2e_encryption">संपर्क में ई2ई एन्क्रिप्शन है</string>
<string name="status_contact_has_no_e2e_encryption">संपर्क में कोई ई2ई एन्क्रिप्शन नहीं है</string>
<string name="chat_is_running">चैट चल रही है</string>
<string name="chat_is_stopped">चैट रोक दी गई है</string>
<string name="rcv_conn_event_switch_queue_phase_changing">पता बदल रहा है…</string>
<string name="ttl_min">%d मिनट</string>
<string name="settings_section_title_device">उपकरण</string>
<string name="group_member_status_creator">रचनाकार</string>
<string name="change_member_role_question">समूह भूमिका बदलें\?</string>
<string name="ttl_week">%d सप्ताह</string>
<string name="v4_2_auto_accept_contact_requests">संपर्क अनुरोधों को स्वत: स्वीकार करें</string>
<string name="integrity_msg_bad_hash">खराब संदेश हैश</string>
<string name="allow_voice_messages_only_if">ध्वनि संदेशों को केवल तभी अनुमति दें यदि आपका संपर्क उन्हें अनुमति देता है।</string>
<string name="incognito_random_profile_from_contact_description">जिस संपर्क से आपने यह लिंक प्राप्त किया है, उसे एक यादृच्छिक प्रोफ़ाइल भेजी जाएगी</string>
<string name="callstatus_calling">कॉल कर रहा है…</string>
<string name="feature_cancelled_item">रद्द %s</string>
<string name="rcv_conn_event_switch_queue_phase_completed">आपके लिए पता बदल दिया</string>
<string name="notifications_mode_periodic_desc">प्रत्येक 10 मिनट में 1 मिनट तक नए संदेशों की जाँच करता है</string>
<string name="ttl_sec">%d सेकंड</string>
<string name="ttl_month">%d महीना</string>
<string name="ttl_months">%d महीने</string>
<string name="settings_developer_tools">डेवलपर उपकरण</string>
<string name="incognito_random_profile_description">आपके संपर्क को एक यादृच्छिक प्रोफ़ाइल भेजी जाएगी</string>
<string name="snd_conn_event_switch_queue_phase_changing">पता बदल रहा है…</string>
<string name="button_add_welcome_message">स्वागत संदेश जोड़ें</string>
<string name="allow_your_contacts_irreversibly_delete">अपने संपर्कों को भेजे गए संदेशों को अपरिवर्तनीय रूप से हटाने की अनुमति दें।</string>
<string name="allow_to_send_voice">ध्वनि संदेश भेजने की अनुमति दें।</string>
<string name="alert_title_cant_invite_contacts">संपर्कों को आमंत्रित नहीं कर सकते!</string>
<string name="snd_conn_event_switch_queue_phase_changing_for_member">%s के लिए पता बदल रहा है…</string>
<string name="dont_show_again">दोबारा मत दिखाओ</string>
<string name="both_you_and_your_contact_can_send_voice">आप और आपका संपर्क दोनों ध्वनि संदेश भेज सकते हैं।</string>
<string name="settings_section_title_develop">विकास करना</string>
<string name="user_mute">आवाज़ बंद करना</string>
<string name="allow_your_contacts_to_send_disappearing_messages">अपने संपर्कों को गायब होने वाले संदेश भेजने की अनुमति दें।</string>
<string name="cancel_file__question">फ़ाइल स्थानांतरण रद्द करें\?</string>
<string name="v4_6_audio_video_calls">ऑडियो और वीडियो कॉल</string>
<string name="v4_6_reduced_battery_usage_descr">अधिक सुधार जल्द ही आ रहे हैं!</string>
<string name="icon_descr_video_asked_to_receive">वीडियो प्राप्त करने के लिए कहा</string>
<string name="delete_contact_all_messages_deleted_cannot_undo_warning">संपर्क और सभी संदेशों को हटा दिया जाएगा - इसे पूर्ववत नहीं किया जा सकता!</string>
</resources>
@@ -728,7 +728,7 @@
<string name="import_database_question">Importare il database della chat\?</string>
<string name="import_database">Importa database</string>
<string name="settings_section_title_incognito">Modalità incognito</string>
<string name="settings_section_title_messages">MESSAGGI</string>
<string name="settings_section_title_messages">MESSAGGI E FILE</string>
<string name="new_database_archive">Nuovo archivio database</string>
<string name="old_database_archive">Vecchio archivio del database</string>
<string name="restart_the_app_to_create_a_new_chat_profile">Riavvia l\'app per creare un profilo di chat nuovo.</string>
@@ -927,7 +927,6 @@
<string name="core_simplexmq_version">simplexmq: v%s (%2s)</string>
<string name="app_version_code">Build dell\'app: %s</string>
<string name="app_version_name">Versione app: v%s</string>
<string name="core_build_timestamp">Core compilato il: %s</string>
<string name="smp_servers_per_user">I server per le nuove connessioni del profilo di chat attuale</string>
<string name="users_add">Aggiungi profilo</string>
<string name="users_delete_question">Eliminare il profilo di chat\?</string>
@@ -1058,4 +1057,22 @@
<string name="video_will_be_received_when_contact_is_online">Il video verrà ricevuto quando il tuo contatto sarà in linea, attendi o controlla più tardi!</string>
<string name="icon_descr_waiting_for_video">In attesa del video</string>
<string name="waiting_for_video">In attesa del video</string>
<string name="error_loading_xftp_servers">Errore nel caricamento dei server XFTP</string>
<string name="error_saving_xftp_servers">Errore nel salvataggio dei server XFTP</string>
<string name="error_xftp_test_server_auth">Il server richiede l\'autorizzazione per l\'invio, controlla la password</string>
<string name="smp_server_test_compare_file">Confronta file</string>
<string name="smp_server_test_create_file">Crea file</string>
<string name="smp_server_test_download_file">Scarica file</string>
<string name="smp_server_test_upload_file">Invia file</string>
<string name="xftp_servers">Server XFTP</string>
<string name="your_XFTP_servers">I tuoi server XFTP</string>
<string name="network_socks_proxy_settings">Impostazioni proxy SOCKS</string>
<string name="network_socks_toggle_use_socks_proxy">Usa proxy SOCKS</string>
<string name="host_verb">Host</string>
<string name="port_verb">Porta</string>
<string name="network_proxy_port">porta %d</string>
<string name="disable_onion_hosts_when_not_supported">Imposta <i>Usa gli host .onion</i> su No se il proxy SOCKS non li supporta.</string>
<string name="smp_server_test_delete_file">Elimina file</string>
<string name="error_loading_smp_servers">Errore nel caricamento dei server SMP</string>
<string name="ensure_xftp_server_address_are_correct_format_and_unique">Assicurati che gli indirizzi del server XFTP siano nel formato corretto, uno per riga e non doppi.</string>
</resources>
@@ -540,7 +540,6 @@
<string name="markdown_help">マークダウン (書式編集) ガイド</string>
<string name="smp_servers_enter_manually">サーバを手動で入力</string>
<string name="network_use_onion_hosts_required_desc">接続にオニオンのホストが必要となります。</string>
<string name="core_build_timestamp">コアのビルド@: %s</string>
<string name="create_address">アドレスを作成</string>
<string name="delete_address__question">アドレスを削除しますか?</string>
<string name="display_name__field">表示の名前:</string>
@@ -10,7 +10,7 @@
<string name="contact_already_exists">이미 추가된 연락처에요.</string>
<string name="smp_server_test_connect">연결</string>
<string name="connection_error_auth">연결 오류 (인증)</string>
<string name="smp_server_test_create_queue">대기열 생성</string>
<string name="smp_server_test_create_queue">대기열 만들기</string>
<string name="database_initialization_error_title">데이터베이스를 초기화할 수 없어요</string>
<string name="notifications_mode_service_desc">앱이 백그라운드에서 항상 실행되어요. 대신 메시지가 도착하자마자 바로 알림이 와요.</string>
<string name="notifications_mode_periodic_desc">10분마다 최대 1분간 새 메시지 확인</string>
@@ -43,10 +43,10 @@
<string name="clear_chat_question">채팅을 지울까요\?</string>
<string name="connection_request_sent">연결 요청 완료</string>
<string name="connect_via_link">링크를 통해 연결</string>
<string name="smp_servers_preset_add">프리셋 서버 추가</string>
<string name="smp_servers_preset_add">프리셋 서버 추가하기</string>
<string name="smp_servers_add">서버 추가…</string>
<string name="chat_console">채팅 콘솔</string>
<string name="smp_servers_check_address">서버 주소를 확인 후 다시 시도하십시오.</string>
<string name="smp_servers_check_address">서버 주소를 확인 후 다시 시도해 주세요.</string>
<string name="configure_ICE_servers">ICE 서버 설정</string>
<string name="contribute">기여</string>
<string name="network_settings">고급 네트워크 설정</string>
@@ -97,8 +97,8 @@
<string name="chat_archive_section">채팅 기록 보관함</string>
<string name="rcv_group_event_changed_your_role">내 역할이 %s 역할로 변경됨.</string>
<string name="rcv_conn_event_switch_queue_phase_changing">주소 바꾸는 중…</string>
<string name="snd_conn_event_switch_queue_phase_changing">주소 바꾸</string>
<string name="snd_conn_event_switch_queue_phase_changing_for_member">%s의 주소 바꾸</string>
<string name="snd_conn_event_switch_queue_phase_changing">주소 바꾸는 중</string>
<string name="snd_conn_event_switch_queue_phase_changing_for_member">%s의 주소 바꾸는 중</string>
<string name="rcv_group_event_member_connected">연결됨</string>
<string name="group_member_status_complete">완료</string>
<string name="group_member_status_connected">연결됨</string>
@@ -135,7 +135,7 @@
<string name="v4_6_chinese_spanish_interface">중국어 및 스페인어 인터페이스</string>
<string name="about_simplex">SimpleX에 대하여</string>
<string name="accept">수락</string>
<string name="share_one_time_link">일회용 초대 링크 생성</string>
<string name="share_one_time_link">일회용 초대 링크 만들기</string>
<string name="create_address">주소 생성</string>
<string name="chat_item_ttl_day">1일</string>
<string name="about_simplex_chat"><xliff:g id="appNameFull">SimpleX</xliff:g>에 대하여</string>
@@ -176,7 +176,7 @@
<string name="onboarding_notifications_mode_off_desc"><b>배터리에 가장 좋음</b>. 앱이 실행 중일 때만 알림을 받게 되며 백그라운드에서 실행되지 않습니다.</string>
<string name="it_can_disabled_via_settings_notifications_still_shown"><b>설정을 통해 비활성화할 수 있어요.</b> – 앱이 실행되는 동안 알림이 표시되요.</string>
<string name="both_you_and_your_contact_can_send_disappearing">나와 대화 상대 모두 자동 삭제되는 메시지를 보낼 수 있어요.</string>
<string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><b>QR 코드 스캔</b>: QR 코드를 보여주는 사람과 연결요.</string>
<string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><b>QR 코드 스캔</b>: QR 코드를 보여주는 사람과 연결할 수 있어요.</string>
<string name="cannot_access_keychain">데이터베이스 암호를 저장하고 있는 암호키 저장소에 접근할 수 없습니다</string>
<string name="onboarding_notifications_mode_service_desc"><b>배터리 많이 사용</b>! 백그라운드에서 항상 실행돼요. 메시지를 수신하자마자 알림이 떠요.</string>
<string name="callstatus_ended">통화 종료됨 <xliff:g id="duration" example="01:15">%1$s</xliff:g></string>
@@ -206,7 +206,6 @@
<string name="delete_contact_all_messages_deleted_cannot_undo_warning">대화 상대와 메시지가 삭제돼요. 삭제 후 되돌릴 수 없어요!</string>
<string name="status_contact_has_e2e_encryption">대화 상대와 종단간 암호화됨</string>
<string name="alert_title_contact_connection_pending">대화 상대와 아직 연결되지 않았어요!</string>
<string name="core_build_timestamp">코어 빌드: %s</string>
<string name="archive_created_on_ts"><xliff:g id="archive_ts">%1$s</xliff:g>에 생성 완료</string>
<string name="create_one_time_link">일회용 초대 링크 생성</string>
<string name="create_secret_group_title">비밀 그룹 생성</string>
@@ -253,7 +252,7 @@
<string name="delete_after">다음 기간 이후 자동 삭제</string>
<string name="above_then_preposition_continuation">위 다음 :</string>
<string name="delete_database">데이터베이스 삭제</string>
<string name="set_password_to_export_desc">데이터베이스는 임의의 비밀번호로 암호화되었습니다. 내보내기 기능 사용 전 비밀번호를 변경해 주세요.</string>
<string name="set_password_to_export_desc">데이터베이스는 임의의 비밀번호로 암호화되었어요. 내보내기 기능 사용 전 비밀번호를 변경해 주세요.</string>
<string name="delete_files_and_media_question">파일과 미디어를 삭제할까요\?</string>
<string name="current_passphrase">현재 비밀번호…</string>
<string name="database_encrypted">데이터베이스 암호화 완료!</string>
@@ -764,4 +763,128 @@
<string name="people_can_connect_only_via_links_you_share">공유한 링크를 통해서만 나에게 연결할 수 있어요.</string>
<string name="rcv_group_event_updated_group_profile">그룹 프로필 업데이트됨</string>
<string name="profile_password">프로필 비밀번호</string>
<string name="reveal_verb">보이기</string>
<string name="save_verb">저장하기</string>
<string name="scan_QR_code">QR 코드 스캔하기</string>
<string name="reply_verb">답장</string>
<string name="reset_verb">초기화</string>
<string name="save_servers_button">저장하기</string>
<string name="save_and_notify_contacts">저장하고 모든 대화 상대에게 알리기</string>
<string name="save_and_notify_group_members">저장하고 그룹 멤버들에게 알리기</string>
<string name="save_and_notify_contact">저장하고 대화 상대에게 알리기</string>
<string name="remove_passphrase">지우기</string>
<string name="save_archive">아카이브 저장하기</string>
<string name="save_color">색상 저장하기</string>
<string name="save_passphrase_in_keychain">암호 저장소에 비밀번호 저장하기</string>
<string name="restore_database">데이터베이스 백업 복원하기</string>
<string name="restore_database_alert_desc">데이터베이스 백업을 복원한 후 이전 비밀번호를 입력해 주세요. 이 작업은 되돌릴 수 없어요.</string>
<string name="restore_database_alert_title">데이터베이스 백업을 복원할까요\?</string>
<string name="restore_passphrase_not_found_desc">키스토어에서 암호를 찾을 수 없어요. 직접 입력해 주세요. 백업 도구를 사용하여 복원했을 때 이 문제가 발생할 수 있는데, 그런 경우가 아니라면 개발자에게 알려주세요.</string>
<string name="save_and_update_group_profile">저장하고 그룹 프로필 업데이트하기</string>
<string name="save_welcome_message_question">환영 메시지를 저장할까요\?</string>
<string name="save_group_profile">그룹 프로필 저장하기</string>
<string name="reset_color">색상 초기화</string>
<string name="remove_member_confirmation">강퇴하기</string>
<string name="scan_code">코드 스캔하기</string>
<string name="scan_code_from_contacts_app">대화 상대의 앱에서 보안 코드를 스캔해 주세요.</string>
<string name="saved_ICE_servers_will_be_removed">저장된 WebRTC ICE 서버가 제거될 거예요.</string>
<string name="save_passphrase_and_open_chat">비밀번호 저장하고 채팅 열기</string>
<string name="role_in_group">역할</string>
<string name="save_preferences_question">설정을 저장할까요\?</string>
<string name="save_profile_password">프로필 비밀번호 저장하기</string>
<string name="restart_the_app_to_use_imported_chat_database">가져온 채팅 데이터베이스를 사용하려면 앱을 다시 실행해 주세요.</string>
<string name="restart_the_app_to_create_a_new_chat_profile">새 프로필을 만드려면 앱을 다시 실행해 주세요.</string>
<string name="remove_passphrase_from_keychain">암호 저장소에서 비밀번호를 삭제할까요\?</string>
<string name="run_chat_section">채팅 기능 실행하기</string>
<string name="restore_database_alert_confirm">복원하기</string>
<string name="sender_cancelled_file_transfer">대화 상대가 파일 전송을 취소했어요.</string>
<string name="smp_server_test_secure_queue">보안 대기열</string>
<string name="smp_server_test_upload_file">파일 업로드하기</string>
<string name="smp_server_test_compare_file">파일 비교</string>
<string name="smp_server_test_delete_file">파일 삭제하기</string>
<string name="smp_server_test_download_file">파일 다운로드하기</string>
<string name="share_verb">공유</string>
<string name="send_live_message">라이브 메시지 보내기</string>
<string name="show_QR_code">QR코드 보기</string>
<string name="smp_server_test_create_file">파일 만들기</string>
<string name="sender_you_pronoun"></string>
<string name="sending_files_not_yet_supported">파일 보내기는 아직 지원되지 않아요.</string>
<string name="simplex_link_connection"><xliff:g id="serverHost" example="smp.simplex.im">%1$s</xliff:g>를 통해</string>
<string name="simplex_link_contact">SimpleX 연락처 주소</string>
<string name="simplex_link_group">SimpleX 그룹 링크</string>
<string name="simplex_link_invitation">SimpleX 일회용 초대 링크</string>
<string name="simplex_link_mode">SimpleX 링크</string>
<string name="simplex_link_mode_browser">브라우저를 통해</string>
<string name="simplex_link_mode_browser_warning">브라우저에서 링크를 열면 익명성 또는 보안에 문제가 생길 수 있어요. 신뢰할 수 없는 SimpleX 링크는 빨간색으로 표시되어요.</string>
<string name="simplex_link_mode_full">링크 전체</string>
<string name="sender_may_have_deleted_the_connection_request">보낸 사람이 연결 요청을 삭제했을 수 있어요.</string>
<string name="service_notifications_disabled">즉각적인 알림이 비활성화되었어요!</string>
<string name="settings_notification_preview_mode_title">미리보기 표시</string>
<string name="settings_notification_preview_title">알림 미리보기</string>
<string name="settings_notifications_mode_title">알림 서비스</string>
<string name="simplex_service_notification_text">메시지 받는 중…</string>
<string name="simplex_service_notification_title"><xliff:g id="appNameFull">SimpleX 채팅</xliff:g> 서비스</string>
<string name="share_file">파일 공유…</string>
<string name="share_image">이미지 공유…</string>
<string name="share_message">메시지 공유…</string>
<string name="send_live_message_desc">라이브 메시지 보내기 - 입력 과정을 실시간으로 상대에게 보여줘요.</string>
<string name="send_verb">보내기</string>
<string name="share_invitation_link">초대 링크 공유</string>
<string name="show_QR_code_for_your_contact_to_scan_from_the_app__multiline">연락하고자 하는 사람이 앱에서 QR 코드를 스캔할 수 있어요.</string>
<string name="security_code">보안 코드</string>
<string name="smp_servers_scan_qr">서버 QR코드 스캔</string>
<string name="smp_servers_test_some_failed">일부 서버가 테스트에 통과하지 못했습니다 :</string>
<string name="smp_servers_test_failed">서버 테스트 실패!</string>
<string name="section_title_welcome_message">환영 메시지</string>
<string name="share_link">링크 공유</string>
<string name="show_call_on_lock_screen">표시하기</string>
<string name="select_contacts">연락처 선택</string>
<string name="skip_inviting_button">멤버 초대 건너뛰기</string>
<string name="sending_via">다음을 통해 보내기</string>
<string name="settings_send_files_via_xftp">XFTP로 동영상 및 파일 보내기</string>
<string name="stop_chat_confirmation">멈추기</string>
<string name="snd_group_event_changed_member_role">%s의 역할을 %s로 변경했어요.</string>
<string name="section_title_for_console">콘솔용</string>
<string name="should_be_at_least_one_visible_profile">적어도 하나의 숨겨지지 않은 사용자 프로필이 있어야 해요.</string>
<string name="set_group_preferences">그룹 설정 지정하기</string>
<string name="snd_conn_event_switch_queue_phase_completed_for_member">%s의 주소를 바꿨어요</string>
<string name="snd_conn_event_switch_queue_phase_completed">주소를 바꿨어요</string>
<string name="snd_group_event_group_profile_updated">그룹 프로필 업데이트됨</string>
<string name="should_be_at_least_one_profile">적어도 하나의 사용자 프로필이 있어야 해요.</string>
<string name="smp_servers_test_server">서버 테스트하기</string>
<string name="smp_servers_use_server">서버 사용하기</string>
<string name="smp_servers_use_server_for_new_conn">새로운 대화에 사용</string>
<string name="smp_servers_invalid_address">잘못된 서버 주소에요!</string>
<string name="secret">비밀</string>
<string name="status_no_e2e_encryption">종단 간 암호화 안 됨</string>
<string name="settings_section_title_themes">테마</string>
<string name="snd_group_event_changed_role_for_yourself">내 역할이 %s로 변경되었어요.</string>
<string name="snd_group_event_user_left">나감</string>
<string name="settings_section_title_help">도움말</string>
<string name="settings_section_title_settings">설정</string>
<string name="send_link_previews">링크 미리보기 보내기</string>
<string name="settings_section_title_socks">SOCKS 프록시</string>
<string name="settings_section_title_support">SIMPLEX CHAT 도와주기</string>
<string name="settings_section_title_you"></string>
<string name="settings_experimental_features">실험적 기능</string>
<string name="show_dev_options">표시 :</string>
<string name="set_contact_name">연락처 이름 설정</string>
<string name="send_us_an_email">개발자에게 이메일 보내기</string>
<string name="smp_servers_enter_manually">서버를 수동으로 입력</string>
<string name="smp_servers_preset_server">미리 설정된 서버</string>
<string name="smp_servers_save">서버 저장하기</string>
<string name="smp_servers_test_servers">서버 테스트하기</string>
<string name="smp_servers_per_user">현재 채팅 프로필의 새로운 연결을 위한 서버</string>
<string name="smp_save_servers_question">서버를 저장할까요\?</string>
<string name="star_on_github">GitHub에서 별 주기</string>
<string name="show_developer_options">개발자 옵션 보기</string>
<string name="settings_section_title_messages">메시지 및 파일</string>
<string name="settings_section_title_incognito">익명 모드</string>
<string name="settings_section_title_experimenta">실험적</string>
<string name="set_password_to_export">내보낼 비밀번호 설정</string>
<string name="smp_servers">SMP 서버</string>
<string name="smp_servers_preset_address">미리 설정된 서버 주소</string>
<string name="smp_servers_your_server">내 서버</string>
<string name="smp_servers_your_server_address">내 서버 주소</string>
<string name="snd_group_event_member_deleted"><xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g>을(를) 강퇴했어요.</string>
</resources>
@@ -159,7 +159,6 @@
<string name="incorrect_code">Neteisingas saugumo kodas!</string>
<string name="smp_servers_save">Įrašyti serverius</string>
<string name="smp_save_servers_question">Įrašyti serverius\?</string>
<string name="core_build_timestamp">Branduolys sudarytas: %s</string>
<string name="create_address">Sukurti adresą</string>
<string name="delete_address">Ištrinti adresą</string>
<string name="error_saving_user_password">Klaida įrašant naudotojo slaptažodį</string>
@@ -174,7 +174,6 @@
<string name="contribute">Bijdragen</string>
<string name="configure_ICE_servers">ICE servers configureren</string>
<string name="network_session_mode_entity">Verbinding</string>
<string name="core_build_timestamp">Core gebouwd op: %s</string>
<string name="core_version">Core versie: v%s</string>
<string name="callstate_connected">verbonden</string>
<string name="callstate_connecting">Verbinden…</string>
@@ -494,7 +493,7 @@
<string name="group_member_role_member">Gebruiker</string>
<string name="image_descr_link_preview">link voorbeeld afbeelding</string>
<string name="member_info_section_title_member">GEBRUIKER</string>
<string name="settings_section_title_messages">BERICHTEN</string>
<string name="settings_section_title_messages">BERICHTEN EN BESTANDEN</string>
<string name="mobile_tap_open_in_mobile_app_then_tap_connect_in_app">📱 mobiel: tik op <b>Openen in mobiele app</b> en tik vervolgens op <b>Verbinden</b> in de app.</string>
<string name="member_will_be_removed_from_group_cannot_be_undone">Gebruiker wordt uit de groep verwijderd, dit kan niet ongedaan worden gemaakt!</string>
<string name="message_delivery_error_title">Fout bij bezorging van bericht</string>
@@ -1057,4 +1056,22 @@
<string name="waiting_for_video">Wachten op video</string>
<string name="video_descr">Video</string>
<string name="video_will_be_received_when_contact_completes_uploading">De video wordt ontvangen wanneer uw contactpersoon het uploaden heeft voltooid.</string>
<string name="error_saving_xftp_servers">Fout bij opslaan van XFTP-servers</string>
<string name="error_loading_xftp_servers">Fout bij het laden van XFTP servers</string>
<string name="error_xftp_test_server_auth">Server vereist autorisatie om te uploaden, wachtwoord controleren</string>
<string name="smp_server_test_compare_file">Bestand vergelijken</string>
<string name="smp_server_test_delete_file">Bestand verwijderen</string>
<string name="smp_server_test_download_file">Bestand downloaden</string>
<string name="smp_server_test_upload_file">Upload bestand</string>
<string name="xftp_servers">XFTP servers</string>
<string name="your_XFTP_servers">Uw XFTP servers</string>
<string name="host_verb">Host</string>
<string name="port_verb">Poort</string>
<string name="network_socks_proxy_settings">SOCKS proxy instellingen</string>
<string name="network_socks_toggle_use_socks_proxy">Gebruik SOCKS proxy</string>
<string name="disable_onion_hosts_when_not_supported">Stel <i>Use .onion hosts</i> in op Nee als de SOCKS-proxy deze niet ondersteunt.</string>
<string name="smp_server_test_create_file">Bestand maken</string>
<string name="error_loading_smp_servers">Fout bij het laden van SMP servers</string>
<string name="ensure_xftp_server_address_are_correct_format_and_unique">Zorg ervoor dat XFTP server adressen de juiste indeling hebben, regel gescheiden zijn en niet gedupliceerd zijn.</string>
<string name="network_proxy_port">poort %d</string>
</resources>
@@ -344,7 +344,6 @@
\n<b>Uwaga</b>: jeśli masz wiele połączeń, zużycie baterii i ruchu może być znacznie wyższe, a niektóre połączenia mogą się nie udać.</string>
<string name="network_session_mode_user">Profil czatu</string>
<string name="network_session_mode_entity">Połączenie</string>
<string name="core_build_timestamp">Kompilacja rdzenia: %s</string>
<string name="core_version">Wersja rdzenia: v%s</string>
<string name="error_saving_ICE_servers">Błąd zapisu serwerów ICE</string>
<string name="enter_one_ICE_server_per_line">Serwery ICE (po jednym na linię)</string>
@@ -536,7 +535,7 @@
<string name="settings_section_title_help">POMOC</string>
<string name="import_database">Importuj bazę danych</string>
<string name="settings_section_title_incognito">Tryb incognito</string>
<string name="settings_section_title_messages">WIADOMOŚCI</string>
<string name="settings_section_title_messages">WIADOMOŚCI I PLIKI</string>
<string name="new_database_archive">Nowe archiwum bazy danych</string>
<string name="old_database_archive">Stare archiwum bazy danych</string>
<string name="protect_app_screen">Chroń ekran aplikacji</string>
@@ -1058,4 +1057,22 @@
<string name="you_will_join_group">Dołączysz do grupy, do której odnosi się ten link i połączysz się z jej członkami.</string>
<string name="your_SMP_servers">Twoje serwery SMP</string>
<string name="you_will_be_connected_when_your_connection_request_is_accepted">Zostaniesz połączony, gdy Twoje żądanie połączenia zostanie zaakceptowane, proszę czekać lub sprawdzić później!</string>
<string name="error_loading_smp_servers">Błąd ładowania serwerów SMP</string>
<string name="error_loading_xftp_servers">Błąd ładowania serwerów XFTP</string>
<string name="error_saving_xftp_servers">Błąd zapisu serwerów XFTP</string>
<string name="smp_server_test_create_file">Utwórz plik</string>
<string name="smp_server_test_download_file">Pobierz plik</string>
<string name="error_xftp_test_server_auth">Serwer wymaga autoryzacji do przesłania, sprawdź hasło</string>
<string name="smp_server_test_upload_file">Prześlij plik</string>
<string name="smp_server_test_compare_file">Porównaj plik</string>
<string name="smp_server_test_delete_file">Usuń plik</string>
<string name="xftp_servers">Serwery XFTP</string>
<string name="your_XFTP_servers">Twoje serwery XFTP</string>
<string name="host_verb">Host</string>
<string name="port_verb">Port</string>
<string name="network_proxy_port">port %d</string>
<string name="disable_onion_hosts_when_not_supported">Ustaw <i>Użyj hostów .onion</i> na Nie jeśli proxy SOCKS ich nie obsługuje.</string>
<string name="network_socks_proxy_settings">Ustawienia PROXY SOCKS</string>
<string name="network_socks_toggle_use_socks_proxy">Użyj proxy SOCKS</string>
<string name="ensure_xftp_server_address_are_correct_format_and_unique">Upewnij się, że adresy serwerów XFTP są w poprawnym formacie, rozdzielone liniami i nie są zduplikowane.</string>
</resources>
@@ -664,7 +664,6 @@
<string name="network_use_onion_hosts_required_desc">Os hosts Onion serão necessários para a conexão.</string>
<string name="network_use_onion_hosts_required_desc_in_alert">Os hosts Onion serão necessários para a conexão.</string>
<string name="core_version">Versão principal: v%s</string>
<string name="core_build_timestamp">Núcleo construído em: %s</string>
<string name="read_more_in_github_with_link">Leia mais no nosso<font color="#0088ff"> repositório do GitHub</font>.</string>
<string name="onboarding_notifications_mode_subtitle">Pode ser mudado mais tarde via configurações.</string>
<string name="contact_wants_to_connect_via_call"><xliff:g id="contactName" example="Alice">%1$s</xliff:g> quer se conectar com você via</string>
@@ -1025,7 +1025,6 @@
<string name="network_session_mode_entity_description">Отдельное TCP-соединение (и авторизация SOCKS) будет использоваться <b>для каждого контакта и члена группы</b>.
\n<b>Обратите внимание</b>: если у Вас много контактов, потребление батареи и трафика может быть значительно выше, и некоторые соединения могут не работать.</string>
<string name="network_session_mode_user_description">Отдельное TCP-соединение (и авторизация SOCKS) будет использоваться <b>для каждого профиля чата, который Вы имеете в приложении</b>.</string>
<string name="core_build_timestamp">Ядро скомпилировано: %s</string>
<string name="core_version">Версия ядра: v%s</string>
<string name="users_delete_question">Удалить профиль чата\?</string>
<string name="users_delete_profile_for">Удалить профиль чата для</string>
@@ -37,7 +37,7 @@
<string name="delete_files_and_media_all">删除所有文件</string>
<string name="messages_section_title">消息</string>
<string name="delete_messages_after">在此后删除消息</string>
<string name="settings_section_title_messages">消息</string>
<string name="settings_section_title_messages">消息和文件</string>
<string name="users_add">添加个人资料</string>
<string name="users_delete_all_chats_deleted">所有聊天记录和消息将被删除——这一行为无法撤销!</string>
<string name="clear_chat_warning">所有聊天记录和消息将被删除——这一行为无法撤销!只有您的消息会被删除。</string>
@@ -103,7 +103,7 @@
<string name="app_version_name">应用程序版本:v%s</string>
<string name="notifications_mode_off_desc">仅在运行时应用程序可以接受通知,不会启动后台服务</string>
<string name="incognito_random_profile_description">一个随机资料将发送给您的联系人</string>
<string name="auth_unavailable">身份证不可用</string>
<string name="auth_unavailable">身份证不可用</string>
<string name="auto_accept_images">自动接受图像</string>
<string name="attach">附件</string>
<string name="icon_descr_audio_call">语音通话</string>
@@ -363,7 +363,6 @@
<string name="encrypted_audio_call">端到端加密语音通话</string>
<string name="enter_one_ICE_server_per_line">ICE 服务器(每行一个)</string>
<string name="create_address">创建地址</string>
<string name="core_build_timestamp">核心构建于:%s</string>
<string name="core_version">核心版本: v%s</string>
<string name="display_name__field">显示名:</string>
<string name="full_name__field">全名:</string>
@@ -1058,4 +1057,22 @@
<string name="icon_descr_video_snd_complete">视频已发送</string>
<string name="icon_descr_video_asked_to_receive">要求接收视频</string>
<string name="video_will_be_received_when_contact_completes_uploading">视频将在您的联系人完成上传后收到。</string>
<string name="error_xftp_test_server_auth">服务器需要授权来上传,检查密码</string>
<string name="smp_server_test_upload_file">上传文件</string>
<string name="xftp_servers">XFTP 服务器</string>
<string name="your_XFTP_servers">您的 XFTP 服务器</string>
<string name="disable_onion_hosts_when_not_supported">如果 SOCKS 代理不支持它们,请将 <i>Use .onion hosts</i> 设置为否。</string>
<string name="network_socks_toggle_use_socks_proxy">使用 SOCKS 代理</string>
<string name="port_verb">端口</string>
<string name="smp_server_test_delete_file">删除文件</string>
<string name="smp_server_test_compare_file">对比文件</string>
<string name="host_verb">主机</string>
<string name="ensure_xftp_server_address_are_correct_format_and_unique">确保 XFTP 服务器地址格式正确、行分隔且不重复。</string>
<string name="smp_server_test_create_file">创建文件</string>
<string name="smp_server_test_download_file">下载文件</string>
<string name="error_loading_smp_servers">加载 SMP 服务器时出错</string>
<string name="error_loading_xftp_servers">加载 XFTP 服务器时出错</string>
<string name="error_saving_xftp_servers">保存 SMP 服务器时出错</string>
<string name="network_proxy_port">端口 %d</string>
<string name="network_socks_proxy_settings">SOCKS 代理设置</string>
</resources>
@@ -425,7 +425,6 @@
<string name="delete_address">刪除地址</string>
<string name="colored">顏色</string>
<string name="how_to_use_your_servers">如何使用你的伺服器</string>
<string name="core_build_timestamp">核心建立於:%s</string>
<string name="to_connect_via_link_title">使用連結連接</string>
<string name="desktop_scan_QR_code_from_app_via_scan_QR_code">💻 桌面版:於應用程式內掃描一個已存在的二維碼,透過二維碼掃描。</string>
<string name="icon_descr_settings">設定</string>
@@ -165,6 +165,20 @@
<string name="la_notice_title_simplex_lock">SimpleX Lock</string>
<string name="la_notice_to_protect_your_information_turn_on_simplex_lock_you_will_be_prompted_to_complete_authentication_before_this_feature_is_enabled">To protect your information, turn on SimpleX Lock.\nYou will be prompted to complete authentication before this feature is enabled.</string>
<string name="la_notice_turn_on">Turn on</string>
<string name="la_lock_mode">SimpleX Lock mode</string>
<string name="la_lock_mode_system">System authentication</string>
<string name="la_lock_mode_passcode">Passcode entry</string>
<string name="la_auth_failed">Authentication failed</string>
<string name="la_could_not_be_verified">You could not be verified; please try again.</string>
<string name="la_no_app_password">No app passcode</string>
<string name="la_enter_app_passcode">Enter Passcode</string>
<string name="la_current_app_passcode">Current Passcode</string>
<string name="la_change_app_passcode">Change passcode</string>
<string name="la_authenticate">Authenticate</string>
<string name="la_immediately">Immediately</string>
<string name="la_seconds">%d seconds</string>
<string name="la_minutes">%d minutes</string>
<string name="la_please_remember_to_store_password">Please remember or store it securely - there is no way to recover a lost password!</string>
<!-- LocalAuthentication.kt -->
<string name="auth_simplex_lock_turned_on">SimpleX Lock turned on</string>
@@ -179,6 +193,8 @@
<string name="auth_device_authentication_is_disabled_turning_off">Device authentication is disabled. Turning off SimpleX Lock.</string>
<string name="auth_stop_chat">Stop chat</string>
<string name="auth_open_chat_console">Open chat console</string>
<string name="lock_not_enabled">SimpleX Lock not enabled!</string>
<string name="you_can_turn_on_lock">You can turn on SimpleX Lock via Settings.</string>
<!-- Chat Alerts - ChatItemView.kt -->
<string name="message_delivery_error_title">Message delivery error</string>
@@ -540,7 +556,6 @@
<string name="app_version_name">App version: v%s</string>
<string name="app_version_code">App build: %s</string>
<string name="core_version">Core version: v%s</string>
<string name="core_build_timestamp">Core built at: %s</string>
<string name="core_simplexmq_version">simplexmq: v%s (%2s)</string>
<string name="show_dev_options">Show:</string>
<string name="hide_dev_options">Hide:</string>
@@ -735,6 +750,20 @@
<string name="auto_accept_images">Auto-accept images</string>
<string name="send_link_previews">Send link previews</string>
<string name="full_backup">App data backup</string>
<string name="enable_lock">Enable lock</string>
<string name="lock_mode">Lock mode</string>
<string name="lock_after">Lock after</string>
<string name="submit_passcode">Submit</string>
<string name="confirm_passcode">Confirm Passcode</string>
<string name="incorrect_passcode">Incorrect passcode</string>
<string name="new_passcode">New Passcode</string>
<string name="authentication_cancelled">Authentication cancelled</string>
<string name="la_mode_system">System</string>
<string name="la_mode_passcode">Passcode</string>
<string name="passcode_set">Passcode set!</string>
<string name="passcode_changed">Passcode changed!</string>
<string name="passcode_not_changed">Passcode not changed!</string>
<string name="change_lock_mode">Change lock mode</string>
<!-- Settings sections -->
<string name="settings_section_title_you">YOU</string>
@@ -186,7 +186,7 @@ struct SimplexLockView: View {
.onChange(of: laMode) { _ in
if performLAModeReset {
performLAModeReset = false
} else if performLA {
} else if prefPerformLA {
toggleLAMode()
} else {
updateLAMode()
@@ -18,7 +18,6 @@ struct VersionView: View {
Text("App build: \(appBuild ?? "?")")
if let info = versionInfo {
Text("Core version: v\(info.version)")
Text("Core built at: \(info.buildTimestamp)")
if let v = try? AttributedString(markdown: "simplexmq: v\(info.simplexmqVersion) ([\(info.simplexmqCommit.prefix(7))](https://github.com/simplex-chat/simplexmq/commit/\(info.simplexmqCommit)))") {
Text(v)
}
@@ -947,11 +947,6 @@
<target>Kopírovat</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Jádro sestavené na: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Verze jádra: v%@</target>
@@ -947,11 +947,6 @@
<target>Kopieren</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Core übersetzt am: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Core Version: v%@</target>
@@ -955,11 +955,6 @@
<target>Copy</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Core built at: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Core version: v%@</target>
@@ -144,6 +144,7 @@
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
<source>%lld minutes</source>
<target>%lld minutos</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld second(s)" xml:space="preserve">
@@ -153,6 +154,7 @@
</trans-unit>
<trans-unit id="%lld seconds" xml:space="preserve">
<source>%lld seconds</source>
<target>%lld segundos</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lldd" xml:space="preserve">
@@ -550,6 +552,7 @@
</trans-unit>
<trans-unit id="Authentication cancelled" xml:space="preserve">
<source>Authentication cancelled</source>
<target>Autenticación cancelada</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve">
@@ -659,6 +662,7 @@
</trans-unit>
<trans-unit id="Change Passcode" xml:space="preserve">
<source>Change Passcode</source>
<target>Cambiar contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Change database passphrase?" xml:space="preserve">
@@ -668,6 +672,7 @@
</trans-unit>
<trans-unit id="Change lock mode" xml:space="preserve">
<source>Change lock mode</source>
<target>Cambiar el modo de bloqueo</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change member role?" xml:space="preserve">
@@ -677,6 +682,7 @@
</trans-unit>
<trans-unit id="Change passcode" xml:space="preserve">
<source>Change passcode</source>
<target>Cambiar contraseña</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change receiving address" xml:space="preserve">
@@ -786,6 +792,7 @@
</trans-unit>
<trans-unit id="Compare file" xml:space="preserve">
<source>Compare file</source>
<target>Comparar archivo</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Compare security codes with your contacts." xml:space="preserve">
@@ -805,6 +812,7 @@
</trans-unit>
<trans-unit id="Confirm Passcode" xml:space="preserve">
<source>Confirm Passcode</source>
<target>Confirmar contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Confirm database upgrades" xml:space="preserve">
@@ -947,11 +955,6 @@
<target>Copiar</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Core compilado en: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Versión Core: v%@</target>
@@ -969,6 +972,7 @@
</trans-unit>
<trans-unit id="Create file" xml:space="preserve">
<source>Create file</source>
<target>Crear archivo</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1008,6 +1012,7 @@
</trans-unit>
<trans-unit id="Current Passcode" xml:space="preserve">
<source>Current Passcode</source>
<target>Contraseña actual</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Current passphrase…" xml:space="preserve">
@@ -1081,8 +1086,7 @@
</trans-unit>
<trans-unit id="Database passphrase &amp; export" xml:space="preserve">
<source>Database passphrase &amp; export</source>
<target>Base de datos
y Contraseña</target>
<target>Base de datos y contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database passphrase is different from saved in the keychain." xml:space="preserve">
@@ -1196,6 +1200,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Delete file" xml:space="preserve">
<source>Delete file</source>
<target>Eliminar archivo</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Delete files and media?" xml:space="preserve">
@@ -1400,6 +1405,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Download file" xml:space="preserve">
<source>Download file</source>
<target>Descargar archivo</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve">
@@ -1444,6 +1450,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Enable lock" xml:space="preserve">
<source>Enable lock</source>
<target>Activar bloqueo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enable notifications" xml:space="preserve">
@@ -1503,6 +1510,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Introducir contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter correct passphrase." xml:space="preserve">
@@ -1647,6 +1655,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Error loading %@ servers" xml:space="preserve">
<source>Error loading %@ servers</source>
<target>Error al cargar servidores %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error receiving file" xml:space="preserve">
@@ -1676,6 +1685,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Error saving passcode" xml:space="preserve">
<source>Error saving passcode</source>
<target>Error al guardar contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error saving passphrase to keychain" xml:space="preserve">
@@ -2055,6 +2065,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Immediately" xml:space="preserve">
<source>Immediately</source>
<target>Inmediatamente</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Immune to spam and abuse" xml:space="preserve">
@@ -2129,6 +2140,7 @@ y Contraseña</target>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Contraseña incorrecta</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Incorrect security code!" xml:space="preserve">
@@ -2255,6 +2267,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="KeyChain error" xml:space="preserve">
<source>KeyChain error</source>
<target>Error en Keychain</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keychain error" xml:space="preserve">
@@ -2319,10 +2332,12 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="Lock after" xml:space="preserve">
<source>Lock after</source>
<target>Bloquear después de</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Lock mode" xml:space="preserve">
<source>Lock mode</source>
<target>Modo de bloqueo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make a private connection" xml:space="preserve">
@@ -2497,6 +2512,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="New Passcode" xml:space="preserve">
<source>New Passcode</source>
<target>Nueva contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New contact request" xml:space="preserve">
@@ -2541,6 +2557,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="No app password" xml:space="preserve">
<source>No app password</source>
<target>Sin contraseña de la aplicación</target>
<note>Authentication unavailable</note>
</trans-unit>
<trans-unit id="No contacts selected" xml:space="preserve">
@@ -2594,6 +2611,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="Off" xml:space="preserve">
<source>Off</source>
<target>Apagado</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve">
@@ -2723,22 +2741,27 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="Passcode" xml:space="preserve">
<source>Passcode</source>
<target>Contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode changed!" xml:space="preserve">
<source>Passcode changed!</source>
<target>¡Contraseña cambiada!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode entry" xml:space="preserve">
<source>Passcode entry</source>
<target>Entrada de contraseña</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode not changed!" xml:space="preserve">
<source>Passcode not changed!</source>
<target>¡Contraseña no cambiada!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode set!" xml:space="preserve">
<source>Passcode set!</source>
<target>¡Contraseña guardada!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
@@ -2813,6 +2836,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="Please remember or store it securely - there is no way to recover a lost passcode!" xml:space="preserve">
<source>Please remember or store it securely - there is no way to recover a lost passcode!</source>
<target>Por favor, recuerda y guarda la contraseña en un lugar seguro. ¡No hay manera de recuperar una contraseña perdida!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please restart the app and migrate the database to enable push notifications." xml:space="preserve">
@@ -3282,6 +3306,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="Server requires authorization to upload, check password" xml:space="preserve">
<source>Server requires authorization to upload, check password</source>
<target>El servidor requiere autorización para subir, comprueba la contraseña</target>
<note>server test error</note>
</trans-unit>
<trans-unit id="Server test failed!" xml:space="preserve">
@@ -3386,10 +3411,12 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="SimpleX Lock mode" xml:space="preserve">
<source>SimpleX Lock mode</source>
<target>Modo Bloqueo SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock not enabled!" xml:space="preserve">
<source>SimpleX Lock not enabled!</source>
<target>¡Bloqueo SimpleX no activado!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock turned on" xml:space="preserve">
@@ -3479,6 +3506,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="Submit" xml:space="preserve">
<source>Submit</source>
<target>Enviar</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
@@ -3493,6 +3521,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="System authentication" xml:space="preserve">
<source>System authentication</source>
<target>Autenticación del sistema</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
@@ -3577,7 +3606,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="Thanks to the users contribute via Weblate!" xml:space="preserve">
<source>Thanks to the users contribute via Weblate!</source>
<target>Gracias a los usuarios: ¡contribuye a través de Weblate!</target>
<target>Agradecimientos a los usuarios. ¡Contribuye a través de Weblate!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The 1st platform without any user identifiers private by design." xml:space="preserve">
@@ -3612,7 +3641,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit>
<trans-unit id="The group is fully decentralized it is visible only to the members." xml:space="preserve">
<source>The group is fully decentralized it is visible only to the members.</source>
<target>El grupo está totalmente descentralizado: sólo es visible para los miembros.</target>
<target>El grupo está totalmente descentralizado y sólo es visible para los miembros.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The message will be deleted for all members." xml:space="preserve">
@@ -3842,6 +3871,7 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
</trans-unit>
<trans-unit id="Unlock app" xml:space="preserve">
<source>Unlock app</source>
<target>Desbloquear aplicación</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Unmute" xml:space="preserve">
@@ -3896,6 +3926,7 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
</trans-unit>
<trans-unit id="Upload file" xml:space="preserve">
<source>Upload file</source>
<target>Subir archivo</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Use .onion hosts" xml:space="preserve">
@@ -3965,10 +3996,12 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
</trans-unit>
<trans-unit id="Video will be received when your contact completes uploading it." xml:space="preserve">
<source>Video will be received when your contact completes uploading it.</source>
<target>El video se recibirá cuando tu contacto termine de subirlo.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video will be received when your contact is online, please wait or check later!" xml:space="preserve">
<source>Video will be received when your contact is online, please wait or check later!</source>
<target>El vídeo se recibirá cuando tu contacto esté en línea, por favor espera o compruébalo más tarde.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="View security code" xml:space="preserve">
@@ -4013,6 +4046,7 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
</trans-unit>
<trans-unit id="Waiting for video" xml:space="preserve">
<source>Waiting for video</source>
<target>Esperando el vídeo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Warning: you may lose some data!" xml:space="preserve">
@@ -4144,11 +4178,12 @@ SimpleX Lock debe estar activado.</target>
</trans-unit>
<trans-unit id="You can start chat via app Settings / Database or by restarting the app" xml:space="preserve">
<source>You can start chat via app Settings / Database or by restarting the app</source>
<target>Puede iniciar Chat a través de la Configuración / base de datos de la aplicación o reiniciando la aplicación</target>
<target>Puede iniciar Chat a través de la Configuración / Base de datos de la aplicación o reiniciando la aplicación</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
<source>You can turn on SimpleX Lock via Settings.</source>
<target>Puedes activar el bloqueo de SimpleX a través de Configuración.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can use markdown to format messages:" xml:space="preserve">
@@ -144,6 +144,7 @@
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
<source>%lld minutes</source>
<target>%lld minutes</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld second(s)" xml:space="preserve">
@@ -153,6 +154,7 @@
</trans-unit>
<trans-unit id="%lld seconds" xml:space="preserve">
<source>%lld seconds</source>
<target>%lld secondes</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lldd" xml:space="preserve">
@@ -550,6 +552,7 @@
</trans-unit>
<trans-unit id="Authentication cancelled" xml:space="preserve">
<source>Authentication cancelled</source>
<target>Authentification interrompue</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve">
@@ -659,6 +662,7 @@
</trans-unit>
<trans-unit id="Change Passcode" xml:space="preserve">
<source>Change Passcode</source>
<target>Modifier le code d'accès</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Change database passphrase?" xml:space="preserve">
@@ -668,6 +672,7 @@
</trans-unit>
<trans-unit id="Change lock mode" xml:space="preserve">
<source>Change lock mode</source>
<target>Modifier le mode de verrouillage</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change member role?" xml:space="preserve">
@@ -677,6 +682,7 @@
</trans-unit>
<trans-unit id="Change passcode" xml:space="preserve">
<source>Change passcode</source>
<target>Modifier le code d'accès</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change receiving address" xml:space="preserve">
@@ -786,6 +792,7 @@
</trans-unit>
<trans-unit id="Compare file" xml:space="preserve">
<source>Compare file</source>
<target>Comparer le fichier</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Compare security codes with your contacts." xml:space="preserve">
@@ -805,6 +812,7 @@
</trans-unit>
<trans-unit id="Confirm Passcode" xml:space="preserve">
<source>Confirm Passcode</source>
<target>Confirmer le code d'accès</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Confirm database upgrades" xml:space="preserve">
@@ -947,11 +955,6 @@
<target>Copier</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Cœur compilé le : %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Version du cœur : v%@</target>
@@ -969,6 +972,7 @@
</trans-unit>
<trans-unit id="Create file" xml:space="preserve">
<source>Create file</source>
<target>Créer un fichier</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1008,6 +1012,7 @@
</trans-unit>
<trans-unit id="Current Passcode" xml:space="preserve">
<source>Current Passcode</source>
<target>Code d'accès actuel</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Current passphrase…" xml:space="preserve">
@@ -1195,6 +1200,7 @@
</trans-unit>
<trans-unit id="Delete file" xml:space="preserve">
<source>Delete file</source>
<target>Supprimer le fichier</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Delete files and media?" xml:space="preserve">
@@ -1399,6 +1405,7 @@
</trans-unit>
<trans-unit id="Download file" xml:space="preserve">
<source>Download file</source>
<target>Télécharger le fichier</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve">
@@ -1443,6 +1450,7 @@
</trans-unit>
<trans-unit id="Enable lock" xml:space="preserve">
<source>Enable lock</source>
<target>Activer le verrouillage</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enable notifications" xml:space="preserve">
@@ -1502,6 +1510,7 @@
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Entrer le code d'accès</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter correct passphrase." xml:space="preserve">
@@ -1646,6 +1655,7 @@
</trans-unit>
<trans-unit id="Error loading %@ servers" xml:space="preserve">
<source>Error loading %@ servers</source>
<target>Erreur lors du chargement des serveurs %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error receiving file" xml:space="preserve">
@@ -1675,6 +1685,7 @@
</trans-unit>
<trans-unit id="Error saving passcode" xml:space="preserve">
<source>Error saving passcode</source>
<target>Erreur lors de la sauvegarde du code d'accès</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error saving passphrase to keychain" xml:space="preserve">
@@ -1784,6 +1795,7 @@
</trans-unit>
<trans-unit id="File transfer will be cancelled. If it's in progress it will be stoppped." xml:space="preserve">
<source>File transfer will be cancelled. If it's in progress it will be stoppped.</source>
<target>Le transfert de fichiers sera annulé. S'il est en cours, il sera interrompu.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File will be received when your contact completes uploading it." xml:space="preserve">
@@ -2053,6 +2065,7 @@
</trans-unit>
<trans-unit id="Immediately" xml:space="preserve">
<source>Immediately</source>
<target>Immédiatement</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Immune to spam and abuse" xml:space="preserve">
@@ -2127,6 +2140,7 @@
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Code d'accès erroné</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Incorrect security code!" xml:space="preserve">
@@ -2253,6 +2267,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="KeyChain error" xml:space="preserve">
<source>KeyChain error</source>
<target>Erreur du trousseau de clés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keychain error" xml:space="preserve">
@@ -2317,10 +2332,12 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="Lock after" xml:space="preserve">
<source>Lock after</source>
<target>Verrouillage après</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Lock mode" xml:space="preserve">
<source>Lock mode</source>
<target>Mode de verrouillage</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make a private connection" xml:space="preserve">
@@ -2495,6 +2512,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="New Passcode" xml:space="preserve">
<source>New Passcode</source>
<target>Nouveau code d'accès</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New contact request" xml:space="preserve">
@@ -2539,6 +2557,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="No app password" xml:space="preserve">
<source>No app password</source>
<target>Pas de mot de passe pour l'app</target>
<note>Authentication unavailable</note>
</trans-unit>
<trans-unit id="No contacts selected" xml:space="preserve">
@@ -2592,6 +2611,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="Off" xml:space="preserve">
<source>Off</source>
<target>Off</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve">
@@ -2721,22 +2741,27 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="Passcode" xml:space="preserve">
<source>Passcode</source>
<target>Code d'accès</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode changed!" xml:space="preserve">
<source>Passcode changed!</source>
<target>Code d'accès modifié !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode entry" xml:space="preserve">
<source>Passcode entry</source>
<target>Saisie du code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode not changed!" xml:space="preserve">
<source>Passcode not changed!</source>
<target>Le code d'accès n'a pas été modifié !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode set!" xml:space="preserve">
<source>Passcode set!</source>
<target>Code d'accès défini !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
@@ -2811,6 +2836,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="Please remember or store it securely - there is no way to recover a lost passcode!" xml:space="preserve">
<source>Please remember or store it securely - there is no way to recover a lost passcode!</source>
<target>N'oubliez pas de le mémoriser ou de le conserver en toute sécurité - il n'y a aucun moyen de récupérer un code d'accès perdu !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please restart the app and migrate the database to enable push notifications." xml:space="preserve">
@@ -3280,6 +3306,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="Server requires authorization to upload, check password" xml:space="preserve">
<source>Server requires authorization to upload, check password</source>
<target>Le serveur requiert une autorisation pour uploader, vérifiez le mot de passe</target>
<note>server test error</note>
</trans-unit>
<trans-unit id="Server test failed!" xml:space="preserve">
@@ -3384,10 +3411,12 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="SimpleX Lock mode" xml:space="preserve">
<source>SimpleX Lock mode</source>
<target>Mode de SimpleX Lock</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock not enabled!" xml:space="preserve">
<source>SimpleX Lock not enabled!</source>
<target>SimpleX Lock n'est pas activé !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock turned on" xml:space="preserve">
@@ -3477,6 +3506,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="Submit" xml:space="preserve">
<source>Submit</source>
<target>Soumettre</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
@@ -3491,6 +3521,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit>
<trans-unit id="System authentication" xml:space="preserve">
<source>System authentication</source>
<target>Authentification du système</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
@@ -3839,6 +3870,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Unlock app" xml:space="preserve">
<source>Unlock app</source>
<target>Déverrouiller l'app</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Unmute" xml:space="preserve">
@@ -3893,6 +3925,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Upload file" xml:space="preserve">
<source>Upload file</source>
<target>Transférer le fichier</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Use .onion hosts" xml:space="preserve">
@@ -3962,10 +3995,12 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Video will be received when your contact completes uploading it." xml:space="preserve">
<source>Video will be received when your contact completes uploading it.</source>
<target>La vidéo ne sera reçue que lorsque votre contact aura fini de la transférer.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video will be received when your contact is online, please wait or check later!" xml:space="preserve">
<source>Video will be received when your contact is online, please wait or check later!</source>
<target>La vidéo ne sera reçue que lorsque votre contact sera en ligne. Veuillez patienter ou vérifier plus tard !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="View security code" xml:space="preserve">
@@ -4010,6 +4045,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Waiting for video" xml:space="preserve">
<source>Waiting for video</source>
<target>En attente de la vidéo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Warning: you may lose some data!" xml:space="preserve">
@@ -4146,6 +4182,7 @@ SimpleX Lock doit être activé.</target>
</trans-unit>
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
<source>You can turn on SimpleX Lock via Settings.</source>
<target>Vous pouvez activer SimpleX Lock dans les Paramètres.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can use markdown to format messages:" xml:space="preserve">
@@ -144,6 +144,7 @@
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
<source>%lld minutes</source>
<target>%lld minuti</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld second(s)" xml:space="preserve">
@@ -153,6 +154,7 @@
</trans-unit>
<trans-unit id="%lld seconds" xml:space="preserve">
<source>%lld seconds</source>
<target>%lld secondi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lldd" xml:space="preserve">
@@ -550,6 +552,7 @@
</trans-unit>
<trans-unit id="Authentication cancelled" xml:space="preserve">
<source>Authentication cancelled</source>
<target>Autenticazione annullata</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve">
@@ -659,6 +662,7 @@
</trans-unit>
<trans-unit id="Change Passcode" xml:space="preserve">
<source>Change Passcode</source>
<target>Cambia codice di accesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Change database passphrase?" xml:space="preserve">
@@ -668,6 +672,7 @@
</trans-unit>
<trans-unit id="Change lock mode" xml:space="preserve">
<source>Change lock mode</source>
<target>Cambia modalità di blocco</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change member role?" xml:space="preserve">
@@ -677,6 +682,7 @@
</trans-unit>
<trans-unit id="Change passcode" xml:space="preserve">
<source>Change passcode</source>
<target>Cambia codice di accesso</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change receiving address" xml:space="preserve">
@@ -786,6 +792,7 @@
</trans-unit>
<trans-unit id="Compare file" xml:space="preserve">
<source>Compare file</source>
<target>Confronta file</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Compare security codes with your contacts." xml:space="preserve">
@@ -805,6 +812,7 @@
</trans-unit>
<trans-unit id="Confirm Passcode" xml:space="preserve">
<source>Confirm Passcode</source>
<target>Conferma il codice di accesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Confirm database upgrades" xml:space="preserve">
@@ -947,11 +955,6 @@
<target>Copia</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Core compilato il: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Versione core: v%@</target>
@@ -969,6 +972,7 @@
</trans-unit>
<trans-unit id="Create file" xml:space="preserve">
<source>Create file</source>
<target>Crea file</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1008,6 +1012,7 @@
</trans-unit>
<trans-unit id="Current Passcode" xml:space="preserve">
<source>Current Passcode</source>
<target>Codice di accesso attuale</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Current passphrase…" xml:space="preserve">
@@ -1195,6 +1200,7 @@
</trans-unit>
<trans-unit id="Delete file" xml:space="preserve">
<source>Delete file</source>
<target>Elimina file</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Delete files and media?" xml:space="preserve">
@@ -1399,6 +1405,7 @@
</trans-unit>
<trans-unit id="Download file" xml:space="preserve">
<source>Download file</source>
<target>Scarica file</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve">
@@ -1443,6 +1450,7 @@
</trans-unit>
<trans-unit id="Enable lock" xml:space="preserve">
<source>Enable lock</source>
<target>Attiva blocco</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enable notifications" xml:space="preserve">
@@ -1502,6 +1510,7 @@
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Inserisci il codice di accesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter correct passphrase." xml:space="preserve">
@@ -1646,6 +1655,7 @@
</trans-unit>
<trans-unit id="Error loading %@ servers" xml:space="preserve">
<source>Error loading %@ servers</source>
<target>Errore nel caricamento dei server %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error receiving file" xml:space="preserve">
@@ -1675,6 +1685,7 @@
</trans-unit>
<trans-unit id="Error saving passcode" xml:space="preserve">
<source>Error saving passcode</source>
<target>Errore nel salvataggio del codice di accesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error saving passphrase to keychain" xml:space="preserve">
@@ -2054,6 +2065,7 @@
</trans-unit>
<trans-unit id="Immediately" xml:space="preserve">
<source>Immediately</source>
<target>Immediatamente</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Immune to spam and abuse" xml:space="preserve">
@@ -2128,6 +2140,7 @@
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Codice di accesso errato</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Incorrect security code!" xml:space="preserve">
@@ -2254,6 +2267,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="KeyChain error" xml:space="preserve">
<source>KeyChain error</source>
<target>Errore del portachiavi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keychain error" xml:space="preserve">
@@ -2318,10 +2332,12 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="Lock after" xml:space="preserve">
<source>Lock after</source>
<target>Blocca dopo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Lock mode" xml:space="preserve">
<source>Lock mode</source>
<target>Modalità di blocco</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make a private connection" xml:space="preserve">
@@ -2496,6 +2512,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="New Passcode" xml:space="preserve">
<source>New Passcode</source>
<target>Nuovo codice di accesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New contact request" xml:space="preserve">
@@ -2540,6 +2557,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="No app password" xml:space="preserve">
<source>No app password</source>
<target>Nessuna password dell'app</target>
<note>Authentication unavailable</note>
</trans-unit>
<trans-unit id="No contacts selected" xml:space="preserve">
@@ -2593,6 +2611,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="Off" xml:space="preserve">
<source>Off</source>
<target>Off</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve">
@@ -2722,22 +2741,27 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="Passcode" xml:space="preserve">
<source>Passcode</source>
<target>Codice di accesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode changed!" xml:space="preserve">
<source>Passcode changed!</source>
<target>Codice di accesso cambiato!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode entry" xml:space="preserve">
<source>Passcode entry</source>
<target>Inserimento del codice di accesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode not changed!" xml:space="preserve">
<source>Passcode not changed!</source>
<target>Codice di accesso non cambiato!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode set!" xml:space="preserve">
<source>Passcode set!</source>
<target>Codice di accesso impostato!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
@@ -2812,6 +2836,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="Please remember or store it securely - there is no way to recover a lost passcode!" xml:space="preserve">
<source>Please remember or store it securely - there is no way to recover a lost passcode!</source>
<target>Ricordalo o conservalo in modo sicuro: non c'è modo di recuperare un codice di accesso perso!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please restart the app and migrate the database to enable push notifications." xml:space="preserve">
@@ -3281,6 +3306,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="Server requires authorization to upload, check password" xml:space="preserve">
<source>Server requires authorization to upload, check password</source>
<target>Il server richiede l'autorizzazione per il caricamento, controllare la password</target>
<note>server test error</note>
</trans-unit>
<trans-unit id="Server test failed!" xml:space="preserve">
@@ -3385,10 +3411,12 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="SimpleX Lock mode" xml:space="preserve">
<source>SimpleX Lock mode</source>
<target>Modalità di SimpleX Lock</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock not enabled!" xml:space="preserve">
<source>SimpleX Lock not enabled!</source>
<target>SimpleX Lock non attivato!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock turned on" xml:space="preserve">
@@ -3478,6 +3506,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="Submit" xml:space="preserve">
<source>Submit</source>
<target>Invia</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
@@ -3492,6 +3521,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit>
<trans-unit id="System authentication" xml:space="preserve">
<source>System authentication</source>
<target>Autenticazione di sistema</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
@@ -3840,6 +3870,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
</trans-unit>
<trans-unit id="Unlock app" xml:space="preserve">
<source>Unlock app</source>
<target>Sblocca l'app</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Unmute" xml:space="preserve">
@@ -3894,6 +3925,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
</trans-unit>
<trans-unit id="Upload file" xml:space="preserve">
<source>Upload file</source>
<target>Invia file</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Use .onion hosts" xml:space="preserve">
@@ -3963,10 +3995,12 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
</trans-unit>
<trans-unit id="Video will be received when your contact completes uploading it." xml:space="preserve">
<source>Video will be received when your contact completes uploading it.</source>
<target>Il video verrà ricevuto quando il tuo contatto completerà l'invio.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video will be received when your contact is online, please wait or check later!" xml:space="preserve">
<source>Video will be received when your contact is online, please wait or check later!</source>
<target>Il video verrà ricevuto quando il tuo contatto sarà in linea, attendi o controlla più tardi!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="View security code" xml:space="preserve">
@@ -4011,6 +4045,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
</trans-unit>
<trans-unit id="Waiting for video" xml:space="preserve">
<source>Waiting for video</source>
<target>In attesa del video</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Warning: you may lose some data!" xml:space="preserve">
@@ -4147,6 +4182,7 @@ SimpleX Lock deve essere attivato.</target>
</trans-unit>
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
<source>You can turn on SimpleX Lock via Settings.</source>
<target>Puoi attivare SimpleX Lock tramite le impostazioni.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can use markdown to format messages:" xml:space="preserve">
@@ -144,6 +144,7 @@
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
<source>%lld minutes</source>
<target>%lld minuten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld second(s)" xml:space="preserve">
@@ -153,6 +154,7 @@
</trans-unit>
<trans-unit id="%lld seconds" xml:space="preserve">
<source>%lld seconds</source>
<target>%lld seconden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lldd" xml:space="preserve">
@@ -550,6 +552,7 @@
</trans-unit>
<trans-unit id="Authentication cancelled" xml:space="preserve">
<source>Authentication cancelled</source>
<target>Verificatie geannuleerd</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve">
@@ -654,11 +657,12 @@
</trans-unit>
<trans-unit id="Change" xml:space="preserve">
<source>Change</source>
<target>Wijziging</target>
<target>Veranderen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Change Passcode" xml:space="preserve">
<source>Change Passcode</source>
<target>Toegangscode wijzigen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Change database passphrase?" xml:space="preserve">
@@ -668,6 +672,7 @@
</trans-unit>
<trans-unit id="Change lock mode" xml:space="preserve">
<source>Change lock mode</source>
<target>Wijzig de vergrendelings modus</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change member role?" xml:space="preserve">
@@ -677,6 +682,7 @@
</trans-unit>
<trans-unit id="Change passcode" xml:space="preserve">
<source>Change passcode</source>
<target>Toegangscode wijzigen</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change receiving address" xml:space="preserve">
@@ -786,6 +792,7 @@
</trans-unit>
<trans-unit id="Compare file" xml:space="preserve">
<source>Compare file</source>
<target>Bestand vergelijken</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Compare security codes with your contacts." xml:space="preserve">
@@ -805,6 +812,7 @@
</trans-unit>
<trans-unit id="Confirm Passcode" xml:space="preserve">
<source>Confirm Passcode</source>
<target>Bevestig toegangscode</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Confirm database upgrades" xml:space="preserve">
@@ -947,11 +955,6 @@
<target>Kopiëren</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Core built at: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Core versie: v% @</target>
@@ -969,6 +972,7 @@
</trans-unit>
<trans-unit id="Create file" xml:space="preserve">
<source>Create file</source>
<target>Bestand maken</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1008,6 +1012,7 @@
</trans-unit>
<trans-unit id="Current Passcode" xml:space="preserve">
<source>Current Passcode</source>
<target>Huidige toegangscode</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Current passphrase…" xml:space="preserve">
@@ -1195,6 +1200,7 @@
</trans-unit>
<trans-unit id="Delete file" xml:space="preserve">
<source>Delete file</source>
<target>Verwijder bestand</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Delete files and media?" xml:space="preserve">
@@ -1399,6 +1405,7 @@
</trans-unit>
<trans-unit id="Download file" xml:space="preserve">
<source>Download file</source>
<target>Download bestand</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve">
@@ -1443,6 +1450,7 @@
</trans-unit>
<trans-unit id="Enable lock" xml:space="preserve">
<source>Enable lock</source>
<target>Vergrendeling inschakelen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enable notifications" xml:space="preserve">
@@ -1502,6 +1510,7 @@
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Voer toegangscode in</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter correct passphrase." xml:space="preserve">
@@ -1646,6 +1655,7 @@
</trans-unit>
<trans-unit id="Error loading %@ servers" xml:space="preserve">
<source>Error loading %@ servers</source>
<target>Fout bij het laden van %@ servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error receiving file" xml:space="preserve">
@@ -1675,6 +1685,7 @@
</trans-unit>
<trans-unit id="Error saving passcode" xml:space="preserve">
<source>Error saving passcode</source>
<target>Fout bij opslaan van toegangscode</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error saving passphrase to keychain" xml:space="preserve">
@@ -2054,6 +2065,7 @@
</trans-unit>
<trans-unit id="Immediately" xml:space="preserve">
<source>Immediately</source>
<target>Onmiddellijk</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Immune to spam and abuse" xml:space="preserve">
@@ -2128,6 +2140,7 @@
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Onjuiste toegangscode</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Incorrect security code!" xml:space="preserve">
@@ -2254,6 +2267,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="KeyChain error" xml:space="preserve">
<source>KeyChain error</source>
<target>Keychain fout</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keychain error" xml:space="preserve">
@@ -2318,10 +2332,12 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="Lock after" xml:space="preserve">
<source>Lock after</source>
<target>Vergrendelen na</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Lock mode" xml:space="preserve">
<source>Lock mode</source>
<target>Vergrendeling modus</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make a private connection" xml:space="preserve">
@@ -2496,6 +2512,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="New Passcode" xml:space="preserve">
<source>New Passcode</source>
<target>Nieuwe toegangscode</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New contact request" xml:space="preserve">
@@ -2540,6 +2557,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="No app password" xml:space="preserve">
<source>No app password</source>
<target>Geen app wachtwoord</target>
<note>Authentication unavailable</note>
</trans-unit>
<trans-unit id="No contacts selected" xml:space="preserve">
@@ -2593,6 +2611,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="Off" xml:space="preserve">
<source>Off</source>
<target>Uit</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve">
@@ -2722,22 +2741,27 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="Passcode" xml:space="preserve">
<source>Passcode</source>
<target>Toegangscode</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode changed!" xml:space="preserve">
<source>Passcode changed!</source>
<target>Toegangscode gewijzigd!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode entry" xml:space="preserve">
<source>Passcode entry</source>
<target>Toegangscode invoer</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode not changed!" xml:space="preserve">
<source>Passcode not changed!</source>
<target>Toegangscode niet gewijzigd!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode set!" xml:space="preserve">
<source>Passcode set!</source>
<target>Toegangscode ingesteld!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
@@ -2812,6 +2836,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="Please remember or store it securely - there is no way to recover a lost passcode!" xml:space="preserve">
<source>Please remember or store it securely - there is no way to recover a lost passcode!</source>
<target>Onthoud het of bewaar het veilig - er is geen manier om een verloren toegangscode te herstellen!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please restart the app and migrate the database to enable push notifications." xml:space="preserve">
@@ -3281,6 +3306,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="Server requires authorization to upload, check password" xml:space="preserve">
<source>Server requires authorization to upload, check password</source>
<target>Server vereist autorisatie om te uploaden, wachtwoord controleren</target>
<note>server test error</note>
</trans-unit>
<trans-unit id="Server test failed!" xml:space="preserve">
@@ -3385,10 +3411,12 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="SimpleX Lock mode" xml:space="preserve">
<source>SimpleX Lock mode</source>
<target>SimpleX Vergrendel modus</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock not enabled!" xml:space="preserve">
<source>SimpleX Lock not enabled!</source>
<target>SimpleX vergrendeling niet ingeschakeld!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock turned on" xml:space="preserve">
@@ -3478,6 +3506,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="Submit" xml:space="preserve">
<source>Submit</source>
<target>Indienen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
@@ -3492,6 +3521,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit>
<trans-unit id="System authentication" xml:space="preserve">
<source>System authentication</source>
<target>Systeem authenticatie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
@@ -3840,6 +3870,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
</trans-unit>
<trans-unit id="Unlock app" xml:space="preserve">
<source>Unlock app</source>
<target>Ontgrendel app</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Unmute" xml:space="preserve">
@@ -3894,6 +3925,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
</trans-unit>
<trans-unit id="Upload file" xml:space="preserve">
<source>Upload file</source>
<target>Upload bestand</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Use .onion hosts" xml:space="preserve">
@@ -3963,10 +3995,12 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
</trans-unit>
<trans-unit id="Video will be received when your contact completes uploading it." xml:space="preserve">
<source>Video will be received when your contact completes uploading it.</source>
<target>De video wordt ontvangen wanneer uw contactpersoon het uploaden heeft voltooid.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video will be received when your contact is online, please wait or check later!" xml:space="preserve">
<source>Video will be received when your contact is online, please wait or check later!</source>
<target>De video wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of kijk later!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="View security code" xml:space="preserve">
@@ -4011,6 +4045,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
</trans-unit>
<trans-unit id="Waiting for video" xml:space="preserve">
<source>Waiting for video</source>
<target>Wachten op video</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Warning: you may lose some data!" xml:space="preserve">
@@ -4147,6 +4182,7 @@ SimpleX Lock moet ingeschakeld zijn.</target>
</trans-unit>
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
<source>You can turn on SimpleX Lock via Settings.</source>
<target>Je kunt SimpleX Vergrendeling aanzetten via Instellingen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can use markdown to format messages:" xml:space="preserve">
@@ -0,0 +1,15 @@
{
"colors" : [
{
"idiom" : "universal",
"locale" : "pl"
}
],
"properties" : {
"localizable" : true
},
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,23 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.000",
"alpha" : "1.000",
"blue" : "1.000",
"green" : "0.533"
}
},
"idiom" : "universal"
}
],
"properties" : {
"localizable" : true
},
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
/* Bundle display name */
"CFBundleDisplayName" = "SimpleX NSE";
/* Bundle name */
"CFBundleName" = "SimpleX NSE";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "Copyright © 2022 SimpleX Chat. All rights reserved.";
@@ -0,0 +1,30 @@
/* No comment provided by engineer. */
"_italic_" = "\\_italic_";
/* No comment provided by engineer. */
"**Add new contact**: to create your one-time QR Code for your contact." = "**Add new contact**: to create your one-time QR Code or link for your contact.";
/* No comment provided by engineer. */
"*bold*" = "\\*bold*";
/* No comment provided by engineer. */
"`a + b`" = "\\`a + b`";
/* No comment provided by engineer. */
"~strike~" = "\\~strike~";
/* call status */
"connecting call" = "connecting call…";
/* No comment provided by engineer. */
"Connecting server…" = "Connecting to server…";
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Connecting to server… (error: %@)";
/* rcv group event chat item */
"member connected" = "connected";
/* No comment provided by engineer. */
"No group!" = "Group not found!";
@@ -0,0 +1,10 @@
/* Bundle name */
"CFBundleName" = "SimpleX";
/* Privacy - Camera Usage Description */
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "SimpleX needs access to Photo Library for saving captured and received media";
@@ -0,0 +1,12 @@
{
"developmentRegion" : "en",
"project" : "SimpleX.xcodeproj",
"targetLocale" : "pl",
"toolInfo" : {
"toolBuildNumber" : "14C18",
"toolID" : "com.apple.dt.xcode",
"toolName" : "Xcode",
"toolVersion" : "14.2"
},
"version" : "1.0"
}
@@ -947,11 +947,6 @@
<target>Скопировать</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>Ядро скомпилировано: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>Версия ядра: v%@</target>
@@ -144,6 +144,7 @@
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
<source>%lld minutes</source>
<target>%lld 分钟</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld second(s)" xml:space="preserve">
@@ -153,6 +154,7 @@
</trans-unit>
<trans-unit id="%lld seconds" xml:space="preserve">
<source>%lld seconds</source>
<target>%lld 秒</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lldd" xml:space="preserve">
@@ -550,11 +552,12 @@
</trans-unit>
<trans-unit id="Authentication cancelled" xml:space="preserve">
<source>Authentication cancelled</source>
<target>身份验证已取消</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve">
<source>Authentication failed</source>
<target>认证失败</target>
<target>身份认证失败</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Authentication is required before the call is connected, but you may miss calls." xml:space="preserve">
@@ -564,7 +567,7 @@
</trans-unit>
<trans-unit id="Authentication unavailable" xml:space="preserve">
<source>Authentication unavailable</source>
<target>认证不可用</target>
<target>身份认证不可用</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Auto-accept contact requests" xml:space="preserve">
@@ -659,6 +662,7 @@
</trans-unit>
<trans-unit id="Change Passcode" xml:space="preserve">
<source>Change Passcode</source>
<target>更改密码</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Change database passphrase?" xml:space="preserve">
@@ -668,6 +672,7 @@
</trans-unit>
<trans-unit id="Change lock mode" xml:space="preserve">
<source>Change lock mode</source>
<target>更改锁定模式</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change member role?" xml:space="preserve">
@@ -677,6 +682,7 @@
</trans-unit>
<trans-unit id="Change passcode" xml:space="preserve">
<source>Change passcode</source>
<target>更改密码</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Change receiving address" xml:space="preserve">
@@ -786,6 +792,7 @@
</trans-unit>
<trans-unit id="Compare file" xml:space="preserve">
<source>Compare file</source>
<target>对比文件</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Compare security codes with your contacts." xml:space="preserve">
@@ -805,6 +812,7 @@
</trans-unit>
<trans-unit id="Confirm Passcode" xml:space="preserve">
<source>Confirm Passcode</source>
<target>确认密码</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Confirm database upgrades" xml:space="preserve">
@@ -947,11 +955,6 @@
<target>复制</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Core built at: %@" xml:space="preserve">
<source>Core built at: %@</source>
<target>核心构建于:%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Core version: v%@" xml:space="preserve">
<source>Core version: v%@</source>
<target>核心版本: v%@</target>
@@ -969,6 +972,7 @@
</trans-unit>
<trans-unit id="Create file" xml:space="preserve">
<source>Create file</source>
<target>创建文件</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1008,6 +1012,7 @@
</trans-unit>
<trans-unit id="Current Passcode" xml:space="preserve">
<source>Current Passcode</source>
<target>当前密码</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Current passphrase…" xml:space="preserve">
@@ -1195,6 +1200,7 @@
</trans-unit>
<trans-unit id="Delete file" xml:space="preserve">
<source>Delete file</source>
<target>删除文件</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Delete files and media?" xml:space="preserve">
@@ -1399,6 +1405,7 @@
</trans-unit>
<trans-unit id="Download file" xml:space="preserve">
<source>Download file</source>
<target>下载文件</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve">
@@ -1443,6 +1450,7 @@
</trans-unit>
<trans-unit id="Enable lock" xml:space="preserve">
<source>Enable lock</source>
<target>启用锁定</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enable notifications" xml:space="preserve">
@@ -1502,6 +1510,7 @@
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>输入密码</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter correct passphrase." xml:space="preserve">
@@ -1646,6 +1655,7 @@
</trans-unit>
<trans-unit id="Error loading %@ servers" xml:space="preserve">
<source>Error loading %@ servers</source>
<target>加载 %@ 服务器错误</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error receiving file" xml:space="preserve">
@@ -1675,6 +1685,7 @@
</trans-unit>
<trans-unit id="Error saving passcode" xml:space="preserve">
<source>Error saving passcode</source>
<target>保存密码错误</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error saving passphrase to keychain" xml:space="preserve">
@@ -2054,6 +2065,7 @@
</trans-unit>
<trans-unit id="Immediately" xml:space="preserve">
<source>Immediately</source>
<target>立即</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Immune to spam and abuse" xml:space="preserve">
@@ -2128,6 +2140,7 @@
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>密码错误</target>
<note>PIN entry</note>
</trans-unit>
<trans-unit id="Incorrect security code!" xml:space="preserve">
@@ -2254,6 +2267,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="KeyChain error" xml:space="preserve">
<source>KeyChain error</source>
<target>钥匙串错误</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keychain error" xml:space="preserve">
@@ -2318,10 +2332,12 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="Lock after" xml:space="preserve">
<source>Lock after</source>
<target>在此后锁定</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Lock mode" xml:space="preserve">
<source>Lock mode</source>
<target>锁定模式</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make a private connection" xml:space="preserve">
@@ -2496,6 +2512,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="New Passcode" xml:space="preserve">
<source>New Passcode</source>
<target>新密码</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New contact request" xml:space="preserve">
@@ -2540,6 +2557,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="No app password" xml:space="preserve">
<source>No app password</source>
<target>没有应用程序密码</target>
<note>Authentication unavailable</note>
</trans-unit>
<trans-unit id="No contacts selected" xml:space="preserve">
@@ -2593,6 +2611,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="Off" xml:space="preserve">
<source>Off</source>
<target>关闭</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve">
@@ -2722,22 +2741,27 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="Passcode" xml:space="preserve">
<source>Passcode</source>
<target>密码</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode changed!" xml:space="preserve">
<source>Passcode changed!</source>
<target>密码已更改!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode entry" xml:space="preserve">
<source>Passcode entry</source>
<target>密码输入</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode not changed!" xml:space="preserve">
<source>Passcode not changed!</source>
<target>密码未更改!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode set!" xml:space="preserve">
<source>Passcode set!</source>
<target>密码已设置!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
@@ -2812,6 +2836,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="Please remember or store it securely - there is no way to recover a lost passcode!" xml:space="preserve">
<source>Please remember or store it securely - there is no way to recover a lost passcode!</source>
<target>请牢记或妥善保管——丢失的密码将无法恢复!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please restart the app and migrate the database to enable push notifications." xml:space="preserve">
@@ -3281,6 +3306,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="Server requires authorization to upload, check password" xml:space="preserve">
<source>Server requires authorization to upload, check password</source>
<target>服务器需要授权来上传,检查密码</target>
<note>server test error</note>
</trans-unit>
<trans-unit id="Server test failed!" xml:space="preserve">
@@ -3385,10 +3411,12 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="SimpleX Lock mode" xml:space="preserve">
<source>SimpleX Lock mode</source>
<target>SimpleX 锁定模式</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock not enabled!" xml:space="preserve">
<source>SimpleX Lock not enabled!</source>
<target>未启用 SimpleX 锁定!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SimpleX Lock turned on" xml:space="preserve">
@@ -3478,6 +3506,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="Submit" xml:space="preserve">
<source>Submit</source>
<target>提交</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
@@ -3492,6 +3521,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit>
<trans-unit id="System authentication" xml:space="preserve">
<source>System authentication</source>
<target>系统认证</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
@@ -3840,6 +3870,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="Unlock app" xml:space="preserve">
<source>Unlock app</source>
<target>解锁应用程序</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Unmute" xml:space="preserve">
@@ -3894,6 +3925,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="Upload file" xml:space="preserve">
<source>Upload file</source>
<target>上传文件</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Use .onion hosts" xml:space="preserve">
@@ -3963,10 +3995,12 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="Video will be received when your contact completes uploading it." xml:space="preserve">
<source>Video will be received when your contact completes uploading it.</source>
<target>视频将在您的联系人完成上传后收到。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video will be received when your contact is online, please wait or check later!" xml:space="preserve">
<source>Video will be received when your contact is online, please wait or check later!</source>
<target>视频将在您的联系人在线时收到,请稍等或稍后查看!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="View security code" xml:space="preserve">
@@ -4011,6 +4045,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="Waiting for video" xml:space="preserve">
<source>Waiting for video</source>
<target>等待视频中</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Warning: you may lose some data!" xml:space="preserve">
@@ -4147,6 +4182,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit>
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
<source>You can turn on SimpleX Lock via Settings.</source>
<target>您可以通过设置开启 SimpleX 锁定。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can use markdown to format messages:" xml:space="preserve">
@@ -0,0 +1,9 @@
/* Bundle display name */
"CFBundleDisplayName" = "SimpleX NSE";
/* Bundle name */
"CFBundleName" = "SimpleX NSE";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "Copyright © 2022 SimpleX Chat. Wszelkie prawa zastrzeżone.";
@@ -0,0 +1 @@
@@ -302,6 +302,8 @@
5C65F341297D3F3600B67AF3 /* VersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionView.swift; sourceTree = "<group>"; };
5C6AD81227A834E300348BD7 /* NewChatButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatButton.swift; sourceTree = "<group>"; };
5C6BA666289BD954009B8ECC /* DismissSheets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissSheets.swift; sourceTree = "<group>"; };
5C6D183229E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = "pl.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
5C6D183329E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIFeaturePreferenceView.swift; sourceTree = "<group>"; };
5C7505A127B65FDB00BE3227 /* CIMetaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMetaView.swift; sourceTree = "<group>"; };
5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavLinkPlain.swift; sourceTree = "<group>"; };
@@ -343,6 +345,8 @@
5CA85D0B297218AA0095AF72 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
5CA85D0C297219EF0095AF72 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = "it.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
5CA85D0D297219EF0095AF72 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
5CAB912529E93F9400F34A95 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
5CAB912629E93F9400F34A95 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
5CADE79929211BB900072E13 /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; };
5CADE79B292131E900072E13 /* ContactPreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPreferencesView.swift; sourceTree = "<group>"; };
5CB0BA872826CB3A00B3292C /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@@ -981,6 +985,7 @@
cs,
"zh-Hans",
es,
pl,
);
mainGroup = 5CA059BD279559F40002BEB4;
packageReferences = (
@@ -1252,6 +1257,7 @@
5C8B41CC29AF44CF00888272 /* cs */,
5C65DAE729C771B9003CEE45 /* zh-Hans */,
5C65DAED29CB8908003CEE45 /* es */,
5C6D183329E93FBA00D430B3 /* pl */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
@@ -1268,6 +1274,7 @@
5C8B41CA29AF41BC00888272 /* cs */,
5C65DAE529C77136003CEE45 /* zh-Hans */,
5C65DAEB29CB8867003CEE45 /* es */,
5CAB912629E93F9400F34A95 /* pl */,
);
name = Localizable.strings;
sourceTree = "<group>";
@@ -1284,6 +1291,7 @@
5C8B41C929AF41BC00888272 /* cs */,
5C65DAE429C77136003CEE45 /* zh-Hans */,
5C65DAEA29CB8867003CEE45 /* es */,
5CAB912529E93F9400F34A95 /* pl */,
);
name = Localizable.strings;
sourceTree = "<group>";
@@ -1299,6 +1307,7 @@
5C8B41CB29AF44CF00888272 /* cs */,
5C65DAE629C771B9003CEE45 /* zh-Hans */,
5C65DAEC29CB8908003CEE45 /* es */,
5C6D183229E93FBA00D430B3 /* pl */,
);
name = "SimpleX--iOS--InfoPlist.strings";
sourceTree = "<group>";
-1
View File
@@ -1153,7 +1153,6 @@ public enum NotificationPreviewMode: String, SelectableItem {
public struct CoreVersionInfo: Decodable {
public var version: String
public var buildTimestamp: String
public var simplexmqVersion: String
public var simplexmqCommit: String
}
+1 -4
View File
@@ -656,9 +656,6 @@
/* chat item action */
"Copy" = "Kopírovat";
/* No comment provided by engineer. */
"Core built at: %@" = "Jádro sestavené na: %@";
/* No comment provided by engineer. */
"Core version: v%@" = "Verze jádra: v%@";
@@ -2502,7 +2499,7 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Pokud váš kontakt neodstranil připojení nebo tento odkaz již nebyl použit, může se jednat o chybu nahlaste ji.\nChcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu na připojení a zkontrolujte, zda máte stabilní připojení k síti.";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "Odemknout";
/* No comment provided by engineer. */
+1 -4
View File
@@ -656,9 +656,6 @@
/* chat item action */
"Copy" = "Kopieren";
/* No comment provided by engineer. */
"Core built at: %@" = "Core übersetzt am: %@";
/* No comment provided by engineer. */
"Core version: v%@" = "Core Version: v%@";
@@ -2502,7 +2499,7 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Entweder hat Ihr Kontakt die Verbindung gelöscht, oder dieser Link wurde bereits verwendet, es könnte sich um einen Fehler handeln - Bitte melden Sie es uns.\nBitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um sich neu verbinden zu können und stellen Sie sicher, dass Sie eine stabile Netzwerk-Verbindung haben.";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "Entsperren";
/* No comment provided by engineer. */
+128 -8
View File
@@ -142,9 +142,15 @@
/* No comment provided by engineer. */
"%lld members" = "%lld miembros";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minutos";
/* No comment provided by engineer. */
"%lld second(s)" = "%lld segundo(s)";
/* No comment provided by engineer. */
"%lld seconds" = "%lld segundos";
/* No comment provided by engineer. */
"%lldd" = "%lldd";
@@ -350,6 +356,9 @@
/* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "llamada de audio (sin cifrado e2e)";
/* PIN entry */
"Authentication cancelled" = "Autenticación cancelada";
/* No comment provided by engineer. */
"Authentication failed" = "Autenticación fallida";
@@ -437,9 +446,18 @@
/* No comment provided by engineer. */
"Change database passphrase?" = "¿Cambiar contraseña de la base de datos?";
/* authentication reason */
"Change lock mode" = "Cambiar el modo de bloqueo";
/* No comment provided by engineer. */
"Change member role?" = "¿Cambiar el rol del miembro?";
/* authentication reason */
"Change passcode" = "Cambiar contraseña";
/* No comment provided by engineer. */
"Change Passcode" = "Cambiar contraseña";
/* No comment provided by engineer. */
"Change receiving address" = "Cambiar la dirección de recepción";
@@ -521,6 +539,9 @@
/* No comment provided by engineer. */
"Colors" = "Colores";
/* server test step */
"Compare file" = "Comparar archivo";
/* No comment provided by engineer. */
"Compare security codes with your contacts." = "Compare los códigos de seguridad con sus contactos.";
@@ -539,6 +560,9 @@
/* No comment provided by engineer. */
"Confirm new passphrase…" = "Confirme nueva contraseña…";
/* No comment provided by engineer. */
"Confirm Passcode" = "Confirmar contraseña";
/* No comment provided by engineer. */
"Confirm password" = "Confirmar contraseña";
@@ -656,9 +680,6 @@
/* chat item action */
"Copy" = "Copiar";
/* No comment provided by engineer. */
"Core built at: %@" = "Core compilado en: %@";
/* No comment provided by engineer. */
"Core version: v%@" = "Versión Core: v%@";
@@ -668,6 +689,9 @@
/* No comment provided by engineer. */
"Create address" = "Crear dirección";
/* server test step */
"Create file" = "Crear archivo";
/* No comment provided by engineer. */
"Create group link" = "Crear enlace de grupo";
@@ -692,6 +716,9 @@
/* No comment provided by engineer. */
"creator" = "creador";
/* No comment provided by engineer. */
"Current Passcode" = "Contraseña actual";
/* No comment provided by engineer. */
"Current passphrase…" = "Contraseña actual…";
@@ -732,7 +759,7 @@
"Database passphrase" = "Contraseña de la base de datos";
/* No comment provided by engineer. */
"Database passphrase & export" = "Base de datos\ny Contraseña";
"Database passphrase & export" = "Base de datos y contraseña";
/* No comment provided by engineer. */
"Database passphrase is different from saved in the keychain." = "La contraseña es distinta a la almacenada en Keychain.";
@@ -803,6 +830,9 @@
/* No comment provided by engineer. */
"Delete database" = "Eliminar base de datos";
/* server test step */
"Delete file" = "Eliminar archivo";
/* No comment provided by engineer. */
"Delete files and media?" = "Eliminar archivos y multimedia?";
@@ -935,6 +965,9 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Degradar y abrir Chat";
/* server test step */
"Download file" = "Descargar archivo";
/* No comment provided by engineer. */
"Duplicate display name!" = "¡Nombre mostrado duplicado!";
@@ -959,6 +992,9 @@
/* No comment provided by engineer. */
"Enable instant notifications?" = "¿Activar notificación instantánea?";
/* No comment provided by engineer. */
"Enable lock" = "Activar bloqueo";
/* No comment provided by engineer. */
"Enable notifications" = "Activar notificaciones";
@@ -1016,6 +1052,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Introduce la contraseña correcta.";
/* No comment provided by engineer. */
"Enter Passcode" = "Introducir contraseña";
/* No comment provided by engineer. */
"Enter passphrase…" = "Introduce la contraseña…";
@@ -1100,6 +1139,9 @@
/* No comment provided by engineer. */
"Error joining group" = "Error uniéndose al grupo";
/* No comment provided by engineer. */
"Error loading %@ servers" = "Error al cargar servidores %@";
/* No comment provided by engineer. */
"Error receiving file" = "Error recibiendo archivo";
@@ -1115,6 +1157,9 @@
/* No comment provided by engineer. */
"Error saving ICE servers" = "Error guardando servidores ICE";
/* No comment provided by engineer. */
"Error saving passcode" = "Error al guardar contraseña";
/* No comment provided by engineer. */
"Error saving passphrase to keychain" = "Error guardando contraseña en Keychain";
@@ -1346,6 +1391,9 @@
/* No comment provided by engineer. */
"Image will be received when your contact is online, please wait or check later!" = "La imagen se recibirá cuando tu contacto esté en línea, por favor espera o compruébalo más tarde.";
/* No comment provided by engineer. */
"Immediately" = "Inmediatamente";
/* No comment provided by engineer. */
"Immune to spam and abuse" = "Inmune a spam y abuso";
@@ -1397,6 +1445,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Versión de base de datos incompatible";
/* PIN entry */
"Incorrect passcode" = "Contraseña incorrecta";
/* No comment provided by engineer. */
"Incorrect security code!" = "¡Código de seguridad incorrecto!";
@@ -1505,6 +1556,9 @@
/* No comment provided by engineer. */
"Keychain error" = "Error en Keychain";
/* No comment provided by engineer. */
"KeyChain error" = "Error en Keychain";
/* No comment provided by engineer. */
"Large file!" = "¡Archivo grande!";
@@ -1541,6 +1595,12 @@
/* No comment provided by engineer. */
"Local profile data only" = "Sólo datos del perfil local";
/* No comment provided by engineer. */
"Lock after" = "Bloquear después de";
/* No comment provided by engineer. */
"Lock mode" = "Modo de bloqueo";
/* No comment provided by engineer. */
"Make a private connection" = "Establecer una conexión privada";
@@ -1688,6 +1748,9 @@
/* notification */
"New message" = "mensaje nuevo";
/* No comment provided by engineer. */
"New Passcode" = "Nueva contraseña";
/* No comment provided by engineer. */
"New passphrase…" = "Contraseña nueva…";
@@ -1697,6 +1760,9 @@
/* No comment provided by engineer. */
"No" = "No";
/* Authentication unavailable */
"No app password" = "Sin contraseña de la aplicación";
/* No comment provided by engineer. */
"No contacts selected" = "Ningún contacto seleccionado";
@@ -1734,6 +1800,9 @@
group pref value */
"off" = "apagado";
/* No comment provided by engineer. */
"Off" = "Apagado";
/* No comment provided by engineer. */
"Off (Local)" = "Apagado (Local)";
@@ -1818,6 +1887,21 @@
/* member role */
"owner" = "propietario";
/* No comment provided by engineer. */
"Passcode" = "Contraseña";
/* No comment provided by engineer. */
"Passcode changed!" = "¡Contraseña cambiada!";
/* No comment provided by engineer. */
"Passcode entry" = "Entrada de contraseña";
/* No comment provided by engineer. */
"Passcode not changed!" = "¡Contraseña no cambiada!";
/* No comment provided by engineer. */
"Passcode set!" = "¡Contraseña guardada!";
/* No comment provided by engineer. */
"Password to show" = "Contraseña para hacerlo visible";
@@ -1869,6 +1953,9 @@
/* No comment provided by engineer. */
"Please enter the previous password after restoring database backup. This action can not be undone." = "Introduce la contraseña anterior después de restaurar la copia de seguridad de la base de datos. Esta acción no se puede deshacer.";
/* No comment provided by engineer. */
"Please remember or store it securely - there is no way to recover a lost passcode!" = "Por favor, recuerda y guarda la contraseña en un lugar seguro. ¡No hay manera de recuperar una contraseña perdida!";
/* No comment provided by engineer. */
"Please restart the app and migrate the database to enable push notifications." = "Reinicia la aplicación y migra la base de datos para activar las notificaciones automáticas.";
@@ -2169,6 +2256,9 @@
/* server test error */
"Server requires authorization to create queues, check password" = "El servidor requiere autorización para crear colas, comprueba la contraseña";
/* server test error */
"Server requires authorization to upload, check password" = "El servidor requiere autorización para subir, comprueba la contraseña";
/* No comment provided by engineer. */
"Server test failed!" = "¡Error en prueba del servidor!";
@@ -2241,6 +2331,12 @@
/* No comment provided by engineer. */
"SimpleX Lock" = "Bloqueo SimpleX";
/* No comment provided by engineer. */
"SimpleX Lock mode" = "Modo Bloqueo SimpleX";
/* No comment provided by engineer. */
"SimpleX Lock not enabled!" = "¡Bloqueo SimpleX no activado!";
/* No comment provided by engineer. */
"SimpleX Lock turned on" = "Bloqueo SimpleX activado";
@@ -2289,12 +2385,18 @@
/* No comment provided by engineer. */
"strike" = "tachado";
/* No comment provided by engineer. */
"Submit" = "Enviar";
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Soporte SimpleX Chat";
/* No comment provided by engineer. */
"System" = "Sistema";
/* No comment provided by engineer. */
"System authentication" = "Autenticación del sistema";
/* No comment provided by engineer. */
"Take picture" = "Tomar foto";
@@ -2344,7 +2446,7 @@
"Thanks to the users [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#translate-the-apps)!" = "Gracias a los usuarios: [contribuye vía Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#traducir-el-aplicaciones)!";
/* No comment provided by engineer. */
"Thanks to the users contribute via Weblate!" = "Gracias a los usuarios: ¡contribuye a través de Weblate!";
"Thanks to the users contribute via Weblate!" = "Agradecimientos a los usuarios. ¡Contribuye a través de Weblate!";
/* No comment provided by engineer. */
"The 1st platform without any user identifiers private by design." = "La primera plataforma sin identificadores de usuario: diseñada para la privacidad.";
@@ -2365,7 +2467,7 @@
"The created archive is available via app Settings / Database / Old database archive." = "El archivo creado está disponible a través de Configuración / Base de datos / Archivo de base de datos antigua.";
/* No comment provided by engineer. */
"The group is fully decentralized it is visible only to the members." = "El grupo está totalmente descentralizado: sólo es visible para los miembros.";
"The group is fully decentralized it is visible only to the members." = "El grupo está totalmente descentralizado y sólo es visible para los miembros.";
/* No comment provided by engineer. */
"The message will be deleted for all members." = "El mensaje se eliminará para todos los miembros.";
@@ -2502,9 +2604,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "A menos que tu contacto haya eliminado la conexión o\nque este enlace ya se haya utilizado, podría tratarse de un error. Por favor, notifícalo.\nPara conectarte, pide a tu contacto que cree otro enlace de conexión y comprueba que tienes buena conexión de red.";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "Desbloquear";
/* authentication reason */
"Unlock app" = "Desbloquear aplicación";
/* No comment provided by engineer. */
"Unmute" = "Activar audio";
@@ -2538,6 +2643,9 @@
/* No comment provided by engineer. */
"Upgrade and open chat" = "Actualizar y abrir Chat";
/* server test step */
"Upload file" = "Subir archivo";
/* No comment provided by engineer. */
"Use .onion hosts" = "Usar hosts .onion";
@@ -2598,6 +2706,12 @@
/* No comment provided by engineer. */
"video call (not e2e encrypted)" = "videollamada (sin cifrado e2e)";
/* No comment provided by engineer. */
"Video will be received when your contact completes uploading it." = "El video se recibirá cuando tu contacto termine de subirlo.";
/* No comment provided by engineer. */
"Video will be received when your contact is online, please wait or check later!" = "El vídeo se recibirá cuando tu contacto esté en línea, por favor espera o compruébalo más tarde.";
/* No comment provided by engineer. */
"View security code" = "Ver código de seguridad";
@@ -2628,6 +2742,9 @@
/* No comment provided by engineer. */
"Waiting for image" = "Esperando imagen";
/* No comment provided by engineer. */
"Waiting for video" = "Esperando el vídeo";
/* No comment provided by engineer. */
"wants to connect to you!" = "¡quiere contactar contigo!";
@@ -2716,7 +2833,10 @@
"You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it." = "Puedes compartir tu dirección como enlace o como código QR: cualquiera podrá conectarse contigo. Si lo eliminas más tarde tus contactos no se perderán.";
/* No comment provided by engineer. */
"You can start chat via app Settings / Database or by restarting the app" = "Puede iniciar Chat a través de la Configuración / base de datos de la aplicación o reiniciando la aplicación";
"You can start chat via app Settings / Database or by restarting the app" = "Puede iniciar Chat a través de la Configuración / Base de datos de la aplicación o reiniciando la aplicación";
/* No comment provided by engineer. */
"You can turn on SimpleX Lock via Settings." = "Puedes activar el bloqueo de SimpleX a través de Configuración.";
/* No comment provided by engineer. */
"You can use markdown to format messages:" = "Puedes usar sintaxis markdown para dar formato a los mensajes:";
+127 -4
View File
@@ -142,9 +142,15 @@
/* No comment provided by engineer. */
"%lld members" = "%lld membres";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minutes";
/* No comment provided by engineer. */
"%lld second(s)" = "%lld seconde·s";
/* No comment provided by engineer. */
"%lld seconds" = "%lld secondes";
/* No comment provided by engineer. */
"%lldd" = "%lldj";
@@ -350,6 +356,9 @@
/* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "appel audio (sans chiffrement)";
/* PIN entry */
"Authentication cancelled" = "Authentification interrompue";
/* No comment provided by engineer. */
"Authentication failed" = "Échec de l'authentification";
@@ -437,9 +446,18 @@
/* No comment provided by engineer. */
"Change database passphrase?" = "Changer la phrase secrète de la base de données ?";
/* authentication reason */
"Change lock mode" = "Modifier le mode de verrouillage";
/* No comment provided by engineer. */
"Change member role?" = "Changer le rôle du membre?";
/* authentication reason */
"Change passcode" = "Modifier le code d'accès";
/* No comment provided by engineer. */
"Change Passcode" = "Modifier le code d'accès";
/* No comment provided by engineer. */
"Change receiving address" = "Changer d'adresse de réception";
@@ -521,6 +539,9 @@
/* No comment provided by engineer. */
"Colors" = "Couleurs";
/* server test step */
"Compare file" = "Comparer le fichier";
/* No comment provided by engineer. */
"Compare security codes with your contacts." = "Comparez les codes de sécurité avec vos contacts.";
@@ -539,6 +560,9 @@
/* No comment provided by engineer. */
"Confirm new passphrase…" = "Confirmer la nouvelle phrase secrète…";
/* No comment provided by engineer. */
"Confirm Passcode" = "Confirmer le code d'accès";
/* No comment provided by engineer. */
"Confirm password" = "Confirmer le mot de passe";
@@ -656,9 +680,6 @@
/* chat item action */
"Copy" = "Copier";
/* No comment provided by engineer. */
"Core built at: %@" = "Cœur compilé le : %@";
/* No comment provided by engineer. */
"Core version: v%@" = "Version du cœur : v%@";
@@ -668,6 +689,9 @@
/* No comment provided by engineer. */
"Create address" = "Créer une adresse";
/* server test step */
"Create file" = "Créer un fichier";
/* No comment provided by engineer. */
"Create group link" = "Créer un lien de groupe";
@@ -692,6 +716,9 @@
/* No comment provided by engineer. */
"creator" = "créateur";
/* No comment provided by engineer. */
"Current Passcode" = "Code d'accès actuel";
/* No comment provided by engineer. */
"Current passphrase…" = "Phrase secrète actuelle…";
@@ -803,6 +830,9 @@
/* No comment provided by engineer. */
"Delete database" = "Supprimer la base de données";
/* server test step */
"Delete file" = "Supprimer le fichier";
/* No comment provided by engineer. */
"Delete files and media?" = "Supprimer les fichiers et médias ?";
@@ -935,6 +965,9 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Rétrograder et ouvrir le chat";
/* server test step */
"Download file" = "Télécharger le fichier";
/* No comment provided by engineer. */
"Duplicate display name!" = "Nom d'affichage en double !";
@@ -959,6 +992,9 @@
/* No comment provided by engineer. */
"Enable instant notifications?" = "Activer les notifications instantanées?";
/* No comment provided by engineer. */
"Enable lock" = "Activer le verrouillage";
/* No comment provided by engineer. */
"Enable notifications" = "Activer les notifications";
@@ -1016,6 +1052,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Entrez la phrase secrète correcte.";
/* No comment provided by engineer. */
"Enter Passcode" = "Entrer le code d'accès";
/* No comment provided by engineer. */
"Enter passphrase…" = "Entrez la phrase secrète…";
@@ -1100,6 +1139,9 @@
/* No comment provided by engineer. */
"Error joining group" = "Erreur lors de la liaison avec le groupe";
/* No comment provided by engineer. */
"Error loading %@ servers" = "Erreur lors du chargement des serveurs %@";
/* No comment provided by engineer. */
"Error receiving file" = "Erreur lors de la réception du fichier";
@@ -1115,6 +1157,9 @@
/* No comment provided by engineer. */
"Error saving ICE servers" = "Erreur lors de la sauvegarde des serveurs ICE";
/* No comment provided by engineer. */
"Error saving passcode" = "Erreur lors de la sauvegarde du code d'accès";
/* No comment provided by engineer. */
"Error saving passphrase to keychain" = "Erreur lors de l'enregistrement de la phrase de passe dans la keychain";
@@ -1178,6 +1223,9 @@
/* No comment provided by engineer. */
"Failed to remove passphrase" = "Échec de la suppression de la phrase secrète";
/* No comment provided by engineer. */
"File transfer will be cancelled. If it's in progress it will be stoppped." = "Le transfert de fichiers sera annulé. S'il est en cours, il sera interrompu.";
/* No comment provided by engineer. */
"File will be received when your contact completes uploading it." = "Le fichier sera reçu lorsque votre contact aura terminé de le mettre en ligne.";
@@ -1343,6 +1391,9 @@
/* No comment provided by engineer. */
"Image will be received when your contact is online, please wait or check later!" = "L'image sera reçue quand votre contact sera en ligne, merci d'attendre ou de revenir plus tard!";
/* No comment provided by engineer. */
"Immediately" = "Immédiatement";
/* No comment provided by engineer. */
"Immune to spam and abuse" = "Protégé du spam et des abus";
@@ -1394,6 +1445,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Version de la base de données incompatible";
/* PIN entry */
"Incorrect passcode" = "Code d'accès erroné";
/* No comment provided by engineer. */
"Incorrect security code!" = "Code de sécurité incorrect !";
@@ -1502,6 +1556,9 @@
/* No comment provided by engineer. */
"Keychain error" = "Erreur de la keychain";
/* No comment provided by engineer. */
"KeyChain error" = "Erreur du trousseau de clés";
/* No comment provided by engineer. */
"Large file!" = "Fichier trop lourd !";
@@ -1538,6 +1595,12 @@
/* No comment provided by engineer. */
"Local profile data only" = "Données de profil local uniquement";
/* No comment provided by engineer. */
"Lock after" = "Verrouillage après";
/* No comment provided by engineer. */
"Lock mode" = "Mode de verrouillage";
/* No comment provided by engineer. */
"Make a private connection" = "Établir une connexion privée";
@@ -1685,6 +1748,9 @@
/* notification */
"New message" = "Nouveau message";
/* No comment provided by engineer. */
"New Passcode" = "Nouveau code d'accès";
/* No comment provided by engineer. */
"New passphrase…" = "Nouvelle phrase secrète…";
@@ -1694,6 +1760,9 @@
/* No comment provided by engineer. */
"No" = "Non";
/* Authentication unavailable */
"No app password" = "Pas de mot de passe pour l'app";
/* No comment provided by engineer. */
"No contacts selected" = "Aucun contact sélectionné";
@@ -1731,6 +1800,9 @@
group pref value */
"off" = "off";
/* No comment provided by engineer. */
"Off" = "Off";
/* No comment provided by engineer. */
"Off (Local)" = "Off (Local)";
@@ -1815,6 +1887,21 @@
/* member role */
"owner" = "propriétaire";
/* No comment provided by engineer. */
"Passcode" = "Code d'accès";
/* No comment provided by engineer. */
"Passcode changed!" = "Code d'accès modifié !";
/* No comment provided by engineer. */
"Passcode entry" = "Saisie du code";
/* No comment provided by engineer. */
"Passcode not changed!" = "Le code d'accès n'a pas été modifié !";
/* No comment provided by engineer. */
"Passcode set!" = "Code d'accès défini !";
/* No comment provided by engineer. */
"Password to show" = "Mot de passe à entrer";
@@ -1866,6 +1953,9 @@
/* No comment provided by engineer. */
"Please enter the previous password after restoring database backup. This action can not be undone." = "Veuillez entrer le mot de passe précédent après avoir restauré la sauvegarde de la base de données. Cette action ne peut pas être annulée.";
/* No comment provided by engineer. */
"Please remember or store it securely - there is no way to recover a lost passcode!" = "N'oubliez pas de le mémoriser ou de le conserver en toute sécurité - il n'y a aucun moyen de récupérer un code d'accès perdu !";
/* No comment provided by engineer. */
"Please restart the app and migrate the database to enable push notifications." = "Veuillez redémarrer l'app et migrer la base de données pour activer les notifications push.";
@@ -2166,6 +2256,9 @@
/* server test error */
"Server requires authorization to create queues, check password" = "Le serveur requiert une autorisation pour créer des files d'attente, vérifiez le mot de passe";
/* server test error */
"Server requires authorization to upload, check password" = "Le serveur requiert une autorisation pour uploader, vérifiez le mot de passe";
/* No comment provided by engineer. */
"Server test failed!" = "Échec du test du serveur !";
@@ -2238,6 +2331,12 @@
/* No comment provided by engineer. */
"SimpleX Lock" = "SimpleX Lock";
/* No comment provided by engineer. */
"SimpleX Lock mode" = "Mode de SimpleX Lock";
/* No comment provided by engineer. */
"SimpleX Lock not enabled!" = "SimpleX Lock n'est pas activé !";
/* No comment provided by engineer. */
"SimpleX Lock turned on" = "SimpleX Lock activé";
@@ -2286,12 +2385,18 @@
/* No comment provided by engineer. */
"strike" = "barré";
/* No comment provided by engineer. */
"Submit" = "Soumettre";
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Supporter SimpleX Chat";
/* No comment provided by engineer. */
"System" = "Système";
/* No comment provided by engineer. */
"System authentication" = "Authentification du système";
/* No comment provided by engineer. */
"Take picture" = "Prendre une photo";
@@ -2499,9 +2604,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "A moins que votre contact ait supprimé la connexion ou que ce lien ait déjà été utilisé, il peut s'agir d'un bug - veuillez le signaler.\nPour vous connecter, veuillez demander à votre contact de créer un autre lien de connexion et vérifiez que vous disposez d'une connexion réseau stable.";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "Déverrouiller";
/* authentication reason */
"Unlock app" = "Déverrouiller l'app";
/* No comment provided by engineer. */
"Unmute" = "Démute";
@@ -2535,6 +2643,9 @@
/* No comment provided by engineer. */
"Upgrade and open chat" = "Mettre à niveau et ouvrir le chat";
/* server test step */
"Upload file" = "Transférer le fichier";
/* No comment provided by engineer. */
"Use .onion hosts" = "Utiliser les hôtes .onions";
@@ -2595,6 +2706,12 @@
/* No comment provided by engineer. */
"video call (not e2e encrypted)" = "appel vidéo (sans chiffrement)";
/* No comment provided by engineer. */
"Video will be received when your contact completes uploading it." = "La vidéo ne sera reçue que lorsque votre contact aura fini de la transférer.";
/* No comment provided by engineer. */
"Video will be received when your contact is online, please wait or check later!" = "La vidéo ne sera reçue que lorsque votre contact sera en ligne. Veuillez patienter ou vérifier plus tard !";
/* No comment provided by engineer. */
"View security code" = "Afficher le code de sécurité";
@@ -2625,6 +2742,9 @@
/* No comment provided by engineer. */
"Waiting for image" = "En attente de l'image";
/* No comment provided by engineer. */
"Waiting for video" = "En attente de la vidéo";
/* No comment provided by engineer. */
"wants to connect to you!" = "veut établir une connexion !";
@@ -2715,6 +2835,9 @@
/* No comment provided by engineer. */
"You can start chat via app Settings / Database or by restarting the app" = "Vous pouvez lancer le chat via Paramètres / Base de données ou en redémarrant l'app";
/* No comment provided by engineer. */
"You can turn on SimpleX Lock via Settings." = "Vous pouvez activer SimpleX Lock dans les Paramètres.";
/* No comment provided by engineer. */
"You can use markdown to format messages:" = "Vous pouvez utiliser le format markdown pour mettre en forme les messages :";
+124 -4
View File
@@ -142,9 +142,15 @@
/* No comment provided by engineer. */
"%lld members" = "%lld membri";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minuti";
/* No comment provided by engineer. */
"%lld second(s)" = "%lld secondo/i";
/* No comment provided by engineer. */
"%lld seconds" = "%lld secondi";
/* No comment provided by engineer. */
"%lldd" = "%lldg";
@@ -350,6 +356,9 @@
/* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "chiamata audio (non crittografata e2e)";
/* PIN entry */
"Authentication cancelled" = "Autenticazione annullata";
/* No comment provided by engineer. */
"Authentication failed" = "Autenticazione fallita";
@@ -437,9 +446,18 @@
/* No comment provided by engineer. */
"Change database passphrase?" = "Cambiare password del database?";
/* authentication reason */
"Change lock mode" = "Cambia modalità di blocco";
/* No comment provided by engineer. */
"Change member role?" = "Cambiare ruolo del membro?";
/* authentication reason */
"Change passcode" = "Cambia codice di accesso";
/* No comment provided by engineer. */
"Change Passcode" = "Cambia codice di accesso";
/* No comment provided by engineer. */
"Change receiving address" = "Cambia indirizzo di ricezione";
@@ -521,6 +539,9 @@
/* No comment provided by engineer. */
"Colors" = "Colori";
/* server test step */
"Compare file" = "Confronta file";
/* No comment provided by engineer. */
"Compare security codes with your contacts." = "Confronta i codici di sicurezza con i tuoi contatti.";
@@ -539,6 +560,9 @@
/* No comment provided by engineer. */
"Confirm new passphrase…" = "Conferma password nuova…";
/* No comment provided by engineer. */
"Confirm Passcode" = "Conferma il codice di accesso";
/* No comment provided by engineer. */
"Confirm password" = "Conferma password";
@@ -656,9 +680,6 @@
/* chat item action */
"Copy" = "Copia";
/* No comment provided by engineer. */
"Core built at: %@" = "Core compilato il: %@";
/* No comment provided by engineer. */
"Core version: v%@" = "Versione core: v%@";
@@ -668,6 +689,9 @@
/* No comment provided by engineer. */
"Create address" = "Crea indirizzo";
/* server test step */
"Create file" = "Crea file";
/* No comment provided by engineer. */
"Create group link" = "Crea link del gruppo";
@@ -692,6 +716,9 @@
/* No comment provided by engineer. */
"creator" = "creatore";
/* No comment provided by engineer. */
"Current Passcode" = "Codice di accesso attuale";
/* No comment provided by engineer. */
"Current passphrase…" = "Password attuale…";
@@ -803,6 +830,9 @@
/* No comment provided by engineer. */
"Delete database" = "Elimina database";
/* server test step */
"Delete file" = "Elimina file";
/* No comment provided by engineer. */
"Delete files and media?" = "Eliminare i file e i multimediali?";
@@ -935,6 +965,9 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Esegui downgrade e apri chat";
/* server test step */
"Download file" = "Scarica file";
/* No comment provided by engineer. */
"Duplicate display name!" = "Nome da mostrare doppio!";
@@ -959,6 +992,9 @@
/* No comment provided by engineer. */
"Enable instant notifications?" = "Attivare le notifiche istantanee?";
/* No comment provided by engineer. */
"Enable lock" = "Attiva blocco";
/* No comment provided by engineer. */
"Enable notifications" = "Attiva le notifiche";
@@ -1016,6 +1052,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Inserisci la password giusta.";
/* No comment provided by engineer. */
"Enter Passcode" = "Inserisci il codice di accesso";
/* No comment provided by engineer. */
"Enter passphrase…" = "Inserisci la password…";
@@ -1100,6 +1139,9 @@
/* No comment provided by engineer. */
"Error joining group" = "Errore di ingresso nel gruppo";
/* No comment provided by engineer. */
"Error loading %@ servers" = "Errore nel caricamento dei server %@";
/* No comment provided by engineer. */
"Error receiving file" = "Errore nella ricezione del file";
@@ -1115,6 +1157,9 @@
/* No comment provided by engineer. */
"Error saving ICE servers" = "Errore nel salvataggio dei server ICE";
/* No comment provided by engineer. */
"Error saving passcode" = "Errore nel salvataggio del codice di accesso";
/* No comment provided by engineer. */
"Error saving passphrase to keychain" = "Errore nel salvataggio della password nel portachiavi";
@@ -1346,6 +1391,9 @@
/* No comment provided by engineer. */
"Image will be received when your contact is online, please wait or check later!" = "L'immagine verrà ricevuta quando il tuo contatto sarà in linea, aspetta o controlla più tardi!";
/* No comment provided by engineer. */
"Immediately" = "Immediatamente";
/* No comment provided by engineer. */
"Immune to spam and abuse" = "Immune a spam e abusi";
@@ -1397,6 +1445,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Versione del database incompatibile";
/* PIN entry */
"Incorrect passcode" = "Codice di accesso errato";
/* No comment provided by engineer. */
"Incorrect security code!" = "Codice di sicurezza sbagliato!";
@@ -1505,6 +1556,9 @@
/* No comment provided by engineer. */
"Keychain error" = "Errore del portachiavi";
/* No comment provided by engineer. */
"KeyChain error" = "Errore del portachiavi";
/* No comment provided by engineer. */
"Large file!" = "File grande!";
@@ -1541,6 +1595,12 @@
/* No comment provided by engineer. */
"Local profile data only" = "Solo dati del profilo locale";
/* No comment provided by engineer. */
"Lock after" = "Blocca dopo";
/* No comment provided by engineer. */
"Lock mode" = "Modalità di blocco";
/* No comment provided by engineer. */
"Make a private connection" = "Crea una connessione privata";
@@ -1688,6 +1748,9 @@
/* notification */
"New message" = "Nuovo messaggio";
/* No comment provided by engineer. */
"New Passcode" = "Nuovo codice di accesso";
/* No comment provided by engineer. */
"New passphrase…" = "Nuova password…";
@@ -1697,6 +1760,9 @@
/* No comment provided by engineer. */
"No" = "No";
/* Authentication unavailable */
"No app password" = "Nessuna password dell'app";
/* No comment provided by engineer. */
"No contacts selected" = "Nessun contatto selezionato";
@@ -1734,6 +1800,9 @@
group pref value */
"off" = "off";
/* No comment provided by engineer. */
"Off" = "Off";
/* No comment provided by engineer. */
"Off (Local)" = "Off (Locale)";
@@ -1818,6 +1887,21 @@
/* member role */
"owner" = "proprietario";
/* No comment provided by engineer. */
"Passcode" = "Codice di accesso";
/* No comment provided by engineer. */
"Passcode changed!" = "Codice di accesso cambiato!";
/* No comment provided by engineer. */
"Passcode entry" = "Inserimento del codice di accesso";
/* No comment provided by engineer. */
"Passcode not changed!" = "Codice di accesso non cambiato!";
/* No comment provided by engineer. */
"Passcode set!" = "Codice di accesso impostato!";
/* No comment provided by engineer. */
"Password to show" = "Password per mostrare";
@@ -1869,6 +1953,9 @@
/* No comment provided by engineer. */
"Please enter the previous password after restoring database backup. This action can not be undone." = "Inserisci la password precedente dopo aver ripristinato il backup del database. Questa azione non può essere annullata.";
/* No comment provided by engineer. */
"Please remember or store it securely - there is no way to recover a lost passcode!" = "Ricordalo o conservalo in modo sicuro: non c'è modo di recuperare un codice di accesso perso!";
/* No comment provided by engineer. */
"Please restart the app and migrate the database to enable push notifications." = "Riavvia l'app ed esegui la migrazione del database per attivare le notifiche push.";
@@ -2169,6 +2256,9 @@
/* server test error */
"Server requires authorization to create queues, check password" = "Il server richiede l'autorizzazione di creare code, controlla la password";
/* server test error */
"Server requires authorization to upload, check password" = "Il server richiede l'autorizzazione per il caricamento, controllare la password";
/* No comment provided by engineer. */
"Server test failed!" = "Test del server fallito!";
@@ -2241,6 +2331,12 @@
/* No comment provided by engineer. */
"SimpleX Lock" = "SimpleX Lock";
/* No comment provided by engineer. */
"SimpleX Lock mode" = "Modalità di SimpleX Lock";
/* No comment provided by engineer. */
"SimpleX Lock not enabled!" = "SimpleX Lock non attivato!";
/* No comment provided by engineer. */
"SimpleX Lock turned on" = "SimpleX Lock attivato";
@@ -2289,12 +2385,18 @@
/* No comment provided by engineer. */
"strike" = "barrato";
/* No comment provided by engineer. */
"Submit" = "Invia";
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Supporta SimpleX Chat";
/* No comment provided by engineer. */
"System" = "Sistema";
/* No comment provided by engineer. */
"System authentication" = "Autenticazione di sistema";
/* No comment provided by engineer. */
"Take picture" = "Scatta foto";
@@ -2502,9 +2604,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "A meno che il tuo contatto non abbia eliminato la connessione o che questo link non sia già stato usato, potrebbe essere un errore; per favore segnalalo.\nPer connetterti, chiedi al tuo contatto di creare un altro link di connessione e controlla di avere una connessione di rete stabile.";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "Sblocca";
/* authentication reason */
"Unlock app" = "Sblocca l'app";
/* No comment provided by engineer. */
"Unmute" = "Riattiva audio";
@@ -2538,6 +2643,9 @@
/* No comment provided by engineer. */
"Upgrade and open chat" = "Aggiorna e apri chat";
/* server test step */
"Upload file" = "Invia file";
/* No comment provided by engineer. */
"Use .onion hosts" = "Usa gli host .onion";
@@ -2598,6 +2706,12 @@
/* No comment provided by engineer. */
"video call (not e2e encrypted)" = "videochiamata (non crittografata e2e)";
/* No comment provided by engineer. */
"Video will be received when your contact completes uploading it." = "Il video verrà ricevuto quando il tuo contatto completerà l'invio.";
/* No comment provided by engineer. */
"Video will be received when your contact is online, please wait or check later!" = "Il video verrà ricevuto quando il tuo contatto sarà in linea, attendi o controlla più tardi!";
/* No comment provided by engineer. */
"View security code" = "Vedi codice di sicurezza";
@@ -2628,6 +2742,9 @@
/* No comment provided by engineer. */
"Waiting for image" = "In attesa dell'immagine";
/* No comment provided by engineer. */
"Waiting for video" = "In attesa del video";
/* No comment provided by engineer. */
"wants to connect to you!" = "vuole connettersi con te!";
@@ -2718,6 +2835,9 @@
/* No comment provided by engineer. */
"You can start chat via app Settings / Database or by restarting the app" = "Puoi avviare la chat via Impostazioni / Database o riavviando l'app";
/* No comment provided by engineer. */
"You can turn on SimpleX Lock via Settings." = "Puoi attivare SimpleX Lock tramite le impostazioni.";
/* No comment provided by engineer. */
"You can use markdown to format messages:" = "Puoi usare il markdown per formattare i messaggi:";
+125 -5
View File
@@ -142,9 +142,15 @@
/* No comment provided by engineer. */
"%lld members" = "%lld leden";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minuten";
/* No comment provided by engineer. */
"%lld second(s)" = "%lld seconde(n)";
/* No comment provided by engineer. */
"%lld seconds" = "%lld seconden";
/* No comment provided by engineer. */
"%lldd" = "%lldd";
@@ -350,6 +356,9 @@
/* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "audio oproep (niet e2e versleuteld)";
/* PIN entry */
"Authentication cancelled" = "Verificatie geannuleerd";
/* No comment provided by engineer. */
"Authentication failed" = "Verificatie mislukt";
@@ -432,14 +441,23 @@
"Cannot receive file" = "Kan bestand niet ontvangen";
/* No comment provided by engineer. */
"Change" = "Wijziging";
"Change" = "Veranderen";
/* No comment provided by engineer. */
"Change database passphrase?" = "Wachtwoord database wijzigen?";
/* authentication reason */
"Change lock mode" = "Wijzig de vergrendelings modus";
/* No comment provided by engineer. */
"Change member role?" = "Rol van gebruiker wijzigen?";
/* authentication reason */
"Change passcode" = "Toegangscode wijzigen";
/* No comment provided by engineer. */
"Change Passcode" = "Toegangscode wijzigen";
/* No comment provided by engineer. */
"Change receiving address" = "Ontvangst adres wijzigen";
@@ -521,6 +539,9 @@
/* No comment provided by engineer. */
"Colors" = "Kleuren";
/* server test step */
"Compare file" = "Bestand vergelijken";
/* No comment provided by engineer. */
"Compare security codes with your contacts." = "Vergelijk beveiligingscodes met je contacten.";
@@ -539,6 +560,9 @@
/* No comment provided by engineer. */
"Confirm new passphrase…" = "Bevestig nieuw wachtwoord…";
/* No comment provided by engineer. */
"Confirm Passcode" = "Bevestig toegangscode";
/* No comment provided by engineer. */
"Confirm password" = "Bevestig wachtwoord";
@@ -656,9 +680,6 @@
/* chat item action */
"Copy" = "Kopiëren";
/* No comment provided by engineer. */
"Core built at: %@" = "Core built at: %@";
/* No comment provided by engineer. */
"Core version: v%@" = "Core versie: v% @";
@@ -668,6 +689,9 @@
/* No comment provided by engineer. */
"Create address" = "Adres aanmaken";
/* server test step */
"Create file" = "Bestand maken";
/* No comment provided by engineer. */
"Create group link" = "Groep link maken";
@@ -692,6 +716,9 @@
/* No comment provided by engineer. */
"creator" = "creator";
/* No comment provided by engineer. */
"Current Passcode" = "Huidige toegangscode";
/* No comment provided by engineer. */
"Current passphrase…" = "Huidige wachtwoord…";
@@ -803,6 +830,9 @@
/* No comment provided by engineer. */
"Delete database" = "Database verwijderen";
/* server test step */
"Delete file" = "Verwijder bestand";
/* No comment provided by engineer. */
"Delete files and media?" = "Bestanden en media verwijderen?";
@@ -935,6 +965,9 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Downgraden en chat openen";
/* server test step */
"Download file" = "Download bestand";
/* No comment provided by engineer. */
"Duplicate display name!" = "Dubbele weergavenaam!";
@@ -959,6 +992,9 @@
/* No comment provided by engineer. */
"Enable instant notifications?" = "Onmiddellijke meldingen inschakelen?";
/* No comment provided by engineer. */
"Enable lock" = "Vergrendeling inschakelen";
/* No comment provided by engineer. */
"Enable notifications" = "Meldingen aanzetten";
@@ -1016,6 +1052,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Voer het juiste wachtwoord in.";
/* No comment provided by engineer. */
"Enter Passcode" = "Voer toegangscode in";
/* No comment provided by engineer. */
"Enter passphrase…" = "Voer wachtwoord in…";
@@ -1100,6 +1139,9 @@
/* No comment provided by engineer. */
"Error joining group" = "Fout bij lid worden van groep";
/* No comment provided by engineer. */
"Error loading %@ servers" = "Fout bij het laden van %@ servers";
/* No comment provided by engineer. */
"Error receiving file" = "Fout bij ontvangen van bestand";
@@ -1115,6 +1157,9 @@
/* No comment provided by engineer. */
"Error saving ICE servers" = "Fout bij opslaan van ICE servers";
/* No comment provided by engineer. */
"Error saving passcode" = "Fout bij opslaan van toegangscode";
/* No comment provided by engineer. */
"Error saving passphrase to keychain" = "Fout bij opslaan van wachtwoord in de keychain";
@@ -1346,6 +1391,9 @@
/* No comment provided by engineer. */
"Image will be received when your contact is online, please wait or check later!" = "De afbeelding wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of kijk later!";
/* No comment provided by engineer. */
"Immediately" = "Onmiddellijk";
/* No comment provided by engineer. */
"Immune to spam and abuse" = "Immuun voor spam en misbruik";
@@ -1397,6 +1445,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Incompatibele database versie";
/* PIN entry */
"Incorrect passcode" = "Onjuiste toegangscode";
/* No comment provided by engineer. */
"Incorrect security code!" = "Onjuiste beveiligingscode!";
@@ -1505,6 +1556,9 @@
/* No comment provided by engineer. */
"Keychain error" = "Keychain fout";
/* No comment provided by engineer. */
"KeyChain error" = "Keychain fout";
/* No comment provided by engineer. */
"Large file!" = "Groot bestand!";
@@ -1541,6 +1595,12 @@
/* No comment provided by engineer. */
"Local profile data only" = "Alleen lokale profielgegevens";
/* No comment provided by engineer. */
"Lock after" = "Vergrendelen na";
/* No comment provided by engineer. */
"Lock mode" = "Vergrendeling modus";
/* No comment provided by engineer. */
"Make a private connection" = "Maak een privéverbinding";
@@ -1688,6 +1748,9 @@
/* notification */
"New message" = "nieuw bericht";
/* No comment provided by engineer. */
"New Passcode" = "Nieuwe toegangscode";
/* No comment provided by engineer. */
"New passphrase…" = "Nieuw wachtwoord…";
@@ -1697,6 +1760,9 @@
/* No comment provided by engineer. */
"No" = "Nee";
/* Authentication unavailable */
"No app password" = "Geen app wachtwoord";
/* No comment provided by engineer. */
"No contacts selected" = "Geen contacten geselecteerd";
@@ -1734,6 +1800,9 @@
group pref value */
"off" = "uit";
/* No comment provided by engineer. */
"Off" = "Uit";
/* No comment provided by engineer. */
"Off (Local)" = "Uit (lokaal)";
@@ -1818,6 +1887,21 @@
/* member role */
"owner" = "Eigenaar";
/* No comment provided by engineer. */
"Passcode" = "Toegangscode";
/* No comment provided by engineer. */
"Passcode changed!" = "Toegangscode gewijzigd!";
/* No comment provided by engineer. */
"Passcode entry" = "Toegangscode invoer";
/* No comment provided by engineer. */
"Passcode not changed!" = "Toegangscode niet gewijzigd!";
/* No comment provided by engineer. */
"Passcode set!" = "Toegangscode ingesteld!";
/* No comment provided by engineer. */
"Password to show" = "Wachtwoord om weer te geven";
@@ -1869,6 +1953,9 @@
/* No comment provided by engineer. */
"Please enter the previous password after restoring database backup. This action can not be undone." = "Voer het vorige wachtwoord in na het herstellen van de database back-up. Deze actie kan niet ongedaan gemaakt worden.";
/* No comment provided by engineer. */
"Please remember or store it securely - there is no way to recover a lost passcode!" = "Onthoud het of bewaar het veilig - er is geen manier om een verloren toegangscode te herstellen!";
/* No comment provided by engineer. */
"Please restart the app and migrate the database to enable push notifications." = "Start de app opnieuw en migreer de database om push meldingen in te schakelen.";
@@ -2169,6 +2256,9 @@
/* server test error */
"Server requires authorization to create queues, check password" = "Server vereist autorisatie om wachtrijen te maken, controleer wachtwoord";
/* server test error */
"Server requires authorization to upload, check password" = "Server vereist autorisatie om te uploaden, wachtwoord controleren";
/* No comment provided by engineer. */
"Server test failed!" = "Servertest mislukt!";
@@ -2241,6 +2331,12 @@
/* No comment provided by engineer. */
"SimpleX Lock" = "SimpleX Vergrendelen";
/* No comment provided by engineer. */
"SimpleX Lock mode" = "SimpleX Vergrendel modus";
/* No comment provided by engineer. */
"SimpleX Lock not enabled!" = "SimpleX vergrendeling niet ingeschakeld!";
/* No comment provided by engineer. */
"SimpleX Lock turned on" = "SimpleX Vergrendelen ingeschakeld";
@@ -2289,12 +2385,18 @@
/* No comment provided by engineer. */
"strike" = "staking";
/* No comment provided by engineer. */
"Submit" = "Indienen";
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Ondersteuning van SimpleX Chat";
/* No comment provided by engineer. */
"System" = "Systeem";
/* No comment provided by engineer. */
"System authentication" = "Systeem authenticatie";
/* No comment provided by engineer. */
"Take picture" = "Foto nemen";
@@ -2502,9 +2604,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Tenzij uw contactpersoon de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft.\nOm verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft.";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "Ontgrendelen";
/* authentication reason */
"Unlock app" = "Ontgrendel app";
/* No comment provided by engineer. */
"Unmute" = "Dempen opheffen";
@@ -2538,6 +2643,9 @@
/* No comment provided by engineer. */
"Upgrade and open chat" = "Upgrade en open chat";
/* server test step */
"Upload file" = "Upload bestand";
/* No comment provided by engineer. */
"Use .onion hosts" = "Gebruik .onion-hosts";
@@ -2598,6 +2706,12 @@
/* No comment provided by engineer. */
"video call (not e2e encrypted)" = "video gesprek (niet e2e versleuteld)";
/* No comment provided by engineer. */
"Video will be received when your contact completes uploading it." = "De video wordt ontvangen wanneer uw contactpersoon het uploaden heeft voltooid.";
/* No comment provided by engineer. */
"Video will be received when your contact is online, please wait or check later!" = "De video wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of kijk later!";
/* No comment provided by engineer. */
"View security code" = "Beveiligingscode bekijken";
@@ -2628,6 +2742,9 @@
/* No comment provided by engineer. */
"Waiting for image" = "Wachten op afbeelding";
/* No comment provided by engineer. */
"Waiting for video" = "Wachten op video";
/* No comment provided by engineer. */
"wants to connect to you!" = "wil met je in contact komen!";
@@ -2718,6 +2835,9 @@
/* No comment provided by engineer. */
"You can start chat via app Settings / Database or by restarting the app" = "U kunt de chat starten via app Instellingen / Database of door de app opnieuw op te starten";
/* No comment provided by engineer. */
"You can turn on SimpleX Lock via Settings." = "Je kunt SimpleX Vergrendeling aanzetten via Instellingen.";
/* No comment provided by engineer. */
"You can use markdown to format messages:" = "U kunt markdown gebruiken voor opmaak in berichten:";
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
/* Bundle name */
"CFBundleName" = "SimpleX";
/* Privacy - Camera Usage Description */
"NSCameraUsageDescription" = "SimpleX potrzebuje dostępu do kamery, w celu skanowania kodów QR aby połączyć się z innymi użytkownikami i połączeń wideo.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX używa Face ID do lokalnego uwierzytelniania";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX potrzebuje dostępu do mikrofonu, w celu połączeń audio i wideo oraz nagrywania wiadomości głosowych.";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "SimpleX potrzebuje dostępu do galerii zdjęć, w celu zapisywania i otrzymywania mediów";
+1 -4
View File
@@ -656,9 +656,6 @@
/* chat item action */
"Copy" = "Скопировать";
/* No comment provided by engineer. */
"Core built at: %@" = "Ядро скомпилировано: %@";
/* No comment provided by engineer. */
"Core version: v%@" = "Версия ядра: v%@";
@@ -2502,7 +2499,7 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Возможно, Ваш контакт удалил ссылку, или она уже была использована. Если это не так, то это может быть ошибкой - пожалуйста, сообщите нам об этом.\nЧтобы установить соединение, попросите Ваш контакт создать еще одну ссылку и проверьте Ваше соединение с сетью.";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "Разблокировать";
/* No comment provided by engineer. */
+126 -6
View File
@@ -142,9 +142,15 @@
/* No comment provided by engineer. */
"%lld members" = "%lld 成员";
/* No comment provided by engineer. */
"%lld minutes" = "%lld 分钟";
/* No comment provided by engineer. */
"%lld second(s)" = "%lld 秒";
/* No comment provided by engineer. */
"%lld seconds" = "%lld 秒";
/* No comment provided by engineer. */
"%lldd" = "%lldd";
@@ -350,14 +356,17 @@
/* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "语音通话(非端到端加密)";
/* PIN entry */
"Authentication cancelled" = "身份验证已取消";
/* No comment provided by engineer. */
"Authentication failed" = "认证失败";
"Authentication failed" = "身份认证失败";
/* No comment provided by engineer. */
"Authentication is required before the call is connected, but you may miss calls." = "通话接通前需要进行认证,但您可能会错过来电。";
/* No comment provided by engineer. */
"Authentication unavailable" = "认证不可用";
"Authentication unavailable" = "身份认证不可用";
/* No comment provided by engineer. */
"Auto-accept contact requests" = "自动接受联系人请求";
@@ -437,9 +446,18 @@
/* No comment provided by engineer. */
"Change database passphrase?" = "更改数据库密码?";
/* authentication reason */
"Change lock mode" = "更改锁定模式";
/* No comment provided by engineer. */
"Change member role?" = "更改成员角色?";
/* authentication reason */
"Change passcode" = "更改密码";
/* No comment provided by engineer. */
"Change Passcode" = "更改密码";
/* No comment provided by engineer. */
"Change receiving address" = "更改接收地址";
@@ -521,6 +539,9 @@
/* No comment provided by engineer. */
"Colors" = "颜色";
/* server test step */
"Compare file" = "对比文件";
/* No comment provided by engineer. */
"Compare security codes with your contacts." = "与您的联系人比较安全码。";
@@ -539,6 +560,9 @@
/* No comment provided by engineer. */
"Confirm new passphrase…" = "确认新密码……";
/* No comment provided by engineer. */
"Confirm Passcode" = "确认密码";
/* No comment provided by engineer. */
"Confirm password" = "确认密码";
@@ -656,9 +680,6 @@
/* chat item action */
"Copy" = "复制";
/* No comment provided by engineer. */
"Core built at: %@" = "核心构建于:%@";
/* No comment provided by engineer. */
"Core version: v%@" = "核心版本: v%@";
@@ -668,6 +689,9 @@
/* No comment provided by engineer. */
"Create address" = "创建地址";
/* server test step */
"Create file" = "创建文件";
/* No comment provided by engineer. */
"Create group link" = "创建群组链接";
@@ -692,6 +716,9 @@
/* No comment provided by engineer. */
"creator" = "创建者";
/* No comment provided by engineer. */
"Current Passcode" = "当前密码";
/* No comment provided by engineer. */
"Current passphrase…" = "现有密码……";
@@ -803,6 +830,9 @@
/* No comment provided by engineer. */
"Delete database" = "删除数据库";
/* server test step */
"Delete file" = "删除文件";
/* No comment provided by engineer. */
"Delete files and media?" = "删除文件和媒体文件吗?";
@@ -935,6 +965,9 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "降级并打开聊天";
/* server test step */
"Download file" = "下载文件";
/* No comment provided by engineer. */
"Duplicate display name!" = "重复的显示名!";
@@ -959,6 +992,9 @@
/* No comment provided by engineer. */
"Enable instant notifications?" = "启用即时通知?";
/* No comment provided by engineer. */
"Enable lock" = "启用锁定";
/* No comment provided by engineer. */
"Enable notifications" = "启用通知";
@@ -1016,6 +1052,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "输入正确密码。";
/* No comment provided by engineer. */
"Enter Passcode" = "输入密码";
/* No comment provided by engineer. */
"Enter passphrase…" = "输入密码……";
@@ -1100,6 +1139,9 @@
/* No comment provided by engineer. */
"Error joining group" = "加入群组错误";
/* No comment provided by engineer. */
"Error loading %@ servers" = "加载 %@ 服务器错误";
/* No comment provided by engineer. */
"Error receiving file" = "接收文件错误";
@@ -1115,6 +1157,9 @@
/* No comment provided by engineer. */
"Error saving ICE servers" = "保存 ICE 服务器错误";
/* No comment provided by engineer. */
"Error saving passcode" = "保存密码错误";
/* No comment provided by engineer. */
"Error saving passphrase to keychain" = "保存密码到钥匙串错误";
@@ -1346,6 +1391,9 @@
/* No comment provided by engineer. */
"Image will be received when your contact is online, please wait or check later!" = "图片将在您的联系人在线时收到,请稍等或稍后查看!";
/* No comment provided by engineer. */
"Immediately" = "立即";
/* No comment provided by engineer. */
"Immune to spam and abuse" = "不受垃圾和骚扰消息影响";
@@ -1397,6 +1445,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "数据库版本不兼容";
/* PIN entry */
"Incorrect passcode" = "密码错误";
/* No comment provided by engineer. */
"Incorrect security code!" = "安全码不正确!";
@@ -1505,6 +1556,9 @@
/* No comment provided by engineer. */
"Keychain error" = "钥匙串错误";
/* No comment provided by engineer. */
"KeyChain error" = "钥匙串错误";
/* No comment provided by engineer. */
"Large file!" = "大文件!";
@@ -1541,6 +1595,12 @@
/* No comment provided by engineer. */
"Local profile data only" = "仅本地配置文件数据";
/* No comment provided by engineer. */
"Lock after" = "在此后锁定";
/* No comment provided by engineer. */
"Lock mode" = "锁定模式";
/* No comment provided by engineer. */
"Make a private connection" = "建立私密连接";
@@ -1688,6 +1748,9 @@
/* notification */
"New message" = "新消息";
/* No comment provided by engineer. */
"New Passcode" = "新密码";
/* No comment provided by engineer. */
"New passphrase…" = "新密码……";
@@ -1697,6 +1760,9 @@
/* No comment provided by engineer. */
"No" = "否";
/* Authentication unavailable */
"No app password" = "没有应用程序密码";
/* No comment provided by engineer. */
"No contacts selected" = "未选择联系人";
@@ -1734,6 +1800,9 @@
group pref value */
"off" = "关闭";
/* No comment provided by engineer. */
"Off" = "关闭";
/* No comment provided by engineer. */
"Off (Local)" = "关闭(本地)";
@@ -1818,6 +1887,21 @@
/* member role */
"owner" = "群主";
/* No comment provided by engineer. */
"Passcode" = "密码";
/* No comment provided by engineer. */
"Passcode changed!" = "密码已更改!";
/* No comment provided by engineer. */
"Passcode entry" = "密码输入";
/* No comment provided by engineer. */
"Passcode not changed!" = "密码未更改!";
/* No comment provided by engineer. */
"Passcode set!" = "密码已设置!";
/* No comment provided by engineer. */
"Password to show" = "显示密码";
@@ -1869,6 +1953,9 @@
/* No comment provided by engineer. */
"Please enter the previous password after restoring database backup. This action can not be undone." = "恢复数据库备份后请输入之前的密码。 此操作无法撤消。";
/* No comment provided by engineer. */
"Please remember or store it securely - there is no way to recover a lost passcode!" = "请牢记或妥善保管——丢失的密码将无法恢复!";
/* No comment provided by engineer. */
"Please restart the app and migrate the database to enable push notifications." = "请重新启动应用程序并迁移数据库以启用推送通知。";
@@ -2169,6 +2256,9 @@
/* server test error */
"Server requires authorization to create queues, check password" = "服务器需要授权才能创建队列,检查密码";
/* server test error */
"Server requires authorization to upload, check password" = "服务器需要授权来上传,检查密码";
/* No comment provided by engineer. */
"Server test failed!" = "服务器测试失败!";
@@ -2241,6 +2331,12 @@
/* No comment provided by engineer. */
"SimpleX Lock" = "SimpleX 锁定";
/* No comment provided by engineer. */
"SimpleX Lock mode" = "SimpleX 锁定模式";
/* No comment provided by engineer. */
"SimpleX Lock not enabled!" = "未启用 SimpleX 锁定!";
/* No comment provided by engineer. */
"SimpleX Lock turned on" = "已开启 SimpleX 锁定";
@@ -2289,12 +2385,18 @@
/* No comment provided by engineer. */
"strike" = "删去";
/* No comment provided by engineer. */
"Submit" = "提交";
/* No comment provided by engineer. */
"Support SimpleX Chat" = "支持 SimpleX Chat";
/* No comment provided by engineer. */
"System" = "系统";
/* No comment provided by engineer. */
"System authentication" = "系统认证";
/* No comment provided by engineer. */
"Take picture" = "拍照";
@@ -2502,9 +2604,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "除非您的联系人已删除此连接或此链接已被使用,否则它可能是一个错误——请报告。\n如果要连接,请让您的联系人创建另一个连接链接,并检查您的网络连接是否稳定。";
/* authentication reason */
/* No comment provided by engineer. */
"Unlock" = "解锁";
/* authentication reason */
"Unlock app" = "解锁应用程序";
/* No comment provided by engineer. */
"Unmute" = "取消静音";
@@ -2538,6 +2643,9 @@
/* No comment provided by engineer. */
"Upgrade and open chat" = "升级并打开聊天";
/* server test step */
"Upload file" = "上传文件";
/* No comment provided by engineer. */
"Use .onion hosts" = "使用 .onion 主机";
@@ -2598,6 +2706,12 @@
/* No comment provided by engineer. */
"video call (not e2e encrypted)" = "视频通话(非端到端加密)";
/* No comment provided by engineer. */
"Video will be received when your contact completes uploading it." = "视频将在您的联系人完成上传后收到。";
/* No comment provided by engineer. */
"Video will be received when your contact is online, please wait or check later!" = "视频将在您的联系人在线时收到,请稍等或稍后查看!";
/* No comment provided by engineer. */
"View security code" = "查看安全码";
@@ -2628,6 +2742,9 @@
/* No comment provided by engineer. */
"Waiting for image" = "等待图像中";
/* No comment provided by engineer. */
"Waiting for video" = "等待视频中";
/* No comment provided by engineer. */
"wants to connect to you!" = "想要与您连接!";
@@ -2718,6 +2835,9 @@
/* No comment provided by engineer. */
"You can start chat via app Settings / Database or by restarting the app" = "您可以通过应用程序设置/数据库或重新启动应用程序开始聊天";
/* No comment provided by engineer. */
"You can turn on SimpleX Lock via Settings." = "您可以通过设置开启 SimpleX 锁定。";
/* No comment provided by engineer. */
"You can use markdown to format messages:" = "您可以使用 markdown 来编排消息格式:";
+1 -1
View File
@@ -7,7 +7,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: 5e39c479758c8646ba2f943575bf9dca4212a2fe
tag: 9f0b9a83d6dfbd926daf09883a81bf370544f48e
source-repository-package
type: git
+1 -1
View File
@@ -2,7 +2,7 @@
set -e
langs=( cs de es fr it nl ru zh-Hans )
langs=( cs de es fr it nl pl ru zh-Hans )
for lang in "${langs[@]}"; do
echo "***"
+1 -1
View File
@@ -2,7 +2,7 @@
set -e
langs=( cs de es fr it nl ru zh-Hans )
langs=( cs de es fr it nl pl ru zh-Hans )
for lang in "${langs[@]}"; do
echo "***"
+1 -1
View File
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."5e39c479758c8646ba2f943575bf9dca4212a2fe" = "00i6w13zzv05gamxbas3yspq241s917f0vg2mnnwvmvqq2x5f4jq";
"https://github.com/simplex-chat/simplexmq.git"."9f0b9a83d6dfbd926daf09883a81bf370544f48e" = "1pnsk2qzb10d3j7rxjqvbwirymky5d55b13y3a6mwj7qbgzzqcy9";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/kazu-yamamoto/http2.git"."b5a1b7200cf5bc7044af34ba325284271f6dff25" = "0dqb50j57an64nf4qcf5vcz4xkd1vzvghvf8bk529c1k30r9nfzb";
"https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd";
+33 -18
View File
@@ -60,9 +60,9 @@ import Simplex.Chat.Store
import Simplex.Chat.Types
import Simplex.FileTransfer.Client.Presets (defaultXFTPServers)
import Simplex.FileTransfer.Description (ValidFileDescription, gb, kb, mb)
import Simplex.FileTransfer.Protocol (FileParty (..))
import Simplex.FileTransfer.Protocol (FileParty (..), FilePartyI)
import Simplex.Messaging.Agent as Agent
import Simplex.Messaging.Agent.Client (AgentStatsKey (..))
import Simplex.Messaging.Agent.Client (AgentStatsKey (..), temporaryAgentError)
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig (..), InitialAgentServers (..), createAgentStore, defaultAgentConfig)
import Simplex.Messaging.Agent.Lock
import Simplex.Messaging.Agent.Protocol
@@ -1467,7 +1467,7 @@ processChatCommand = \case
p {groupPreferences = Just . setGroupPreference' SGFTimedMessages pref $ groupPreferences p}
QuitChat -> liftIO exitSuccess
ShowVersion -> do
let versionInfo = coreVersionInfo $(buildTimestampQ) $(simplexmqCommitQ)
let versionInfo = coreVersionInfo $(simplexmqCommitQ)
chatMigrations <- map upMigration <$> withStore' Migrations.getCurrent
agentMigrations <- withAgent getAgentMigrations
pure $ CRVersionInfo {versionInfo, chatMigrations, agentMigrations}
@@ -1961,7 +1961,7 @@ acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileI
receiveViaCompleteFD :: ChatMonad m => User -> FileTransferId -> RcvFileDescr -> m ()
receiveViaCompleteFD user fileId RcvFileDescr {fileDescrText, fileDescrComplete} =
when fileDescrComplete $ do
rd <- parseRcvFileDescription fileDescrText
rd <- parseFileDescription fileDescrText
aFileId <- withAgent $ \a -> xftpReceiveFile a (aUserId user) rd
startReceivingFile user fileId
withStore' $ \db -> updateRcvFileAgentId db fileId (Just $ AgentRcvFileId aFileId)
@@ -2335,9 +2335,9 @@ processAgentMsgSndFile _corrId aFileId msg =
liftIO $ updateCIFileStatus db user fileId status
getChatItemByFileId db user fileId
toView $ CRSndFileProgressXFTP user ci ft sndProgress sndTotal
SFDONE _sndDescr rfds ->
SFDONE sndDescr rfds ->
unless cancelled $ do
-- TODO save sender file description
withStore' $ \db -> setSndFTPrivateSndDescr db user fileId (fileDescrText sndDescr)
ci@(AChatItem _ d cInfo _ci@ChatItem {meta = CIMeta {itemSharedMsgId = msgId_, itemDeleted}}) <-
withStore $ \db -> getChatItemByFileId db user fileId
case (msgId_, itemDeleted) of
@@ -2350,6 +2350,7 @@ processAgentMsgSndFile _corrId aFileId msg =
withStore' $ \db -> createExtraSndFTDescrs db user fileId (map fileDescrText extraRFDs)
msgDeliveryId <- sendFileDescription sft rfd sharedMsgId $ sendDirectContactMessage ct
withStore' $ \db -> updateSndFTDeliveryXFTP db sft msgDeliveryId
agentXFTPDeleteSndFileInternal user aFileId
(_, _, SMDSnd, GroupChat g@GroupInfo {groupId}) -> do
ms <- withStore' $ \db -> getGroupMembers db user g
let rfdsMemberFTs = zip rfds $ memberFTs ms
@@ -2359,6 +2360,7 @@ processAgentMsgSndFile _corrId aFileId msg =
ci' <- withStore $ \db -> do
liftIO $ updateCIFileStatus db user fileId CIFSSndComplete
getChatItemByFileId db user fileId
agentXFTPDeleteSndFileInternal user aFileId
toView $ CRSndFileCompleteXFTP user ci' ft
where
memberFTs :: [GroupMember] -> [(Connection, SndFileTransfer)]
@@ -2376,11 +2378,13 @@ processAgentMsgSndFile _corrId aFileId msg =
_ -> pure ()
_ -> pure () -- TODO error?
SFERR e -> do
-- update chat item status
-- send status to view
-- agentXFTPDeleteSndFile
unless (temporaryAgentError e) $ do
-- update chat item status
-- send status to view
agentXFTPDeleteSndFileInternal user aFileId
throwChatError $ CEXFTPSndFile fileId (AgentSndFileId aFileId) e
where
fileDescrText :: FilePartyI p => ValidFileDescription p -> T.Text
fileDescrText = safeDecodeUtf8 . strEncode
sendFileDescription :: SndFileTransfer -> ValidFileDescription 'FRecipient -> SharedMsgId -> (ChatMsgEvent 'Json -> m (SndMessage, Int64)) -> m Int64
sendFileDescription sft rfd msgId sendMsg = do
@@ -2432,9 +2436,10 @@ processAgentMsgRcvFile _corrId aFileId msg =
agentXFTPDeleteRcvFile user aFileId fileId
toView $ CRRcvFileComplete user ci
RFERR e -> do
-- update chat item status
-- send status to view
agentXFTPDeleteRcvFile user aFileId fileId
unless (temporaryAgentError e) $ do
-- update chat item status
-- send status to view
agentXFTPDeleteRcvFile user aFileId fileId
throwChatError $ CEXFTPRcvFile fileId (AgentRcvFileId aFileId) e
processAgentMessageConn :: forall m. ChatMonad m => User -> ACorrId -> ConnId -> ACommand 'Agent 'AEConn -> m ()
@@ -3810,8 +3815,8 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do
groupMsgToView g' m ci msgMeta
createGroupFeatureChangedItems user cd CIRcvGroupFeature g g'
parseRcvFileDescription :: ChatMonad m => Text -> m (ValidFileDescription 'FRecipient)
parseRcvFileDescription =
parseFileDescription :: (ChatMonad m, FilePartyI p) => Text -> m (ValidFileDescription p)
parseFileDescription =
liftEither . first (ChatError . CEInvalidFileDescription) . (strDecode . encodeUtf8)
sendDirectFileInline :: ChatMonad m => Contact -> FileTransferMeta -> SharedMsgId -> m ()
@@ -3939,11 +3944,9 @@ cancelSndFile user FileTransferMeta {fileId, xftpSndFile} fts sendCancel = do
case xftpSndFile of
Nothing ->
catMaybes <$> forM fts (\ft -> cancelSndFileTransfer user ft sendCancel)
Just _patternAgentSndFileId -> do
Just xsf -> do
forM_ fts (\ft -> cancelSndFileTransfer user ft False)
-- TODO unless agentSndFileDeleted, do agentXFTPDeleteSndFile:
-- TODO - with agent xftpDeleteSndFile
-- TODO - with store setSndFTAgentDeleted
agentXFTPDeleteSndFileRemote user xsf fileId `catchError` (toView . CRChatError (Just user))
pure []
cancelSndFileTransfer :: ChatMonad m => User -> SndFileTransfer -> Bool -> m (Maybe ConnId)
@@ -4192,6 +4195,18 @@ agentXFTPDeleteRcvFile user aFileId fileId = do
withAgent $ \a -> xftpDeleteRcvFile a (aUserId user) aFileId
withStore' $ \db -> setRcvFTAgentDeleted db fileId
agentXFTPDeleteSndFileInternal :: ChatMonad m => User -> SndFileId -> m ()
agentXFTPDeleteSndFileInternal user aFileId = do
withAgent (\a -> xftpDeleteSndFileInternal a (aUserId user) aFileId) `catchError` (toView . CRChatError (Just user))
agentXFTPDeleteSndFileRemote :: ChatMonad m => User -> XFTPSndFile -> FileTransferId -> m ()
agentXFTPDeleteSndFileRemote user XFTPSndFile {agentSndFileId = AgentSndFileId aFileId, privateSndFileDescr, agentSndFileDeleted} fileId =
unless agentSndFileDeleted $
forM_ privateSndFileDescr $ \sfdText -> do
sd <- parseFileDescription sfdText
withAgent $ \a -> xftpDeleteSndFileRemote a (aUserId user) aFileId sd
withStore' $ \db -> setSndFTAgentDeleted db user fileId
userProfileToSend :: User -> Maybe Profile -> Maybe Contact -> Profile
userProfileToSend user@User {profile = p} incognitoProfile ct =
let p' = fromMaybe (fromLocalProfile p) incognitoProfile
+3 -11
View File
@@ -33,8 +33,7 @@ import Data.Map.Strict (Map)
import Data.String
import Data.Text (Text)
import Data.Time (ZonedTime)
import Data.Time.Clock (UTCTime, getCurrentTime)
import Data.Time.Format (defaultTimeLocale, formatTime, iso8601DateFormat)
import Data.Time.Clock (UTCTime)
import Data.Version (showVersion)
import GHC.Generics (Generic)
import Language.Haskell.TH (Exp, Q, runIO)
@@ -73,11 +72,6 @@ versionString version = "SimpleX Chat v" <> version
updateStr :: String
updateStr = "To update run: curl -o- https://raw.githubusercontent.com/simplex-chat/simplex-chat/master/install.sh | bash"
buildTimestampQ :: Q Exp
buildTimestampQ = do
s <- formatTime defaultTimeLocale (iso8601DateFormat $ Just "%H:%M:%S") <$> runIO getCurrentTime
[|fromString s|]
simplexmqCommitQ :: Q Exp
simplexmqCommitQ = do
s <- either error B.unpack . A.parseOnly commitHashP <$> runIO (B.readFile "./cabal.project")
@@ -92,11 +86,10 @@ simplexmqCommitQ = do
*> "tag: "
*> A.takeWhile (A.notInClass " \r\n")
coreVersionInfo :: String -> String -> CoreVersionInfo
coreVersionInfo buildTimestamp simplexmqCommit =
coreVersionInfo :: String -> CoreVersionInfo
coreVersionInfo simplexmqCommit =
CoreVersionInfo
{ version = versionNumber,
buildTimestamp,
simplexmqVersion = simplexMQVersion,
simplexmqCommit
}
@@ -724,7 +717,6 @@ data ChatLogLevel = CLLDebug | CLLInfo | CLLWarning | CLLError | CLLImportant
data CoreVersionInfo = CoreVersionInfo
{ version :: String,
buildTimestamp :: String,
simplexmqVersion :: String,
simplexmqCommit :: String
}
+23 -5
View File
@@ -159,9 +159,11 @@ module Simplex.Chat.Store
getSndFTViaMsgDelivery,
createSndFileTransferXFTP,
createSndFTDescrXFTP,
setSndFTPrivateSndDescr,
updateSndFTDescrXFTP,
createExtraSndFTDescrs,
updateSndFTDeliveryXFTP,
setSndFTAgentDeleted,
getXFTPSndFileDBId,
getXFTPRcvFileDBId,
updateFileCancelled,
@@ -2789,7 +2791,7 @@ getSndFTViaMsgDelivery db User {userId} Connection {connId, agentConnId} agentMs
createSndFileTransferXFTP :: DB.Connection -> User -> ContactOrGroup -> FilePath -> FileInvitation -> AgentSndFileId -> Integer -> IO FileTransferMeta
createSndFileTransferXFTP db User {userId} contactOrGroup filePath FileInvitation {fileName, fileSize} agentSndFileId chunkSize = do
currentTs <- getCurrentTime
let xftpSndFile = Just XFTPSndFile {agentSndFileId, privateSndFileDescr = Nothing}
let xftpSndFile = Just XFTPSndFile {agentSndFileId, privateSndFileDescr = Nothing, agentSndFileDeleted = False}
DB.execute
db
"INSERT INTO files (contact_id, group_id, user_id, file_name, file_path, file_size, chunk_size, agent_snd_file_id, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"
@@ -2811,6 +2813,14 @@ createSndFTDescrXFTP db User {userId} m Connection {connId} FileTransferMeta {fi
"INSERT INTO snd_files (file_id, file_status, file_descr_id, group_member_id, connection_id, created_at, updated_at) VALUES (?,?,?,?,?,?,?)"
(fileId, fileStatus, fileDescrId, groupMemberId' <$> m, connId, currentTs, currentTs)
setSndFTPrivateSndDescr :: DB.Connection -> User -> FileTransferId -> Text -> IO ()
setSndFTPrivateSndDescr db User {userId} fileId sfdText = do
currentTs <- getCurrentTime
DB.execute
db
"UPDATE files SET private_snd_file_descr = ?, updated_at = ? WHERE user_id = ? AND file_id = ?"
(sfdText, currentTs, userId, fileId)
updateSndFTDescrXFTP :: DB.Connection -> User -> SndFileTransfer -> Text -> IO ()
updateSndFTDescrXFTP db user@User {userId} sft@SndFileTransfer {fileId, fileDescrId} rfdText = do
currentTs <- getCurrentTime
@@ -2841,6 +2851,14 @@ updateSndFTDeliveryXFTP db SndFileTransfer {connId, fileId, fileDescrId} msgDeli
"UPDATE snd_files SET last_inline_msg_delivery_id = ? WHERE connection_id = ? AND file_id = ? AND file_descr_id = ?"
(msgDeliveryId, connId, fileId, fileDescrId)
setSndFTAgentDeleted :: DB.Connection -> User -> FileTransferId -> IO ()
setSndFTAgentDeleted db User {userId} fileId = do
currentTs <- getCurrentTime
DB.execute
db
"UPDATE files SET agent_snd_file_deleted = 1, updated_at = ? WHERE user_id = ? AND file_id = ?"
(currentTs, userId, fileId)
getXFTPSndFileDBId :: DB.Connection -> User -> AgentSndFileId -> ExceptT StoreError IO FileTransferId
getXFTPSndFileDBId db User {userId} aSndFileId =
ExceptT . firstRow fromOnly (SESndFileNotFoundXFTP aSndFileId) $
@@ -3330,15 +3348,15 @@ getFileTransferMeta db User {userId} fileId =
DB.query
db
[sql|
SELECT file_name, file_size, chunk_size, file_path, file_inline, agent_snd_file_id, private_snd_file_descr, cancelled
SELECT file_name, file_size, chunk_size, file_path, file_inline, agent_snd_file_id, agent_snd_file_deleted, private_snd_file_descr, cancelled
FROM files
WHERE user_id = ? AND file_id = ?
|]
(userId, fileId)
where
fileTransferMeta :: (String, Integer, Integer, FilePath, Maybe InlineFileMode, Maybe AgentSndFileId, Maybe Text, Maybe Bool) -> FileTransferMeta
fileTransferMeta (fileName, fileSize, chunkSize, filePath, fileInline, aSndFileId_, privateSndFileDescr, cancelled_) =
let xftpSndFile = (\fId -> XFTPSndFile {agentSndFileId = fId, privateSndFileDescr}) <$> aSndFileId_
fileTransferMeta :: (String, Integer, Integer, FilePath, Maybe InlineFileMode, Maybe AgentSndFileId, Bool, Maybe Text, Maybe Bool) -> FileTransferMeta
fileTransferMeta (fileName, fileSize, chunkSize, filePath, fileInline, aSndFileId_, agentSndFileDeleted, privateSndFileDescr, cancelled_) =
let xftpSndFile = (\fId -> XFTPSndFile {agentSndFileId = fId, privateSndFileDescr, agentSndFileDeleted}) <$> aSndFileId_
in FileTransferMeta {fileId, xftpSndFile, fileName, fileSize, chunkSize, filePath, fileInline, cancelled = fromMaybe False cancelled_}
getContactFileInfo :: DB.Connection -> User -> Contact -> IO [CIFileInfo]
+2 -2
View File
@@ -1737,8 +1737,8 @@ instance ToJSON FileTransferMeta where toEncoding = J.genericToEncoding J.defaul
data XFTPSndFile = XFTPSndFile
{ agentSndFileId :: AgentSndFileId,
privateSndFileDescr :: Maybe Text
-- TODO agentSndFileDeleted :: Bool
privateSndFileDescr :: Maybe Text,
agentSndFileDeleted :: Bool
}
deriving (Eq, Show, Generic)
+2 -2
View File
@@ -1240,10 +1240,10 @@ instance ToJSON WCallCommand where
toJSON = J.genericToJSON . taggedObjectJSON $ dropPrefix "WCCall"
viewVersionInfo :: ChatLogLevel -> CoreVersionInfo -> [StyledString]
viewVersionInfo logLevel CoreVersionInfo {version, buildTimestamp, simplexmqVersion, simplexmqCommit} =
viewVersionInfo logLevel CoreVersionInfo {version, simplexmqVersion, simplexmqCommit} =
map plain $
if logLevel <= CLLInfo
then [versionString version <> parens buildTimestamp, updateStr, "simplexmq: " <> simplexmqVersion <> parens simplexmqCommit]
then [versionString version, updateStr, "simplexmq: " <> simplexmqVersion <> parens simplexmqCommit]
else [versionString version, updateStr]
where
parens s = " (" <> s <> ")"
+1 -1
View File
@@ -49,7 +49,7 @@ extra-deps:
# - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561
# - ../simplexmq
- github: simplex-chat/simplexmq
commit: 5e39c479758c8646ba2f943575bf9dca4212a2fe
commit: 9f0b9a83d6dfbd926daf09883a81bf370544f48e
- github: kazu-yamamoto/http2
commit: b5a1b7200cf5bc7044af34ba325284271f6dff25
# - ../direct-sqlcipher
+6 -1
View File
@@ -1 +1,6 @@
{}
{
"home": "Início",
"developers": "Desenvolvedores",
"reference": "Referência",
"blog": "Blog"
}