Merge branch 'master' into xftp

This commit is contained in:
Evgeny Poberezkin 2023-03-27 18:57:14 +01:00
commit 1f15cf54af
112 changed files with 7406 additions and 989 deletions

1
.gitignore vendored
View file

@ -75,3 +75,4 @@ website/package-lock.json
# Ignore test files # Ignore test files
website/.cache website/.cache
website/test/stubs-layout-cache/_includes/*.js website/test/stubs-layout-cache/_includes/*.js
apps/android/app/release

View file

@ -9,15 +9,12 @@ android {
defaultConfig { defaultConfig {
applicationId "chat.simplex.app" applicationId "chat.simplex.app"
minSdk 29 minSdk 26
targetSdk 32 targetSdk 32
versionCode 105 versionCode 107
versionName "4.6-beta.1" versionName "4.6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'arm64-v8a'
}
vectorDrawables { vectorDrawables {
useSupportLibrary true useSupportLibrary true
} }
@ -77,10 +74,27 @@ android {
jniLibs.useLegacyPackaging = compression_level != "0" jniLibs.useLegacyPackaging = compression_level != "0"
} }
def isRelease = gradle.getStartParameter().taskNames.find({ it.toLowerCase().contains("release") }) != null def isRelease = gradle.getStartParameter().taskNames.find({ it.toLowerCase().contains("release") }) != null
def isBundle = gradle.getStartParameter().taskNames.find({ it.toLowerCase().contains("bundle") }) != null
// if (isRelease) { // if (isRelease) {
// Comma separated list of languages that will be included in the apk // 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", "ru", "zh-rCN")
// } // }
if (isBundle) {
defaultConfig.ndk.abiFilters 'arm64-v8a', 'armeabi-v7a'
} else {
splits {
abi {
enable true
reset()
if (isRelease) {
include 'arm64-v8a', 'armeabi-v7a'
} else {
include 'arm64-v8a', 'armeabi-v7a'
universalApk false
}
}
}
}
} }
dependencies { dependencies {
@ -196,6 +210,8 @@ tasks.register("compressApk") {
if (project.properties['android.injected.signing.key.alias'] != null && buildType == 'release') { if (project.properties['android.injected.signing.key.alias'] != null && buildType == 'release') {
new File(outputDir, "app-release.apk").renameTo(new File(outputDir, "simplex.apk")) new File(outputDir, "app-release.apk").renameTo(new File(outputDir, "simplex.apk"))
new File(outputDir, "app-armeabi-v7a-release.apk").renameTo(new File(outputDir, "simplex-armv7a.apk"))
new File(outputDir, "app-arm64-v8a-release.apk").renameTo(new File(outputDir, "simplex.apk"))
} }
// View all gradle properties set // View all gradle properties set

View file

@ -53,10 +53,6 @@ add_library( support SHARED IMPORTED )
set_target_properties( support PROPERTIES IMPORTED_LOCATION set_target_properties( support PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libsupport.so) ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libsupport.so)
add_library( crypto SHARED IMPORTED )
set_target_properties( crypto PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcrypto.so)
# Specifies libraries CMake should link to your target library. You # Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this # can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries. # build script, prebuilt third-party libraries, or system libraries.
@ -64,7 +60,7 @@ set_target_properties( crypto PROPERTIES IMPORTED_LOCATION
target_link_libraries( # Specifies the target library. target_link_libraries( # Specifies the target library.
app-lib app-lib
simplex support crypto simplex support
# Links the target library to the log library # Links the target library to the log library
# included in the NDK. # included in the NDK.

View file

@ -7,6 +7,17 @@ void hs_init(int * argc, char **argv[]);
void setLineBuffering(void); void setLineBuffering(void);
int pipe_std_to_socket(const char * name); int pipe_std_to_socket(const char * name);
extern void __svfscanf(void){};
extern void __vfwscanf(void){};
extern void __memset_chk_fail(void){};
extern void __strcpy_chk_generic(void){};
extern void __strcat_chk_generic(void){};
extern void __libc_globals(void){};
extern void __rel_iplt_start(void){};
// Android 9 only, not 13
extern void reallocarray(void){};
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_chat_simplex_app_SimplexAppKt_pipeStdOutToSocket(JNIEnv *env, __unused jclass clazz, jstring socket_name) { Java_chat_simplex_app_SimplexAppKt_pipeStdOutToSocket(JNIEnv *env, __unused jclass clazz, jstring socket_name) {
const char *name = (*env)->GetStringUTFChars(env, socket_name, JNI_FALSE); const char *name = (*env)->GetStringUTFChars(env, socket_name, JNI_FALSE);
@ -30,6 +41,7 @@ extern char *chat_recv_msg(chat_ctrl ctrl); // deprecated
extern char *chat_recv_msg_wait(chat_ctrl ctrl, const int wait); extern char *chat_recv_msg_wait(chat_ctrl ctrl, const int wait);
extern char *chat_parse_markdown(const char *str); extern char *chat_parse_markdown(const char *str);
extern char *chat_parse_server(const char *str); extern char *chat_parse_server(const char *str);
extern char *chat_password_hash(const char *pwd, const char *salt);
JNIEXPORT jobjectArray JNICALL JNIEXPORT jobjectArray JNICALL
Java_chat_simplex_app_SimplexAppKt_chatMigrateInit(JNIEnv *env, __unused jclass clazz, jstring dbPath, jstring dbKey) { Java_chat_simplex_app_SimplexAppKt_chatMigrateInit(JNIEnv *env, __unused jclass clazz, jstring dbPath, jstring dbKey) {
@ -85,3 +97,13 @@ Java_chat_simplex_app_SimplexAppKt_chatParseServer(JNIEnv *env, __unused jclass
(*env)->ReleaseStringUTFChars(env, str, _str); (*env)->ReleaseStringUTFChars(env, str, _str);
return res; return res;
} }
JNIEXPORT jstring JNICALL
Java_chat_simplex_app_SimplexAppKt_chatPasswordHash(JNIEnv *env, __unused jclass clazz, jstring pwd, jstring salt) {
const char *_pwd = (*env)->GetStringUTFChars(env, pwd, JNI_FALSE);
const char *_salt = (*env)->GetStringUTFChars(env, salt, JNI_FALSE);
jstring res = (*env)->NewStringUTF(env, chat_password_hash(_pwd, _salt));
(*env)->ReleaseStringUTFChars(env, pwd, _pwd);
(*env)->ReleaseStringUTFChars(env, salt, _salt);
return res;
}

View file

@ -402,7 +402,7 @@ fun processNotificationIntent(intent: Intent?, chatModel: ChatModel) {
if (chatId != null) { if (chatId != null) {
withBGApi { withBGApi {
if (userId != null && userId != chatModel.currentUser.value?.userId) { if (userId != null && userId != chatModel.currentUser.value?.userId) {
chatModel.controller.changeActiveUser(userId) chatModel.controller.changeActiveUser(userId, null)
} }
val cInfo = chatModel.getChat(chatId)?.chatInfo val cInfo = chatModel.getChat(chatId)?.chatInfo
chatModel.clearOverlays.value = true chatModel.clearOverlays.value = true
@ -414,7 +414,7 @@ fun processNotificationIntent(intent: Intent?, chatModel: ChatModel) {
Log.d(TAG, "processNotificationIntent: ShowChatsAction") Log.d(TAG, "processNotificationIntent: ShowChatsAction")
withBGApi { withBGApi {
if (userId != null && userId != chatModel.currentUser.value?.userId) { if (userId != null && userId != chatModel.currentUser.value?.userId) {
chatModel.controller.changeActiveUser(userId) chatModel.controller.changeActiveUser(userId, null)
} }
chatModel.chatId.value = null chatModel.chatId.value = null
chatModel.clearOverlays.value = true chatModel.clearOverlays.value = true

View file

@ -32,6 +32,7 @@ external fun chatRecvMsg(ctrl: ChatCtrl): String
external fun chatRecvMsgWait(ctrl: ChatCtrl, timeout: Int): String external fun chatRecvMsgWait(ctrl: ChatCtrl, timeout: Int): String
external fun chatParseMarkdown(str: String): String external fun chatParseMarkdown(str: String): String
external fun chatParseServer(str: String): String external fun chatParseServer(str: String): String
external fun chatPasswordHash(pwd: String, salt: String): String
class SimplexApp: Application(), LifecycleEventObserver { class SimplexApp: Application(), LifecycleEventObserver {
lateinit var chatController: ChatController lateinit var chatController: ChatController

View file

@ -94,6 +94,32 @@ class ChatModel(val controller: ChatController) {
val filesToDelete = mutableSetOf<File>() val filesToDelete = mutableSetOf<File>()
val simplexLinkMode = mutableStateOf(controller.appPrefs.simplexLinkMode.get()) val simplexLinkMode = mutableStateOf(controller.appPrefs.simplexLinkMode.get())
fun getUser(userId: Long): User? = if (currentUser.value?.userId == userId) {
currentUser.value
} else {
users.firstOrNull { it.user.userId == userId }?.user
}
private fun getUserIndex(user: User): Int =
users.indexOfFirst { it.user.userId == user.userId }
fun updateUser(user: User) {
val i = getUserIndex(user)
if (i != -1) {
users[i] = users[i].copy(user = user)
}
if (currentUser.value?.userId == user.userId) {
currentUser.value = user
}
}
fun removeUser(user: User) {
val i = getUserIndex(user)
if (i != -1 && users[i].user.userId != currentUser.value?.userId) {
users.removeAt(i)
}
}
fun hasChat(id: String): Boolean = chats.firstOrNull { it.id == id } != null fun hasChat(id: String): Boolean = chats.firstOrNull { it.id == id } != null
fun getChat(id: String): Chat? = chats.firstOrNull { it.id == id } fun getChat(id: String): Chat? = chats.firstOrNull { it.id == id }
fun getContactChat(contactId: Long): Chat? = chats.firstOrNull { it.chatInfo is ChatInfo.Direct && it.chatInfo.apiId == contactId } fun getContactChat(contactId: Long): Chat? = chats.firstOrNull { it.chatInfo is ChatInfo.Direct && it.chatInfo.apiId == contactId }
@ -422,13 +448,19 @@ data class User(
val localDisplayName: String, val localDisplayName: String,
val profile: LocalProfile, val profile: LocalProfile,
val fullPreferences: FullChatPreferences, val fullPreferences: FullChatPreferences,
val activeUser: Boolean val activeUser: Boolean,
val showNtfs: Boolean,
val viewPwdHash: UserPwdHash?
): NamedChat { ): NamedChat {
override val displayName: String get() = profile.displayName override val displayName: String get() = profile.displayName
override val fullName: String get() = profile.fullName override val fullName: String get() = profile.fullName
override val image: String? get() = profile.image override val image: String? get() = profile.image
override val localAlias: String = "" override val localAlias: String = ""
val hidden: Boolean = viewPwdHash != null
val showNotifications: Boolean = activeUser || showNtfs
companion object { companion object {
val sampleData = User( val sampleData = User(
userId = 1, userId = 1,
@ -436,11 +468,19 @@ data class User(
localDisplayName = "alice", localDisplayName = "alice",
profile = LocalProfile.sampleData, profile = LocalProfile.sampleData,
fullPreferences = FullChatPreferences.sampleData, fullPreferences = FullChatPreferences.sampleData,
activeUser = true activeUser = true,
showNtfs = true,
viewPwdHash = null,
) )
} }
} }
@Serializable
data class UserPwdHash(
val hash: String,
val salt: String
)
@Serializable @Serializable
data class UserInfo( data class UserInfo(
val user: User, val user: User,

View file

@ -80,7 +80,7 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
} }
fun notifyContactRequestReceived(user: User, cInfo: ChatInfo.ContactRequest) { fun notifyContactRequestReceived(user: User, cInfo: ChatInfo.ContactRequest) {
notifyMessageReceived( displayNotification(
user = user, user = user,
chatId = cInfo.id, chatId = cInfo.id,
displayName = cInfo.displayName, displayName = cInfo.displayName,
@ -91,7 +91,7 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
} }
fun notifyContactConnected(user: User, contact: Contact) { fun notifyContactConnected(user: User, contact: Contact) {
notifyMessageReceived( displayNotification(
user = user, user = user,
chatId = contact.id, chatId = contact.id,
displayName = contact.displayName, displayName = contact.displayName,
@ -101,11 +101,11 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
fun notifyMessageReceived(user: User, cInfo: ChatInfo, cItem: ChatItem) { fun notifyMessageReceived(user: User, cInfo: ChatInfo, cItem: ChatItem) {
if (!cInfo.ntfsEnabled) return if (!cInfo.ntfsEnabled) return
displayNotification(user = user, chatId = cInfo.id, displayName = cInfo.displayName, msgText = hideSecrets(cItem))
notifyMessageReceived(user = user, chatId = cInfo.id, displayName = cInfo.displayName, msgText = hideSecrets(cItem))
} }
fun notifyMessageReceived(user: User, chatId: String, displayName: String, msgText: String, image: String? = null, actions: List<NotificationAction> = emptyList()) { fun displayNotification(user: User, chatId: String, displayName: String, msgText: String, image: String? = null, actions: List<NotificationAction> = emptyList()) {
if (!user.showNotifications) return
Log.d(TAG, "notifyMessageReceived $chatId") Log.d(TAG, "notifyMessageReceived $chatId")
val now = Clock.System.now().toEpochMilliseconds() val now = Clock.System.now().toEpochMilliseconds()
val recentNotification = (now - prevNtfTime.getOrDefault(chatId, 0) < msgNtfTimeoutMs) val recentNotification = (now - prevNtfTime.getOrDefault(chatId, 0) < msgNtfTimeoutMs)

View file

@ -133,6 +133,8 @@ class AppPreferences(val context: Context) {
val incognito = mkBoolPreference(SHARED_PREFS_INCOGNITO, false) val incognito = mkBoolPreference(SHARED_PREFS_INCOGNITO, false)
val connectViaLinkTab = mkStrPreference(SHARED_PREFS_CONNECT_VIA_LINK_TAB, ConnectViaLinkTab.SCAN.name) val connectViaLinkTab = mkStrPreference(SHARED_PREFS_CONNECT_VIA_LINK_TAB, ConnectViaLinkTab.SCAN.name)
val liveMessageAlertShown = mkBoolPreference(SHARED_PREFS_LIVE_MESSAGE_ALERT_SHOWN, false) val liveMessageAlertShown = mkBoolPreference(SHARED_PREFS_LIVE_MESSAGE_ALERT_SHOWN, false)
val showHiddenProfilesNotice = mkBoolPreference(SHARED_PREFS_SHOW_HIDDEN_PROFILES_NOTICE, true)
val showMuteProfileAlert = mkBoolPreference(SHARED_PREFS_SHOW_MUTE_PROFILE_ALERT, true)
val appLanguage = mkStrPreference(SHARED_PREFS_APP_LANGUAGE, null) val appLanguage = mkStrPreference(SHARED_PREFS_APP_LANGUAGE, null)
val storeDBPassphrase = mkBoolPreference(SHARED_PREFS_STORE_DB_PASSPHRASE, true) val storeDBPassphrase = mkBoolPreference(SHARED_PREFS_STORE_DB_PASSPHRASE, true)
@ -235,6 +237,8 @@ class AppPreferences(val context: Context) {
private const val SHARED_PREFS_INCOGNITO = "Incognito" private const val SHARED_PREFS_INCOGNITO = "Incognito"
private const val SHARED_PREFS_CONNECT_VIA_LINK_TAB = "ConnectViaLinkTab" private const val SHARED_PREFS_CONNECT_VIA_LINK_TAB = "ConnectViaLinkTab"
private const val SHARED_PREFS_LIVE_MESSAGE_ALERT_SHOWN = "LiveMessageAlertShown" private const val SHARED_PREFS_LIVE_MESSAGE_ALERT_SHOWN = "LiveMessageAlertShown"
private const val SHARED_PREFS_SHOW_HIDDEN_PROFILES_NOTICE = "ShowHiddenProfilesNotice"
private const val SHARED_PREFS_SHOW_MUTE_PROFILE_ALERT = "ShowMuteProfileAlert"
private const val SHARED_PREFS_STORE_DB_PASSPHRASE = "StoreDBPassphrase" private const val SHARED_PREFS_STORE_DB_PASSPHRASE = "StoreDBPassphrase"
private const val SHARED_PREFS_INITIAL_RANDOM_DB_PASSPHRASE = "InitialRandomDBPassphrase" private const val SHARED_PREFS_INITIAL_RANDOM_DB_PASSPHRASE = "InitialRandomDBPassphrase"
private const val SHARED_PREFS_ENCRYPTED_DB_PASSPHRASE = "EncryptedDBPassphrase" private const val SHARED_PREFS_ENCRYPTED_DB_PASSPHRASE = "EncryptedDBPassphrase"
@ -264,6 +268,16 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
chatModel.incognito.value = appPrefs.incognito.get() chatModel.incognito.value = appPrefs.incognito.get()
} }
private fun currentUserId(funcName: String): Long {
val userId = chatModel.currentUser.value?.userId
if (userId == null) {
val error = "$funcName: no current user"
Log.e(TAG, error)
throw Exception(error)
}
return userId
}
suspend fun startChat(user: User) { suspend fun startChat(user: User) {
Log.d(TAG, "user: $user") Log.d(TAG, "user: $user")
try { try {
@ -297,21 +311,26 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
} }
suspend fun changeActiveUser(toUserId: Long) { suspend fun changeActiveUser(toUserId: Long, viewPwd: String?) {
try { try {
changeActiveUser_(toUserId) changeActiveUser_(toUserId, viewPwd)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Unable to set active user: ${e.stackTraceToString()}") Log.e(TAG, "Unable to set active user: ${e.stackTraceToString()}")
AlertManager.shared.showAlertMsg(generalGetString(R.string.failed_to_active_user_title), e.stackTraceToString()) AlertManager.shared.showAlertMsg(generalGetString(R.string.failed_to_active_user_title), e.stackTraceToString())
} }
} }
suspend fun changeActiveUser_(toUserId: Long) { suspend fun changeActiveUser_(toUserId: Long, viewPwd: String?) {
chatModel.currentUser.value = apiSetActiveUser(toUserId) val currentUser = apiSetActiveUser(toUserId, viewPwd)
chatModel.currentUser.value = currentUser
val users = listUsers() val users = listUsers()
chatModel.users.clear() chatModel.users.clear()
chatModel.users.addAll(users) chatModel.users.addAll(users)
getUserChatData() getUserChatData()
val invitation = chatModel.callInvitations.values.firstOrNull { inv -> inv.user.userId == toUserId }
if (invitation != null) {
chatModel.callManager.reportNewIncomingCall(invitation.copy(user = currentUser))
}
} }
suspend fun getUserChatData() { suspend fun getUserChatData() {
@ -408,15 +427,33 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
throw Exception("failed to list users ${r.responseType} ${r.details}") throw Exception("failed to list users ${r.responseType} ${r.details}")
} }
suspend fun apiSetActiveUser(userId: Long): User { suspend fun apiSetActiveUser(userId: Long, viewPwd: String?): User {
val r = sendCmd(CC.ApiSetActiveUser(userId)) val r = sendCmd(CC.ApiSetActiveUser(userId, viewPwd))
if (r is CR.ActiveUser) return r.user if (r is CR.ActiveUser) return r.user
Log.d(TAG, "apiSetActiveUser: ${r.responseType} ${r.details}") Log.d(TAG, "apiSetActiveUser: ${r.responseType} ${r.details}")
throw Exception("failed to set the user as active ${r.responseType} ${r.details}") throw Exception("failed to set the user as active ${r.responseType} ${r.details}")
} }
suspend fun apiDeleteUser(userId: Long, delSMPQueues: Boolean) { suspend fun apiHideUser(userId: Long, viewPwd: String): User =
val r = sendCmd(CC.ApiDeleteUser(userId, delSMPQueues)) setUserPrivacy(CC.ApiHideUser(userId, viewPwd))
suspend fun apiUnhideUser(userId: Long, viewPwd: String?): User =
setUserPrivacy(CC.ApiUnhideUser(userId, viewPwd))
suspend fun apiMuteUser(userId: Long, viewPwd: String?): User =
setUserPrivacy(CC.ApiMuteUser(userId, viewPwd))
suspend fun apiUnmuteUser(userId: Long, viewPwd: String?): User =
setUserPrivacy(CC.ApiUnmuteUser(userId, viewPwd))
private suspend fun setUserPrivacy(cmd: CC): User {
val r = sendCmd(cmd)
if (r is CR.UserPrivacy) return r.user
else throw Exception("Failed to change user privacy: ${r.responseType} ${r.details}")
}
suspend fun apiDeleteUser(userId: Long, delSMPQueues: Boolean, viewPwd: String?) {
val r = sendCmd(CC.ApiDeleteUser(userId, delSMPQueues, viewPwd))
if (r is CR.CmdOk) return if (r is CR.CmdOk) return
Log.d(TAG, "apiDeleteUser: ${r.responseType} ${r.details}") Log.d(TAG, "apiDeleteUser: ${r.responseType} ${r.details}")
throw Exception("failed to delete the user ${r.responseType} ${r.details}") throw Exception("failed to delete the user ${r.responseType} ${r.details}")
@ -489,10 +526,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun apiGetChats(): List<Chat> { suspend fun apiGetChats(): List<Chat> {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("apiGetChats") }.getOrElse { return emptyList() }
Log.e(TAG, "apiGetChats: no current user")
return emptyList()
}
val r = sendCmd(CC.ApiGetChats(userId)) val r = sendCmd(CC.ApiGetChats(userId))
if (r is CR.ApiChats) return r.chats if (r is CR.ApiChats) return r.chats
Log.e(TAG, "failed getting the list of chats: ${r.responseType} ${r.details}") Log.e(TAG, "failed getting the list of chats: ${r.responseType} ${r.details}")
@ -544,10 +578,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
private suspend fun getUserSMPServers(): Pair<List<ServerCfg>, List<String>>? { private suspend fun getUserSMPServers(): Pair<List<ServerCfg>, List<String>>? {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("getUserSMPServers") }.getOrElse { return null }
Log.e(TAG, "getUserSMPServers: no current user")
return null
}
val r = sendCmd(CC.APIGetUserSMPServers(userId)) val r = sendCmd(CC.APIGetUserSMPServers(userId))
if (r is CR.UserSMPServers) return r.smpServers to r.presetSMPServers if (r is CR.UserSMPServers) return r.smpServers to r.presetSMPServers
Log.e(TAG, "getUserSMPServers bad response: ${r.responseType} ${r.details}") Log.e(TAG, "getUserSMPServers bad response: ${r.responseType} ${r.details}")
@ -555,10 +586,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun setUserSMPServers(smpServers: List<ServerCfg>): Boolean { suspend fun setUserSMPServers(smpServers: List<ServerCfg>): Boolean {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("setUserSMPServers") }.getOrElse { return false }
Log.e(TAG, "setUserSMPServers: no current user")
return false
}
val r = sendCmd(CC.APISetUserSMPServers(userId, smpServers)) val r = sendCmd(CC.APISetUserSMPServers(userId, smpServers))
return when (r) { return when (r) {
is CR.CmdOk -> true is CR.CmdOk -> true
@ -574,7 +602,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun testSMPServer(smpServer: String): SMPTestFailure? { suspend fun testSMPServer(smpServer: String): SMPTestFailure? {
val userId = chatModel.currentUser.value?.userId ?: run { throw Exception("testSMPServer: no current user") } val userId = currentUserId("testSMPServer")
val r = sendCmd(CC.APITestSMPServer(userId, smpServer)) val r = sendCmd(CC.APITestSMPServer(userId, smpServer))
return when (r) { return when (r) {
is CR.SmpTestResult -> r.smpTestFailure is CR.SmpTestResult -> r.smpTestFailure
@ -586,14 +614,14 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun getChatItemTTL(): ChatItemTTL { suspend fun getChatItemTTL(): ChatItemTTL {
val userId = chatModel.currentUser.value?.userId ?: run { throw Exception("getChatItemTTL: no current user") } val userId = currentUserId("getChatItemTTL")
val r = sendCmd(CC.APIGetChatItemTTL(userId)) val r = sendCmd(CC.APIGetChatItemTTL(userId))
if (r is CR.ChatItemTTL) return ChatItemTTL.fromSeconds(r.chatItemTTL) if (r is CR.ChatItemTTL) return ChatItemTTL.fromSeconds(r.chatItemTTL)
throw Exception("failed to get chat item TTL: ${r.responseType} ${r.details}") throw Exception("failed to get chat item TTL: ${r.responseType} ${r.details}")
} }
suspend fun setChatItemTTL(chatItemTTL: ChatItemTTL) { suspend fun setChatItemTTL(chatItemTTL: ChatItemTTL) {
val userId = chatModel.currentUser.value?.userId ?: run { throw Exception("setChatItemTTL: no current user") } val userId = currentUserId("setChatItemTTL")
val r = sendCmd(CC.APISetChatItemTTL(userId, chatItemTTL.seconds)) val r = sendCmd(CC.APISetChatItemTTL(userId, chatItemTTL.seconds))
if (r is CR.CmdOk) return if (r is CR.CmdOk) return
throw Exception("failed to set chat item TTL: ${r.responseType} ${r.details}") throw Exception("failed to set chat item TTL: ${r.responseType} ${r.details}")
@ -777,10 +805,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun apiListContacts(): List<Contact>? { suspend fun apiListContacts(): List<Contact>? {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("apiListContacts") }.getOrElse { return null }
Log.e(TAG, "apiListContacts: no current user")
return null
}
val r = sendCmd(CC.ApiListContacts(userId)) val r = sendCmd(CC.ApiListContacts(userId))
if (r is CR.ContactsList) return r.contacts if (r is CR.ContactsList) return r.contacts
Log.e(TAG, "apiListContacts bad response: ${r.responseType} ${r.details}") Log.e(TAG, "apiListContacts bad response: ${r.responseType} ${r.details}")
@ -788,10 +813,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun apiUpdateProfile(profile: Profile): Profile? { suspend fun apiUpdateProfile(profile: Profile): Profile? {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("apiUpdateProfile") }.getOrElse { return null }
Log.e(TAG, "apiUpdateProfile: no current user")
return null
}
val r = sendCmd(CC.ApiUpdateProfile(userId, profile)) val r = sendCmd(CC.ApiUpdateProfile(userId, profile))
if (r is CR.UserProfileNoChange) return profile if (r is CR.UserProfileNoChange) return profile
if (r is CR.UserProfileUpdated) return r.toProfile if (r is CR.UserProfileUpdated) return r.toProfile
@ -821,10 +843,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun apiCreateUserAddress(): String? { suspend fun apiCreateUserAddress(): String? {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("apiCreateUserAddress") }.getOrElse { return null }
Log.e(TAG, "apiCreateUserAddress: no current user")
return null
}
val r = sendCmd(CC.ApiCreateMyAddress(userId)) val r = sendCmd(CC.ApiCreateMyAddress(userId))
return when (r) { return when (r) {
is CR.UserContactLinkCreated -> r.connReqContact is CR.UserContactLinkCreated -> r.connReqContact
@ -838,10 +857,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun apiDeleteUserAddress(): Boolean { suspend fun apiDeleteUserAddress(): Boolean {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("apiDeleteUserAddress") }.getOrElse { return false }
Log.e(TAG, "apiDeleteUserAddress: no current user")
return false
}
val r = sendCmd(CC.ApiDeleteMyAddress(userId)) val r = sendCmd(CC.ApiDeleteMyAddress(userId))
if (r is CR.UserContactLinkDeleted) return true if (r is CR.UserContactLinkDeleted) return true
Log.e(TAG, "apiDeleteUserAddress bad response: ${r.responseType} ${r.details}") Log.e(TAG, "apiDeleteUserAddress bad response: ${r.responseType} ${r.details}")
@ -849,10 +865,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
private suspend fun apiGetUserAddress(): UserContactLinkRec? { private suspend fun apiGetUserAddress(): UserContactLinkRec? {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("apiGetUserAddress") }.getOrElse { return null }
Log.e(TAG, "apiGetUserAddress: no current user")
return null
}
val r = sendCmd(CC.ApiShowMyAddress(userId)) val r = sendCmd(CC.ApiShowMyAddress(userId))
if (r is CR.UserContactLink) return r.contactLink if (r is CR.UserContactLink) return r.contactLink
if (r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorStore if (r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorStore
@ -864,10 +877,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun userAddressAutoAccept(autoAccept: AutoAccept?): UserContactLinkRec? { suspend fun userAddressAutoAccept(autoAccept: AutoAccept?): UserContactLinkRec? {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("userAddressAutoAccept") }.getOrElse { return null }
Log.e(TAG, "userAddressAutoAccept: no current user")
return null
}
val r = sendCmd(CC.ApiAddressAutoAccept(userId, autoAccept)) val r = sendCmd(CC.ApiAddressAutoAccept(userId, autoAccept))
if (r is CR.UserContactLinkUpdated) return r.contactLink if (r is CR.UserContactLinkUpdated) return r.contactLink
if (r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorStore if (r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorStore
@ -987,10 +997,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
} }
suspend fun apiNewGroup(p: GroupProfile): GroupInfo? { suspend fun apiNewGroup(p: GroupProfile): GroupInfo? {
val userId = chatModel.currentUser.value?.userId ?: run { val userId = kotlin.runCatching { currentUserId("apiNewGroup") }.getOrElse { return null }
Log.e(TAG, "apiNewGroup: no current user")
return null
}
val r = sendCmd(CC.ApiNewGroup(userId, p)) val r = sendCmd(CC.ApiNewGroup(userId, p))
if (r is CR.GroupCreated) return r.groupInfo if (r is CR.GroupCreated) return r.groupInfo
Log.e(TAG, "apiNewGroup bad response: ${r.responseType} ${r.details}") Log.e(TAG, "apiNewGroup bad response: ${r.responseType} ${r.details}")
@ -1223,7 +1230,11 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
val contactRequest = r.contactRequest val contactRequest = r.contactRequest
val cInfo = ChatInfo.ContactRequest(contactRequest) val cInfo = ChatInfo.ContactRequest(contactRequest)
if (active(r.user)) { if (active(r.user)) {
chatModel.addChat(Chat(chatInfo = cInfo, chatItems = listOf())) if (chatModel.hasChat(contactRequest.id)) {
chatModel.updateChatInfo(cInfo)
} else {
chatModel.addChat(Chat(chatInfo = cInfo, chatItems = listOf()))
}
} }
ntfManager.notifyContactRequestReceived(r.user, cInfo) ntfManager.notifyContactRequestReceived(r.user, cInfo)
} }
@ -1309,7 +1320,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
val isLastChatItem = chatModel.getChat(cInfo.id)?.chatItems?.lastOrNull()?.id == cItem.id val isLastChatItem = chatModel.getChat(cInfo.id)?.chatItems?.lastOrNull()?.id == cItem.id
if (isLastChatItem && ntfManager.hasNotificationsForChat(cInfo.id)) { if (isLastChatItem && ntfManager.hasNotificationsForChat(cInfo.id)) {
ntfManager.cancelNotificationsForChat(cInfo.id) ntfManager.cancelNotificationsForChat(cInfo.id)
ntfManager.notifyMessageReceived( ntfManager.displayNotification(
r.user, r.user,
cInfo.id, cInfo.id,
cInfo.displayName, cInfo.displayName,
@ -1404,8 +1415,9 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
removeFile(appContext, fileName) removeFile(appContext, fileName)
} }
} }
is CR.CallInvitation -> is CR.CallInvitation -> {
chatModel.callManager.reportNewIncomingCall(r.callInvitation) chatModel.callManager.reportNewIncomingCall(r.callInvitation)
}
is CR.CallOffer -> { is CR.CallOffer -> {
// TODO askConfirmation? // TODO askConfirmation?
// TODO check encryption is compatible // TODO check encryption is compatible
@ -1776,8 +1788,12 @@ sealed class CC {
class ShowActiveUser: CC() class ShowActiveUser: CC()
class CreateActiveUser(val profile: Profile): CC() class CreateActiveUser(val profile: Profile): CC()
class ListUsers: CC() class ListUsers: CC()
class ApiSetActiveUser(val userId: Long): CC() class ApiSetActiveUser(val userId: Long, val viewPwd: String?): CC()
class ApiDeleteUser(val userId: Long, val delSMPQueues: Boolean): CC() class ApiHideUser(val userId: Long, val viewPwd: String): CC()
class ApiUnhideUser(val userId: Long, val viewPwd: String?): CC()
class ApiMuteUser(val userId: Long, val viewPwd: String?): CC()
class ApiUnmuteUser(val userId: Long, val viewPwd: String?): CC()
class ApiDeleteUser(val userId: Long, val delSMPQueues: Boolean, val viewPwd: String?): CC()
class StartChat(val expire: Boolean): CC() class StartChat(val expire: Boolean): CC()
class ApiStopChat: CC() class ApiStopChat: CC()
class SetTempFolder(val tempFolder: String): CC() class SetTempFolder(val tempFolder: String): CC()
@ -1855,8 +1871,12 @@ sealed class CC {
is ShowActiveUser -> "/u" is ShowActiveUser -> "/u"
is CreateActiveUser -> "/create user ${profile.displayName} ${profile.fullName}" is CreateActiveUser -> "/create user ${profile.displayName} ${profile.fullName}"
is ListUsers -> "/users" is ListUsers -> "/users"
is ApiSetActiveUser -> "/_user $userId" is ApiSetActiveUser -> "/_user $userId${maybePwd(viewPwd)}"
is ApiDeleteUser -> "/_delete user $userId del_smp=${onOff(delSMPQueues)}" is ApiHideUser -> "/_hide user $userId ${json.encodeToString(viewPwd)}"
is ApiUnhideUser -> "/_unhide user $userId${maybePwd(viewPwd)}"
is ApiMuteUser -> "/_mute user $userId${maybePwd(viewPwd)}"
is ApiUnmuteUser -> "/_unmute user $userId${maybePwd(viewPwd)}"
is ApiDeleteUser -> "/_delete user $userId del_smp=${onOff(delSMPQueues)}${maybePwd(viewPwd)}"
is StartChat -> "/_start subscribe=on expire=${onOff(expire)}" is StartChat -> "/_start subscribe=on expire=${onOff(expire)}"
is ApiStopChat -> "/_stop" is ApiStopChat -> "/_stop"
is SetTempFolder -> "/_temp_folder $tempFolder" is SetTempFolder -> "/_temp_folder $tempFolder"
@ -1936,6 +1956,10 @@ sealed class CC {
is CreateActiveUser -> "createActiveUser" is CreateActiveUser -> "createActiveUser"
is ListUsers -> "listUsers" is ListUsers -> "listUsers"
is ApiSetActiveUser -> "apiSetActiveUser" is ApiSetActiveUser -> "apiSetActiveUser"
is ApiHideUser -> "apiHideUser"
is ApiUnhideUser -> "apiUnhideUser"
is ApiMuteUser -> "apiMuteUser"
is ApiUnmuteUser -> "apiUnmuteUser"
is ApiDeleteUser -> "apiDeleteUser" is ApiDeleteUser -> "apiDeleteUser"
is StartChat -> "startChat" is StartChat -> "startChat"
is ApiStopChat -> "apiStopChat" is ApiStopChat -> "apiStopChat"
@ -2020,13 +2044,28 @@ sealed class CC {
val obfuscated: CC val obfuscated: CC
get() = when (this) { get() = when (this) {
is ApiStorageEncryption -> ApiStorageEncryption(DBEncryptionConfig(obfuscate(config.currentKey), obfuscate(config.newKey))) is ApiStorageEncryption -> ApiStorageEncryption(DBEncryptionConfig(obfuscate(config.currentKey), obfuscate(config.newKey)))
is ApiSetActiveUser -> ApiSetActiveUser(userId, obfuscateOrNull(viewPwd))
is ApiHideUser -> ApiHideUser(userId, obfuscate(viewPwd))
is ApiUnhideUser -> ApiUnhideUser(userId, obfuscateOrNull(viewPwd))
is ApiMuteUser -> ApiMuteUser(userId, obfuscateOrNull(viewPwd))
is ApiUnmuteUser -> ApiUnmuteUser(userId, obfuscateOrNull(viewPwd))
is ApiDeleteUser -> ApiDeleteUser(userId, delSMPQueues, obfuscateOrNull(viewPwd))
else -> this else -> this
} }
private fun obfuscate(s: String): String = if (s.isEmpty()) "" else "***" private fun obfuscate(s: String): String = if (s.isEmpty()) "" else "***"
private fun obfuscateOrNull(s: String?): String? =
if (s != null) {
obfuscate(s)
} else {
null
}
private fun onOff(b: Boolean): String = if (b) "on" else "off" private fun onOff(b: Boolean): String = if (b) "on" else "off"
private fun maybePwd(pwd: String?): String = if (pwd == "" || pwd == null) "" else " " + json.encodeToString(pwd)
companion object { companion object {
fun chatRef(chatType: ChatType, id: Long) = "${chatType.type}${id}" fun chatRef(chatType: ChatType, id: Long) = "${chatType.type}${id}"
@ -2882,6 +2921,13 @@ class APIResponse(val resp: CR, val corr: String? = null) {
resp = CR.ApiChat(user, chat), resp = CR.ApiChat(user, chat),
corr = data["corr"]?.toString() corr = data["corr"]?.toString()
) )
} else if (type == "chatCmdError") {
val userObject = resp["user_"]?.jsonObject
val user = runCatching<User?> { json.decodeFromJsonElement(userObject!!) }.getOrNull()
return APIResponse(
resp = CR.ChatCmdError(user, ChatError.ChatErrorInvalidJSON(json.encodeToString(resp["chatError"]))),
corr = data["corr"]?.toString()
)
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Error while parsing chat(s): " + e.stackTraceToString()) Log.e(TAG, "Error while parsing chat(s): " + e.stackTraceToString())
@ -2938,6 +2984,7 @@ sealed class CR {
@Serializable @SerialName("chatCleared") class ChatCleared(val user: User, val chatInfo: ChatInfo): CR() @Serializable @SerialName("chatCleared") class ChatCleared(val user: User, val chatInfo: ChatInfo): CR()
@Serializable @SerialName("userProfileNoChange") class UserProfileNoChange(val user: User): CR() @Serializable @SerialName("userProfileNoChange") class UserProfileNoChange(val user: User): CR()
@Serializable @SerialName("userProfileUpdated") class UserProfileUpdated(val user: User, val fromProfile: Profile, val toProfile: Profile): CR() @Serializable @SerialName("userProfileUpdated") class UserProfileUpdated(val user: User, val fromProfile: Profile, val toProfile: Profile): CR()
@Serializable @SerialName("userPrivacy") class UserPrivacy(val user: User): CR()
@Serializable @SerialName("contactAliasUpdated") class ContactAliasUpdated(val user: User, val toContact: Contact): CR() @Serializable @SerialName("contactAliasUpdated") class ContactAliasUpdated(val user: User, val toContact: Contact): CR()
@Serializable @SerialName("connectionAliasUpdated") class ConnectionAliasUpdated(val user: User, val toConnection: PendingContactConnection): CR() @Serializable @SerialName("connectionAliasUpdated") class ConnectionAliasUpdated(val user: User, val toConnection: PendingContactConnection): CR()
@Serializable @SerialName("contactPrefsUpdated") class ContactPrefsUpdated(val user: User, val fromContact: Contact, val toContact: Contact): CR() @Serializable @SerialName("contactPrefsUpdated") class ContactPrefsUpdated(val user: User, val fromContact: Contact, val toContact: Contact): CR()
@ -3011,8 +3058,8 @@ sealed class CR {
@Serializable @SerialName("versionInfo") class VersionInfo(val versionInfo: CoreVersionInfo): CR() @Serializable @SerialName("versionInfo") class VersionInfo(val versionInfo: CoreVersionInfo): CR()
@Serializable @SerialName("apiParsedMarkdown") class ParsedMarkdown(val formattedText: List<FormattedText>? = null): CR() @Serializable @SerialName("apiParsedMarkdown") class ParsedMarkdown(val formattedText: List<FormattedText>? = null): CR()
@Serializable @SerialName("cmdOk") class CmdOk(val user: User?): CR() @Serializable @SerialName("cmdOk") class CmdOk(val user: User?): CR()
@Serializable @SerialName("chatCmdError") class ChatCmdError(val user: User?, val chatError: ChatError): CR() @Serializable @SerialName("chatCmdError") class ChatCmdError(val user_: User?, val chatError: ChatError): CR()
@Serializable @SerialName("chatError") class ChatRespError(val user: User?, val chatError: ChatError): CR() @Serializable @SerialName("chatError") class ChatRespError(val user_: User?, val chatError: ChatError): CR()
@Serializable class Response(val type: String, val json: String): CR() @Serializable class Response(val type: String, val json: String): CR()
@Serializable class Invalid(val str: String): CR() @Serializable class Invalid(val str: String): CR()
@ -3041,6 +3088,7 @@ sealed class CR {
is ChatCleared -> "chatCleared" is ChatCleared -> "chatCleared"
is UserProfileNoChange -> "userProfileNoChange" is UserProfileNoChange -> "userProfileNoChange"
is UserProfileUpdated -> "userProfileUpdated" is UserProfileUpdated -> "userProfileUpdated"
is UserPrivacy -> "userPrivacy"
is ContactAliasUpdated -> "contactAliasUpdated" is ContactAliasUpdated -> "contactAliasUpdated"
is ConnectionAliasUpdated -> "connectionAliasUpdated" is ConnectionAliasUpdated -> "connectionAliasUpdated"
is ContactPrefsUpdated -> "contactPrefsUpdated" is ContactPrefsUpdated -> "contactPrefsUpdated"
@ -3142,6 +3190,7 @@ sealed class CR {
is ChatCleared -> withUser(user, json.encodeToString(chatInfo)) is ChatCleared -> withUser(user, json.encodeToString(chatInfo))
is UserProfileNoChange -> withUser(user, noDetails()) is UserProfileNoChange -> withUser(user, noDetails())
is UserProfileUpdated -> withUser(user, json.encodeToString(toProfile)) is UserProfileUpdated -> withUser(user, json.encodeToString(toProfile))
is UserPrivacy -> withUser(user, "")
is ContactAliasUpdated -> withUser(user, json.encodeToString(toContact)) is ContactAliasUpdated -> withUser(user, json.encodeToString(toContact))
is ConnectionAliasUpdated -> withUser(user, json.encodeToString(toConnection)) is ConnectionAliasUpdated -> withUser(user, json.encodeToString(toConnection))
is ContactPrefsUpdated -> withUser(user, "fromContact: $fromContact\ntoContact: \n${json.encodeToString(toContact)}") is ContactPrefsUpdated -> withUser(user, "fromContact: $fromContact\ntoContact: \n${json.encodeToString(toContact)}")
@ -3212,8 +3261,8 @@ sealed class CR {
is ContactConnectionDeleted -> withUser(user, json.encodeToString(connection)) is ContactConnectionDeleted -> withUser(user, json.encodeToString(connection))
is VersionInfo -> json.encodeToString(versionInfo) is VersionInfo -> json.encodeToString(versionInfo)
is CmdOk -> withUser(user, noDetails()) is CmdOk -> withUser(user, noDetails())
is ChatCmdError -> withUser(user, chatError.string) is ChatCmdError -> withUser(user_, chatError.string)
is ChatRespError -> withUser(user, chatError.string) is ChatRespError -> withUser(user_, chatError.string)
is Response -> json is Response -> json
is Invalid -> str is Invalid -> str
} }
@ -3285,11 +3334,13 @@ sealed class ChatError {
is ChatErrorAgent -> "agent ${agentError.string}" is ChatErrorAgent -> "agent ${agentError.string}"
is ChatErrorStore -> "store ${storeError.string}" is ChatErrorStore -> "store ${storeError.string}"
is ChatErrorDatabase -> "database ${databaseError.string}" is ChatErrorDatabase -> "database ${databaseError.string}"
is ChatErrorInvalidJSON -> "invalid json ${json}"
} }
@Serializable @SerialName("error") class ChatErrorChat(val errorType: ChatErrorType): ChatError() @Serializable @SerialName("error") class ChatErrorChat(val errorType: ChatErrorType): ChatError()
@Serializable @SerialName("errorAgent") class ChatErrorAgent(val agentError: AgentErrorType): ChatError() @Serializable @SerialName("errorAgent") class ChatErrorAgent(val agentError: AgentErrorType): ChatError()
@Serializable @SerialName("errorStore") class ChatErrorStore(val storeError: StoreError): ChatError() @Serializable @SerialName("errorStore") class ChatErrorStore(val storeError: StoreError): ChatError()
@Serializable @SerialName("errorDatabase") class ChatErrorDatabase(val databaseError: DatabaseError): ChatError() @Serializable @SerialName("errorDatabase") class ChatErrorDatabase(val databaseError: DatabaseError): ChatError()
@Serializable @SerialName("invalidJSON") class ChatErrorInvalidJSON(val json: String): ChatError()
} }
@Serializable @Serializable

View file

@ -13,12 +13,14 @@ class CallManager(val chatModel: ChatModel) {
Log.d(TAG, "CallManager.reportNewIncomingCall") Log.d(TAG, "CallManager.reportNewIncomingCall")
with (chatModel) { with (chatModel) {
callInvitations[invitation.contact.id] = invitation callInvitations[invitation.contact.id] = invitation
if (Clock.System.now() - invitation.callTs <= 3.minutes) { if (invitation.user.showNotifications) {
activeCallInvitation.value = invitation if (Clock.System.now() - invitation.callTs <= 3.minutes) {
controller.ntfManager.notifyCallInvitation(invitation) activeCallInvitation.value = invitation
} else { controller.ntfManager.notifyCallInvitation(invitation)
val contact = invitation.contact } else {
controller.ntfManager.notifyMessageReceived(user = invitation.user, chatId = contact.id, displayName = contact.displayName, msgText = invitation.callTypeText) val contact = invitation.contact
controller.ntfManager.displayNotification(user = invitation.user, chatId = contact.id, displayName = contact.displayName, msgText = invitation.callTypeText)
}
} }
} }
} }

View file

@ -92,7 +92,7 @@ fun ActiveCallView(chatModel: ChatModel) {
am.registerAudioDeviceCallback(audioCallback, null) am.registerAudioDeviceCallback(audioCallback, null)
val pm = (SimplexApp.context.getSystemService(Context.POWER_SERVICE) as PowerManager) val pm = (SimplexApp.context.getSystemService(Context.POWER_SERVICE) as PowerManager)
val proximityLock = if (pm.isWakeLockLevelSupported(PROXIMITY_SCREEN_OFF_WAKE_LOCK)) { val proximityLock = if (pm.isWakeLockLevelSupported(PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
pm.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, "proximityLock") pm.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, SimplexApp.context.packageName + ":proximityLock")
} else { } else {
null null
} }

View file

@ -7,11 +7,10 @@ import android.Manifest
import android.app.Activity import android.app.Activity
import android.content.* import android.content.*
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Bitmap import android.graphics.*
import android.graphics.ImageDecoder
import android.graphics.ImageDecoder.DecodeException
import android.graphics.drawable.AnimatedImageDrawable import android.graphics.drawable.AnimatedImageDrawable
import android.net.Uri import android.net.Uri
import android.os.Build
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
@ -36,6 +35,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.net.toFile
import chat.simplex.app.* import chat.simplex.app.*
import chat.simplex.app.R import chat.simplex.app.R
import chat.simplex.app.model.* import chat.simplex.app.model.*
@ -186,10 +186,11 @@ fun ComposeView(
val textStyle = remember { mutableStateOf(smallFont) } val textStyle = remember { mutableStateOf(smallFont) }
val cameraLauncher = rememberCameraLauncher { uri: Uri? -> val cameraLauncher = rememberCameraLauncher { uri: Uri? ->
if (uri != null) { if (uri != null) {
val source = ImageDecoder.createSource(SimplexApp.context.contentResolver, uri) val bitmap: Bitmap? = getBitmapFromUri(uri)
val bitmap = ImageDecoder.decodeBitmap(source) if (bitmap != null) {
val imagePreview = resizeImageToStrSize(bitmap, maxDataSize = 14000) val imagePreview = resizeImageToStrSize(bitmap, maxDataSize = 14000)
composeState.value = composeState.value.copy(preview = ComposePreview.ImagePreview(listOf(imagePreview), listOf(UploadContent.SimpleImage(uri)))) composeState.value = composeState.value.copy(preview = ComposePreview.ImagePreview(listOf(imagePreview), listOf(UploadContent.SimpleImage(uri))))
}
} }
} }
val cameraPermissionLauncher = rememberPermissionLauncher { isGranted: Boolean -> val cameraPermissionLauncher = rememberPermissionLauncher { isGranted: Boolean ->
@ -203,19 +204,12 @@ fun ComposeView(
val content = ArrayList<UploadContent>() val content = ArrayList<UploadContent>()
val imagesPreview = ArrayList<String>() val imagesPreview = ArrayList<String>()
uris.forEach { uri -> uris.forEach { uri ->
val source = ImageDecoder.createSource(context.contentResolver, uri) val drawable = getDrawableFromUri(uri)
val drawable = try { var bitmap: Bitmap? = if (drawable != null) getBitmapFromUri(uri) else null
ImageDecoder.decodeDrawable(source) val isAnimNewApi = Build.VERSION.SDK_INT >= 28 && drawable is AnimatedImageDrawable
} catch (e: DecodeException) { val isAnimOldApi = Build.VERSION.SDK_INT < 28 &&
AlertManager.shared.showAlertMsg( (getFileName(SimplexApp.context, uri)?.endsWith(".gif") == true || getFileName(SimplexApp.context, uri)?.endsWith(".webp") == true)
title = generalGetString(R.string.image_decoding_exception_title), if (isAnimNewApi || isAnimOldApi) {
text = generalGetString(R.string.image_decoding_exception_desc)
)
Log.e(TAG, "Error while decoding drawable: ${e.stackTraceToString()}")
null
}
var bitmap: Bitmap? = if (drawable != null) ImageDecoder.decodeBitmap(source) else null
if (drawable is AnimatedImageDrawable) {
// It's a gif or webp // It's a gif or webp
val fileSize = getFileSize(context, uri) val fileSize = getFileSize(context, uri)
if (fileSize != null && fileSize <= MAX_FILE_SIZE) { if (fileSize != null && fileSize <= MAX_FILE_SIZE) {

View file

@ -8,10 +8,12 @@ import android.content.pm.ActivityInfo
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Build import android.os.Build
import android.text.InputType import android.text.InputType
import android.util.Log
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import android.view.inputmethod.* import android.view.inputmethod.*
import android.widget.EditText import android.widget.EditText
import android.widget.TextView
import androidx.compose.animation.core.* import androidx.compose.animation.core.*
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
@ -50,6 +52,7 @@ import chat.simplex.app.views.chat.item.ItemAction
import chat.simplex.app.views.helpers.* import chat.simplex.app.views.helpers.*
import com.google.accompanist.permissions.rememberMultiplePermissionsState import com.google.accompanist.permissions.rememberMultiplePermissionsState
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.lang.reflect.Field
@Composable @Composable
fun SendMsgView( fun SendMsgView(
@ -240,7 +243,17 @@ private fun NativeKeyboard(
editText.background = drawable editText.background = drawable
editText.setPadding(paddingStart, paddingTop, paddingEnd, paddingBottom) editText.setPadding(paddingStart, paddingTop, paddingEnd, paddingBottom)
editText.setText(cs.message) editText.setText(cs.message)
editText.textCursorDrawable?.let { DrawableCompat.setTint(it, HighOrLowlight.toArgb()) } if (Build.VERSION.SDK_INT >= 29) {
editText.textCursorDrawable?.let { DrawableCompat.setTint(it, HighOrLowlight.toArgb()) }
} else {
try {
val f: Field = TextView::class.java.getDeclaredField("mCursorDrawableRes")
f.isAccessible = true
f.set(editText, R.drawable.edit_text_cursor)
} catch (e: Exception) {
Log.e(chat.simplex.app.TAG, e.stackTraceToString())
}
}
editText.doOnTextChanged { text, _, _, _ -> onMessageChange(text.toString()) } editText.doOnTextChanged { text, _, _, _ -> onMessageChange(text.toString()) }
editText.doAfterTextChanged { text -> if (composeState.value.preview is ComposePreview.VoicePreview && text.toString() != "") editText.setText("") } editText.doAfterTextChanged { text -> if (composeState.value.preview is ComposePreview.VoicePreview && text.toString() != "") editText.setText("") }
editText editText

View file

@ -1,5 +1,7 @@
package chat.simplex.app.views.chat.item package chat.simplex.app.views.chat.item
import android.Manifest
import android.os.Build
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
@ -25,6 +27,7 @@ import chat.simplex.app.ui.theme.SimpleXTheme
import chat.simplex.app.views.chat.ComposeContextItem import chat.simplex.app.views.chat.ComposeContextItem
import chat.simplex.app.views.chat.ComposeState import chat.simplex.app.views.chat.ComposeState
import chat.simplex.app.views.helpers.* import chat.simplex.app.views.helpers.*
import com.google.accompanist.permissions.rememberPermissionState
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
// TODO refactor so that FramedItemView can show all CIContent items if they're deleted (see Swift code) // TODO refactor so that FramedItemView can show all CIContent items if they're deleted (see Swift code)
@ -131,9 +134,16 @@ fun ChatItemView(
if (cItem.content.msgContent is MsgContent.MCImage || cItem.content.msgContent is MsgContent.MCFile || cItem.content.msgContent is MsgContent.MCVoice) { if (cItem.content.msgContent is MsgContent.MCImage || cItem.content.msgContent is MsgContent.MCFile || cItem.content.msgContent is MsgContent.MCVoice) {
val filePath = getLoadedFilePath(context, cItem.file) val filePath = getLoadedFilePath(context, cItem.file)
if (filePath != null) { if (filePath != null) {
val writePermissionState = rememberPermissionState(permission = Manifest.permission.WRITE_EXTERNAL_STORAGE)
ItemAction(stringResource(R.string.save_verb), Icons.Outlined.SaveAlt, onClick = { ItemAction(stringResource(R.string.save_verb), Icons.Outlined.SaveAlt, onClick = {
when (cItem.content.msgContent) { when (cItem.content.msgContent) {
is MsgContent.MCImage -> saveImage(context, cItem.file) is MsgContent.MCImage -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || writePermissionState.hasPermission) {
saveImage(context, cItem.file)
} else {
writePermissionState.launchPermissionRequest()
}
}
is MsgContent.MCFile -> saveFileLauncher.launch(cItem.file?.fileName) is MsgContent.MCFile -> saveFileLauncher.launch(cItem.file?.fileName)
is MsgContent.MCVoice -> saveFileLauncher.launch(cItem.file?.fileName) is MsgContent.MCVoice -> saveFileLauncher.launch(cItem.file?.fileName)
else -> {} else -> {}

View file

@ -1,8 +1,7 @@
package chat.simplex.app.views.chat.item package chat.simplex.app.views.chat.item
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -31,10 +30,12 @@ fun MarkedDeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, showMember: Bool
Modifier.padding(horizontal = 12.dp, vertical = 6.dp), Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
if (ci.meta.itemDeleted is CIDeleted.Moderated) { Box(Modifier.weight(1f, false)) {
MarkedDeletedText(String.format(generalGetString(R.string.moderated_item_description), ci.meta.itemDeleted.byGroupMember.chatViewName)) if (ci.meta.itemDeleted is CIDeleted.Moderated) {
} else { MarkedDeletedText(String.format(generalGetString(R.string.moderated_item_description), ci.meta.itemDeleted.byGroupMember.chatViewName))
MarkedDeletedText(generalGetString(R.string.marked_deleted_description)) } else {
MarkedDeletedText(generalGetString(R.string.marked_deleted_description))
}
} }
CIMetaView(ci, timedMessagesTTL) CIMetaView(ci, timedMessagesTTL)
} }

View file

@ -208,9 +208,9 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user
} else if (chatModel.users.isEmpty()) { } else if (chatModel.users.isEmpty()) {
NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } } NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } }
} else { } else {
val users by remember { derivedStateOf { chatModel.users.toList() } } val users by remember { derivedStateOf { chatModel.users.filter { u -> u.user.activeUser || !u.user.hidden } } }
val allRead = users val allRead = users
.filter { !it.user.activeUser } .filter { u -> !u.user.activeUser && !u.user.hidden }
.all { u -> u.unreadCount == 0 } .all { u -> u.unreadCount == 0 }
UserProfileButton(chatModel.currentUser.value?.profile?.image, allRead) { UserProfileButton(chatModel.currentUser.value?.profile?.image, allRead) {
if (users.size == 1) { if (users.size == 1) {
@ -247,7 +247,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user
} }
@Composable @Composable
private fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) { fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) {
IconButton(onClick = onButtonClicked) { IconButton(onClick = onButtonClicked) {
Box { Box {
ProfileImage( ProfileImage(

View file

@ -24,12 +24,15 @@ import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.HighOrLowlight import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.ui.theme.Indigo import chat.simplex.app.ui.theme.Indigo
import chat.simplex.app.views.helpers.* import chat.simplex.app.views.helpers.*
import kotlinx.coroutines.flow.MutableStateFlow
@Composable @Composable
fun ShareListView(chatModel: ChatModel, stopped: Boolean) { fun ShareListView(chatModel: ChatModel, stopped: Boolean) {
var searchInList by rememberSaveable { mutableStateOf("") } var searchInList by rememberSaveable { mutableStateOf("") }
val userPickerState by rememberSaveable(stateSaver = AnimatedViewState.saver()) { mutableStateOf(MutableStateFlow(AnimatedViewState.GONE)) }
val switchingUsers = rememberSaveable { mutableStateOf(false) }
Scaffold( Scaffold(
topBar = { Column { ShareListToolbar(chatModel, stopped) { searchInList = it.trim() } } }, topBar = { Column { ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() } } },
) { ) {
Box(Modifier.padding(it)) { Box(Modifier.padding(it)) {
Column( Column(
@ -45,23 +48,41 @@ fun ShareListView(chatModel: ChatModel, stopped: Boolean) {
} }
} }
} }
UserPicker(chatModel, userPickerState, switchingUsers, showSettings = false, showCancel = true, cancelClicked = {
chatModel.sharedContent.value = null
})
} }
@Composable @Composable
private fun EmptyList() { private fun EmptyList() {
Box { Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(stringResource(R.string.you_have_no_chats), Modifier.align(Alignment.Center), color = HighOrLowlight) Text(stringResource(R.string.you_have_no_chats), color = HighOrLowlight)
} }
} }
@Composable @Composable
private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchValueChanged: (String) -> Unit) { private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedViewState>, stopped: Boolean, onSearchValueChanged: (String) -> Unit) {
var showSearch by rememberSaveable { mutableStateOf(false) } var showSearch by rememberSaveable { mutableStateOf(false) }
val hideSearchOnBack = { onSearchValueChanged(""); showSearch = false } val hideSearchOnBack = { onSearchValueChanged(""); showSearch = false }
if (showSearch) { if (showSearch) {
BackHandler(onBack = hideSearchOnBack) BackHandler(onBack = hideSearchOnBack)
} }
val barButtons = arrayListOf<@Composable RowScope.() -> Unit>() val barButtons = arrayListOf<@Composable RowScope.() -> Unit>()
val users by remember { derivedStateOf { chatModel.users.filter { u -> u.user.activeUser || !u.user.hidden } } }
val navButton: @Composable RowScope.() -> Unit = {
when {
showSearch -> NavigationButtonBack(hideSearchOnBack)
users.size > 1 -> {
val allRead = users
.filter { u -> !u.user.activeUser && !u.user.hidden }
.all { u -> u.unreadCount == 0 }
UserProfileButton(chatModel.currentUser.value?.profile?.image, allRead) {
userPickerState.value = AnimatedViewState.VISIBLE
}
}
else -> NavigationButtonBack { chatModel.sharedContent.value = null }
}
}
if (chatModel.chats.size >= 8) { if (chatModel.chats.size >= 8) {
barButtons.add { barButtons.add {
IconButton({ showSearch = true }) { IconButton({ showSearch = true }) {
@ -87,7 +108,7 @@ private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchVal
} }
DefaultTopAppBar( DefaultTopAppBar(
navigationButton = { if (showSearch) NavigationButtonBack(hideSearchOnBack) else NavigationButtonBack { chatModel.sharedContent.value = null } }, navigationButton = navButton,
title = { title = {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Text( Text(

View file

@ -9,11 +9,12 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.* import androidx.compose.ui.*
import androidx.compose.ui.draw.shadow import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
@ -33,10 +34,24 @@ import kotlinx.coroutines.launch
import kotlin.math.roundToInt import kotlin.math.roundToInt
@Composable @Composable
fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedViewState>, switchingUsers: MutableState<Boolean>, openSettings: () -> Unit) { fun UserPicker(
chatModel: ChatModel,
userPickerState: MutableStateFlow<AnimatedViewState>,
switchingUsers: MutableState<Boolean>,
showSettings: Boolean = true,
showCancel: Boolean = false,
cancelClicked: () -> Unit = {},
settingsClicked: () -> Unit = {},
) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
var newChat by remember { mutableStateOf(userPickerState.value) } var newChat by remember { mutableStateOf(userPickerState.value) }
val users by remember { derivedStateOf { chatModel.users.sortedByDescending { it.user.activeUser } } } val users by remember {
derivedStateOf {
chatModel.users
.filter { u -> u.user.activeUser || !u.user.hidden }
.sortedByDescending { it.user.activeUser }
}
}
val animatedFloat = remember { Animatable(if (newChat.isVisible()) 0f else 1f) } val animatedFloat = remember { Animatable(if (newChat.isVisible()) 0f else 1f) }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
launch { launch {
@ -94,23 +109,22 @@ fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedV
.width(IntrinsicSize.Min) .width(IntrinsicSize.Min)
.height(IntrinsicSize.Min) .height(IntrinsicSize.Min)
.shadow(8.dp, MaterialTheme.shapes.medium, clip = false) .shadow(8.dp, MaterialTheme.shapes.medium, clip = false)
.background(MaterialTheme.colors.background, MaterialTheme.shapes.medium) .background(if (isInDarkTheme()) MaterialTheme.colors.background.darker(-0.7f) else MaterialTheme.colors.background, MaterialTheme.shapes.medium)
) { ) {
Column(Modifier.weight(1f).verticalScroll(rememberScrollState())) { Column(Modifier.weight(1f).verticalScroll(rememberScrollState())) {
users.forEach { u -> users.forEach { u ->
UserProfilePickerItem(u.user, u.unreadCount, openSettings = { UserProfilePickerItem(u.user, u.unreadCount, openSettings = {
openSettings() settingsClicked()
userPickerState.value = AnimatedViewState.GONE userPickerState.value = AnimatedViewState.GONE
}) { }) {
userPickerState.value = AnimatedViewState.HIDING userPickerState.value = AnimatedViewState.HIDING
if (!u.user.activeUser) { if (!u.user.activeUser) {
chatModel.chats.clear()
scope.launch { scope.launch {
val job = launch { val job = launch {
delay(500) delay(500)
switchingUsers.value = true switchingUsers.value = true
} }
chatModel.controller.changeActiveUser(u.user.userId) chatModel.controller.changeActiveUser(u.user.userId, null)
job.cancel() job.cancel()
switchingUsers.value = false switchingUsers.value = false
} }
@ -120,9 +134,17 @@ fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedV
if (u.user.activeUser) Divider(Modifier.requiredHeight(0.5.dp)) if (u.user.activeUser) Divider(Modifier.requiredHeight(0.5.dp))
} }
} }
SettingsPickerItem { if (showSettings) {
openSettings() SettingsPickerItem {
userPickerState.value = AnimatedViewState.GONE settingsClicked()
userPickerState.value = AnimatedViewState.GONE
}
}
if (showCancel) {
CancelPickerItem {
cancelClicked()
userPickerState.value = AnimatedViewState.GONE
}
} }
} }
} }
@ -144,33 +166,19 @@ fun UserProfilePickerItem(u: User, unreadCount: Int = 0, onLongClick: () -> Unit
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Row( UserProfileRow(u)
Modifier
.widthIn(max = LocalConfiguration.current.screenWidthDp.dp * 0.7f)
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
ProfileImage(
image = u.image,
size = 54.dp
)
Text(
u.displayName,
modifier = Modifier
.padding(start = 8.dp, end = 8.dp),
fontWeight = if (u.activeUser) FontWeight.Medium else FontWeight.Normal
)
}
if (u.activeUser) { if (u.activeUser) {
Icon(Icons.Filled.Done, null, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Icon(Icons.Filled.Done, null, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
} else if (u.hidden) {
Icon(Icons.Outlined.Lock, null, Modifier.size(20.dp), tint = HighOrLowlight)
} else if (unreadCount > 0) { } else if (unreadCount > 0) {
Row { Row {
Text( Text(
unreadCountStr(unreadCount), unreadCountStr(unreadCount),
color = MaterialTheme.colors.onPrimary, color = Color.White,
fontSize = 11.sp, fontSize = 11.sp,
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.primary, shape = CircleShape) .background(if (u.showNtfs) MaterialTheme.colors.primary else HighOrLowlight, shape = CircleShape)
.sizeIn(minWidth = 20.dp, minHeight = 20.dp) .sizeIn(minWidth = 20.dp, minHeight = 20.dp)
.padding(horizontal = 3.dp) .padding(horizontal = 3.dp)
.padding(vertical = 1.dp), .padding(vertical = 1.dp),
@ -179,12 +187,35 @@ fun UserProfilePickerItem(u: User, unreadCount: Int = 0, onLongClick: () -> Unit
) )
Spacer(Modifier.width(2.dp)) Spacer(Modifier.width(2.dp))
} }
} else { } else if (!u.showNtfs) {
Icon(Icons.Outlined.NotificationsOff, null, Modifier.size(20.dp), tint = HighOrLowlight)
} else {
Box(Modifier.size(20.dp)) Box(Modifier.size(20.dp))
} }
} }
} }
@Composable
fun UserProfileRow(u: User) {
Row(
Modifier
.widthIn(max = LocalConfiguration.current.screenWidthDp.dp * 0.7f)
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
ProfileImage(
image = u.image,
size = 54.dp
)
Text(
u.displayName,
modifier = Modifier
.padding(start = 8.dp, end = 8.dp),
fontWeight = if (u.activeUser) FontWeight.Medium else FontWeight.Normal
)
}
}
@Composable @Composable
private fun SettingsPickerItem(onClick: () -> Unit) { private fun SettingsPickerItem(onClick: () -> Unit) {
SectionItemViewSpaceBetween(onClick, minHeight = 68.dp) { SectionItemViewSpaceBetween(onClick, minHeight = 68.dp) {
@ -196,3 +227,15 @@ private fun SettingsPickerItem(onClick: () -> Unit) {
Icon(Icons.Outlined.Settings, text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Icon(Icons.Outlined.Settings, text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
} }
} }
@Composable
private fun CancelPickerItem(onClick: () -> Unit) {
SectionItemViewSpaceBetween(onClick, minHeight = 68.dp) {
val text = generalGetString(R.string.cancel_verb)
Text(
text,
color = MaterialTheme.colors.onBackground,
)
Icon(Icons.Outlined.Close, text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
}
}

View file

@ -1,5 +1,6 @@
package chat.simplex.app.views.database package chat.simplex.app.views.database
import SectionDivider
import SectionItemView import SectionItemView
import SectionItemViewSpaceBetween import SectionItemViewSpaceBetween
import SectionTextFooter import SectionTextFooter
@ -25,13 +26,13 @@ import androidx.compose.ui.text.*
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.* import androidx.compose.ui.text.input.*
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.*
import androidx.compose.ui.unit.sp
import chat.simplex.app.R import chat.simplex.app.R
import chat.simplex.app.SimplexApp import chat.simplex.app.SimplexApp
import chat.simplex.app.model.* import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.* import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.helpers.* import chat.simplex.app.views.helpers.*
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlin.math.log2 import kotlin.math.log2
@ -161,7 +162,9 @@ fun DatabaseEncryptionLayout(
} }
if (!initialRandomDBPassphrase.value && chatDbEncrypted == true) { if (!initialRandomDBPassphrase.value && chatDbEncrypted == true) {
DatabaseKeyField( SectionDivider()
PassphraseField(
currentKey, currentKey,
generalGetString(R.string.current_passphrase), generalGetString(R.string.current_passphrase),
modifier = Modifier.padding(horizontal = DEFAULT_PADDING), modifier = Modifier.padding(horizontal = DEFAULT_PADDING),
@ -170,7 +173,9 @@ fun DatabaseEncryptionLayout(
) )
} }
DatabaseKeyField( SectionDivider()
PassphraseField(
newKey, newKey,
generalGetString(R.string.new_passphrase), generalGetString(R.string.new_passphrase),
modifier = Modifier.padding(horizontal = DEFAULT_PADDING), modifier = Modifier.padding(horizontal = DEFAULT_PADDING),
@ -201,7 +206,9 @@ fun DatabaseEncryptionLayout(
!validKey(newKey.value) || !validKey(newKey.value) ||
progressIndicator.value progressIndicator.value
DatabaseKeyField( SectionDivider()
PassphraseField(
confirmNewKey, confirmNewKey,
generalGetString(R.string.confirm_new_passphrase), generalGetString(R.string.confirm_new_passphrase),
modifier = Modifier.padding(horizontal = DEFAULT_PADDING), modifier = Modifier.padding(horizontal = DEFAULT_PADDING),
@ -212,7 +219,9 @@ fun DatabaseEncryptionLayout(
}), }),
) )
SectionItemViewSpaceBetween(onClickUpdate, disabled = disabled) { SectionDivider()
SectionItemViewSpaceBetween(onClickUpdate, disabled = disabled, minHeight = TextFieldDefaults.MinHeight) {
Text(generalGetString(R.string.update_database_passphrase), color = if (disabled) HighOrLowlight else MaterialTheme.colors.primary) Text(generalGetString(R.string.update_database_passphrase), color = if (disabled) HighOrLowlight else MaterialTheme.colors.primary)
} }
} }
@ -285,9 +294,10 @@ fun SavePassphraseSetting(
initialRandomDBPassphrase: Boolean, initialRandomDBPassphrase: Boolean,
storedKey: Boolean, storedKey: Boolean,
progressIndicator: Boolean, progressIndicator: Boolean,
minHeight: Dp = TextFieldDefaults.MinHeight,
onCheckedChange: (Boolean) -> Unit, onCheckedChange: (Boolean) -> Unit,
) { ) {
SectionItemView { SectionItemView(minHeight = minHeight) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Icon( Icon(
if (storedKey) Icons.Filled.VpnKey else Icons.Filled.VpnKeyOff, if (storedKey) Icons.Filled.VpnKey else Icons.Filled.VpnKeyOff,
@ -349,13 +359,14 @@ private fun operationEnded(m: ChatModel, progressIndicator: MutableState<Boolean
@OptIn(ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun DatabaseKeyField( fun PassphraseField(
key: MutableState<String>, key: MutableState<String>,
placeholder: String, placeholder: String,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
showStrength: Boolean = false, showStrength: Boolean = false,
isValid: (String) -> Boolean, isValid: (String) -> Boolean,
keyboardActions: KeyboardActions = KeyboardActions(), keyboardActions: KeyboardActions = KeyboardActions(),
dependsOn: MutableState<String>? = null,
) { ) {
var valid by remember { mutableStateOf(validKey(key.value)) } var valid by remember { mutableStateOf(validKey(key.value)) }
var showKey by remember { mutableStateOf(false) } var showKey by remember { mutableStateOf(false) }
@ -436,6 +447,13 @@ fun DatabaseKeyField(
) )
} }
) )
LaunchedEffect(Unit) {
snapshotFlow { dependsOn?.value }
.distinctUntilChanged()
.collect {
valid = isValid(state.value.text)
}
}
} }
// based on https://generatepasswords.org/how-to-calculate-entropy/ // based on https://generatepasswords.org/how-to-calculate-entropy/

View file

@ -206,7 +206,7 @@ private fun restoreDb(restoreDbFromBackup: MutableState<Boolean>, prefs: AppPref
@Composable @Composable
private fun DatabaseKeyField(text: MutableState<String>, enabled: Boolean, onClick: (() -> Unit)? = null) { private fun DatabaseKeyField(text: MutableState<String>, enabled: Boolean, onClick: (() -> Unit)? = null) {
DatabaseKeyField( PassphraseField(
text, text,
generalGetString(R.string.enter_passphrase), generalGetString(R.string.enter_passphrase),
isValid = ::validKey, isValid = ::validKey,

View file

@ -8,7 +8,6 @@ import SectionView
import android.content.Context import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.net.Uri import android.net.Uri
import android.os.FileUtils
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.compose.ManagedActivityResultLauncher
@ -40,6 +39,7 @@ import chat.simplex.app.views.helpers.*
import chat.simplex.app.views.usersettings.* import chat.simplex.app.views.usersettings.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.datetime.* import kotlinx.datetime.*
import org.apache.commons.io.IOUtils
import java.io.* import java.io.*
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -620,7 +620,7 @@ private fun saveArchiveFromUri(context: Context, importedArchiveUri: Uri): Strin
if (inputStream != null && archiveName != null) { if (inputStream != null && archiveName != null) {
val archivePath = "${context.cacheDir}/$archiveName" val archivePath = "${context.cacheDir}/$archiveName"
val destFile = File(archivePath) val destFile = File(archivePath)
FileUtils.copy(inputStream, FileOutputStream(destFile)) IOUtils.copy(inputStream, FileOutputStream(destFile))
archivePath archivePath
} else { } else {
Log.e(TAG, "saveArchiveFromUri null inputStream") Log.e(TAG, "saveArchiveFromUri null inputStream")

View file

@ -4,6 +4,7 @@ import android.content.res.Configuration
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -22,7 +23,11 @@ fun CloseSheetBar(close: () -> Unit, endButtons: @Composable RowScope.() -> Unit
Modifier Modifier
.padding(top = 4.dp), // Like in DefaultAppBar .padding(top = 4.dp), // Like in DefaultAppBar
content = { content = {
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Row(
Modifier.fillMaxWidth().height(TextFieldDefaults.MinHeight),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
NavigationButtonBack(close) NavigationButtonBack(close)
Row { Row {
endButtons() endButtons()

View file

@ -34,7 +34,7 @@ fun DefaultTopAppBar(
if (!showSearch) { if (!showSearch) {
title?.invoke() title?.invoke()
} else { } else {
SearchTextField(Modifier.fillMaxWidth(), stringResource(android.R.string.search_go), onSearchValueChanged) SearchTextField(Modifier.fillMaxWidth(), stringResource(android.R.string.search_go), alwaysVisible = false, onSearchValueChanged)
} }
}, },
backgroundColor = if (isInDarkTheme()) ToolbarDark else ToolbarLight, backgroundColor = if (isInDarkTheme()) ToolbarDark else ToolbarLight,

View file

@ -6,7 +6,6 @@ import android.content.*
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.* import android.graphics.*
import android.graphics.ImageDecoder.DecodeException
import android.net.Uri import android.net.Uri
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Base64 import android.util.Base64
@ -114,7 +113,7 @@ fun base64ToBitmap(base64ImageString: String): Bitmap {
class CustomTakePicturePreview(var uri: Uri?, var tmpFile: File?): ActivityResultContract<Void?, Uri?>() { class CustomTakePicturePreview(var uri: Uri?, var tmpFile: File?): ActivityResultContract<Void?, Uri?>() {
@CallSuper @CallSuper
override fun createIntent(context: Context, input: Void?): Intent { override fun createIntent(context: Context, input: Void?): Intent {
tmpFile = File.createTempFile("image", ".bmp", context.filesDir) tmpFile = File.createTempFile("image", ".bmp", File(getAppFilesDirectory(SimplexApp.context)))
// Since the class should return Uri, the file should be deleted somewhere else. And in order to be sure, delegate this to system // Since the class should return Uri, the file should be deleted somewhere else. And in order to be sure, delegate this to system
tmpFile?.deleteOnExit() tmpFile?.deleteOnExit()
uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.provider", tmpFile!!) uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.provider", tmpFile!!)
@ -205,17 +204,10 @@ fun GetImageBottomSheet(
val context = LocalContext.current val context = LocalContext.current
val processPickedImage = { uri: Uri? -> val processPickedImage = { uri: Uri? ->
if (uri != null) { if (uri != null) {
val source = ImageDecoder.createSource(context.contentResolver, uri) val bitmap = getBitmapFromUri(uri)
try { if (bitmap != null) {
val bitmap = ImageDecoder.decodeBitmap(source)
imageBitmap.value = uri imageBitmap.value = uri
onImageChange(bitmap) onImageChange(bitmap)
} catch (e: DecodeException) {
Log.e(TAG, "Unable to decode the image: ${e.stackTraceToString()}")
AlertManager.shared.showAlertMsg(
title = generalGetString(R.string.image_decoding_exception_title),
text = generalGetString(R.string.image_decoding_exception_desc)
)
} }
} }
} }

View file

@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.* import androidx.compose.ui.graphics.*
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
@ -29,15 +30,18 @@ import kotlinx.coroutines.delay
@OptIn(ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun SearchTextField(modifier: Modifier, placeholder: String, onValueChange: (String) -> Unit) { fun SearchTextField(modifier: Modifier, placeholder: String, alwaysVisible: Boolean, onValueChange: (String) -> Unit) {
var searchText by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) } var searchText by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) }
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val keyboard = LocalSoftwareKeyboardController.current val keyboard = LocalSoftwareKeyboardController.current
LaunchedEffect(Unit) { if (!alwaysVisible) {
focusRequester.requestFocus() LaunchedEffect(Unit) {
delay(200) focusRequester.requestFocus()
keyboard?.show() delay(200)
keyboard?.show()
}
} }
DisposableEffect(Unit) { DisposableEffect(Unit) {
@ -87,7 +91,14 @@ fun SearchTextField(modifier: Modifier, placeholder: String, onValueChange: (Str
Text(placeholder) Text(placeholder)
}, },
trailingIcon = if (searchText.text.isNotEmpty()) {{ trailingIcon = if (searchText.text.isNotEmpty()) {{
IconButton({ searchText = TextFieldValue(""); onValueChange("") }) { IconButton({
if (alwaysVisible) {
keyboard?.hide()
focusManager.clearFocus()
}
searchText = TextFieldValue("");
onValueChange("")
}) {
Icon(Icons.Default.Close, stringResource(R.string.icon_descr_close_button), tint = MaterialTheme.colors.primary,) Icon(Icons.Default.Close, stringResource(R.string.icon_descr_close_button), tint = MaterialTheme.colors.primary,)
} }
}} else null, }} else null,

View file

@ -1,5 +1,6 @@
package chat.simplex.app.views.helpers package chat.simplex.app.views.helpers
import android.Manifest
import android.content.* import android.content.*
import android.net.Uri import android.net.Uri
import android.provider.MediaStore import android.provider.MediaStore
@ -81,6 +82,7 @@ fun imageMimeType(fileName: String): String {
} }
} }
/** Before calling, make sure the user allows to write to external storage [Manifest.permission.WRITE_EXTERNAL_STORAGE] */
fun saveImage(cxt: Context, ciFile: CIFile?) { fun saveImage(cxt: Context, ciFile: CIFile?) {
val filePath = getLoadedFilePath(cxt, ciFile) val filePath = getLoadedFilePath(cxt, ciFile)
val fileName = ciFile?.fileName val fileName = ciFile?.fileName

View file

@ -9,6 +9,7 @@ import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.graphics.* import android.graphics.*
import android.graphics.Typeface import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.os.* import android.os.*
import android.provider.OpenableColumns import android.provider.OpenableColumns
@ -33,10 +34,12 @@ import androidx.compose.ui.unit.*
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import chat.simplex.app.* import chat.simplex.app.*
import chat.simplex.app.R
import chat.simplex.app.model.* import chat.simplex.app.model.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import org.apache.commons.io.IOUtils
import java.io.* import java.io.*
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -327,6 +330,14 @@ fun getFileName(context: Context, uri: Uri): String? {
} }
} }
fun getAppFilePath(context: Context, uri: Uri): String? {
return context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
getAppFilePath(context, cursor.getString(nameIndex))
}
}
fun getFileSize(context: Context, uri: Uri): Long? { fun getFileSize(context: Context, uri: Uri): Long? {
return context.contentResolver.query(uri, null, null, null, null)?.use { cursor -> return context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE) val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
@ -335,9 +346,48 @@ fun getFileSize(context: Context, uri: Uri): Long? {
} }
} }
fun getBitmapFromUri(uri: Uri, withAlertOnException: Boolean = true): Bitmap? {
return if (Build.VERSION.SDK_INT >= 28) {
val source = ImageDecoder.createSource(SimplexApp.context.contentResolver, uri)
try {
ImageDecoder.decodeBitmap(source)
} catch (e: android.graphics.ImageDecoder.DecodeException) {
Log.e(TAG, "Unable to decode the image: ${e.stackTraceToString()}")
if (withAlertOnException) {
AlertManager.shared.showAlertMsg(
title = generalGetString(R.string.image_decoding_exception_title),
text = generalGetString(R.string.image_decoding_exception_desc)
)
}
null
}
} else {
BitmapFactory.decodeFile(getAppFilePath(SimplexApp.context, uri))
}
}
fun getDrawableFromUri(uri: Uri, withAlertOnException: Boolean = true): Drawable? {
return if (Build.VERSION.SDK_INT >= 28) {
val source = ImageDecoder.createSource(SimplexApp.context.contentResolver, uri)
try {
ImageDecoder.decodeDrawable(source)
} catch (e: android.graphics.ImageDecoder.DecodeException) {
if (withAlertOnException) {
AlertManager.shared.showAlertMsg(
title = generalGetString(R.string.image_decoding_exception_title),
text = generalGetString(R.string.image_decoding_exception_desc)
)
}
Log.e(TAG, "Error while decoding drawable: ${e.stackTraceToString()}")
null
}
} else {
Drawable.createFromPath(getAppFilePath(SimplexApp.context, uri))
}
}
fun saveImage(context: Context, uri: Uri): String? { fun saveImage(context: Context, uri: Uri): String? {
val source = ImageDecoder.createSource(SimplexApp.context.contentResolver, uri) val bitmap = getBitmapFromUri(uri) ?: return null
val bitmap = ImageDecoder.decodeBitmap(source)
return saveImage(context, bitmap) return saveImage(context, bitmap)
} }
@ -408,7 +458,7 @@ fun saveFileFromUri(context: Context, uri: Uri): String? {
if (inputStream != null && fileToSave != null) { if (inputStream != null && fileToSave != null) {
val destFileName = uniqueCombine(context, fileToSave) val destFileName = uniqueCombine(context, fileToSave)
val destFile = File(getAppFilePath(context, destFileName)) val destFile = File(getAppFilePath(context, destFileName))
FileUtils.copy(inputStream, FileOutputStream(destFile)) IOUtils.copy(inputStream, FileOutputStream(destFile))
destFileName destFileName
} else { } else {
Log.e(chat.simplex.app.TAG, "Util.kt saveFileFromUri null inputStream") Log.e(chat.simplex.app.TAG, "Util.kt saveFileFromUri null inputStream")

View file

@ -0,0 +1,89 @@
package chat.simplex.app.views.usersettings
import SectionDivider
import SectionItemView
import SectionItemViewSpaceBetween
import SectionSpacer
import SectionTextFooter
import SectionView
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import chat.simplex.app.R
import chat.simplex.app.model.ChatModel
import chat.simplex.app.model.User
import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.chatlist.UserProfileRow
import chat.simplex.app.views.database.PassphraseField
import chat.simplex.app.views.helpers.*
@Composable
fun HiddenProfileView(
m: ChatModel,
user: User,
close: () -> Unit,
) {
HiddenProfileLayout(
user,
saveProfilePassword = { hidePassword ->
withBGApi {
try {
val u = m.controller.apiHideUser(user.userId, hidePassword)
m.updateUser(u)
close()
} catch (e: Exception) {
AlertManager.shared.showAlertMsg(
title = generalGetString(R.string.error_saving_user_password),
text = e.stackTraceToString()
)
}
}
}
)
}
@Composable
private fun HiddenProfileLayout(
user: User,
saveProfilePassword: (String) -> Unit
) {
Column(
Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(bottom = DEFAULT_BOTTOM_PADDING),
) {
AppBarTitle(stringResource(R.string.hide_profile))
SectionView(padding = PaddingValues(start = 8.dp, end = DEFAULT_PADDING)) {
UserProfileRow(user)
}
SectionSpacer()
val hidePassword = rememberSaveable { mutableStateOf("") }
val confirmHidePassword = rememberSaveable { mutableStateOf("") }
val confirmValid by remember { derivedStateOf { confirmHidePassword.value == "" || hidePassword.value == confirmHidePassword.value } }
val saveDisabled by remember { derivedStateOf { hidePassword.value == "" || confirmHidePassword.value == "" || !confirmValid } }
SectionView(stringResource(R.string.hidden_profile_password).uppercase()) {
SectionItemView {
PassphraseField(hidePassword, generalGetString(R.string.password_to_show), isValid = { true }, showStrength = true)
}
SectionDivider()
SectionItemView {
PassphraseField(confirmHidePassword, stringResource(R.string.confirm_password), isValid = { confirmValid }, dependsOn = hidePassword)
}
SectionDivider()
SectionItemViewSpaceBetween({ saveProfilePassword(hidePassword.value) }, disabled = saveDisabled, minHeight = TextFieldDefaults.MinHeight) {
Text(generalGetString(R.string.save_profile_password), color = if (saveDisabled) HighOrLowlight else MaterialTheme.colors.primary)
}
}
SectionTextFooter(stringResource(R.string.to_reveal_profile_enter_password))
}
}

View file

@ -6,6 +6,7 @@ import SectionSpacer
import SectionView import SectionView
import android.content.Context import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material.* import androidx.compose.material.*
@ -13,6 +14,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.* import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.* import androidx.compose.material.icons.outlined.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@ -20,7 +22,9 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.* import androidx.compose.ui.platform.*
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.capitalize
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.* import androidx.compose.ui.unit.*
@ -58,6 +62,18 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit) {
setPerformLA = setPerformLA, setPerformLA = setPerformLA,
showModal = { modalView -> { ModalManager.shared.showModal { modalView(chatModel) } } }, showModal = { modalView -> { ModalManager.shared.showModal { modalView(chatModel) } } },
showSettingsModal = { modalView -> { ModalManager.shared.showModal(true) { modalView(chatModel) } } }, showSettingsModal = { modalView -> { ModalManager.shared.showModal(true) { modalView(chatModel) } } },
showSettingsModalWithSearch = { modalView ->
ModalManager.shared.showCustomModal { close ->
val search = rememberSaveable { mutableStateOf("") }
ModalView(
{ close() },
if (isInDarkTheme()) MaterialTheme.colors.background else SettingsBackgroundLight,
endButtons = {
SearchTextField(Modifier.fillMaxWidth(), stringResource(android.R.string.search_go), alwaysVisible = true) { search.value = it }
},
content = { modalView(chatModel, search) })
}
},
showCustomModal = { modalView -> { ModalManager.shared.showCustomModal { close -> modalView(chatModel, close) } } }, showCustomModal = { modalView -> { ModalManager.shared.showCustomModal { close -> modalView(chatModel, close) } } },
showVersion = { showVersion = {
withApi { withApi {
@ -115,6 +131,7 @@ fun SettingsLayout(
setPerformLA: (Boolean) -> Unit, setPerformLA: (Boolean) -> Unit,
showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
showSettingsModalWithSearch: (@Composable (ChatModel, MutableState<String>) -> Unit) -> Unit,
showCustomModal: (@Composable (ChatModel, () -> Unit) -> Unit) -> (() -> Unit), showCustomModal: (@Composable (ChatModel, () -> Unit) -> Unit) -> (() -> Unit),
showVersion: () -> Unit, showVersion: () -> Unit,
withAuth: (block: () -> Unit) -> Unit withAuth: (block: () -> Unit) -> Unit
@ -141,7 +158,8 @@ fun SettingsLayout(
ProfilePreview(profile, stopped = stopped) ProfilePreview(profile, stopped = stopped)
} }
SectionDivider() SectionDivider()
SettingsActionItem(Icons.Outlined.ManageAccounts, stringResource(R.string.your_chat_profiles), { withAuth { showSettingsModal { UserProfilesView(it) }() } }, disabled = stopped) val profileHidden = rememberSaveable { mutableStateOf(false) }
SettingsActionItem(Icons.Outlined.ManageAccounts, stringResource(R.string.your_chat_profiles), { withAuth { showSettingsModalWithSearch { it, search -> UserProfilesView(it, search, profileHidden) } } }, disabled = stopped)
SectionDivider() SectionDivider()
SettingsIncognitoActionItem(incognitoPref, incognito, stopped) { showModal { IncognitoView() }() } SettingsIncognitoActionItem(incognitoPref, incognito, stopped) { showModal { IncognitoView() }() }
SectionDivider() SectionDivider()
@ -531,6 +549,7 @@ fun PreviewSettingsLayout() {
setPerformLA = {}, setPerformLA = {},
showModal = { {} }, showModal = { {} },
showSettingsModal = { {} }, showSettingsModal = { {} },
showSettingsModalWithSearch = { },
showCustomModal = { {} }, showCustomModal = { {} },
showVersion = {}, showVersion = {},
withAuth = {}, withAuth = {},

View file

@ -2,6 +2,7 @@ package chat.simplex.app.views.usersettings
import SectionDivider import SectionDivider
import SectionItemView import SectionItemView
import SectionSpacer
import SectionTextFooter import SectionTextFooter
import SectionView import SectionView
import androidx.compose.foundation.* import androidx.compose.foundation.*
@ -10,6 +11,7 @@ import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.* import androidx.compose.material.icons.outlined.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -17,18 +19,28 @@ import androidx.compose.ui.text.*
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import chat.simplex.app.R import chat.simplex.app.R
import chat.simplex.app.chatPasswordHash
import chat.simplex.app.model.* import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.* import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.chat.item.ItemAction import chat.simplex.app.views.chat.item.ItemAction
import chat.simplex.app.views.chatlist.UserProfilePickerItem import chat.simplex.app.views.chatlist.UserProfilePickerItem
import chat.simplex.app.views.helpers.* import chat.simplex.app.views.helpers.*
import chat.simplex.app.views.onboarding.CreateProfile import chat.simplex.app.views.onboarding.CreateProfile
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable @Composable
fun UserProfilesView(m: ChatModel) { fun UserProfilesView(m: ChatModel, search: MutableState<String>, profileHidden: MutableState<Boolean>) {
val searchTextOrPassword = rememberSaveable { search }
val users by remember { derivedStateOf { m.users.map { it.user } } } val users by remember { derivedStateOf { m.users.map { it.user } } }
val filteredUsers by remember { derivedStateOf { filteredUsers(m, searchTextOrPassword.value) } }
UserProfilesView( UserProfilesView(
users = users, users = users,
filteredUsers = filteredUsers,
profileHidden = profileHidden,
searchTextOrPassword = searchTextOrPassword,
showHiddenProfilesNotice = m.controller.appPrefs.showHiddenProfilesNotice,
visibleUsersCount = visibleUsersCount(m),
addUser = { addUser = {
ModalManager.shared.showModalCloseable { close -> ModalManager.shared.showModalCloseable { close ->
CreateProfile(m, close) CreateProfile(m, close)
@ -36,38 +48,72 @@ fun UserProfilesView(m: ChatModel) {
}, },
activateUser = { user -> activateUser = { user ->
withBGApi { withBGApi {
m.controller.changeActiveUser(user.userId) m.controller.changeActiveUser(user.userId, userViewPassword(user, searchTextOrPassword.value))
} }
}, },
removeUser = { user -> removeUser = { user ->
val text = buildAnnotatedString { if (m.users.size > 1 && (user.hidden || visibleUsersCount(m) > 1)) {
append(generalGetString(R.string.users_delete_all_chats_deleted) + "\n\n" + generalGetString(R.string.users_delete_profile_for) + " ") val text = buildAnnotatedString {
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append(generalGetString(R.string.users_delete_all_chats_deleted) + "\n\n" + generalGetString(R.string.users_delete_profile_for) + " ")
append(user.displayName) withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
append(user.displayName)
}
append(":")
} }
append(":") AlertManager.shared.showAlertDialogButtonsColumn(
} title = generalGetString(R.string.users_delete_question),
AlertManager.shared.showAlertDialogButtonsColumn( text = text,
title = generalGetString(R.string.users_delete_question), buttons = {
text = text, Column {
buttons = { SectionItemView({
Column { AlertManager.shared.hideAlert()
SectionItemView({ removeUser(m, user, users, true, searchTextOrPassword.value)
AlertManager.shared.hideAlert() }) {
removeUser(m, user, users, true) Text(stringResource(R.string.users_delete_with_connections), color = Color.Red)
}) { }
Text(stringResource(R.string.users_delete_with_connections), color = Color.Red) SectionItemView({
} AlertManager.shared.hideAlert()
SectionItemView({ removeUser(m, user, users, false, searchTextOrPassword.value)
AlertManager.shared.hideAlert() }
removeUser(m, user, users, false) ) {
} Text(stringResource(R.string.users_delete_data_only), color = Color.Red)
) { }
Text(stringResource(R.string.users_delete_data_only), color = Color.Red)
} }
} }
)
} else {
AlertManager.shared.showAlertMsg(
title = generalGetString(R.string.cant_delete_user_profile),
text = if (m.users.size > 1) {
generalGetString(R.string.should_be_at_least_one_visible_profile)
} else {
generalGetString(R.string.should_be_at_least_one_profile)
}
)
}
},
unhideUser = { user ->
setUserPrivacy(m) { m.controller.apiUnhideUser(user.userId, userViewPassword(user, searchTextOrPassword.value)) }
},
muteUser = { user ->
setUserPrivacy(m, onSuccess = { if (m.controller.appPrefs.showMuteProfileAlert.get()) showMuteProfileAlert(m.controller.appPrefs.showMuteProfileAlert) }) {
m.controller.apiMuteUser(user.userId, userViewPassword(user, searchTextOrPassword.value))
}
},
unmuteUser = { user ->
setUserPrivacy(m) { m.controller.apiUnmuteUser(user.userId, userViewPassword(user, searchTextOrPassword.value)) }
},
showHiddenProfile = { user ->
ModalManager.shared.showModalCloseable(true) { close ->
HiddenProfileView(m, user) {
profileHidden.value = true
withBGApi {
delay(10_000)
profileHidden.value = false
}
close()
} }
) }
} }
) )
} }
@ -75,9 +121,18 @@ fun UserProfilesView(m: ChatModel) {
@Composable @Composable
private fun UserProfilesView( private fun UserProfilesView(
users: List<User>, users: List<User>,
filteredUsers: List<User>,
searchTextOrPassword: MutableState<String>,
profileHidden: MutableState<Boolean>,
visibleUsersCount: Int,
showHiddenProfilesNotice: SharedPreference<Boolean>,
addUser: () -> Unit, addUser: () -> Unit,
activateUser: (User) -> Unit, activateUser: (User) -> Unit,
removeUser: (User) -> Unit, removeUser: (User) -> Unit,
unhideUser: (User) -> Unit,
muteUser: (User) -> Unit,
unmuteUser: (User) -> Unit,
showHiddenProfile: (User) -> Unit,
) { ) {
Column( Column(
Modifier Modifier
@ -85,25 +140,59 @@ private fun UserProfilesView(
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
.padding(bottom = DEFAULT_PADDING), .padding(bottom = DEFAULT_PADDING),
) { ) {
if (profileHidden.value) {
SectionView {
SettingsActionItem(Icons.Outlined.LockOpen, stringResource(R.string.enter_password_to_show), click = {
profileHidden.value = false
}
)
}
SectionSpacer()
}
AppBarTitle(stringResource(R.string.your_chat_profiles)) AppBarTitle(stringResource(R.string.your_chat_profiles))
SectionView { SectionView {
for (user in users) { for (user in filteredUsers) {
UserView(user, users, activateUser, removeUser) UserView(user, users, visibleUsersCount, activateUser, removeUser, unhideUser, muteUser, unmuteUser, showHiddenProfile)
SectionDivider() SectionDivider()
} }
SectionItemView(addUser, minHeight = 68.dp) { if (searchTextOrPassword.value.isEmpty()) {
Icon(Icons.Outlined.Add, stringResource(R.string.users_add), tint = MaterialTheme.colors.primary) SectionItemView(addUser, minHeight = 68.dp) {
Spacer(Modifier.padding(horizontal = 4.dp)) Icon(Icons.Outlined.Add, stringResource(R.string.users_add), tint = MaterialTheme.colors.primary)
Text(stringResource(R.string.users_add), color = MaterialTheme.colors.primary) Spacer(Modifier.padding(horizontal = 4.dp))
Text(stringResource(R.string.users_add), color = MaterialTheme.colors.primary)
}
}
}
SectionTextFooter(stringResource(R.string.tap_to_activate_profile))
LaunchedEffect(Unit) {
if (showHiddenProfilesNotice.state.value && users.size > 1) {
AlertManager.shared.showAlertDialog(
title = generalGetString(R.string.make_profile_private),
text = generalGetString(R.string.you_can_hide_or_mute_user_profile),
confirmText = generalGetString(R.string.ok),
dismissText = generalGetString(R.string.dont_show_again),
onDismiss = {
showHiddenProfilesNotice.set(false)
},
)
} }
} }
SectionTextFooter(stringResource(R.string.your_chat_profiles_stored_locally))
} }
} }
@Composable @Composable
private fun UserView(user: User, users: List<User>, activateUser: (User) -> Unit, removeUser: (User) -> Unit) { private fun UserView(
user: User,
users: List<User>,
visibleUsersCount: Int,
activateUser: (User) -> Unit,
removeUser: (User) -> Unit,
unhideUser: (User) -> Unit,
muteUser: (User) -> Unit,
unmuteUser: (User) -> Unit,
showHiddenProfile: (User) -> Unit,
) {
var showDropdownMenu by remember { mutableStateOf(false) } var showDropdownMenu by remember { mutableStateOf(false) }
UserProfilePickerItem(user, onLongClick = { if (users.size > 1) showDropdownMenu = true }) { UserProfilePickerItem(user, onLongClick = { if (users.size > 1) showDropdownMenu = true }) {
activateUser(user) activateUser(user)
@ -114,28 +203,103 @@ private fun UserView(user: User, users: List<User>, activateUser: (User) -> Unit
onDismissRequest = { showDropdownMenu = false }, onDismissRequest = { showDropdownMenu = false },
Modifier.width(220.dp) Modifier.width(220.dp)
) { ) {
if (user.hidden) {
ItemAction(stringResource(R.string.user_unhide), Icons.Outlined.LockOpen, onClick = {
showDropdownMenu = false
unhideUser(user)
})
} else {
if (visibleUsersCount > 1) {
ItemAction(stringResource(R.string.user_hide), Icons.Outlined.Lock, onClick = {
showDropdownMenu = false
showHiddenProfile(user)
})
}
if (user.showNtfs) {
ItemAction(stringResource(R.string.user_mute), Icons.Outlined.NotificationsOff, onClick = {
showDropdownMenu = false
muteUser(user)
})
} else {
ItemAction(stringResource(R.string.user_unmute), Icons.Outlined.Notifications, onClick = {
showDropdownMenu = false
unmuteUser(user)
})
}
}
ItemAction(stringResource(R.string.delete_verb), Icons.Outlined.Delete, color = Color.Red, onClick = { ItemAction(stringResource(R.string.delete_verb), Icons.Outlined.Delete, color = Color.Red, onClick = {
removeUser(user) removeUser(user)
showDropdownMenu = false showDropdownMenu = false
} })
)
} }
} }
} }
private fun removeUser(m: ChatModel, user: User, users: List<User>, delSMPQueues: Boolean) { private fun filteredUsers(m: ChatModel, searchTextOrPassword: String): List<User> {
val s = searchTextOrPassword.trim()
val lower = s.lowercase()
return m.users.filter { u ->
if ((u.user.activeUser || u.user.viewPwdHash == null) && (s == "" || u.user.chatViewName.lowercase().contains(lower))) {
true
} else if (u.user.viewPwdHash != null) {
s != "" && chatPasswordHash(s, u.user.viewPwdHash.salt) == u.user.viewPwdHash.hash
} else {
false
}
}.map { it.user }
}
private fun visibleUsersCount(m: ChatModel): Int = m.users.filter { u -> !u.user.hidden }.size
private fun userViewPassword(user: User, searchTextOrPassword: String): String? =
if (user.activeUser || !user.hidden) null else searchTextOrPassword
private fun removeUser(m: ChatModel, user: User, users: List<User>, delSMPQueues: Boolean, searchTextOrPassword: String) {
if (users.size < 2) return if (users.size < 2) return
withBGApi { withBGApi {
suspend fun deleteUser(user: User) {
m.controller.apiDeleteUser(user.userId, delSMPQueues, userViewPassword(user, searchTextOrPassword))
m.removeUser(user)
}
try { try {
if (user.activeUser) { if (user.activeUser) {
val newActive = users.first { !it.activeUser } val newActive = users.firstOrNull { u -> !u.activeUser && !u.hidden }
m.controller.changeActiveUser_(newActive.userId) if (newActive != null) {
m.controller.changeActiveUser_(newActive.userId, null)
deleteUser(user.copy(activeUser = false))
}
} else {
deleteUser(user)
} }
m.controller.apiDeleteUser(user.userId, delSMPQueues)
m.users.removeAll { it.user.userId == user.userId }
} catch (e: Exception) { } catch (e: Exception) {
AlertManager.shared.showAlertMsg(generalGetString(R.string.error_deleting_user), e.stackTraceToString()) AlertManager.shared.showAlertMsg(generalGetString(R.string.error_deleting_user), e.stackTraceToString())
} }
} }
} }
private fun setUserPrivacy(m: ChatModel, onSuccess: (() -> Unit)? = null, api: suspend () -> User) {
withBGApi {
try {
m.updateUser(api())
onSuccess?.invoke()
} catch (e: Exception) {
AlertManager.shared.showAlertMsg(
title = generalGetString(R.string.error_updating_user_privacy),
text = e.stackTraceToString()
)
}
}
}
private fun showMuteProfileAlert(showMuteProfileAlert: SharedPreference<Boolean>) {
AlertManager.shared.showAlertDialog(
title = generalGetString(R.string.muted_when_inactive),
text = generalGetString(R.string.you_will_still_receive_calls_and_ntfs),
confirmText = generalGetString(R.string.ok),
dismissText = generalGetString(R.string.dont_show_again),
onDismiss = {
showMuteProfileAlert.set(false)
},
)
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="@color/highOrLowLight" />
<size android:width="1dp" />
</shape>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="allow_voice_messages_only_if">Povolte hlasové zprávy, pouze pokud je váš kontakt povolí.</string> <string name="allow_voice_messages_only_if">Povolit hlasové zprávy, pokud je váš kontakt povolí.</string>
<string name="allow_to_send_disappearing">Mizící zprávy povoleny.</string> <string name="allow_to_send_disappearing">Mizící zprávy povoleny.</string>
<string name="allow_to_send_voice">Hlasové zprávy povoleny.</string> <string name="allow_to_send_voice">Hlasové zprávy povoleny.</string>
<string name="v4_2_group_links_desc">Správci mohou vytvářet odkazy pro připojení ke skupinám.</string> <string name="v4_2_group_links_desc">Správci mohou vytvářet odkazy pro připojení ke skupinám.</string>
@ -48,7 +48,7 @@
<string name="conn_stats_section_title_servers">SERVERY</string> <string name="conn_stats_section_title_servers">SERVERY</string>
<string name="receiving_via">Příjímáno přez</string> <string name="receiving_via">Příjímáno přez</string>
<string name="create_secret_group_title">Vytvoření tajné skupiny</string> <string name="create_secret_group_title">Vytvoření tajné skupiny</string>
<string name="group_display_name_field">Zobrazení názvu skupiny:</string> <string name="group_display_name_field">Zobrazený název skupiny:</string>
<string name="group_full_name_field">Úplný název skupiny:</string> <string name="group_full_name_field">Úplný název skupiny:</string>
<string name="group_main_profile_sent">Váš chat profil bude zaslán členům skupiny</string> <string name="group_main_profile_sent">Váš chat profil bude zaslán členům skupiny</string>
<string name="group_profile_is_stored_on_members_devices">Profil skupiny je uložen v zařízeních členů, nikoli na serverech.</string> <string name="group_profile_is_stored_on_members_devices">Profil skupiny je uložen v zařízeních členů, nikoli na serverech.</string>
@ -854,7 +854,7 @@
<string name="skip_inviting_button">Přeskočit pozvání členů</string> <string name="skip_inviting_button">Přeskočit pozvání členů</string>
<string name="select_contacts">Vybrat kontakty</string> <string name="select_contacts">Vybrat kontakty</string>
<string name="icon_descr_contact_checked">Zkontrolované kontakty</string> <string name="icon_descr_contact_checked">Zkontrolované kontakty</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> kontakt(y) vybrán(y)</string> <string name="num_contacts_selected">%d kontakt(y) vybrán(y)</string>
<string name="button_add_members">Pozvat členy</string> <string name="button_add_members">Pozvat členy</string>
<string name="group_info_section_title_num_members"><xliff:g id="num_members">%1$s</xliff:g> MEMBERS</string> <string name="group_info_section_title_num_members"><xliff:g id="num_members">%1$s</xliff:g> MEMBERS</string>
<string name="group_info_member_you">vy: <xliff:g id="group_info_you">%1$s</xliff:g></string> <string name="group_info_member_you">vy: <xliff:g id="group_info_you">%1$s</xliff:g></string>
@ -906,7 +906,7 @@
<string name="theme_light">Světlé</string> <string name="theme_light">Světlé</string>
<string name="theme_dark">Tmavé</string> <string name="theme_dark">Tmavé</string>
<string name="theme">Téma</string> <string name="theme">Téma</string>
<string name="chat_preferences_contact_allows">Kontakt povolen</string> <string name="chat_preferences_contact_allows">Kontakt povolil</string>
<string name="chat_preferences_on">zapnuto</string> <string name="chat_preferences_on">zapnuto</string>
<string name="chat_preferences_off">vypnuto</string> <string name="chat_preferences_off">vypnuto</string>
<string name="chat_preferences">Chat předvolby</string> <string name="chat_preferences">Chat předvolby</string>
@ -963,7 +963,6 @@
<string name="your_contact_address">Vaše adresa</string> <string name="your_contact_address">Vaše adresa</string>
<string name="your_chat_profile_will_be_sent_to_your_contact">Váš chat profil bude odeslán <string name="your_chat_profile_will_be_sent_to_your_contact">Váš chat profil bude odeslán
\nvašemu kontaktu</string> \nvašemu kontaktu</string>
<string name="your_chat_profiles_stored_locally">Vaše chat profily jsou uloženy lokálně, pouze ve vašem zařízení.</string>
<string name="your_chats">Vaše konverzace</string> <string name="your_chats">Vaše konverzace</string>
<string name="paste_connection_link_below_to_connect">Do níže uvedeného pole vložte odkaz, který jste obdrželi pro spojení s kontaktem.</string> <string name="paste_connection_link_below_to_connect">Do níže uvedeného pole vložte odkaz, který jste obdrželi pro spojení s kontaktem.</string>
<string name="share_invitation_link">Sdílet pozvánku</string> <string name="share_invitation_link">Sdílet pozvánku</string>
@ -981,4 +980,41 @@
<string name="error_updating_link_for_group">Chyba aktualizace odkazu skupiny</string> <string name="error_updating_link_for_group">Chyba aktualizace odkazu skupiny</string>
<string name="initial_member_role">Počáteční role</string> <string name="initial_member_role">Počáteční role</string>
<string name="language_system">Systém</string> <string name="language_system">Systém</string>
<string name="smp_save_servers_question">Uložit servery\?</string>
<string name="dont_show_again">Znovu neukazuj</string>
<string name="cant_delete_user_profile">Nemohu smazat uživatelský profil!</string>
<string name="button_add_welcome_message">Přidat uvítací zprávu</string>
<string name="v4_6_chinese_spanish_interface">Čínské a Španělské rozhranní</string>
<string name="v4_6_audio_video_calls">Hlasové a video hovory</string>
<string name="confirm_password">Potvrdit heslo</string>
<string name="enter_password_to_show">Pro zobrazení zadejte heslo výše!</string>
<string name="v4_6_reduced_battery_usage">Další snížení spotřeby baterie</string>
<string name="error_saving_user_password">Chyba ukládání hesla uživatele</string>
<string name="error_updating_user_privacy">Chyba aktualizace soukromí uživatele</string>
<string name="v4_6_group_moderation">Správa skupin</string>
<string name="v4_6_group_welcome_message">Uvítací zpráva skupin</string>
<string name="v4_6_hidden_chat_profiles">Skryté chat profily</string>
<string name="hidden_profile_password">Hesla skrytých profilů</string>
<string name="user_hide">Skrýt</string>
<string name="hide_profile">Skrýt profil</string>
<string name="make_profile_private">Změnit profil na soukromý!</string>
<string name="v4_6_reduced_battery_usage_descr">Další vylepšení již brzy!</string>
<string name="v4_6_group_moderation_descr">Nyní mohou správci:
\n- mazat zprávy členů.
\n- zakázat členy (role \"pozorovatel\")</string>
<string name="save_profile_password">Uložit heslo profilu</string>
<string name="user_mute">Ztlumit</string>
<string name="v4_6_hidden_chat_profiles_descr">Chraňte své chat profily heslem!</string>
<string name="save_and_update_group_profile">Uložit a aktualizovat profil skupiny</string>
<string name="muted_when_inactive">Ztlumit při neaktivitě!</string>
<string name="password_to_show">Heslo k zobrazení</string>
<string name="save_welcome_message_question">Uložit uvítací zprávu\?</string>
<string name="v4_6_group_welcome_message_descr">Nastavte zprávu zobrazenou novým členům!</string>
<string name="v4_6_audio_video_calls_descr">Podpora bluetooth a další vylepšení.</string>
<string name="tap_to_activate_profile">Klepnutím aktivujete profil.</string>
<string name="v4_6_chinese_spanish_interface_descr">Díky uživatelům - překládejte prostřednictvím Weblate!</string>
<string name="should_be_at_least_one_profile">Měl by tam být alespoň jeden uživatelský profil.</string>
<string name="button_welcome_message">Uvítací zpráva</string>
<string name="group_welcome_title">Uvítací zpráva</string>
<string name="user_unmute">Zrušit ztlumení</string>
</resources> </resources>

View file

@ -765,7 +765,7 @@
<string name="select_contacts">Kontakte auswählen</string> <string name="select_contacts">Kontakte auswählen</string>
<string name="icon_descr_contact_checked">Kontakt geprüft</string> <string name="icon_descr_contact_checked">Kontakt geprüft</string>
<string name="clear_contacts_selection_button">Löschen</string> <string name="clear_contacts_selection_button">Löschen</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> Kontakt(e) ausgewählt</string> <string name="num_contacts_selected">%d Kontakt(e) ausgewählt</string>
<string name="no_contacts_selected">Keine Kontakte ausgewählt</string> <string name="no_contacts_selected">Keine Kontakte ausgewählt</string>
<string name="invite_prohibited">Kontakt kann nicht eingeladen werden!</string> <string name="invite_prohibited">Kontakt kann nicht eingeladen werden!</string>
<string name="invite_prohibited_description">Sie versuchen, einen Kontakt, mit dem Sie ein Inkognito-Profil geteilt haben, in die Gruppe einzuladen, in der Sie Ihr Hauptprofil verwenden.</string> <string name="invite_prohibited_description">Sie versuchen, einen Kontakt, mit dem Sie ein Inkognito-Profil geteilt haben, in die Gruppe einzuladen, in der Sie Ihr Hauptprofil verwenden.</string>
@ -1023,7 +1023,6 @@
<string name="users_delete_data_only">Nur lokale Profildaten</string> <string name="users_delete_data_only">Nur lokale Profildaten</string>
<string name="users_delete_with_connections">Profil und Serververbindungen</string> <string name="users_delete_with_connections">Profil und Serververbindungen</string>
<string name="messages_section_description">Diese Einstellung gilt für Nachrichten in Ihrem aktuellen Chat-Profil</string> <string name="messages_section_description">Diese Einstellung gilt für Nachrichten in Ihrem aktuellen Chat-Profil</string>
<string name="your_chat_profiles_stored_locally">Ihre Chat-Profile werden nur lokal auf Ihrem Endgerät gespeichert</string>
<string name="failed_to_create_user_duplicate_title">Doppelter Anzeigename!</string> <string name="failed_to_create_user_duplicate_title">Doppelter Anzeigename!</string>
<string name="failed_to_create_user_title">Fehler beim Erstellen des Profils!</string> <string name="failed_to_create_user_title">Fehler beim Erstellen des Profils!</string>
<string name="failed_to_active_user_title">Fehler beim Umschalten des Profils!</string> <string name="failed_to_active_user_title">Fehler beim Umschalten des Profils!</string>
@ -1055,4 +1054,46 @@
<string name="observer_cant_send_message_desc">Bitte kontaktieren Sie den Gruppen-Administrator.</string> <string name="observer_cant_send_message_desc">Bitte kontaktieren Sie den Gruppen-Administrator.</string>
<string name="moderate_message_will_be_deleted_warning">Diese Nachricht wird für alle Gruppenmitglieder gelöscht.</string> <string name="moderate_message_will_be_deleted_warning">Diese Nachricht wird für alle Gruppenmitglieder gelöscht.</string>
<string name="language_system">System</string> <string name="language_system">System</string>
<string name="confirm_password">Bestätigen Sie das Passwort</string>
<string name="cant_delete_user_profile">Das Benutzerprofil kann nicht gelöscht werden!</string>
<string name="dont_show_again">Nicht nochmals anzeigen</string>
<string name="v4_6_chinese_spanish_interface">Chinesische und spanische Bedienoberfläche</string>
<string name="v4_6_audio_video_calls">Audio- und Videoanrufe</string>
<string name="button_add_welcome_message">Fügen Sie eine Begrüßungsmeldung hinzu</string>
<string name="error_updating_user_privacy">Fehler beim Aktualisieren der Benutzer-Privatsphäre</string>
<string name="smp_save_servers_question">Alle Server speichern\?</string>
<string name="hide_profile">Verberge das Profil</string>
<string name="password_to_show">Passwort anzeigen</string>
<string name="save_profile_password">Profil-Passwort speichern</string>
<string name="error_saving_user_password">Fehler beim Speichern des Benutzer-Passworts</string>
<string name="hidden_profile_password">Verborgenes Profil-Passwort</string>
<string name="button_welcome_message">Begrüßungsmeldung</string>
<string name="save_welcome_message_question">Begrüßungsmeldung speichern\?</string>
<string name="user_unhide">Verbergen aufheben</string>
<string name="enter_password_to_show">Geben Sie oben das Passwort für die Anzeige an!</string>
<string name="make_profile_private">Erzeugen Sie ein privates Profil!</string>
<string name="user_mute">Stummschalten</string>
<string name="tap_to_activate_profile">Tippen Sie, um das Profil zu aktivieren.</string>
<string name="should_be_at_least_one_profile">Es muss mindestens ein Benutzer-Profil vorhanden sein.</string>
<string name="should_be_at_least_one_visible_profile">Es muss mindestens ein sichtbares Benutzer-Profil vorhanden sein.</string>
<string name="user_unmute">Stummschaltung aufheben</string>
<string name="muted_when_inactive">Bei Inaktivität stummgeschaltet!</string>
<string name="v4_6_hidden_chat_profiles_descr">Schützen Sie Ihre Chat-Profile mit einem Passwort!</string>
<string name="v4_6_audio_video_calls_descr">Bluetooth-Unterstützung und weitere Verbesserungen.</string>
<string name="v4_6_group_moderation_descr">Administratoren können nun
\n- Nachrichten von Gruppenmitgliedern löschen
\n- Gruppenmitglieder deaktivieren (\"Beobachter\"-Rolle)</string>
<string name="v4_6_group_welcome_message">Gruppen-Begrüßungsmeldung</string>
<string name="v4_6_reduced_battery_usage">Weiter reduzierter Batterieverbrauch</string>
<string name="v4_6_reduced_battery_usage_descr">Weitere Verbesserungen sind bald verfügbar!</string>
<string name="v4_6_group_welcome_message_descr">Legen Sie die Nachricht fest, die neuen Mitgliedern angezeigt werden soll!</string>
<string name="v4_6_chinese_spanish_interface_descr">Dank der Nutzer - Tragen Sie per Weblate bei!</string>
<string name="v4_6_group_moderation">Gruppenmoderation</string>
<string name="v4_6_hidden_chat_profiles">Verborgene Chat-Profile</string>
<string name="user_hide">Verberge</string>
<string name="save_and_update_group_profile">Sichern und aktualisieren des Gruppen-Profils</string>
<string name="you_will_still_receive_calls_and_ntfs">Sie können Anrufe und Benachrichtigungen auch von stummgeschalteten Profilen empfangen, solange diese aktiv sind.</string>
<string name="group_welcome_title">Begrüßungsmeldung</string>
<string name="you_can_hide_or_mute_user_profile">Sie können ein Benutzerprofil verbergen oder stummschalten - für das Menü gedrückt halten.</string>
<string name="to_reveal_profile_enter_password">Geben Sie ein vollständiges Passwort in das Suchfeld auf der Seite \"Meine Chat-Profile\" ein, um Ihr verborgenes Profil zu sehen.</string>
</resources> </resources>

View file

@ -10,20 +10,20 @@
<string name="chat_item_ttl_day">un dia</string> <string name="chat_item_ttl_day">un dia</string>
<string name="chat_item_ttl_month">un mes</string> <string name="chat_item_ttl_month">un mes</string>
<string name="chat_item_ttl_week">una semana</string> <string name="chat_item_ttl_week">una semana</string>
<string name="allow_disappearing_messages_only_if">Permitir que desaparezcan los mensajes sólo si su contacto lo permite.</string> <string name="allow_disappearing_messages_only_if">Permitir mensajes temporales sólo si tu contacto los permite.</string>
<string name="v4_3_improved_server_configuration_desc">Añadir servidores escaneando códigos QR.</string> <string name="v4_3_improved_server_configuration_desc">Añadir servidores escaneando códigos QR.</string>
<string name="smp_servers_preset_add">Añadir servidores predefinidos</string> <string name="smp_servers_preset_add">Añadir servidores predefinidos</string>
<string name="all_group_members_will_remain_connected">Todos los miembros del grupo permanecerán conectados.</string> <string name="all_group_members_will_remain_connected">Todos los miembros del grupo permanecerán conectados.</string>
<string name="allow_irreversible_message_deletion_only_if">Permitir la eliminación irreversible de mensajes sólo si tu contacto también lo permite para tí.</string> <string name="allow_irreversible_message_deletion_only_if">Permitir la eliminación irreversible de mensajes sólo si tu contacto también lo permite.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore se usará para almacenar de forma segura la frase de contraseña después de reiniciar la aplicación o cambiar la frase de contraseña - permitirá recibir notificaciones.</string> <string name="keychain_allows_to_receive_ntfs">Android Keystore se usará para almacenar de forma segura la frase de contraseña después de reiniciar la aplicación o cambiar la frase de contraseña - permitirá recibir notificaciones.</string>
<string name="allow_your_contacts_to_send_disappearing_messages">Permitir a tus contactos enviar mensajes que desaparecen.</string> <string name="allow_your_contacts_to_send_disappearing_messages">Permitir a tus contactos enviar mensajes temporales</string>
<string name="allow_your_contacts_to_send_voice_messages">Permitir a tus contactos enviar mensajes de voz.</string> <string name="allow_your_contacts_to_send_voice_messages">Permitir a tus contactos enviar mensajes de voz.</string>
<string name="chat_preferences_always">siempre</string> <string name="chat_preferences_always">siempre</string>
<string name="notifications_mode_off_desc">La aplicación sólo puede recibir notificaciones cuando se está ejecutando, no se iniciará ningún servicio en segundo plano.</string> <string name="notifications_mode_off_desc">La aplicación sólo puede recibir notificaciones cuando se está ejecutando, no se iniciará ningún servicio en segundo plano.</string>
<string name="settings_section_title_icon">ICONO DE LA APLICACIÓN</string> <string name="settings_section_title_icon">ICONO DE LA APLICACIÓN</string>
<string name="incognito_random_profile_from_contact_description">Se enviará un perfil aleatorio al contacto del que recibió este enlace</string> <string name="incognito_random_profile_from_contact_description">Se enviará un perfil aleatorio al contacto del que recibió este enlace</string>
<string name="turning_off_service_and_periodic">La optimización de la batería está activa, desactivando el servicio en segundo plano y las solicitudes periódicas de nuevos mensajes. Puedes volver a activarlos en Configuración.</string> <string name="turning_off_service_and_periodic">La optimización de la batería está activa, desactivando el servicio en segundo plano y las solicitudes periódicas de nuevos mensajes. Puedes volver a activarlos en Configuración.</string>
<string name="notifications_mode_service_desc">El servicio en segundo plano está siempre en funcionamiento las notificaciones se mostrarán en cuanto los mensajes estén disponibles.</string> <string name="notifications_mode_service_desc">El servicio en segundo plano está siempre en funcionamiento las notificaciones se muestran en cuanto los mensajes estén disponibles.</string>
<string name="it_can_disabled_via_settings_notifications_still_shown"><b>Se puede desactivar en Configuración</b> las notificaciones se seguirán mostrando mientras la app esté en funcionamiento.</string> <string name="it_can_disabled_via_settings_notifications_still_shown"><b>Se puede desactivar en Configuración</b> las notificaciones se seguirán mostrando mientras la app esté en funcionamiento.</string>
<string name="notifications_mode_service">Siempre activo</string> <string name="notifications_mode_service">Siempre activo</string>
<string name="allow_verb">Permitir</string> <string name="allow_verb">Permitir</string>
@ -80,12 +80,12 @@
<string name="icon_descr_asked_to_receive">Solicita recibir la imagen</string> <string name="icon_descr_asked_to_receive">Solicita recibir la imagen</string>
<string name="impossible_to_recover_passphrase"><b>Ten en cuenta</b>: NO podrás recuperar o cambiar la contraseña si la pierdes.</string> <string name="impossible_to_recover_passphrase"><b>Ten en cuenta</b>: NO podrás recuperar o cambiar la contraseña si la pierdes.</string>
<string name="both_you_and_your_contact_can_send_voice">Tanto tú como tu contacto podéis enviar mensajes de voz.</string> <string name="both_you_and_your_contact_can_send_voice">Tanto tú como tu contacto podéis enviar mensajes de voz.</string>
<string name="onboarding_notifications_mode_service_desc"><b>¡Usa más batería!</b> El servicio en segundo plano está siempre en funcionamiento - las notificaciones se mostrarán tan pronto como los mensajes estén disponibles.</string> <string name="onboarding_notifications_mode_service_desc"><b>¡Gasta más batería!</b> El servicio en segundo plano está siempre en funcionamiento - las notificaciones se mostrarán tan pronto como los mensajes estén disponibles.</string>
<string name="both_you_and_your_contacts_can_delete">Tanto tú como tu contacto podéis eliminar de forma irreversible los mensajes enviados.</string> <string name="both_you_and_your_contacts_can_delete">Tanto tú como tu contacto podéis eliminar de forma irreversible los mensajes enviados.</string>
<string name="both_you_and_your_contact_can_send_disappearing">Tanto tú como tu contacto podéis enviar mensajes temporales.</string> <string name="both_you_and_your_contact_can_send_disappearing">Tanto tú como tu contacto podéis enviar mensajes temporales.</string>
<string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><b>Escanear código QR</b>: para conectar con tu contacto que te muestre código QR.</string> <string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><b>Escanear código QR</b>: para conectar con tu contacto que te muestre código QR.</string>
<string name="create_profile_button">Crear</string> <string name="create_profile_button">Crear</string>
<string name="create_one_time_link">Crear enlace único de invitación</string> <string name="create_one_time_link">Crear enlace de invitación de un uso.</string>
<string name="create_group">Crear grupo secreto</string> <string name="create_group">Crear grupo secreto</string>
<string name="database_passphrase_will_be_updated">La contraseña de cifrado de la base de datos será actualizada.</string> <string name="database_passphrase_will_be_updated">La contraseña de cifrado de la base de datos será actualizada.</string>
<string name="info_row_database_id">ID de la base de datos</string> <string name="info_row_database_id">ID de la base de datos</string>
@ -152,7 +152,7 @@
<string name="notification_preview_mode_contact">Nombre del contacto</string> <string name="notification_preview_mode_contact">Nombre del contacto</string>
<string name="copy_verb">Copiar</string> <string name="copy_verb">Copiar</string>
<string name="create_your_profile">Crear tu perfil</string> <string name="create_your_profile">Crear tu perfil</string>
<string name="always_use_relay">Conectar mediante relay</string> <string name="always_use_relay">Siempre usar relay</string>
<string name="set_password_to_export_desc">La base de datos está cifrada con una contraseña aleatoria. Cámbiala antes de exportar.</string> <string name="set_password_to_export_desc">La base de datos está cifrada con una contraseña aleatoria. Cámbiala antes de exportar.</string>
<string name="total_files_count_and_size">%d archivo(s) con tamaño total de %s</string> <string name="total_files_count_and_size">%d archivo(s) con tamaño total de %s</string>
<string name="enable_automatic_deletion_question">¿Activar eliminación automática de mensajes\?</string> <string name="enable_automatic_deletion_question">¿Activar eliminación automática de mensajes\?</string>
@ -166,7 +166,7 @@
<string name="icon_descr_server_status_disconnected">Desconectado</string> <string name="icon_descr_server_status_disconnected">Desconectado</string>
<string name="icon_descr_server_status_connected">Conectado</string> <string name="icon_descr_server_status_connected">Conectado</string>
<string name="copied">Copiado en portapapeles</string> <string name="copied">Copiado en portapapeles</string>
<string name="share_one_time_link">Crear enlace único de invitación</string> <string name="share_one_time_link">Crear enlace de invitación de un uso.</string>
<string name="desktop_scan_QR_code_from_app_via_scan_QR_code">💻 PC: escanéa el código QR desde la app mediante <b>Escanéo de código QR </b></string> <string name="desktop_scan_QR_code_from_app_via_scan_QR_code">💻 PC: escanéa el código QR desde la app mediante <b>Escanéo de código QR </b></string>
<string name="delete_contact_menu_action">Eliminar</string> <string name="delete_contact_menu_action">Eliminar</string>
<string name="delete_group_menu_action">Eliminar</string> <string name="delete_group_menu_action">Eliminar</string>
@ -272,7 +272,7 @@
<string name="callstatus_calling">llamando</string> <string name="callstatus_calling">llamando</string>
<string name="callstatus_in_progress">llamada en curso</string> <string name="callstatus_in_progress">llamada en curso</string>
<string name="colored">coloreado</string> <string name="colored">coloreado</string>
<string name="rcv_group_event_changed_your_role">su rol a cambiado a %s</string> <string name="rcv_group_event_changed_your_role">ha cambiado tu rol a %s</string>
<string name="snd_conn_event_switch_queue_phase_changing_for_member">cambiando dirección por %s</string> <string name="snd_conn_event_switch_queue_phase_changing_for_member">cambiando dirección por %s</string>
<string name="group_member_status_complete">completado</string> <string name="group_member_status_complete">completado</string>
<string name="invite_prohibited">¡No se puede invitar el contacto!</string> <string name="invite_prohibited">¡No se puede invitar el contacto!</string>
@ -283,7 +283,7 @@
<string name="chat_is_stopped_indication">El chat está detenido</string> <string name="chat_is_stopped_indication">El chat está detenido</string>
<string name="rcv_group_event_changed_member_role">rol de %s cambiado a %s</string> <string name="rcv_group_event_changed_member_role">rol de %s cambiado a %s</string>
<string name="change_role">Cambiar rol</string> <string name="change_role">Cambiar rol</string>
<string name="v4_5_transport_isolation_descr">A través del perfil de chat (por defecto) or a través de conexión (BETA)</string> <string name="v4_5_transport_isolation_descr">Mediante perfil de Chat (por defecto) o por conexión (BETA)</string>
<string name="snd_conn_event_switch_queue_phase_changing">cambiando dirección…</string> <string name="snd_conn_event_switch_queue_phase_changing">cambiando dirección…</string>
<string name="chat_preferences">Preferencias de chat</string> <string name="chat_preferences">Preferencias de chat</string>
<string name="feature_cancelled_item">cancelado %s</string> <string name="feature_cancelled_item">cancelado %s</string>
@ -319,7 +319,7 @@
<string name="network_disable_socks_info">Si confirmas los servidores de mensajería podrán ver tu IP, y tu proveedor de acceso a internet a qué servidores te estás conectando.</string> <string name="network_disable_socks_info">Si confirmas los servidores de mensajería podrán ver tu IP, y tu proveedor de acceso a internet a qué servidores te estás conectando.</string>
<string name="image_saved">Imagen guardada en la Galería</string> <string name="image_saved">Imagen guardada en la Galería</string>
<string name="file_will_be_received_when_contact_is_online">El archivo se recibirá cuando tu contacto esté en línea, por favor espera o compruébalo más tarde.</string> <string name="file_will_be_received_when_contact_is_online">El archivo se recibirá cuando tu contacto esté en línea, por favor espera o compruébalo más tarde.</string>
<string name="add_contact">Enlace único de invitación</string> <string name="add_contact">Enlace de invitación de un uso</string>
<string name="paste_the_link_you_received">Pegar enlace recibido</string> <string name="paste_the_link_you_received">Pegar enlace recibido</string>
<string name="error_saving_group_profile">Error guardando perfil de grupo</string> <string name="error_saving_group_profile">Error guardando perfil de grupo</string>
<string name="exit_without_saving">Salir sin guardar</string> <string name="exit_without_saving">Salir sin guardar</string>
@ -329,7 +329,7 @@
<string name="alert_message_group_invitation_expired">La invitación al grupo ya no es válida, ha sido eliminada por el remitente.</string> <string name="alert_message_group_invitation_expired">La invitación al grupo ya no es válida, ha sido eliminada por el remitente.</string>
<string name="delete_group_for_self_cannot_undo_warning">El grupo se eliminará para tí. ¡No puede deshacerse!</string> <string name="delete_group_for_self_cannot_undo_warning">El grupo se eliminará para tí. ¡No puede deshacerse!</string>
<string name="how_to_use_markdown">Cómo usar el marcador</string> <string name="how_to_use_markdown">Cómo usar el marcador</string>
<string name="description_via_one_time_link_incognito">Incógnito mediante enlace único</string> <string name="description_via_one_time_link_incognito">Incógnito mediante enlace de un uso</string>
<string name="simplex_link_contact">Dirección de contacto SimpleX</string> <string name="simplex_link_contact">Dirección de contacto SimpleX</string>
<string name="error_saving_smp_servers">Error guardando servidores SMP</string> <string name="error_saving_smp_servers">Error guardando servidores SMP</string>
<string name="simplex_link_mode_browser_warning">Abrir el enlace en el navegador puede reducir la privacidad y seguridad de la conexión. Los enlaces SimpleX que no son de confianza aparecerán en rojo.</string> <string name="simplex_link_mode_browser_warning">Abrir el enlace en el navegador puede reducir la privacidad y seguridad de la conexión. Los enlaces SimpleX que no son de confianza aparecerán en rojo.</string>
@ -337,7 +337,7 @@
<string name="error_creating_address">Error creando dirección</string> <string name="error_creating_address">Error creando dirección</string>
<string name="error_deleting_user">Error eliminando perfil de usuario</string> <string name="error_deleting_user">Error eliminando perfil de usuario</string>
<string name="auth_enable_simplex_lock">Activar SimpleX Lock</string> <string name="auth_enable_simplex_lock">Activar SimpleX Lock</string>
<string name="one_time_link">Enlace único de invitación</string> <string name="one_time_link">Enlace de invitación de un uso</string>
<string name="smp_servers">Servidores SMP</string> <string name="smp_servers">Servidores SMP</string>
<string name="settings_experimental_features">Características experimentales</string> <string name="settings_experimental_features">Características experimentales</string>
<string name="error_importing_database">Error importando la base de datos</string> <string name="error_importing_database">Error importando la base de datos</string>
@ -449,7 +449,7 @@
<string name="install_simplex_chat_for_terminal">Instalar <xliff:g id="appNameFull">SimpleX Chat</xliff:g> para terminal</string> <string name="install_simplex_chat_for_terminal">Instalar <xliff:g id="appNameFull">SimpleX Chat</xliff:g> para terminal</string>
<string name="group_invitation_item_description">invitación al grupo <xliff:g id="group_name">%1$s</xliff:g></string> <string name="group_invitation_item_description">invitación al grupo <xliff:g id="group_name">%1$s</xliff:g></string>
<string name="rcv_group_event_member_added">invitado <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g></string> <string name="rcv_group_event_member_added">invitado <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g></string>
<string name="incognito_info_allows">Permite tener muchas conexiones anónimas sin datos compartidos entre estas en un único perfil de chat.</string> <string name="incognito_info_allows">Permite tener varias conexiones anónimas sin datos compartidos entre estas en un único perfil de chat.</string>
<string name="invite_to_group_button">Invitar al grupo</string> <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="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. Establece una contraseña para protegerla.</string> <string name="database_is_not_encrypted">La base de datos no está cifrada. Establece una contraseña para protegerla.</string>
@ -698,7 +698,7 @@
<string name="v4_2_security_assessment">Evaluación de la seguridad</string> <string name="v4_2_security_assessment">Evaluación de la seguridad</string>
<string name="receiving_files_not_yet_supported">la recepción de archivos aún no está disponible</string> <string name="receiving_files_not_yet_supported">la recepción de archivos aún no está disponible</string>
<string name="sending_files_not_yet_supported">el envío de archivos aún no está disponible</string> <string name="sending_files_not_yet_supported">el envío de archivos aún no está disponible</string>
<string name="call_connection_peer_to_peer">entre particulares</string> <string name="call_connection_peer_to_peer">p2p</string>
<string name="icon_descr_call_rejected">Llamada rechazada</string> <string name="icon_descr_call_rejected">Llamada rechazada</string>
<string name="remove_passphrase">Eliminar</string> <string name="remove_passphrase">Eliminar</string>
<string name="remove_passphrase_from_keychain">¿Eliminar contraseña de Keystore\?</string> <string name="remove_passphrase_from_keychain">¿Eliminar contraseña de Keystore\?</string>
@ -801,8 +801,8 @@
<string name="alert_message_no_group">Este grupo ya no existe.</string> <string name="alert_message_no_group">Este grupo ya no existe.</string>
<string name="incognito_info_find">Para encontrar el perfil usado en una conexión en modo incógnito, pulsa el nombre del contacto o del grupo en la parte superior del chat.</string> <string name="incognito_info_find">Para encontrar el perfil usado en una conexión en modo incógnito, pulsa el nombre del contacto o del grupo en la parte superior del chat.</string>
<string name="accept_feature_set_1_day">Establecer 1 día</string> <string name="accept_feature_set_1_day">Establecer 1 día</string>
<string name="v4_4_french_interface_descr">Gracias a los usuarios: ¡contribuye a través de Weblate!</string> <string name="v4_4_french_interface_descr">Agradecimientos a los usuarios. ¡Contribuye a través de Weblate!</string>
<string name="v4_5_italian_interface_descr">Gracias a los usuarios: ¡contribuye a través de Weblate!</string> <string name="v4_5_italian_interface_descr">Agradecimientos a los usuarios. ¡Contribuye a través de Weblate!</string>
<string name="v4_5_private_filenames_descr">Para proteger la zona horaria, los archivos de imagen/voz usan la hora UTC.</string> <string name="v4_5_private_filenames_descr">Para proteger la zona horaria, los archivos de imagen/voz usan la hora UTC.</string>
<string name="v4_5_transport_isolation">Aislamiento de transporte</string> <string name="v4_5_transport_isolation">Aislamiento de transporte</string>
<string name="to_share_with_your_contact">(para compartir con tu contacto)</string> <string name="to_share_with_your_contact">(para compartir con tu contacto)</string>
@ -855,7 +855,7 @@
<string name="smp_servers_use_server">Usar servidor</string> <string name="smp_servers_use_server">Usar servidor</string>
<string name="smp_servers_use_server_for_new_conn">Usar para conexiones nuevas</string> <string name="smp_servers_use_server_for_new_conn">Usar para conexiones nuevas</string>
<string name="theme_system">Sistema</string> <string name="theme_system">Sistema</string>
<string name="description_via_one_time_link">mediante enlace único</string> <string name="description_via_one_time_link">mediante enlace de un uso</string>
<string name="your_chats">Tus chats</string> <string name="your_chats">Tus chats</string>
<string name="voice_message_send_text">Mensaje de voz…</string> <string name="voice_message_send_text">Mensaje de voz…</string>
<string name="your_contact_address">Tu dirección de contacto</string> <string name="your_contact_address">Tu dirección de contacto</string>
@ -879,7 +879,7 @@
<string name="your_ICE_servers">Tus servidores ICE</string> <string name="your_ICE_servers">Tus servidores ICE</string>
<string name="you_rejected_group_invitation">Has rechazado la invitación del grupo.</string> <string name="you_rejected_group_invitation">Has rechazado la invitación del grupo.</string>
<string name="snd_group_event_changed_member_role">has cambiado el rol de %s a %s</string> <string name="snd_group_event_changed_member_role">has cambiado el rol de %s a %s</string>
<string name="call_connection_via_relay">mediante servidor de retransmisión</string> <string name="call_connection_via_relay">mediante relay</string>
<string name="contact_wants_to_connect_with_you">¡quiere contactar contigo!</string> <string name="contact_wants_to_connect_with_you">¡quiere contactar contigo!</string>
<string name="voice_message">Mensaje de voz</string> <string name="voice_message">Mensaje de voz</string>
<string name="waiting_for_image">Esperando imagen</string> <string name="waiting_for_image">Esperando imagen</string>
@ -939,9 +939,8 @@
<string name="your_chat_database">Base de datos de Chat</string> <string name="your_chat_database">Base de datos de Chat</string>
<string name="you_can_start_chat_via_setting_or_by_restarting_the_app">Puedes iniciar el chat en Configuración / Base de datos o reiniciando la aplicación.</string> <string name="you_can_start_chat_via_setting_or_by_restarting_the_app">Puedes iniciar el chat en Configuración / Base de datos o reiniciando la aplicación.</string>
<string name="you_sent_group_invitation">Has enviado una invitación de grupo</string> <string name="you_sent_group_invitation">Has enviado una invitación de grupo</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> contacto(s) seleccionado(s)</string> <string name="num_contacts_selected">%d contacto(s) seleccionado(s)</string>
<string name="group_info_section_title_num_members"><xliff:g id="num_members"> %1$s </xliff:g> MIEMBROS</string> <string name="group_info_section_title_num_members"><xliff:g id="num_members"> %1$s </xliff:g> MIEMBROS</string>
<string name="your_chat_profiles_stored_locally">Tus perfiles de chat se almacenan localmente, sólo en tu dispositivo</string>
<string name="voice_prohibited_in_this_chat">Los mensajes de voz están prohibidos en este chat.</string> <string name="voice_prohibited_in_this_chat">Los mensajes de voz están prohibidos en este chat.</string>
<string name="whats_new">Novedades</string> <string name="whats_new">Novedades</string>
<string name="you_have_to_enter_passphrase_every_time">La contraseña no se almacena en el dispositivo, tienes que introducirla cada vez que inicies la aplicación.</string> <string name="you_have_to_enter_passphrase_every_time">La contraseña no se almacena en el dispositivo, tienes que introducirla cada vez que inicies la aplicación.</string>
@ -955,8 +954,8 @@
<string name="connected_to_server_to_receive_messages_from_contact">Estás conectado al servidor utilizado para recibir mensajes de este contacto.</string> <string name="connected_to_server_to_receive_messages_from_contact">Estás conectado al servidor utilizado para recibir mensajes de este contacto.</string>
<string name="description_via_contact_address_link">mediante enlace de dirección de contacto</string> <string name="description_via_contact_address_link">mediante enlace de dirección de contacto</string>
<string name="description_via_group_link">mediante enlace de grupo</string> <string name="description_via_group_link">mediante enlace de grupo</string>
<string name="description_you_shared_one_time_link">has compartido un enlace único</string> <string name="description_you_shared_one_time_link">has compartido enlace de un uso</string>
<string name="description_you_shared_one_time_link_incognito">has compartido un enlace único en módo incógnito</string> <string name="description_you_shared_one_time_link_incognito">has compartido enlace de un uso en módo incógnito</string>
<string name="you_have_no_chats">No tienes chats</string> <string name="you_have_no_chats">No tienes chats</string>
<string name="contact_sent_large_file">El contacto ha enviado un archivo mayor al máximo admitido (<xliff:g id="maxFileSize">%1$s</xliff:g> ).</string> <string name="contact_sent_large_file">El contacto ha enviado un archivo mayor al máximo admitido (<xliff:g id="maxFileSize">%1$s</xliff:g> ).</string>
<string name="integrity_msg_skipped"><xliff:g id="connection ID" example="1">%1$d</xliff:g> mensaje(s) omitido(s)</string> <string name="integrity_msg_skipped"><xliff:g id="connection ID" example="1">%1$d</xliff:g> mensaje(s) omitido(s)</string>
@ -979,4 +978,48 @@
\n \n
\nLos servidores <xliff:g id="appName">SimpleX</xliff:g> no pueden ver tu perfil.</string> \nLos servidores <xliff:g id="appName">SimpleX</xliff:g> no pueden ver tu perfil.</string>
<string name="language_system">Sistema</string> <string name="language_system">Sistema</string>
<string name="button_add_welcome_message">Agregar mensaje de bienvenida</string>
<string name="v4_6_audio_video_calls">Llamadas y videollamadas</string>
<string name="smp_save_servers_question">¿Guardar servidores\?</string>
<string name="hide_profile">Ocultar perfil</string>
<string name="save_profile_password">Guardar contraseña de perfil</string>
<string name="password_to_show">Contraseña para hacerlo visible</string>
<string name="error_saving_user_password">Error guardando la contraseña de usuario</string>
<string name="relay_server_if_necessary">El relay sólo se usa en caso de necesidad. Un tercero podría ver tu IP.</string>
<string name="relay_server_protects_ip">El servidor relay protege tu IP pero puede ver la duración de la llamada.</string>
<string name="cant_delete_user_profile">¡No se puede eliminar el perfil!</string>
<string name="enter_password_to_show">Introduce la contraseña</string>
<string name="user_hide">Ocultar</string>
<string name="user_mute">Silenciar</string>
<string name="save_and_update_group_profile">Guardar y actualizar perfil del grupo</string>
<string name="tap_to_activate_profile">Pulsa para activar el perfil.</string>
<string name="should_be_at_least_one_visible_profile">Debe haber al menos un perfil de usuario visible.</string>
<string name="user_unhide">Mostrar</string>
<string name="button_welcome_message">Mensaje de bienvenida</string>
<string name="group_welcome_title">Mensaje de bienvenida</string>
<string name="should_be_at_least_one_profile">Debe haber al menos un perfil de usuario.</string>
<string name="make_profile_private">¡Hacer un perfil privado!</string>
<string name="dont_show_again">No mostrar de nuevo</string>
<string name="muted_when_inactive">¡Silenciado cuando está inactivo!</string>
<string name="v4_6_group_moderation">Moderación de grupos</string>
<string name="v4_6_hidden_chat_profiles">Perfiles Chat ocultos</string>
<string name="v4_6_hidden_chat_profiles_descr">¡Proteje los perfiles de Chat con contraseña!</string>
<string name="v4_6_audio_video_calls_descr">Soporte bluetooth y otras mejoras.</string>
<string name="v4_6_group_welcome_message_descr">¡Establece el mensaje mostrado a los miembros nuevos!</string>
<string name="v4_6_chinese_spanish_interface">Interfaz en chino y español</string>
<string name="v4_6_chinese_spanish_interface_descr">Agradecimientos a los usuarios. ¡Contribuye a través de Weblate!</string>
<string name="error_updating_user_privacy">Error actualizando la privacidad de usuario</string>
<string name="confirm_password">Confirmar contraseña</string>
<string name="v4_6_reduced_battery_usage">Consumo de batería reducido aun más</string>
<string name="v4_6_group_welcome_message">Mensaje de bienvenida en grupos</string>
<string name="v4_6_reduced_battery_usage_descr">¡Más mejoras en camino!</string>
<string name="hidden_profile_password">Contraseña de perfil oculto</string>
<string name="save_welcome_message_question">¿Guardar mensaje de bienvenida\?</string>
<string name="user_unmute">Activar audio</string>
<string name="you_can_hide_or_mute_user_profile">Puedes ocultar o silenciar un perfil. Mantenlo pulsado para abrir el menú.</string>
<string name="you_will_still_receive_calls_and_ntfs">Seguirás recibiendo llamadas y notificaciones de los perfiles silenciados cuando estén activos.</string>
<string name="v4_6_group_moderation_descr">Ahora los administradores pueden
\n- borrar mensajes de los miembros.
\n- desactivar el rol a miembros (a rol \"observador\")</string>
<string name="to_reveal_profile_enter_password">Para hacer visible tu perfil oculto, introduce la contraseña completa en el campo de búsqueda de la página Tus perfiles Chat.</string>
</resources> </resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -744,7 +744,7 @@
<string name="member_role_will_be_changed_with_notification">Le rôle sera changé pour «%s». Les membres du groupe seront notifiés.</string> <string name="member_role_will_be_changed_with_notification">Le rôle sera changé pour «%s». Les membres du groupe seront notifiés.</string>
<string name="icon_descr_contact_checked">Contact vérifié⸱e</string> <string name="icon_descr_contact_checked">Contact vérifié⸱e</string>
<string name="clear_contacts_selection_button">Effacer</string> <string name="clear_contacts_selection_button">Effacer</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> contact·s sélectionné·e·s</string> <string name="num_contacts_selected">%d contact·s sélectionné·e·s</string>
<string name="skip_inviting_button">Passer linvitation de membres</string> <string name="skip_inviting_button">Passer linvitation de membres</string>
<string name="select_contacts">Sélectionnez des contacts</string> <string name="select_contacts">Sélectionnez des contacts</string>
<string name="no_contacts_selected">Aucun contact sélectionné</string> <string name="no_contacts_selected">Aucun contact sélectionné</string>
@ -942,7 +942,6 @@
<string name="users_delete_with_connections">Profil et connexions au serveur</string> <string name="users_delete_with_connections">Profil et connexions au serveur</string>
<string name="network_session_mode_transport_isolation">Isolement du transport</string> <string name="network_session_mode_transport_isolation">Isolement du transport</string>
<string name="update_network_session_mode_question">Mettre à jour le mode d\'isolation du transport \?</string> <string name="update_network_session_mode_question">Mettre à jour le mode d\'isolation du transport \?</string>
<string name="your_chat_profiles_stored_locally">Vos profils de chat sont stockés localement, uniquement sur votre appareil</string>
<string name="network_session_mode_entity_description">Une connexion TCP distincte (et identifiant SOCKS) sera utilisée <b>pour chaque contact et membre de groupe</b>. <string name="network_session_mode_entity_description">Une connexion TCP distincte (et identifiant SOCKS) sera utilisée <b>pour chaque contact et membre de groupe</b>.
\n<b>Veuillez noter</b> : si vous avez de nombreuses connexions, votre consommation de batterie et de réseau peut être nettement plus élevée et certaines liaisons peuvent échouer.</string> \n<b>Veuillez noter</b> : si vous avez de nombreuses connexions, votre consommation de batterie et de réseau peut être nettement plus élevée et certaines liaisons peuvent échouer.</string>
<string name="network_session_mode_user">Profil de chat</string> <string name="network_session_mode_user">Profil de chat</string>
@ -981,4 +980,46 @@
<string name="observer_cant_send_message_title">Vous ne pouvez pas envoyer de messages !</string> <string name="observer_cant_send_message_title">Vous ne pouvez pas envoyer de messages !</string>
<string name="group_member_role_observer">observateur</string> <string name="group_member_role_observer">observateur</string>
<string name="language_system">Système</string> <string name="language_system">Système</string>
<string name="smp_save_servers_question">Sauvegarder les serveurs \?</string>
<string name="dont_show_again">Ne plus afficher</string>
<string name="button_add_welcome_message">Ajouter un message d\'accueil</string>
<string name="cant_delete_user_profile">Impossible de supprimer le profil d\'utilisateur !</string>
<string name="v4_6_group_moderation">Modération de groupe</string>
<string name="user_hide">Cacher</string>
<string name="muted_when_inactive">Mute en cas d\'inactivité !</string>
<string name="confirm_password">Confirmer le mot de passe</string>
<string name="v4_6_reduced_battery_usage">Réduction accrue de l\'utilisation de la batterie</string>
<string name="v4_6_chinese_spanish_interface">Interface en chinois et en espagnol</string>
<string name="enter_password_to_show">Entrez le mot de passe ci-dessus pour continuer !</string>
<string name="v4_6_audio_video_calls">Appels audio et vidéo</string>
<string name="v4_6_group_welcome_message">Message d\'accueil du groupe</string>
<string name="error_saving_user_password">Erreur d\'enregistrement du mot de passe de l\'utilisateur</string>
<string name="error_updating_user_privacy">Erreur de mise à jour de la confidentialité de l\'utilisateur</string>
<string name="hidden_profile_password">Mot de passe de profil caché</string>
<string name="v4_6_hidden_chat_profiles">Profils de chat cachés</string>
<string name="v4_6_group_moderation_descr">Désormais, les administrateurs peuvent :
\n- supprimer les messages des membres.
\n- désactiver des membres (rôle \"observateur\")</string>
<string name="save_welcome_message_question">Sauvegarder le message d\'accueil \?</string>
<string name="v4_6_group_welcome_message_descr">Choisissez un message à l\'attention des nouveaux membres !</string>
<string name="hide_profile">Masquer le profil</string>
<string name="v4_6_reduced_battery_usage_descr">D\'autres améliorations sont à venir !</string>
<string name="password_to_show">Mot de passe à afficher</string>
<string name="make_profile_private">Rendre le profil privé !</string>
<string name="user_mute">Mute</string>
<string name="v4_6_hidden_chat_profiles_descr">Protégez vos profils de chat par un mot de passe !</string>
<string name="tap_to_activate_profile">Appuyez pour activer le profil.</string>
<string name="save_and_update_group_profile">Sauvegarder et mettre à jour le profil du groupe</string>
<string name="save_profile_password">Enregistrer le mot de passe du profil</string>
<string name="to_reveal_profile_enter_password">Pour révéler votre profil caché, entrez un mot de passe complet dans le champ de recherche de la page Profils de chat.</string>
<string name="v4_6_audio_video_calls_descr">Prise en charge du Bluetooth et autres améliorations.</string>
<string name="v4_6_chinese_spanish_interface_descr">Merci aux utilisateurs - contribuez via Weblate !</string>
<string name="should_be_at_least_one_profile">Il doit y avoir au moins un profil d\'utilisateur.</string>
<string name="should_be_at_least_one_visible_profile">Il doit y avoir au moins un profil d\'utilisateur visible.</string>
<string name="user_unhide">Dévoiler</string>
<string name="user_unmute">Démute</string>
<string name="button_welcome_message">Message d\'accueil</string>
<string name="group_welcome_title">Message d\'accueil</string>
<string name="you_can_hide_or_mute_user_profile">Vous pouvez masquer ou mettre en sourdine un profil d\'utilisateur - maintenez-le enfoncé pour accéder au menu.</string>
<string name="you_will_still_receive_calls_and_ntfs">Vous continuerez à recevoir des appels et des notifications des profils mis en sourdine lorsqu\'ils sont actifs.</string>
</resources> </resources>

View file

@ -819,7 +819,7 @@
<string name="button_send_direct_message">Invia messaggio diretto</string> <string name="button_send_direct_message">Invia messaggio diretto</string>
<string name="skip_inviting_button">Salta l\'invito di membri</string> <string name="skip_inviting_button">Salta l\'invito di membri</string>
<string name="switch_verb">Cambia</string> <string name="switch_verb">Cambia</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> contatto/i selezionato/i</string> <string name="num_contacts_selected">%d contatto/i selezionato/i</string>
<string name="group_info_section_title_num_members"><xliff:g id="num_members">%1$s</xliff:g> MEMBRI</string> <string name="group_info_section_title_num_members"><xliff:g id="num_members">%1$s</xliff:g> MEMBRI</string>
<string name="you_can_share_group_link_anybody_will_be_able_to_connect">Puoi condividere un link o un codice QR: chiunque potrà unirsi al gruppo. Non perderai i membri del gruppo se in seguito lo elimini.</string> <string name="you_can_share_group_link_anybody_will_be_able_to_connect">Puoi condividere un link o un codice QR: chiunque potrà unirsi al gruppo. Non perderai i membri del gruppo se in seguito lo elimini.</string>
<string name="invite_prohibited_description">Stai tentando di invitare un contatto con cui hai condiviso un profilo in incognito nel gruppo in cui stai usando il tuo profilo principale</string> <string name="invite_prohibited_description">Stai tentando di invitare un contatto con cui hai condiviso un profilo in incognito nel gruppo in cui stai usando il tuo profilo principale</string>
@ -948,7 +948,6 @@
<string name="delete_files_and_media_for_all_users">Elimina i file per tutti i profili di chat</string> <string name="delete_files_and_media_for_all_users">Elimina i file per tutti i profili di chat</string>
<string name="failed_to_active_user_title">Errore nel cambio di profilo!</string> <string name="failed_to_active_user_title">Errore nel cambio di profilo!</string>
<string name="failed_to_create_user_title">Errore nella creazione del profilo!</string> <string name="failed_to_create_user_title">Errore nella creazione del profilo!</string>
<string name="your_chat_profiles_stored_locally">I tuoi profili di chat sono memorizzati localmente, solo sul tuo dispositivo</string>
<string name="error_deleting_user">Errore nell\'eliminazione del profilo utente</string> <string name="error_deleting_user">Errore nell\'eliminazione del profilo utente</string>
<string name="users_delete_with_connections">Profilo e connessioni al server</string> <string name="users_delete_with_connections">Profilo e connessioni al server</string>
<string name="your_chat_profiles">I tuoi profili di chat</string> <string name="your_chat_profiles">I tuoi profili di chat</string>
@ -981,4 +980,46 @@
<string name="observer_cant_send_message_desc">Contatta l\'amministratore del gruppo.</string> <string name="observer_cant_send_message_desc">Contatta l\'amministratore del gruppo.</string>
<string name="observer_cant_send_message_title">Non puoi inviare messaggi!</string> <string name="observer_cant_send_message_title">Non puoi inviare messaggi!</string>
<string name="language_system">Sistema</string> <string name="language_system">Sistema</string>
<string name="button_add_welcome_message">Aggiungi messaggio di benvenuto</string>
<string name="button_welcome_message">Messaggio di benvenuto</string>
<string name="save_welcome_message_question">Salvare il messaggio di benvenuto\?</string>
<string name="group_welcome_title">Messaggio di benvenuto</string>
<string name="save_and_update_group_profile">Salva e aggiorna il profilo del gruppo</string>
<string name="enter_password_to_show">Inserisci la password sopra per mostrare!</string>
<string name="user_mute">Silenzia</string>
<string name="tap_to_activate_profile">Tocca per attivare il profilo.</string>
<string name="user_unhide">Svela</string>
<string name="make_profile_private">Rendi privato il profilo!</string>
<string name="should_be_at_least_one_profile">Deve esserci almeno un profilo utente.</string>
<string name="should_be_at_least_one_visible_profile">Deve esserci almeno un profilo utente visibile.</string>
<string name="you_can_hide_or_mute_user_profile">Puoi nascondere o silenziare un profilo utente - tienilo premuto per il menu.</string>
<string name="dont_show_again">Non mostrare più</string>
<string name="muted_when_inactive">Silenzioso quando inattivo!</string>
<string name="you_will_still_receive_calls_and_ntfs">Continuerai a ricevere chiamate e notifiche da profili silenziati quando sono attivi.</string>
<string name="v4_6_audio_video_calls">Chiamate audio e video</string>
<string name="v4_6_group_moderation">Moderazione del gruppo</string>
<string name="v4_6_hidden_chat_profiles_descr">Proteggi i tuoi profili di chat con una password!</string>
<string name="v4_6_audio_video_calls_descr">Supporto a bluetooth e altri miglioramenti.</string>
<string name="v4_6_group_welcome_message">Messaggio di benvenuto del gruppo</string>
<string name="v4_6_reduced_battery_usage_descr">Altri miglioramenti sono in arrivo!</string>
<string name="v4_6_chinese_spanish_interface">Interfaccia cinese e spagnola</string>
<string name="v4_6_chinese_spanish_interface_descr">Grazie agli utenti contribuite via Weblate!</string>
<string name="hidden_profile_password">Password del profilo nascosta</string>
<string name="save_profile_password">Salva la password del profilo</string>
<string name="to_reveal_profile_enter_password">Per rivelare il tuo profilo nascosto, inserisci una password completa in un campo di ricerca nella pagina \"I tuoi profili di chat\".</string>
<string name="password_to_show">Password per mostrare</string>
<string name="v4_6_group_moderation_descr">Ora gli amministratori possono:
\n- eliminare i messaggi dei membri.
\n- disattivare i membri (ruolo \"osservatore\")</string>
<string name="cant_delete_user_profile">Impossibile eliminare il profilo utente!</string>
<string name="hide_profile">Nascondi il profilo</string>
<string name="confirm_password">Conferma password</string>
<string name="error_updating_user_privacy">Errore nell\'aggiornamento della privacy dell\'utente</string>
<string name="smp_save_servers_question">Salvare i server\?</string>
<string name="error_saving_user_password">Errore nel salvataggio della password utente</string>
<string name="v4_6_reduced_battery_usage">Ulteriore riduzione del consumo della batteria</string>
<string name="v4_6_hidden_chat_profiles">Profili di chat nascosti</string>
<string name="user_hide">Nascondi</string>
<string name="v4_6_group_welcome_message_descr">Imposta il messaggio mostrato ai nuovi membri!</string>
<string name="user_unmute">Riattiva audio</string>
</resources> </resources>

View file

@ -802,7 +802,7 @@
<string name="you_sent_group_invitation">グループの招待を送りました</string> <string name="you_sent_group_invitation">グループの招待を送りました</string>
<string name="snd_group_event_changed_member_role">%sの役割を次に変えました%s</string> <string name="snd_group_event_changed_member_role">%sの役割を次に変えました%s</string>
<string name="button_send_direct_message">ダイレクトメッセージを送信</string> <string name="button_send_direct_message">ダイレクトメッセージを送信</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g>連絡先が選択中</string> <string name="num_contacts_selected">%d 連絡先が選択中</string>
<string name="snd_group_event_member_deleted">除名しました: <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g></string> <string name="snd_group_event_member_deleted">除名しました: <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g></string>
<string name="switch_verb">切り替える</string> <string name="switch_verb">切り替える</string>
<string name="member_role_will_be_changed_with_notification">役割が「%s」となります。グループの全員に通知が出ます。</string> <string name="member_role_will_be_changed_with_notification">役割が「%s」となります。グループの全員に通知が出ます。</string>
@ -812,7 +812,6 @@
<string name="network_options_save">保存</string> <string name="network_options_save">保存</string>
<string name="update_network_settings_question">ネットワーク設定を更新しますか?</string> <string name="update_network_settings_question">ネットワーク設定を更新しますか?</string>
<string name="updating_settings_will_reconnect_client_to_all_servers">設定を更新すると、全サーバにクライントの再接続が行われます。</string> <string name="updating_settings_will_reconnect_client_to_all_servers">設定を更新すると、全サーバにクライントの再接続が行われます。</string>
<string name="your_chat_profiles_stored_locally">チャットプロフィールはローカルであなたの端末だけに保存されます。</string>
<string name="save_color">色を保存</string> <string name="save_color">色を保存</string>
<string name="chat_preferences_you_allow">あなたが次を許可しています:</string> <string name="chat_preferences_you_allow">あなたが次を許可しています:</string>
<string name="chat_preferences_yes">はい</string> <string name="chat_preferences_yes">はい</string>

View file

@ -8,4 +8,43 @@
<string name="about_simplex">Apie SimpleX</string> <string name="about_simplex">Apie SimpleX</string>
<string name="smp_servers_add">Pridėti serverį…</string> <string name="smp_servers_add">Pridėti serverį…</string>
<string name="v4_3_improved_server_configuration_desc">Pridėti serverius skenuojant QR kodus.</string> <string name="v4_3_improved_server_configuration_desc">Pridėti serverius skenuojant QR kodus.</string>
<string name="appearance_settings">Išvaizda</string>
<string name="app_version_title">Programėlės versija</string>
<string name="app_version_name">Programėlės versija: v%s</string>
<string name="app_version_code">Programėlės darinys: %s</string>
<string name="accept_automatically">Automatiškai</string>
<string name="callstatus_calling">skambinama…</string>
<string name="callstatus_error">skambučio klaida</string>
<string name="call_already_ended">Skambutis jau baigtas!</string>
<string name="answer_call">Atsiliepti</string>
<string name="icon_descr_call_ended">Skambutis baigtas</string>
<string name="settings_section_title_calls">SKAMBUČIAI</string>
<string name="allow_your_contacts_irreversibly_delete">Leisti jūsų adresatams negrįžtamai ištrinti išsiųstas žinutes.</string>
<string name="back">Atgal</string>
<string name="settings_section_title_icon">PROGRAMĖLĖS PIKTOGRAMA</string>
<string name="incognito_random_profile_from_contact_description">Adresatui, iš kurio gavote šią nuorodą, bus išsiųstas atsitiktinis profilis</string>
<string name="chat_preferences_always">visada</string>
<string name="allow_your_contacts_to_send_voice_messages">Leisti jūsų adresatams siųsti balso žinutes.</string>
<string name="allow_irreversible_message_deletion_only_if">Leisti negrįžtamą žinučių ištrynimą tik tuo atveju, jei jūsų adresatas jums tai leidžia.</string>
<string name="allow_voice_messages_only_if">Leisti balso žinutes tik tuo atveju, jei jūsų adresatas jas leidžia.</string>
<string name="allow_verb">Leisti</string>
<string name="allow_voice_messages_question">Leisti balso žinutes\?</string>
<string name="bold">pusjuodis</string>
<string name="callstatus_ended">skambutis baigtas <xliff:g id="duration" example="01:15">%1$s</xliff:g></string>
<string name="icon_descr_audio_call">garso skambutis</string>
<string name="settings_audio_video_calls">Garso ir vaizdo skambučiai</string>
<string name="integrity_msg_bad_hash">bloga žinutės maiša</string>
<string name="integrity_msg_bad_id">blogas žinutės ID</string>
<string name="incognito_random_profile_description">Jūsų adresatui bus išsiųstas atsitiktinis profilis</string>
<string name="allow_disappearing_messages_only_if">Leisti išnykstančias žinutes tik tuo atveju, jei jūsų adresatas jas leidžia.</string>
<string name="clear_chat_warning">Visos žinutės bus ištrintos to neįmanoma bus atšaukti! Žinutės bus ištrintos TIK jums.</string>
<string name="allow_to_delete_messages">Leisti negrįžtamai ištrinti išsiųstas žinutes.</string>
<string name="allow_to_send_disappearing">Leisti siųsti išnykstančias žinutes.</string>
<string name="allow_to_send_voice">Leisti siųsti balso žinutes.</string>
<string name="allow_direct_messages">Leisti siųsti tiesiogines žinutes nariams.</string>
<string name="v4_6_audio_video_calls">Garso ir vaizdo skambučiai</string>
<string name="allow_your_contacts_to_send_disappearing_messages">Leisti jūsų adresatams siųsti išnykstančias žinutes.</string>
<string name="auth_unavailable">Tapatybės nustatymas neprieinamas</string>
<string name="impossible_to_recover_passphrase"><b>Turėkite omenyje</b>: jeigu prarasite slaptafrazę, NEBEGALĖSITE jos atkurti ar pakeisti.</string>
<string name="cancel_verb">Atsisakyti</string>
</resources> </resources>

View file

@ -74,7 +74,7 @@
<string name="chat_item_ttl_month">1 maand</string> <string name="chat_item_ttl_month">1 maand</string>
<string name="about_simplex">Over SimpleX</string> <string name="about_simplex">Over SimpleX</string>
<string name="about_simplex_chat">Over <xliff:g id="appNameFull">SimpleX Chat</xliff:g></string> <string name="about_simplex_chat">Over <xliff:g id="appNameFull">SimpleX Chat</xliff:g></string>
<string name="above_then_preposition_continuation">hierboven, dan:</string> <string name="above_then_preposition_continuation">hier boven, dan:</string>
<string name="accept_requests">Verzoeken accepteren</string> <string name="accept_requests">Verzoeken accepteren</string>
<string name="users_delete_all_chats_deleted">Alle gesprekken en berichten worden verwijderd, dit kan niet ongedaan worden gemaakt!</string> <string name="users_delete_all_chats_deleted">Alle gesprekken en berichten worden verwijderd, dit kan niet ongedaan worden gemaakt!</string>
<string name="clear_chat_warning">Alle berichten worden verwijderd, dit kan niet ongedaan worden gemaakt! De berichten worden ALLEEN voor jou verwijderd.</string> <string name="clear_chat_warning">Alle berichten worden verwijderd, dit kan niet ongedaan worden gemaakt! De berichten worden ALLEEN voor jou verwijderd.</string>
@ -491,7 +491,7 @@
\nWe zullen serverredundantie toevoegen om verloren berichten te voorkomen.</string> \nWe zullen serverredundantie toevoegen om verloren berichten te voorkomen.</string>
<string name="joining_group">Deel nemen aan groep</string> <string name="joining_group">Deel nemen aan groep</string>
<string name="leave_group_button">Verlaten</string> <string name="leave_group_button">Verlaten</string>
<string name="group_member_role_member">gebruiker</string> <string name="group_member_role_member">Gebruiker</string>
<string name="image_descr_link_preview">link voorbeeld afbeelding</string> <string name="image_descr_link_preview">link voorbeeld afbeelding</string>
<string name="member_info_section_title_member">GEBRUIKER</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</string>
@ -576,7 +576,7 @@
<string name="feature_offered_item_with_param">voorgesteld %s: %2s</string> <string name="feature_offered_item_with_param">voorgesteld %s: %2s</string>
<string name="old_database_archive">Oud database archief</string> <string name="old_database_archive">Oud database archief</string>
<string name="enter_correct_current_passphrase">Voer het juiste huidige wachtwoord in.</string> <string name="enter_correct_current_passphrase">Voer het juiste huidige wachtwoord in.</string>
<string name="group_member_role_owner">eigenaar</string> <string name="group_member_role_owner">Eigenaar</string>
<string name="network_option_ping_count">PING telling</string> <string name="network_option_ping_count">PING telling</string>
<string name="network_option_ping_interval">PING interval</string> <string name="network_option_ping_interval">PING interval</string>
<string name="v4_5_message_draft_descr">Bewaar het laatste berichtconcept, met bijlagen.</string> <string name="v4_5_message_draft_descr">Bewaar het laatste berichtconcept, met bijlagen.</string>
@ -729,7 +729,7 @@
<string name="network_socks_toggle">SOCKS-proxy gebruiken (poort 9050)</string> <string name="network_socks_toggle">SOCKS-proxy gebruiken (poort 9050)</string>
<string name="save_preferences_question">Voorkeuren opslaan\?</string> <string name="save_preferences_question">Voorkeuren opslaan\?</string>
<string name="save_and_notify_contact">Opslaan en Contact melden</string> <string name="save_and_notify_contact">Opslaan en Contact melden</string>
<string name="section_title_welcome_message">WELKOMS BERICHT</string> <string name="section_title_welcome_message">WELKOMST BERICHT</string>
<string name="your_current_profile">Je huidige profiel</string> <string name="your_current_profile">Je huidige profiel</string>
<string name="save_and_notify_contacts">Opslaan en Contacten melden</string> <string name="save_and_notify_contacts">Opslaan en Contacten melden</string>
<string name="save_and_notify_group_members">Opslaan en Groepsleden melden</string> <string name="save_and_notify_group_members">Opslaan en Groepsleden melden</string>
@ -815,7 +815,7 @@
<string name="snd_conn_event_switch_queue_phase_completed">je bent van adres veranderd</string> <string name="snd_conn_event_switch_queue_phase_completed">je bent van adres veranderd</string>
<string name="select_contacts">Selecteer contacten</string> <string name="select_contacts">Selecteer contacten</string>
<string name="skip_inviting_button">Sla het uitnodigen van leden over</string> <string name="skip_inviting_button">Sla het uitnodigen van leden over</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> contact(en) geselecteerd</string> <string name="num_contacts_selected">%d contact(en) geselecteerd</string>
<string name="remove_member_confirmation">Verwijderen</string> <string name="remove_member_confirmation">Verwijderen</string>
<string name="button_remove_member">Gebruiker verwijderen</string> <string name="button_remove_member">Gebruiker verwijderen</string>
<string name="role_in_group">Rol</string> <string name="role_in_group">Rol</string>
@ -883,7 +883,7 @@
<string name="prohibit_direct_messages">Verbied het sturen van directe berichten naar leden.</string> <string name="prohibit_direct_messages">Verbied het sturen van directe berichten naar leden.</string>
<string name="prohibit_sending_voice">Verbieden het verzenden van spraak berichten.</string> <string name="prohibit_sending_voice">Verbieden het verzenden van spraak berichten.</string>
<string name="v4_2_security_assessment_desc">De beveiliging van SimpleX Chat is gecontroleerd door Trail of Bits.</string> <string name="v4_2_security_assessment_desc">De beveiliging van SimpleX Chat is gecontroleerd door Trail of Bits.</string>
<string name="v4_2_auto_accept_contact_requests_desc">Met optioneel welkomstbericht.</string> <string name="v4_2_auto_accept_contact_requests_desc">Met optioneel welkomst bericht.</string>
<string name="v4_3_voice_messages">Spraak berichten</string> <string name="v4_3_voice_messages">Spraak berichten</string>
<string name="v4_3_irreversible_message_deletion_desc">Uw contacten kunnen volledige verwijdering van berichten toestaan.</string> <string name="v4_3_irreversible_message_deletion_desc">Uw contacten kunnen volledige verwijdering van berichten toestaan.</string>
<string name="you_have_to_enter_passphrase_every_time">U moet elke keer dat de app start het wachtwoord invoeren, deze wordt niet op het apparaat opgeslagen.</string> <string name="you_have_to_enter_passphrase_every_time">U moet elke keer dat de app start het wachtwoord invoeren, deze wordt niet op het apparaat opgeslagen.</string>
@ -898,7 +898,6 @@
<string name="update_network_settings_question">Netwerk instellingen bijwerken\?</string> <string name="update_network_settings_question">Netwerk instellingen bijwerken\?</string>
<string name="updating_settings_will_reconnect_client_to_all_servers">Door de instellingen bij te werken, wordt de client opnieuw verbonden met alle servers.</string> <string name="updating_settings_will_reconnect_client_to_all_servers">Door de instellingen bij te werken, wordt de client opnieuw verbonden met alle servers.</string>
<string name="update_network_settings_confirmation">Update</string> <string name="update_network_settings_confirmation">Update</string>
<string name="your_chat_profiles_stored_locally">Uw chat profielen worden lokaal opgeslagen, alleen op uw apparaat</string>
<string name="incognito_random_profile">Je willekeurige profiel</string> <string name="incognito_random_profile">Je willekeurige profiel</string>
<string name="prohibit_sending_disappearing_messages">Verbied het verzenden van verdwijnende berichten.</string> <string name="prohibit_sending_disappearing_messages">Verbied het verzenden van verdwijnende berichten.</string>
<string name="prohibit_sending_voice_messages">Verbieden het verzenden van spraak berichten.</string> <string name="prohibit_sending_voice_messages">Verbieden het verzenden van spraak berichten.</string>
@ -976,8 +975,50 @@
<string name="observer_cant_send_message_desc">Neem contact op met de groep beheerder.</string> <string name="observer_cant_send_message_desc">Neem contact op met de groep beheerder.</string>
<string name="error_updating_link_for_group">Fout bij bijwerken van groep link</string> <string name="error_updating_link_for_group">Fout bij bijwerken van groep link</string>
<string name="initial_member_role">Initiële rol</string> <string name="initial_member_role">Initiële rol</string>
<string name="group_member_role_observer">waarnemer</string> <string name="group_member_role_observer">Waarnemer</string>
<string name="observer_cant_send_message_title">Je kunt geen berichten versturen!</string> <string name="observer_cant_send_message_title">Je kunt geen berichten versturen!</string>
<string name="you_are_observer">jij bent waarnemer</string> <string name="you_are_observer">jij bent waarnemer</string>
<string name="language_system">Systeem</string> <string name="language_system">Systeem</string>
<string name="v4_6_audio_video_calls">Audio en video oproepen</string>
<string name="cant_delete_user_profile">Kan gebruikers profiel niet verwijderen!</string>
<string name="confirm_password">Bevestig wachtwoord</string>
<string name="v4_6_chinese_spanish_interface">Chinese en Spaanse interface</string>
<string name="enter_password_to_show">Voer wachtwoord in bij zoeken</string>
<string name="error_saving_user_password">Fout bij opslaan gebruikers wachtwoord</string>
<string name="button_add_welcome_message">Welkomst bericht toevoegen</string>
<string name="dont_show_again">Niet meer weergeven</string>
<string name="v4_6_group_moderation">Groep moderatie</string>
<string name="error_updating_user_privacy">Fout bij updaten van gebruikers privacy</string>
<string name="v4_6_reduced_battery_usage">Verder verminderd batterij verbruik</string>
<string name="v4_6_group_welcome_message">Groep welkomst bericht</string>
<string name="v4_6_hidden_chat_profiles">Verborgen chat profielen</string>
<string name="hide_profile">Profiel verbergen</string>
<string name="user_hide">Verbergen</string>
<string name="hidden_profile_password">Verborgen profiel wachtwoord</string>
<string name="muted_when_inactive">Gedempt wanneer inactief!</string>
<string name="user_mute">Dempen</string>
<string name="v4_6_reduced_battery_usage_descr">Meer verbeteringen volgen snel!</string>
<string name="make_profile_private">Profiel privé maken!</string>
<string name="v4_6_group_moderation_descr">Nu kunnen beheerders:
\n- berichten van leden verwijderen.
\n- schakel leden uit (\"waarnemer\" rol)</string>
<string name="v4_6_hidden_chat_profiles_descr">Bescherm je chat profielen met een wachtwoord!</string>
<string name="password_to_show">Wachtwoord om weer te geven</string>
<string name="save_and_update_group_profile">Groep profiel opslaan en bijwerken</string>
<string name="smp_save_servers_question">Servers opslaan\?</string>
<string name="save_profile_password">Bewaar profiel wachtwoord</string>
<string name="v4_6_group_welcome_message_descr">Stel het getoonde bericht in voor nieuwe leden!</string>
<string name="save_welcome_message_question">Welkomst bericht opslaan\?</string>
<string name="v4_6_audio_video_calls_descr">Ondersteuning voor bluetooth en andere verbeteringen.</string>
<string name="tap_to_activate_profile">Tik om profiel te activeren.</string>
<string name="v4_6_chinese_spanish_interface_descr">Dank aan de gebruikers draag bij via Weblate!</string>
<string name="should_be_at_least_one_profile">Er moet ten minste één gebruikers profiel zijn.</string>
<string name="you_can_hide_or_mute_user_profile">U kunt een gebruikers profiel verbergen of dempen - houd het vast voor het menu.</string>
<string name="user_unhide">zichtbaar maken</string>
<string name="user_unmute">Dempen opheffen</string>
<string name="group_welcome_title">Welkomst bericht</string>
<string name="should_be_at_least_one_visible_profile">"Er moet ten minste één zichtbaar gebruikers profiel zijn."</string>
<string name="to_reveal_profile_enter_password">Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoekveld in op de pagina Uw chat profielen.</string>
<string name="button_welcome_message">Welkomst bericht</string>
<string name="you_will_still_receive_calls_and_ntfs">U ontvangt nog steeds oproepen en meldingen van gedempte profielen wanneer deze actief zijn.</string>
</resources> </resources>

View file

@ -767,7 +767,7 @@
<string name="select_contacts">Выберите контакты</string> <string name="select_contacts">Выберите контакты</string>
<string name="icon_descr_contact_checked">Контакт выбран</string> <string name="icon_descr_contact_checked">Контакт выбран</string>
<string name="clear_contacts_selection_button">Очистить</string> <string name="clear_contacts_selection_button">Очистить</string>
<string name="num_contacts_selected">Выбрано контактов: <xliff:g id="num_contacts">%1$s</xliff:g></string> <string name="num_contacts_selected">Выбрано контактов: %d</string>
<string name="no_contacts_selected">Контакты не выбраны</string> <string name="no_contacts_selected">Контакты не выбраны</string>
<string name="invite_prohibited">Нельзя пригласить контакт!</string> <string name="invite_prohibited">Нельзя пригласить контакт!</string>
<string name="invite_prohibited_description">Вы пытаетесь пригласить инкогнито контакт в группу, где вы используете свой основной профиль</string> <string name="invite_prohibited_description">Вы пытаетесь пригласить инкогнито контакт в группу, где вы используете свой основной профиль</string>
@ -1007,7 +1007,6 @@
<string name="users_delete_data_only">Только локальные данные профиля</string> <string name="users_delete_data_only">Только локальные данные профиля</string>
<string name="messages_section_title">Сообщения</string> <string name="messages_section_title">Сообщения</string>
<string name="smp_servers_per_user">Серверы для новых соединений вашего текущего профиля чата</string> <string name="smp_servers_per_user">Серверы для новых соединений вашего текущего профиля чата</string>
<string name="your_chat_profiles_stored_locally">Ваши профили чата хранятся локально, только на вашем устройстве</string>
<string name="your_chat_profiles">Ваши профили чата</string> <string name="your_chat_profiles">Ваши профили чата</string>
<string name="users_delete_all_chats_deleted">Все чаты и сообщения будут удалены - это нельзя отменить!</string> <string name="users_delete_all_chats_deleted">Все чаты и сообщения будут удалены - это нельзя отменить!</string>
<string name="app_version_code">Сборка приложения: %s</string> <string name="app_version_code">Сборка приложения: %s</string>
@ -1052,4 +1051,47 @@
<string name="group_member_role_observer">читатель</string> <string name="group_member_role_observer">читатель</string>
<string name="initial_member_role">Роль при вступлении</string> <string name="initial_member_role">Роль при вступлении</string>
<string name="error_updating_link_for_group">Ошибка обновления ссылки группы</string> <string name="error_updating_link_for_group">Ошибка обновления ссылки группы</string>
<string name="language_system">Системный</string>
<string name="v4_6_audio_video_calls">Аудио и видео звонки</string>
<string name="error_saving_user_password">Ошибка при сохранении пароля пользователя</string>
<string name="smp_save_servers_question">Сохранить серверы\?</string>
<string name="should_be_at_least_one_profile">Должен быть хотя бы один профиль пользователя.</string>
<string name="should_be_at_least_one_visible_profile">Должен быть хотя бы один открытый профиль пользователя.</string>
<string name="to_reveal_profile_enter_password">Чтобы показать Ваш скрытый профиль, введите пароль в поле поиска на странице Ваши профили чата.</string>
<string name="user_unmute">Уведомлять</string>
<string name="group_welcome_title">Приветственное сообщение</string>
<string name="confirm_password">Подтвердить пароль</string>
<string name="button_add_welcome_message">Добавить приветственное сообщение</string>
<string name="button_welcome_message">Приветственное сообщение</string>
<string name="save_and_update_group_profile">Сохранить сообщение и обновить группу</string>
<string name="muted_when_inactive">Без звука, когда не активный!</string>
<string name="cant_delete_user_profile">Нельзя удалить профиль пользователя!</string>
<string name="enter_password_to_show">Введите пароль в поиске!</string>
<string name="save_profile_password">Сохранить пароль профиля</string>
<string name="v4_6_chinese_spanish_interface">Китайский и Испанский интерфейс</string>
<string name="dont_show_again">Не показывать</string>
<string name="user_hide">Скрыть</string>
<string name="v4_6_reduced_battery_usage">Уменьшенное потребление батареи</string>
<string name="v4_6_group_moderation">Модерация группы</string>
<string name="hidden_profile_password">Пароль скрытого профиля</string>
<string name="password_to_show">Пароль чтобы раскрыть</string>
<string name="v4_6_hidden_chat_profiles">Скрытые профили чата</string>
<string name="error_updating_user_privacy">Ошибка при обновлении конфиденциальности</string>
<string name="v4_6_group_welcome_message">Приветственное сообщение группы</string>
<string name="hide_profile">Скрыть профиль</string>
<string name="user_mute">Без звука</string>
<string name="make_profile_private">Сделайте профиль конфиденциальным!</string>
<string name="v4_6_reduced_battery_usage_descr">Дополнительные улучшения скоро!</string>
<string name="v4_6_group_moderation_descr">Теперь админы могут:
\n- удалять сообщения членов.
\n- приостанавливать членов (роль \"наблюдатель\")</string>
<string name="v4_6_hidden_chat_profiles_descr">Защитите ваши профили чата паролем!</string>
<string name="user_unhide">Раскрыть</string>
<string name="v4_6_audio_video_calls_descr">Поддержка bluetooth и другие улучшения.</string>
<string name="save_welcome_message_question">Сохранить приветственное сообщение\?</string>
<string name="v4_6_group_welcome_message_descr">Установить сообщение для новых членов группы!</string>
<string name="tap_to_activate_profile">Нажмите, чтобы сделать профиль активным.</string>
<string name="v4_6_chinese_spanish_interface_descr">Благодаря пользователям добавьте переводы через Weblate!</string>
<string name="you_will_still_receive_calls_and_ntfs">Вы все равно получите звонки и уведомления в профилях без звука, когда они активные.</string>
<string name="you_can_hide_or_mute_user_profile">Вы можете скрыть профиль или выключить уведомления - подержите, чтобы увидеть меню.</string>
</resources> </resources>

View file

@ -112,7 +112,7 @@
<string name="integrity_msg_bad_hash">错误消息散列</string> <string name="integrity_msg_bad_hash">错误消息散列</string>
<string name="integrity_msg_bad_id">错误消息 ID</string> <string name="integrity_msg_bad_id">错误消息 ID</string>
<string name="settings_audio_video_calls">语音和视频通话</string> <string name="settings_audio_video_calls">语音和视频通话</string>
<string name="accept_automatically">自动</string> <string name="accept_automatically">自动</string>
<string name="turning_off_service_and_periodic">激活电池优化,关闭了后台服务和新消息的定期请求。您可以通过设置重新启用它们。</string> <string name="turning_off_service_and_periodic">激活电池优化,关闭了后台服务和新消息的定期请求。您可以通过设置重新启用它们。</string>
<string name="notifications_mode_service_desc">后台服务一直在运行——一旦有消息,就会显示通知。</string> <string name="notifications_mode_service_desc">后台服务一直在运行——一旦有消息,就会显示通知。</string>
<string name="icon_descr_audio_off">关闭音频</string> <string name="icon_descr_audio_off">关闭音频</string>
@ -132,7 +132,7 @@
<string name="it_can_disabled_via_settings_notifications_still_shown"><b> 可以通过设置禁用它 </b> - 应用程序运行时仍会显示通知。</string> <string name="it_can_disabled_via_settings_notifications_still_shown"><b> 可以通过设置禁用它 </b> - 应用程序运行时仍会显示通知。</string>
<string name="onboarding_notifications_mode_service_desc"><b> 使用更多电池 </b>!后台服务一直在运行——一旦收到消息,就会显示通知。</string> <string name="onboarding_notifications_mode_service_desc"><b> 使用更多电池 </b>!后台服务一直在运行——一旦收到消息,就会显示通知。</string>
<string name="impossible_to_recover_passphrase"><b>请注意</b>:如果您丢失密码,您将无法恢复或者更改密码。</string> <string name="impossible_to_recover_passphrase"><b>请注意</b>:如果您丢失密码,您将无法恢复或者更改密码。</string>
<string name="call_already_ended">通话已结束!</string> <string name="call_already_ended">通话已结束!</string>
<string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><b>扫描二维码</b> :与向您展示二维码的联系人联系。</string> <string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><b>扫描二维码</b> :与向您展示二维码的联系人联系。</string>
<string name="alert_title_cant_invite_contacts">无法邀请联系人!</string> <string name="alert_title_cant_invite_contacts">无法邀请联系人!</string>
<string name="invite_prohibited">无法邀请联系人!</string> <string name="invite_prohibited">无法邀请联系人!</string>
@ -234,7 +234,7 @@
<string name="clear_chat_question">清除聊天记录?</string> <string name="clear_chat_question">清除聊天记录?</string>
<string name="chat_with_developers">与开发者聊天</string> <string name="chat_with_developers">与开发者聊天</string>
<string name="clear_contacts_selection_button">清除</string> <string name="clear_contacts_selection_button">清除</string>
<string name="colored"></string> <string name="colored"></string>
<string name="callstate_connected">已连接</string> <string name="callstate_connected">已连接</string>
<string name="connect_button">连接</string> <string name="connect_button">连接</string>
<string name="connect_via_link_verb">连接</string> <string name="connect_via_link_verb">连接</string>
@ -266,7 +266,7 @@
<string name="error_deleting_pending_contact_connection">删除待定的联系人连接错误</string> <string name="error_deleting_pending_contact_connection">删除待定的联系人连接错误</string>
<string name="error_receiving_file">接收文件错误</string> <string name="error_receiving_file">接收文件错误</string>
<string name="failed_to_active_user_title">切换资料错误!</string> <string name="failed_to_active_user_title">切换资料错误!</string>
<string name="notification_preview_mode_hidden">隐藏</string> <string name="notification_preview_mode_hidden">隐藏</string>
<string name="edit_verb">编辑</string> <string name="edit_verb">编辑</string>
<string name="notification_display_mode_hidden_desc">隐藏联系人和消息</string> <string name="notification_display_mode_hidden_desc">隐藏联系人和消息</string>
<string name="icon_descr_edited">已编辑</string> <string name="icon_descr_edited">已编辑</string>
@ -510,7 +510,7 @@
<string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages">只有客户端设备存储用户配置文件、联系人、群组和使用 <b>双层端到端加密 </b> 发送的消息。</string> <string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages">只有客户端设备存储用户配置文件、联系人、群组和使用 <b>双层端到端加密 </b> 发送的消息。</string>
<string name="video_call_no_encryption">视频通话(非端到端加密)</string> <string name="video_call_no_encryption">视频通话(非端到端加密)</string>
<string name="onboarding_notifications_mode_periodic">定期</string> <string name="onboarding_notifications_mode_periodic">定期</string>
<string name="onboarding_notifications_mode_title">通知</string> <string name="onboarding_notifications_mode_title">通知</string>
<string name="onboarding_notifications_mode_off">应用程序运行时</string> <string name="onboarding_notifications_mode_off">应用程序运行时</string>
<string name="status_no_e2e_encryption">无端到端加密</string> <string name="status_no_e2e_encryption">无端到端加密</string>
<string name="show_call_on_lock_screen">显示</string> <string name="show_call_on_lock_screen">显示</string>
@ -592,7 +592,6 @@
<string name="your_chat_profiles">您的聊天资料</string> <string name="your_chat_profiles">您的聊天资料</string>
<string name="icon_descr_call_missed">未接来电</string> <string name="icon_descr_call_missed">未接来电</string>
<string name="icon_descr_call_pending_sent">待定来电</string> <string name="icon_descr_call_pending_sent">待定来电</string>
<string name="your_chat_profiles_stored_locally">您的聊天资料存储在本地,仅存储在您的设备上</string>
<string name="connection_error_auth_desc">除非您的联系人已删除此连接或此链接已被使用,否则它可能是一个错误——请报告。 <string name="connection_error_auth_desc">除非您的联系人已删除此连接或此链接已被使用,否则它可能是一个错误——请报告。
\n如果要连接请让您的联系人创建另一个连接链接并检查您的网络连接是否稳定。</string> \n如果要连接请让您的联系人创建另一个连接链接并检查您的网络连接是否稳定。</string>
<string name="you_are_already_connected_to_vName_via_this_link">您已经连接到 <xliff:g id="contactName" example="Alice">%1$s!</xliff:g></string> <string name="you_are_already_connected_to_vName_via_this_link">您已经连接到 <xliff:g id="contactName" example="Alice">%1$s!</xliff:g></string>
@ -628,7 +627,7 @@
\n<xliff:g id="appName">SimpleX</xliff:g> 服务器无法看见您的资料。</string> \n<xliff:g id="appName">SimpleX</xliff:g> 服务器无法看见您的资料。</string>
<string name="your_profile_is_stored_on_your_device">您的资料、联系人和发送的消息存储在您的设备上。</string> <string name="your_profile_is_stored_on_your_device">您的资料、联系人和发送的消息存储在您的设备上。</string>
<string name="profile_is_only_shared_with_your_contacts">该资料仅与您的联系人共享。</string> <string name="profile_is_only_shared_with_your_contacts">该资料仅与您的联系人共享。</string>
<string name="chat_preferences_on"></string> <string name="chat_preferences_on">开启</string>
<string name="delete_chat_profile_action_cannot_be_undone_warning">此操作无法撤消——您的个人资料、联系人、消息和文件将不可撤回地丢失。</string> <string name="delete_chat_profile_action_cannot_be_undone_warning">此操作无法撤消——您的个人资料、联系人、消息和文件将不可撤回地丢失。</string>
<string name="messages_section_description">此设置适用于您当前聊天资料中的消息</string> <string name="messages_section_description">此设置适用于您当前聊天资料中的消息</string>
<string name="database_restore_error">恢复数据库错误</string> <string name="database_restore_error">恢复数据库错误</string>
@ -715,7 +714,7 @@
<string name="is_verified">%s 已验证</string> <string name="is_verified">%s 已验证</string>
<string name="smp_servers_use_server_for_new_conn">用于新连接</string> <string name="smp_servers_use_server_for_new_conn">用于新连接</string>
<string name="network_disable_socks">使用直接互联网连接?</string> <string name="network_disable_socks">使用直接互联网连接?</string>
<string name="network_use_onion_hosts_required"></string> <string name="network_use_onion_hosts_required"></string>
<string name="save_and_notify_contact">保存并通知联系人</string> <string name="save_and_notify_contact">保存并通知联系人</string>
<string name="save_and_notify_contacts">保存并通知联系人</string> <string name="save_and_notify_contacts">保存并通知联系人</string>
<string name="read_more_in_github">在我们的 GitHub 仓库中阅读更多内容。</string> <string name="read_more_in_github">在我们的 GitHub 仓库中阅读更多内容。</string>
@ -843,7 +842,7 @@
<string name="group_invitation_tap_to_join">点击加入</string> <string name="group_invitation_tap_to_join">点击加入</string>
<string name="stop_chat_confirmation">停止</string> <string name="stop_chat_confirmation">停止</string>
<string name="restart_the_app_to_use_imported_chat_database">重新启动应用程序以使用导入的聊天数据库。</string> <string name="restart_the_app_to_use_imported_chat_database">重新启动应用程序以使用导入的聊天数据库。</string>
<string name="group_member_role_owner">所有者</string> <string name="group_member_role_owner">群主</string>
<string name="group_member_status_removed">已删除</string> <string name="group_member_status_removed">已删除</string>
<string name="role_in_group">角色</string> <string name="role_in_group">角色</string>
<string name="network_option_seconds_label"></string> <string name="network_option_seconds_label"></string>
@ -956,7 +955,7 @@
<string name="youve_accepted_group_invitation_connecting_to_inviting_group_member">你加入了这个群组。连接到邀请组成员。</string> <string name="youve_accepted_group_invitation_connecting_to_inviting_group_member">你加入了这个群组。连接到邀请组成员。</string>
<string name="snd_conn_event_switch_queue_phase_completed_for_member">您更改了 %s 的地址</string> <string name="snd_conn_event_switch_queue_phase_completed_for_member">您更改了 %s 的地址</string>
<string name="snd_group_event_user_left">您已离开</string> <string name="snd_group_event_user_left">您已离开</string>
<string name="num_contacts_selected"><xliff:g id="connection ID" example="1">%1$d</xliff:g> 已选择联系人</string> <string name="num_contacts_selected">%d 已选择联系人</string>
<string name="chat_preferences_you_allow">您允许</string> <string name="chat_preferences_you_allow">您允许</string>
<string name="v4_2_auto_accept_contact_requests_desc">带有可选的欢迎消息。</string> <string name="v4_2_auto_accept_contact_requests_desc">带有可选的欢迎消息。</string>
<string name="ttl_m">%dm</string> <string name="ttl_m">%dm</string>
@ -972,7 +971,7 @@
<string name="moderated_item_description">由 %s 审核</string> <string name="moderated_item_description">由 %s 审核</string>
<string name="moderate_verb">管理员移除</string> <string name="moderate_verb">管理员移除</string>
<string name="moderate_message_will_be_deleted_warning">将为所有成员删除该消息。</string> <string name="moderate_message_will_be_deleted_warning">将为所有成员删除该消息。</string>
<string name="moderate_message_will_be_marked_warning">该消息将对所有成员显示为已审核</string> <string name="moderate_message_will_be_marked_warning">该消息将对所有成员标记为已被管理员移除</string>
<string name="delete_member_message__question">删除成员消息?</string> <string name="delete_member_message__question">删除成员消息?</string>
<string name="group_member_role_observer">观察者</string> <string name="group_member_role_observer">观察者</string>
<string name="you_are_observer">您是观察者</string> <string name="you_are_observer">您是观察者</string>
@ -981,4 +980,46 @@
<string name="initial_member_role">初始角色</string> <string name="initial_member_role">初始角色</string>
<string name="observer_cant_send_message_desc">请联系群组管理员。</string> <string name="observer_cant_send_message_desc">请联系群组管理员。</string>
<string name="language_system">系统</string> <string name="language_system">系统</string>
<string name="password_to_show">用于显示的密码</string>
<string name="save_profile_password">保存个人资料密码</string>
<string name="button_add_welcome_message">添加欢迎消息</string>
<string name="user_hide">隐藏</string>
<string name="make_profile_private">将个人资料设置为私密!</string>
<string name="user_mute">静音</string>
<string name="save_and_update_group_profile">保存并更新组配置文件</string>
<string name="dont_show_again">不再显示</string>
<string name="muted_when_inactive">不活跃时静音!</string>
<string name="v4_6_audio_video_calls">语音和视频通话</string>
<string name="v4_6_chinese_spanish_interface">中文和西班牙文界面</string>
<string name="v4_6_reduced_battery_usage">进一步减少电池使用</string>
<string name="v4_6_reduced_battery_usage_descr">更多改进即将推出!</string>
<string name="v4_6_group_moderation_descr">现在管理员可以:
\n- 删除成员的消息。
\n- 禁用成员(“观察员”角色)</string>
<string name="v4_6_hidden_chat_profiles_descr">使用密码保护您的聊天资料!</string>
<string name="confirm_password">确认密码</string>
<string name="error_updating_user_privacy">更新用户隐私错误</string>
<string name="cant_delete_user_profile">无法删除用户资料!</string>
<string name="error_saving_user_password">保存用户密码错误</string>
<string name="enter_password_to_show">在搜索中输入密码</string>
<string name="v4_6_group_welcome_message">群组欢迎消息</string>
<string name="v4_6_group_moderation">群组管理员移除</string>
<string name="hidden_profile_password">隐藏的个人资料密码</string>
<string name="v4_6_hidden_chat_profiles">隐藏的聊天资料</string>
<string name="hide_profile">隐藏个人资料</string>
<string name="smp_save_servers_question">保存服务器?</string>
<string name="to_reveal_profile_enter_password">要显示您的隐藏的个人资料,请在您的聊天个人资料页面的搜索字段中输入完整密码。</string>
<string name="save_welcome_message_question">保存欢迎信息?</string>
<string name="tap_to_activate_profile">点击以激活个人资料。</string>
<string name="should_be_at_least_one_profile">应该至少有一个用户资料。</string>
<string name="user_unhide">解除隐藏</string>
<string name="v4_6_group_welcome_message_descr">设置向新成员显示的消息!</string>
<string name="v4_6_audio_video_calls_descr">支持蓝牙和其他改进。</string>
<string name="v4_6_chinese_spanish_interface_descr">感谢用户——通过 Weblate 做出贡献!</string>
<string name="should_be_at_least_one_visible_profile">应该至少有一个可见的用户资料。</string>
<string name="user_unmute">解除静音</string>
<string name="button_welcome_message">欢迎信息</string>
<string name="you_will_still_receive_calls_and_ntfs">当静音配置文件处于活动状态时,您仍会收到来自静音配置文件的电话和通知。</string>
<string name="you_can_hide_or_mute_user_profile">您可以隐藏或静音用户配置文件——长按以显示菜单。</string>
<string name="group_welcome_title">欢迎信息</string>
</resources> </resources>

View file

@ -765,7 +765,6 @@
<string name="network_options_save">儲存</string> <string name="network_options_save">儲存</string>
<string name="update_network_settings_question">更新網路設定?</string> <string name="update_network_settings_question">更新網路設定?</string>
<string name="update_network_settings_confirmation">更新</string> <string name="update_network_settings_confirmation">更新</string>
<string name="your_chat_profiles_stored_locally">你的個人檔案只會儲存於你的本機裝置內。</string>
<string name="updating_settings_will_reconnect_client_to_all_servers">更新設定會將客戶端重新連接到所有的伺服器。</string> <string name="updating_settings_will_reconnect_client_to_all_servers">更新設定會將客戶端重新連接到所有的伺服器。</string>
<string name="users_delete_question">刪除個人檔案?</string> <string name="users_delete_question">刪除個人檔案?</string>
<string name="users_delete_profile_for">刪除個人檔案</string> <string name="users_delete_profile_for">刪除個人檔案</string>
@ -927,7 +926,7 @@
<string name="you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved">你將停止接收來自此群組的訊息。群組內的記錄會保留。</string> <string name="you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved">你將停止接收來自此群組的訊息。群組內的記錄會保留。</string>
<string name="you_rejected_group_invitation">你已拒絕加入群組</string> <string name="you_rejected_group_invitation">你已拒絕加入群組</string>
<string name="group_member_status_announced">連線中(宣布階段)</string> <string name="group_member_status_announced">連線中(宣布階段)</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> 已選擇多個聊絡人</string> <string name="num_contacts_selected">%d 已選擇多個聊絡人</string>
<string name="your_ice_servers">你的 ICE 伺服器</string> <string name="your_ice_servers">你的 ICE 伺服器</string>
<string name="webrtc_ice_servers">WebRTC ICE 伺服器</string> <string name="webrtc_ice_servers">WebRTC ICE 伺服器</string>
<string name="update_database">更新</string> <string name="update_database">更新</string>
@ -983,4 +982,48 @@
<string name="observer_cant_send_message_desc">請聯繫群管理員。</string> <string name="observer_cant_send_message_desc">請聯繫群管理員。</string>
<string name="initial_member_role">初始角色</string> <string name="initial_member_role">初始角色</string>
<string name="language_system">系統</string> <string name="language_system">系統</string>
<string name="you_can_hide_or_mute_user_profile">您可以隱藏或靜音用戶配置文件 - 按住它以顯示菜單。</string>
<string name="smp_save_servers_question">保存服務器?</string>
<string name="confirm_password">確認密碼</string>
<string name="hidden_profile_password">隱藏的個人資料密碼</string>
<string name="hide_profile">隱藏個人資料</string>
<string name="password_to_show">顯示密碼</string>
<string name="save_profile_password">保存個人資料密碼</string>
<string name="to_reveal_profile_enter_password">要顯示您的隱藏個人資料,請在您的聊天個人資料頁面的搜索字段中輸入完整密碼。</string>
<string name="button_welcome_message">歡迎信息</string>
<string name="save_and_update_group_profile">保存和更新組配置文件</string>
<string name="save_welcome_message_question">保存歡迎信息?</string>
<string name="cant_delete_user_profile">無法刪除用戶個人資料!</string>
<string name="user_hide">隱藏</string>
<string name="make_profile_private">將個人資料設為私密!</string>
<string name="v4_6_audio_video_calls">音視頻通話</string>
<string name="v4_6_chinese_spanish_interface">中文和西班牙文界面</string>
<string name="v4_6_reduced_battery_usage">進一步減少電池使用</string>
<string name="v4_6_group_moderation">小組審核</string>
<string name="v4_6_reduced_battery_usage_descr">更多改進即將推出!</string>
<string name="v4_6_group_moderation_descr">現在管理員可以:
\n- 刪除成員的消息。
\n- 禁用成員(“觀察員”角色)</string>
<string name="v4_6_hidden_chat_profiles_descr">使用密碼保護您的聊天資料!</string>
<string name="relay_server_protects_ip">中繼服務器保護您的 IP 地址,但它可以觀察通話的持續時間。</string>
<string name="button_add_welcome_message">添加歡迎信息</string>
<string name="error_saving_user_password">保存用戶密碼時出錯</string>
<string name="error_updating_user_privacy">更新用戶隱私時出錯</string>
<string name="relay_server_if_necessary">中繼服務器僅在必要時使用。 另一方可以觀察到您的 IP 地址。</string>
<string name="enter_password_to_show">在上面輸入密碼以顯示!</string>
<string name="v4_6_group_welcome_message">群组欢迎信息</string>
<string name="v4_6_hidden_chat_profiles">隱藏的聊天資料</string>
<string name="dont_show_again">不再顯示</string>
<string name="user_mute">靜音</string>
<string name="muted_when_inactive">Muted when inactive!</string>
<string name="v4_6_group_welcome_message_descr">設置向新成員顯示的消息!</string>
<string name="tap_to_activate_profile">點擊以激活配置文件。</string>
<string name="v4_6_audio_video_calls_descr">支持藍牙和其他改進。</string>
<string name="should_be_at_least_one_visible_profile">應該至少有一個可見的用戶配置文件。</string>
<string name="group_welcome_title">歡迎信息</string>
<string name="v4_6_chinese_spanish_interface_descr">感謝用戶——通過 Weblate 做出貢獻!</string>
<string name="should_be_at_least_one_profile">應該至少有一個用戶配置文件。</string>
<string name="user_unmute">取消靜音</string>
<string name="you_will_still_receive_calls_and_ntfs">當靜音配置文件處於活動狀態時,您仍會收到來自靜音配置文件的電話和通知。</string>
<string name="user_unhide">取消隱藏</string>
</resources> </resources>

View file

@ -2,5 +2,6 @@
<resources> <resources>
<color name="black">#FF000000</color> <color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<color name="highOrLowLight">#8b8786</color>
<color name="window_background_dark">#121212</color> <color name="window_background_dark">#121212</color>
</resources> </resources>

View file

@ -922,7 +922,7 @@
<string name="select_contacts">Select contacts</string> <string name="select_contacts">Select contacts</string>
<string name="icon_descr_contact_checked">Contact checked</string> <string name="icon_descr_contact_checked">Contact checked</string>
<string name="clear_contacts_selection_button">Clear</string> <string name="clear_contacts_selection_button">Clear</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> contact(s) selected</string> <string name="num_contacts_selected">%d contact(s) selected</string>
<string name="no_contacts_selected">No contacts selected</string> <string name="no_contacts_selected">No contacts selected</string>
<string name="invite_prohibited">Can\'t invite contact!</string> <string name="invite_prohibited">Can\'t invite contact!</string>
<string name="invite_prohibited_description">You\'re trying to invite contact with whom you\'ve shared an incognito profile to the group in which you\'re using your main profile</string> <string name="invite_prohibited_description">You\'re trying to invite contact with whom you\'ve shared an incognito profile to the group in which you\'re using your main profile</string>
@ -1017,7 +1017,6 @@
<string name="update_network_settings_confirmation">Update</string> <string name="update_network_settings_confirmation">Update</string>
<!-- UserProfilesView.kt --> <!-- UserProfilesView.kt -->
<string name="your_chat_profiles_stored_locally">Your chat profiles are stored locally, only on your device</string>
<string name="users_add">Add profile</string> <string name="users_add">Add profile</string>
<string name="users_delete_question">Delete chat profile?</string> <string name="users_delete_question">Delete chat profile?</string>
<string name="users_delete_all_chats_deleted">All chats and messages will be deleted - this cannot be undone!</string> <string name="users_delete_all_chats_deleted">All chats and messages will be deleted - this cannot be undone!</string>
@ -1028,13 +1027,13 @@
<string name="user_unhide">Unhide</string> <string name="user_unhide">Unhide</string>
<string name="user_mute">Mute</string> <string name="user_mute">Mute</string>
<string name="user_unmute">Unmute</string> <string name="user_unmute">Unmute</string>
<string name="enter_password_to_show">Enter password above to show!</string> <string name="enter_password_to_show">Enter password in search</string>
<string name="tap_to_activate_profile">Tap to activate profile.</string> <string name="tap_to_activate_profile">Tap to activate profile.</string>
<string name="cant_delete_user_profile">Can\'t delete user profile!</string> <string name="cant_delete_user_profile">Can\'t delete user profile!</string>
<string name="should_be_at_least_one_visible_profile">There should be at least one visible user profile.</string> <string name="should_be_at_least_one_visible_profile">There should be at least one visible user profile.</string>
<string name="should_be_at_least_one_profile">There should be at least one user profile.</string> <string name="should_be_at_least_one_profile">There should be at least one user profile.</string>
<string name="make_profile_private">Make profile private!</string> <string name="make_profile_private">Make profile private!</string>
<string name="you_can_hide_or_mute_user_profile">You can hide or mute a user profile - hold it for the menu.\nSimpleX Lock must be enabled.</string> <string name="you_can_hide_or_mute_user_profile">You can hide or mute a user profile - hold it for the menu.</string>
<string name="dont_show_again">Don\'t show again</string> <string name="dont_show_again">Don\'t show again</string>
<string name="muted_when_inactive">Muted when inactive!</string> <string name="muted_when_inactive">Muted when inactive!</string>
<string name="you_will_still_receive_calls_and_ntfs">You will still receive calls and notifications from muted profiles when they are active.</string> <string name="you_will_still_receive_calls_and_ntfs">You will still receive calls and notifications from muted profiles when they are active.</string>

View file

@ -8,6 +8,7 @@ buildscript {
compose_version = localProperties['compose_version'] ?: '1.2.0-beta02' compose_version = localProperties['compose_version'] ?: '1.2.0-beta02'
kotlin_version = localProperties['kotlin_version'] ?: '1.6.21' kotlin_version = localProperties['kotlin_version'] ?: '1.6.21'
gradle_plugin_version = localProperties['gradle_plugin_version'] ?: '7.2.0' gradle_plugin_version = localProperties['gradle_plugin_version'] ?: '7.2.0'
abi_filter = localProperties['abi_filter'] ?: 'arm64-v8a'
// Name that will be shown for debug build. By default it is from strings // Name that will be shown for debug build. By default it is from strings
app_name = localProperties['app_name'] ?: "@string/app_name" app_name = localProperties['app_name'] ?: "@string/app_name"

View file

@ -984,7 +984,7 @@ func apiGetGroupLink(_ groupId: Int64) throws -> (String, GroupMemberRole)? {
func apiGetVersion() throws -> CoreVersionInfo { func apiGetVersion() throws -> CoreVersionInfo {
let r = chatSendCmdSync(.showVersion) let r = chatSendCmdSync(.showVersion)
if case let .versionInfo(info) = r { return info } if case let .versionInfo(info, _, _) = r { return info }
throw r throw r
} }
@ -995,10 +995,10 @@ private func currentUserId(_ funcName: String) throws -> Int64 {
throw RuntimeError("\(funcName): no current user") throw RuntimeError("\(funcName): no current user")
} }
func initializeChat(start: Bool, dbKey: String? = nil, refreshInvitations: Bool = true) throws { func initializeChat(start: Bool, dbKey: String? = nil, refreshInvitations: Bool = true, confirmMigrations: MigrationConfirmation? = nil) throws {
logger.debug("initializeChat") logger.debug("initializeChat")
let m = ChatModel.shared let m = ChatModel.shared
(m.chatDbEncrypted, m.chatDbStatus) = chatMigrateInit(dbKey) (m.chatDbEncrypted, m.chatDbStatus) = chatMigrateInit(dbKey, confirmMigrations: confirmMigrations)
if m.chatDbStatus != .ok { return } if m.chatDbStatus != .ok { return }
// If we migrated successfully means previous re-encryption process on database level finished successfully too // If we migrated successfully means previous re-encryption process on database level finished successfully too
if encryptionStartedDefault.get() { if encryptionStartedDefault.get() {

View file

@ -71,7 +71,7 @@ struct ChatListView: View {
.toolbar { .toolbar {
ToolbarItem(placement: .navigationBarLeading) { ToolbarItem(placement: .navigationBarLeading) {
Button { Button {
if chatModel.users.count > 1 { if chatModel.users.filter { u in u.user.activeUser || !u.user.hidden }.count > 1 {
withAnimation { withAnimation {
userPickerVisible.toggle() userPickerVisible.toggle()
} }

View file

@ -16,40 +16,68 @@ struct DatabaseErrorView: View {
@State private var storedDBKey = getDatabaseKey() @State private var storedDBKey = getDatabaseKey()
@State private var useKeychain = storeDBPassphraseGroupDefault.get() @State private var useKeychain = storeDBPassphraseGroupDefault.get()
@State private var showRestoreDbButton = false @State private var showRestoreDbButton = false
@State private var starting = false
var body: some View { var body: some View {
ZStack {
databaseErrorView().disabled(starting)
if starting {
ProgressView().scaleEffect(2)
}
}
}
@ViewBuilder private func databaseErrorView() -> some View {
VStack(alignment: .leading, spacing: 16) { VStack(alignment: .leading, spacing: 16) {
switch status { switch status {
case let .errorNotADatabase(dbFile): case let .errorNotADatabase(dbFile):
if useKeychain && storedDBKey != nil && storedDBKey != "" { if useKeychain && storedDBKey != nil && storedDBKey != "" {
Text("Wrong database passphrase").font(.title) titleText("Wrong database passphrase")
Text("Database passphrase is different from saved in the keychain.") Text("Database passphrase is different from saved in the keychain.")
databaseKeyField(onSubmit: saveAndRunChat) databaseKeyField(onSubmit: saveAndRunChat)
saveAndOpenButton() saveAndOpenButton()
Text("File: \(dbFile)") fileNameText(dbFile)
} else { } else {
Text("Encrypted database").font(.title) titleText("Encrypted database")
Text("Database passphrase is required to open chat.") Text("Database passphrase is required to open chat.")
if useKeychain { if useKeychain {
databaseKeyField(onSubmit: saveAndRunChat) databaseKeyField(onSubmit: saveAndRunChat)
saveAndOpenButton() saveAndOpenButton()
} else { } else {
databaseKeyField(onSubmit: runChat) databaseKeyField(onSubmit: { runChat() })
openChatButton() openChatButton()
} }
} }
case let .error(dbFile, migrationError): case let .errorMigration(dbFile, migrationError):
Text("Database error") switch migrationError {
.font(.title) case let .upgrade(upMigrations):
Text("File: \(dbFile)") titleText("Database upgrade")
Text("Error: \(migrationError)") Button("Upgrade and open chat") { runChat(confirmMigrations: .yesUp) }
fileNameText(dbFile)
migrationsText(upMigrations.map(\.upName))
case let .downgrade(downMigrations):
titleText("Database downgrade")
Text("Warning: you may lose some data!").bold()
Button("Downgrade and open chat") { runChat(confirmMigrations: .yesUpDown) }
fileNameText(dbFile)
migrationsText(downMigrations)
case let .migrationError(mtrError):
titleText("Incompatible database version")
fileNameText(dbFile)
Text("Error: ") + Text(mtrErrorDescription(mtrError))
}
case let .errorSQL(dbFile, migrationSQLError):
titleText("Database error")
fileNameText(dbFile)
Text("Error: \(migrationSQLError)")
case .errorKeychain: case .errorKeychain:
Text("Keychain error") titleText("Keychain error")
.font(.title)
Text("Cannot access keychain to save database password") Text("Cannot access keychain to save database password")
case .invalidConfirmation:
// this can only happen if incorrect parameter is passed
Text(String("Invalid migration confirmation")).font(.title)
case let .unknown(json): case let .unknown(json):
Text("Database error") titleText("Database error")
.font(.title)
Text("Unknown database error: \(json)") Text("Unknown database error: \(json)")
case .ok: case .ok:
EmptyView() EmptyView()
@ -61,10 +89,31 @@ struct DatabaseErrorView: View {
} }
} }
.padding() .padding()
.frame(maxHeight: .infinity, alignment: .topLeading) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
.onAppear() { showRestoreDbButton = shouldShowRestoreDbButton() } .onAppear() { showRestoreDbButton = shouldShowRestoreDbButton() }
} }
private func titleText(_ s: LocalizedStringKey) -> Text {
Text(s).font(.title)
}
private func fileNameText(_ f: String) -> Text {
Text("File: \((f as NSString).lastPathComponent)")
}
private func migrationsText(_ ms: [String]) -> Text {
Text("Migrations: \(ms.joined(separator: ", "))")
}
private func mtrErrorDescription(_ err: MTRError) -> LocalizedStringKey {
switch err {
case let .noDown(dbMigrations):
return "database version is newer than the app, but no down migration for: \(dbMigrations.joined(separator: ", "))"
case let .different(appMigration, dbMigration):
return "different migration in the app/database: \(appMigration) / \(dbMigration)"
}
}
private func databaseKeyField(onSubmit: @escaping () -> Void) -> some View { private func databaseKeyField(onSubmit: @escaping () -> Void) -> some View {
PassphraseField(key: $dbKey, placeholder: "Enter passphrase…", valid: validKey(dbKey), onSubmit: onSubmit) PassphraseField(key: $dbKey, placeholder: "Enter passphrase…", valid: validKey(dbKey), onSubmit: onSubmit)
} }
@ -89,14 +138,24 @@ struct DatabaseErrorView: View {
runChat() runChat()
} }
private func runChat() { private func runChat(confirmMigrations: MigrationConfirmation? = nil) {
starting = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
runChatSync(confirmMigrations: confirmMigrations)
starting = false
}
}
private func runChatSync(confirmMigrations: MigrationConfirmation? = nil) {
do { do {
resetChatCtrl() resetChatCtrl()
try initializeChat(start: m.v3DBMigration.startChat, dbKey: dbKey) try initializeChat(start: m.v3DBMigration.startChat, dbKey: useKeychain ? nil : dbKey, confirmMigrations: confirmMigrations)
if let s = m.chatDbStatus { if let s = m.chatDbStatus {
status = s status = s
let am = AlertManager.shared let am = AlertManager.shared
switch s { switch s {
case .invalidConfirmation:
am.showAlert(Alert(title: Text(String("Invalid migration confirmation"))))
case .errorNotADatabase: case .errorNotADatabase:
am.showAlertMsg( am.showAlertMsg(
title: "Wrong passphrase!", title: "Wrong passphrase!",
@ -104,7 +163,7 @@ struct DatabaseErrorView: View {
) )
case .errorKeychain: case .errorKeychain:
am.showAlertMsg(title: "Keychain error") am.showAlertMsg(title: "Keychain error")
case let .error(_, error): case let .errorSQL(_, error):
am.showAlert(Alert( am.showAlert(Alert(
title: Text("Database error"), title: Text("Database error"),
message: Text(error) message: Text(error)
@ -114,6 +173,7 @@ struct DatabaseErrorView: View {
title: Text("Unknown error"), title: Text("Unknown error"),
message: Text(error) message: Text(error)
)) ))
case .errorMigration: ()
case .ok: () case .ok: ()
} }
} }

View file

@ -11,7 +11,7 @@ import SimpleXChat
struct CallSettings: View { struct CallSettings: View {
@AppStorage(DEFAULT_WEBRTC_POLICY_RELAY) private var webrtcPolicyRelay = true @AppStorage(DEFAULT_WEBRTC_POLICY_RELAY) private var webrtcPolicyRelay = true
@AppStorage(GROUP_DEFAULT_CALL_KIT_ENABLED, store: UserDefaults(suiteName: APP_GROUP_NAME)!) private var callKitEnabled = true @AppStorage(GROUP_DEFAULT_CALL_KIT_ENABLED, store: groupDefaults) private var callKitEnabled = true
@AppStorage(DEFAULT_CALL_KIT_CALLS_IN_RECENTS) private var callKitCallsInRecents = false @AppStorage(DEFAULT_CALL_KIT_CALLS_IN_RECENTS) private var callKitCallsInRecents = false
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
private let allowChangingCallsHistory = false private let allowChangingCallsHistory = false

View file

@ -0,0 +1,50 @@
//
// DeveloperView.swift
// SimpleX (iOS)
//
// Created by Evgeny on 26/03/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import SwiftUI
import SimpleXChat
struct DeveloperView: View {
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
@AppStorage(GROUP_DEFAULT_CONFIRM_DB_UPGRADES, store: groupDefaults) private var confirmDatabaseUpgrades = false
@Environment(\.colorScheme) var colorScheme
var body: some View {
VStack {
List {
Section {
NavigationLink {
TerminalView()
} label: {
settingsRow("terminal") { Text("Chat console") }
}
settingsRow("chevron.left.forwardslash.chevron.right") {
Toggle("Show developer options", isOn: $developerTools)
}
settingsRow("internaldrive") {
Toggle("Confirm database upgrades", isOn: $confirmDatabaseUpgrades)
}
ZStack(alignment: .leading) {
Image(colorScheme == .dark ? "github_light" : "github")
.resizable()
.frame(width: 24, height: 24)
.opacity(0.5)
Text("Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)")
.padding(.leading, 36)
}
}
}
}
}
}
struct DeveloperView_Previews: PreviewProvider {
static var previews: some View {
DeveloperView()
}
}

View file

@ -108,7 +108,6 @@ struct SettingsView: View {
@EnvironmentObject var chatModel: ChatModel @EnvironmentObject var chatModel: ChatModel
@EnvironmentObject var sceneDelegate: SceneDelegate @EnvironmentObject var sceneDelegate: SceneDelegate
@Binding var showSettings: Bool @Binding var showSettings: Bool
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
@State private var settingsSheet: SettingsSheet? @State private var settingsSheet: SettingsSheet?
var body: some View { var body: some View {
@ -259,23 +258,11 @@ struct SettingsView: View {
} }
Section("Develop") { Section("Develop") {
settingsRow("chevron.left.forwardslash.chevron.right") { NavigationLink {
Toggle("Developer tools", isOn: $developerTools) DeveloperView()
} .navigationTitle("Developer tools")
if developerTools { } label: {
NavigationLink { settingsRow("chevron.left.forwardslash.chevron.right") { Text("Developer tools") }
TerminalView()
} label: {
settingsRow("terminal") { Text("Chat console") }
}
ZStack(alignment: .leading) {
Image(colorScheme == .dark ? "github_light" : "github")
.resizable()
.frame(width: 24, height: 24)
.opacity(0.5)
Text("Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)")
.padding(.leading, indent)
}
} }
NavigationLink { NavigationLink {
ExperimentalFeaturesView() ExperimentalFeaturesView()

View file

@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>Přidat uvítací zprávu</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>Hlasové a video hovory</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -600,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>Nemohu smazat uživatelský profil!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -709,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>Čínské a Španělské rozhranní</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -768,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>Potvrdit heslo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -1300,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>Znovu neukazuj</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1563,6 +1569,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>Chyba ukládání hesla uživatele</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1602,6 +1609,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>Chyba aktualizace soukromí uživatele</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1695,6 +1703,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>Další snížení spotřeby baterie</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1774,6 +1783,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>Správa skupin</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1793,6 +1803,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>Uvítací zpráva skupin</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1817,10 +1828,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>Skryté chat profily</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>Hesla skrytých profilů</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1835,6 +1848,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>Skrýt profil</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1962,6 +1976,11 @@
<target>Nesprávný bezpečnostní kód!</target> <target>Nesprávný bezpečnostní kód!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Počáteční role</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>Nainstalujte [SimpleX Chat pro terminál](https://github.com/simplex-chat/simplex-chat)</target> <target>Nainstalujte [SimpleX Chat pro terminál](https://github.com/simplex-chat/simplex-chat)</target>
@ -2141,6 +2160,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>Změnit profil na soukromý!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2270,6 +2290,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>Ztlumit při neaktivitě!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2376,6 +2397,9 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>Nyní mohou správci:
- mazat zprávy členů.
- zakázat členy (role "pozorovatel")</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
@ -2505,6 +2529,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>Heslo k zobrazení</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2659,6 +2684,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>Chraňte své chat profily heslem!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2858,6 +2884,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>Uložit a aktualizovat profil skupiny</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2887,6 +2914,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>Uložit heslo profilu</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2896,10 +2924,12 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>Uložit servery?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>Uložit uvítací zprávu?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3054,6 +3084,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>Nastavte zprávu zobrazenou novým členům!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3238,6 +3269,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>Klepnutím aktivujete profil.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3367,6 +3399,7 @@ Budeme přidávat redundantní servery, abychom zabránili ztrátě zpráv.</tar
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>Měl by tam být alespoň jeden uživatelský profil.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">

View file

@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>Fügen Sie eine Begrüßungsmeldung hinzu</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>Audio- und Videoanrufe</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -600,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>Das Benutzerprofil kann nicht gelöscht werden!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -709,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>Chinesische und spanische Bedienoberfläche</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -768,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>Bestätigen Sie das Passwort</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -1300,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>Nicht nochmals anzeigen</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1404,6 +1410,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Enter password above to show!" xml:space="preserve"> <trans-unit id="Enter password above to show!" xml:space="preserve">
<source>Enter password above to show!</source> <source>Enter password above to show!</source>
<target>Geben Sie oben das Passwort für die Anzeige an!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Enter server manually" xml:space="preserve"> <trans-unit id="Enter server manually" xml:space="preserve">
@ -1563,6 +1570,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>Fehler beim Speichern des Benutzer-Passworts</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1602,6 +1610,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>Fehler beim Aktualisieren der Benutzer-Privatsphäre</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1691,10 +1700,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve"> <trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
<source>Fully re-implemented - work in background!</source> <source>Fully re-implemented - work in background!</source>
<target>Komplett neu umgesetzt - arbeitet nun im Hintergrund!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>Weiter reduzierter Batterieverbrauch</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1774,6 +1785,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>Gruppenmoderation</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1793,6 +1805,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>Gruppen-Begrüßungsmeldung</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1817,10 +1830,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>Verborgene Chat-Profile</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>Verborgenes Profil-Passwort</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1835,6 +1850,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>Verberge das Profil</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1962,6 +1978,11 @@
<target>Falscher Sicherheitscode!</target> <target>Falscher Sicherheitscode!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Anfängliche Rolle</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>Installieren Sie [SimpleX Chat als Terminalanwendung](https://github.com/simplex-chat/simplex-chat)</target> <target>Installieren Sie [SimpleX Chat als Terminalanwendung](https://github.com/simplex-chat/simplex-chat)</target>
@ -2141,6 +2162,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>Erzeugen Sie ein privates Profil!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2270,6 +2292,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>Bei Inaktivität stummgeschaltet!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2376,6 +2399,9 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>Administratoren können nun
- Nachrichten von Gruppenmitgliedern löschen
- Gruppenmitglieder deaktivieren ("Beobachter"-Rolle)</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
@ -2505,6 +2531,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>Passwort anzeigen</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2659,6 +2686,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>Schützen Sie Ihre Chat-Profile mit einem Passwort!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2858,6 +2886,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>Sichern und aktualisieren des Gruppen-Profils</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2887,6 +2916,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>Profil-Passwort speichern</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2896,10 +2926,12 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>Alle Server speichern?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>Begrüßungsmeldung speichern?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3054,6 +3086,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>Legen Sie die Nachricht fest, die neuen Mitgliedern angezeigt werden soll!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3238,6 +3271,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>Tippen Sie, um das Profil zu aktivieren.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3367,10 +3401,12 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>Es muss mindestens ein Benutzer-Profil vorhanden sein.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">
<source>There should be at least one visible user profile.</source> <source>There should be at least one visible user profile.</source>
<target>Es muss mindestens ein sichtbares Benutzer-Profil vorhanden sein.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve"> <trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
@ -3442,6 +3478,7 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
</trans-unit> </trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve"> <trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source> <source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Geben Sie ein vollständiges Passwort in das Suchfeld auf der Seite **Meine Chat-Profile** ein, um Ihr verborgenes Profil zu sehen.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve"> <trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@ -3501,6 +3538,7 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
</trans-unit> </trans-unit>
<trans-unit id="Unhide" xml:space="preserve"> <trans-unit id="Unhide" xml:space="preserve">
<source>Unhide</source> <source>Unhide</source>
<target>Verbergen aufheben</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown caller" xml:space="preserve"> <trans-unit id="Unknown caller" xml:space="preserve">
@ -3778,6 +3816,8 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve"> <trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right. <source>You can hide or mute a user profile - swipe it to the right.
SimpleX Lock must be enabled.</source> SimpleX Lock must be enabled.</source>
<target>Sie können ein Benutzerprofil verbergen oder stummschalten - wischen Sie es nach rechts.
Dafür muss die SimpleX Sperre aktiviert sein.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can now send messages to %@" xml:space="preserve"> <trans-unit id="You can now send messages to %@" xml:space="preserve">
@ -3897,6 +3937,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit> </trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve"> <trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
<source>You will still receive calls and notifications from muted profiles when they are active.</source> <source>You will still receive calls and notifications from muted profiles when they are active.</source>
<target>Sie können Anrufe und Benachrichtigungen auch von stummgeschalteten Profilen empfangen, solange diese aktiv sind.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve"> <trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve">

View file

@ -1978,6 +1978,11 @@
<target>Incorrect security code!</target> <target>Incorrect security code!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Initial role</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</target> <target>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</target>

View file

@ -189,7 +189,7 @@
</trans-unit> </trans-unit>
<trans-unit id="**Add new contact**: to create your one-time QR Code for your contact." xml:space="preserve"> <trans-unit id="**Add new contact**: to create your one-time QR Code for your contact." xml:space="preserve">
<source>**Add new contact**: to create your one-time QR Code or link for your contact.</source> <source>**Add new contact**: to create your one-time QR Code or link for your contact.</source>
<target>**Añadir nuevo contacto**: para crear tu código QR único o un enlace para tu contacto.</target> <target>**Añadir nuevo contacto**: para crear tu código QR o enlace de un uso para tu contacto.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="**Create link / QR code** for your contact to use." xml:space="preserve"> <trans-unit id="**Create link / QR code** for your contact to use." xml:space="preserve">
@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>Agregar mensaje de bienvenida</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -426,7 +427,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve"> <trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
<source>Allow disappearing messages only if your contact allows it to you.</source> <source>Allow disappearing messages only if your contact allows it to you.</source>
<target>Permitir mensajes temporales sólo si tu contacto también los permite para tí.</target> <target>Permitir mensajes temporales sólo si tu contacto también los permite.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow irreversible message deletion only if your contact allows it to you." xml:space="preserve"> <trans-unit id="Allow irreversible message deletion only if your contact allows it to you." xml:space="preserve">
@ -471,7 +472,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Allow your contacts to send disappearing messages." xml:space="preserve"> <trans-unit id="Allow your contacts to send disappearing messages." xml:space="preserve">
<source>Allow your contacts to send disappearing messages.</source> <source>Allow your contacts to send disappearing messages.</source>
<target>Permitir a tus contactos enviar mensajes que desaparecen.</target> <target>Permitir a tus contactos enviar mensajes temporales.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow your contacts to send voice messages." xml:space="preserve"> <trans-unit id="Allow your contacts to send voice messages." xml:space="preserve">
@ -486,7 +487,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Always use relay" xml:space="preserve"> <trans-unit id="Always use relay" xml:space="preserve">
<source>Always use relay</source> <source>Always use relay</source>
<target>Siempre usa relay</target> <target>Siempre usar relay</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Answer call" xml:space="preserve"> <trans-unit id="Answer call" xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>Llamadas y videollamadas</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -585,7 +587,7 @@
</trans-unit> </trans-unit>
<trans-unit id="By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." xml:space="preserve"> <trans-unit id="By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." xml:space="preserve">
<source>By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).</source> <source>By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).</source>
<target>Por perfil de Chat (por defecto) o [por conexión](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).</target> <target>Mediante perfil de Chat (por defecto) o [por conexión](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Call already ended!" xml:space="preserve"> <trans-unit id="Call already ended!" xml:space="preserve">
@ -600,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>¡No se puede eliminar el perfil!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -709,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>Interfaz en chino y español</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -768,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>Confirmar contraseña</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -797,7 +802,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Connect via one-time link?" xml:space="preserve"> <trans-unit id="Connect via one-time link?" xml:space="preserve">
<source>Connect via one-time link?</source> <source>Connect via one-time link?</source>
<target>¿Conectar mediante enlace único?</target> <target>¿Conectar mediante enlace de un uso?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve"> <trans-unit id="Connecting server…" xml:space="preserve">
@ -927,7 +932,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Create one-time invitation link" xml:space="preserve"> <trans-unit id="Create one-time invitation link" xml:space="preserve">
<source>Create one-time invitation link</source> <source>Create one-time invitation link</source>
<target>Crear enlace único de invitación</target> <target>Crear enlace de invitación de un uso</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Create queue" xml:space="preserve"> <trans-unit id="Create queue" xml:space="preserve">
@ -1300,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>No mostrar de nuevo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1404,6 +1410,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Enter password above to show!" xml:space="preserve"> <trans-unit id="Enter password above to show!" xml:space="preserve">
<source>Enter password above to show!</source> <source>Enter password above to show!</source>
<target>¡Introduce la contraseña arriba para mostrar!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Enter server manually" xml:space="preserve"> <trans-unit id="Enter server manually" xml:space="preserve">
@ -1563,6 +1570,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>Error guardando la contraseña de usuario</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1602,6 +1610,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>Error actualizando la privacidad de usuario</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1691,10 +1700,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve"> <trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
<source>Fully re-implemented - work in background!</source> <source>Fully re-implemented - work in background!</source>
<target>Completamente reimplementado: ¡funciona en segundo plano!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>Consumo de batería reducido aun más</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1774,6 +1785,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>Moderación de grupos</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1793,6 +1805,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>Mensaje de bienvenida en grupos</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1817,10 +1830,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>Perfiles Chat ocultos</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>Contraseña de perfil oculto</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1835,6 +1850,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>Ocultar perfil</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1962,6 +1978,11 @@
<target>¡Código de seguridad incorrecto!</target> <target>¡Código de seguridad incorrecto!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Rol inicial</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>Instalar [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</target> <target>Instalar [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</target>
@ -2026,7 +2047,7 @@
</trans-unit> </trans-unit>
<trans-unit id="It allows having many anonymous connections without any shared data between them in a single chat profile." xml:space="preserve"> <trans-unit id="It allows having many anonymous connections without any shared data between them in a single chat profile." xml:space="preserve">
<source>It allows having many anonymous connections without any shared data between them in a single chat profile.</source> <source>It allows having many anonymous connections without any shared data between them in a single chat profile.</source>
<target>Permite tener muchas conexiones anónimas sin datos compartidos entre estas en un único perfil de chat.</target> <target>Permite tener varias conexiones anónimas sin datos compartidos entre estas en un único perfil de chat.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="It can happen when:&#10;1. The messages expire on the server if they were not received for 30 days,&#10;2. The server you use to receive the messages from this contact was updated and restarted.&#10;3. The connection is compromised.&#10;Please connect to the developers via Settings to receive the updates about the servers.&#10;We will be adding server redundancy to prevent lost messages." xml:space="preserve"> <trans-unit id="It can happen when:&#10;1. The messages expire on the server if they were not received for 30 days,&#10;2. The server you use to receive the messages from this contact was updated and restarted.&#10;3. The connection is compromised.&#10;Please connect to the developers via Settings to receive the updates about the servers.&#10;We will be adding server redundancy to prevent lost messages." xml:space="preserve">
@ -2141,6 +2162,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>¡Hacer un perfil privado!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2270,6 +2292,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>¡Silenciado cuando está inactivo!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2376,6 +2399,9 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>Ahora los administradores pueden
- borrar mensajes de los miembros.
- desactivar el rol a miembros (a rol "observador")</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
@ -2400,7 +2426,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="One-time invitation link" xml:space="preserve"> <trans-unit id="One-time invitation link" xml:space="preserve">
<source>One-time invitation link</source> <source>One-time invitation link</source>
<target>Enlace único de invitación</target> <target>Enlace único de invitación de un uso</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Onion hosts will be required for connection. Requires enabling VPN." xml:space="preserve"> <trans-unit id="Onion hosts will be required for connection. Requires enabling VPN." xml:space="preserve">
@ -2505,6 +2531,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>Contraseña para hacerlo visible</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2659,6 +2686,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>¡Proteje los perfiles de Chat con contraseña!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2728,12 +2756,12 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Relay server is only used if necessary. Another party can observe your IP address." xml:space="preserve"> <trans-unit id="Relay server is only used if necessary. Another party can observe your IP address." xml:space="preserve">
<source>Relay server is only used if necessary. Another party can observe your IP address.</source> <source>Relay server is only used if necessary. Another party can observe your IP address.</source>
<target>El servidor de retransmisión sólo se utiliza en caso necesario. Una tercera persona puede observar tu dirección IP.</target> <target>El relay sólo se usa en caso de necesidad. Un tercero podría ver tu IP.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Relay server protects your IP address, but it can observe the duration of the call." xml:space="preserve"> <trans-unit id="Relay server protects your IP address, but it can observe the duration of the call." xml:space="preserve">
<source>Relay server protects your IP address, but it can observe the duration of the call.</source> <source>Relay server protects your IP address, but it can observe the duration of the call.</source>
<target>El servidor de retransmisión protege tu IP pero puede observar la duración de la llamada.</target> <target>El servidor relay protege tu IP pero puede observar la duración de la llamada.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Remove" xml:space="preserve"> <trans-unit id="Remove" xml:space="preserve">
@ -2858,6 +2886,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>Guardar y actualizar perfil del grupo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2887,6 +2916,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>Guardar contraseña de perfil</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2896,10 +2926,12 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>¿Guardar servidores?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>¿Guardar mensaje de bienvenida?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3054,6 +3086,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>¡Establece el mensaje mostrado a los miembros nuevos!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3083,7 +3116,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Share one-time invitation link" xml:space="preserve"> <trans-unit id="Share one-time invitation link" xml:space="preserve">
<source>Share one-time invitation link</source> <source>Share one-time invitation link</source>
<target>Compartir enlace único de invitación</target> <target>Compartir enlace de invitación de un uso</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Show QR code" xml:space="preserve"> <trans-unit id="Show QR code" xml:space="preserve">
@ -3138,7 +3171,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="SimpleX one-time invitation" xml:space="preserve"> <trans-unit id="SimpleX one-time invitation" xml:space="preserve">
<source>SimpleX one-time invitation</source> <source>SimpleX one-time invitation</source>
<target>Invitación única SimpleX</target> <target>Invitación SimpleX de un uso</target>
<note>simplex link type</note> <note>simplex link type</note>
</trans-unit> </trans-unit>
<trans-unit id="Skip" xml:space="preserve"> <trans-unit id="Skip" xml:space="preserve">
@ -3238,6 +3271,7 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>Pulsa para activar el perfil.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3367,10 +3401,12 @@ Añadiremos redundancia de servidores para evitar la pérdida de mensajes.</targ
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>Debe haber al menos un perfil de usuario.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">
<source>There should be at least one visible user profile.</source> <source>There should be at least one visible user profile.</source>
<target>Debe haber al menos un perfil de usuario visible.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve"> <trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
@ -3442,6 +3478,7 @@ Se te pedirá que completes la autenticación antes de activar esta función.</t
</trans-unit> </trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve"> <trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source> <source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Para hacer visible tu perfil oculto, introduce la contraseña completa en el campo de búsqueda de la página **Tus perfiles Chat**.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve"> <trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@ -3501,6 +3538,7 @@ Se te pedirá que completes la autenticación antes de activar esta función.</t
</trans-unit> </trans-unit>
<trans-unit id="Unhide" xml:space="preserve"> <trans-unit id="Unhide" xml:space="preserve">
<source>Unhide</source> <source>Unhide</source>
<target>Mostrar</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown caller" xml:space="preserve"> <trans-unit id="Unknown caller" xml:space="preserve">
@ -3779,6 +3817,8 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
<trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve"> <trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right. <source>You can hide or mute a user profile - swipe it to the right.
SimpleX Lock must be enabled.</source> SimpleX Lock must be enabled.</source>
<target>Puedes ocultar o silenciar un perfil de usuario: deslízalo hacia la derecha.
SimpleX Lock debe estar activado.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can now send messages to %@" xml:space="preserve"> <trans-unit id="You can now send messages to %@" xml:space="preserve">
@ -3898,6 +3938,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit> </trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve"> <trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
<source>You will still receive calls and notifications from muted profiles when they are active.</source> <source>You will still receive calls and notifications from muted profiles when they are active.</source>
<target>Seguirás recibiendo llamadas y notificaciones de los perfiles silenciados cuando estén activos.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve"> <trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve">
@ -4331,7 +4372,7 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
</trans-unit> </trans-unit>
<trans-unit id="incognito via one-time link" xml:space="preserve"> <trans-unit id="incognito via one-time link" xml:space="preserve">
<source>incognito via one-time link</source> <source>incognito via one-time link</source>
<target>Incógnito mediante enlace único</target> <target>Incógnito mediante enlace de un uso</target>
<note>chat list item description</note> <note>chat list item description</note>
</trans-unit> </trans-unit>
<trans-unit id="indirect (%d)" xml:space="preserve"> <trans-unit id="indirect (%d)" xml:space="preserve">
@ -4487,7 +4528,7 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
</trans-unit> </trans-unit>
<trans-unit id="peer-to-peer" xml:space="preserve"> <trans-unit id="peer-to-peer" xml:space="preserve">
<source>peer-to-peer</source> <source>peer-to-peer</source>
<target>entre particulares</target> <target>p2p</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="received answer…" xml:space="preserve"> <trans-unit id="received answer…" xml:space="preserve">
@ -4572,12 +4613,12 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
</trans-unit> </trans-unit>
<trans-unit id="via one-time link" xml:space="preserve"> <trans-unit id="via one-time link" xml:space="preserve">
<source>via one-time link</source> <source>via one-time link</source>
<target>mediante enlace único</target> <target>mediante enlace de un uso</target>
<note>chat list item description</note> <note>chat list item description</note>
</trans-unit> </trans-unit>
<trans-unit id="via relay" xml:space="preserve"> <trans-unit id="via relay" xml:space="preserve">
<source>via relay</source> <source>via relay</source>
<target>mediante servidor de retransmisión</target> <target>mediante servidor relay</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve"> <trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
@ -4647,12 +4688,12 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
</trans-unit> </trans-unit>
<trans-unit id="you shared one-time link" xml:space="preserve"> <trans-unit id="you shared one-time link" xml:space="preserve">
<source>you shared one-time link</source> <source>you shared one-time link</source>
<target>has compartido un enlace único</target> <target>has compartido un enlace de un uso</target>
<note>chat list item description</note> <note>chat list item description</note>
</trans-unit> </trans-unit>
<trans-unit id="you shared one-time link incognito" xml:space="preserve"> <trans-unit id="you shared one-time link incognito" xml:space="preserve">
<source>you shared one-time link incognito</source> <source>you shared one-time link incognito</source>
<target>has compartido un enlace único en módo incógnito</target> <target>has compartido enlace de un uso en modo incógnito</target>
<note>chat list item description</note> <note>chat list item description</note>
</trans-unit> </trans-unit>
<trans-unit id="you: " xml:space="preserve"> <trans-unit id="you: " xml:space="preserve">

File diff suppressed because it is too large Load diff

View file

@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>Ajouter un message d'accueil</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>Appels audio et vidéo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -600,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>Impossible de supprimer le profil d'utilisateur !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -709,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>Interface en chinois et en espagnol</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -768,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>Confirmer le mot de passe</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -1300,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>Ne plus afficher</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1404,6 +1410,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Enter password above to show!" xml:space="preserve"> <trans-unit id="Enter password above to show!" xml:space="preserve">
<source>Enter password above to show!</source> <source>Enter password above to show!</source>
<target>Entrez le mot de passe ci-dessus pour continuer !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Enter server manually" xml:space="preserve"> <trans-unit id="Enter server manually" xml:space="preserve">
@ -1563,6 +1570,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>Erreur d'enregistrement du mot de passe de l'utilisateur</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1602,6 +1610,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>Erreur de mise à jour de la confidentialité de l'utilisateur</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1691,10 +1700,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve"> <trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
<source>Fully re-implemented - work in background!</source> <source>Fully re-implemented - work in background!</source>
<target>Entièrement réimplémenté - fonctionne en arrière-plan !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>Réduction accrue de l'utilisation de la batterie</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1774,6 +1785,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>Modération de groupe</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1793,6 +1805,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>Message d'accueil du groupe</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1817,10 +1830,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>Profils de chat cachés</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>Mot de passe de profil caché</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1835,6 +1850,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>Masquer le profil</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1962,6 +1978,11 @@
<target>Code de sécurité incorrect !</target> <target>Code de sécurité incorrect !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Rôle initial</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>Installer [SimpleX Chat pour terminal](https://github.com/simplex-chat/simplex-chat)</target> <target>Installer [SimpleX Chat pour terminal](https://github.com/simplex-chat/simplex-chat)</target>
@ -2141,6 +2162,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>Rendre le profil privé !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2270,6 +2292,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>Mute en cas d'inactivité !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2376,6 +2399,9 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>Désormais, les administrateurs peuvent :
- supprimer les messages des membres.
- désactiver des membres (rôle "observateur")</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
@ -2505,6 +2531,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>Mot de passe à afficher</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2659,6 +2686,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>Protégez vos profils de chat par un mot de passe !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2858,6 +2886,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>Sauvegarder et mettre à jour le profil du groupe</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2887,6 +2916,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>Enregistrer le mot de passe du profil</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2896,10 +2926,12 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>Sauvegarder les serveurs ?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>Sauvegarder le message d'accueil ?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3054,6 +3086,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>Choisissez un message à l'attention des nouveaux membres !</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3238,6 +3271,7 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>Appuyez pour activer le profil.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3367,10 +3401,12 @@ Nous allons ajouter une redondance des serveurs pour éviter la perte de message
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>Il doit y avoir au moins un profil d'utilisateur.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">
<source>There should be at least one visible user profile.</source> <source>There should be at least one visible user profile.</source>
<target>Il doit y avoir au moins un profil d'utilisateur visible.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve"> <trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
@ -3442,6 +3478,7 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
</trans-unit> </trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve"> <trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source> <source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Pour révéler votre profil caché, entrez un mot de passe complet dans le champ de recherche de la page **Vos profils de chat**.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve"> <trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@ -3501,6 +3538,7 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
</trans-unit> </trans-unit>
<trans-unit id="Unhide" xml:space="preserve"> <trans-unit id="Unhide" xml:space="preserve">
<source>Unhide</source> <source>Unhide</source>
<target>Dévoiler</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown caller" xml:space="preserve"> <trans-unit id="Unknown caller" xml:space="preserve">
@ -3778,6 +3816,8 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve"> <trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right. <source>You can hide or mute a user profile - swipe it to the right.
SimpleX Lock must be enabled.</source> SimpleX Lock must be enabled.</source>
<target>Vous pouvez masquer ou mettre en sourdine un profil d'utilisateur - faites-le glisser vers la droite.
SimpleX Lock doit être activé.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can now send messages to %@" xml:space="preserve"> <trans-unit id="You can now send messages to %@" xml:space="preserve">
@ -3897,6 +3937,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit> </trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve"> <trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
<source>You will still receive calls and notifications from muted profiles when they are active.</source> <source>You will still receive calls and notifications from muted profiles when they are active.</source>
<target>Vous continuerez à recevoir des appels et des notifications des profils mis en sourdine lorsqu'ils sont actifs.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve"> <trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve">

View file

@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>Aggiungi messaggio di benvenuto</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>Chiamate audio e video</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -600,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>Impossibile eliminare il profilo utente!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -709,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>Interfaccia cinese e spagnola</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -768,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>Conferma password</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -1300,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>Non mostrare più</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1404,6 +1410,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Enter password above to show!" xml:space="preserve"> <trans-unit id="Enter password above to show!" xml:space="preserve">
<source>Enter password above to show!</source> <source>Enter password above to show!</source>
<target>Inserisci la password sopra per mostrare!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Enter server manually" xml:space="preserve"> <trans-unit id="Enter server manually" xml:space="preserve">
@ -1563,6 +1570,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>Errore nel salvataggio della password utente</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1602,6 +1610,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>Errore nell'aggiornamento della privacy dell'utente</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1691,10 +1700,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve"> <trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
<source>Fully re-implemented - work in background!</source> <source>Fully re-implemented - work in background!</source>
<target>Completamente reimplementato - funziona in secondo piano!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>Ulteriore riduzione del consumo della batteria</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1774,6 +1785,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>Moderazione del gruppo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1793,6 +1805,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>Messaggio di benvenuto del gruppo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1817,10 +1830,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>Profili di chat nascosti</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>Password del profilo nascosta</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1835,6 +1850,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>Nascondi il profilo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1962,6 +1978,11 @@
<target>Codice di sicurezza sbagliato!</target> <target>Codice di sicurezza sbagliato!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Ruolo iniziale</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>Installa [Simplex Chat per terminale](https://github.com/simplex-chat/simplex-chat)</target> <target>Installa [Simplex Chat per terminale](https://github.com/simplex-chat/simplex-chat)</target>
@ -2141,6 +2162,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>Rendi privato il profilo!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2270,6 +2292,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>Silenzioso quando inattivo!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2376,6 +2399,9 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>Ora gli amministratori possono:
- eliminare i messaggi dei membri.
- disattivare i membri (ruolo "osservatore")</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
@ -2505,6 +2531,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>Password per mostrare</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2659,6 +2686,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>Proteggi i tuoi profili di chat con una password!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2858,6 +2886,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>Salva e aggiorna il profilo del gruppo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2887,6 +2916,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>Salva la password del profilo</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2896,10 +2926,12 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>Salvare i server?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>Salvare il messaggio di benvenuto?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3054,6 +3086,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>Imposta il messaggio mostrato ai nuovi membri!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3238,6 +3271,7 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>Tocca per attivare il profilo.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3367,10 +3401,12 @@ Aggiungeremo la ridondanza del server per prevenire la perdita di messaggi.</tar
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>Deve esserci almeno un profilo utente.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">
<source>There should be at least one visible user profile.</source> <source>There should be at least one visible user profile.</source>
<target>Deve esserci almeno un profilo utente visibile.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve"> <trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
@ -3442,6 +3478,7 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
</trans-unit> </trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve"> <trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source> <source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Per rivelare il tuo profilo nascosto, inserisci una password completa in un campo di ricerca nella pagina **I tuoi profili di chat**.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve"> <trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@ -3501,6 +3538,7 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
</trans-unit> </trans-unit>
<trans-unit id="Unhide" xml:space="preserve"> <trans-unit id="Unhide" xml:space="preserve">
<source>Unhide</source> <source>Unhide</source>
<target>Svela</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown caller" xml:space="preserve"> <trans-unit id="Unknown caller" xml:space="preserve">
@ -3778,6 +3816,8 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve"> <trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right. <source>You can hide or mute a user profile - swipe it to the right.
SimpleX Lock must be enabled.</source> SimpleX Lock must be enabled.</source>
<target>Puoi nascondere o silenziare un profilo utente - scorrilo verso destra.
SimpleX Lock deve essere attivato.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can now send messages to %@" xml:space="preserve"> <trans-unit id="You can now send messages to %@" xml:space="preserve">
@ -3897,6 +3937,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit> </trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve"> <trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
<source>You will still receive calls and notifications from muted profiles when they are active.</source> <source>You will still receive calls and notifications from muted profiles when they are active.</source>
<target>Continuerai a ricevere chiamate e notifiche da profili silenziati quando sono attivi.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve"> <trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve">

View file

@ -152,12 +152,14 @@
<source>%lldw</source> <source>%lldw</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="(" xml:space="preserve"> <trans-unit id="(" xml:space="preserve" approved="no">
<source>(</source> <source>(</source>
<target state="translated">(</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id=")" xml:space="preserve"> <trans-unit id=")" xml:space="preserve" approved="no">
<source>)</source> <source>)</source>
<target state="translated">)</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="**Add new contact**: to create your one-time QR Code for your contact." xml:space="preserve"> <trans-unit id="**Add new contact**: to create your one-time QR Code for your contact." xml:space="preserve">
@ -180,8 +182,9 @@
<source>**Paste received link** or open it in the browser and tap **Open in mobile app**.</source> <source>**Paste received link** or open it in the browser and tap **Open in mobile app**.</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="**Please note**: you will NOT be able to recover or change passphrase if you lose it." xml:space="preserve"> <trans-unit id="**Please note**: you will NOT be able to recover or change passphrase if you lose it." xml:space="preserve" approved="no">
<source>**Please note**: you will NOT be able to recover or change passphrase if you lose it.</source> <source>**Please note**: you will NOT be able to recover or change passphrase if you lose it.</source>
<target state="translated">**Turėkite omenyje**: jeigu prarasite slaptafrazę, NEBEGALĖSITE jos atkurti ar pakeisti.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="**Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from." xml:space="preserve"> <trans-unit id="**Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from." xml:space="preserve">
@ -208,52 +211,64 @@
<source>\*bold*</source> <source>\*bold*</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id=", " xml:space="preserve"> <trans-unit id=", " xml:space="preserve" approved="no">
<source>, </source> <source>, </source>
<target state="translated">, </target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="." xml:space="preserve"> <trans-unit id="." xml:space="preserve" approved="no">
<source>.</source> <source>.</source>
<target state="translated">.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="1 day" xml:space="preserve"> <trans-unit id="1 day" xml:space="preserve" approved="no">
<source>1 day</source> <source>1 day</source>
<target state="translated">1 diena</target>
<note>message ttl</note> <note>message ttl</note>
</trans-unit> </trans-unit>
<trans-unit id="1 hour" xml:space="preserve"> <trans-unit id="1 hour" xml:space="preserve" approved="no">
<source>1 hour</source> <source>1 hour</source>
<target state="translated">1 valanda</target>
<note>message ttl</note> <note>message ttl</note>
</trans-unit> </trans-unit>
<trans-unit id="1 month" xml:space="preserve"> <trans-unit id="1 month" xml:space="preserve" approved="no">
<source>1 month</source> <source>1 month</source>
<target state="translated">1 mėnuo</target>
<note>message ttl</note> <note>message ttl</note>
</trans-unit> </trans-unit>
<trans-unit id="1 week" xml:space="preserve"> <trans-unit id="1 week" xml:space="preserve" approved="no">
<source>1 week</source> <source>1 week</source>
<target state="translated">1 savaitė</target>
<note>message ttl</note> <note>message ttl</note>
</trans-unit> </trans-unit>
<trans-unit id="2 weeks" xml:space="preserve"> <trans-unit id="2 weeks" xml:space="preserve" approved="no">
<source>2 weeks</source> <source>2 weeks</source>
<target state="translated">2 savaitės</target>
<note>message ttl</note> <note>message ttl</note>
</trans-unit> </trans-unit>
<trans-unit id="6" xml:space="preserve"> <trans-unit id="6" xml:space="preserve" approved="no">
<source>6</source> <source>6</source>
<target state="translated">6</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id=": " xml:space="preserve"> <trans-unit id=": " xml:space="preserve" approved="no">
<source>: </source> <source>: </source>
<target state="translated">: </target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="A new contact" xml:space="preserve"> <trans-unit id="A new contact" xml:space="preserve" approved="no">
<source>A new contact</source> <source>A new contact</source>
<target state="translated">Naujas adresatas</target>
<note>notification title</note> <note>notification title</note>
</trans-unit> </trans-unit>
<trans-unit id="A random profile will be sent to the contact that you received this link from" xml:space="preserve"> <trans-unit id="A random profile will be sent to the contact that you received this link from" xml:space="preserve" approved="no">
<source>A random profile will be sent to the contact that you received this link from</source> <source>A random profile will be sent to the contact that you received this link from</source>
<target state="translated">Adresatui, iš kurio gavote šią nuorodą, bus išsiųstas atsitiktinis profilis</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="A random profile will be sent to your contact" xml:space="preserve"> <trans-unit id="A random profile will be sent to your contact" xml:space="preserve" approved="no">
<source>A random profile will be sent to your contact</source> <source>A random profile will be sent to your contact</source>
<target state="translated">Jūsų adresatui bus išsiųstas atsitiktinis profilis</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="A separate TCP connection will be used **for each chat profile you have in the app**." xml:space="preserve"> <trans-unit id="A separate TCP connection will be used **for each chat profile you have in the app**." xml:space="preserve">
@ -265,12 +280,14 @@
**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail.</source> **Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail.</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="About SimpleX" xml:space="preserve"> <trans-unit id="About SimpleX" xml:space="preserve" approved="no">
<source>About SimpleX</source> <source>About SimpleX</source>
<target state="translated">Apie SimpleX</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="About SimpleX Chat" xml:space="preserve"> <trans-unit id="About SimpleX Chat" xml:space="preserve" approved="no">
<source>About SimpleX Chat</source> <source>About SimpleX Chat</source>
<target state="translated">Apie SimpleX Chat</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Accent color" xml:space="preserve"> <trans-unit id="Accent color" xml:space="preserve">
@ -302,16 +319,19 @@
<source>Add preset servers</source> <source>Add preset servers</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Add profile" xml:space="preserve"> <trans-unit id="Add profile" xml:space="preserve" approved="no">
<source>Add profile</source> <source>Add profile</source>
<target state="translated">Pridėti profilį</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve"> <trans-unit id="Add servers by scanning QR codes." xml:space="preserve" approved="no">
<source>Add servers by scanning QR codes.</source> <source>Add servers by scanning QR codes.</source>
<target state="translated">Pridėti serverius skenuojant QR kodus.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Add server…" xml:space="preserve"> <trans-unit id="Add server…" xml:space="preserve" approved="no">
<source>Add server…</source> <source>Add server…</source>
<target state="translated">Pridėti serverį…</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Add to another device" xml:space="preserve"> <trans-unit id="Add to another device" xml:space="preserve">
@ -322,72 +342,86 @@
<source>Admins can create the links to join groups.</source> <source>Admins can create the links to join groups.</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Advanced network settings" xml:space="preserve"> <trans-unit id="Advanced network settings" xml:space="preserve" approved="no">
<source>Advanced network settings</source> <source>Advanced network settings</source>
<target state="translated">Išplėstiniai tinklo nustatymai</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="All chats and messages will be deleted - this cannot be undone!" xml:space="preserve"> <trans-unit id="All chats and messages will be deleted - this cannot be undone!" xml:space="preserve" approved="no">
<source>All chats and messages will be deleted - this cannot be undone!</source> <source>All chats and messages will be deleted - this cannot be undone!</source>
<target state="translated">Visos žinutės ir pokalbiai bus ištrinti to neįmanoma bus atšaukti!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="All group members will remain connected." xml:space="preserve"> <trans-unit id="All group members will remain connected." xml:space="preserve">
<source>All group members will remain connected.</source> <source>All group members will remain connected.</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." xml:space="preserve"> <trans-unit id="All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." xml:space="preserve" approved="no">
<source>All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you.</source> <source>All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you.</source>
<target state="translated">Visos žinutės bus ištrintos to neįmanoma bus atšaukti! Žinutės bus ištrintos TIK jums.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="All your contacts will remain connected" xml:space="preserve"> <trans-unit id="All your contacts will remain connected" xml:space="preserve">
<source>All your contacts will remain connected</source> <source>All your contacts will remain connected</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow" xml:space="preserve"> <trans-unit id="Allow" xml:space="preserve" approved="no">
<source>Allow</source> <source>Allow</source>
<target state="translated">Leisti</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve"> <trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
<source>Allow disappearing messages only if your contact allows it to you.</source> <source>Allow disappearing messages only if your contact allows it to you.</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow irreversible message deletion only if your contact allows it to you." xml:space="preserve"> <trans-unit id="Allow irreversible message deletion only if your contact allows it to you." xml:space="preserve" approved="no">
<source>Allow irreversible message deletion only if your contact allows it to you.</source> <source>Allow irreversible message deletion only if your contact allows it to you.</source>
<target state="translated">Leisti negrįžtamą žinučių ištrynimą tik tuo atveju, jei jūsų adresatas jums tai leidžia.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow sending direct messages to members." xml:space="preserve"> <trans-unit id="Allow sending direct messages to members." xml:space="preserve" approved="no">
<source>Allow sending direct messages to members.</source> <source>Allow sending direct messages to members.</source>
<target state="translated">Leisti siųsti tiesiogines žinutes nariams.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow sending disappearing messages." xml:space="preserve"> <trans-unit id="Allow sending disappearing messages." xml:space="preserve" approved="no">
<source>Allow sending disappearing messages.</source> <source>Allow sending disappearing messages.</source>
<target state="translated">Leisti siųsti išnykstančias žinutes.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow to irreversibly delete sent messages." xml:space="preserve"> <trans-unit id="Allow to irreversibly delete sent messages." xml:space="preserve" approved="no">
<source>Allow to irreversibly delete sent messages.</source> <source>Allow to irreversibly delete sent messages.</source>
<target state="translated">Leisti negrįžtamai ištrinti išsiųstas žinutes.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow to send voice messages." xml:space="preserve"> <trans-unit id="Allow to send voice messages." xml:space="preserve" approved="no">
<source>Allow to send voice messages.</source> <source>Allow to send voice messages.</source>
<target state="translated">Leisti siųsti balso žinutes.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow voice messages only if your contact allows them." xml:space="preserve"> <trans-unit id="Allow voice messages only if your contact allows them." xml:space="preserve" approved="no">
<source>Allow voice messages only if your contact allows them.</source> <source>Allow voice messages only if your contact allows them.</source>
<target state="translated">Leisti balso žinutes tik tuo atveju, jei jūsų adresatas jas leidžia.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow voice messages?" xml:space="preserve"> <trans-unit id="Allow voice messages?" xml:space="preserve" approved="no">
<source>Allow voice messages?</source> <source>Allow voice messages?</source>
<target state="translated">Leisti balso žinutes?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow your contacts to irreversibly delete sent messages." xml:space="preserve"> <trans-unit id="Allow your contacts to irreversibly delete sent messages." xml:space="preserve" approved="no">
<source>Allow your contacts to irreversibly delete sent messages.</source> <source>Allow your contacts to irreversibly delete sent messages.</source>
<target state="translated">Leisti jūsų adresatams negrįžtamai ištrinti išsiųstas žinutes.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow your contacts to send disappearing messages." xml:space="preserve"> <trans-unit id="Allow your contacts to send disappearing messages." xml:space="preserve" approved="no">
<source>Allow your contacts to send disappearing messages.</source> <source>Allow your contacts to send disappearing messages.</source>
<target state="translated">Leisti jūsų adresatams siųsti išnykstančias žinutes.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Allow your contacts to send voice messages." xml:space="preserve"> <trans-unit id="Allow your contacts to send voice messages." xml:space="preserve" approved="no">
<source>Allow your contacts to send voice messages.</source> <source>Allow your contacts to send voice messages.</source>
<target state="translated">Leisti jūsų adresatams siųsti balso žinutes.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Already connected?" xml:space="preserve"> <trans-unit id="Already connected?" xml:space="preserve">
@ -398,48 +432,57 @@
<source>Always use relay</source> <source>Always use relay</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Answer call" xml:space="preserve"> <trans-unit id="Answer call" xml:space="preserve" approved="no">
<source>Answer call</source> <source>Answer call</source>
<target state="translated">Atsiliepti</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="App build: %@" xml:space="preserve"> <trans-unit id="App build: %@" xml:space="preserve" approved="no">
<source>App build: %@</source> <source>App build: %@</source>
<target state="translated">Programėlės darinys: %@</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="App icon" xml:space="preserve"> <trans-unit id="App icon" xml:space="preserve" approved="no">
<source>App icon</source> <source>App icon</source>
<target state="translated">Programėlės piktograma</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="App version" xml:space="preserve"> <trans-unit id="App version" xml:space="preserve" approved="no">
<source>App version</source> <source>App version</source>
<target state="translated">Programėlės versija</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="App version: v%@" xml:space="preserve"> <trans-unit id="App version: v%@" xml:space="preserve" approved="no">
<source>App version: v%@</source> <source>App version: v%@</source>
<target state="translated">Programėlės versija: v%@</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Appearance" xml:space="preserve"> <trans-unit id="Appearance" xml:space="preserve" approved="no">
<source>Appearance</source> <source>Appearance</source>
<target state="translated">Išvaizda</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Attach" xml:space="preserve"> <trans-unit id="Attach" xml:space="preserve">
<source>Attach</source> <source>Attach</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Audio &amp; video calls" xml:space="preserve"> <trans-unit id="Audio &amp; video calls" xml:space="preserve" approved="no">
<source>Audio &amp; video calls</source> <source>Audio &amp; video calls</source>
<target state="translated">Garso ir vaizdo skambučiai</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve" approved="no">
<source>Authentication failed</source> <source>Authentication failed</source>
<target state="translated">Nepavyko nustatyti tapatybės</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication is required before the call is connected, but you may miss calls." xml:space="preserve"> <trans-unit id="Authentication is required before the call is connected, but you may miss calls." xml:space="preserve">
<source>Authentication is required before the call is connected, but you may miss calls.</source> <source>Authentication is required before the call is connected, but you may miss calls.</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication unavailable" xml:space="preserve"> <trans-unit id="Authentication unavailable" xml:space="preserve" approved="no">
<source>Authentication unavailable</source> <source>Authentication unavailable</source>
<target state="translated">Tapatybės nustatymas neprieinamas</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Auto-accept contact requests" xml:space="preserve"> <trans-unit id="Auto-accept contact requests" xml:space="preserve">
@ -3629,6 +3672,11 @@ SimpleX servers cannot see your profile.</source>
<source>\~strike~</source> <source>\~strike~</source>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve" approved="no">
<source>Audio and video calls</source>
<target state="translated">Garso ir vaizdo skambučiai</target>
<note>No comment provided by engineer.</note>
</trans-unit>
</body> </body>
</file> </file>
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="lt" datatype="plaintext"> <file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="lt" datatype="plaintext">

View file

@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>Welkomst bericht toevoegen</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>Audio en video oproepen</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -600,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>Kan gebruikers profiel niet verwijderen!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -709,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>Chinese en Spaanse interface</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -768,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>Bevestig wachtwoord</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -1205,7 +1210,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Delete user profile?" xml:space="preserve"> <trans-unit id="Delete user profile?" xml:space="preserve">
<source>Delete user profile?</source> <source>Delete user profile?</source>
<target>Gebruikersprofiel verwijderen?</target> <target>Gebruikers profiel verwijderen?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Description" xml:space="preserve"> <trans-unit id="Description" xml:space="preserve">
@ -1300,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>Niet meer weergeven</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1404,6 +1410,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Enter password above to show!" xml:space="preserve"> <trans-unit id="Enter password above to show!" xml:space="preserve">
<source>Enter password above to show!</source> <source>Enter password above to show!</source>
<target>Voer hier boven het wachtwoord in om weer te geven!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Enter server manually" xml:space="preserve"> <trans-unit id="Enter server manually" xml:space="preserve">
@ -1563,6 +1570,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>Fout bij opslaan gebruikers wachtwoord</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1602,6 +1610,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>Fout bij updaten van gebruikers privacy</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1691,10 +1700,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve"> <trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
<source>Fully re-implemented - work in background!</source> <source>Fully re-implemented - work in background!</source>
<target>Volledig opnieuw geïmplementeerd - werk op de achtergrond!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>Verder verminderd batterij verbruik</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1774,6 +1785,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>Groep moderatie</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1793,6 +1805,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>Groep welkomst bericht</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1817,10 +1830,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>Verborgen chat profielen</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>Verborgen profiel wachtwoord</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1835,6 +1850,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>Profiel verbergen</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1962,6 +1978,11 @@
<target>Onjuiste beveiligingscode!</target> <target>Onjuiste beveiligingscode!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Initiële rol</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>Installeer [SimpleX Chat voor terminal](https://github.com/simplex-chat/simplex-chat)</target> <target>Installeer [SimpleX Chat voor terminal](https://github.com/simplex-chat/simplex-chat)</target>
@ -2141,6 +2162,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>Profiel privé maken!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2270,6 +2292,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>Gedempt wanneer inactief!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2376,6 +2399,9 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>Nu kunnen beheerders:
- berichten van leden verwijderen.
- schakel leden uit ("waarnemer" rol)</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
@ -2420,7 +2446,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." xml:space="preserve"> <trans-unit id="Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." xml:space="preserve">
<source>Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**.</source> <source>Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**.</source>
<target>Alleen client apparaten slaan gebruikersprofielen, contacten, groepen en berichten op die zijn verzonden met **2-laags end-to-end-codering**.</target> <target>Alleen client apparaten slaan gebruikers profielen, contacten, groepen en berichten op die zijn verzonden met **2-laags end-to-end-codering**.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Only group owners can change group preferences." xml:space="preserve"> <trans-unit id="Only group owners can change group preferences." xml:space="preserve">
@ -2480,7 +2506,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve"> <trans-unit id="Open user profiles" xml:space="preserve">
<source>Open user profiles</source> <source>Open user profiles</source>
<target>Gebruikersprofielen openen</target> <target>Gebruikers profielen openen</target>
<note>authentication reason</note> <note>authentication reason</note>
</trans-unit> </trans-unit>
<trans-unit id="Open-source protocol and code anybody can run the servers." xml:space="preserve"> <trans-unit id="Open-source protocol and code anybody can run the servers." xml:space="preserve">
@ -2505,6 +2531,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>Wachtwoord om weer te geven</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2659,6 +2686,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>Bescherm je chat profielen met een wachtwoord!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2858,6 +2886,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>Groep profiel opslaan en bijwerken</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2887,6 +2916,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>Bewaar profiel wachtwoord</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2896,10 +2926,12 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>Servers opslaan?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>Welkomst bericht opslaan?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3054,6 +3086,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>Stel het getoonde bericht in voor nieuwe leden!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3238,6 +3271,7 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>Tik om profiel te activeren.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3367,10 +3401,12 @@ We zullen serverredundantie toevoegen om verloren berichten te voorkomen.</targe
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>Er moet ten minste één gebruikers profiel zijn.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">
<source>There should be at least one visible user profile.</source> <source>There should be at least one visible user profile.</source>
<target>Er moet ten minste één zichtbaar gebruikers profiel zijn.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve"> <trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
@ -3442,6 +3478,7 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
</trans-unit> </trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve"> <trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source> <source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoek veld in op de pagina **Uw chat profielen**.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve"> <trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@ -3501,6 +3538,7 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
</trans-unit> </trans-unit>
<trans-unit id="Unhide" xml:space="preserve"> <trans-unit id="Unhide" xml:space="preserve">
<source>Unhide</source> <source>Unhide</source>
<target>zichtbaar maken</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown caller" xml:space="preserve"> <trans-unit id="Unknown caller" xml:space="preserve">
@ -3612,7 +3650,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
</trans-unit> </trans-unit>
<trans-unit id="User profile" xml:space="preserve"> <trans-unit id="User profile" xml:space="preserve">
<source>User profile</source> <source>User profile</source>
<target>Gebruikersprofiel</target> <target>Gebruikers profiel</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Using .onion hosts requires compatible VPN provider." xml:space="preserve"> <trans-unit id="Using .onion hosts requires compatible VPN provider." xml:space="preserve">
@ -3697,7 +3735,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
</trans-unit> </trans-unit>
<trans-unit id="Welcome message" xml:space="preserve"> <trans-unit id="Welcome message" xml:space="preserve">
<source>Welcome message</source> <source>Welcome message</source>
<target>Welkoms bericht</target> <target>Welkomst bericht</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="What's new" xml:space="preserve"> <trans-unit id="What's new" xml:space="preserve">
@ -3717,7 +3755,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
</trans-unit> </trans-unit>
<trans-unit id="With optional welcome message." xml:space="preserve"> <trans-unit id="With optional welcome message." xml:space="preserve">
<source>With optional welcome message.</source> <source>With optional welcome message.</source>
<target>Met optioneel welkomstbericht.</target> <target>Met optioneel welkomst bericht.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve"> <trans-unit id="Wrong database passphrase" xml:space="preserve">
@ -3778,6 +3816,8 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link
<trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve"> <trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right. <source>You can hide or mute a user profile - swipe it to the right.
SimpleX Lock must be enabled.</source> SimpleX Lock must be enabled.</source>
<target>U kunt een gebruikers profiel verbergen of dempen - veeg het naar rechts.
SimpleX Lock moet ingeschakeld zijn.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can now send messages to %@" xml:space="preserve"> <trans-unit id="You can now send messages to %@" xml:space="preserve">
@ -3897,6 +3937,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit> </trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve"> <trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
<source>You will still receive calls and notifications from muted profiles when they are active.</source> <source>You will still receive calls and notifications from muted profiles when they are active.</source>
<target>U ontvangt nog steeds oproepen en meldingen van gedempte profielen wanneer deze actief zijn.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve"> <trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve">
@ -4075,7 +4116,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
</trans-unit> </trans-unit>
<trans-unit id="above, then choose:" xml:space="preserve"> <trans-unit id="above, then choose:" xml:space="preserve">
<source>above, then choose:</source> <source>above, then choose:</source>
<target>hierboven, kies dan:</target> <target>hier boven, kies dan:</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="accepted call" xml:space="preserve"> <trans-unit id="accepted call" xml:space="preserve">
@ -4450,7 +4491,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
</trans-unit> </trans-unit>
<trans-unit id="observer" xml:space="preserve"> <trans-unit id="observer" xml:space="preserve">
<source>observer</source> <source>observer</source>
<target>waarnemer</target> <target>Waarnemer</target>
<note>member role</note> <note>member role</note>
</trans-unit> </trans-unit>
<trans-unit id="off" xml:space="preserve"> <trans-unit id="off" xml:space="preserve">
@ -4481,7 +4522,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
</trans-unit> </trans-unit>
<trans-unit id="owner" xml:space="preserve"> <trans-unit id="owner" xml:space="preserve">
<source>owner</source> <source>owner</source>
<target>eigenaar</target> <target>Eigenaar</target>
<note>member role</note> <note>member role</note>
</trans-unit> </trans-unit>
<trans-unit id="peer-to-peer" xml:space="preserve"> <trans-unit id="peer-to-peer" xml:space="preserve">

View file

@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>Добавить приветственное сообщение</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>Аудио и видео звонки</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -540,6 +542,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Authentication is required before the call is connected, but you may miss calls." xml:space="preserve"> <trans-unit id="Authentication is required before the call is connected, but you may miss calls." xml:space="preserve">
<source>Authentication is required before the call is connected, but you may miss calls.</source> <source>Authentication is required before the call is connected, but you may miss calls.</source>
<target>Аутентификация требуется до того, как звонок соединится, но вы можете пропустить звонки.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication unavailable" xml:space="preserve"> <trans-unit id="Authentication unavailable" xml:space="preserve">
@ -599,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>Нельзя удалить профиль пользователя!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -708,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>Китайский и Испанский интерфейс</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -767,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>Подтвердить пароль</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -1299,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>Не показывать</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1403,6 +1410,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Enter password above to show!" xml:space="preserve"> <trans-unit id="Enter password above to show!" xml:space="preserve">
<source>Enter password above to show!</source> <source>Enter password above to show!</source>
<target>Введите пароль выше, чтобы раскрыть!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Enter server manually" xml:space="preserve"> <trans-unit id="Enter server manually" xml:space="preserve">
@ -1562,6 +1570,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>Ошибка при сохранении пароля пользователя</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1601,6 +1610,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>Ошибка при обновлении конфиденциальности</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1690,10 +1700,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve"> <trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
<source>Fully re-implemented - work in background!</source> <source>Fully re-implemented - work in background!</source>
<target>Полностью обновлены - работают в фоне!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>Уменьшенное потребление батареи</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1773,6 +1785,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>Модерация группы</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1792,6 +1805,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>Приветственное сообщение группы</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1816,10 +1830,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>Скрытые профили чата</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>Пароль скрытого профиля</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1834,6 +1850,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>Скрыть профиль</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1961,6 +1978,11 @@
<target>Неправильный код безопасности!</target> <target>Неправильный код безопасности!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>Роль при вступлении</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>[SimpleX Chat для терминала](https://github.com/simplex-chat/simplex-chat)</target> <target>[SimpleX Chat для терминала](https://github.com/simplex-chat/simplex-chat)</target>
@ -1980,6 +2002,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Interface" xml:space="preserve"> <trans-unit id="Interface" xml:space="preserve">
<source>Interface</source> <source>Interface</source>
<target>Интерфейс</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Invalid connection link" xml:space="preserve"> <trans-unit id="Invalid connection link" xml:space="preserve">
@ -2139,6 +2162,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>Сделайте профиль скрытым!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2268,6 +2292,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>Без звука, когда не активный!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2374,6 +2399,9 @@ We will be adding server redundancy to prevent lost messages.</source>
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>Теперь админы могут:
- удалять сообщения членов.
- приостанавливать членов (роль "наблюдатель")</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
@ -2503,6 +2531,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>Пароль чтобы раскрыть</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2657,6 +2686,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>Защитите ваши профили чата паролем!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2856,6 +2886,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>Сохранить сообщение и обновить группу</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2885,6 +2916,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>Сохранить пароль профиля</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2894,10 +2926,12 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>Сохранить серверы?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>Сохранить приветственное сообщение?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3052,6 +3086,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>Установить сообщение для новых членов группы!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3091,6 +3126,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Show calls in phone history" xml:space="preserve"> <trans-unit id="Show calls in phone history" xml:space="preserve">
<source>Show calls in phone history</source> <source>Show calls in phone history</source>
<target>Показать звонки в истории телефона</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Show preview" xml:space="preserve"> <trans-unit id="Show preview" xml:space="preserve">
@ -3235,6 +3271,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>Нажмите, чтобы сделать профиль активным.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3364,10 +3401,12 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>Должен быть хотя бы один профиль пользователя.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">
<source>There should be at least one visible user profile.</source> <source>There should be at least one visible user profile.</source>
<target>Должен быть хотя бы один открытый профиль пользователя.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve"> <trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
@ -3439,6 +3478,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit> </trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve"> <trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source> <source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Чтобы показать Ваш скрытый профиль, введите его пароль в поле поиска на странице **Ваши профили чата**.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve"> <trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@ -3498,10 +3538,12 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit> </trans-unit>
<trans-unit id="Unhide" xml:space="preserve"> <trans-unit id="Unhide" xml:space="preserve">
<source>Unhide</source> <source>Unhide</source>
<target>Раскрыть</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown caller" xml:space="preserve"> <trans-unit id="Unknown caller" xml:space="preserve">
<source>Unknown caller</source> <source>Unknown caller</source>
<target>Неизвестный звонок</target>
<note>callkit banner</note> <note>callkit banner</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown database error: %@" xml:space="preserve"> <trans-unit id="Unknown database error: %@" xml:space="preserve">
@ -3516,6 +3558,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit> </trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve"> <trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source> <source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
<target>Если вы не используете интерфейс iOS, включите режим Не отвлекать, чтобы звонок не прерывался.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.&#10;To connect, please ask your contact to create another connection link and check that you have a stable network connection." xml:space="preserve"> <trans-unit id="Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.&#10;To connect, please ask your contact to create another connection link and check that you have a stable network connection." xml:space="preserve">
@ -3597,6 +3640,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit> </trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve"> <trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source> <source>Use iOS call interface</source>
<target>Использовать интерфейс iOS для звонков</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Use server" xml:space="preserve"> <trans-unit id="Use server" xml:space="preserve">
@ -3761,6 +3805,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit> </trans-unit>
<trans-unit id="You can accept calls from lock screen, without device and app authentication." xml:space="preserve"> <trans-unit id="You can accept calls from lock screen, without device and app authentication." xml:space="preserve">
<source>You can accept calls from lock screen, without device and app authentication.</source> <source>You can accept calls from lock screen, without device and app authentication.</source>
<target>Вы можете принимать звонки на экране блокировки, без аутентификации.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." xml:space="preserve"> <trans-unit id="You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." xml:space="preserve">
@ -3771,6 +3816,8 @@ To connect, please ask your contact to create another connection link and check
<trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve"> <trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right. <source>You can hide or mute a user profile - swipe it to the right.
SimpleX Lock must be enabled.</source> SimpleX Lock must be enabled.</source>
<target>Вы можете скрыть профиль или выключить уведомления - потяните его вправо.
Блокировка SimpleX должна быть включена.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can now send messages to %@" xml:space="preserve"> <trans-unit id="You can now send messages to %@" xml:space="preserve">
@ -3890,6 +3937,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit> </trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve"> <trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
<source>You will still receive calls and notifications from muted profiles when they are active.</source> <source>You will still receive calls and notifications from muted profiles when they are active.</source>
<target>Вы все равно получите звонки и уведомления в профилях без звука, когда они активные.</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve"> <trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve">

View file

@ -39,7 +39,7 @@
</trans-unit> </trans-unit>
<trans-unit id="!1 colored!" xml:space="preserve"> <trans-unit id="!1 colored!" xml:space="preserve">
<source>!1 colored!</source> <source>!1 colored!</source>
<target>!1 色!</target> <target>!1 种彩色!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="#secret#" xml:space="preserve"> <trans-unit id="#secret#" xml:space="preserve">
@ -387,6 +387,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Add welcome message" xml:space="preserve"> <trans-unit id="Add welcome message" xml:space="preserve">
<source>Add welcome message</source> <source>Add welcome message</source>
<target>添加欢迎信息</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Admins can create the links to join groups." xml:space="preserve"> <trans-unit id="Admins can create the links to join groups." xml:space="preserve">
@ -531,6 +532,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Audio and video calls" xml:space="preserve"> <trans-unit id="Audio and video calls" xml:space="preserve">
<source>Audio and video calls</source> <source>Audio and video calls</source>
<target>音视频通话</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Authentication failed" xml:space="preserve"> <trans-unit id="Authentication failed" xml:space="preserve">
@ -560,7 +562,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Automatically" xml:space="preserve"> <trans-unit id="Automatically" xml:space="preserve">
<source>Automatically</source> <source>Automatically</source>
<target>自动</target> <target>自动</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Back" xml:space="preserve"> <trans-unit id="Back" xml:space="preserve">
@ -590,7 +592,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Call already ended!" xml:space="preserve"> <trans-unit id="Call already ended!" xml:space="preserve">
<source>Call already ended!</source> <source>Call already ended!</source>
<target>通话已结束!</target> <target>通话已结束!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Calls" xml:space="preserve"> <trans-unit id="Calls" xml:space="preserve">
@ -600,6 +602,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Can't delete user profile!" xml:space="preserve"> <trans-unit id="Can't delete user profile!" xml:space="preserve">
<source>Can't delete user profile!</source> <source>Can't delete user profile!</source>
<target>无法删除用户个人资料!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve"> <trans-unit id="Can't invite contact!" xml:space="preserve">
@ -709,6 +712,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Chinese and Spanish interface" xml:space="preserve"> <trans-unit id="Chinese and Spanish interface" xml:space="preserve">
<source>Chinese and Spanish interface</source> <source>Chinese and Spanish interface</source>
<target>中文和西班牙文界面</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Choose file" xml:space="preserve"> <trans-unit id="Choose file" xml:space="preserve">
@ -768,6 +772,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Confirm password" xml:space="preserve"> <trans-unit id="Confirm password" xml:space="preserve">
<source>Confirm password</source> <source>Confirm password</source>
<target>确认密码</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Connect" xml:space="preserve"> <trans-unit id="Connect" xml:space="preserve">
@ -1300,6 +1305,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Don't show again" xml:space="preserve"> <trans-unit id="Don't show again" xml:space="preserve">
<source>Don't show again</source> <source>Don't show again</source>
<target>不再显示</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Duplicate display name!" xml:space="preserve"> <trans-unit id="Duplicate display name!" xml:space="preserve">
@ -1404,6 +1410,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Enter password above to show!" xml:space="preserve"> <trans-unit id="Enter password above to show!" xml:space="preserve">
<source>Enter password above to show!</source> <source>Enter password above to show!</source>
<target>在上面输入密码以显示!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Enter server manually" xml:space="preserve"> <trans-unit id="Enter server manually" xml:space="preserve">
@ -1563,6 +1570,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve"> <trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source> <source>Error saving user password</source>
<target>保存用户密码时出错</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error sending message" xml:space="preserve"> <trans-unit id="Error sending message" xml:space="preserve">
@ -1602,6 +1610,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve"> <trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source> <source>Error updating user privacy</source>
<target>更新用户隐私时出错</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Error: %@" xml:space="preserve"> <trans-unit id="Error: %@" xml:space="preserve">
@ -1691,10 +1700,12 @@
</trans-unit> </trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve"> <trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
<source>Fully re-implemented - work in background!</source> <source>Fully re-implemented - work in background!</source>
<target>完全重新实现 - 在后台工作!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Further reduced battery usage" xml:space="preserve"> <trans-unit id="Further reduced battery usage" xml:space="preserve">
<source>Further reduced battery usage</source> <source>Further reduced battery usage</source>
<target>进一步减少电池使用</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="GIFs and stickers" xml:space="preserve"> <trans-unit id="GIFs and stickers" xml:space="preserve">
@ -1774,6 +1785,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group moderation" xml:space="preserve"> <trans-unit id="Group moderation" xml:space="preserve">
<source>Group moderation</source> <source>Group moderation</source>
<target>小组审核</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group preferences" xml:space="preserve"> <trans-unit id="Group preferences" xml:space="preserve">
@ -1793,6 +1805,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Group welcome message" xml:space="preserve"> <trans-unit id="Group welcome message" xml:space="preserve">
<source>Group welcome message</source> <source>Group welcome message</source>
<target>群欢迎词</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve"> <trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
@ -1812,15 +1825,17 @@
</trans-unit> </trans-unit>
<trans-unit id="Hidden" xml:space="preserve"> <trans-unit id="Hidden" xml:space="preserve">
<source>Hidden</source> <source>Hidden</source>
<target>隐藏</target> <target>隐藏</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve"> <trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source> <source>Hidden chat profiles</source>
<target>隐藏的聊天资料</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve"> <trans-unit id="Hidden profile password" xml:space="preserve">
<source>Hidden profile password</source> <source>Hidden profile password</source>
<target>隐藏的个人资料密码</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Hide" xml:space="preserve"> <trans-unit id="Hide" xml:space="preserve">
@ -1835,6 +1850,7 @@
</trans-unit> </trans-unit>
<trans-unit id="Hide profile" xml:space="preserve"> <trans-unit id="Hide profile" xml:space="preserve">
<source>Hide profile</source> <source>Hide profile</source>
<target>隐藏个人资料</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve"> <trans-unit id="How SimpleX works" xml:space="preserve">
@ -1962,6 +1978,11 @@
<target>安全码不正确!</target> <target>安全码不正确!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Initial role" xml:space="preserve">
<source>Initial role</source>
<target>初始角色</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
<source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source> <source>Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)</source>
<target>安装[用于终端的 SimpleX Chat](https://github.com/simplex-chat/simplex-chat)</target> <target>安装[用于终端的 SimpleX Chat](https://github.com/simplex-chat/simplex-chat)</target>
@ -2141,6 +2162,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Make profile private!" xml:space="preserve"> <trans-unit id="Make profile private!" xml:space="preserve">
<source>Make profile private!</source> <source>Make profile private!</source>
<target>将个人资料设为私密!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve"> <trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
@ -2235,7 +2257,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat)." xml:space="preserve"> <trans-unit id="Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat)." xml:space="preserve">
<source>Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat).</source> <source>Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat).</source>
<target>迁移失败。点击下面的 **Skip** 继续使用当前数据库。请通过聊天或电子邮件 [chat@simplex.chat](mailto:chat@simplex.chat) 将问题报告给应用程序开发人员。</target> <target>迁移失败。点击下面的 **Skip** 继续使用当前数据库。请通过通过聊天或电邮 [chat@simplex.chat](mailto:chat@simplex.chat) 将问题报告给应用程序开发人员。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Migration is completed" xml:space="preserve"> <trans-unit id="Migration is completed" xml:space="preserve">
@ -2270,6 +2292,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Muted when inactive!" xml:space="preserve"> <trans-unit id="Muted when inactive!" xml:space="preserve">
<source>Muted when inactive!</source> <source>Muted when inactive!</source>
<target>不活动时静音!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Name" xml:space="preserve"> <trans-unit id="Name" xml:space="preserve">
@ -2376,11 +2399,14 @@ We will be adding server redundancy to prevent lost messages.</source>
<source>Now admins can: <source>Now admins can:
- delete members' messages. - delete members' messages.
- disable members ("observer" role)</source> - disable members ("observer" role)</source>
<target>现在管理员可以:
- 删除成员的消息。
- 禁用成员(“观察员”角色)</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Off (Local)" xml:space="preserve"> <trans-unit id="Off (Local)" xml:space="preserve">
<source>Off (Local)</source> <source>Off (Local)</source>
<target>关闭 (本地)</target> <target>关闭(本地)</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Ok" xml:space="preserve"> <trans-unit id="Ok" xml:space="preserve">
@ -2505,6 +2531,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Password to show" xml:space="preserve"> <trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source> <source>Password to show</source>
<target>显示密码</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Paste" xml:space="preserve"> <trans-unit id="Paste" xml:space="preserve">
@ -2534,7 +2561,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Periodically" xml:space="preserve"> <trans-unit id="Periodically" xml:space="preserve">
<source>Periodically</source> <source>Periodically</source>
<target>定期</target> <target>定期</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve"> <trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
@ -2659,6 +2686,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve"> <trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source> <source>Protect your chat profiles with a password!</source>
<target>使用密码保护您的聊天资料!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve"> <trans-unit id="Protocol timeout" xml:space="preserve">
@ -2763,7 +2791,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Required" xml:space="preserve"> <trans-unit id="Required" xml:space="preserve">
<source>Required</source> <source>Required</source>
<target>必</target> <target>必</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Reset" xml:space="preserve"> <trans-unit id="Reset" xml:space="preserve">
@ -2858,6 +2886,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve"> <trans-unit id="Save and update group profile" xml:space="preserve">
<source>Save and update group profile</source> <source>Save and update group profile</source>
<target>保存和更新组配置文件</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save archive" xml:space="preserve"> <trans-unit id="Save archive" xml:space="preserve">
@ -2887,6 +2916,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Save profile password" xml:space="preserve"> <trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source> <source>Save profile password</source>
<target>保存个人资料密码</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save servers" xml:space="preserve"> <trans-unit id="Save servers" xml:space="preserve">
@ -2896,10 +2926,12 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Save servers?" xml:space="preserve"> <trans-unit id="Save servers?" xml:space="preserve">
<source>Save servers?</source> <source>Save servers?</source>
<target>保存服务器?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Save welcome message?" xml:space="preserve"> <trans-unit id="Save welcome message?" xml:space="preserve">
<source>Save welcome message?</source> <source>Save welcome message?</source>
<target>保存欢迎信息?</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve"> <trans-unit id="Saved WebRTC ICE servers will be removed" xml:space="preserve">
@ -3054,6 +3086,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Set the message shown to new members!" xml:space="preserve"> <trans-unit id="Set the message shown to new members!" xml:space="preserve">
<source>Set the message shown to new members!</source> <source>Set the message shown to new members!</source>
<target>设置向新成员显示的消息!</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve"> <trans-unit id="Set timeouts for proxy/VPN" xml:space="preserve">
@ -3238,6 +3271,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve"> <trans-unit id="Tap to activate profile." xml:space="preserve">
<source>Tap to activate profile.</source> <source>Tap to activate profile.</source>
<target>点击以激活个人资料。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Tap to join" xml:space="preserve"> <trans-unit id="Tap to join" xml:space="preserve">
@ -3332,7 +3366,7 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="The message will be marked as moderated for all members." xml:space="preserve"> <trans-unit id="The message will be marked as moderated for all members." xml:space="preserve">
<source>The message will be marked as moderated for all members.</source> <source>The message will be marked as moderated for all members.</source>
<target>该消息将对所有成员显示为已审核。</target> <target>该消息将对所有成员标记为已被管理员移除。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="The next generation of private messaging" xml:space="preserve"> <trans-unit id="The next generation of private messaging" xml:space="preserve">
@ -3367,10 +3401,12 @@ We will be adding server redundancy to prevent lost messages.</source>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one user profile." xml:space="preserve"> <trans-unit id="There should be at least one user profile." xml:space="preserve">
<source>There should be at least one user profile.</source> <source>There should be at least one user profile.</source>
<target>应该至少有一个用户资料。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="There should be at least one visible user profile." xml:space="preserve"> <trans-unit id="There should be at least one visible user profile." xml:space="preserve">
<source>There should be at least one visible user profile.</source> <source>There should be at least one visible user profile.</source>
<target>应该至少有一个可见的用户资料。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve"> <trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
@ -3442,6 +3478,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit> </trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve"> <trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source> <source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>要显示您的隐藏的个人资料,请在**您的聊天个人资料**页面的搜索字段中输入完整密码。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve"> <trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@ -3471,7 +3508,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit> </trans-unit>
<trans-unit id="Turn off" xml:space="preserve"> <trans-unit id="Turn off" xml:space="preserve">
<source>Turn off</source> <source>Turn off</source>
<target>关</target> <target>关</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Turn off notifications?" xml:space="preserve"> <trans-unit id="Turn off notifications?" xml:space="preserve">
@ -3501,6 +3538,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit> </trans-unit>
<trans-unit id="Unhide" xml:space="preserve"> <trans-unit id="Unhide" xml:space="preserve">
<source>Unhide</source> <source>Unhide</source>
<target>取消隐藏</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="Unknown caller" xml:space="preserve"> <trans-unit id="Unknown caller" xml:space="preserve">
@ -3778,6 +3816,8 @@ To connect, please ask your contact to create another connection link and check
<trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve"> <trans-unit id="You can hide or mute a user profile - swipe it to the right.&#10;SimpleX Lock must be enabled." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right. <source>You can hide or mute a user profile - swipe it to the right.
SimpleX Lock must be enabled.</source> SimpleX Lock must be enabled.</source>
<target>您可以隐藏或静音用户个人资料——只需向右滑动。
必须启用 SimpleX Lock。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You can now send messages to %@" xml:space="preserve"> <trans-unit id="You can now send messages to %@" xml:space="preserve">
@ -3897,6 +3937,7 @@ SimpleX Lock must be enabled.</source>
</trans-unit> </trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve"> <trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
<source>You will still receive calls and notifications from muted profiles when they are active.</source> <source>You will still receive calls and notifications from muted profiles when they are active.</source>
<target>当静音配置文件处于活动状态时,您仍会收到来自静音配置文件的电话和通知。</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve"> <trans-unit id="You will stop receiving messages from this group. Chat history will be preserved." xml:space="preserve">
@ -4055,7 +4096,7 @@ SimpleX 服务器无法看到您的资料。</target>
</trans-unit> </trans-unit>
<trans-unit id="[Send us email](mailto:chat@simplex.chat)" xml:space="preserve"> <trans-unit id="[Send us email](mailto:chat@simplex.chat)" xml:space="preserve">
<source>[Send us email](mailto:chat@simplex.chat)</source> <source>[Send us email](mailto:chat@simplex.chat)</source>
<target>[发送邮件至](mailto:chat@simplex.chat)</target> <target>[给我们发电邮](mailto:chat@simplex.chat)</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="[Star on GitHub](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve"> <trans-unit id="[Star on GitHub](https://github.com/simplex-chat/simplex-chat)" xml:space="preserve">
@ -4160,7 +4201,7 @@ SimpleX 服务器无法看到您的资料。</target>
</trans-unit> </trans-unit>
<trans-unit id="colored" xml:space="preserve"> <trans-unit id="colored" xml:space="preserve">
<source>colored</source> <source>colored</source>
<target>色</target> <target>色</target>
<note>No comment provided by engineer.</note> <note>No comment provided by engineer.</note>
</trans-unit> </trans-unit>
<trans-unit id="complete" xml:space="preserve"> <trans-unit id="complete" xml:space="preserve">
@ -4471,7 +4512,7 @@ SimpleX 服务器无法看到您的资料。</target>
</trans-unit> </trans-unit>
<trans-unit id="on" xml:space="preserve"> <trans-unit id="on" xml:space="preserve">
<source>on</source> <source>on</source>
<target></target> <target>开启</target>
<note>group pref value</note> <note>group pref value</note>
</trans-unit> </trans-unit>
<trans-unit id="or chat with the developers" xml:space="preserve"> <trans-unit id="or chat with the developers" xml:space="preserve">
@ -4481,7 +4522,7 @@ SimpleX 服务器无法看到您的资料。</target>
</trans-unit> </trans-unit>
<trans-unit id="owner" xml:space="preserve"> <trans-unit id="owner" xml:space="preserve">
<source>owner</source> <source>owner</source>
<target>所有者</target> <target>群主</target>
<note>member role</note> <note>member role</note>
</trans-unit> </trans-unit>
<trans-unit id="peer-to-peer" xml:space="preserve"> <trans-unit id="peer-to-peer" xml:space="preserve">

View file

@ -204,7 +204,7 @@ var xftpConfig: XFTPFileConfig? = getXFTPCfg()
func startChat() -> DBMigrationResult? { func startChat() -> DBMigrationResult? {
hs_init(0, nil) hs_init(0, nil)
if chatStarted { return .ok } if chatStarted { return .ok }
let (_, dbStatus) = chatMigrateInit() let (_, dbStatus) = chatMigrateInit(confirmMigrations: defaultMigrationConfirmation())
if dbStatus != .ok { if dbStatus != .ok {
resetChatCtrl() resetChatCtrl()
return dbStatus return dbStatus

View file

@ -58,6 +58,7 @@
5C65DAF529CBA429003CEE45 /* libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65DAF029CBA429003CEE45 /* libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a */; }; 5C65DAF529CBA429003CEE45 /* libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65DAF029CBA429003CEE45 /* libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a */; };
5C65DAF629CBA429003CEE45 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65DAF129CBA429003CEE45 /* libgmpxx.a */; }; 5C65DAF629CBA429003CEE45 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65DAF129CBA429003CEE45 /* libgmpxx.a */; };
5C65DAF729CBA429003CEE45 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65DAF229CBA429003CEE45 /* libffi.a */; }; 5C65DAF729CBA429003CEE45 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65DAF229CBA429003CEE45 /* libffi.a */; };
5C65DAF929D0CC20003CEE45 /* DeveloperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65DAF829D0CC20003CEE45 /* DeveloperView.swift */; };
5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65F341297D3F3600B67AF3 /* VersionView.swift */; }; 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65F341297D3F3600B67AF3 /* VersionView.swift */; };
5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6AD81227A834E300348BD7 /* NewChatButton.swift */; }; 5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6AD81227A834E300348BD7 /* NewChatButton.swift */; };
5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6BA666289BD954009B8ECC /* DismissSheets.swift */; }; 5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6BA666289BD954009B8ECC /* DismissSheets.swift */; };
@ -294,6 +295,7 @@
5C65DAF029CBA429003CEE45 /* libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a"; sourceTree = "<group>"; }; 5C65DAF029CBA429003CEE45 /* libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.6.0.0-KxI2qGrpKDHEZQGy0eoUXU.a"; sourceTree = "<group>"; };
5C65DAF129CBA429003CEE45 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; }; 5C65DAF129CBA429003CEE45 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
5C65DAF229CBA429003CEE45 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; }; 5C65DAF229CBA429003CEE45 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
5C65DAF829D0CC20003CEE45 /* DeveloperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperView.swift; sourceTree = "<group>"; };
5C65F341297D3F3600B67AF3 /* VersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionView.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 5C6BA666289BD954009B8ECC /* DismissSheets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissSheets.swift; sourceTree = "<group>"; };
@ -691,6 +693,7 @@
64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */, 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */,
18415845648CA4F5A8BCA272 /* UserProfilesView.swift */, 18415845648CA4F5A8BCA272 /* UserProfilesView.swift */,
5C65F341297D3F3600B67AF3 /* VersionView.swift */, 5C65F341297D3F3600B67AF3 /* VersionView.swift */,
5C65DAF829D0CC20003CEE45 /* DeveloperView.swift */,
); );
path = UserSettings; path = UserSettings;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1022,6 +1025,7 @@
5C93292F29239A170090FFF9 /* SMPServersView.swift in Sources */, 5C93292F29239A170090FFF9 /* SMPServersView.swift in Sources */,
5CB924D727A8563F00ACCCDD /* SettingsView.swift in Sources */, 5CB924D727A8563F00ACCCDD /* SettingsView.swift in Sources */,
5CEACCE327DE9246000BD591 /* ComposeView.swift in Sources */, 5CEACCE327DE9246000BD591 /* ComposeView.swift in Sources */,
5C65DAF929D0CC20003CEE45 /* DeveloperView.swift in Sources */,
5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */, 5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */,
5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */, 5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */,
5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */, 5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */,
@ -1396,7 +1400,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 132; CURRENT_PROJECT_VERSION = 134;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@ -1438,7 +1442,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 132; CURRENT_PROJECT_VERSION = 134;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@ -1518,7 +1522,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 132; CURRENT_PROJECT_VERSION = 134;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@ -1550,7 +1554,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 132; CURRENT_PROJECT_VERSION = 134;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;

View file

@ -17,7 +17,7 @@ public func getChatCtrl(_ useKey: String? = nil) -> chat_ctrl {
fatalError("chat controller not initialized") fatalError("chat controller not initialized")
} }
public func chatMigrateInit(_ useKey: String? = nil) -> (Bool, DBMigrationResult) { public func chatMigrateInit(_ useKey: String? = nil, confirmMigrations: MigrationConfirmation? = nil) -> (Bool, DBMigrationResult) {
if let res = migrationResult { return res } if let res = migrationResult { return res }
let dbPath = getAppDatabasePath().path let dbPath = getAppDatabasePath().path
var dbKey = "" var dbKey = ""
@ -34,12 +34,14 @@ public func chatMigrateInit(_ useKey: String? = nil) -> (Bool, DBMigrationResult
dbKey = key dbKey = key
} }
} }
logger.debug("chatMigrateInit DB path: \(dbPath)") let confirm = confirmMigrations ?? defaultMigrationConfirmation()
logger.debug("chatMigrateInit DB path: \(dbPath), confirm: \(confirm.rawValue)")
// logger.debug("chatMigrateInit DB key: \(dbKey)") // logger.debug("chatMigrateInit DB key: \(dbKey)")
var cPath = dbPath.cString(using: .utf8)! var cPath = dbPath.cString(using: .utf8)!
var cKey = dbKey.cString(using: .utf8)! var cKey = dbKey.cString(using: .utf8)!
var cConfirm = confirm.rawValue.cString(using: .utf8)!
// the last parameter of chat_migrate_init is used to return the pointer to chat controller // the last parameter of chat_migrate_init is used to return the pointer to chat controller
let cjson = chat_migrate_init(&cPath, &cKey, &chatController)! let cjson = chat_migrate_init(&cPath, &cKey, &cConfirm, &chatController)!
let dbRes = dbMigrationResult(fromCString(cjson)) let dbRes = dbMigrationResult(fromCString(cjson))
let encrypted = dbKey != "" let encrypted = dbKey != ""
let keychainErr = dbRes == .ok && useKeychain && encrypted && !setDatabaseKey(dbKey) let keychainErr = dbRes == .ok && useKeychain && encrypted && !setDatabaseKey(dbKey)
@ -207,12 +209,40 @@ func chatErrorString(_ err: ChatError) -> String {
public enum DBMigrationResult: Decodable, Equatable { public enum DBMigrationResult: Decodable, Equatable {
case ok case ok
case invalidConfirmation
case errorNotADatabase(dbFile: String) case errorNotADatabase(dbFile: String)
case error(dbFile: String, migrationError: String) case errorMigration(dbFile: String, migrationError: MigrationError)
case errorSQL(dbFile: String, migrationSQLError: String)
case errorKeychain case errorKeychain
case unknown(json: String) case unknown(json: String)
} }
public enum MigrationConfirmation: String {
case yesUp
case yesUpDown
case error
}
public func defaultMigrationConfirmation() -> MigrationConfirmation {
confirmDBUpgradesGroupDefault.get() ? .error : .yesUp
}
public enum MigrationError: Decodable, Equatable {
case upgrade(upMigrations: [UpMigration])
case downgrade(downMigrations: [String])
case migrationError(mtrError: MTRError)
}
public struct UpMigration: Decodable, Equatable {
public var upName: String
// public var withDown: Bool
}
public enum MTRError: Decodable, Equatable {
case noDown(dbMigrations: [String])
case different(appMigration: String, dbMigration: String)
}
func dbMigrationResult(_ s: String) -> DBMigrationResult { func dbMigrationResult(_ s: String) -> DBMigrationResult {
let d = s.data(using: .utf8)! let d = s.data(using: .utf8)!
// TODO is there a way to do it without copying the data? e.g: // TODO is there a way to do it without copying the data? e.g:

View file

@ -471,7 +471,7 @@ public enum ChatResponse: Decodable, Error {
case ntfMessages(user_: User?, connEntity: ConnectionEntity?, msgTs: Date?, ntfMessages: [NtfMsgInfo]) case ntfMessages(user_: User?, connEntity: ConnectionEntity?, msgTs: Date?, ntfMessages: [NtfMsgInfo])
case newContactConnection(user: User, connection: PendingContactConnection) case newContactConnection(user: User, connection: PendingContactConnection)
case contactConnectionDeleted(user: User, connection: PendingContactConnection) case contactConnectionDeleted(user: User, connection: PendingContactConnection)
case versionInfo(versionInfo: CoreVersionInfo) case versionInfo(versionInfo: CoreVersionInfo, chatMigrations: [UpMigration], agentMigrations: [UpMigration])
case cmdOk(user: User?) case cmdOk(user: User?)
case chatCmdError(user_: User?, chatError: ChatError) case chatCmdError(user_: User?, chatError: ChatError)
case chatError(user_: User?, chatError: ChatError) case chatError(user_: User?, chatError: ChatError)
@ -690,7 +690,7 @@ public enum ChatResponse: Decodable, Error {
case let .ntfMessages(u, connEntity, msgTs, ntfMessages): return withUser(u, "connEntity: \(String(describing: connEntity))\nmsgTs: \(String(describing: msgTs))\nntfMessages: \(String(describing: ntfMessages))") case let .ntfMessages(u, connEntity, msgTs, ntfMessages): return withUser(u, "connEntity: \(String(describing: connEntity))\nmsgTs: \(String(describing: msgTs))\nntfMessages: \(String(describing: ntfMessages))")
case let .newContactConnection(u, connection): return withUser(u, String(describing: connection)) case let .newContactConnection(u, connection): return withUser(u, String(describing: connection))
case let .contactConnectionDeleted(u, connection): return withUser(u, String(describing: connection)) case let .contactConnectionDeleted(u, connection): return withUser(u, String(describing: connection))
case let .versionInfo(versionInfo): return String(describing: versionInfo) case let .versionInfo(versionInfo, chatMigrations, agentMigrations): return "\(String(describing: versionInfo))\n\nchat migrations: \(chatMigrations.map(\.upName))\n\nagent migrations: \(agentMigrations.map(\.upName))"
case .cmdOk: return noDetails case .cmdOk: return noDetails
case let .chatCmdError(u, chatError): return withUser(u, String(describing: chatError)) case let .chatCmdError(u, chatError): return withUser(u, String(describing: chatError))
case let .chatError(u, chatError): return withUser(u, String(describing: chatError)) case let .chatError(u, chatError): return withUser(u, String(describing: chatError))

View file

@ -29,6 +29,7 @@ let GROUP_DEFAULT_NETWORK_TCP_KEEP_CNT = "networkTCPKeepCnt"
let GROUP_DEFAULT_INCOGNITO = "incognito" let GROUP_DEFAULT_INCOGNITO = "incognito"
let GROUP_DEFAULT_STORE_DB_PASSPHRASE = "storeDBPassphrase" let GROUP_DEFAULT_STORE_DB_PASSPHRASE = "storeDBPassphrase"
let GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE = "initialRandomDBPassphrase" let GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE = "initialRandomDBPassphrase"
public let GROUP_DEFAULT_CONFIRM_DB_UPGRADES = "confirmDBUpgrades"
public let GROUP_DEFAULT_CALL_KIT_ENABLED = "callKitEnabled" public let GROUP_DEFAULT_CALL_KIT_ENABLED = "callKitEnabled"
public let GROUP_DEFAULT_XFTP_SEND_ENABLED = "xftpSendEnabled" public let GROUP_DEFAULT_XFTP_SEND_ENABLED = "xftpSendEnabled"
@ -53,8 +54,9 @@ public func registerGroupDefaults() {
GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE: false, GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE: false,
GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES: true, GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES: true,
GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE: false, GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE: false,
GROUP_DEFAULT_CONFIRM_DB_UPGRADES: false,
GROUP_DEFAULT_CALL_KIT_ENABLED: true, GROUP_DEFAULT_CALL_KIT_ENABLED: true,
GROUP_DEFAULT_XFTP_SEND_ENABLED: false GROUP_DEFAULT_XFTP_SEND_ENABLED: false,
]) ])
} }
@ -123,6 +125,8 @@ public let storeDBPassphraseGroupDefault = BoolDefault(defaults: groupDefaults,
public let initialRandomDBPassphraseGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE) public let initialRandomDBPassphraseGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE)
public let confirmDBUpgradesGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_CONFIRM_DB_UPGRADES)
public let callKitEnabledGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_CALL_KIT_ENABLED) public let callKitEnabledGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_CALL_KIT_ENABLED)
public let xftpSendEnabledGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_XFTP_SEND_ENABLED) public let xftpSendEnabledGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_XFTP_SEND_ENABLED)

View file

@ -127,12 +127,16 @@ public func createErrorNtf(_ dbStatus: DBMigrationResult) -> UNMutableNotificati
switch dbStatus { switch dbStatus {
case .errorNotADatabase: case .errorNotADatabase:
title = NSLocalizedString("Encrypted message: no passphrase", comment: "notification") title = NSLocalizedString("Encrypted message: no passphrase", comment: "notification")
case .error: case .errorMigration:
title = NSLocalizedString("Encrypted message: database migration error", comment: "notification")
case .errorSQL:
title = NSLocalizedString("Encrypted message: database error", comment: "notification") title = NSLocalizedString("Encrypted message: database error", comment: "notification")
case .errorKeychain: case .errorKeychain:
title = NSLocalizedString("Encrypted message: keychain error", comment: "notification") title = NSLocalizedString("Encrypted message: keychain error", comment: "notification")
case .unknown: case .unknown:
title = NSLocalizedString("Encrypted message: unexpected error", comment: "notification") title = NSLocalizedString("Encrypted message: unexpected error", comment: "notification")
case .invalidConfirmation:
title = NSLocalizedString("Encrypted message or another event", comment: "notification")
case .ok: case .ok:
title = NSLocalizedString("Encrypted message or another event", comment: "notification") title = NSLocalizedString("Encrypted message or another event", comment: "notification")
} }

View file

@ -16,7 +16,7 @@ extern void hs_init(int argc, char **argv[]);
typedef void* chat_ctrl; typedef void* chat_ctrl;
// the last parameter is used to return the pointer to chat controller // the last parameter is used to return the pointer to chat controller
extern char *chat_migrate_init(char *path, char *key, chat_ctrl *ctrl); extern char *chat_migrate_init(char *path, char *key, char *confirm, chat_ctrl *ctrl);
extern char *chat_send_cmd(chat_ctrl ctl, char *cmd); extern char *chat_send_cmd(chat_ctrl ctl, char *cmd);
extern char *chat_recv_msg(chat_ctrl ctl); extern char *chat_recv_msg(chat_ctrl ctl);
extern char *chat_recv_msg_wait(chat_ctrl ctl, int wait); extern char *chat_recv_msg_wait(chat_ctrl ctl, int wait);

View file

@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "Přidat do jiného zařízení"; "Add to another device" = "Přidat do jiného zařízení";
/* No comment provided by engineer. */
"Add welcome message" = "Přidat uvítací zprávu";
/* member role */ /* member role */
"admin" = "správce"; "admin" = "správce";
@ -338,6 +341,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "Audio a video hovory"; "Audio & video calls" = "Audio a video hovory";
/* No comment provided by engineer. */
"Audio and video calls" = "Hlasové a video hovory";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "zvukový hovor (nešifrovaný e2e)"; "audio call (not e2e encrypted)" = "zvukový hovor (nešifrovaný e2e)";
@ -398,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "Hovory"; "Calls" = "Hovory";
/* No comment provided by engineer. */
"Can't delete user profile!" = "Nemohu smazat uživatelský profil!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "Nelze pozvat kontakt!"; "Can't invite contact!" = "Nelze pozvat kontakt!";
@ -479,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "Zkontrolujte adresu serveru a zkuste to znovu."; "Check server address and try again." = "Zkontrolujte adresu serveru a zkuste to znovu.";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "Čínské a Španělské rozhranní";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "Vybrat soubor"; "Choose file" = "Vybrat soubor";
@ -518,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "Potvrdit novou heslovou frázi…"; "Confirm new passphrase…" = "Potvrdit novou heslovou frázi…";
/* No comment provided by engineer. */
"Confirm password" = "Potvrdit heslo";
/* server test step */ /* server test step */
"Connect" = "Připojit"; "Connect" = "Připojit";
@ -884,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "NEpoužívejte SimpleX pro tísňová volání."; "Do NOT use SimpleX for emergency calls." = "NEpoužívejte SimpleX pro tísňová volání.";
/* No comment provided by engineer. */
"Don't show again" = "Znovu neukazuj";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "Duplicitní zobrazované jméno!"; "Duplicate display name!" = "Duplicitní zobrazované jméno!";
@ -1061,6 +1079,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "Chyba při ukládání serverů SMP"; "Error saving SMP servers" = "Chyba při ukládání serverů SMP";
/* No comment provided by engineer. */
"Error saving user password" = "Chyba ukládání hesla uživatele";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "Chyba při odesílání zprávy"; "Error sending message" = "Chyba při odesílání zprávy";
@ -1082,6 +1103,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "Chyba při aktualizaci nastavení"; "Error updating settings" = "Chyba při aktualizaci nastavení";
/* No comment provided by engineer. */
"Error updating user privacy" = "Chyba aktualizace soukromí uživatele";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "Chyba: %@"; "Error: %@" = "Chyba: %@";
@ -1133,6 +1157,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "Celé jméno:"; "Full name:" = "Celé jméno:";
/* No comment provided by engineer. */
"Further reduced battery usage" = "Další snížení spotřeby baterie";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "GIFy a nálepky"; "GIFs and stickers" = "GIFy a nálepky";
@ -1181,6 +1208,9 @@
/* notification */ /* notification */
"Group message:" = "Skupinová zpráva:"; "Group message:" = "Skupinová zpráva:";
/* No comment provided by engineer. */
"Group moderation" = "Správa skupin";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "Předvolby skupiny"; "Group preferences" = "Předvolby skupiny";
@ -1193,6 +1223,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "profil skupiny aktualizován"; "group profile updated" = "profil skupiny aktualizován";
/* No comment provided by engineer. */
"Group welcome message" = "Uvítací zpráva skupin";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "Skupina bude smazána pro všechny členy - nelze to vzít zpět!"; "Group will be deleted for all members - this cannot be undone!" = "Skupina bude smazána pro všechny členy - nelze to vzít zpět!";
@ -1205,12 +1238,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "Skryté"; "Hidden" = "Skryté";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Skryté chat profily";
/* No comment provided by engineer. */
"Hidden profile password" = "Hesla skrytých profilů";
/* chat item action */ /* chat item action */
"Hide" = "Skrýt"; "Hide" = "Skrýt";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "Skrytí obrazovky aplikace v posledních aplikacích."; "Hide app screen in the recent apps." = "Skrytí obrazovky aplikace v posledních aplikacích.";
/* No comment provided by engineer. */
"Hide profile" = "Skrýt profil";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "Jak to funguje"; "How it works" = "Jak to funguje";
@ -1298,6 +1340,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "nepřímé (%d)"; "indirect (%d)" = "nepřímé (%d)";
/* No comment provided by engineer. */
"Initial role" = "Počáteční role";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Nainstalujte [SimpleX Chat pro terminál](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Nainstalujte [SimpleX Chat pro terminál](https://github.com/simplex-chat/simplex-chat)";
@ -1436,6 +1481,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "Vytvořte si soukromé připojení"; "Make a private connection" = "Vytvořte si soukromé připojení";
/* No comment provided by engineer. */
"Make profile private!" = "Změnit profil na soukromý!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Ujistěte se, že adresy SMP serverů jsou ve správném formátu, oddělené řádky a nejsou duplicitní (%@)."; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Ujistěte se, že adresy SMP serverů jsou ve správném formátu, oddělené řádky a nejsou duplicitní (%@).";
@ -1532,6 +1580,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "Ztlumit"; "Mute" = "Ztlumit";
/* No comment provided by engineer. */
"Muted when inactive!" = "Ztlumit při neaktivitě!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "Jméno"; "Name" = "Jméno";
@ -1604,6 +1655,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "Oznámení jsou zakázána!"; "Notifications are disabled!" = "Oznámení jsou zakázána!";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Nyní mohou správci:\n- mazat zprávy členů.\n- zakázat členy (role \"pozorovatel\")";
/* member role */ /* member role */
"observer" = "pozorovatel"; "observer" = "pozorovatel";
@ -1695,6 +1749,9 @@
/* member role */ /* member role */
"owner" = "vlastník"; "owner" = "vlastník";
/* No comment provided by engineer. */
"Password to show" = "Heslo k zobrazení";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "Vložit"; "Paste" = "Vložit";
@ -1794,6 +1851,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "Ochrana obrazovky aplikace"; "Protect app screen" = "Ochrana obrazovky aplikace";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "Chraňte své chat profily heslem!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "Časový limit protokolu"; "Protocol timeout" = "Časový limit protokolu";
@ -1926,6 +1986,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "Uložit a upozornit členy skupiny"; "Save and notify group members" = "Uložit a upozornit členy skupiny";
/* No comment provided by engineer. */
"Save and update group profile" = "Uložit a aktualizovat profil skupiny";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "Uložit archiv"; "Save archive" = "Uložit archiv";
@ -1941,9 +2004,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "Uložit předvolby?"; "Save preferences?" = "Uložit předvolby?";
/* No comment provided by engineer. */
"Save profile password" = "Uložit heslo profilu";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "Uložit servery"; "Save servers" = "Uložit servery";
/* No comment provided by engineer. */
"Save servers?" = "Uložit servery?";
/* No comment provided by engineer. */
"Save welcome message?" = "Uložit uvítací zprávu?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "Uložené servery WebRTC ICE budou odstraněny"; "Saved WebRTC ICE servers will be removed" = "Uložené servery WebRTC ICE budou odstraněny";
@ -2040,6 +2112,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "Nastavení přístupové fráze pro export"; "Set passphrase to export" = "Nastavení přístupové fráze pro export";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "Nastavte zprávu zobrazenou novým členům!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "Nastavit časové limity pro proxy/VPN"; "Set timeouts for proxy/VPN" = "Nastavit časové limity pro proxy/VPN";
@ -2145,6 +2220,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "Klepněte na tlačítko "; "Tap button " = "Klepněte na tlačítko ";
/* No comment provided by engineer. */
"Tap to activate profile." = "Klepnutím aktivujete profil.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "Klepnutím se připojíte"; "Tap to join" = "Klepnutím se připojíte";
@ -2232,6 +2310,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "Téma"; "Theme" = "Téma";
/* No comment provided by engineer. */
"There should be at least one user profile." = "Měl by tam být alespoň jeden uživatelský profil.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Tuto akci nelze vrátit zpět - všechny přijaté a odeslané soubory a média budou smazány. Obrázky s nízkým rozlišením zůstanou zachovány."; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Tuto akci nelze vrátit zpět - všechny přijaté a odeslané soubory a média budou smazány. Obrázky s nízkým rozlišením zůstanou zachovány.";

View file

@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "Einem anderen Gerät hinzufügen"; "Add to another device" = "Einem anderen Gerät hinzufügen";
/* No comment provided by engineer. */
"Add welcome message" = "Fügen Sie eine Begrüßungsmeldung hinzu";
/* member role */ /* member role */
"admin" = "Admin"; "admin" = "Admin";
@ -338,6 +341,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "Audio- & Videoanrufe"; "Audio & video calls" = "Audio- & Videoanrufe";
/* No comment provided by engineer. */
"Audio and video calls" = "Audio- und Videoanrufe";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "Audioanruf (nicht E2E verschlüsselt)"; "audio call (not e2e encrypted)" = "Audioanruf (nicht E2E verschlüsselt)";
@ -398,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "Anrufe"; "Calls" = "Anrufe";
/* No comment provided by engineer. */
"Can't delete user profile!" = "Das Benutzerprofil kann nicht gelöscht werden!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "Kontakt kann nicht eingeladen werden!"; "Can't invite contact!" = "Kontakt kann nicht eingeladen werden!";
@ -479,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "Überprüfen Sie die Serveradresse und versuchen Sie es nochmal."; "Check server address and try again." = "Überprüfen Sie die Serveradresse und versuchen Sie es nochmal.";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "Chinesische und spanische Bedienoberfläche";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "Datei auswählen"; "Choose file" = "Datei auswählen";
@ -518,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "Neues Passwort bestätigen…"; "Confirm new passphrase…" = "Neues Passwort bestätigen…";
/* No comment provided by engineer. */
"Confirm password" = "Bestätigen Sie das Passwort";
/* server test step */ /* server test step */
"Connect" = "Verbinden"; "Connect" = "Verbinden";
@ -884,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "Nutzen Sie SimpleX nicht für Notrufe."; "Do NOT use SimpleX for emergency calls." = "Nutzen Sie SimpleX nicht für Notrufe.";
/* No comment provided by engineer. */
"Don't show again" = "Nicht nochmals anzeigen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "Doppelter Anzeigename!"; "Duplicate display name!" = "Doppelter Anzeigename!";
@ -965,6 +983,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter passphrase…" = "Passwort eingeben…"; "Enter passphrase…" = "Passwort eingeben…";
/* No comment provided by engineer. */
"Enter password above to show!" = "Geben Sie oben das Passwort für die Anzeige an!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter server manually" = "Geben Sie den Server manuell ein"; "Enter server manually" = "Geben Sie den Server manuell ein";
@ -1061,6 +1082,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "Fehler beim Speichern der SMP-Server"; "Error saving SMP servers" = "Fehler beim Speichern der SMP-Server";
/* No comment provided by engineer. */
"Error saving user password" = "Fehler beim Speichern des Benutzer-Passworts";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "Fehler beim Senden der Nachricht"; "Error sending message" = "Fehler beim Senden der Nachricht";
@ -1082,6 +1106,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "Fehler beim Aktualisieren der Einstellungen"; "Error updating settings" = "Fehler beim Aktualisieren der Einstellungen";
/* No comment provided by engineer. */
"Error updating user privacy" = "Fehler beim Aktualisieren der Benutzer-Privatsphäre";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "Fehler: %@"; "Error: %@" = "Fehler: %@";
@ -1133,6 +1160,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "Vollständiger Name:"; "Full name:" = "Vollständiger Name:";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Komplett neu umgesetzt - arbeitet nun im Hintergrund!";
/* No comment provided by engineer. */
"Further reduced battery usage" = "Weiter reduzierter Batterieverbrauch";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "GIFs und Sticker"; "GIFs and stickers" = "GIFs und Sticker";
@ -1181,6 +1214,9 @@
/* notification */ /* notification */
"Group message:" = "Grppennachricht:"; "Group message:" = "Grppennachricht:";
/* No comment provided by engineer. */
"Group moderation" = "Gruppenmoderation";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "Gruppenpräferenzen"; "Group preferences" = "Gruppenpräferenzen";
@ -1193,6 +1229,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "Gruppenprofil aktualisiert"; "group profile updated" = "Gruppenprofil aktualisiert";
/* No comment provided by engineer. */
"Group welcome message" = "Gruppen-Begrüßungsmeldung";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "Die Gruppe wird für alle Mitglieder gelöscht - dies kann nicht rückgängig gemacht werden!"; "Group will be deleted for all members - this cannot be undone!" = "Die Gruppe wird für alle Mitglieder gelöscht - dies kann nicht rückgängig gemacht werden!";
@ -1205,12 +1244,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "Verborgen"; "Hidden" = "Verborgen";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Verborgene Chat-Profile";
/* No comment provided by engineer. */
"Hidden profile password" = "Verborgenes Profil-Passwort";
/* chat item action */ /* chat item action */
"Hide" = "Verbergen"; "Hide" = "Verbergen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "App-Bildschirm in aktuellen Anwendungen verbergen."; "Hide app screen in the recent apps." = "App-Bildschirm in aktuellen Anwendungen verbergen.";
/* No comment provided by engineer. */
"Hide profile" = "Verberge das Profil";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "Wie es funktioniert"; "How it works" = "Wie es funktioniert";
@ -1298,6 +1346,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "indirekt (%d)"; "indirect (%d)" = "indirekt (%d)";
/* No comment provided by engineer. */
"Initial role" = "Anfängliche Rolle";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installieren Sie [SimpleX Chat als Terminalanwendung](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installieren Sie [SimpleX Chat als Terminalanwendung](https://github.com/simplex-chat/simplex-chat)";
@ -1436,6 +1487,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "Stellen Sie eine private Verbindung her"; "Make a private connection" = "Stellen Sie eine private Verbindung her";
/* No comment provided by engineer. */
"Make profile private!" = "Erzeugen Sie ein privates Profil!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Stellen Sie sicher, dass die SMP-Server-Adressen das richtige Format haben, zeilenweise getrennt und nicht doppelt vorhanden sind (%@)."; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Stellen Sie sicher, dass die SMP-Server-Adressen das richtige Format haben, zeilenweise getrennt und nicht doppelt vorhanden sind (%@).";
@ -1532,6 +1586,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "Stummschalten"; "Mute" = "Stummschalten";
/* No comment provided by engineer. */
"Muted when inactive!" = "Bei Inaktivität stummgeschaltet!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "Name"; "Name" = "Name";
@ -1604,6 +1661,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "Benachrichtigungen sind deaktiviert!"; "Notifications are disabled!" = "Benachrichtigungen sind deaktiviert!";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Administratoren können nun\n- Nachrichten von Gruppenmitgliedern löschen\n- Gruppenmitglieder deaktivieren (\"Beobachter\"-Rolle)";
/* member role */ /* member role */
"observer" = "Beobachter"; "observer" = "Beobachter";
@ -1695,6 +1755,9 @@
/* member role */ /* member role */
"owner" = "Eigentümer"; "owner" = "Eigentümer";
/* No comment provided by engineer. */
"Password to show" = "Passwort anzeigen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "Einfügen"; "Paste" = "Einfügen";
@ -1794,6 +1857,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "App-Bildschirm schützen"; "Protect app screen" = "App-Bildschirm schützen";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "Schützen Sie Ihre Chat-Profile mit einem Passwort!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "Protokollzeitüberschreitung"; "Protocol timeout" = "Protokollzeitüberschreitung";
@ -1926,6 +1992,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "Speichern und Gruppenmitglieder benachrichtigen"; "Save and notify group members" = "Speichern und Gruppenmitglieder benachrichtigen";
/* No comment provided by engineer. */
"Save and update group profile" = "Sichern und aktualisieren des Gruppen-Profils";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "Archiv speichern"; "Save archive" = "Archiv speichern";
@ -1941,9 +2010,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "Präferenzen speichern?"; "Save preferences?" = "Präferenzen speichern?";
/* No comment provided by engineer. */
"Save profile password" = "Profil-Passwort speichern";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "Alle Server speichern"; "Save servers" = "Alle Server speichern";
/* No comment provided by engineer. */
"Save servers?" = "Alle Server speichern?";
/* No comment provided by engineer. */
"Save welcome message?" = "Begrüßungsmeldung speichern?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "Gespeicherte WebRTC ICE-Server werden entfernt"; "Saved WebRTC ICE servers will be removed" = "Gespeicherte WebRTC ICE-Server werden entfernt";
@ -2040,6 +2118,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "Passwort für den Export festlegen"; "Set passphrase to export" = "Passwort für den Export festlegen";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "Legen Sie die Nachricht fest, die neuen Mitgliedern angezeigt werden soll!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "Zeitüberschreitungen für Proxy/VPN einstellen"; "Set timeouts for proxy/VPN" = "Zeitüberschreitungen für Proxy/VPN einstellen";
@ -2145,6 +2226,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "Schaltfläche antippen "; "Tap button " = "Schaltfläche antippen ";
/* No comment provided by engineer. */
"Tap to activate profile." = "Tippen Sie, um das Profil zu aktivieren.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "Zum Beitreten tippen"; "Tap to join" = "Zum Beitreten tippen";
@ -2232,6 +2316,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "Design"; "Theme" = "Design";
/* No comment provided by engineer. */
"There should be at least one user profile." = "Es muss mindestens ein Benutzer-Profil vorhanden sein.";
/* No comment provided by engineer. */
"There should be at least one visible user profile." = "Es muss mindestens ein sichtbares Benutzer-Profil vorhanden sein.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Diese Aktion kann nicht rückgängig gemacht werden! Alle empfangenen und gesendeten Dateien und Medien werden gelöscht. Bilder mit niedriger Auflösung bleiben erhalten."; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Diese Aktion kann nicht rückgängig gemacht werden! Alle empfangenen und gesendeten Dateien und Medien werden gelöscht. Bilder mit niedriger Auflösung bleiben erhalten.";
@ -2274,6 +2364,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To record voice message please grant permission to use Microphone." = "Bitte erlauben Sie die Nutzung des Mikrofons, um Sprachnachrichten aufnehmen zu können."; "To record voice message please grant permission to use Microphone." = "Bitte erlauben Sie die Nutzung des Mikrofons, um Sprachnachrichten aufnehmen zu können.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Geben Sie ein vollständiges Passwort in das Suchfeld auf der Seite **Meine Chat-Profile** ein, um Ihr verborgenes Profil zu sehen.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Um sofortige Push-Benachrichtigungen zu unterstützen, muss die Chat-Datenbank migriert werden."; "To support instant push notifications the chat database has to be migrated." = "Um sofortige Push-Benachrichtigungen zu unterstützen, muss die Chat-Datenbank migriert werden.";
@ -2307,6 +2400,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unexpected migration state" = "Unerwarteter Migrationsstatus"; "Unexpected migration state" = "Unerwarteter Migrationsstatus";
/* No comment provided by engineer. */
"Unhide" = "Verbergen aufheben";
/* connection info */ /* connection info */
"unknown" = "Unbekannt"; "unknown" = "Unbekannt";
@ -2511,6 +2607,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Sie können sich auch verbinden, indem Sie auf den Link klicken. Wenn er im Browser geöffnet wird, klicken Sie auf die Schaltfläche **In mobiler App öffnen**."; "You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Sie können sich auch verbinden, indem Sie auf den Link klicken. Wenn er im Browser geöffnet wird, klicken Sie auf die Schaltfläche **In mobiler App öffnen**.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right.\nSimpleX Lock must be enabled." = "Sie können ein Benutzerprofil verbergen oder stummschalten - wischen Sie es nach rechts.\nDafür muss die SimpleX Sperre aktiviert sein.";
/* notification body */ /* notification body */
"You can now send messages to %@" = "Sie können nun Nachrichten an %@ versenden"; "You can now send messages to %@" = "Sie können nun Nachrichten an %@ versenden";
@ -2604,6 +2703,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will join a group this link refers to and connect to its group members." = "Sie werden der Gruppe beitreten, auf die sich dieser Link bezieht und sich mit deren Gruppenmitgliedern verbinden."; "You will join a group this link refers to and connect to its group members." = "Sie werden der Gruppe beitreten, auf die sich dieser Link bezieht und sich mit deren Gruppenmitgliedern verbinden.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Sie können Anrufe und Benachrichtigungen auch von stummgeschalteten Profilen empfangen, solange diese aktiv sind.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will stop receiving messages from this group. Chat history will be preserved." = "Sie werden von dieser Gruppe keine Nachrichten mehr erhalten. Der Chatverlauf wird beibehalten."; "You will stop receiving messages from this group. Chat history will be preserved." = "Sie werden von dieser Gruppe keine Nachrichten mehr erhalten. Der Chatverlauf wird beibehalten.";

View file

@ -47,7 +47,7 @@
"[Star on GitHub](https://github.com/simplex-chat/simplex-chat)" = "[Comienza en GitHub] (https://github.com/simplex-chat/simplex-chat)"; "[Star on GitHub](https://github.com/simplex-chat/simplex-chat)" = "[Comienza en GitHub] (https://github.com/simplex-chat/simplex-chat)";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"**Add new contact**: to create your one-time QR Code for your contact." = "**Añadir nuevo contacto**: para crear tu código QR único o un enlace para tu contacto."; "**Add new contact**: to create your one-time QR Code for your contact." = "**Añadir nuevo contacto**: para crear tu código QR o enlace de un uso para tu contacto.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"**Create link / QR code** for your contact to use." = "**Crea enlace / código QR** para que tu contacto lo use."; "**Create link / QR code** for your contact to use." = "**Crea enlace / código QR** para que tu contacto lo use.";
@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "Añadir a otro dispositivo"; "Add to another device" = "Añadir a otro dispositivo";
/* No comment provided by engineer. */
"Add welcome message" = "Agregar mensaje de bienvenida";
/* member role */ /* member role */
"admin" = "administrador"; "admin" = "administrador";
@ -273,7 +276,7 @@
"Allow" = "Permitir"; "Allow" = "Permitir";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Allow disappearing messages only if your contact allows it to you." = "Permitir mensajes temporales sólo si tu contacto también los permite para tí."; "Allow disappearing messages only if your contact allows it to you." = "Permitir mensajes temporales sólo si tu contacto también los permite.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Allow irreversible message deletion only if your contact allows it to you." = "Permitir la eliminación irreversible de mensajes sólo si tu contacto también lo permite para tí."; "Allow irreversible message deletion only if your contact allows it to you." = "Permitir la eliminación irreversible de mensajes sólo si tu contacto también lo permite para tí.";
@ -300,7 +303,7 @@
"Allow your contacts to irreversibly delete sent messages." = "Permitir a tus contactos eliminar irreversiblemente los mensajes enviados."; "Allow your contacts to irreversibly delete sent messages." = "Permitir a tus contactos eliminar irreversiblemente los mensajes enviados.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Allow your contacts to send disappearing messages." = "Permitir a tus contactos enviar mensajes que desaparecen."; "Allow your contacts to send disappearing messages." = "Permitir a tus contactos enviar mensajes temporales.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Allow your contacts to send voice messages." = "Permitir a tus contactos enviar mensajes de voz."; "Allow your contacts to send voice messages." = "Permitir a tus contactos enviar mensajes de voz.";
@ -312,7 +315,7 @@
"always" = "siempre"; "always" = "siempre";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Always use relay" = "Siempre usa relay"; "Always use relay" = "Siempre usar relay";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Answer call" = "Responder llamada"; "Answer call" = "Responder llamada";
@ -338,6 +341,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "Llamadas de audio y vídeo"; "Audio & video calls" = "Llamadas de audio y vídeo";
/* No comment provided by engineer. */
"Audio and video calls" = "Llamadas y videollamadas";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "llamada de audio (sin cifrado e2e)"; "audio call (not e2e encrypted)" = "llamada de audio (sin cifrado e2e)";
@ -381,7 +387,7 @@
"Both you and your contact can send voice messages." = "Tanto tú como tu contacto podéis enviar mensajes de voz."; "Both you and your contact can send voice messages." = "Tanto tú como tu contacto podéis enviar mensajes de voz.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." = "Por perfil de Chat (por defecto) o [por conexión](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)."; "By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." = "Mediante perfil de Chat (por defecto) o [por conexión](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Call already ended!" = "¡La llamada ha terminado!"; "Call already ended!" = "¡La llamada ha terminado!";
@ -398,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "Llamadas"; "Calls" = "Llamadas";
/* No comment provided by engineer. */
"Can't delete user profile!" = "¡No se puede eliminar el perfil!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "¡No se puede invitar el contacto!"; "Can't invite contact!" = "¡No se puede invitar el contacto!";
@ -479,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "Comprueba la dirección del servidor e inténtalo de nuevo."; "Check server address and try again." = "Comprueba la dirección del servidor e inténtalo de nuevo.";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "Interfaz en chino y español";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "Elije archivo"; "Choose file" = "Elije archivo";
@ -518,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "Confirme nueva contraseña…"; "Confirm new passphrase…" = "Confirme nueva contraseña…";
/* No comment provided by engineer. */
"Confirm password" = "Confirmar contraseña";
/* server test step */ /* server test step */
"Connect" = "Conectar"; "Connect" = "Conectar";
@ -537,7 +552,7 @@
"Connect via link / QR code" = "Conectar mediante enlace / Código QR"; "Connect via link / QR code" = "Conectar mediante enlace / Código QR";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Connect via one-time link?" = "¿Conectar mediante enlace único?"; "Connect via one-time link?" = "¿Conectar mediante enlace de un uso?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"connected" = "conectado"; "connected" = "conectado";
@ -651,7 +666,7 @@
"Create link" = "Crear enlace"; "Create link" = "Crear enlace";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Create one-time invitation link" = "Crear enlace único de invitación"; "Create one-time invitation link" = "Crear enlace de invitación de un uso";
/* server test step */ /* server test step */
"Create queue" = "Crear cola"; "Create queue" = "Crear cola";
@ -884,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "NO uses SimpleX para llamadas de emergencia."; "Do NOT use SimpleX for emergency calls." = "NO uses SimpleX para llamadas de emergencia.";
/* No comment provided by engineer. */
"Don't show again" = "No mostrar de nuevo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "¡Nombre mostrado duplicado!"; "Duplicate display name!" = "¡Nombre mostrado duplicado!";
@ -965,6 +983,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter passphrase…" = "Introduce la contraseña…"; "Enter passphrase…" = "Introduce la contraseña…";
/* No comment provided by engineer. */
"Enter password above to show!" = "¡Introduce la contraseña arriba para mostrar!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter server manually" = "Introduce el servidor manualmente"; "Enter server manually" = "Introduce el servidor manualmente";
@ -1061,6 +1082,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "Error guardando servidores SMP"; "Error saving SMP servers" = "Error guardando servidores SMP";
/* No comment provided by engineer. */
"Error saving user password" = "Error guardando la contraseña de usuario";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "Error enviando mensaje"; "Error sending message" = "Error enviando mensaje";
@ -1082,6 +1106,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "Error actualizando configuración"; "Error updating settings" = "Error actualizando configuración";
/* No comment provided by engineer. */
"Error updating user privacy" = "Error actualizando la privacidad de usuario";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "Error: %@"; "Error: %@" = "Error: %@";
@ -1133,6 +1160,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "Nombre completo:"; "Full name:" = "Nombre completo:";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Completamente reimplementado: ¡funciona en segundo plano!";
/* No comment provided by engineer. */
"Further reduced battery usage" = "Consumo de batería reducido aun más";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "GIFs y stickers"; "GIFs and stickers" = "GIFs y stickers";
@ -1181,6 +1214,9 @@
/* notification */ /* notification */
"Group message:" = "Mensaje de grupo:"; "Group message:" = "Mensaje de grupo:";
/* No comment provided by engineer. */
"Group moderation" = "Moderación de grupos";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "Preferencias del grupo"; "Group preferences" = "Preferencias del grupo";
@ -1193,6 +1229,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "perfil de grupo actualizado"; "group profile updated" = "perfil de grupo actualizado";
/* No comment provided by engineer. */
"Group welcome message" = "Mensaje de bienvenida en grupos";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "El grupo se eliminará para todos los miembros. ¡No puede deshacerse!"; "Group will be deleted for all members - this cannot be undone!" = "El grupo se eliminará para todos los miembros. ¡No puede deshacerse!";
@ -1205,12 +1244,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "Oculto"; "Hidden" = "Oculto";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Perfiles Chat ocultos";
/* No comment provided by engineer. */
"Hidden profile password" = "Contraseña de perfil oculto";
/* chat item action */ /* chat item action */
"Hide" = "Ocultar"; "Hide" = "Ocultar";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "Ocultar pantalla de aplicaciones en aplicaciones recientes."; "Hide app screen in the recent apps." = "Ocultar pantalla de aplicaciones en aplicaciones recientes.";
/* No comment provided by engineer. */
"Hide profile" = "Ocultar perfil";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "Cómo funciona"; "How it works" = "Cómo funciona";
@ -1281,7 +1329,7 @@
"incognito via group link" = "Incógnito mediante enlace de grupo"; "incognito via group link" = "Incógnito mediante enlace de grupo";
/* chat list item description */ /* chat list item description */
"incognito via one-time link" = "Incógnito mediante enlace único"; "incognito via one-time link" = "Incógnito mediante enlace de un uso";
/* notification */ /* notification */
"Incoming audio call" = "Llamada entrante"; "Incoming audio call" = "Llamada entrante";
@ -1298,6 +1346,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "indirecto (%d)"; "indirect (%d)" = "indirecto (%d)";
/* No comment provided by engineer. */
"Initial role" = "Rol inicial";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Instalar [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Instalar [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)";
@ -1365,7 +1416,7 @@
"Irreversible message deletion is prohibited in this group." = "La eliminación irreversible de mensajes está prohibida en este grupo."; "Irreversible message deletion is prohibited in this group." = "La eliminación irreversible de mensajes está prohibida en este grupo.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"It allows having many anonymous connections without any shared data between them in a single chat profile." = "Permite tener muchas conexiones anónimas sin datos compartidos entre estas en un único perfil de chat."; "It allows having many anonymous connections without any shared data between them in a single chat profile." = "Permite tener varias conexiones anónimas sin datos compartidos entre estas en un único perfil de chat.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"It can happen when:\n1. The messages expire on the server if they were not received for 30 days,\n2. The server you use to receive the messages from this contact was updated and restarted.\n3. The connection is compromised.\nPlease connect to the developers via Settings to receive the updates about the servers.\nWe will be adding server redundancy to prevent lost messages." = "Esto puede suceder cuando:\n1. Los mensajes caducan en el servidor si no se han recibido durante 30 días.\n2. El servidor que utiliza para recibir los mensajes de este contacto fue actualizado y reiniciado.\n3. La conexión está comprometida.\nPor favor, contacta con los desarrolladores a través del menú Configuración para recibir actualizaciones sobre los servidores.\nAñadiremos redundancia de servidores para evitar la pérdida de mensajes."; "It can happen when:\n1. The messages expire on the server if they were not received for 30 days,\n2. The server you use to receive the messages from this contact was updated and restarted.\n3. The connection is compromised.\nPlease connect to the developers via Settings to receive the updates about the servers.\nWe will be adding server redundancy to prevent lost messages." = "Esto puede suceder cuando:\n1. Los mensajes caducan en el servidor si no se han recibido durante 30 días.\n2. El servidor que utiliza para recibir los mensajes de este contacto fue actualizado y reiniciado.\n3. La conexión está comprometida.\nPor favor, contacta con los desarrolladores a través del menú Configuración para recibir actualizaciones sobre los servidores.\nAñadiremos redundancia de servidores para evitar la pérdida de mensajes.";
@ -1436,6 +1487,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "Establecer una conexión privada"; "Make a private connection" = "Establecer una conexión privada";
/* No comment provided by engineer. */
"Make profile private!" = "¡Hacer un perfil privado!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Asegúrate de que las direcciones del servidor SMP tienen el formato correcto, están separadas por líneas y no duplicadas (%@)."; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Asegúrate de que las direcciones del servidor SMP tienen el formato correcto, están separadas por líneas y no duplicadas (%@).";
@ -1532,6 +1586,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "Silenciar"; "Mute" = "Silenciar";
/* No comment provided by engineer. */
"Muted when inactive!" = "¡Silenciado cuando está inactivo!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "Nombre"; "Name" = "Nombre";
@ -1604,6 +1661,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "¡Las notificaciones están desactivadas!"; "Notifications are disabled!" = "¡Las notificaciones están desactivadas!";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Ahora los administradores pueden\n- borrar mensajes de los miembros.\n- desactivar el rol a miembros (a rol \"observador\")";
/* member role */ /* member role */
"observer" = "observador"; "observer" = "observador";
@ -1633,7 +1693,7 @@
"on" = "Activado"; "on" = "Activado";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"One-time invitation link" = "Enlace único de invitación"; "One-time invitation link" = "Enlace único de invitación de un uso";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Onion hosts will be required for connection. Requires enabling VPN." = "Se requieren hosts .onion para la conexión. Requiere activación de la VPN."; "Onion hosts will be required for connection. Requires enabling VPN." = "Se requieren hosts .onion para la conexión. Requiere activación de la VPN.";
@ -1695,6 +1755,9 @@
/* member role */ /* member role */
"owner" = "propietario"; "owner" = "propietario";
/* No comment provided by engineer. */
"Password to show" = "Contraseña para hacerlo visible";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "Pegar"; "Paste" = "Pegar";
@ -1708,7 +1771,7 @@
"Paste the link you received into the box below to connect with your contact." = "Pega el enlace que has recibido en el recuadro para conectar con tu contacto."; "Paste the link you received into the box below to connect with your contact." = "Pega el enlace que has recibido en el recuadro para conectar con tu contacto.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"peer-to-peer" = "entre particulares"; "peer-to-peer" = "p2p";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"People can connect to you only via the links you share." = "Las personas pueden conectarse contigo solo mediante los enlaces que compartes."; "People can connect to you only via the links you share." = "Las personas pueden conectarse contigo solo mediante los enlaces que compartes.";
@ -1794,6 +1857,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "Proteger la pantalla de la aplicación"; "Protect app screen" = "Proteger la pantalla de la aplicación";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "¡Proteje los perfiles de Chat con contraseña!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "Tiempo de espera del protocolo"; "Protocol timeout" = "Tiempo de espera del protocolo";
@ -1843,10 +1909,10 @@
"rejected call" = "llamada rechazada"; "rejected call" = "llamada rechazada";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Relay server is only used if necessary. Another party can observe your IP address." = "El servidor de retransmisión sólo se utiliza en caso necesario. Una tercera persona puede observar tu dirección IP."; "Relay server is only used if necessary. Another party can observe your IP address." = "El relay sólo se usa en caso de necesidad. Un tercero podría ver tu IP.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Relay server protects your IP address, but it can observe the duration of the call." = "El servidor de retransmisión protege tu IP pero puede observar la duración de la llamada."; "Relay server protects your IP address, but it can observe the duration of the call." = "El servidor relay protege tu IP pero puede observar la duración de la llamada.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Remove" = "Eliminar"; "Remove" = "Eliminar";
@ -1926,6 +1992,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "Guardar y notificar a los miembros del grupo"; "Save and notify group members" = "Guardar y notificar a los miembros del grupo";
/* No comment provided by engineer. */
"Save and update group profile" = "Guardar y actualizar perfil del grupo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "Guardar archivo"; "Save archive" = "Guardar archivo";
@ -1941,9 +2010,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "¿Guardar preferencias?"; "Save preferences?" = "¿Guardar preferencias?";
/* No comment provided by engineer. */
"Save profile password" = "Guardar contraseña de perfil";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "Guardar servidores"; "Save servers" = "Guardar servidores";
/* No comment provided by engineer. */
"Save servers?" = "¿Guardar servidores?";
/* No comment provided by engineer. */
"Save welcome message?" = "¿Guardar mensaje de bienvenida?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "Los servidores WebRTC ICE guardados serán eliminados"; "Saved WebRTC ICE servers will be removed" = "Los servidores WebRTC ICE guardados serán eliminados";
@ -2040,6 +2118,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "Seleccióna contraseña para exportar"; "Set passphrase to export" = "Seleccióna contraseña para exportar";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "¡Establece el mensaje mostrado a los miembros nuevos!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "Establecer tiempos de espera para proxy/VPN"; "Set timeouts for proxy/VPN" = "Establecer tiempos de espera para proxy/VPN";
@ -2056,7 +2137,7 @@
"Share link" = "Compartir enlace"; "Share link" = "Compartir enlace";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Share one-time invitation link" = "Compartir enlace único de invitación"; "Share one-time invitation link" = "Compartir enlace de invitación de un uso";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Show calls in phone history" = "Mostrar llamadas en el historial del teléfono"; "Show calls in phone history" = "Mostrar llamadas en el historial del teléfono";
@ -2089,7 +2170,7 @@
"SimpleX Lock turned on" = "Bloqueo SimpleX activado"; "SimpleX Lock turned on" = "Bloqueo SimpleX activado";
/* simplex link type */ /* simplex link type */
"SimpleX one-time invitation" = "Invitación única SimpleX"; "SimpleX one-time invitation" = "Invitación SimpleX de un uso";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Skip" = "Omitir"; "Skip" = "Omitir";
@ -2145,6 +2226,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "Pulsa el botón "; "Tap button " = "Pulsa el botón ";
/* No comment provided by engineer. */
"Tap to activate profile." = "Pulsa para activar el perfil.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "Pulsa para unirse"; "Tap to join" = "Pulsa para unirse";
@ -2232,6 +2316,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "Tema"; "Theme" = "Tema";
/* No comment provided by engineer. */
"There should be at least one user profile." = "Debe haber al menos un perfil de usuario.";
/* No comment provided by engineer. */
"There should be at least one visible user profile." = "Debe haber al menos un perfil de usuario visible.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Esta acción no se puede deshacer. Se eliminarán todos los archivos y multimedia recibidos y enviados. Las imágenes de baja resolución permanecerán."; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Esta acción no se puede deshacer. Se eliminarán todos los archivos y multimedia recibidos y enviados. Las imágenes de baja resolución permanecerán.";
@ -2274,6 +2364,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To record voice message please grant permission to use Microphone." = "Para grabar el mensaje de voz concede permiso para usar el micrófono."; "To record voice message please grant permission to use Microphone." = "Para grabar el mensaje de voz concede permiso para usar el micrófono.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Para hacer visible tu perfil oculto, introduce la contraseña completa en el campo de búsqueda de la página **Tus perfiles Chat**.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Para permitir las notificaciones automáticas instantáneas, la base de datos se debe migrar."; "To support instant push notifications the chat database has to be migrated." = "Para permitir las notificaciones automáticas instantáneas, la base de datos se debe migrar.";
@ -2307,6 +2400,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unexpected migration state" = "Estado de migración inesperado"; "Unexpected migration state" = "Estado de migración inesperado";
/* No comment provided by engineer. */
"Unhide" = "Mostrar";
/* connection info */ /* connection info */
"unknown" = "desconocido"; "unknown" = "desconocido";
@ -2404,10 +2500,10 @@
"via group link" = "mediante enlace de grupo"; "via group link" = "mediante enlace de grupo";
/* chat list item description */ /* chat list item description */
"via one-time link" = "mediante enlace único"; "via one-time link" = "mediante enlace de un uso";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"via relay" = "mediante servidor de retransmisión"; "via relay" = "mediante servidor relay";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Video call" = "Videollamada"; "Video call" = "Videollamada";
@ -2511,6 +2607,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "También puedes conectarte haciendo clic en el enlace. Si se abre en el navegador, haz clic en el botón **Abrir en aplicación móvil**."; "You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "También puedes conectarte haciendo clic en el enlace. Si se abre en el navegador, haz clic en el botón **Abrir en aplicación móvil**.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right.\nSimpleX Lock must be enabled." = "Puedes ocultar o silenciar un perfil de usuario: deslízalo hacia la derecha.\nSimpleX Lock debe estar activado.";
/* notification body */ /* notification body */
"You can now send messages to %@" = "Ya puedes enviar mensajes a %@"; "You can now send messages to %@" = "Ya puedes enviar mensajes a %@";
@ -2584,10 +2683,10 @@
"You sent group invitation" = "Has enviado una invitación de grupo"; "You sent group invitation" = "Has enviado una invitación de grupo";
/* chat list item description */ /* chat list item description */
"you shared one-time link" = "has compartido un enlace único"; "you shared one-time link" = "has compartido un enlace de un uso";
/* chat list item description */ /* chat list item description */
"you shared one-time link incognito" = "has compartido un enlace único en módo incógnito"; "you shared one-time link incognito" = "has compartido enlace de un uso en modo incógnito";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will be connected to group when the group host's device is online, please wait or check later!" = "Te conectarás al grupo cuando el dispositivo del anfitrión esté en línea, por favor espera o compruébalo más tarde."; "You will be connected to group when the group host's device is online, please wait or check later!" = "Te conectarás al grupo cuando el dispositivo del anfitrión esté en línea, por favor espera o compruébalo más tarde.";
@ -2604,6 +2703,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will join a group this link refers to and connect to its group members." = "Te unirás al grupo al que hace referencia este enlace y te conectarás con sus miembros."; "You will join a group this link refers to and connect to its group members." = "Te unirás al grupo al que hace referencia este enlace y te conectarás con sus miembros.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Seguirás recibiendo llamadas y notificaciones de los perfiles silenciados cuando estén activos.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will stop receiving messages from this group. Chat history will be preserved." = "Dejarás de recibir mensajes de este grupo. El historial del chat se conservará."; "You will stop receiving messages from this group. Chat history will be preserved." = "Dejarás de recibir mensajes de este grupo. El historial del chat se conservará.";

View file

@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "Ajouter à un autre appareil"; "Add to another device" = "Ajouter à un autre appareil";
/* No comment provided by engineer. */
"Add welcome message" = "Ajouter un message d'accueil";
/* member role */ /* member role */
"admin" = "admin"; "admin" = "admin";
@ -338,6 +341,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "Appels audio et vidéo"; "Audio & video calls" = "Appels audio et vidéo";
/* No comment provided by engineer. */
"Audio and video calls" = "Appels audio et vidéo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "appel audio (sans chiffrement)"; "audio call (not e2e encrypted)" = "appel audio (sans chiffrement)";
@ -398,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "Appels"; "Calls" = "Appels";
/* No comment provided by engineer. */
"Can't delete user profile!" = "Impossible de supprimer le profil d'utilisateur !";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "Impossible d'inviter le contact!"; "Can't invite contact!" = "Impossible d'inviter le contact!";
@ -479,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "Vérifiez l'adresse du serveur et réessayez."; "Check server address and try again." = "Vérifiez l'adresse du serveur et réessayez.";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "Interface en chinois et en espagnol";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "Choisir le fichier"; "Choose file" = "Choisir le fichier";
@ -518,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "Confirmer la nouvelle phrase secrète…"; "Confirm new passphrase…" = "Confirmer la nouvelle phrase secrète…";
/* No comment provided by engineer. */
"Confirm password" = "Confirmer le mot de passe";
/* server test step */ /* server test step */
"Connect" = "Se connecter"; "Connect" = "Se connecter";
@ -884,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "N'utilisez PAS SimpleX pour les appels d'urgence."; "Do NOT use SimpleX for emergency calls." = "N'utilisez PAS SimpleX pour les appels d'urgence.";
/* No comment provided by engineer. */
"Don't show again" = "Ne plus afficher";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "Nom d'affichage en double !"; "Duplicate display name!" = "Nom d'affichage en double !";
@ -965,6 +983,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter passphrase…" = "Entrez la phrase secrète…"; "Enter passphrase…" = "Entrez la phrase secrète…";
/* No comment provided by engineer. */
"Enter password above to show!" = "Entrez le mot de passe ci-dessus pour continuer !";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter server manually" = "Entrer un serveur manuellement"; "Enter server manually" = "Entrer un serveur manuellement";
@ -1061,6 +1082,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "Erreur lors de la sauvegarde des serveurs SMP"; "Error saving SMP servers" = "Erreur lors de la sauvegarde des serveurs SMP";
/* No comment provided by engineer. */
"Error saving user password" = "Erreur d'enregistrement du mot de passe de l'utilisateur";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "Erreur lors de l'envoi du message"; "Error sending message" = "Erreur lors de l'envoi du message";
@ -1082,6 +1106,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "Erreur lors de la mise à jour des paramètres"; "Error updating settings" = "Erreur lors de la mise à jour des paramètres";
/* No comment provided by engineer. */
"Error updating user privacy" = "Erreur de mise à jour de la confidentialité de l'utilisateur";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "Erreur: %@"; "Error: %@" = "Erreur: %@";
@ -1133,6 +1160,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "Nom complet :"; "Full name:" = "Nom complet :";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Entièrement réimplémenté - fonctionne en arrière-plan !";
/* No comment provided by engineer. */
"Further reduced battery usage" = "Réduction accrue de l'utilisation de la batterie";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "GIFs et stickers"; "GIFs and stickers" = "GIFs et stickers";
@ -1181,6 +1214,9 @@
/* notification */ /* notification */
"Group message:" = "Message du groupe:"; "Group message:" = "Message du groupe:";
/* No comment provided by engineer. */
"Group moderation" = "Modération de groupe";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "Préférences du groupe"; "Group preferences" = "Préférences du groupe";
@ -1193,6 +1229,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "mise à jour du profil de groupe"; "group profile updated" = "mise à jour du profil de groupe";
/* No comment provided by engineer. */
"Group welcome message" = "Message d'accueil du groupe";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "Le groupe va être supprimé pour tout les membres - impossible de revenir en arrière!"; "Group will be deleted for all members - this cannot be undone!" = "Le groupe va être supprimé pour tout les membres - impossible de revenir en arrière!";
@ -1205,12 +1244,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "Caché"; "Hidden" = "Caché";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Profils de chat cachés";
/* No comment provided by engineer. */
"Hidden profile password" = "Mot de passe de profil caché";
/* chat item action */ /* chat item action */
"Hide" = "Cacher"; "Hide" = "Cacher";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "Masquer l'écran de l'app dans les apps récentes."; "Hide app screen in the recent apps." = "Masquer l'écran de l'app dans les apps récentes.";
/* No comment provided by engineer. */
"Hide profile" = "Masquer le profil";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "Comment ça fonctionne"; "How it works" = "Comment ça fonctionne";
@ -1298,6 +1346,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "indirect (%d)"; "indirect (%d)" = "indirect (%d)";
/* No comment provided by engineer. */
"Initial role" = "Rôle initial";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installer [SimpleX Chat pour terminal](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installer [SimpleX Chat pour terminal](https://github.com/simplex-chat/simplex-chat)";
@ -1436,6 +1487,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "Établir une connexion privée"; "Make a private connection" = "Établir une connexion privée";
/* No comment provided by engineer. */
"Make profile private!" = "Rendre le profil privé !";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Assurez-vous que les adresses des serveurs SMP sont au bon format et ne sont pas dupliquées, un par ligne."; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Assurez-vous que les adresses des serveurs SMP sont au bon format et ne sont pas dupliquées, un par ligne.";
@ -1532,6 +1586,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "Muet"; "Mute" = "Muet";
/* No comment provided by engineer. */
"Muted when inactive!" = "Mute en cas d'inactivité !";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "Nom"; "Name" = "Nom";
@ -1604,6 +1661,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "Les notifications sont désactivées!"; "Notifications are disabled!" = "Les notifications sont désactivées!";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Désormais, les administrateurs peuvent :\n- supprimer les messages des membres.\n- désactiver des membres (rôle \"observateur\")";
/* member role */ /* member role */
"observer" = "observateur"; "observer" = "observateur";
@ -1695,6 +1755,9 @@
/* member role */ /* member role */
"owner" = "propriétaire"; "owner" = "propriétaire";
/* No comment provided by engineer. */
"Password to show" = "Mot de passe à afficher";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "Coller"; "Paste" = "Coller";
@ -1794,6 +1857,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "Protéger l'écran de l'app"; "Protect app screen" = "Protéger l'écran de l'app";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "Protégez vos profils de chat par un mot de passe !";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "Délai du protocole"; "Protocol timeout" = "Délai du protocole";
@ -1926,6 +1992,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "Sauvegarder et en informer les membres du groupe"; "Save and notify group members" = "Sauvegarder et en informer les membres du groupe";
/* No comment provided by engineer. */
"Save and update group profile" = "Sauvegarder et mettre à jour le profil du groupe";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "Sauvegarder l'archive"; "Save archive" = "Sauvegarder l'archive";
@ -1941,9 +2010,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "Sauvegarder les préférences ?"; "Save preferences?" = "Sauvegarder les préférences ?";
/* No comment provided by engineer. */
"Save profile password" = "Enregistrer le mot de passe du profil";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "Sauvegarder les serveurs"; "Save servers" = "Sauvegarder les serveurs";
/* No comment provided by engineer. */
"Save servers?" = "Sauvegarder les serveurs ?";
/* No comment provided by engineer. */
"Save welcome message?" = "Sauvegarder le message d'accueil ?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "Les serveurs WebRTC ICE sauvegardés seront supprimés"; "Saved WebRTC ICE servers will be removed" = "Les serveurs WebRTC ICE sauvegardés seront supprimés";
@ -2040,6 +2118,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "Définir la phrase secrète pour l'export"; "Set passphrase to export" = "Définir la phrase secrète pour l'export";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "Choisissez un message à l'attention des nouveaux membres !";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "Définir les délais pour le proxy/VPN"; "Set timeouts for proxy/VPN" = "Définir les délais pour le proxy/VPN";
@ -2145,6 +2226,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "Appuyez sur le bouton "; "Tap button " = "Appuyez sur le bouton ";
/* No comment provided by engineer. */
"Tap to activate profile." = "Appuyez pour activer le profil.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "Appuyez pour rejoindre"; "Tap to join" = "Appuyez pour rejoindre";
@ -2232,6 +2316,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "Thème"; "Theme" = "Thème";
/* No comment provided by engineer. */
"There should be at least one user profile." = "Il doit y avoir au moins un profil d'utilisateur.";
/* No comment provided by engineer. */
"There should be at least one visible user profile." = "Il doit y avoir au moins un profil d'utilisateur visible.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Cette action ne peut être annulée - tous les fichiers et médias reçus et envoyés seront supprimés. Les photos à faible résolution seront conservées."; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Cette action ne peut être annulée - tous les fichiers et médias reçus et envoyés seront supprimés. Les photos à faible résolution seront conservées.";
@ -2274,6 +2364,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To record voice message please grant permission to use Microphone." = "Pour enregistrer un message vocal, veuillez accorder la permission d'utiliser le microphone."; "To record voice message please grant permission to use Microphone." = "Pour enregistrer un message vocal, veuillez accorder la permission d'utiliser le microphone.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Pour révéler votre profil caché, entrez un mot de passe complet dans le champ de recherche de la page **Vos profils de chat**.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Pour prendre en charge les notifications push instantanées, la base de données du chat doit être migrée."; "To support instant push notifications the chat database has to be migrated." = "Pour prendre en charge les notifications push instantanées, la base de données du chat doit être migrée.";
@ -2307,6 +2400,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unexpected migration state" = "État de la migration inattendu"; "Unexpected migration state" = "État de la migration inattendu";
/* No comment provided by engineer. */
"Unhide" = "Dévoiler";
/* connection info */ /* connection info */
"unknown" = "inconnu"; "unknown" = "inconnu";
@ -2511,6 +2607,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Vous pouvez également vous connecter en cliquant sur le lien. S'il s'ouvre dans le navigateur, cliquez sur le bouton **Open in mobile app**."; "You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Vous pouvez également vous connecter en cliquant sur le lien. S'il s'ouvre dans le navigateur, cliquez sur le bouton **Open in mobile app**.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right.\nSimpleX Lock must be enabled." = "Vous pouvez masquer ou mettre en sourdine un profil d'utilisateur - faites-le glisser vers la droite.\nSimpleX Lock doit être activé.";
/* notification body */ /* notification body */
"You can now send messages to %@" = "Vous pouvez maintenant envoyer des messages à %@"; "You can now send messages to %@" = "Vous pouvez maintenant envoyer des messages à %@";
@ -2604,6 +2703,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will join a group this link refers to and connect to its group members." = "Vous allez rejoindre le groupe correspondant à ce lien et être mis en relation avec les autres membres du groupe."; "You will join a group this link refers to and connect to its group members." = "Vous allez rejoindre le groupe correspondant à ce lien et être mis en relation avec les autres membres du groupe.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Vous continuerez à recevoir des appels et des notifications des profils mis en sourdine lorsqu'ils sont actifs.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will stop receiving messages from this group. Chat history will be preserved." = "Vous ne recevrez plus de messages de ce groupe. L'historique du chat sera conservé."; "You will stop receiving messages from this group. Chat history will be preserved." = "Vous ne recevrez plus de messages de ce groupe. L'historique du chat sera conservé.";

View file

@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "Aggiungi ad un altro dispositivo"; "Add to another device" = "Aggiungi ad un altro dispositivo";
/* No comment provided by engineer. */
"Add welcome message" = "Aggiungi messaggio di benvenuto";
/* member role */ /* member role */
"admin" = "amministratore"; "admin" = "amministratore";
@ -338,6 +341,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "Chiamate audio e video"; "Audio & video calls" = "Chiamate audio e video";
/* No comment provided by engineer. */
"Audio and video calls" = "Chiamate audio e video";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "chiamata audio (non crittografata e2e)"; "audio call (not e2e encrypted)" = "chiamata audio (non crittografata e2e)";
@ -398,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "Chiamate"; "Calls" = "Chiamate";
/* No comment provided by engineer. */
"Can't delete user profile!" = "Impossibile eliminare il profilo utente!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "Impossibile invitare il contatto!"; "Can't invite contact!" = "Impossibile invitare il contatto!";
@ -479,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "Controlla l'indirizzo del server e riprova."; "Check server address and try again." = "Controlla l'indirizzo del server e riprova.";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "Interfaccia cinese e spagnola";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "Scegli file"; "Choose file" = "Scegli file";
@ -518,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "Conferma password nuova…"; "Confirm new passphrase…" = "Conferma password nuova…";
/* No comment provided by engineer. */
"Confirm password" = "Conferma password";
/* server test step */ /* server test step */
"Connect" = "Connetti"; "Connect" = "Connetti";
@ -884,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "NON usare SimpleX per chiamate di emergenza."; "Do NOT use SimpleX for emergency calls." = "NON usare SimpleX per chiamate di emergenza.";
/* No comment provided by engineer. */
"Don't show again" = "Non mostrare più";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "Nome da mostrare doppio!"; "Duplicate display name!" = "Nome da mostrare doppio!";
@ -965,6 +983,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter passphrase…" = "Inserisci la password…"; "Enter passphrase…" = "Inserisci la password…";
/* No comment provided by engineer. */
"Enter password above to show!" = "Inserisci la password sopra per mostrare!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter server manually" = "Inserisci il server a mano"; "Enter server manually" = "Inserisci il server a mano";
@ -1061,6 +1082,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "Errore nel salvataggio dei server SMP"; "Error saving SMP servers" = "Errore nel salvataggio dei server SMP";
/* No comment provided by engineer. */
"Error saving user password" = "Errore nel salvataggio della password utente";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "Errore nell'invio del messaggio"; "Error sending message" = "Errore nell'invio del messaggio";
@ -1082,6 +1106,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "Errore nell'aggiornamento delle impostazioni"; "Error updating settings" = "Errore nell'aggiornamento delle impostazioni";
/* No comment provided by engineer. */
"Error updating user privacy" = "Errore nell'aggiornamento della privacy dell'utente";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "Errore: %@"; "Error: %@" = "Errore: %@";
@ -1133,6 +1160,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "Nome completo:"; "Full name:" = "Nome completo:";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Completamente reimplementato - funziona in secondo piano!";
/* No comment provided by engineer. */
"Further reduced battery usage" = "Ulteriore riduzione del consumo della batteria";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "GIF e adesivi"; "GIFs and stickers" = "GIF e adesivi";
@ -1181,6 +1214,9 @@
/* notification */ /* notification */
"Group message:" = "Messaggio del gruppo:"; "Group message:" = "Messaggio del gruppo:";
/* No comment provided by engineer. */
"Group moderation" = "Moderazione del gruppo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "Preferenze del gruppo"; "Group preferences" = "Preferenze del gruppo";
@ -1193,6 +1229,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "profilo del gruppo aggiornato"; "group profile updated" = "profilo del gruppo aggiornato";
/* No comment provided by engineer. */
"Group welcome message" = "Messaggio di benvenuto del gruppo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "Il gruppo verrà eliminato per tutti i membri. Non è reversibile!"; "Group will be deleted for all members - this cannot be undone!" = "Il gruppo verrà eliminato per tutti i membri. Non è reversibile!";
@ -1205,12 +1244,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "Nascosta"; "Hidden" = "Nascosta";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Profili di chat nascosti";
/* No comment provided by engineer. */
"Hidden profile password" = "Password del profilo nascosta";
/* chat item action */ /* chat item action */
"Hide" = "Nascondi"; "Hide" = "Nascondi";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "Nascondi la schermata dell'app nelle app recenti."; "Hide app screen in the recent apps." = "Nascondi la schermata dell'app nelle app recenti.";
/* No comment provided by engineer. */
"Hide profile" = "Nascondi il profilo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "Come funziona"; "How it works" = "Come funziona";
@ -1298,6 +1346,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "indiretta (%d)"; "indirect (%d)" = "indiretta (%d)";
/* No comment provided by engineer. */
"Initial role" = "Ruolo iniziale";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installa [Simplex Chat per terminale](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installa [Simplex Chat per terminale](https://github.com/simplex-chat/simplex-chat)";
@ -1436,6 +1487,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "Crea una connessione privata"; "Make a private connection" = "Crea una connessione privata";
/* No comment provided by engineer. */
"Make profile private!" = "Rendi privato il profilo!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Assicurati che gli indirizzi dei server SMP siano nel formato corretto, uno per riga e non doppi (%@)."; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Assicurati che gli indirizzi dei server SMP siano nel formato corretto, uno per riga e non doppi (%@).";
@ -1532,6 +1586,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "Silenzia"; "Mute" = "Silenzia";
/* No comment provided by engineer. */
"Muted when inactive!" = "Silenzioso quando inattivo!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "Nome"; "Name" = "Nome";
@ -1604,6 +1661,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "Le notifiche sono disattivate!"; "Notifications are disabled!" = "Le notifiche sono disattivate!";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Ora gli amministratori possono:\n- eliminare i messaggi dei membri.\n- disattivare i membri (ruolo \"osservatore\")";
/* member role */ /* member role */
"observer" = "osservatore"; "observer" = "osservatore";
@ -1695,6 +1755,9 @@
/* member role */ /* member role */
"owner" = "proprietario"; "owner" = "proprietario";
/* No comment provided by engineer. */
"Password to show" = "Password per mostrare";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "Incolla"; "Paste" = "Incolla";
@ -1794,6 +1857,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "Proteggi la schermata dell'app"; "Protect app screen" = "Proteggi la schermata dell'app";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "Proteggi i tuoi profili di chat con una password!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "Scadenza del protocollo"; "Protocol timeout" = "Scadenza del protocollo";
@ -1926,6 +1992,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "Salva e avvisa i membri del gruppo"; "Save and notify group members" = "Salva e avvisa i membri del gruppo";
/* No comment provided by engineer. */
"Save and update group profile" = "Salva e aggiorna il profilo del gruppo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "Salva archivio"; "Save archive" = "Salva archivio";
@ -1941,9 +2010,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "Salvare le preferenze?"; "Save preferences?" = "Salvare le preferenze?";
/* No comment provided by engineer. */
"Save profile password" = "Salva la password del profilo";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "Salva i server"; "Save servers" = "Salva i server";
/* No comment provided by engineer. */
"Save servers?" = "Salvare i server?";
/* No comment provided by engineer. */
"Save welcome message?" = "Salvare il messaggio di benvenuto?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "I server WebRTC ICE salvati verranno rimossi"; "Saved WebRTC ICE servers will be removed" = "I server WebRTC ICE salvati verranno rimossi";
@ -2040,6 +2118,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "Imposta la password per esportare"; "Set passphrase to export" = "Imposta la password per esportare";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "Imposta il messaggio mostrato ai nuovi membri!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "Imposta scadenze per proxy/VPN"; "Set timeouts for proxy/VPN" = "Imposta scadenze per proxy/VPN";
@ -2145,6 +2226,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "Tocca il pulsante "; "Tap button " = "Tocca il pulsante ";
/* No comment provided by engineer. */
"Tap to activate profile." = "Tocca per attivare il profilo.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "Tocca per entrare"; "Tap to join" = "Tocca per entrare";
@ -2232,6 +2316,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "Tema"; "Theme" = "Tema";
/* No comment provided by engineer. */
"There should be at least one user profile." = "Deve esserci almeno un profilo utente.";
/* No comment provided by engineer. */
"There should be at least one visible user profile." = "Deve esserci almeno un profilo utente visibile.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Questa azione non può essere annullata: tutti i file e i media ricevuti e inviati verranno eliminati. Rimarranno le immagini a bassa risoluzione."; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Questa azione non può essere annullata: tutti i file e i media ricevuti e inviati verranno eliminati. Rimarranno le immagini a bassa risoluzione.";
@ -2274,6 +2364,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To record voice message please grant permission to use Microphone." = "Per registrare un messaggio vocale, concedi l'autorizzazione all'uso del microfono."; "To record voice message please grant permission to use Microphone." = "Per registrare un messaggio vocale, concedi l'autorizzazione all'uso del microfono.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Per rivelare il tuo profilo nascosto, inserisci una password completa in un campo di ricerca nella pagina **I tuoi profili di chat**.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Per supportare le notifiche push istantanee, il database della chat deve essere migrato."; "To support instant push notifications the chat database has to be migrated." = "Per supportare le notifiche push istantanee, il database della chat deve essere migrato.";
@ -2307,6 +2400,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unexpected migration state" = "Stato di migrazione imprevisto"; "Unexpected migration state" = "Stato di migrazione imprevisto";
/* No comment provided by engineer. */
"Unhide" = "Svela";
/* connection info */ /* connection info */
"unknown" = "sconosciuto"; "unknown" = "sconosciuto";
@ -2511,6 +2607,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Puoi anche connetterti cliccando il link. Se si apre nel browser, clicca il pulsante **Apri nell'app mobile**."; "You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Puoi anche connetterti cliccando il link. Se si apre nel browser, clicca il pulsante **Apri nell'app mobile**.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right.\nSimpleX Lock must be enabled." = "Puoi nascondere o silenziare un profilo utente - scorrilo verso destra.\nSimpleX Lock deve essere attivato.";
/* notification body */ /* notification body */
"You can now send messages to %@" = "Ora puoi inviare messaggi a %@"; "You can now send messages to %@" = "Ora puoi inviare messaggi a %@";
@ -2604,6 +2703,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will join a group this link refers to and connect to its group members." = "Entrerai in un gruppo a cui si riferisce questo link e ti connetterai ai suoi membri."; "You will join a group this link refers to and connect to its group members." = "Entrerai in un gruppo a cui si riferisce questo link e ti connetterai ai suoi membri.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Continuerai a ricevere chiamate e notifiche da profili silenziati quando sono attivi.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will stop receiving messages from this group. Chat history will be preserved." = "Non riceverai più messaggi da questo gruppo. La cronologia della chat verrà conservata."; "You will stop receiving messages from this group. Chat history will be preserved." = "Non riceverai più messaggi da questo gruppo. La cronologia della chat verrà conservata.";

View file

@ -209,7 +209,7 @@
"About SimpleX Chat" = "Over SimpleX Chat"; "About SimpleX Chat" = "Over SimpleX Chat";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"above, then choose:" = "hierboven, kies dan:"; "above, then choose:" = "hier boven, kies dan:";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Accent color" = "Accent kleur"; "Accent color" = "Accent kleur";
@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "Toevoegen aan een ander apparaat"; "Add to another device" = "Toevoegen aan een ander apparaat";
/* No comment provided by engineer. */
"Add welcome message" = "Welkomst bericht toevoegen";
/* member role */ /* member role */
"admin" = "Beheerder"; "admin" = "Beheerder";
@ -338,6 +341,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "Audio en video gesprekken"; "Audio & video calls" = "Audio en video gesprekken";
/* No comment provided by engineer. */
"Audio and video calls" = "Audio en video oproepen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "audio oproep (niet e2e versleuteld)"; "audio call (not e2e encrypted)" = "audio oproep (niet e2e versleuteld)";
@ -398,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "Oproepen"; "Calls" = "Oproepen";
/* No comment provided by engineer. */
"Can't delete user profile!" = "Kan gebruikers profiel niet verwijderen!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "Kan contact niet uitnodigen!"; "Can't invite contact!" = "Kan contact niet uitnodigen!";
@ -479,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "Controleer het server adres en probeer het opnieuw."; "Check server address and try again." = "Controleer het server adres en probeer het opnieuw.";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "Chinese en Spaanse interface";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "Kies bestand"; "Choose file" = "Kies bestand";
@ -518,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "Bevestig nieuw wachtwoord…"; "Confirm new passphrase…" = "Bevestig nieuw wachtwoord…";
/* No comment provided by engineer. */
"Confirm password" = "Bevestig wachtwoord";
/* server test step */ /* server test step */
"Connect" = "Verbind"; "Connect" = "Verbind";
@ -819,7 +834,7 @@
"Delete queue" = "Wachtrij verwijderen"; "Delete queue" = "Wachtrij verwijderen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Delete user profile?" = "Gebruikersprofiel verwijderen?"; "Delete user profile?" = "Gebruikers profiel verwijderen?";
/* deleted chat item */ /* deleted chat item */
"deleted" = "verwijderd"; "deleted" = "verwijderd";
@ -884,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "Gebruik SimpleX NIET voor noodoproepen."; "Do NOT use SimpleX for emergency calls." = "Gebruik SimpleX NIET voor noodoproepen.";
/* No comment provided by engineer. */
"Don't show again" = "Niet meer weergeven";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "Dubbele weergavenaam!"; "Duplicate display name!" = "Dubbele weergavenaam!";
@ -965,6 +983,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter passphrase…" = "Voer wachtwoord in…"; "Enter passphrase…" = "Voer wachtwoord in…";
/* No comment provided by engineer. */
"Enter password above to show!" = "Voer hier boven het wachtwoord in om weer te geven!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter server manually" = "Voer de server handmatig in"; "Enter server manually" = "Voer de server handmatig in";
@ -1061,6 +1082,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "Fout bij opslaan van SMP servers"; "Error saving SMP servers" = "Fout bij opslaan van SMP servers";
/* No comment provided by engineer. */
"Error saving user password" = "Fout bij opslaan gebruikers wachtwoord";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "Fout bij verzenden van bericht"; "Error sending message" = "Fout bij verzenden van bericht";
@ -1082,6 +1106,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "Fout bij bijwerken van instellingen"; "Error updating settings" = "Fout bij bijwerken van instellingen";
/* No comment provided by engineer. */
"Error updating user privacy" = "Fout bij updaten van gebruikers privacy";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "Fout: %@"; "Error: %@" = "Fout: %@";
@ -1133,6 +1160,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "Volledige naam:"; "Full name:" = "Volledige naam:";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Volledig opnieuw geïmplementeerd - werk op de achtergrond!";
/* No comment provided by engineer. */
"Further reduced battery usage" = "Verder verminderd batterij verbruik";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "GIF's en stickers"; "GIFs and stickers" = "GIF's en stickers";
@ -1181,6 +1214,9 @@
/* notification */ /* notification */
"Group message:" = "Groep bericht:"; "Group message:" = "Groep bericht:";
/* No comment provided by engineer. */
"Group moderation" = "Groep moderatie";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "Groep voorkeuren"; "Group preferences" = "Groep voorkeuren";
@ -1193,6 +1229,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "groep profiel bijgewerkt"; "group profile updated" = "groep profiel bijgewerkt";
/* No comment provided by engineer. */
"Group welcome message" = "Groep welkomst bericht";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "Groep wordt verwijderd voor alle leden, dit kan niet ongedaan worden gemaakt!"; "Group will be deleted for all members - this cannot be undone!" = "Groep wordt verwijderd voor alle leden, dit kan niet ongedaan worden gemaakt!";
@ -1205,12 +1244,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "Verborgen"; "Hidden" = "Verborgen";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Verborgen chat profielen";
/* No comment provided by engineer. */
"Hidden profile password" = "Verborgen profiel wachtwoord";
/* chat item action */ /* chat item action */
"Hide" = "Verbergen"; "Hide" = "Verbergen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "App scherm verbergen in de recente apps."; "Hide app screen in the recent apps." = "App scherm verbergen in de recente apps.";
/* No comment provided by engineer. */
"Hide profile" = "Profiel verbergen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "Hoe het werkt"; "How it works" = "Hoe het werkt";
@ -1298,6 +1346,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "indirect (%d)"; "indirect (%d)" = "indirect (%d)";
/* No comment provided by engineer. */
"Initial role" = "Initiële rol";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installeer [SimpleX Chat voor terminal](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installeer [SimpleX Chat voor terminal](https://github.com/simplex-chat/simplex-chat)";
@ -1436,6 +1487,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "Maak een privéverbinding"; "Make a private connection" = "Maak een privéverbinding";
/* No comment provided by engineer. */
"Make profile private!" = "Profiel privé maken!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Zorg ervoor dat SMP server adressen de juiste indeling hebben, regel gescheiden zijn en niet gedupliceerd zijn (%@)."; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Zorg ervoor dat SMP server adressen de juiste indeling hebben, regel gescheiden zijn en niet gedupliceerd zijn (%@).";
@ -1532,6 +1586,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "Dempen"; "Mute" = "Dempen";
/* No comment provided by engineer. */
"Muted when inactive!" = "Gedempt wanneer inactief!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "Naam"; "Name" = "Naam";
@ -1604,8 +1661,11 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "Meldingen zijn uitgeschakeld!"; "Notifications are disabled!" = "Meldingen zijn uitgeschakeld!";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Nu kunnen beheerders: \n- berichten van leden verwijderen.\n- schakel leden uit (\"waarnemer\" rol)";
/* member role */ /* member role */
"observer" = "waarnemer"; "observer" = "Waarnemer";
/* enabled status /* enabled status
group pref value */ group pref value */
@ -1645,7 +1705,7 @@
"Onion hosts will not be used." = "Onion hosts worden niet gebruikt."; "Onion hosts will not be used." = "Onion hosts worden niet gebruikt.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Alleen client apparaten slaan gebruikersprofielen, contacten, groepen en berichten op die zijn verzonden met **2-laags end-to-end-codering**."; "Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Alleen client apparaten slaan gebruikers profielen, contacten, groepen en berichten op die zijn verzonden met **2-laags end-to-end-codering**.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Only group owners can change group preferences." = "Alleen groep eigenaren kunnen groep voorkeuren wijzigen."; "Only group owners can change group preferences." = "Alleen groep eigenaren kunnen groep voorkeuren wijzigen.";
@ -1681,7 +1741,7 @@
"Open Settings" = "Open instellingen"; "Open Settings" = "Open instellingen";
/* authentication reason */ /* authentication reason */
"Open user profiles" = "Gebruikersprofielen openen"; "Open user profiles" = "Gebruikers profielen openen";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Open-source protocol and code anybody can run the servers." = "Open-source protocol en code. Iedereen kan de servers draaien."; "Open-source protocol and code anybody can run the servers." = "Open-source protocol en code. Iedereen kan de servers draaien.";
@ -1693,7 +1753,10 @@
"or chat with the developers" = "of praat met de ontwikkelaars"; "or chat with the developers" = "of praat met de ontwikkelaars";
/* member role */ /* member role */
"owner" = "eigenaar"; "owner" = "Eigenaar";
/* No comment provided by engineer. */
"Password to show" = "Wachtwoord om weer te geven";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "Plakken"; "Paste" = "Plakken";
@ -1794,6 +1857,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "App scherm verbergen"; "Protect app screen" = "App scherm verbergen";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "Bescherm je chat profielen met een wachtwoord!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "Protocol timeout"; "Protocol timeout" = "Protocol timeout";
@ -1926,6 +1992,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "Opslaan en Groep leden melden"; "Save and notify group members" = "Opslaan en Groep leden melden";
/* No comment provided by engineer. */
"Save and update group profile" = "Groep profiel opslaan en bijwerken";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "Bewaar archief"; "Save archive" = "Bewaar archief";
@ -1941,9 +2010,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "Voorkeuren opslaan?"; "Save preferences?" = "Voorkeuren opslaan?";
/* No comment provided by engineer. */
"Save profile password" = "Bewaar profiel wachtwoord";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "Bewaar servers"; "Save servers" = "Bewaar servers";
/* No comment provided by engineer. */
"Save servers?" = "Servers opslaan?";
/* No comment provided by engineer. */
"Save welcome message?" = "Welkomst bericht opslaan?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "Opgeslagen WebRTC ICE servers worden verwijderd"; "Saved WebRTC ICE servers will be removed" = "Opgeslagen WebRTC ICE servers worden verwijderd";
@ -2040,6 +2118,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "Wachtwoord instellen om te exporteren"; "Set passphrase to export" = "Wachtwoord instellen om te exporteren";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "Stel het getoonde bericht in voor nieuwe leden!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "Stel timeouts in voor proxy/VPN"; "Set timeouts for proxy/VPN" = "Stel timeouts in voor proxy/VPN";
@ -2145,6 +2226,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "Tik op de knop "; "Tap button " = "Tik op de knop ";
/* No comment provided by engineer. */
"Tap to activate profile." = "Tik om profiel te activeren.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "Tik om mee te doen"; "Tap to join" = "Tik om mee te doen";
@ -2232,6 +2316,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "Thema"; "Theme" = "Thema";
/* No comment provided by engineer. */
"There should be at least one user profile." = "Er moet ten minste één gebruikers profiel zijn.";
/* No comment provided by engineer. */
"There should be at least one visible user profile." = "Er moet ten minste één zichtbaar gebruikers profiel zijn.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Deze actie kan niet ongedaan worden gemaakt, alle ontvangen en verzonden bestanden en media worden verwijderd. Foto's met een lage resolutie blijven behouden."; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Deze actie kan niet ongedaan worden gemaakt, alle ontvangen en verzonden bestanden en media worden verwijderd. Foto's met een lage resolutie blijven behouden.";
@ -2274,6 +2364,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To record voice message please grant permission to use Microphone." = "Geef toestemming om de microfoon te gebruiken om een spraakbericht op te nemen."; "To record voice message please grant permission to use Microphone." = "Geef toestemming om de microfoon te gebruiken om een spraakbericht op te nemen.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoek veld in op de pagina **Uw chat profielen**.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Om directe push meldingen te ondersteunen, moet de chat database worden gemigreerd."; "To support instant push notifications the chat database has to be migrated." = "Om directe push meldingen te ondersteunen, moet de chat database worden gemigreerd.";
@ -2307,6 +2400,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unexpected migration state" = "Onverwachte migratiestatus"; "Unexpected migration state" = "Onverwachte migratiestatus";
/* No comment provided by engineer. */
"Unhide" = "zichtbaar maken";
/* connection info */ /* connection info */
"unknown" = "onbekend"; "unknown" = "onbekend";
@ -2377,7 +2473,7 @@
"Use SimpleX Chat servers?" = "SimpleX Chat servers gebruiken?"; "Use SimpleX Chat servers?" = "SimpleX Chat servers gebruiken?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"User profile" = "Gebruikersprofiel"; "User profile" = "Gebruikers profiel";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Using .onion hosts requires compatible VPN provider." = "Het gebruik van .onion-hosts vereist een compatibele VPN-provider."; "Using .onion hosts requires compatible VPN provider." = "Het gebruik van .onion-hosts vereist een compatibele VPN-provider.";
@ -2455,7 +2551,7 @@
"Welcome %@!" = "Welkom %@!"; "Welcome %@!" = "Welkom %@!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Welcome message" = "Welkoms bericht"; "Welcome message" = "Welkomst bericht";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"What's new" = "Wat is er nieuw"; "What's new" = "Wat is er nieuw";
@ -2467,7 +2563,7 @@
"When you share an incognito profile with somebody, this profile will be used for the groups they invite you to." = "Wanneer je een incognito profiel met iemand deelt, wordt dit profiel gebruikt voor de groepen waarvoor ze je uitnodigen."; "When you share an incognito profile with somebody, this profile will be used for the groups they invite you to." = "Wanneer je een incognito profiel met iemand deelt, wordt dit profiel gebruikt voor de groepen waarvoor ze je uitnodigen.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"With optional welcome message." = "Met optioneel welkomstbericht."; "With optional welcome message." = "Met optioneel welkomst bericht.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Wrong database passphrase" = "Verkeerd wachtwoord voor de database"; "Wrong database passphrase" = "Verkeerd wachtwoord voor de database";
@ -2511,6 +2607,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "U kunt ook verbinding maken door op de link te klikken. Als het in de browser wordt geopend, klikt u op de knop **Openen in mobiele app**."; "You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "U kunt ook verbinding maken door op de link te klikken. Als het in de browser wordt geopend, klikt u op de knop **Openen in mobiele app**.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right.\nSimpleX Lock must be enabled." = "U kunt een gebruikers profiel verbergen of dempen - veeg het naar rechts.\nSimpleX Lock moet ingeschakeld zijn.";
/* notification body */ /* notification body */
"You can now send messages to %@" = "Je kunt nu berichten sturen naar %@"; "You can now send messages to %@" = "Je kunt nu berichten sturen naar %@";
@ -2604,6 +2703,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will join a group this link refers to and connect to its group members." = "U wordt lid van een groep waarnaar deze link verwijst en maakt verbinding met de groepsleden."; "You will join a group this link refers to and connect to its group members." = "U wordt lid van een groep waarnaar deze link verwijst en maakt verbinding met de groepsleden.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "U ontvangt nog steeds oproepen en meldingen van gedempte profielen wanneer deze actief zijn.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will stop receiving messages from this group. Chat history will be preserved." = "Je ontvangt geen berichten meer van deze groep. Je gesprek geschiedenis blijft behouden."; "You will stop receiving messages from this group. Chat history will be preserved." = "Je ontvangt geen berichten meer van deze groep. Je gesprek geschiedenis blijft behouden.";

View file

@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "Добавить на другое устройство"; "Add to another device" = "Добавить на другое устройство";
/* No comment provided by engineer. */
"Add welcome message" = "Добавить приветственное сообщение";
/* member role */ /* member role */
"admin" = "админ"; "admin" = "админ";
@ -338,12 +341,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "Аудио- и видеозвонки"; "Audio & video calls" = "Аудио- и видеозвонки";
/* No comment provided by engineer. */
"Audio and video calls" = "Аудио и видео звонки";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "аудиозвонок (не e2e зашифрованный)"; "audio call (not e2e encrypted)" = "аудиозвонок (не e2e зашифрованный)";
/* No comment provided by engineer. */ /* 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. */ /* No comment provided by engineer. */
"Authentication unavailable" = "Аутентификация недоступна"; "Authentication unavailable" = "Аутентификация недоступна";
@ -395,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "Звонки"; "Calls" = "Звонки";
/* No comment provided by engineer. */
"Can't delete user profile!" = "Нельзя удалить профиль пользователя!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "Нельзя пригласить контакт!"; "Can't invite contact!" = "Нельзя пригласить контакт!";
@ -476,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "Проверьте адрес сервера и попробуйте снова."; "Check server address and try again." = "Проверьте адрес сервера и попробуйте снова.";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "Китайский и Испанский интерфейс";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "Выбрать файл"; "Choose file" = "Выбрать файл";
@ -515,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "Подтвердите новый пароль…"; "Confirm new passphrase…" = "Подтвердите новый пароль…";
/* No comment provided by engineer. */
"Confirm password" = "Подтвердить пароль";
/* server test step */ /* server test step */
"Connect" = "Соединиться"; "Connect" = "Соединиться";
@ -881,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "Не используйте SimpleX для экстренных звонков."; "Do NOT use SimpleX for emergency calls." = "Не используйте SimpleX для экстренных звонков.";
/* No comment provided by engineer. */
"Don't show again" = "Не показывать";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "Имя профиля уже используется!"; "Duplicate display name!" = "Имя профиля уже используется!";
@ -962,6 +983,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter passphrase…" = "Введите пароль…"; "Enter passphrase…" = "Введите пароль…";
/* No comment provided by engineer. */
"Enter password above to show!" = "Введите пароль выше, чтобы раскрыть!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter server manually" = "Ввести сервер вручную"; "Enter server manually" = "Ввести сервер вручную";
@ -1058,6 +1082,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "Ошибка при сохранении SMP серверов"; "Error saving SMP servers" = "Ошибка при сохранении SMP серверов";
/* No comment provided by engineer. */
"Error saving user password" = "Ошибка при сохранении пароля пользователя";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "Ошибка при отправке сообщения"; "Error sending message" = "Ошибка при отправке сообщения";
@ -1079,6 +1106,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "Ошибка при сохранении настроек сети"; "Error updating settings" = "Ошибка при сохранении настроек сети";
/* No comment provided by engineer. */
"Error updating user privacy" = "Ошибка при обновлении конфиденциальности";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "Ошибка: %@"; "Error: %@" = "Ошибка: %@";
@ -1130,6 +1160,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "Полное имя:"; "Full name:" = "Полное имя:";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Полностью обновлены - работают в фоне!";
/* No comment provided by engineer. */
"Further reduced battery usage" = "Уменьшенное потребление батареи";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "ГИФ файлы и стикеры"; "GIFs and stickers" = "ГИФ файлы и стикеры";
@ -1178,6 +1214,9 @@
/* notification */ /* notification */
"Group message:" = "Групповое сообщение:"; "Group message:" = "Групповое сообщение:";
/* No comment provided by engineer. */
"Group moderation" = "Модерация группы";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "Предпочтения группы"; "Group preferences" = "Предпочтения группы";
@ -1190,6 +1229,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "профиль группы обновлен"; "group profile updated" = "профиль группы обновлен";
/* No comment provided by engineer. */
"Group welcome message" = "Приветственное сообщение группы";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "Группа будет удалена для всех членов - это действие нельзя отменить!"; "Group will be deleted for all members - this cannot be undone!" = "Группа будет удалена для всех членов - это действие нельзя отменить!";
@ -1202,12 +1244,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "Скрытое"; "Hidden" = "Скрытое";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Скрытые профили чата";
/* No comment provided by engineer. */
"Hidden profile password" = "Пароль скрытого профиля";
/* chat item action */ /* chat item action */
"Hide" = "Спрятать"; "Hide" = "Спрятать";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "Скрыть экран приложения."; "Hide app screen in the recent apps." = "Скрыть экран приложения.";
/* No comment provided by engineer. */
"Hide profile" = "Скрыть профиль";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "Как это работает"; "How it works" = "Как это работает";
@ -1295,6 +1346,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "непрямое (%d)"; "indirect (%d)" = "непрямое (%d)";
/* No comment provided by engineer. */
"Initial role" = "Роль при вступлении";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "[SimpleX Chat для терминала](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "[SimpleX Chat для терминала](https://github.com/simplex-chat/simplex-chat)";
@ -1304,6 +1358,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Instantly" = "Мгновенно"; "Instantly" = "Мгновенно";
/* No comment provided by engineer. */
"Interface" = "Интерфейс";
/* invalid chat data */ /* invalid chat data */
"invalid chat" = "ошибка чата"; "invalid chat" = "ошибка чата";
@ -1430,6 +1487,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "Добавьте контакт"; "Make a private connection" = "Добавьте контакт";
/* No comment provided by engineer. */
"Make profile private!" = "Сделайте профиль скрытым!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Пожалуйста, проверьте, что адреса SMP серверов имеют правильный формат, каждый адрес на отдельной строке и не повторяется (%@)."; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "Пожалуйста, проверьте, что адреса SMP серверов имеют правильный формат, каждый адрес на отдельной строке и не повторяется (%@).";
@ -1526,6 +1586,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "Без звука"; "Mute" = "Без звука";
/* No comment provided by engineer. */
"Muted when inactive!" = "Без звука, когда не активный!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "Имя"; "Name" = "Имя";
@ -1598,6 +1661,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "Уведомления выключены"; "Notifications are disabled!" = "Уведомления выключены";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Теперь админы могут:\n- удалять сообщения членов.\n- приостанавливать членов (роль \"наблюдатель\")";
/* member role */ /* member role */
"observer" = "читатель"; "observer" = "читатель";
@ -1689,6 +1755,9 @@
/* member role */ /* member role */
"owner" = "владелец"; "owner" = "владелец";
/* No comment provided by engineer. */
"Password to show" = "Пароль чтобы раскрыть";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "Вставить"; "Paste" = "Вставить";
@ -1788,6 +1857,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "Защитить экран приложения"; "Protect app screen" = "Защитить экран приложения";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "Защитите ваши профили чата паролем!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "Таймаут протокола"; "Protocol timeout" = "Таймаут протокола";
@ -1920,6 +1992,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "Сохранить и уведомить членов группы"; "Save and notify group members" = "Сохранить и уведомить членов группы";
/* No comment provided by engineer. */
"Save and update group profile" = "Сохранить сообщение и обновить группу";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "Сохранить архив"; "Save archive" = "Сохранить архив";
@ -1935,9 +2010,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "Сохранить предпочтения?"; "Save preferences?" = "Сохранить предпочтения?";
/* No comment provided by engineer. */
"Save profile password" = "Сохранить пароль профиля";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "Сохранить серверы"; "Save servers" = "Сохранить серверы";
/* No comment provided by engineer. */
"Save servers?" = "Сохранить серверы?";
/* No comment provided by engineer. */
"Save welcome message?" = "Сохранить приветственное сообщение?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "Сохраненные WebRTC ICE серверы будут удалены"; "Saved WebRTC ICE servers will be removed" = "Сохраненные WebRTC ICE серверы будут удалены";
@ -2034,6 +2118,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "Установите пароль"; "Set passphrase to export" = "Установите пароль";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "Установить сообщение для новых членов группы!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "Установить таймауты для прокси/VPN"; "Set timeouts for proxy/VPN" = "Установить таймауты для прокси/VPN";
@ -2052,6 +2139,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Share one-time invitation link" = "Поделиться ссылкой-приглашением"; "Share one-time invitation link" = "Поделиться ссылкой-приглашением";
/* No comment provided by engineer. */
"Show calls in phone history" = "Показать звонки в истории телефона";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Show preview" = "Показывать уведомления"; "Show preview" = "Показывать уведомления";
@ -2136,6 +2226,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "Нажмите кнопку "; "Tap button " = "Нажмите кнопку ";
/* No comment provided by engineer. */
"Tap to activate profile." = "Нажмите, чтобы сделать профиль активным.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "Нажмите, чтобы вступить"; "Tap to join" = "Нажмите, чтобы вступить";
@ -2223,6 +2316,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "Тема"; "Theme" = "Тема";
/* No comment provided by engineer. */
"There should be at least one user profile." = "Должен быть хотя бы один профиль пользователя.";
/* No comment provided by engineer. */
"There should be at least one visible user profile." = "Должен быть хотя бы один открытый профиль пользователя.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Это действие нельзя отменить — все полученные и отправленные файлы будут удалены. Изображения останутся в низком разрешении."; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Это действие нельзя отменить — все полученные и отправленные файлы будут удалены. Изображения останутся в низком разрешении.";
@ -2265,6 +2364,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To record voice message please grant permission to use Microphone." = "Для записи голосового сообщения, пожалуйста разрешите доступ к микрофону."; "To record voice message please grant permission to use Microphone." = "Для записи голосового сообщения, пожалуйста разрешите доступ к микрофону.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Чтобы показать Ваш скрытый профиль, введите его пароль в поле поиска на странице **Ваши профили чата**.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Для поддержки мгновенный доставки уведомлений данные чата должны быть перемещены."; "To support instant push notifications the chat database has to be migrated." = "Для поддержки мгновенный доставки уведомлений данные чата должны быть перемещены.";
@ -2298,15 +2400,24 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unexpected migration state" = "Неожиданная ошибка при перемещении данных чата"; "Unexpected migration state" = "Неожиданная ошибка при перемещении данных чата";
/* No comment provided by engineer. */
"Unhide" = "Раскрыть";
/* connection info */ /* connection info */
"unknown" = "неизвестно"; "unknown" = "неизвестно";
/* callkit banner */
"Unknown caller" = "Неизвестный звонок";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unknown database error: %@" = "Неизвестная ошибка базы данных: %@"; "Unknown database error: %@" = "Неизвестная ошибка базы данных: %@";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unknown error" = "Неизвестная ошибка"; "Unknown error" = "Неизвестная ошибка";
/* No comment provided by engineer. */
"Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." = "Если вы не используете интерфейс iOS, включите режим Не отвлекать, чтобы звонок не прерывался.";
/* No comment provided by engineer. */ /* 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Чтобы установить соединение, попросите ваш контакт создать еще одну ссылку и проверьте ваше соединение с сетью."; "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Чтобы установить соединение, попросите ваш контакт создать еще одну ссылку и проверьте ваше соединение с сетью.";
@ -2352,6 +2463,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Use for new connections" = "Использовать для новых соединений"; "Use for new connections" = "Использовать для новых соединений";
/* No comment provided by engineer. */
"Use iOS call interface" = "Использовать интерфейс iOS для звонков";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Use server" = "Использовать сервер"; "Use server" = "Использовать сервер";
@ -2487,9 +2601,15 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"you are observer" = "только чтение сообщений"; "you are observer" = "только чтение сообщений";
/* No comment provided by engineer. */
"You can accept calls from lock screen, without device and app authentication." = "Вы можете принимать звонки на экране блокировки, без аутентификации.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Вы также можете соединиться, открыв ссылку. Если ссылка откроется в браузере, нажмите кнопку **Open in mobile app**."; "You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Вы также можете соединиться, открыв ссылку. Если ссылка откроется в браузере, нажмите кнопку **Open in mobile app**.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right.\nSimpleX Lock must be enabled." = "Вы можете скрыть профиль или выключить уведомления - потяните его вправо.\nБлокировка SimpleX должна быть включена.";
/* notification body */ /* notification body */
"You can now send messages to %@" = "Вы теперь можете отправлять сообщения %@"; "You can now send messages to %@" = "Вы теперь можете отправлять сообщения %@";
@ -2583,6 +2703,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will join a group this link refers to and connect to its group members." = "Вы вступите в группу, на которую ссылается эта ссылка, и соединитесь с её членами."; "You will join a group this link refers to and connect to its group members." = "Вы вступите в группу, на которую ссылается эта ссылка, и соединитесь с её членами.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Вы все равно получите звонки и уведомления в профилях без звука, когда они активные.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will stop receiving messages from this group. Chat history will be preserved." = "Вы перестанете получать сообщения от этой группы. История чата будет сохранена."; "You will stop receiving messages from this group. Chat history will be preserved." = "Вы перестанете получать сообщения от этой группы. История чата будет сохранена.";

View file

@ -26,7 +26,7 @@
": " = ": "; ": " = ": ";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"!1 colored!" = "!1 色!"; "!1 colored!" = "!1 种彩色!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"." = "."; "." = ".";
@ -41,7 +41,7 @@
"[Contribute](https://github.com/simplex-chat/simplex-chat#contribute)" = "[贡献](https://github.com/simplex-chat/simplex-chat#contribute)"; "[Contribute](https://github.com/simplex-chat/simplex-chat#contribute)" = "[贡献](https://github.com/simplex-chat/simplex-chat#contribute)";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"[Send us email](mailto:chat@simplex.chat)" = "[发送邮件至](mailto:chat@simplex.chat)"; "[Send us email](mailto:chat@simplex.chat)" = "[给我们发电邮](mailto:chat@simplex.chat)";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"[Star on GitHub](https://github.com/simplex-chat/simplex-chat)" = "[在 GitHub 上加星](https://github.com/simplex-chat/simplex-chat)"; "[Star on GitHub](https://github.com/simplex-chat/simplex-chat)" = "[在 GitHub 上加星](https://github.com/simplex-chat/simplex-chat)";
@ -248,6 +248,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Add to another device" = "添加另一设备"; "Add to another device" = "添加另一设备";
/* No comment provided by engineer. */
"Add welcome message" = "添加欢迎信息";
/* member role */ /* member role */
"admin" = "管理员"; "admin" = "管理员";
@ -338,6 +341,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Audio & video calls" = "语音和视频通话"; "Audio & video calls" = "语音和视频通话";
/* No comment provided by engineer. */
"Audio and video calls" = "音视频通话";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"audio call (not e2e encrypted)" = "语音通话(非端到端加密)"; "audio call (not e2e encrypted)" = "语音通话(非端到端加密)";
@ -357,7 +363,7 @@
"Auto-accept images" = "自动接受图片"; "Auto-accept images" = "自动接受图片";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Automatically" = "自动"; "Automatically" = "自动";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Back" = "返回"; "Back" = "返回";
@ -384,7 +390,7 @@
"By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." = "通过聊天资料(默认)或者[通过连接](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)。"; "By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." = "通过聊天资料(默认)或者[通过连接](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Call already ended!" = "通话已结束!"; "Call already ended!" = "通话已结束!";
/* call status */ /* call status */
"call error" = "通话错误"; "call error" = "通话错误";
@ -398,6 +404,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Calls" = "通话"; "Calls" = "通话";
/* No comment provided by engineer. */
"Can't delete user profile!" = "无法删除用户个人资料!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Can't invite contact!" = "无法邀请联系人!"; "Can't invite contact!" = "无法邀请联系人!";
@ -479,6 +488,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Check server address and try again." = "检查服务器地址并再试一次。"; "Check server address and try again." = "检查服务器地址并再试一次。";
/* No comment provided by engineer. */
"Chinese and Spanish interface" = "中文和西班牙文界面";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Choose file" = "选择文件"; "Choose file" = "选择文件";
@ -498,7 +510,7 @@
"Clear verification" = "清除验证"; "Clear verification" = "清除验证";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"colored" = "色"; "colored" = "色";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Colors" = "颜色"; "Colors" = "颜色";
@ -518,6 +530,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Confirm new passphrase…" = "确认新密码……"; "Confirm new passphrase…" = "确认新密码……";
/* No comment provided by engineer. */
"Confirm password" = "确认密码";
/* server test step */ /* server test step */
"Connect" = "连接"; "Connect" = "连接";
@ -884,6 +899,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Do NOT use SimpleX for emergency calls." = "请勿使用 SimpleX 进行紧急通话。"; "Do NOT use SimpleX for emergency calls." = "请勿使用 SimpleX 进行紧急通话。";
/* No comment provided by engineer. */
"Don't show again" = "不再显示";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Duplicate display name!" = "重复的显示名!"; "Duplicate display name!" = "重复的显示名!";
@ -965,6 +983,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter passphrase…" = "输入密码……"; "Enter passphrase…" = "输入密码……";
/* No comment provided by engineer. */
"Enter password above to show!" = "在上面输入密码以显示!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Enter server manually" = "手动输入服务器"; "Enter server manually" = "手动输入服务器";
@ -1061,6 +1082,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error saving SMP servers" = "保存 SMP 服务器错误"; "Error saving SMP servers" = "保存 SMP 服务器错误";
/* No comment provided by engineer. */
"Error saving user password" = "保存用户密码时出错";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error sending message" = "发送消息错误"; "Error sending message" = "发送消息错误";
@ -1082,6 +1106,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error updating settings" = "更新设置错误"; "Error updating settings" = "更新设置错误";
/* No comment provided by engineer. */
"Error updating user privacy" = "更新用户隐私时出错";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Error: %@" = "错误: @"; "Error: %@" = "错误: @";
@ -1133,6 +1160,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Full name:" = "全名:"; "Full name:" = "全名:";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "完全重新实现 - 在后台工作!";
/* No comment provided by engineer. */
"Further reduced battery usage" = "进一步减少电池使用";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GIFs and stickers" = "GIF 和贴纸"; "GIFs and stickers" = "GIF 和贴纸";
@ -1181,6 +1214,9 @@
/* notification */ /* notification */
"Group message:" = "群组消息:"; "Group message:" = "群组消息:";
/* No comment provided by engineer. */
"Group moderation" = "小组审核";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group preferences" = "群组偏好设置"; "Group preferences" = "群组偏好设置";
@ -1193,6 +1229,9 @@
/* snd group event chat item */ /* snd group event chat item */
"group profile updated" = "群组资料已更新"; "group profile updated" = "群组资料已更新";
/* No comment provided by engineer. */
"Group welcome message" = "群欢迎词";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Group will be deleted for all members - this cannot be undone!" = "将为所有成员删除群组——此操作无法撤消!"; "Group will be deleted for all members - this cannot be undone!" = "将为所有成员删除群组——此操作无法撤消!";
@ -1203,7 +1242,13 @@
"Help" = "帮助"; "Help" = "帮助";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hidden" = "已隐藏"; "Hidden" = "隐藏";
/* No comment provided by engineer. */
"Hidden chat profiles" = "隐藏的聊天资料";
/* No comment provided by engineer. */
"Hidden profile password" = "隐藏的个人资料密码";
/* chat item action */ /* chat item action */
"Hide" = "隐藏"; "Hide" = "隐藏";
@ -1211,6 +1256,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Hide app screen in the recent apps." = "在最近的应用程序中隐藏应用程序屏幕。"; "Hide app screen in the recent apps." = "在最近的应用程序中隐藏应用程序屏幕。";
/* No comment provided by engineer. */
"Hide profile" = "隐藏个人资料";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"How it works" = "工作原理"; "How it works" = "工作原理";
@ -1298,6 +1346,9 @@
/* connection level description */ /* connection level description */
"indirect (%d)" = "间接(%d"; "indirect (%d)" = "间接(%d";
/* No comment provided by engineer. */
"Initial role" = "初始角色";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "安装[用于终端的 SimpleX Chat](https://github.com/simplex-chat/simplex-chat)"; "Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "安装[用于终端的 SimpleX Chat](https://github.com/simplex-chat/simplex-chat)";
@ -1436,6 +1487,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make a private connection" = "建立私密连接"; "Make a private connection" = "建立私密连接";
/* No comment provided by engineer. */
"Make profile private!" = "将个人资料设为私密!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "请确保 SMP服 务器地址格式正确,每行一个地址并且不重复 (%@)。"; "Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@)." = "请确保 SMP服 务器地址格式正确,每行一个地址并且不重复 (%@)。";
@ -1503,7 +1557,7 @@
"Migration error:" = "迁移错误:"; "Migration error:" = "迁移错误:";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat)." = "迁移失败。点击下面的 **Skip** 继续使用当前数据库。请通过聊天或电子邮件 [chat@simplex.chat](mailto:chat@simplex.chat) 将问题报告给应用程序开发人员。"; "Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat)." = "迁移失败。点击下面的 **Skip** 继续使用当前数据库。请通过通过聊天或电邮 [chat@simplex.chat](mailto:chat@simplex.chat) 将问题报告给应用程序开发人员。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Migration is completed" = "迁移完成"; "Migration is completed" = "迁移完成";
@ -1532,6 +1586,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Mute" = "静音"; "Mute" = "静音";
/* No comment provided by engineer. */
"Muted when inactive!" = "不活动时静音!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Name" = "名称"; "Name" = "名称";
@ -1604,6 +1661,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Notifications are disabled!" = "通知被禁用!"; "Notifications are disabled!" = "通知被禁用!";
/* No comment provided by engineer. */
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "现在管理员可以:\n- 删除成员的消息。\n- 禁用成员(“观察员”角色)";
/* member role */ /* member role */
"observer" = "观察者"; "observer" = "观察者";
@ -1612,7 +1672,7 @@
"off" = "关闭"; "off" = "关闭";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Off (Local)" = "关闭 (本地)"; "Off (Local)" = "关闭(本地)";
/* feature offered item */ /* feature offered item */
"offered %@" = "已提供 %@"; "offered %@" = "已提供 %@";
@ -1630,7 +1690,7 @@
"Old database archive" = "旧数据库存档"; "Old database archive" = "旧数据库存档";
/* group pref value */ /* group pref value */
"on" = ""; "on" = "开启";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"One-time invitation link" = "一次性邀请链接"; "One-time invitation link" = "一次性邀请链接";
@ -1693,7 +1753,10 @@
"or chat with the developers" = "或与开发者聊天"; "or chat with the developers" = "或与开发者聊天";
/* member role */ /* member role */
"owner" = "所有者"; "owner" = "群主";
/* No comment provided by engineer. */
"Password to show" = "显示密码";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Paste" = "粘贴"; "Paste" = "粘贴";
@ -1714,7 +1777,7 @@
"People can connect to you only via the links you share." = "人们只能通过您共享的链接与您建立联系。"; "People can connect to you only via the links you share." = "人们只能通过您共享的链接与您建立联系。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Periodically" = "定期"; "Periodically" = "定期";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"PING count" = "PING 次数"; "PING count" = "PING 次数";
@ -1794,6 +1857,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protect app screen" = "保护应用程序屏幕"; "Protect app screen" = "保护应用程序屏幕";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "使用密码保护您的聊天资料!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Protocol timeout" = "协议超时"; "Protocol timeout" = "协议超时";
@ -1873,7 +1939,7 @@
"Reply" = "回复"; "Reply" = "回复";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Required" = "必"; "Required" = "必";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Reset" = "重置"; "Reset" = "重置";
@ -1926,6 +1992,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save and notify group members" = "保存并通知群组成员"; "Save and notify group members" = "保存并通知群组成员";
/* No comment provided by engineer. */
"Save and update group profile" = "保存和更新组配置文件";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save archive" = "保存存档"; "Save archive" = "保存存档";
@ -1941,9 +2010,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save preferences?" = "保存偏好设置?"; "Save preferences?" = "保存偏好设置?";
/* No comment provided by engineer. */
"Save profile password" = "保存个人资料密码";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Save servers" = "保存服务器"; "Save servers" = "保存服务器";
/* No comment provided by engineer. */
"Save servers?" = "保存服务器?";
/* No comment provided by engineer. */
"Save welcome message?" = "保存欢迎信息?";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Saved WebRTC ICE servers will be removed" = "已保存的WebRTC ICE服务器将被删除"; "Saved WebRTC ICE servers will be removed" = "已保存的WebRTC ICE服务器将被删除";
@ -2040,6 +2118,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set passphrase to export" = "设置密码来导出"; "Set passphrase to export" = "设置密码来导出";
/* No comment provided by engineer. */
"Set the message shown to new members!" = "设置向新成员显示的消息!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Set timeouts for proxy/VPN" = "设置代理/VPN的超时时间"; "Set timeouts for proxy/VPN" = "设置代理/VPN的超时时间";
@ -2145,6 +2226,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap button " = "点击按钮 "; "Tap button " = "点击按钮 ";
/* No comment provided by engineer. */
"Tap to activate profile." = "点击以激活个人资料。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Tap to join" = "点击加入"; "Tap to join" = "点击加入";
@ -2212,7 +2296,7 @@
"The message will be deleted for all members." = "将为所有成员删除该消息。"; "The message will be deleted for all members." = "将为所有成员删除该消息。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"The message will be marked as moderated for all members." = "该消息将对所有成员显示为已审核。"; "The message will be marked as moderated for all members." = "该消息将对所有成员标记为已被管理员移除。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"The next generation of private messaging" = "下一代私密通讯软件"; "The next generation of private messaging" = "下一代私密通讯软件";
@ -2232,6 +2316,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Theme" = "主题"; "Theme" = "主题";
/* No comment provided by engineer. */
"There should be at least one user profile." = "应该至少有一个用户资料。";
/* No comment provided by engineer. */
"There should be at least one visible user profile." = "应该至少有一个可见的用户资料。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "此操作无法撤消——所有接收和发送的文件和媒体都将被删除。 低分辨率图片将保留。"; "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "此操作无法撤消——所有接收和发送的文件和媒体都将被删除。 低分辨率图片将保留。";
@ -2274,6 +2364,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To record voice message please grant permission to use Microphone." = "请授权使用麦克风以录制语音消息。"; "To record voice message please grant permission to use Microphone." = "请授权使用麦克风以录制语音消息。";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "要显示您的隐藏的个人资料,请在**您的聊天个人资料**页面的搜索字段中输入完整密码。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "为了支持即时推送通知,聊天数据库必须被迁移。"; "To support instant push notifications the chat database has to be migrated." = "为了支持即时推送通知,聊天数据库必须被迁移。";
@ -2290,7 +2383,7 @@
"Trying to connect to the server used to receive messages from this contact." = "正在尝试连接到用于从该联系人接收消息的服务器。"; "Trying to connect to the server used to receive messages from this contact." = "正在尝试连接到用于从该联系人接收消息的服务器。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Turn off" = "关"; "Turn off" = "关";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Turn off notifications?" = "关闭通知?"; "Turn off notifications?" = "关闭通知?";
@ -2307,6 +2400,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Unexpected migration state" = "未预料的迁移状态"; "Unexpected migration state" = "未预料的迁移状态";
/* No comment provided by engineer. */
"Unhide" = "取消隐藏";
/* connection info */ /* connection info */
"unknown" = "未知"; "unknown" = "未知";
@ -2511,6 +2607,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "您也可以通过点击链接进行连接。如果在浏览器中打开,请点击“在移动应用程序中打开”按钮。"; "You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "您也可以通过点击链接进行连接。如果在浏览器中打开,请点击“在移动应用程序中打开”按钮。";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right.\nSimpleX Lock must be enabled." = "您可以隐藏或静音用户个人资料——只需向右滑动。\n必须启用 SimpleX Lock。";
/* notification body */ /* notification body */
"You can now send messages to %@" = "您现在可以给 %@ 发送消息"; "You can now send messages to %@" = "您现在可以给 %@ 发送消息";
@ -2604,6 +2703,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will join a group this link refers to and connect to its group members." = "您将加入此链接指向的群组并连接到其群组成员。"; "You will join a group this link refers to and connect to its group members." = "您将加入此链接指向的群组并连接到其群组成员。";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "当静音配置文件处于活动状态时,您仍会收到来自静音配置文件的电话和通知。";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"You will stop receiving messages from this group. Chat history will be preserved." = "您将停止接收来自该群组的消息。聊天记录将被保留。"; "You will stop receiving messages from this group. Chat history will be preserved." = "您将停止接收来自该群组的消息。聊天记录将被保留。";

View file

@ -0,0 +1,124 @@
---
layout: layouts/article.html
title: "SimpleX Chat v4.6 with hidden profiles, community moderation, improved audio/video calls and reduced battery usage."
date: 2023-03-28
image: images/20230328-hidden-profiles2.png
imageBottom: true
previewBody: blog_previews/20230328.html
permalink: "/blog/20230328-simplex-chat-v4-6-hidden-profiles.html"
---
# SimpleX Chat v4.6 with hidden profiles, community moderation, improved audio/video calls and reduced battery usage.
**Published:** Mar 28, 2023
## What's new in v4.6
- [ARMv7a and Android 8+ support](#armv7a-32-bit-and-android-8-support)
- [hidden chat profiles](#hidden-chat-profiles)
- [community moderation](#community-moderation)
- [improved audio/video calls](#improved-audiovideo-calls)
- [reduced battery usage](#reduced-battery-usage).
- [SMP server monitoring: status bot and page](#smp-server-monitoring)
Also, we added [Chinese and Spanish interface languages](#chinese-and-spanish-interface---you-can-choose-the-language-via-the-app), thanks to the users' community and Weblate!
### ARMv7a (32 bit) and Android 8+ support!
It increases the number of supported Android devices twice - now most of your friends should be able to install SimpleX Chat. SimpleX Chat still doesn't support Android 7 and erlier versions.
If you install the app from GitHub or F-Droid you need to choose the correct APK, Play Store will provide it automatically.
### Hidden chat profiles
<img src="./images/20230328-hidden-profiles1.png" width="288"> &nbsp;&nbsp; <img src="./images/20230328-hidden-profiles2.png" width="288"> &nbsp;&nbsp; <img src="./images/20230328-hidden-profiles3.png" width="288">
For a long time the main way to protect SimpleX Chat app from people who have access to your phone was device authentication - it is requested when you open the app (and some of its sensitive functions).
Many users asked to allow setting the app password or PIN independently from the device PIN, as some other apps do. But it did not seem a good enough solution - if somebody has your device PIN, then in most cases they can also ask you to provide the app PIN as well.
So instead of having an app password, that reduces convenience and doesn't improve security too much, we did what we think could be better. You can now create hidden chat profiles, that are not visible anywhere in the app, and do not show any notifications, until you enter a correct passphrase. If multiple profiles are hidden with the same passphrase they will all show in the list when you enter it.
It's important to remember that these hidden profiles are still stored locally on your device, so if somebody has access to your chat database (they need to know database passphrase, that is independent from device PIN or profile passphrases) or to chat console in the app, they will be able to access these profiles data and reset their passwords. We are considering how chat console can be better protected - e.g., by requiring a separate password or by providing an option to remove it from the UI permanently - tell us what you think.
### Community moderation
Initially we did not design SimpleX Chat to support communities - our focus has always been maximum privacy and security.
SimpleX Chat supports small and fully decentralized groups, that are not hosted anywhere. But many users want to participate in and to discover communities. Since we added support for group links, the groups we created to let users test the app started to grow, and many other communities of over 100 people emerged.
We are already observing some less-than-friendly messages and undesirable content that is not welcome in some communities. So this version adds features allowing to moderate groups.
Firstly, group admins and owners can revoke members rights to send messages to the group by assigning members an "observer" role, and also make this role default for users joining via a group link.
Secondly, group admins can now delete messages sent by other members (excluding the messages sent by the group owners). "Moderate" action in the message menu will either mark the message as deleted or delete it irreversibly for all members, as set in group preferences by the owners.
These features will allow group owners to decide their own rules. More robust moderation tools are coming later when we build support for large communities.
### Improved audio/video calls
<img src="./images/20230328-call2.png" width="288">
Prior to this version audio and video calls in iOS app were very limited they only worked while the app was in foreground. This version fully re-implemented audio/video calls in iOS it now uses native WebRTC library instead of web view. These calls are still end-to-end encrypted, and compatible with the calls in the previous versions of the app, both on iOS and on Android platforms.
Where allowed by App Store policy, the calls on iOS now use Apple's native interface for calls CallKit, that allows to accept calls from the lock screen, prevents call interruption by incoming phone calls and optionally allows to include calls in the phone call history - the last option needs to be enabled separately.
Calls on Android were also improved they now support bluetooth headphones, allow changing volume in video calls and support proximity sensor during the audio call, to prevent accidental interruption when you hold the phone close to your ear.
### Reduced battery usage
We know that battery usage of SimpleX Chat is suboptimal, and we are committed to reduce it. Unfortunately, there is no simple change that we could make to solve this problem, it requires many systematic improvements and fixes.
One of the big issues, particularly in large groups, was inefficient retry strategy for sending messages in cases when the receiving message queue (mailbox) was out of capacity.
This version increases the maximum retry period for "out-of-capacity" scenario to 1 hour, and also preserves this retry period in the database. So, if previously before the message expired in 48 hours there were up to ~2800 delivery attempts and up to ~45Mb wasted traffic per recipient (depending on how frequently the app was restarted), now there will be only ~50 retries, resulting in not more than 0.8Mb of traffic - up to 56x traffic reduction when sending messages to the large groups.
This issue might not have affected you at all, and also solving it won't reduce overall traffic/battery usage by that factor - there are other inefficiences we will be addressing. But if you actively sent messages to large groups you should observe a substantial reduction of battery and traffic consumption.
Please share your experience. If the battery usage is still suboptimal, please share your usage statistics - they can be requested in chat console with `/get stats` command - it will return the aggregated number of network operations, per server, since the app was started. Please note that these statistics include the addresses of the servers you connect to, so if you want to keep them private, please redact them. You can also reset usage statistics with `/reset stats` command.
### SMP server monitoring
If you use preset servers in SimpleX Chat you can now see when we do any maintenance or when the server is down either by [connecting to status bot via the app](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FShQuD-rPokbDvkyotKx5NwM8P3oUXHxA%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEA6fSx1k9zrOmF0BJpCaTarZvnZpMTAVQhd3RkDQ35KT0%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) or by visiting a [status page](https://status.simplex.chat). Status bot always sends automatic messages before the server is restarted for maintenance, but in case of downtime if the same server is down that you use to receive the messages from the bot, you may miss them - check the status page in this case.
### Chinese and Spanish interface - you can choose the language via the app!
Thanks to our users' community and to Weblate providing a free hosting plan for SimpleX Chat translations we can now support more languages in the interface this version adds Chinese and Spanish and more are in progress.
You can [contribute the translation](https://github.com/simplex-chat/simplex-chat/tree/stable#translate-the-apps) of the apps to your language too!
The app now supports 8 languages in addition to English - Czech, German, Spanish, French, Italian, Dutch, Russian and Chinese. You can now choose the language via the app settings (Appearance page), independently from the system settings.
## SimpleX platform
Some links to answer the most common questions:
[SimpleX Chat security assessment](./20221108-simplex-chat-v4.2-security-audit-new-website.md).
[How can SimpleX deliver messages without user identifiers](https://simplex.chat/#how-simplex-works).
[What are the risks to have identifiers assigned to the users](https://simplex.chat/#why-ids-bad-for-privacy).
[Technical details and limitations](https://github.com/simplex-chat/simplex-chat#privacy-technical-details-and-limitations).
[How SimpleX is different from Session, Matrix, Signal, etc.](https://github.com/simplex-chat/simplex-chat/blob/stable/README.md#frequently-asked-questions).
Visit our [website](https://simplex.chat) to learn more.
## Help us with donations
Huge thank you to everybody who donated to SimpleX Chat!
We are prioritizing users privacy and security - it would be impossible without your support.
Our pledge to our users is that SimpleX protocols are and will remain open, and in public domain, - so anybody can build the future implementations of the clients and the servers. We are building SimpleX platform based on the same principles as email and web, but much more private and secure.
Your donations help us raise more funds any amount, even the price of the cup of coffee, makes a big difference for us.
See [this section](https://github.com/simplex-chat/simplex-chat/tree/master#help-us-with-donations) for the ways to donate.
Thank you,
Evgeny
SimpleX Chat founder

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View file

@ -7,7 +7,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package source-repository-package
type: git type: git
location: https://github.com/simplex-chat/simplexmq.git location: https://github.com/simplex-chat/simplexmq.git
tag: c5eb65fec873e0493c28af8b190c3458445d1811 tag: 6a665a083387fe7145d161957f0fcab223a48838
source-repository-package source-repository-package
type: git type: git

248
flake.lock generated
View file

@ -51,11 +51,11 @@
"cabal-34": { "cabal-34": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1640353650, "lastModified": 1645834128,
"narHash": "sha256-N1t6M3/wqj90AEdRkeC8i923gQYUpzSr8b40qVOZ1Rk=", "narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=",
"owner": "haskell", "owner": "haskell",
"repo": "cabal", "repo": "cabal",
"rev": "942639c18c0cd8ec53e0a6f8d120091af35312cd", "rev": "5ff598c67f53f7c4f48e31d722ba37172230c462",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -68,11 +68,11 @@
"cabal-36": { "cabal-36": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1641652457, "lastModified": 1669081697,
"narHash": "sha256-BlFPKP4C4HRUJeAbdembX1Rms1LD380q9s0qVDeoAak=", "narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=",
"owner": "haskell", "owner": "haskell",
"repo": "cabal", "repo": "cabal",
"rev": "f27667f8ec360c475027dcaee0138c937477b070", "rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -159,15 +159,16 @@
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1635892615, "lastModified": 1672831974,
"narHash": "sha256-harGbMZr4hzat2BWBU+Y5OYXlu+fVz7E4WeQzHi5o8A=", "narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=",
"owner": "input-output-hk", "owner": "input-output-hk",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "eca47d3377946315596da653862d341ee5341318", "rev": "45f2638735f8cdc40fe302742b79f248d23eb368",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "input-output-hk", "owner": "input-output-hk",
"ref": "hkm/gitlab-fix",
"repo": "flake-compat", "repo": "flake-compat",
"type": "github" "type": "github"
} }
@ -190,11 +191,11 @@
}, },
"flake-utils": { "flake-utils": {
"locked": { "locked": {
"lastModified": 1667395993, "lastModified": 1676283394,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -205,11 +206,11 @@
}, },
"flake-utils_2": { "flake-utils_2": {
"locked": { "locked": {
"lastModified": 1644229661, "lastModified": 1667395993,
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -248,21 +249,6 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils_5": {
"locked": {
"lastModified": 1653893745,
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"ghc-8.6.5-iohk": { "ghc-8.6.5-iohk": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -302,11 +288,11 @@
"hackage": { "hackage": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1672446463, "lastModified": 1676679913,
"narHash": "sha256-N5dcK1V+BLQeri5oB0ZSk2ABPs/hTGBC7jZvcY9CVLs=", "narHash": "sha256-nW7ApRgiA9uChV/UrW89HK75rIToLt7XtSrkodO0Nbc=",
"owner": "input-output-hk", "owner": "input-output-hk",
"repo": "hackage.nix", "repo": "hackage.nix",
"rev": "7289869780da23633bc193e11d2da94ecee1489d", "rev": "c37cffd51315d8e27dd8d3faf75abf897e39c8c8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -330,6 +316,7 @@
], ],
"hpc-coveralls": "hpc-coveralls", "hpc-coveralls": "hpc-coveralls",
"hydra": "hydra", "hydra": "hydra",
"iserv-proxy": "iserv-proxy",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
@ -337,21 +324,23 @@
"nixpkgs-2105": "nixpkgs-2105", "nixpkgs-2105": "nixpkgs-2105",
"nixpkgs-2111": "nixpkgs-2111", "nixpkgs-2111": "nixpkgs-2111",
"nixpkgs-2205": "nixpkgs-2205", "nixpkgs-2205": "nixpkgs-2205",
"nixpkgs-2211": "nixpkgs-2211",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"old-ghc-nix": "old-ghc-nix", "old-ghc-nix": "old-ghc-nix",
"stackage": "stackage", "stackage": "stackage",
"tullia": "tullia" "tullia": "tullia"
}, },
"locked": { "locked": {
"lastModified": 1672501055, "lastModified": 1677975916,
"narHash": "sha256-Wy6KqoYqQOP1rBvfHUvM3ex8HIdBA4kwnvZj2qQ1VLU=", "narHash": "sha256-dbe8lEEPyfzjdRwpePClv7J9p9lQg7BwbBqAMCw4RLw=",
"owner": "simplex-chat", "owner": "input-output-hk",
"repo": "haskell.nix", "repo": "haskell.nix",
"rev": "dc719cd6dc318923c4a524d005c13f474c00d3d3", "rev": "ab5efd87ce3fd8ade38a01d97693d29a4f1ae7e4",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "simplex-chat", "owner": "input-output-hk",
"ref": "armv7a",
"repo": "haskell.nix", "repo": "haskell.nix",
"type": "github" "type": "github"
} }
@ -383,11 +372,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1646878427, "lastModified": 1671755331,
"narHash": "sha256-KtbrofMtN8GlM7D+n90kixr7QpSlVmdN+vK5CA/aRzc=", "narHash": "sha256-hXsgJj0Cy0ZiCiYdW2OdBz5WmFyOMKuw4zyxKpgUKm4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "hydra", "repo": "hydra",
"rev": "28b682b85b7efc5cf7974065792a1f22203a5927", "rev": "f48f00ee6d5727ae3e488cbf9ce157460853fea8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -395,6 +384,46 @@
"type": "indirect" "type": "indirect"
} }
}, },
"incl": {
"inputs": {
"nixlib": [
"haskellNix",
"tullia",
"std",
"nixpkgs"
]
},
"locked": {
"lastModified": 1669263024,
"narHash": "sha256-E/+23NKtxAqYG/0ydYgxlgarKnxmDbg6rCMWnOBqn9Q=",
"owner": "divnix",
"repo": "incl",
"rev": "ce7bebaee048e4cd7ebdb4cee7885e00c4e2abca",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "incl",
"type": "github"
}
},
"iserv-proxy": {
"flake": false,
"locked": {
"lastModified": 1670983692,
"narHash": "sha256-avLo34JnI9HNyOuauK5R69usJm+GfW3MlyGlYxZhTgY=",
"ref": "hkm/remote-iserv",
"rev": "50d0abb3317ac439a4e7495b185a64af9b7b9300",
"revCount": 10,
"type": "git",
"url": "https://gitlab.haskell.org/hamishmack/iserv-proxy.git"
},
"original": {
"ref": "hkm/remote-iserv",
"type": "git",
"url": "https://gitlab.haskell.org/hamishmack/iserv-proxy.git"
}
},
"lowdown-src": { "lowdown-src": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -411,25 +440,14 @@
"type": "github" "type": "github"
} }
}, },
"mdbook-kroki-preprocessor": {
"flake": false,
"locked": {
"lastModified": 1661755005,
"narHash": "sha256-1TJuUzfyMycWlOQH67LR63/ll2GDZz25I3JfScy/Jnw=",
"owner": "JoelCourtney",
"repo": "mdbook-kroki-preprocessor",
"rev": "93adb5716d035829efed27f65f2f0833a7d3e76f",
"type": "github"
},
"original": {
"owner": "JoelCourtney",
"repo": "mdbook-kroki-preprocessor",
"type": "github"
}
},
"n2c": { "n2c": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_5", "flake-utils": [
"haskellNix",
"tullia",
"std",
"flake-utils"
],
"nixpkgs": [ "nixpkgs": [
"haskellNix", "haskellNix",
"tullia", "tullia",
@ -458,16 +476,16 @@
"nixpkgs-regression": "nixpkgs-regression" "nixpkgs-regression": "nixpkgs-regression"
}, },
"locked": { "locked": {
"lastModified": 1643066034, "lastModified": 1661606874,
"narHash": "sha256-xEPeMcNJVOeZtoN+d+aRwolpW8mFSEQx76HTRdlhPhg=", "narHash": "sha256-9+rpYzI+SmxJn+EbYxjGv68Ucp22bdFUSy/4LkHkkDQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nix", "repo": "nix",
"rev": "a1cd7e58606a41fcf62bf8637804cf8306f17f62", "rev": "11e45768b34fdafdcf019ddbd337afa16127ff0f",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "2.6.0", "ref": "2.11.0",
"repo": "nix", "repo": "nix",
"type": "github" "type": "github"
} }
@ -563,17 +581,18 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1632864508, "lastModified": 1657693803,
"narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=", "narHash": "sha256-G++2CJ9u0E7NNTAi9n5G8TdDmGJXcIjkJ3NF8cetQB8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "82891b5e2c2359d7e58d08849e4c89511ab94234", "rev": "365e1b3a859281cf11b94f87231adeabbdd878a2",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "owner": "NixOS",
"ref": "nixos-21.05-small", "ref": "nixos-22.05-small",
"type": "indirect" "repo": "nixpkgs",
"type": "github"
} }
}, },
"nixpkgs-2003": { "nixpkgs-2003": {
@ -626,11 +645,11 @@
}, },
"nixpkgs-2205": { "nixpkgs-2205": {
"locked": { "locked": {
"lastModified": 1663981975, "lastModified": 1672580127,
"narHash": "sha256-TKaxWAVJR+a5JJauKZqibmaM5e/Pi5tBDx9s8fl/kSE=", "narHash": "sha256-3lW3xZslREhJogoOkjeZtlBtvFMyxHku7I/9IVehhT8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "309faedb8338d3ae8ad8f1043b3ccf48c9cc2970", "rev": "0874168639713f547c05947c76124f78441ea46c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -640,6 +659,22 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-2211": {
"locked": {
"lastModified": 1675730325,
"narHash": "sha256-uNvD7fzO5hNlltNQUAFBPlcEjNG5Gkbhl/ROiX+GZU4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b7ce17b1ebf600a72178f6302c77b6382d09323f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-22.11-darwin",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-regression": { "nixpkgs-regression": {
"locked": { "locked": {
"lastModified": 1643052045, "lastModified": 1643052045,
@ -650,18 +685,19 @@
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "indirect" "type": "github"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1663905476, "lastModified": 1675758091,
"narHash": "sha256-0CSwRKaYravh9v6qSlBpM0gNg0UhKT2lL7Yn6Zbx7UM=", "narHash": "sha256-7gFSQbSVAFUHtGCNHPF7mPc5CcqDk9M2+inlVPZSneg=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "e14f9fb57315f0d4abde222364f19f88c77d2b79", "rev": "747927516efcb5e31ba03b7ff32f61f6d47e7d87",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -720,20 +756,35 @@
}, },
"nixpkgs_5": { "nixpkgs_5": {
"locked": { "locked": {
"lastModified": 1669833724, "lastModified": 1676726892,
"narHash": "sha256-/HEZNyGbnQecrgJnfE8d0WC5c1xuPSD2LUpB6YXlg4c=", "narHash": "sha256-M7OYVR6dKmzmlebIjybFf3l18S2uur8lMyWWnHQooLY=",
"owner": "nixos", "owner": "angerman",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4d2b37a84fad1091b9de401eb450aae66f1a741e", "rev": "729469087592bdea58b360de59dadf6d58714c42",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "angerman",
"ref": "22.11", "ref": "release-22.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nosys": {
"locked": {
"lastModified": 1667881534,
"narHash": "sha256-FhwJ15uPLRsvaxtt/bNuqE/ykMpNAPF0upozFKhTtXM=",
"owner": "divnix",
"repo": "nosys",
"rev": "2d0d5207f6a230e9d0f660903f8db9807b54814f",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "nosys",
"type": "github"
}
},
"old-ghc-nix": { "old-ghc-nix": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -762,11 +813,11 @@
"stackage": { "stackage": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1669598217, "lastModified": 1677888571,
"narHash": "sha256-UioviNyxA3fexeguXLQpgMR6uWL9Q/wulipCbET3C8w=", "narHash": "sha256-YkhRNOaN6QVagZo1cfykYV8KqkI8/q6r2F5+jypOma4=",
"owner": "input-output-hk", "owner": "input-output-hk",
"repo": "stackage.nix", "repo": "stackage.nix",
"rev": "8400280d894949e26354123aebc20801a2165182", "rev": "cb50e6fabdfb2d7e655059039012ad0623f06a27",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -777,17 +828,23 @@
}, },
"std": { "std": {
"inputs": { "inputs": {
"arion": [
"haskellNix",
"tullia",
"std",
"blank"
],
"blank": "blank", "blank": "blank",
"devshell": "devshell", "devshell": "devshell",
"dmerge": "dmerge", "dmerge": "dmerge",
"flake-utils": "flake-utils_4", "flake-utils": "flake-utils_4",
"incl": "incl",
"makes": [ "makes": [
"haskellNix", "haskellNix",
"tullia", "tullia",
"std", "std",
"blank" "blank"
], ],
"mdbook-kroki-preprocessor": "mdbook-kroki-preprocessor",
"microvm": [ "microvm": [
"haskellNix", "haskellNix",
"tullia", "tullia",
@ -797,14 +854,15 @@
"n2c": "n2c", "n2c": "n2c",
"nixago": "nixago", "nixago": "nixago",
"nixpkgs": "nixpkgs_4", "nixpkgs": "nixpkgs_4",
"nosys": "nosys",
"yants": "yants" "yants": "yants"
}, },
"locked": { "locked": {
"lastModified": 1665513321, "lastModified": 1674526466,
"narHash": "sha256-D6Pacw9yf/HMs84KYuCxHXnNDL7v43gtcka5URagFqE=", "narHash": "sha256-tMTaS0bqLx6VJ+K+ZT6xqsXNpzvSXJTmogkraBGzymg=",
"owner": "divnix", "owner": "divnix",
"repo": "std", "repo": "std",
"rev": "94a90eedb9cfc115b12ae8f6622d9904788559e4", "rev": "516387e3d8d059b50e742a2ff1909ed3c8f82826",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -824,11 +882,11 @@
"std": "std" "std": "std"
}, },
"locked": { "locked": {
"lastModified": 1666200256, "lastModified": 1675695930,
"narHash": "sha256-cJPS8zBu30SMhxMe7I8DWutwqMuhPsEez87y9gxMKc4=", "narHash": "sha256-B7rEZ/DBUMlK1AcJ9ajnAPPxqXY6zW2SBX+51bZV0Ac=",
"owner": "input-output-hk", "owner": "input-output-hk",
"repo": "tullia", "repo": "tullia",
"rev": "575362c2244498e8d2c97f72861510fa72e75d44", "rev": "621365f2c725608f381b3ad5b57afef389fd4c31",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -862,11 +920,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1660507851, "lastModified": 1667096281,
"narHash": "sha256-BKjq7JnVuUR/xDtcv6Vm9GYGKAblisXrAgybor9hT/s=", "narHash": "sha256-wRRec6ze0gJHmGn6m57/zhz/Kdvp9HS4Nl5fkQ+uIuA=",
"owner": "divnix", "owner": "divnix",
"repo": "yants", "repo": "yants",
"rev": "0b895ca02a8fa72bad50b454cb3e7d8a66407c96", "rev": "d18f356ec25cb94dc9c275870c3a7927a10f8c3c",
"type": "github" "type": "github"
}, },
"original": { "original": {

215
flake.nix
View file

@ -1,7 +1,7 @@
{ {
description = "nix flake for simplex-chat"; description = "nix flake for simplex-chat";
inputs.nixpkgs.url = "github:nixos/nixpkgs/22.11"; inputs.nixpkgs.url = "github:angerman/nixpkgs/release-22.11";
inputs.haskellNix.url = "github:simplex-chat/haskell.nix"; inputs.haskellNix.url = "github:input-output-hk/haskell.nix/armv7a";
inputs.haskellNix.inputs.nixpkgs.follows = "nixpkgs"; inputs.haskellNix.inputs.nixpkgs.follows = "nixpkgs";
inputs.hackage = { inputs.hackage = {
url = "github:input-output-hk/hackage.nix"; url = "github:input-output-hk/hackage.nix";
@ -12,7 +12,23 @@
outputs = { self, haskellNix, nixpkgs, flake-utils, ... }: outputs = { self, haskellNix, nixpkgs, flake-utils, ... }:
let systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; in let systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; in
flake-utils.lib.eachSystem systems (system: flake-utils.lib.eachSystem systems (system:
let pkgs = haskellNix.legacyPackages.${system}; in # this android26 overlay makes the pkgsCross.{aarch64-android,armv7a-android-prebuilt} to set stdVer to 26 (Android 8).
let android26 = final: prev: {
pkgsCross = prev.pkgsCross // {
aarch64-android = import prev.path {
inherit system;
inherit (prev) overlays;
crossSystem = prev.lib.systems.examples.aarch64-android // { sdkVer = "26"; };
};
armv7a-android-prebuilt = import prev.path {
inherit system;
inherit (prev) overlays;
crossSystem = prev.lib.systems.examples.armv7a-android-prebuilt // { sdkVer = "26"; };
};
};
}; in
# `appendOverlays` with a singleton is identical to `extend`.
let pkgs = haskellNix.legacyPackages.${system}.appendOverlays [android26]; in
let drv' = { extra-modules, pkgs', ... }: pkgs'.haskell-nix.project { let drv' = { extra-modules, pkgs', ... }: pkgs'.haskell-nix.project {
compiler-nix-name = "ghc8107"; compiler-nix-name = "ghc8107";
index-state = "2022-06-20T00:00:00Z"; index-state = "2022-06-20T00:00:00Z";
@ -81,6 +97,7 @@
"x86_64-linux" = "x86_64-linux" =
let let
androidPkgs = pkgs.pkgsCross.aarch64-android; androidPkgs = pkgs.pkgsCross.aarch64-android;
android32Pkgs = pkgs.pkgsCross.armv7a-android-prebuilt;
# For some reason building libiconv with nixpgks android setup produces # For some reason building libiconv with nixpgks android setup produces
# LANGINFO_CODESET to be found, which is not compatible with android sdk 23; # LANGINFO_CODESET to be found, which is not compatible with android sdk 23;
# so we'll patch up iconv to not include that. # so we'll patch up iconv to not include that.
@ -96,11 +113,32 @@
androidFFI = androidPkgs.libffi.overrideAttrs (old: { androidFFI = androidPkgs.libffi.overrideAttrs (old: {
dontDisableStatic = true; dontDisableStatic = true;
hardeningDisable = [ "fortify" ]; hardeningDisable = [ "fortify" ];
postConfigure = '' });
echo "#undef HAVE_MEMFD_CREATE" >> aarch64-unknown-linux-android/fficonfig.h android32FFI = android32Pkgs.libffi.overrideAttrs (old: {
''; dontDisableStatic = true;
hardeningDisable = [ "fortify" ];
} }
);in { );in {
"${pkgs.pkgsCross.musl64.hostPlatform.system}-static:exe:simplex-chat" = (drv pkgs.pkgsCross.musl64).simplex-chat.components.exes.simplex-chat;
"${pkgs.pkgsCross.musl32.hostPlatform.system}-static:exe:simplex-chat" = (drv pkgs.pkgsCross.musl32).simplex-chat.components.exes.simplex-chat;
# "${pkgs.pkgsCross.muslpi.hostPlatform.system}-static:exe:simplex-chat" = (drv pkgs.pkgsCross.muslpi).simplex-chat.components.exes.simplex-chat;
"${pkgs.pkgsCross.aarch64-multiplatform-musl.hostPlatform.system}-static:exe:simplex-chat" = (drv pkgs.pkgsCross.aarch64-multiplatform-musl).simplex-chat.components.exes.simplex-chat;
"armv7a-android:lib:support" = (drv android32Pkgs).android-support.components.library.override {
smallAddressSpace = true; enableShared = false;
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ];
postInstall = ''
mkdir -p $out/_pkg
cp libsupport.so $out/_pkg
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsupport.so
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg-armv7a-android-libsupport.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
};
"aarch64-android:lib:support" = (drv androidPkgs).android-support.components.library.override { "aarch64-android:lib:support" = (drv androidPkgs).android-support.components.library.override {
smallAddressSpace = true; enableShared = false; smallAddressSpace = true; enableShared = false;
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ]; setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ];
@ -117,6 +155,67 @@
> $out/nix-support/hydra-build-products > $out/nix-support/hydra-build-products
''; '';
}; };
"armv7a-android:lib:simplex-chat" = (drv' {
pkgs' = android32Pkgs;
extra-modules = [{
packages.direct-sqlcipher.flags.openssl = true;
packages.direct-sqlcipher.components.library.libs = pkgs.lib.mkForce [
(android32Pkgs.openssl.override { static = true; enableKTLS = false; })
];
packages.direct-sqlcipher.patches = [
./scripts/nix/direct-sqlcipher-android-log.patch
];
}];
}).simplex-chat.components.library.override {
smallAddressSpace = true; enableShared = false;
# for android we build a shared library, passing these arguments is a bit tricky, as
# we want only the threaded rts (HSrts_thr) and ffi to be linked, but not fed into iserv for
# template haskell cross compilation. Thus we just pass them as linker options (-optl).
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsimplex.so" "-optl-lHSrts_thr" "-optl-lffi"];
postInstall = ''
set -x
${pkgs.tree}/bin/tree $out
mkdir -p $out/_pkg
# copy over includes, we might want those, but maybe not.
# cp -r $out/lib/*/*/include $out/_pkg/
# find the libHS...ghc-X.Y.Z.a static library; this is the
# rolled up one with all dependencies included.
cp libsimplex.so $out/_pkg
# find ./dist -name "lib*.so" -exec cp {} $out/_pkg \;
# find ./dist -name "libHS*-ghc*.a" -exec cp {} $out/_pkg \;
# find ${android32FFI}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${android32Pkgs.gmp6.override { withStatic = true; }}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidIconv}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${android32Pkgs.stdenv.cc.libc}/lib -name "*.a" -exec cp {} $out/_pkg \;
echo ${android32Pkgs.openssl.override { enableKTLS = false; }}
find ${(android32Pkgs.openssl.override { enableKTLS = false; }).out}/lib -name "*.so" -exec cp {} $out/_pkg \;
# remove the .1 and other version suffixes from .so's. Androids linker
# doesn't play nice with them.
for lib in $out/_pkg/*.so; do
for dep in $(${pkgs.patchelf}/bin/patchelf --print-needed "$lib"); do
if [[ "''${dep##*.so}" ]]; then
echo "$lib : $dep -> ''${dep%%.so*}.so"
chmod +w "$lib"
${pkgs.patchelf}/bin/patchelf --replace-needed "$dep" "''${dep%%.so*}.so" "$lib"
fi
done
done
for lib in $out/_pkg/*.so; do
chmod +w "$lib"
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so "$lib"
[[ "$lib" != *libsimplex.so ]] && ${pkgs.patchelf}/bin/patchelf --set-soname "$(basename -a $lib)" "$lib"
done
${pkgs.tree}/bin/tree $out/_pkg
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg-armv7a-android-libsimplex.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
};
"aarch64-android:lib:simplex-chat" = (drv' { "aarch64-android:lib:simplex-chat" = (drv' {
pkgs' = androidPkgs; pkgs' = androidPkgs;
extra-modules = [{ extra-modules = [{
@ -178,110 +277,6 @@
> $out/nix-support/hydra-build-products > $out/nix-support/hydra-build-products
''; '';
}; };
"x86_64-android:lib:support" = (drv androidPkgs).android-support.components.library.override {
smallAddressSpace = true; enableShared = false;
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ];
postInstall = ''
mkdir -p $out/_pkg
cp libsupport.so $out/_pkg
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsupport.so
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg-x86_64-android-libsupport.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
};
"x86_64-android:lib:simplex-chat" = (drv' {
pkgs' = androidPkgs;
extra-modules = [{
packages.direct-sqlcipher.flags.openssl = true;
}];
}).simplex-chat.components.library.override {
smallAddressSpace = true; enableShared = false;
# for android we build a shared library, passing these arguments is a bit tricky, as
# we want only the threaded rts (HSrts_thr) and ffi to be linked, but not fed into iserv for
# template haskell cross compilation. Thus we just pass them as linker options (-optl).
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsimplex.so" "-optl-lHSrts_thr" "-optl-lffi"];
postInstall = ''
${pkgs.tree}/bin/tree $out
mkdir -p $out/_pkg
# copy over includes, we might want those, but maybe not.
# cp -r $out/lib/*/*/include $out/_pkg/
# find the libHS...ghc-X.Y.Z.a static library; this is the
# rolled up one with all dependencies included.
cp libsimplex.so $out/_pkg
# find ./dist -name "lib*.so" -exec cp {} $out/_pkg \;
# find ./dist -name "libHS*-ghc*.a" -exec cp {} $out/_pkg \;
# find ${androidFFI}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidPkgs.gmp6.override { withStatic = true; }}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidIconv}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidPkgs.stdenv.cc.libc}/lib -name "*.a" -exec cp {} $out/_pkg \;
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsimplex.so
${pkgs.tree}/bin/tree $out/_pkg
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg-x86_64-android-libsimplex.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
};
"x86_64-linux:lib:support" = (drv androidPkgs).android-support.components.library.override {
smallAddressSpace = true; enableShared = false;
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ];
postInstall = ''
mkdir -p $out/_pkg
cp libsupport.so $out/_pkg
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsupport.so
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg-x86_64-linux-libsupport.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
};
"x86_64-linux:lib:simplex-chat" = (drv' {
pkgs' = androidPkgs;
extra-modules = [{
packages.direct-sqlcipher.flags.openssl = true;
}];
}).simplex-chat.components.library.override {
smallAddressSpace = true; enableShared = false;
# for android we build a shared library, passing these arguments is a bit tricky, as
# we want only the threaded rts (HSrts_thr) and ffi to be linked, but not fed into iserv for
# template haskell cross compilation. Thus we just pass them as linker options (-optl).
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsimplex.so" "-optl-lHSrts_thr" "-optl-lffi"];
postInstall = ''
${pkgs.tree}/bin/tree $out
mkdir -p $out/_pkg
# copy over includes, we might want those, but maybe not.
# cp -r $out/lib/*/*/include $out/_pkg/
# find the libHS...ghc-X.Y.Z.a static library; this is the
# rolled up one with all dependencies included.
cp libsimplex.so $out/_pkg
# find ./dist -name "lib*.so" -exec cp {} $out/_pkg \;
# find ./dist -name "libHS*-ghc*.a" -exec cp {} $out/_pkg \;
# find ${androidFFI}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidPkgs.gmp6.override { withStatic = true; }}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidIconv}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidPkgs.stdenv.cc.libc}/lib -name "*.a" -exec cp {} $out/_pkg \;
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsimplex.so
${pkgs.tree}/bin/tree $out/_pkg
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg-x86_64-linux-libsimplex.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
};
}; };
# builds for iOS and iOS simulator # builds for iOS and iOS simulator

View file

@ -12,9 +12,9 @@ nix_install() {
[ ! -d /nix ] && sudo sh -c "mkdir -p /nix && chown -R $u /nix" [ ! -d /nix ] && sudo sh -c "mkdir -p /nix && chown -R $u /nix"
# Install nix # Install nix
nix_ver="nix-2.11.1" nix_ver="nix-2.14.1"
nix_url="https://releases.nixos.org/nix/$nix_ver/install" nix_url="https://releases.nixos.org/nix/$nix_ver/install"
nix_hash="4569a01dc5f62056f29f3195673bc3242fc70bf2474927fb5d8549c4d997402d" nix_hash="565974057264f0536f600c68d59395927cd73e9fc5a60f33c1906e8f7bc33fcf"
curl -sSf "$nix_url" -o "$tmp/nix-install" curl -sSf "$nix_url" -o "$tmp/nix-install"
printf "%s %s" "$nix_hash" "$tmp/nix-install" | sha256sum -c printf "%s %s" "$nix_hash" "$tmp/nix-install" | sha256sum -c
@ -29,11 +29,16 @@ nix_setup() {
} }
git_setup() { git_setup() {
[ "$folder" != "." ] && {
git clone --depth=1 https://github.com/simplex-chat/simplex-chat "$folder"
}
# Switch to nix-android branch # Switch to nix-android branch
git -C "$folder" checkout "$commit" git -C "$folder" checkout "$commit"
# Create missing folders # Create missing folders
mkdir -p "$folder/apps/android/app/src/main/cpp/libs/arm64-v8a" mkdir -p "$folder/apps/android/app/src/main/cpp/libs/arm64-v8a"
mkdir -p "$folder/apps/android/app/src/main/cpp/libs/armeabi-v7a"
} }
checks() { checks() {
@ -55,10 +60,6 @@ checks() {
esac esac
done done
[ "$folder" != "." ] && {
git clone https://github.com/simplex-chat/simplex-chat "$folder"
}
if [ -n "$commands_failed" ]; then if [ -n "$commands_failed" ]; then
commands_failed=${commands_failed% *} commands_failed=${commands_failed% *}
printf "%s is not found in your \$PATH. Please install them and re-run the script.\n" "$commands_failed" printf "%s is not found in your \$PATH. Please install them and re-run the script.\n" "$commands_failed"
@ -72,21 +73,31 @@ build() {
# Build simplex lib # Build simplex lib
nix build "$folder#hydraJobs.aarch64-android:lib:simplex-chat.x86_64-linux" nix build "$folder#hydraJobs.aarch64-android:lib:simplex-chat.x86_64-linux"
unzip -o "$PWD/result/pkg-aarch64-android-libsimplex.zip" -d "$folder/apps/android/app/src/main/cpp/libs/arm64-v8a" unzip -o "$PWD/result/pkg-aarch64-android-libsimplex.zip" -d "$folder/apps/android/app/src/main/cpp/libs/arm64-v8a"
nix build "$folder#hydraJobs.armv7a-android:lib:simplex-chat.x86_64-linux"
unzip -o "$PWD/result/pkg-armv7a-android-libsimplex.zip" -d "$folder/apps/android/app/src/main/cpp/libs/armeabi-v7a"
# Build android suppprt lib # Build android suppprt lib
nix build "$folder#hydraJobs.aarch64-android:lib:support.x86_64-linux" nix build "$folder#hydraJobs.aarch64-android:lib:support.x86_64-linux"
unzip -o "$PWD/result/pkg-aarch64-android-libsupport.zip" -d "$folder/apps/android/app/src/main/cpp/libs/arm64-v8a" unzip -o "$PWD/result/pkg-aarch64-android-libsupport.zip" -d "$folder/apps/android/app/src/main/cpp/libs/arm64-v8a"
nix build "$folder#hydraJobs.armv7a-android:lib:support.x86_64-linux"
unzip -o "$PWD/result/pkg-armv7a-android-libsupport.zip" -d "$folder/apps/android/app/src/main/cpp/libs/armeabi-v7a"
sed -i.bak 's/${extract_native_libs}/true/' "$folder/apps/android/app/src/main/AndroidManifest.xml" sed -i.bak 's/${extract_native_libs}/true/' "$folder/apps/android/app/src/main/AndroidManifest.xml"
sed -i.bak '/android {/a lint {abortOnError false}' "$folder/apps/android/app/build.gradle"
gradle -p "$folder/apps/android/" clean build assembleRelease gradle -p "$folder/apps/android/" clean build assembleRelease
mkdir -p "$tmp/android" mkdir -p "$tmp/android-aarch64"
unzip -oqd "$tmp/android/" "$folder/apps/android/app/build/outputs/apk/release/app-release-unsigned.apk" unzip -oqd "$tmp/android-aarch64/" "$folder/apps/android/app/build/outputs/apk/release/app-arm64-v8a-release-unsigned.apk"
(cd "$tmp/android-aarch64" && zip -rq5 "$tmp/simplex-chat-aarch64.apk" . && zip -rq0 "$tmp/simplex-chat-aarch64.apk" resources.arsc res)
zipalign -p -f 4 "$tmp/simplex-chat-aarch64.apk" "$PWD/simplex-chat-aarch64.apk"
(cd "$tmp/android" && zip -rq5 "$tmp/simplex-chat.apk" . && zip -rq0 "$tmp/simplex-chat.apk" resources.arsc res) mkdir -p "$tmp/android-armv7"
unzip -oqd "$tmp/android-armv7/" "$folder/apps/android/app/build/outputs/apk/release/app-armeabi-v7a-release-unsigned.apk"
zipalign -p -f 4 "$tmp/simplex-chat.apk" "$PWD/simplex-chat.apk" (cd "$tmp/android-armv7" && zip -rq5 "$tmp/simplex-chat-armv7.apk" . && zip -rq0 "$tmp/simplex-chat-armv7.apk" resources.arsc res)
zipalign -p -f 4 "$tmp/simplex-chat-armv7.apk" "$PWD/simplex-chat-armv7.apk"
} }
final() { final() {

View file

@ -18,29 +18,31 @@ fi
cd $apk_parent_dir cd $apk_parent_dir
ORIG_NAME=$(echo app*.apk) ORIG_NAMES=( $(echo app*.apk) )
unzip -o -q -d apk $ORIG_NAME for ORIG_NAME in "${ORIG_NAMES[@]}"; do
unzip -o -q -d apk $ORIG_NAME
rm $ORIG_NAME rm $ORIG_NAME
(cd apk && zip -r -q -$level ../$ORIG_NAME .) (cd apk && zip -r -q -$level ../$ORIG_NAME .)
# Shouldn't be compressed because of Android requirement # Shouldn't be compressed because of Android requirement
(cd apk && zip -r -q -0 ../$ORIG_NAME resources.arsc) (cd apk && zip -r -q -0 ../$ORIG_NAME resources.arsc)
(cd apk && zip -r -q -0 ../$ORIG_NAME res) (cd apk && zip -r -q -0 ../$ORIG_NAME res)
#(cd apk && 7z a -r -mx=$level -tzip -x!resources.arsc ../$ORIG_NAME .) #(cd apk && 7z a -r -mx=$level -tzip -x!resources.arsc ../$ORIG_NAME .)
#(cd apk && 7z a -r -mx=0 -tzip ../$ORIG_NAME resources.arsc) #(cd apk && 7z a -r -mx=0 -tzip ../$ORIG_NAME resources.arsc)
ALL_TOOLS=($sdk_dir/build-tools/*/) ALL_TOOLS=($sdk_dir/build-tools/*/)
BIN_DIR="${ALL_TOOLS[1]}" BIN_DIR="${ALL_TOOLS[1]}"
$BIN_DIR/zipalign -p -f 4 $ORIG_NAME $ORIG_NAME-2 $BIN_DIR/zipalign -p -f 4 $ORIG_NAME $ORIG_NAME-2
mv $ORIG_NAME{-2,} mv $ORIG_NAME{-2,}
$BIN_DIR/apksigner sign \ $BIN_DIR/apksigner sign \
--ks "$store_file" --ks-key-alias "$key_alias" --ks-pass "pass:$store_password" \ --ks "$store_file" --ks-key-alias "$key_alias" --ks-pass "pass:$store_password" \
--key-pass "pass:$key_password" $ORIG_NAME --key-pass "pass:$key_password" $ORIG_NAME
# cleanup # cleanup
rm -rf apk || true rm -rf apk || true
rm ${ORIG_NAME}.idsig 2> /dev/null || true rm ${ORIG_NAME}.idsig 2> /dev/null || true
done

View file

@ -0,0 +1,49 @@
#!/bin/bash
set -e
function readlink() {
echo "$(cd "$(dirname "$1")"; pwd -P)"
}
if [ -z "${1}" ]; then
echo "Job repo is unset. Provide it via first argument like: $(readlink "$0")/download_libs.sh https://something.com/job/something/{master,stable}"
exit 1
fi
job_repo=$1
default_arch=$2
arches=("aarch64" "armv7a")
output_arches=("arm64-v8a" "armeabi-v7a")
if [ -z "${default_arch}" ]; then
# No custom architectures were specified, using defaults
echo "Libs for all supported architectures will be downloaded. To use single arch, pass one of the following values to the end of command: ${arches[*]}"
else
for ((i = 0 ; i < ${#output_arches[@]}; i++)); do
if [ "${arches[$i]}" == "$default_arch" ]; then
output_arches=("${output_arches[$i]}")
fi
done
arches=("$default_arch")
fi
root_dir="$(dirname "$(dirname "$(readlink "$0")")")"
for ((i = 0 ; i < ${#arches[@]}; i++)); do
arch="${arches[$i]}"
output_arch="${output_arches[$i]}"
output_dir="$root_dir/apps/android/app/src/main/cpp/libs/$output_arch/"
mkdir -p "$output_dir" 2> /dev/null
curl --location -o libsupport.zip $job_repo/$arch-android:lib:support.x86_64-linux/latest/download/1 && \
unzip -o libsupport.zip && \
mv libsupport.so "$output_dir" && \
rm libsupport.zip
curl --location -o libsimplex.zip "$job_repo"/"$arch"-android:lib:simplex-chat.x86_64-linux/latest/download/1 && \
unzip -o libsimplex.zip && \
mv libsimplex.so "$output_dir" && \
rm libsimplex.zip
done

View file

@ -1,33 +0,0 @@
#!/bin/bash
set -e
function readlink() {
echo $(cd $(dirname $1); pwd -P)
}
if [ -z ${1} ]; then
echo "Job repo is unset. Provide it via first argument like: $(readlink $0)/download_libs_aarch64.sh https://something.com/job/something/{master,stable}"
exit 1
fi
job_repo=$1
arch="aarch64"
#arch="x86_64"
output_arch="arm64-v8a"
#output_arch="x86_64"
root_dir="$(dirname $(dirname $(readlink $0)))"
output_dir="$root_dir/apps/android/app/src/main/cpp/libs/$output_arch/"
mkdir -p "$output_dir" 2> /dev/null
curl --location -o libsupport.zip $job_repo/$arch-android:lib:support.x86_64-linux/latest/download/1 && \
unzip -o libsupport.zip && \
mv libsupport.so "$output_dir" && \
rm libsupport.zip
curl --location -o libsimplex.zip $job_repo/$arch-android:lib:simplex-chat.x86_64-linux/latest/download/1 && \
unzip -o libsimplex.zip && \
mv libsimplex.so "$output_dir" && \
rm libsimplex.zip

View file

@ -1,8 +1,12 @@
#!/bin/sh #!/bin/sh
# libsimplex.so and libsupport.so binaries should be in ~/Downloads folder # libsimplex.so and libsupport.so binaries should be in ~/Downloads folder in their directories based on archive name
mkdir -p ./apps/android/app/src/main/cpp/libs/arm64-v8a/ mkdir -p ./apps/android/app/src/main/cpp/libs/arm64-v8a/
rm ./apps/android/app/src/main/cpp/libs/arm64-v8a/* rm ./apps/android/app/src/main/cpp/libs/arm64-v8a/*
cp ~/Downloads/libsupport.so ./apps/android/app/src/main/cpp/libs/arm64-v8a/ unzip -o ~/Downloads/pkg-aarch64-android-libsupport.zip -d ./apps/android/app/src/main/cpp/libs/arm64-v8a
cp ~/Downloads/pkg-aarch64-android-libsimplex/libsimplex.so ./apps/android/app/src/main/cpp/libs/arm64-v8a/ unzip -o ~/Downloads/pkg-aarch64-android-libsimplex.zip -d ./apps/android/app/src/main/cpp/libs/arm64-v8a/
cp ~/Downloads/pkg-aarch64-android-libsimplex/libcrypto.so ./apps/android/app/src/main/cpp/libs/arm64-v8a/
mkdir -p ./apps/android/app/src/main/cpp/libs/armeabi-v7a/
rm ./apps/android/app/src/main/cpp/libs/armeabi-v7a/*
unzip -o ~/Downloads/pkg-armv7a-android-libsupport.zip -d ./apps/android/app/src/main/cpp/libs/armeabi-v7a/
unzip -o ~/Downloads/pkg-armv7a-android-libsimplex.zip -d ./apps/android/app/src/main/cpp/libs/armeabi-v7a/

41
scripts/ios/download-libs.sh Executable file
View file

@ -0,0 +1,41 @@
#!/bin/bash
set -e
function readlink() {
echo "$(cd "$(dirname "$1")"; pwd -P)"
}
if [ -z "${1}" ]; then
echo "Job repo is unset. Provide it via first argument like: $(readlink "$0")/download_libs.sh https://something.com/job/something/{master,stable}"
exit 1
fi
job_repo=$1
default_arch=$2
arches=("aarch64" "x86_64")
output_arches=("aarch64" "x86_64")
if [ -z "${default_arch}" ]; then
# No custom architectures were specified, using defaults
echo "Libs for all supported architectures will be downloaded. To use single arch, pass one of the following values to the end of command: ${arches[*]}"
else
for ((i = 0 ; i < ${#output_arches[@]}; i++)); do
if [ "${arches[$i]}" == "$default_arch" ]; then
output_arches=("${output_arches[$i]}")
fi
done
arches=("$default_arch")
fi
root_dir="$(dirname "$(dirname "$(readlink "$0")")")"
for ((i = 0 ; i < ${#arches[@]}; i++)); do
arch="${arches[$i]}"
output_arch="${output_arches[$i]}"
output_dir="$HOME/Downloads"
curl --location -o "$output_dir"/pkg-ios-"$arch"-swift-json.zip "$job_repo"/"$arch"-darwin-ios:lib:simplex-chat."$arch"-darwin/latest/download/1 && \
unzip -o "$output_dir"/pkg-ios-"$output_arch"-swift-json.zip -d ~/Downloads/pkg-ios-"$output_arch"-swift-json
done
sh "$root_dir"/scripts/ios/prepare-x86_64.sh

View file

@ -1,24 +0,0 @@
#!/bin/bash
set -e
function readlink() {
echo $(cd $(dirname $1); pwd -P)
}
if [ -z ${1} ]; then
echo "Job repo is unset. Provide it via first argument like: $(readlink $0)/download_libs_aarch64.sh https://something.com/job/something/{master,stable}"
exit 1
fi
job_repo=$1
root_dir="$(dirname $(dirname $(readlink $0)))"
curl --location -o ~/Downloads/pkg-ios-aarch64-swift-json.zip $job_repo/aarch64-darwin-ios:lib:simplex-chat.aarch64-darwin/latest/download/1 && \
unzip -o ~/Downloads/pkg-ios-aarch64-swift-json.zip -d ~/Downloads/pkg-ios-aarch64-swift-json
curl --location -o ~/Downloads/pkg-ios-x86_64-swift-json.zip $job_repo/x86_64-darwin-ios:lib:simplex-chat.x86_64-darwin/latest/download/1 && \
unzip -o ~/Downloads/pkg-ios-x86_64-swift-json.zip -d ~/Downloads/pkg-ios-x86_64-swift-json
sh $root_dir/scripts/ios/prepare-x86_64.sh

View file

@ -1,5 +1,5 @@
{ {
"https://github.com/simplex-chat/simplexmq.git"."c5eb65fec873e0493c28af8b190c3458445d1811" = "1cqxl2862fxfl9zv2i1ckvq4xcminslqwfgy5q1w71qk0g2gg96h"; "https://github.com/simplex-chat/simplexmq.git"."6a665a083387fe7145d161957f0fcab223a48838" = "06nmqbnvalwx8zc8dndzcp31asm65clx519aplzpkipjcbyz93y4";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/kazu-yamamoto/http2.git"."78e18f52295a7f89e828539a03fbcb24931461a3" = "05q165anvv0qrcxqbvq1dlvw0l8gmsa9kl6sazk1mfhz2g0yimdk"; "https://github.com/kazu-yamamoto/http2.git"."78e18f52295a7f89e828539a03fbcb24931461a3" = "05q165anvv0qrcxqbvq1dlvw0l8gmsa9kl6sazk1mfhz2g0yimdk";
"https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd"; "https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd";

View file

@ -63,10 +63,11 @@ import Simplex.FileTransfer.Description (ValidFileDescription, gb, kb, mb)
import Simplex.FileTransfer.Protocol (FileParty (..)) import Simplex.FileTransfer.Protocol (FileParty (..))
import Simplex.Messaging.Agent as Agent import Simplex.Messaging.Agent as Agent
import Simplex.Messaging.Agent.Client (AgentStatsKey (..)) import Simplex.Messaging.Agent.Client (AgentStatsKey (..))
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig (..), AgentDatabase (..), InitialAgentServers (..), createAgentStore, defaultAgentConfig) import Simplex.Messaging.Agent.Env.SQLite (AgentConfig (..), InitialAgentServers (..), createAgentStore, defaultAgentConfig)
import Simplex.Messaging.Agent.Lock import Simplex.Messaging.Agent.Lock
import Simplex.Messaging.Agent.Protocol import Simplex.Messaging.Agent.Protocol
import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore (dbNew), execSQL) import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation (..), MigrationError, SQLiteStore (dbNew), execSQL, upMigration)
import qualified Simplex.Messaging.Agent.Store.SQLite.Migrations as Migrations
import Simplex.Messaging.Client (defaultNetworkConfig) import Simplex.Messaging.Client (defaultNetworkConfig)
import qualified Simplex.Messaging.Crypto as C import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Encoding import Simplex.Messaging.Encoding
@ -94,11 +95,9 @@ defaultChatConfig =
{ agentConfig = { agentConfig =
defaultAgentConfig defaultAgentConfig
{ tcpPort = undefined, -- agent does not listen to TCP { tcpPort = undefined, -- agent does not listen to TCP
tbqSize = 1024, tbqSize = 1024
database = AgentDBFile {dbFile = "simplex_v1_agent", dbKey = ""},
yesToMigrations = False
}, },
yesToMigrations = False, confirmMigrations = MCConsole,
defaultServers = defaultServers =
DefaultAgentServers DefaultAgentServers
{ smp = _defaultSMPServers, { smp = _defaultSMPServers,
@ -139,10 +138,10 @@ fixedImagePreview = ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEA
logCfg :: LogConfig logCfg :: LogConfig
logCfg = LogConfig {lc_file = Nothing, lc_stderr = True} logCfg = LogConfig {lc_file = Nothing, lc_stderr = True}
createChatDatabase :: FilePath -> String -> Bool -> IO ChatDatabase createChatDatabase :: FilePath -> String -> MigrationConfirmation -> IO (Either MigrationError ChatDatabase)
createChatDatabase filePrefix key yesToMigrations = do createChatDatabase filePrefix key confirmMigrations = runExceptT $ do
chatStore <- createChatStore (chatStoreFile filePrefix) key yesToMigrations chatStore <- ExceptT $ createChatStore (chatStoreFile filePrefix) key confirmMigrations
agentStore <- createAgentStore (agentStoreFile filePrefix) key yesToMigrations agentStore <- ExceptT $ createAgentStore (agentStoreFile filePrefix) key confirmMigrations
pure ChatDatabase {chatStore, agentStore} pure ChatDatabase {chatStore, agentStore}
newChatController :: ChatDatabase -> Maybe User -> ChatConfig -> ChatOpts -> Maybe (Notification -> IO ()) -> IO ChatController newChatController :: ChatDatabase -> Maybe User -> ChatConfig -> ChatOpts -> Maybe (Notification -> IO ()) -> IO ChatController
@ -153,9 +152,10 @@ newChatController ChatDatabase {chatStore, agentStore} user cfg@ChatConfig {agen
firstTime = dbNew chatStore firstTime = dbNew chatStore
activeTo <- newTVarIO ActiveNone activeTo <- newTVarIO ActiveNone
currentUser <- newTVarIO user currentUser <- newTVarIO user
smpAgent <- getSMPAgentClient aCfg {tbqSize, database = AgentDB agentStore} =<< agentServers config servers <- agentServers config
smpAgent <- getSMPAgentClient aCfg {tbqSize} servers agentStore
agentAsync <- newTVarIO Nothing agentAsync <- newTVarIO Nothing
idsDrg <- newTVarIO =<< drgNew idsDrg <- newTVarIO =<< liftIO drgNew
inputQ <- newTBQueueIO tbqSize inputQ <- newTBQueueIO tbqSize
outputQ <- newTBQueueIO tbqSize outputQ <- newTBQueueIO tbqSize
notifyQ <- newTBQueueIO tbqSize notifyQ <- newTBQueueIO tbqSize
@ -1445,7 +1445,11 @@ processChatCommand = \case
updateGroupProfileByName gName $ \p -> updateGroupProfileByName gName $ \p ->
p {groupPreferences = Just . setGroupPreference' SGFTimedMessages pref $ groupPreferences p} p {groupPreferences = Just . setGroupPreference' SGFTimedMessages pref $ groupPreferences p}
QuitChat -> liftIO exitSuccess QuitChat -> liftIO exitSuccess
ShowVersion -> pure $ CRVersionInfo $ coreVersionInfo $(buildTimestampQ) $(simplexmqCommitQ) ShowVersion -> do
let versionInfo = coreVersionInfo $(buildTimestampQ) $(simplexmqCommitQ)
chatMigrations <- map upMigration <$> withStore' Migrations.getCurrent
agentMigrations <- withAgent getAgentMigrations
pure $ CRVersionInfo {versionInfo, chatMigrations, agentMigrations}
DebugLocks -> do DebugLocks -> do
chatLockName <- atomically . tryReadTMVar =<< asks chatLock chatLockName <- atomically . tryReadTMVar =<< asks chatLock
agentLocks <- withAgent debugAgentLocks agentLocks <- withAgent debugAgentLocks

View file

@ -49,7 +49,7 @@ import Simplex.Messaging.Agent.Client (AgentLocks, SMPTestFailure)
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, NetworkConfig) import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, NetworkConfig)
import Simplex.Messaging.Agent.Lock import Simplex.Messaging.Agent.Lock
import Simplex.Messaging.Agent.Protocol import Simplex.Messaging.Agent.Protocol
import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore) import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation, SQLiteStore, UpMigration)
import qualified Simplex.Messaging.Crypto as C import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Encoding.String import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus) import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus)
@ -101,7 +101,7 @@ coreVersionInfo buildTimestamp simplexmqCommit =
data ChatConfig = ChatConfig data ChatConfig = ChatConfig
{ agentConfig :: AgentConfig, { agentConfig :: AgentConfig,
yesToMigrations :: Bool, confirmMigrations :: MigrationConfirmation,
defaultServers :: DefaultAgentServers, defaultServers :: DefaultAgentServers,
tbqSize :: Natural, tbqSize :: Natural,
fileChunkSize :: Integer, fileChunkSize :: Integer,
@ -422,7 +422,7 @@ data ChatResponse
| CRUserProfile {user :: User, profile :: Profile} | CRUserProfile {user :: User, profile :: Profile}
| CRUserProfileNoChange {user :: User} | CRUserProfileNoChange {user :: User}
| CRUserPrivacy {user :: User} | CRUserPrivacy {user :: User}
| CRVersionInfo {versionInfo :: CoreVersionInfo} | CRVersionInfo {versionInfo :: CoreVersionInfo, chatMigrations :: [UpMigration], agentMigrations :: [UpMigration]}
| CRInvitation {user :: User, connReqInvitation :: ConnReqInvitation} | CRInvitation {user :: User, connReqInvitation :: ConnReqInvitation}
| CRSentConfirmation {user :: User} | CRSentConfirmation {user :: User}
| CRSentInvitation {user :: User, customUserProfile :: Maybe Profile} | CRSentInvitation {user :: User, customUserProfile :: Maybe Profile}

View file

@ -11,18 +11,22 @@ import Simplex.Chat
import Simplex.Chat.Controller import Simplex.Chat.Controller
import Simplex.Chat.Options (ChatOpts (..), CoreChatOpts (..)) import Simplex.Chat.Options (ChatOpts (..), CoreChatOpts (..))
import Simplex.Chat.Types import Simplex.Chat.Types
import System.Exit (exitFailure)
import UnliftIO.Async import UnliftIO.Async
simplexChatCore :: ChatConfig -> ChatOpts -> Maybe (Notification -> IO ()) -> (User -> ChatController -> IO ()) -> IO () simplexChatCore :: ChatConfig -> ChatOpts -> Maybe (Notification -> IO ()) -> (User -> ChatController -> IO ()) -> IO ()
simplexChatCore cfg@ChatConfig {yesToMigrations} opts@ChatOpts {coreOptions = CoreChatOpts {dbFilePrefix, dbKey, logAgent}} sendToast chat = simplexChatCore cfg@ChatConfig {confirmMigrations} opts@ChatOpts {coreOptions = CoreChatOpts {dbFilePrefix, dbKey, logAgent}} sendToast chat =
case logAgent of case logAgent of
Just level -> do Just level -> do
setLogLevel level setLogLevel level
withGlobalLogging logCfg initRun withGlobalLogging logCfg initRun
_ -> initRun _ -> initRun
where where
initRun = do initRun = createChatDatabase dbFilePrefix dbKey confirmMigrations >>= either exit run
db@ChatDatabase {chatStore} <- createChatDatabase dbFilePrefix dbKey yesToMigrations exit e = do
putStrLn $ "Error opening database: " <> show e
exitFailure
run db@ChatDatabase {chatStore} = do
u <- getCreateActiveUser chatStore u <- getCreateActiveUser chatStore
cc <- newChatController db (Just u) cfg opts sendToast cc <- newChatController db (Just u) cfg opts sendToast
runSimplexChat opts u cc chat runSimplexChat opts u cc chat

View file

@ -12,3 +12,11 @@ ALTER TABLE users ADD COLUMN view_pwd_hash BLOB;
ALTER TABLE users ADD COLUMN view_pwd_salt BLOB; ALTER TABLE users ADD COLUMN view_pwd_salt BLOB;
ALTER TABLE users ADD COLUMN show_ntfs INTEGER NOT NULL DEFAULT 1; ALTER TABLE users ADD COLUMN show_ntfs INTEGER NOT NULL DEFAULT 1;
|] |]
down_m20230317_hidden_profiles :: Query
down_m20230317_hidden_profiles =
[sql|
ALTER TABLE users DROP COLUMN view_pwd_hash;
ALTER TABLE users DROP COLUMN view_pwd_salt;
ALTER TABLE users DROP COLUMN show_ntfs;
|]

View file

@ -1,6 +1,7 @@
CREATE TABLE migrations( CREATE TABLE migrations(
name TEXT NOT NULL, name TEXT NOT NULL,
ts TEXT NOT NULL, ts TEXT NOT NULL,
down TEXT,
PRIMARY KEY(name) PRIMARY KEY(name)
); );
CREATE TABLE contact_profiles( CREATE TABLE contact_profiles(

Some files were not shown because too many files have changed in this diff Show more