Compare commits

...

25 Commits

Author SHA1 Message Date
Evgeny Poberezkin 82c4d77c73 6.0.1: ios 233, android 232, desktop 62 2024-08-14 23:10:06 +01:00
Evgeny 25938af62f ui: translations (#4654)
* Translated using Weblate (Dutch)

Currently translated at 100.0% (2030 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/nl/

* Translated using Weblate (Vietnamese)

Currently translated at 28.5% (580 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/vi/

* Translated using Weblate (Indonesian)

Currently translated at 5.2% (106 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/id/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (2030 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/nl/

* Translated using Weblate (Vietnamese)

Currently translated at 28.5% (580 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/vi/

* Translated using Weblate (Indonesian)

Currently translated at 5.2% (106 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/id/

* Translated using Weblate (German)

Currently translated at 100.0% (1785 of 1785 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/de/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2030 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (1785 of 1785 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Vietnamese)

Currently translated at 29.3% (595 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/vi/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2030 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (1785 of 1785 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2030 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (1785 of 1785 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Vietnamese)

Currently translated at 29.9% (607 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/vi/

* Translated using Weblate (Vietnamese)

Currently translated at 30.5% (621 of 2030 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/vi/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (French)

Currently translated at 97.4% (1981 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fr/

* Translated using Weblate (French)

Currently translated at 97.8% (1989 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fr/

* Translated using Weblate (French)

Currently translated at 98.7% (2007 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1785 of 1785 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/fr/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ar/

* Translated using Weblate (German)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (French)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1785 of 1785 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/fr/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (1785 of 1785 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/it/

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (2032 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/uk/

* Translated using Weblate (Vietnamese)

Currently translated at 31.3% (638 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/vi/

* Translated using Weblate (Indonesian)

Currently translated at 5.2% (107 of 2032 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/id/

* process localizations

* update ru

---------

Co-authored-by: summoner001 <summoner@vivaldi.net>
Co-authored-by: tuananh-ng <158744840+tuananh-ng@users.noreply.github.com>
Co-authored-by: billy appetie <billy_appetie@users.noreply.hosted.weblate.org>
Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: No name <CertainBot@users.noreply.hosted.weblate.org>
Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: jonnysemon <jonnysemon@users.noreply.hosted.weblate.org>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Bezruchenko Simon <worcposj44@gmail.com>
2024-08-14 21:12:50 +01:00
Evgeny edfcced1fa website: translation (#4692)
* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (257 of 257 strings)

Translation: SimpleX Chat/SimpleX Chat website
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/uk/

* space

---------

Co-authored-by: Bezruchenko Simon <worcposj44@gmail.com>
2024-08-14 21:01:28 +01:00
Evgeny Poberezkin 5bff5a855e core: 6.0.1.0 2024-08-14 20:30:11 +01:00
Arturs Krumins 46a60d979b ios: fix messages reseting position, when app is brought from background to foreground (#4686)
* ios: fix messages reseting position, when app is brought back to foreground

* minor
2024-08-14 20:14:40 +01:00
Arturs Krumins f6ef57534f ios: add text to share extension link preview (#4683)
* ios: add text to share extension link preview

* remove maxHeight contraint
2024-08-14 19:29:13 +01:00
Stanislav Dmitrenko 1e4479f736 android, desktop: fix loading more items when fast switching chats (#4685)
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2024-08-14 19:08:08 +01:00
Stanislav Dmitrenko 789c762c81 android: hide keyboard when not needed (#4689)
* android: hide keyboard when not needed

* revert some parts

* more places

* unused

* delay

* comment
2024-08-14 18:59:53 +01:00
Evgeny e9baeba31f blog: v6 announcement (#4598)
* blog: v6 announcement

* update
2024-08-14 14:10:14 +01:00
Arturs Krumins 2d5bbcdd61 ios: fix merged item order (#4682) 2024-08-14 07:59:58 +01:00
Arturs Krumins c3f67aff69 ios: speed up network status handling (#4678)
* move network status into a separate model

* reduce network model observation scope (#4679)

* dont pass chat

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2024-08-13 21:08:04 +01:00
Arturs Krumins 7cb3a499b2 ios: optimise chat switching (#4663)
* ios: shooth chat switching

* debug button

* navigation timeout

* fix scroll crash

* fix merge

* whitespace

* wip

* add spinner; extract load and nav logic

* cleanup

* direct chat button

* cleanup

* showLoadingProgress

* reverse rename

* rename

* spinner layout

* move all programmatic navigation to `openLoadChat`

* remove access restriction

* fix scroll on item added regression

* print

* fix page load regression

* fix member sheet disappearing

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2024-08-13 19:37:48 +01:00
Stanislav Dmitrenko 32e7fd72d3 android, desktop: searching in different screens using the same data (#4673)
* android, desktop: searching in different screens using the same data

* don't filter if not needed
2024-08-13 19:15:54 +01:00
Stanislav Dmitrenko 915bbed400 android, desktop: fix chatView state propagation (#4676) 2024-08-13 19:11:04 +01:00
Stanislav Dmitrenko 2ae5a8bffd android, desktop: padding for RTL layout and remembering prefered layout (#4675)
* android, desktop: padding for RTL layout and remembering prefered layout

* refactor

* changes
2024-08-13 19:07:03 +01:00
Stanislav Dmitrenko cd1550a14d android, desktop: fix crash on marking chat read (#4671) 2024-08-13 18:56:47 +01:00
Stanislav Dmitrenko c72c461306 android: replacing a crash with an alert when opening broken Uri (#4674)
* android: replacing a crash with an alert when opening broken Uri

* strings

---------

Co-authored-by: Evgeny <evgeny@poberezkin.com>
2024-08-13 18:42:33 +01:00
spaced4ndy 38fa4c231f ui: improve remote controller stop reason (#4670) 2024-08-13 15:05:13 +04:00
spaced4ndy cb683d0706 ui: disable subs indicator when chat is stopped (#4672) 2024-08-13 13:14:27 +04:00
Diogo 84ae39b012 android: fix group creation chat redirection showing attachments view (#4669) 2024-08-13 12:18:06 +04:00
Stanislav Dmitrenko 6a12f2dec8 ios: fix updating chat wallpaper while app is in background (#4661) 2024-08-12 21:57:04 +01:00
Diogo d1f704d160 multiplatform: mark chat non deleted only on send/receive (keep chatDeleted flag on open) (#4664) 2024-08-12 19:50:36 +04:00
Diogo 9871ebb3b1 ios: mark chat non deleted only on send/receive (keep chatDeleted flag on open) (#4659)
* ios: navigation to delete chat working for group members

* modify

* Revert "modify"

This reverts commit fc811bbb84.

* don't mark non deleted on open, mark on send

* simplify

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2024-08-12 18:49:34 +04:00
Evgeny 02c404593c cli: do not log events for hidden user profiles (#4658)
* cli: do not log events for hidden user profiles

* fix
2024-08-12 08:45:11 +01:00
sh 1d9c5b7a0b flatpak: update metainfo (#4660) 2024-08-12 11:42:48 +04:00
85 changed files with 1532 additions and 468 deletions
+4 -2
View File
@@ -18,7 +18,7 @@
2. ↔️ [Connect to the team](#connect-to-the-team), [join user groups](#join-user-groups) and [follow our updates](#follow-our-updates).
3. 🤝 [Make a private connection](#make-a-private-connection) with a friend.
4. 🔤 [Help translating SimpleX Chat](#help-translating-simplex-chat).
5. ⚡️ [Contribute](#contribute) and [help us with donations](#help-us-with-donations).
5. ⚡️ [Contribute](#contribute) and [support us with donations](#please-support-us-with-your-donations).
[Learn more about SimpleX Chat](#contents).
@@ -150,7 +150,7 @@ We would love to have you join the development! You can help us with:
- contributing to SimpleX Chat knowledge-base.
- developing features - please connect to us via chat so we can help you get started.
## Help us with donations
## Please support us with your donations
Huge thank you to everybody who donated to SimpleX Chat!
@@ -233,6 +233,8 @@ You can use SimpleX with your own servers and still communicate with people usin
Recent and important updates:
[Aug 14, 2024. SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing](./blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.md)
[Jun 4, 2024. SimpleX network: private message routing, v5.8 released with IP address protection and chat themes](./blog/20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md)
[Apr 26, 2024. SimpleX network: legally binding transparency, v5.7 released with better calls and messages.](./blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md)
+67 -16
View File
@@ -54,12 +54,73 @@ class ItemsModel: ObservableObject {
willSet { publisher.send() }
}
// Publishes directly to `objectWillChange` publisher,
// this will cause reversedChatItems to be rendered without throttling
@Published var isLoading = false
@Published var showLoadingProgress = false
init() {
publisher
.throttle(for: 0.25, scheduler: DispatchQueue.main, latest: true)
.sink { self.objectWillChange.send() }
.store(in: &bag)
}
func loadOpenChat(_ chatId: ChatId, willNavigate: @escaping () -> Void = {}) {
let navigationTimeout = Task {
do {
try await Task.sleep(nanoseconds: 250_000000)
await MainActor.run {
willNavigate()
ChatModel.shared.chatId = chatId
}
} catch {}
}
let progressTimeout = Task {
do {
try await Task.sleep(nanoseconds: 1500_000000)
await MainActor.run { showLoadingProgress = true }
} catch {}
}
Task {
if let chat = ChatModel.shared.getChat(chatId) {
await MainActor.run { self.isLoading = true }
// try? await Task.sleep(nanoseconds: 5000_000000)
await loadChat(chat: chat)
navigationTimeout.cancel()
progressTimeout.cancel()
await MainActor.run {
self.isLoading = false
self.showLoadingProgress = false
willNavigate()
ChatModel.shared.chatId = chatId
}
}
}
}
}
class NetworkModel: ObservableObject {
// map of connections network statuses, key is agent connection id
@Published var networkStatuses: Dictionary<String, NetworkStatus> = [:]
static let shared = NetworkModel()
private init() { }
func setContactNetworkStatus(_ contact: Contact, _ status: NetworkStatus) {
if let conn = contact.activeConn {
networkStatuses[conn.agentConnId] = status
}
}
func contactNetworkStatus(_ contact: Contact) -> NetworkStatus {
if let conn = contact.activeConn {
networkStatuses[conn.agentConnId] ?? .unknown
} else {
.unknown
}
}
}
final class ChatModel: ObservableObject {
@@ -84,8 +145,6 @@ final class ChatModel: ObservableObject {
// list of chat "previews"
@Published var chats: [Chat] = []
@Published var deletedChats: Set<String> = []
// map of connections network statuses, key is agent connection id
@Published var networkStatuses: Dictionary<String, NetworkStatus> = [:]
// current chat
@Published var chatId: String?
var chatItemStatuses: Dictionary<Int64, CIStatus> = [:]
@@ -328,6 +387,12 @@ final class ChatModel: ObservableObject {
// }
func addChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) {
// mark chat non deleted
if case let .direct(contact) = cInfo, contact.chatDeleted {
var updatedContact = contact
updatedContact.chatDeleted = false
updateContact(updatedContact)
}
// update previews
if let i = getChatIndex(cInfo.id) {
chats[i].chatItems = switch cInfo {
@@ -865,20 +930,6 @@ final class ChatModel: ObservableObject {
while i < maxIx && inView(i) { i += 1 }
return im.reversedChatItems[min(i - 1, maxIx)]
}
func setContactNetworkStatus(_ contact: Contact, _ status: NetworkStatus) {
if let conn = contact.activeConn {
networkStatuses[conn.agentConnId] = status
}
}
func contactNetworkStatus(_ contact: Contact) -> NetworkStatus {
if let conn = contact.activeConn {
networkStatuses[conn.agentConnId] ?? .unknown
} else {
.unknown
}
}
}
struct ShowingInvitation {
+3 -1
View File
@@ -57,7 +57,9 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
chatModel.ntfCallInvitationAction = (chatId, ntfAction)
}
} else {
chatModel.chatId = content.targetContentIdentifier
if let chatId = content.targetContentIdentifier {
ItemsModel.shared.loadOpenChat(chatId)
}
}
handler()
}
+25 -28
View File
@@ -320,8 +320,8 @@ private func apiChatsResponse(_ r: ChatResponse) throws -> [ChatData] {
let loadItemsPerPage = 50
func apiGetChat(type: ChatType, id: Int64, search: String = "") throws -> Chat {
let r = chatSendCmdSync(.apiGetChat(type: type, id: id, pagination: .last(count: loadItemsPerPage), search: search))
func apiGetChat(type: ChatType, id: Int64, search: String = "") async throws -> Chat {
let r = await chatSendCmd(.apiGetChat(type: type, id: id, pagination: .last(count: loadItemsPerPage), search: search))
if case let .apiChat(_, chat) = r { return Chat.init(chat) }
throw r
}
@@ -332,22 +332,20 @@ func apiGetChatItems(type: ChatType, id: Int64, pagination: ChatPagination, sear
throw r
}
func loadChat(chat: Chat, search: String = "") {
func loadChat(chat: Chat, search: String = "", clearItems: Bool = true) async {
do {
let cInfo = chat.chatInfo
let m = ChatModel.shared
let im = ItemsModel.shared
m.chatItemStatuses = [:]
im.reversedChatItems = []
let chat = try apiGetChat(type: cInfo.chatType, id: cInfo.apiId, search: search)
if case let .direct(contact) = chat.chatInfo, !cInfo.chatDeleted, chat.chatInfo.chatDeleted {
var updatedContact = contact
updatedContact.chatDeleted = false
m.updateContact(updatedContact)
} else {
if clearItems {
await MainActor.run { im.reversedChatItems = [] }
}
let chat = try await apiGetChat(type: cInfo.chatType, id: cInfo.apiId, search: search)
await MainActor.run {
im.reversedChatItems = chat.chatItems.reversed()
m.updateChatInfo(chat.chatInfo)
}
im.reversedChatItems = chat.chatItems.reversed()
} catch let error {
logger.error("loadChat error: \(responseError(error))")
}
@@ -707,7 +705,7 @@ func apiConnect_(incognito: Bool, connReq: String) async -> ((ConnReqType, Pendi
return ((.contact, connection), nil)
case let .contactAlreadyExists(_, contact):
if let c = m.getContactChat(contact.contactId) {
await MainActor.run { m.chatId = c.id }
ItemsModel.shared.loadOpenChat(c.id)
}
let alert = contactAlreadyExistsAlert(contact)
return (nil, alert)
@@ -1171,12 +1169,12 @@ func acceptContactRequest(incognito: Bool, contactRequest: UserContactRequest) a
let chat = Chat(chatInfo: ChatInfo.direct(contact: contact), chatItems: [])
await MainActor.run {
ChatModel.shared.replaceChat(contactRequest.id, chat)
ChatModel.shared.setContactNetworkStatus(contact, .connected)
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
}
if contact.sndReady {
DispatchQueue.main.async {
dismissAllSheets(animated: true) {
ChatModel.shared.chatId = chat.id
ItemsModel.shared.loadOpenChat(chat.id)
}
}
}
@@ -1663,6 +1661,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
await TerminalItems.shared.add(.resp(.now, res))
}
let m = ChatModel.shared
let n = NetworkModel.shared
logger.debug("processReceivedMsg: \(res.responseType)")
switch res {
case let .contactDeletedByContact(user, contact):
@@ -1685,7 +1684,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
NtfManager.shared.notifyContactConnected(user, contact)
}
await MainActor.run {
m.setContactNetworkStatus(contact, .connected)
n.setContactNetworkStatus(contact, .connected)
}
case let .contactConnecting(user, contact):
if active(user) && contact.directOrUsed {
@@ -1708,7 +1707,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
}
}
await MainActor.run {
m.setContactNetworkStatus(contact, .connected)
n.setContactNetworkStatus(contact, .connected)
}
case let .receivedContactRequest(user, contactRequest):
if active(user) {
@@ -1742,7 +1741,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
if active(user) && m.hasChat(mergedContact.id) {
await MainActor.run {
if m.chatId == mergedContact.id {
m.chatId = intoContact.id
ItemsModel.shared.loadOpenChat(mergedContact.id)
}
m.removeChat(mergedContact.id)
}
@@ -1750,27 +1749,27 @@ func processReceivedMsg(_ res: ChatResponse) async {
case let .networkStatus(status, connections):
// dispatch queue to synchronize access
networkStatusesLock.sync {
var ns = m.networkStatuses
var ns = n.networkStatuses
// slow loop is on the background thread
for cId in connections {
ns[cId] = status
}
// fast model update is on the main thread
DispatchQueue.main.sync {
m.networkStatuses = ns
n.networkStatuses = ns
}
}
case let .networkStatuses(_, statuses): ()
// dispatch queue to synchronize access
networkStatusesLock.sync {
var ns = m.networkStatuses
var ns = n.networkStatuses
// slow loop is on the background thread
for s in statuses {
ns[s.agentConnId] = s.networkStatus
}
// fast model update is on the main thread
DispatchQueue.main.sync {
m.networkStatuses = ns
n.networkStatuses = ns
}
}
case let .newChatItem(user, aChatItem):
@@ -1778,11 +1777,6 @@ func processReceivedMsg(_ res: ChatResponse) async {
let cItem = aChatItem.chatItem
await MainActor.run {
if active(user) {
if case let .direct(contact) = cInfo, contact.chatDeleted {
var updatedContact = contact
updatedContact.chatDeleted = false
m.updateContact(updatedContact)
}
m.addChatItem(cInfo, cItem)
} else if cItem.isRcvNew && cInfo.ntfsEnabled {
m.increaseUnreadCounter(user: user)
@@ -1916,7 +1910,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
}
if let contact = memberContact {
await MainActor.run {
m.setContactNetworkStatus(contact, .connected)
n.setContactNetworkStatus(contact, .connected)
}
}
case let .groupUpdated(user, toGroup):
@@ -2097,6 +2091,8 @@ func processReceivedMsg(_ res: ChatResponse) async {
m.remoteCtrlSession = nil
dismissAllSheets() {
switch rcStopReason {
case .disconnected:
()
case .connectionFailed(.errorAgent(.RCP(.identity))):
AlertManager.shared.showAlertMsg(
title: "Connection with desktop stopped",
@@ -2139,12 +2135,13 @@ func processReceivedMsg(_ res: ChatResponse) async {
func switchToLocalSession() {
let m = ChatModel.shared
let n = NetworkModel.shared
m.remoteCtrlSession = nil
do {
m.users = try listUsers()
try getUserChatData()
let statuses = (try apiGetNetworkStatuses()).map { s in (s.agentConnId, s.networkStatus) }
m.networkStatuses = Dictionary(uniqueKeysWithValues: statuses)
n.networkStatuses = Dictionary(uniqueKeysWithValues: statuses)
} catch let error {
logger.debug("error updating chat data: \(responseError(error))")
}
+1 -1
View File
@@ -136,7 +136,7 @@ struct SimpleXApp: App {
chatModel.updateChats(with: chats)
if let id = chatModel.chatId,
let chat = chatModel.getChat(id) {
loadChat(chat: chat)
Task { await loadChat(chat: chat, clearItems: false) }
}
if let ncr = chatModel.ntfContactRequest {
chatModel.ntfContactRequest = nil
@@ -92,6 +92,7 @@ struct ChatInfoView: View {
@EnvironmentObject var chatModel: ChatModel
@EnvironmentObject var theme: AppTheme
@Environment(\.dismiss) var dismiss: DismissAction
@ObservedObject var networkModel = NetworkModel.shared
@ObservedObject var chat: Chat
@State var contact: Contact
@State var localAlias: String
@@ -502,14 +503,14 @@ struct ChatInfoView: View {
.foregroundColor(theme.colors.primary)
.font(.system(size: 14))
Spacer()
Text(chatModel.contactNetworkStatus(contact).statusString)
Text(networkModel.contactNetworkStatus(contact).statusString)
.foregroundColor(theme.colors.secondary)
serverImage()
}
}
private func serverImage() -> some View {
let status = chatModel.contactNetworkStatus(contact)
let status = networkModel.contactNetworkStatus(contact)
return Image(systemName: status.imageName)
.foregroundColor(status == .connected ? .green : theme.colors.secondary)
.font(.system(size: 12))
@@ -557,7 +558,7 @@ struct ChatInfoView: View {
private func networkStatusAlert() -> Alert {
Alert(
title: Text("Network status"),
message: Text(chatModel.contactNetworkStatus(contact).statusExplanation)
message: Text(networkModel.contactNetworkStatus(contact).statusExplanation)
)
}
@@ -97,7 +97,7 @@ struct ChatItemForwardingView: View {
)
} else {
composeState = ComposeState.init(forwardingItem: ci, fromChatInfo: fromChatInfo)
chatModel.chatId = chat.id
ItemsModel.shared.loadOpenChat(chat.id)
}
}
} label: {
@@ -351,7 +351,7 @@ struct ChatItemInfoView: View {
Button {
Task {
await MainActor.run {
chatModel.chatId = forwardedFromItem.chatInfo.id
ItemsModel.shared.loadOpenChat(forwardedFromItem.chatInfo.id)
dismiss()
}
}
+41 -35
View File
@@ -59,7 +59,7 @@ struct ChatView: View {
viewBody
}
}
@ViewBuilder
private var viewBody: some View {
let cInfo = chat.chatInfo
@@ -130,16 +130,23 @@ struct ChatView: View {
}
}
}
.appSheet(item: $selectedMember) { member in
Group {
if case let .group(groupInfo) = chat.chatInfo {
GroupMemberInfoView(groupInfo: groupInfo, groupMember: member, navigation: true)
}
}
}
.onAppear {
loadChat(chat: chat)
initChatView()
selectedChatItems = nil
initChatView()
}
.onChange(of: chatModel.chatId) { cId in
showChatInfoSheet = false
selectedChatItems = nil
scrollModel.scrollToBottom()
stopAudioPlayer()
if let cId {
selectedChatItems = nil
if let c = chatModel.getChat(cId) {
chat = c
}
@@ -152,8 +159,10 @@ struct ChatView: View {
.onChange(of: revealedChatItem) { _ in
NotificationCenter.postReverseListNeedsLayout()
}
.onChange(of: im.reversedChatItems) { reversedChatItems in
if reversedChatItems.count <= loadItemsPerPage && filtered(reversedChatItems).count < 10 {
.onChange(of: im.isLoading) { isLoading in
if !isLoading,
im.reversedChatItems.count <= loadItemsPerPage,
filtered(im.reversedChatItems).count < 10 {
loadChatItems(chat.chatInfo)
}
}
@@ -221,6 +230,7 @@ struct ChatView: View {
}
}
ToolbarItem(placement: .navigationBarTrailing) {
let isLoading = im.isLoading && im.showLoadingProgress
if selectedChatItems != nil {
Button {
withAnimation {
@@ -243,19 +253,23 @@ struct ChatView: View {
}
}
Menu {
if callsPrefEnabled && chatModel.activeCall == nil {
Button {
CallController.shared.startCall(contact, .video)
} label: {
Label("Video call", systemImage: "video")
if !isLoading {
if callsPrefEnabled && chatModel.activeCall == nil {
Button {
CallController.shared.startCall(contact, .video)
} label: {
Label("Video call", systemImage: "video")
}
.disabled(!contact.ready || !contact.active)
}
.disabled(!contact.ready || !contact.active)
searchButton()
ToggleNtfsButton(chat: chat)
.disabled(!contact.ready || !contact.active)
}
searchButton()
ToggleNtfsButton(chat: chat)
.disabled(!contact.ready || !contact.active)
} label: {
Image(systemName: "ellipsis")
.tint(isLoading ? Color.clear : nil)
.overlay { if isLoading { ProgressView() } }
}
}
case let .group(groupInfo):
@@ -280,10 +294,14 @@ struct ChatView: View {
}
}
Menu {
searchButton()
ToggleNtfsButton(chat: chat)
if !isLoading {
searchButton()
ToggleNtfsButton(chat: chat)
}
} label: {
Image(systemName: "ellipsis")
.tint(isLoading ? Color.clear : nil)
.overlay { if isLoading { ProgressView() } }
}
}
case .local:
@@ -349,9 +367,7 @@ struct ChatView: View {
searchText = ""
searchMode = false
searchFocussed = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
loadChat(chat: chat)
}
Task { await loadChat(chat: chat) }
}
}
.padding(.horizontal)
@@ -408,18 +424,11 @@ struct ChatView: View {
} loadPage: {
loadChatItems(cInfo)
}
.opacity(ItemsModel.shared.isLoading ? 0 : 1)
.padding(.vertical, -InvertedTableView.inset)
.onTapGesture { hideKeyboard() }
.onChange(of: searchText) { _ in
loadChat(chat: chat, search: searchText)
}
.onChange(of: chatModel.chatId) { chatId in
if let chatId, let c = chatModel.getChat(chatId) {
chat = c
showChatInfoSheet = false
loadChat(chat: c)
scrollModel.scrollToBottom()
}
Task { await loadChat(chat: chat, search: searchText) }
}
.onChange(of: im.reversedChatItems) { _ in
floatingButtonModel.chatItemsChanged()
@@ -717,7 +726,7 @@ struct ChatView: View {
Group {
if revealed, let range = range {
let items = Array(zip(Array(range), im.reversedChatItems[range]))
ForEach(items, id: \.1.viewId) { (i, ci) in
ForEach(items.reversed(), id: \.1.viewId) { (i, ci) in
let prev = i == prevHidden ? prevItem : im.reversedChatItems[i + 1]
chatItemView(ci, nil, prev)
.overlay {
@@ -815,8 +824,8 @@ struct ChatView: View {
HStack(alignment: .top, spacing: 8) {
MemberProfileImage(member, size: memberImageSize, backgroundColor: theme.colors.background)
.onTapGesture {
if m.membersLoaded {
selectedMember = m.getGroupMember(member.groupMemberId)
if let member = m.getGroupMember(member.groupMemberId) {
selectedMember = member
} else {
Task {
await m.loadGroupMembers(groupInfo) {
@@ -825,9 +834,6 @@ struct ChatView: View {
}
}
}
.appSheet(item: $selectedMember) { member in
GroupMemberInfoView(groupInfo: groupInfo, groupMember: member, navigation: true)
}
chatItemWithMenu(ci, range, maxWidth)
}
}
@@ -55,7 +55,7 @@ struct ComposeLinkView: View {
.foregroundColor(theme.colors.secondary)
}
.padding(.vertical, 5)
.frame(maxWidth: .infinity, minHeight: 60, maxHeight: 60)
.frame(maxWidth: .infinity, minHeight: 60)
}
}
}
@@ -321,24 +321,24 @@ struct GroupMemberInfoView: View {
func knownDirectChatButton(_ chat: Chat, width: CGFloat) -> some View {
InfoViewButton(image: "message.fill", title: "message", width: width) {
dismissAllSheets(animated: true)
DispatchQueue.main.async {
chatModel.chatId = chat.id
ItemsModel.shared.loadOpenChat(chat.id) {
dismissAllSheets(animated: true)
}
}
}
func newDirectChatButton(_ contactId: Int64, width: CGFloat) -> some View {
InfoViewButton(image: "message.fill", title: "message", width: width) {
do {
let chat = try apiGetChat(type: .direct, id: contactId)
chatModel.addChat(chat)
dismissAllSheets(animated: true)
DispatchQueue.main.async {
chatModel.chatId = chat.id
Task {
do {
let chat = try await apiGetChat(type: .direct, id: contactId)
chatModel.addChat(chat)
ItemsModel.shared.loadOpenChat(chat.id) {
dismissAllSheets(animated: true)
}
} catch let error {
logger.error("openDirectChatButton apiGetChat error: \(responseError(error))")
}
} catch let error {
logger.error("openDirectChatButton apiGetChat error: \(responseError(error))")
}
}
}
@@ -352,9 +352,10 @@ struct GroupMemberInfoView: View {
await MainActor.run {
progressIndicator = false
chatModel.addChat(Chat(chatInfo: .direct(contact: memberContact)))
dismissAllSheets(animated: true)
chatModel.chatId = memberContact.id
chatModel.setContactNetworkStatus(memberContact, .connected)
ItemsModel.shared.loadOpenChat(memberContact.id) {
dismissAllSheets(animated: true)
}
NetworkModel.shared.setContactNetworkStatus(memberContact, .connected)
}
} catch let error {
logger.error("createMemberContactButton apiCreateMemberContact error: \(responseError(error))")
+11 -6
View File
@@ -152,18 +152,23 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
/// Scrolls to Item at index path
/// - Parameter indexPath: Item to scroll to - will scroll to beginning of the list, if `nil`
func scroll(to index: Int?, position: UITableView.ScrollPosition) {
if let index {
var animated = false
if #available(iOS 16.0, *) {
animated = true
}
var animated = false
if #available(iOS 16.0, *) {
animated = true
}
if let index, tableView.numberOfRows(inSection: 0) != 0 {
tableView.scrollToRow(
at: IndexPath(row: index, section: 0),
at: position,
animated: animated
)
Task { representer.scrollState = .atDestination }
} else {
tableView.setContentOffset(
CGPoint(x: .zero, y: -InvertedTableView.inset),
animated: animated
)
}
Task { representer.scrollState = .atDestination }
}
func update(items: Array<Item>) {
@@ -114,7 +114,7 @@ struct ChatListNavLink: View {
}
} else {
NavLinkPlain(
tag: chat.chatInfo.id,
chatId: chat.chatInfo.id,
selection: $chatModel.chatId,
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) }
)
@@ -194,7 +194,7 @@ struct ChatListNavLink: View {
}
default:
NavLinkPlain(
tag: chat.chatInfo.id,
chatId: chat.chatInfo.id,
selection: $chatModel.chatId,
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
disabled: !groupInfo.ready
@@ -221,7 +221,7 @@ struct ChatListNavLink: View {
@ViewBuilder private func noteFolderNavLink(_ noteFolder: NoteFolder) -> some View {
NavLinkPlain(
tag: chat.chatInfo.id,
chatId: chat.chatInfo.id,
selection: $chatModel.chatId,
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
disabled: !noteFolder.ready
@@ -472,9 +472,7 @@ struct ChatListNavLink: View {
Task {
let ok = await connectContactViaAddress(contact.contactId, incognito, showAlert: { AlertManager.shared.showAlert($0) })
if ok {
await MainActor.run {
chatModel.chatId = contact.id
}
ItemsModel.shared.loadOpenChat(contact.id)
AlertManager.shared.showAlert(connReqSentAlert(.contact))
}
}
@@ -341,6 +341,7 @@ struct SubsStatusIndicator: View {
}
}
}
.disabled(ChatModel.shared.chatRunning != true)
.onAppear {
startTimer()
}
@@ -376,17 +376,7 @@ struct ChatPreviewView: View {
switch chat.chatInfo {
case let .direct(contact):
if contact.active && contact.activeConn != nil {
switch (chatModel.contactNetworkStatus(contact)) {
case .connected: incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
case .error:
Image(systemName: "exclamationmark.circle")
.resizable()
.scaledToFit()
.frame(width: dynamicChatInfoSize, height: dynamicChatInfoSize)
.foregroundColor(theme.colors.secondary)
default:
ProgressView()
}
NetworkStatusView(contact: contact, size: size)
} else {
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
}
@@ -400,6 +390,30 @@ struct ChatPreviewView: View {
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
}
}
struct NetworkStatusView: View {
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
@EnvironmentObject var theme: AppTheme
@ObservedObject var networkModel = NetworkModel.shared
let contact: Contact
let size: CGFloat
var body: some View {
let dynamicChatInfoSize = dynamicSize(userFont).chatInfoSize
switch (networkModel.contactNetworkStatus(contact)) {
case .connected: incognitoIcon(contact.contactConnIncognito, theme.colors.secondary, size: size)
case .error:
Image(systemName: "exclamationmark.circle")
.resizable()
.scaledToFit()
.frame(width: dynamicChatInfoSize, height: dynamicChatInfoSize)
.foregroundColor(theme.colors.secondary)
default:
ProgressView()
}
}
}
}
@ViewBuilder func incognitoIcon(_ incognito: Bool, _ secondaryColor: Color, size: CGFloat) -> some View {
@@ -56,7 +56,7 @@ struct ContactListNavLink: View {
func recentContactNavLink(_ contact: Contact) -> some View {
Button {
dismissAllSheets(animated: true) {
ChatModel.shared.chatId = contact.id
ItemsModel.shared.loadOpenChat(contact.id)
}
} label: {
contactPreview(contact, titleColor: theme.colors.onBackground)
@@ -82,11 +82,8 @@ struct ContactListNavLink: View {
Button {
Task {
await MainActor.run {
var updatedContact = contact
updatedContact.chatDeleted = false
ChatModel.shared.updateContact(updatedContact)
dismissAllSheets(animated: true) {
ChatModel.shared.chatId = contact.id
ItemsModel.shared.loadOpenChat(contact.id)
}
}
}
@@ -191,9 +188,7 @@ struct ContactListNavLink: View {
Task {
let ok = await connectContactViaAddress(contact.contactId, incognito, showAlert: { alert = SomeAlert(alert: $0, id: "ContactListNavLink connectContactViaAddress") })
if ok {
await MainActor.run {
ChatModel.shared.chatId = contact.id
}
ItemsModel.shared.loadOpenChat(contact.id)
DispatchQueue.main.async {
dismissAllSheets(animated: true) {
AlertManager.shared.showAlert(connReqSentAlert(.contact))
@@ -11,13 +11,22 @@ import SwiftUI
import SimpleXChat
struct ChatViewBackground: ViewModifier {
@EnvironmentObject var theme: AppTheme
@Environment(\.colorScheme) var colorScheme
var image: Image
var imageType: WallpaperType
var background: Color
var tint: Color
func body(content: Content) -> some View {
// Workaround a problem (SwiftUI bug?) when wallpaper is not updated when user changes global theme in iOS settings from dark to light and vice versa
if colorScheme == .light {
back(content)
} else {
back(content)
}
}
func back(_ content: Content) -> some View {
content.background(
Canvas { context, size in
var image = context.resolve(image)
@@ -7,16 +7,17 @@
//
import SwiftUI
import SimpleXChat
struct NavLinkPlain<V: Hashable, Label: View>: View {
@State var tag: V
@Binding var selection: V?
struct NavLinkPlain<Label: View>: View {
let chatId: ChatId
@Binding var selection: ChatId?
@ViewBuilder var label: () -> Label
var disabled = false
var body: some View {
ZStack {
Button("") { DispatchQueue.main.async { selection = tag } }
Button("") { ItemsModel.shared.loadOpenChat(chatId) }
.disabled(disabled)
label()
}
@@ -37,7 +37,7 @@ struct AddGroupView: View {
) { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
dismissAllSheets(animated: true) {
m.chatId = groupInfo.id
ItemsModel.shared.loadOpenChat(groupInfo.id)
}
}
}
@@ -52,7 +52,7 @@ struct AddGroupView: View {
) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
dismissAllSheets(animated: true) {
m.chatId = groupInfo.id
ItemsModel.shared.loadOpenChat(groupInfo.id)
}
}
}
@@ -898,11 +898,11 @@ func openKnownContact(_ contact: Contact, dismiss: Bool, showAlreadyExistsAlert:
DispatchQueue.main.async {
if dismiss {
dismissAllSheets(animated: true) {
m.chatId = c.id
ItemsModel.shared.loadOpenChat(c.id)
showAlreadyExistsAlert?()
}
} else {
m.chatId = c.id
ItemsModel.shared.loadOpenChat(c.id)
showAlreadyExistsAlert?()
}
}
@@ -917,11 +917,11 @@ func openKnownGroup(_ groupInfo: GroupInfo, dismiss: Bool, showAlreadyExistsAler
DispatchQueue.main.async {
if dismiss {
dismissAllSheets(animated: true) {
m.chatId = g.id
ItemsModel.shared.loadOpenChat(g.id)
showAlreadyExistsAlert?()
}
} else {
m.chatId = g.id
ItemsModel.shared.loadOpenChat(g.id)
showAlreadyExistsAlert?()
}
}
@@ -1057,7 +1057,7 @@
</trans-unit>
<trans-unit id="Better networking" xml:space="preserve">
<source>Better networking</source>
<target>Bessere Vernetzung</target>
<target>Kontrollieren Sie Ihr Netzwerk</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -947,7 +947,7 @@
</trans-unit>
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
<source>Archive contacts to chat later.</source>
<target>Archivar contactos para charlar más tarde.</target>
<target>Archiva contactos para charlar más tarde.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Archived contacts" xml:space="preserve">
@@ -1102,7 +1102,7 @@
</trans-unit>
<trans-unit id="Blur for better privacy." xml:space="preserve">
<source>Blur for better privacy.</source>
<target>Difuminar para más privacidad.</target>
<target>Difumina para mayor privacidad.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Blur media" xml:space="preserve">
@@ -1617,7 +1617,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Connection and servers status." xml:space="preserve">
<source>Connection and servers status.</source>
<target>Estado de conexión y servidores.</target>
<target>Estado de tu conexión y servidores.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection error" xml:space="preserve">
@@ -4819,7 +4819,7 @@ Requiere activación de la VPN.</target>
</trans-unit>
<trans-unit id="Pending" xml:space="preserve">
<source>Pending</source>
<target>Pendiente</target>
<target>Pendientes</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="People can connect to you only via the links you share." xml:space="preserve">
@@ -5125,7 +5125,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
</trans-unit>
<trans-unit id="Proxied" xml:space="preserve">
<source>Proxied</source>
<target>Con proxy</target>
<target>Como proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxied servers" xml:space="preserve">
@@ -5906,7 +5906,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
</trans-unit>
<trans-unit id="Sent directly" xml:space="preserve">
<source>Sent directly</source>
<target>Enviado directamente</target>
<target>Directamente</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sent file event" xml:space="preserve">
@@ -5941,7 +5941,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
</trans-unit>
<trans-unit id="Sent via proxy" xml:space="preserve">
<source>Sent via proxy</source>
<target>Enviado vía proxy</target>
<target>Mediante proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Server address" xml:space="preserve">
@@ -6538,7 +6538,7 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida.</target>
</trans-unit>
<trans-unit id="The app will ask to confirm downloads from unknown file servers (except .onion)." xml:space="preserve">
<source>The app will ask to confirm downloads from unknown file servers (except .onion).</source>
<target>La aplicación pedirá que confirmes las descargas desde servidores de archivos desconocidos (excepto .onion).</target>
<target>La aplicación pedirá que confirmes las descargas desde servidores de archivos desconocidos (excepto si son .onion).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The attempt to change database passphrase was not completed." xml:space="preserve">
@@ -7087,7 +7087,7 @@ Para conectarte pide a tu contacto que cree otro enlace y comprueba la conexión
</trans-unit>
<trans-unit id="Use the app with one hand." xml:space="preserve">
<source>Use the app with one hand.</source>
<target>Usa la aplicación con una mano.</target>
<target>Usa la aplicación con una sola mano.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="User profile" xml:space="preserve">
@@ -8208,7 +8208,7 @@ Los servidores SimpleX no pueden ver tu perfil.</target>
</trans-unit>
<trans-unit id="expired" xml:space="preserve">
<source>expired</source>
<target>expirado</target>
<target>expirados</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="forwarded" xml:space="preserve">
@@ -524,7 +524,7 @@
</trans-unit>
<trans-unit id="Abort" xml:space="preserve">
<source>Abort</source>
<target>Annuler</target>
<target>Abandonner</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Abort changing address" xml:space="preserve">
@@ -752,6 +752,7 @@
</trans-unit>
<trans-unit id="Allow calls?" xml:space="preserve">
<source>Allow calls?</source>
<target>Autoriser les appels?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
@@ -941,15 +942,17 @@
</trans-unit>
<trans-unit id="Archive and upload" xml:space="preserve">
<source>Archive and upload</source>
<target>Archiver et transférer</target>
<target>Archiver et téléverser</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
<source>Archive contacts to chat later.</source>
<target>Archiver les contacts pour discuter plus tard.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Archived contacts" xml:space="preserve">
<source>Archived contacts</source>
<target>Contacts archivés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Archiving database" xml:space="preserve">
@@ -1054,6 +1057,7 @@
</trans-unit>
<trans-unit id="Better networking" xml:space="preserve">
<source>Better networking</source>
<target>Meilleure gestion de réseau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1098,6 +1102,7 @@
</trans-unit>
<trans-unit id="Blur for better privacy." xml:space="preserve">
<source>Blur for better privacy.</source>
<target>Rendez les images floues et protégez-les contre les regards indiscrets.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Blur media" xml:space="preserve">
@@ -1152,6 +1157,7 @@
</trans-unit>
<trans-unit id="Calls prohibited!" xml:space="preserve">
<source>Calls prohibited!</source>
<target>Les appels ne sont pas autorisés!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Camera not available" xml:space="preserve">
@@ -1161,10 +1167,12 @@
</trans-unit>
<trans-unit id="Can't call contact" xml:space="preserve">
<source>Can't call contact</source>
<target>Impossible d'appeler le contact</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Can't call member" xml:space="preserve">
<source>Can't call member</source>
<target>Impossible d'appeler le membre</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve">
@@ -1179,6 +1187,7 @@
</trans-unit>
<trans-unit id="Can't message member" xml:space="preserve">
<source>Can't message member</source>
<target>Impossible d'envoyer un message à ce membre</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Cancel" xml:space="preserve">
@@ -1294,6 +1303,7 @@
</trans-unit>
<trans-unit id="Chat database exported" xml:space="preserve">
<source>Chat database exported</source>
<target>Exportation de la base de données des discussions</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Chat database imported" xml:space="preserve">
@@ -1318,6 +1328,7 @@
</trans-unit>
<trans-unit id="Chat list" xml:space="preserve">
<source>Chat list</source>
<target>Liste de discussion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Chat migrated!" xml:space="preserve">
@@ -1407,6 +1418,7 @@
</trans-unit>
<trans-unit id="Color chats with the new themes." xml:space="preserve">
<source>Color chats with the new themes.</source>
<target>Colorez vos discussions avec les nouveaux thèmes.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Color mode" xml:space="preserve">
@@ -1426,7 +1438,7 @@
</trans-unit>
<trans-unit id="Completed" xml:space="preserve">
<source>Completed</source>
<target>Complété</target>
<target>Complétées</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Configure ICE servers" xml:space="preserve">
@@ -1451,6 +1463,7 @@
</trans-unit>
<trans-unit id="Confirm contact deletion?" xml:space="preserve">
<source>Confirm contact deletion?</source>
<target>Confirmer la suppression du contact?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Confirm database upgrades" xml:space="preserve">
@@ -1510,6 +1523,7 @@
</trans-unit>
<trans-unit id="Connect to your friends faster." xml:space="preserve">
<source>Connect to your friends faster.</source>
<target>Connectez-vous à vos amis plus rapidement.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
@@ -1588,6 +1602,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Connecting to contact, please wait or check later!" xml:space="preserve">
<source>Connecting to contact, please wait or check later!</source>
<target>Connexion au contact, veuillez patienter ou vérifier plus tard!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
@@ -1602,6 +1617,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Connection and servers status." xml:space="preserve">
<source>Connection and servers status.</source>
<target>État de la connexion et des serveurs.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection error" xml:space="preserve">
@@ -1656,6 +1672,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Contact deleted!" xml:space="preserve">
<source>Contact deleted!</source>
<target>Contact supprimé !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contact hidden:" xml:space="preserve">
@@ -1670,6 +1687,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Contact is deleted." xml:space="preserve">
<source>Contact is deleted.</source>
<target>Le contact est supprimé.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contact name" xml:space="preserve">
@@ -1684,6 +1702,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Contact will be deleted - this cannot be undone!" xml:space="preserve">
<source>Contact will be deleted - this cannot be undone!</source>
<target>Le contact sera supprimé - il n'est pas possible de revenir en arrière!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contacts" xml:space="preserve">
@@ -1703,6 +1722,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Conversation deleted!" xml:space="preserve">
<source>Conversation deleted!</source>
<target>Conversation supprimée!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Copy" xml:space="preserve">
@@ -1792,7 +1812,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Created" xml:space="preserve">
<source>Created</source>
<target>Créé</target>
<target>Créées</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Created at" xml:space="preserve">
@@ -2046,6 +2066,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Delete contact?" xml:space="preserve">
<source>Delete contact?</source>
<target>Supprimer le contact?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -2155,6 +2176,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
<source>Delete up to 20 messages at once.</source>
<target>Supprimez jusqu'à 20 messages à la fois.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete user profile?" xml:space="preserve">
@@ -2164,11 +2186,12 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Delete without notification" xml:space="preserve">
<source>Delete without notification</source>
<target>Supprimer sans notification</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Deleted" xml:space="preserve">
<source>Deleted</source>
<target>Supprimé</target>
<target>Supprimées</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Deleted at" xml:space="preserve">
@@ -2253,6 +2276,7 @@ Il s'agit de votre propre lien unique !</target>
</trans-unit>
<trans-unit id="Developer options" xml:space="preserve">
<source>Developer options</source>
<target>Options pour les développeurs</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Developer tools" xml:space="preserve">
@@ -3815,6 +3839,7 @@ Erreur: %2$@</target>
</trans-unit>
<trans-unit id="It protects your IP address and connections." xml:space="preserve">
<source>It protects your IP address and connections.</source>
<target>Il protège votre adresse IP et vos connexions.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="It seems like you are already connected via this link. If it is not the case, there was an error (%@)." xml:space="preserve">
@@ -3881,6 +3906,7 @@ Voici votre lien pour le groupe %@ !</target>
</trans-unit>
<trans-unit id="Keep conversation" xml:space="preserve">
<source>Keep conversation</source>
<target>Garder la conversation</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
@@ -4060,6 +4086,7 @@ Voici votre lien pour le groupe %@ !</target>
</trans-unit>
<trans-unit id="Media &amp; file servers" xml:space="preserve">
<source>Media &amp; file servers</source>
<target>Serveurs de fichiers et de médias</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Medium" xml:space="preserve">
@@ -4154,6 +4181,7 @@ Voici votre lien pour le groupe %@ !</target>
</trans-unit>
<trans-unit id="Message servers" xml:space="preserve">
<source>Message servers</source>
<target>Serveurs de messages</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message source remains private." xml:space="preserve">
@@ -4368,6 +4396,7 @@ Voici votre lien pour le groupe %@ !</target>
</trans-unit>
<trans-unit id="New chat experience 🎉" xml:space="preserve">
<source>New chat experience 🎉</source>
<target>Nouvelle expérience de discussion 🎉</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New contact request" xml:space="preserve">
@@ -4402,6 +4431,7 @@ Voici votre lien pour le groupe %@ !</target>
</trans-unit>
<trans-unit id="New media options" xml:space="preserve">
<source>New media options</source>
<target>Nouvelles options de médias</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New member role" xml:space="preserve">
@@ -4574,6 +4604,7 @@ Nécessite l'activation d'un VPN.</target>
</trans-unit>
<trans-unit id="Only delete conversation" xml:space="preserve">
<source>Only delete conversation</source>
<target>Ne supprimer que la conversation</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Only group owners can change group preferences." xml:space="preserve">
@@ -4813,10 +4844,12 @@ Nécessite l'activation d'un VPN.</target>
</trans-unit>
<trans-unit id="Play from the chat list." xml:space="preserve">
<source>Play from the chat list.</source>
<target>Aperçu depuis la liste de conversation.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
<source>Please ask your contact to enable calls.</source>
<target>Veuillez demander à votre contact d'autoriser les appels.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
@@ -5122,6 +5155,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
<source>Reachable chat toolbar</source>
<target>Barre d'outils accessible</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="React…" xml:space="preserve">
@@ -5397,6 +5431,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Reset all hints" xml:space="preserve">
<source>Reset all hints</source>
<target>Rétablir tous les conseils</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reset all statistics" xml:space="preserve">
@@ -5531,6 +5566,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Save and reconnect" xml:space="preserve">
<source>Save and reconnect</source>
<target>Sauvegarder et se reconnecter</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve">
@@ -5675,7 +5711,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Secured" xml:space="preserve">
<source>Secured</source>
<target>Sécurisé</target>
<target>Sécurisées</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Security assessment" xml:space="preserve">
@@ -5755,7 +5791,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Send link previews" xml:space="preserve">
<source>Send link previews</source>
<target>Envoi d'aperçus de liens</target>
<target>Aperçu des liens</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Send live message" xml:space="preserve">
@@ -5765,6 +5801,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Send message to enable calls." xml:space="preserve">
<source>Send message to enable calls.</source>
<target>Envoyer un message pour activer les appels.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Send messages directly when IP address is protected and your or destination server does not support private routing." xml:space="preserve">
@@ -5929,7 +5966,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Server requires authorization to upload, check password" xml:space="preserve">
<source>Server requires authorization to upload, check password</source>
<target>Le serveur requiert une autorisation pour uploader, vérifiez le mot de passe</target>
<target>Le serveur requiert une autorisation pour téléverser, vérifiez le mot de passe</target>
<note>server test error</note>
</trans-unit>
<trans-unit id="Server test failed!" xml:space="preserve">
@@ -6054,6 +6091,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Share from other apps." xml:space="preserve">
<source>Share from other apps.</source>
<target>Partager depuis d'autres applications.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share link" xml:space="preserve">
@@ -6093,7 +6131,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Show last messages" xml:space="preserve">
<source>Show last messages</source>
<target>Voir les derniers messages</target>
<target>Aperçu des derniers messages</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Show message status" xml:space="preserve">
@@ -6108,7 +6146,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Show preview" xml:space="preserve">
<source>Show preview</source>
<target>Afficher l'aperçu</target>
<target>Aperçu affiché</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Show → on messages sent via private routing." xml:space="preserve">
@@ -6228,6 +6266,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
<source>Some file(s) were not exported:</source>
<target>Certains fichiers n'ont pas été exportés:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Some non-fatal errors occurred during import - you may see Chat console for more details." xml:space="preserve">
@@ -6237,6 +6276,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Some non-fatal errors occurred during import:" xml:space="preserve">
<source>Some non-fatal errors occurred during import:</source>
<target>L'importation a entraîné des erreurs non fatales:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Somebody" xml:space="preserve">
@@ -6346,7 +6386,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="Subscribed" xml:space="preserve">
<source>Subscribed</source>
<target>Inscrit</target>
<target>Inscriptions</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Subscription errors" xml:space="preserve">
@@ -6376,6 +6416,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
</trans-unit>
<trans-unit id="TCP connection" xml:space="preserve">
<source>TCP connection</source>
<target>Connexion TCP</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
@@ -6739,6 +6780,7 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
</trans-unit>
<trans-unit id="Toggle chat list:" xml:space="preserve">
<source>Toggle chat list:</source>
<target>Afficher la liste des conversations:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
@@ -6748,6 +6790,7 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
</trans-unit>
<trans-unit id="Toolbar opacity" xml:space="preserve">
<source>Toolbar opacity</source>
<target>Opacité de la barre d'outils</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Total" xml:space="preserve">
@@ -6934,6 +6977,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Update settings?" xml:space="preserve">
<source>Update settings?</source>
<target>Mettre à jour les paramètres?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Updating settings will re-connect the client to all servers." xml:space="preserve">
@@ -6958,7 +7002,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Upload file" xml:space="preserve">
<source>Upload file</source>
<target>Transférer le fichier</target>
<target>Téléverser le fichier</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Uploaded" xml:space="preserve">
@@ -7043,6 +7087,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Use the app with one hand." xml:space="preserve">
<source>Use the app with one hand.</source>
<target>Utiliser l'application d'une main.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="User profile" xml:space="preserve">
@@ -7112,7 +7157,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="Video will be received when your contact completes uploading it." xml:space="preserve">
<source>Video will be received when your contact completes uploading it.</source>
<target>La vidéo ne sera reçue que lorsque votre contact aura fini de la transférer.</target>
<target>La vidéo ne sera reçue que lorsque votre contact aura fini la mettre en ligne.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video will be received when your contact is online, please wait or check later!" xml:space="preserve">
@@ -7404,6 +7449,7 @@ Répéter la demande d'adhésion ?</target>
</trans-unit>
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
<source>You can change it in Appearance settings.</source>
<target>Vous pouvez choisir de le modifier dans les paramètres d'apparence.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can create it later" xml:space="preserve">
@@ -7443,6 +7489,7 @@ Répéter la demande d'adhésion ?</target>
</trans-unit>
<trans-unit id="You can send messages to %@ from Archived contacts." xml:space="preserve">
<source>You can send messages to %@ from Archived contacts.</source>
<target>Vous pouvez envoyer des messages à %@ à partir des contacts archivés.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
@@ -7472,6 +7519,7 @@ Répéter la demande d'adhésion ?</target>
</trans-unit>
<trans-unit id="You can still view conversation with %@ in the list of chats." xml:space="preserve">
<source>You can still view conversation with %@ in the list of chats.</source>
<target>Vous pouvez toujours voir la conversation avec %@ dans la liste des discussions.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
@@ -7538,10 +7586,12 @@ Répéter la demande de connexion ?</target>
</trans-unit>
<trans-unit id="You may migrate the exported database." xml:space="preserve">
<source>You may migrate the exported database.</source>
<target>Vous pouvez migrer la base de données exportée.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You may save the exported archive." xml:space="preserve">
<source>You may save the exported archive.</source>
<target>Vous pouvez enregistrer l'archive exportée.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." xml:space="preserve">
@@ -7551,6 +7601,7 @@ Répéter la demande de connexion ?</target>
</trans-unit>
<trans-unit id="You need to allow your contact to call to be able to call them." xml:space="preserve">
<source>You need to allow your contact to call to be able to call them.</source>
<target>Vous devez autoriser votre contact à appeler pour pouvoir l'appeler.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You need to allow your contact to send voice messages to be able to send them." xml:space="preserve">
@@ -7862,6 +7913,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="call" xml:space="preserve">
<source>call</source>
<target>appeler</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="call error" xml:space="preserve">
@@ -8236,6 +8288,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="invite" xml:space="preserve">
<source>invite</source>
<target>inviter</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="invited" xml:space="preserve">
@@ -8295,6 +8348,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="message" xml:space="preserve">
<source>message</source>
<target>message</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="message received" xml:space="preserve">
@@ -8329,6 +8383,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="mute" xml:space="preserve">
<source>mute</source>
<target>muet</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="never" xml:space="preserve">
@@ -8465,6 +8520,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="search" xml:space="preserve">
<source>search</source>
<target>rechercher</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="sec" xml:space="preserve">
@@ -8553,6 +8609,7 @@ dernier message reçu: %2$@</target>
</trans-unit>
<trans-unit id="unmute" xml:space="preserve">
<source>unmute</source>
<target>démuter</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="unprotected" xml:space="preserve">
@@ -8602,6 +8659,7 @@ dernier message reçu: %2$@</target>
</trans-unit>
<trans-unit id="video" xml:space="preserve">
<source>video</source>
<target>vidéo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
@@ -8944,10 +9002,12 @@ dernier message reçu: %2$@</target>
</trans-unit>
<trans-unit id="Sending a message takes longer than expected." xml:space="preserve">
<source>Sending a message takes longer than expected.</source>
<target>L'envoi d'un message prend plus de temps que prévu.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sending message…" xml:space="preserve">
<source>Sending message…</source>
<target>Envoi du message…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share" xml:space="preserve">
@@ -8957,6 +9017,7 @@ dernier message reçu: %2$@</target>
</trans-unit>
<trans-unit id="Slow network?" xml:space="preserve">
<source>Slow network?</source>
<target>Réseau lent?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unknown database error: %@" xml:space="preserve">
@@ -8971,6 +9032,7 @@ dernier message reçu: %2$@</target>
</trans-unit>
<trans-unit id="Wait" xml:space="preserve">
<source>Wait</source>
<target>Attendez</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
@@ -219,12 +219,12 @@
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve">
<source>%lld messages blocked</source>
<target>%lld üzenet blokkolva</target>
<target>%lld üzenet letiltva</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages blocked by admin" xml:space="preserve">
<source>%lld messages blocked by admin</source>
<target>%lld üzenet blokkolva az admin által</target>
<target>%lld üzenet letiltva az admin által</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
@@ -1067,7 +1067,7 @@
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Blokkolás</target>
<target>Letiltás</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block for all" xml:space="preserve">
@@ -1077,12 +1077,12 @@
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Csoporttagok blokkolása</target>
<target>Csoporttagok letiltása</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Tag blokkolása</target>
<target>Tag letiltása</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member for all?" xml:space="preserve">
@@ -1092,7 +1092,7 @@
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve">
<source>Block member?</source>
<target>Tag blokkolása?</target>
<target>Tag letiltása?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Blocked by admin" xml:space="preserve">
@@ -2961,7 +2961,7 @@ Ez az egyszer használatos hivatkozása!</target>
</trans-unit>
<trans-unit id="Error synchronizing connection" xml:space="preserve">
<source>Error synchronizing connection</source>
<target>Hiba a kapcsolat szinkronizálása során</target>
<target>Hiba a kapcsolat szinkronizálása közben</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error updating group link" xml:space="preserve">
@@ -3541,7 +3541,7 @@ Hiba: %2$@</target>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás során, vagy ossza meg a hivatkozást.</target>
<target>Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás közben, vagy ossza meg a hivatkozást.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you enter this passcode when opening the app, all app data will be irreversibly removed!" xml:space="preserve">
@@ -5971,7 +5971,7 @@ Engedélyezze a Beállítások / Hálózat és kiszolgálók menüben.</target>
</trans-unit>
<trans-unit id="Server test failed!" xml:space="preserve">
<source>Server test failed!</source>
<target>Sikertelen kiszolgáló-teszt!</target>
<target>Sikertelen kiszolgáló teszt!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Server type" xml:space="preserve">
@@ -6271,12 +6271,12 @@ Engedélyezze a Beállítások / Hálózat és kiszolgálók menüben.</target>
</trans-unit>
<trans-unit id="Some non-fatal errors occurred during import - you may see Chat console for more details." xml:space="preserve">
<source>Some non-fatal errors occurred during import - you may see Chat console for more details.</source>
<target>Néhány nem végzetes hiba történt az importálás során további részletekért a csevegési konzolban olvashat.</target>
<target>Néhány nem végzetes hiba történt az importálás közben további részletekért a csevegési konzolban olvashat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Some non-fatal errors occurred during import:" xml:space="preserve">
<source>Some non-fatal errors occurred during import:</source>
<target>Néhány nem végzetes hiba történt az importálás során:</target>
<target>Néhány nem végzetes hiba történt az importálás közben:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Somebody" xml:space="preserve">
@@ -6603,7 +6603,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
</trans-unit>
<trans-unit id="The old database was not removed during the migration, it can be deleted." xml:space="preserve">
<source>The old database was not removed during the migration, it can be deleted.</source>
<target>A régi adatbázis nem került eltávolításra az átköltöztetés során, így törölhető.</target>
<target>A régi adatbázis nem került eltávolításra az átköltöztetés közben, így törölhető.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
@@ -7893,12 +7893,12 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
<source>blocked</source>
<target>blokkolva</target>
<target>letiltva</target>
<note>marked deleted chat item preview text</note>
</trans-unit>
<trans-unit id="blocked %@" xml:space="preserve">
<source>blocked %@</source>
<target>letiltotta őt: %@</target>
<target>letiltotta %@-t</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="blocked by admin" xml:space="preserve">
@@ -8589,7 +8589,7 @@ utoljára fogadott üzenet: %2$@</target>
</trans-unit>
<trans-unit id="unblocked %@" xml:space="preserve">
<source>unblocked %@</source>
<target>%@ feloldva</target>
<target>feloldotta %@ letiltását</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="unknown" xml:space="preserve">
@@ -8714,7 +8714,7 @@ utoljára fogadott üzenet: %2$@</target>
</trans-unit>
<trans-unit id="you blocked %@" xml:space="preserve">
<source>you blocked %@</source>
<target>blokkolta őt: %@</target>
<target>ön letiltotta %@-t</target>
<note>snd group event chat item</note>
</trans-unit>
<trans-unit id="you changed address" xml:space="preserve">
@@ -8759,7 +8759,7 @@ utoljára fogadott üzenet: %2$@</target>
</trans-unit>
<trans-unit id="you unblocked %@" xml:space="preserve">
<source>you unblocked %@</source>
<target>feloldotta %@ blokkolását</target>
<target>ön feloldotta %@ letiltását</target>
<note>snd group event chat item</note>
</trans-unit>
<trans-unit id="you: " xml:space="preserve">
@@ -6780,7 +6780,7 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
</trans-unit>
<trans-unit id="Toggle chat list:" xml:space="preserve">
<source>Toggle chat list:</source>
<target>Cambia elenco chat:</target>
<target>Cambia l'elenco delle chat:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
+24 -1
View File
@@ -132,7 +132,7 @@ struct ShareView: View {
switch content {
case let .image(preview, _): imagePreview(preview)
case let .movie(preview, _, _): imagePreview(preview)
case let .url(linkPreview): imagePreview(linkPreview.image)
case let .url(preview): linkPreview(preview)
case let .data(cryptoFile):
previewArea {
Image(systemName: "doc.fill")
@@ -160,6 +160,29 @@ struct ShareView: View {
}
}
@ViewBuilder private func linkPreview(_ linkPreview: LinkPreview) -> some View {
previewArea {
HStack(alignment: .center, spacing: 8) {
if let uiImage = UIImage(base64Encoded: linkPreview.image) {
Image(uiImage: uiImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 80, maxHeight: 60)
}
VStack(alignment: .center, spacing: 4) {
Text(linkPreview.title)
.lineLimit(1)
Text(linkPreview.uri.absoluteString)
.font(.caption)
.lineLimit(1)
.foregroundColor(.secondary)
}
.padding(.vertical, 5)
.frame(maxWidth: .infinity, minHeight: 60)
}
}
}
@ViewBuilder private func previewArea<V: View>(@ViewBuilder content: @escaping () -> V) -> some View {
HStack(alignment: .center, spacing: 8) {
content()
@@ -82,15 +82,27 @@
/* No comment provided by engineer. */
"Selected chat preferences prohibit this message." = "Les paramètres de chat sélectionnés ne permettent pas l'envoi de ce message.";
/* No comment provided by engineer. */
"Sending a message takes longer than expected." = "L'envoi d'un message prend plus de temps que prévu.";
/* No comment provided by engineer. */
"Sending message…" = "Envoi du message…";
/* No comment provided by engineer. */
"Share" = "Partager";
/* No comment provided by engineer. */
"Slow network?" = "Réseau lent?";
/* No comment provided by engineer. */
"Unknown database error: %@" = "Erreur inconnue de la base de données: %@";
/* No comment provided by engineer. */
"Unsupported format" = "Format non pris en charge";
/* No comment provided by engineer. */
"Wait" = "Attendez";
/* No comment provided by engineer. */
"Wrong database passphrase" = "Mauvaise phrase secrète pour la base de données";
+40 -40
View File
@@ -219,11 +219,11 @@
E5DCF9712C590272007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF96F2C590272007928CC /* Localizable.strings */; };
E5DCF9842C5902CE007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9822C5902CE007928CC /* Localizable.strings */; };
E5DCF9982C5906FF007928CC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9962C5906FF007928CC /* InfoPlist.strings */; };
E5E218492C6813750013B4C6 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218442C6813750013B4C6 /* libgmpxx.a */; };
E5E2184A2C6813750013B4C6 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218452C6813750013B4C6 /* libffi.a */; };
E5E2184B2C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218462C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf-ghc9.6.3.a */; };
E5E2184C2C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218472C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf.a */; };
E5E2184D2C6813750013B4C6 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218482C6813750013B4C6 /* libgmp.a */; };
E5E218532C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E2184E2C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q-ghc9.6.3.a */; };
E5E218542C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E2184F2C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q.a */; };
E5E218552C6D4C0F0013B4C6 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218502C6D4C0F0013B4C6 /* libgmp.a */; };
E5E218562C6D4C0F0013B4C6 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218512C6D4C0F0013B4C6 /* libffi.a */; };
E5E218572C6D4C0F0013B4C6 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E218522C6D4C0F0013B4C6 /* libgmpxx.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -604,11 +604,11 @@
E5DCF9A62C590731007928CC /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E5DCF9A72C590732007928CC /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E5DCF9A82C590732007928CC /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E5E218442C6813750013B4C6 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
E5E218452C6813750013B4C6 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
E5E218462C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf-ghc9.6.3.a"; sourceTree = "<group>"; };
E5E218472C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf.a"; sourceTree = "<group>"; };
E5E218482C6813750013B4C6 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
E5E2184E2C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q-ghc9.6.3.a"; sourceTree = "<group>"; };
E5E2184F2C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q.a"; sourceTree = "<group>"; };
E5E218502C6D4C0F0013B4C6 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
E5E218512C6D4C0F0013B4C6 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
E5E218522C6D4C0F0013B4C6 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -647,14 +647,14 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E5E218492C6813750013B4C6 /* libgmpxx.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
E5E2184D2C6813750013B4C6 /* libgmp.a in Frameworks */,
E5E2184C2C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf.a in Frameworks */,
E5E218542C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
E5E2184B2C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf-ghc9.6.3.a in Frameworks */,
E5E2184A2C6813750013B4C6 /* libffi.a in Frameworks */,
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
E5E218572C6D4C0F0013B4C6 /* libgmpxx.a in Frameworks */,
E5E218562C6D4C0F0013B4C6 /* libffi.a in Frameworks */,
E5E218552C6D4C0F0013B4C6 /* libgmp.a in Frameworks */,
E5E218532C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q-ghc9.6.3.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -731,11 +731,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
E5E218452C6813750013B4C6 /* libffi.a */,
E5E218482C6813750013B4C6 /* libgmp.a */,
E5E218442C6813750013B4C6 /* libgmpxx.a */,
E5E218462C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf-ghc9.6.3.a */,
E5E218472C6813750013B4C6 /* libHSsimplex-chat-6.0.0.7-JAEd2ymO3CfCyjlINhbKkf.a */,
E5E218512C6D4C0F0013B4C6 /* libffi.a */,
E5E218502C6D4C0F0013B4C6 /* libgmp.a */,
E5E218522C6D4C0F0013B4C6 /* libgmpxx.a */,
E5E2184E2C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q-ghc9.6.3.a */,
E5E2184F2C6D4C0F0013B4C6 /* libHSsimplex-chat-6.0.0.8-9fvDFLivFrv8AINTqPH03q.a */,
);
path = Libraries;
sourceTree = "<group>";
@@ -1883,7 +1883,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1908,7 +1908,7 @@
"@executable_path/Frameworks",
);
LLVM_LTO = YES_THIN;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
@@ -1932,7 +1932,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1957,7 +1957,7 @@
"@executable_path/Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
@@ -1973,11 +1973,11 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -1993,11 +1993,11 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2018,7 +2018,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s;
@@ -2033,7 +2033,7 @@
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2055,7 +2055,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
@@ -2070,7 +2070,7 @@
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2092,7 +2092,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2118,7 +2118,7 @@
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
@@ -2143,7 +2143,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2169,7 +2169,7 @@
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
@@ -2194,7 +2194,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2209,7 +2209,7 @@
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2228,7 +2228,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 232;
CURRENT_PROJECT_VERSION = 233;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2243,7 +2243,7 @@
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.0;
MARKETING_VERSION = 6.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
+1 -1
View File
@@ -677,7 +677,7 @@
"Better messages" = "Verbesserungen bei Nachrichten";
/* No comment provided by engineer. */
"Better networking" = "Bessere Vernetzung";
"Better networking" = "Kontrollieren Sie Ihr Netzwerk";
/* No comment provided by engineer. */
"Black" = "Schwarz";
+10 -10
View File
@@ -596,7 +596,7 @@
"Archive and upload" = "Archivar y subir";
/* No comment provided by engineer. */
"Archive contacts to chat later." = "Archivar contactos para charlar más tarde.";
"Archive contacts to chat later." = "Archiva contactos para charlar más tarde.";
/* No comment provided by engineer. */
"Archived contacts" = "Contactos archivados";
@@ -713,7 +713,7 @@
"Blocked by admin" = "Bloqueado por administrador";
/* No comment provided by engineer. */
"Blur for better privacy." = "Difuminar para más privacidad.";
"Blur for better privacy." = "Difumina para mayor privacidad.";
/* No comment provided by engineer. */
"Blur media" = "Difuminar multimedia";
@@ -1089,7 +1089,7 @@
"Connection" = "Conexión";
/* No comment provided by engineer. */
"Connection and servers status." = "Estado de conexión y servidores.";
"Connection and servers status." = "Estado de tu conexión y servidores.";
/* No comment provided by engineer. */
"Connection error" = "Error conexión";
@@ -2048,7 +2048,7 @@
"Expand" = "Expandir";
/* No comment provided by engineer. */
"expired" = "expirado";
"expired" = "expirados";
/* No comment provided by engineer. */
"Export database" = "Exportar base de datos";
@@ -3253,7 +3253,7 @@
"peer-to-peer" = "p2p";
/* No comment provided by engineer. */
"Pending" = "Pendiente";
"Pending" = "Pendientes";
/* 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.";
@@ -3439,7 +3439,7 @@
"Protocol timeout per KB" = "Timeout protocolo por KB";
/* No comment provided by engineer. */
"Proxied" = "Con proxy";
"Proxied" = "Como proxy";
/* No comment provided by engineer. */
"Proxied servers" = "Servidores con proxy";
@@ -3956,7 +3956,7 @@
"Sent at: %@" = "Enviado: %@";
/* No comment provided by engineer. */
"Sent directly" = "Enviado directamente";
"Sent directly" = "Directamente";
/* notification */
"Sent file event" = "Evento de archivo enviado";
@@ -3977,7 +3977,7 @@
"Sent total" = "Total enviados";
/* No comment provided by engineer. */
"Sent via proxy" = "Enviado vía proxy";
"Sent via proxy" = "Mediante proxy";
/* No comment provided by engineer. */
"Server address" = "Dirección del servidor";
@@ -4352,7 +4352,7 @@
"The app can notify you when you receive messages or contact requests - please open settings to enable." = "La aplicación puede notificarte cuando recibas mensajes o solicitudes de contacto: por favor, abre la configuración para activarlo.";
/* No comment provided by engineer. */
"The app will ask to confirm downloads from unknown file servers (except .onion)." = "La aplicación pedirá que confirmes las descargas desde servidores de archivos desconocidos (excepto .onion).";
"The app will ask to confirm downloads from unknown file servers (except .onion)." = "La aplicación pedirá que confirmes las descargas desde servidores de archivos desconocidos (excepto si son .onion).";
/* No comment provided by engineer. */
"The attempt to change database passphrase was not completed." = "El intento de cambiar la contraseña de la base de datos no se ha completado.";
@@ -4709,7 +4709,7 @@
"Use the app while in the call." = "Usar la aplicación durante la llamada.";
/* No comment provided by engineer. */
"Use the app with one hand." = "Usa la aplicación con una mano.";
"Use the app with one hand." = "Usa la aplicación con una sola mano.";
/* No comment provided by engineer. */
"User profile" = "Perfil de usuario";
+187 -13
View File
@@ -314,7 +314,7 @@
"A separate TCP connection will be used **for each contact and group member**.\n**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail." = "Une connexion TCP distincte sera utilisée **pour chaque contact et membre de groupe**.\n**Veuillez noter** : 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.";
/* No comment provided by engineer. */
"Abort" = "Annuler";
"Abort" = "Abandonner";
/* No comment provided by engineer. */
"Abort changing address" = "Annuler le changement d'adresse";
@@ -472,6 +472,9 @@
/* No comment provided by engineer. */
"Allow calls only if your contact allows them." = "Autoriser les appels que si votre contact les autorise.";
/* No comment provided by engineer. */
"Allow calls?" = "Autoriser les appels?";
/* No comment provided by engineer. */
"Allow disappearing messages only if your contact allows it to you." = "Autorise les messages éphémères seulement si votre contact vous lautorise.";
@@ -590,7 +593,13 @@
"Apply to" = "Appliquer à";
/* No comment provided by engineer. */
"Archive and upload" = "Archiver et transférer";
"Archive and upload" = "Archiver et téléverser";
/* No comment provided by engineer. */
"Archive contacts to chat later." = "Archiver les contacts pour discuter plus tard.";
/* No comment provided by engineer. */
"Archived contacts" = "Contacts archivés";
/* No comment provided by engineer. */
"Archiving database" = "Archivage de la base de données";
@@ -667,6 +676,9 @@
/* No comment provided by engineer. */
"Better messages" = "Meilleurs messages";
/* No comment provided by engineer. */
"Better networking" = "Meilleure gestion de réseau";
/* No comment provided by engineer. */
"Black" = "Noir";
@@ -700,6 +712,9 @@
/* No comment provided by engineer. */
"Blocked by admin" = "Bloqué par l'administrateur";
/* No comment provided by engineer. */
"Blur for better privacy." = "Rendez les images floues et protégez-les contre les regards indiscrets.";
/* No comment provided by engineer. */
"Blur media" = "Flouter les médias";
@@ -727,6 +742,9 @@
/* 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)." = "Par profil de chat (par défaut) ou [par connexion](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).";
/* No comment provided by engineer. */
"call" = "appeler";
/* No comment provided by engineer. */
"Call already ended!" = "Appel déjà terminé !";
@@ -742,15 +760,27 @@
/* No comment provided by engineer. */
"Calls" = "Appels";
/* No comment provided by engineer. */
"Calls prohibited!" = "Les appels ne sont pas autorisés!";
/* No comment provided by engineer. */
"Camera not available" = "Caméra non disponible";
/* No comment provided by engineer. */
"Can't call contact" = "Impossible d'appeler le contact";
/* No comment provided by engineer. */
"Can't call member" = "Impossible d'appeler le membre";
/* No comment provided by engineer. */
"Can't invite contact!" = "Impossible d'inviter le contact!";
/* No comment provided by engineer. */
"Can't invite contacts!" = "Impossible d'inviter les contacts !";
/* No comment provided by engineer. */
"Can't message member" = "Impossible d'envoyer un message à ce membre";
/* No comment provided by engineer. */
"Cancel" = "Annuler";
@@ -836,6 +866,9 @@
/* No comment provided by engineer. */
"Chat database deleted" = "Base de données du chat supprimée";
/* No comment provided by engineer. */
"Chat database exported" = "Exportation de la base de données des discussions";
/* No comment provided by engineer. */
"Chat database imported" = "Base de données du chat importée";
@@ -848,6 +881,9 @@
/* No comment provided by engineer. */
"Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat." = "Le chat est arrêté. Si vous avez déjà utilisé cette base de données sur un autre appareil, vous devez la transférer à nouveau avant de démarrer le chat.";
/* No comment provided by engineer. */
"Chat list" = "Liste de discussion";
/* No comment provided by engineer. */
"Chat migrated!" = "Messagerie transférée!";
@@ -899,6 +935,9 @@
/* No comment provided by engineer. */
"Clear verification" = "Retirer la vérification";
/* No comment provided by engineer. */
"Color chats with the new themes." = "Colorez vos discussions avec les nouveaux thèmes.";
/* No comment provided by engineer. */
"Color mode" = "Mode de couleur";
@@ -915,7 +954,7 @@
"complete" = "complet";
/* No comment provided by engineer. */
"Completed" = "Complété";
"Completed" = "Complétées";
/* No comment provided by engineer. */
"Configure ICE servers" = "Configurer les serveurs ICE";
@@ -926,6 +965,9 @@
/* No comment provided by engineer. */
"Confirm" = "Confirmer";
/* No comment provided by engineer. */
"Confirm contact deletion?" = "Confirmer la suppression du contact?";
/* No comment provided by engineer. */
"Confirm database upgrades" = "Confirmer la mise à niveau de la base de données";
@@ -965,6 +1007,9 @@
/* No comment provided by engineer. */
"connect to SimpleX Chat developers." = "se connecter aux developpeurs de SimpleX Chat.";
/* No comment provided by engineer. */
"Connect to your friends faster." = "Connectez-vous à vos amis plus rapidement.";
/* No comment provided by engineer. */
"Connect to yourself?" = "Se connecter à soi-même ?";
@@ -1031,6 +1076,9 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Connexion au serveur… (erreur : %@)";
/* No comment provided by engineer. */
"Connecting to contact, please wait or check later!" = "Connexion au contact, veuillez patienter ou vérifier plus tard!";
/* No comment provided by engineer. */
"Connecting to desktop" = "Connexion au bureau";
@@ -1040,6 +1088,9 @@
/* No comment provided by engineer. */
"Connection" = "Connexion";
/* No comment provided by engineer. */
"Connection and servers status." = "État de la connexion et des serveurs.";
/* No comment provided by engineer. */
"Connection error" = "Erreur de connexion";
@@ -1079,6 +1130,9 @@
/* No comment provided by engineer. */
"Contact already exists" = "Contact déjà existant";
/* No comment provided by engineer. */
"Contact deleted!" = "Contact supprimé !";
/* No comment provided by engineer. */
"contact has e2e encryption" = "Ce contact a le chiffrement de bout en bout";
@@ -1091,12 +1145,18 @@
/* notification */
"Contact is connected" = "Le contact est connecté";
/* No comment provided by engineer. */
"Contact is deleted." = "Le contact est supprimé.";
/* No comment provided by engineer. */
"Contact name" = "Nom du contact";
/* No comment provided by engineer. */
"Contact preferences" = "Préférences de contact";
/* No comment provided by engineer. */
"Contact will be deleted - this cannot be undone!" = "Le contact sera supprimé - il n'est pas possible de revenir en arrière!";
/* No comment provided by engineer. */
"Contacts" = "Contacts";
@@ -1106,6 +1166,9 @@
/* No comment provided by engineer. */
"Continue" = "Continuer";
/* No comment provided by engineer. */
"Conversation deleted!" = "Conversation supprimée!";
/* No comment provided by engineer. */
"Copy" = "Copier";
@@ -1158,7 +1221,7 @@
"Create your profile" = "Créez votre profil";
/* No comment provided by engineer. */
"Created" = "Créé";
"Created" = "Créées";
/* No comment provided by engineer. */
"Created at" = "Créé à";
@@ -1329,6 +1392,9 @@
/* No comment provided by engineer. */
"Delete contact" = "Supprimer le contact";
/* No comment provided by engineer. */
"Delete contact?" = "Supprimer le contact?";
/* No comment provided by engineer. */
"Delete database" = "Supprimer la base de données";
@@ -1392,14 +1458,20 @@
/* server test step */
"Delete queue" = "Supprimer la file d'attente";
/* No comment provided by engineer. */
"Delete up to 20 messages at once." = "Supprimez jusqu'à 20 messages à la fois.";
/* No comment provided by engineer. */
"Delete user profile?" = "Supprimer le profil utilisateur ?";
/* No comment provided by engineer. */
"Delete without notification" = "Supprimer sans notification";
/* deleted chat item */
"deleted" = "supprimé";
/* No comment provided by engineer. */
"Deleted" = "Supprimé";
"Deleted" = "Supprimées";
/* No comment provided by engineer. */
"Deleted at" = "Supprimé à";
@@ -1455,6 +1527,9 @@
/* No comment provided by engineer. */
"Develop" = "Développer";
/* No comment provided by engineer. */
"Developer options" = "Options pour les développeurs";
/* No comment provided by engineer. */
"Developer tools" = "Outils du développeur";
@@ -2461,6 +2536,9 @@
/* group name */
"invitation to group %@" = "invitation au groupe %@";
/* No comment provided by engineer. */
"invite" = "inviter";
/* No comment provided by engineer. */
"Invite friends" = "Inviter des amis";
@@ -2506,6 +2584,9 @@
/* No comment provided by engineer. */
"It can happen when:\n1. The messages expired in the sending client after 2 days or on the server after 30 days.\n2. Message decryption failed, because you or your contact used old database backup.\n3. The connection was compromised." = "Cela peut arriver quand :\n1. Les messages ont expiré dans le client expéditeur après 2 jours ou sur le serveur après 30 jours.\n2. Le déchiffrement du message a échoué, car vous ou votre contact avez utilisé une ancienne sauvegarde de base de données.\n3. La connexion a été compromise.";
/* No comment provided by engineer. */
"It protects your IP address and connections." = "Il protège votre adresse IP et vos connexions.";
/* No comment provided by engineer. */
"It seems like you are already connected via this link. If it is not the case, there was an error (%@)." = "Il semblerait que vous êtes déjà connecté via ce lien. Si ce n'est pas le cas, il y a eu une erreur (%@).";
@@ -2548,6 +2629,9 @@
/* No comment provided by engineer. */
"Keep" = "Conserver";
/* No comment provided by engineer. */
"Keep conversation" = "Garder la conversation";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Garder l'application ouverte pour l'utiliser depuis le bureau";
@@ -2659,6 +2743,9 @@
/* No comment provided by engineer. */
"Max 30 seconds, received instantly." = "Max 30 secondes, réception immédiate.";
/* No comment provided by engineer. */
"Media & file servers" = "Serveurs de fichiers et de médias";
/* blur media */
"Medium" = "Modéré";
@@ -2689,6 +2776,9 @@
/* No comment provided by engineer. */
"Menus" = "Menus";
/* No comment provided by engineer. */
"message" = "message";
/* item status text */
"Message delivery error" = "Erreur de distribution du message";
@@ -2725,6 +2815,9 @@
/* No comment provided by engineer. */
"Message reception" = "Réception de message";
/* No comment provided by engineer. */
"Message servers" = "Serveurs de messages";
/* No comment provided by engineer. */
"Message source remains private." = "La source du message reste privée.";
@@ -2833,6 +2926,9 @@
/* No comment provided by engineer. */
"Multiple chat profiles" = "Différents profils de chat";
/* No comment provided by engineer. */
"mute" = "muet";
/* swipe action */
"Mute" = "Muet";
@@ -2866,6 +2962,9 @@
/* No comment provided by engineer. */
"New chat" = "Nouveau chat";
/* No comment provided by engineer. */
"New chat experience 🎉" = "Nouvelle expérience de discussion 🎉";
/* notification */
"New contact request" = "Nouvelle demande de contact";
@@ -2884,6 +2983,9 @@
/* No comment provided by engineer. */
"New in %@" = "Nouveautés de la %@";
/* No comment provided by engineer. */
"New media options" = "Nouvelles options de médias";
/* No comment provided by engineer. */
"New member role" = "Nouveau rôle";
@@ -3012,6 +3114,9 @@
/* No comment provided by engineer. */
"Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Seuls les appareils clients stockent les profils des utilisateurs, les contacts, les groupes et les messages envoyés avec un **chiffrement de bout en bout à deux couches**.";
/* No comment provided by engineer. */
"Only delete conversation" = "Ne supprimer que la conversation";
/* No comment provided by engineer. */
"Only group owners can change group preferences." = "Seuls les propriétaires du groupe peuvent modifier les préférences du groupe.";
@@ -3168,6 +3273,12 @@
/* No comment provided by engineer. */
"PING interval" = "Intervalle de PING";
/* No comment provided by engineer. */
"Play from the chat list." = "Aperçu depuis la liste de conversation.";
/* No comment provided by engineer. */
"Please ask your contact to enable calls." = "Veuillez demander à votre contact d'autoriser les appels.";
/* No comment provided by engineer. */
"Please ask your contact to enable sending voice messages." = "Veuillez demander à votre contact de permettre l'envoi de messages vocaux.";
@@ -3348,6 +3459,9 @@
/* No comment provided by engineer. */
"Rate the app" = "Évaluer l'app";
/* No comment provided by engineer. */
"Reachable chat toolbar" = "Barre d'outils accessible";
/* chat item menu */
"React…" = "Réagissez…";
@@ -3535,6 +3649,9 @@
/* No comment provided by engineer. */
"Reset" = "Réinitialisation";
/* No comment provided by engineer. */
"Reset all hints" = "Rétablir tous les conseils";
/* No comment provided by engineer. */
"Reset all statistics" = "Réinitialiser toutes les statistiques";
@@ -3610,6 +3727,9 @@
/* No comment provided by engineer. */
"Save and notify group members" = "Enregistrer et en informer les membres du groupe";
/* No comment provided by engineer. */
"Save and reconnect" = "Sauvegarder et se reconnecter";
/* No comment provided by engineer. */
"Save and update group profile" = "Enregistrer et mettre à jour le profil du groupe";
@@ -3685,6 +3805,9 @@
/* No comment provided by engineer. */
"Scan server QR code" = "Scanner un code QR de serveur";
/* No comment provided by engineer. */
"search" = "rechercher";
/* No comment provided by engineer. */
"Search" = "Rechercher";
@@ -3710,7 +3833,7 @@
"Secure queue" = "File d'attente sécurisée";
/* No comment provided by engineer. */
"Secured" = "Sécurisé";
"Secured" = "Sécurisées";
/* No comment provided by engineer. */
"Security assessment" = "Évaluation de sécurité";
@@ -3764,11 +3887,14 @@
"Send errors" = "Erreurs d'envoi";
/* No comment provided by engineer. */
"Send link previews" = "Envoi d'aperçus de liens";
"Send link previews" = "Aperçu des liens";
/* No comment provided by engineer. */
"Send live message" = "Envoyer un message dynamique";
/* No comment provided by engineer. */
"Send message to enable calls." = "Envoyer un message pour activer les appels.";
/* No comment provided by engineer. */
"Send messages directly when IP address is protected and your or destination server does not support private routing." = "Envoyer les messages de manière directe lorsque l'adresse IP est protégée et que votre serveur ou le serveur de destination ne prend pas en charge le routage privé.";
@@ -3869,7 +3995,7 @@
"Server requires authorization to create queues, check password" = "Le serveur requiert une autorisation pour créer des files d'attente, vérifiez le mot de passe";
/* server test error */
"Server requires authorization to upload, check password" = "Le serveur requiert une autorisation pour uploader, vérifiez le mot de passe";
"Server requires authorization to upload, check password" = "Le serveur requiert une autorisation pour téléverser, vérifiez le mot de passe";
/* No comment provided by engineer. */
"Server test failed!" = "Échec du test du serveur !";
@@ -3949,6 +4075,9 @@
/* No comment provided by engineer. */
"Share address with contacts?" = "Partager l'adresse avec vos contacts ?";
/* No comment provided by engineer. */
"Share from other apps." = "Partager depuis d'autres applications.";
/* No comment provided by engineer. */
"Share link" = "Partager le lien";
@@ -3971,7 +4100,7 @@
"Show developer options" = "Afficher les options pour les développeurs";
/* No comment provided by engineer. */
"Show last messages" = "Voir les derniers messages";
"Show last messages" = "Aperçu des derniers messages";
/* No comment provided by engineer. */
"Show message status" = "Afficher le statut du message";
@@ -3980,7 +4109,7 @@
"Show percentage" = "Afficher le pourcentage";
/* No comment provided by engineer. */
"Show preview" = "Afficher l'aperçu";
"Show preview" = "Aperçu affiché";
/* No comment provided by engineer. */
"Show QR code" = "Afficher le code QR";
@@ -4054,9 +4183,15 @@
/* blur media */
"Soft" = "Léger";
/* No comment provided by engineer. */
"Some file(s) were not exported:" = "Certains fichiers n'ont pas été exportés:";
/* No comment provided by engineer. */
"Some non-fatal errors occurred during import - you may see Chat console for more details." = "Des erreurs non fatales se sont produites lors de l'importation - vous pouvez consulter la console de chat pour plus de détails.";
/* No comment provided by engineer. */
"Some non-fatal errors occurred during import:" = "L'importation a entraîné des erreurs non fatales:";
/* notification title */
"Somebody" = "Quelqu'un";
@@ -4130,7 +4265,7 @@
"Submit" = "Soumettre";
/* No comment provided by engineer. */
"Subscribed" = "Inscrit";
"Subscribed" = "Inscriptions";
/* No comment provided by engineer. */
"Subscription errors" = "Erreurs d'inscription";
@@ -4171,6 +4306,9 @@
/* No comment provided by engineer. */
"Tap to scan" = "Appuyez pour scanner";
/* No comment provided by engineer. */
"TCP connection" = "Connexion TCP";
/* No comment provided by engineer. */
"TCP connection timeout" = "Délai de connexion TCP";
@@ -4363,9 +4501,15 @@
/* No comment provided by engineer. */
"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Pour vérifier le chiffrement de bout en bout avec votre contact, comparez (ou scannez) le code sur vos appareils.";
/* No comment provided by engineer. */
"Toggle chat list:" = "Afficher la liste des conversations:";
/* No comment provided by engineer. */
"Toggle incognito when connecting." = "Basculer en mode incognito lors de la connexion.";
/* No comment provided by engineer. */
"Toolbar opacity" = "Opacité de la barre d'outils";
/* No comment provided by engineer. */
"Total" = "Total";
@@ -4468,6 +4612,9 @@
/* authentication reason */
"Unlock app" = "Déverrouiller l'app";
/* No comment provided by engineer. */
"unmute" = "démuter";
/* swipe action */
"Unmute" = "Démute";
@@ -4489,6 +4636,9 @@
/* No comment provided by engineer. */
"Update network settings?" = "Mettre à jour les paramètres réseau ?";
/* No comment provided by engineer. */
"Update settings?" = "Mettre à jour les paramètres?";
/* rcv group event chat item */
"updated group profile" = "mise à jour du profil de groupe";
@@ -4508,7 +4658,7 @@
"Upload failed" = "Échec de l'envoi";
/* server test step */
"Upload file" = "Transférer le fichier";
"Upload file" = "Téléverser le fichier";
/* No comment provided by engineer. */
"Uploaded" = "Téléversé";
@@ -4558,6 +4708,9 @@
/* No comment provided by engineer. */
"Use the app while in the call." = "Utiliser l'application pendant l'appel.";
/* No comment provided by engineer. */
"Use the app with one hand." = "Utiliser l'application d'une main.";
/* No comment provided by engineer. */
"User profile" = "Profil d'utilisateur";
@@ -4612,6 +4765,9 @@
/* No comment provided by engineer. */
"Via secure quantum resistant protocol." = "Via un protocole sécurisé de cryptographie post-quantique.";
/* No comment provided by engineer. */
"video" = "vidéo";
/* No comment provided by engineer. */
"Video call" = "Appel vidéo";
@@ -4619,7 +4775,7 @@
"video call (not e2e encrypted)" = "appel vidéo (sans chiffrement)";
/* No comment provided by engineer. */
"Video will be received when your contact completes uploading it." = "La vidéo ne sera reçue que lorsque votre contact aura fini de la transférer.";
"Video will be received when your contact completes uploading it." = "La vidéo ne sera reçue que lorsque votre contact aura fini la mettre en ligne.";
/* No comment provided by engineer. */
"Video will be received when your contact is online, please wait or check later!" = "La vidéo ne sera reçue que lorsque votre contact sera en ligne. Veuillez patienter ou vérifier plus tard !";
@@ -4822,6 +4978,9 @@
/* No comment provided by engineer. */
"You can accept calls from lock screen, without device and app authentication." = "Vous pouvez accepter des appels à partir de l'écran de verrouillage, sans authentification de l'appareil ou de l'application.";
/* No comment provided by engineer. */
"You can change it in Appearance settings." = "Vous pouvez choisir de le modifier dans les paramètres d'apparence.";
/* No comment provided by engineer. */
"You can create it later" = "Vous pouvez la créer plus tard";
@@ -4843,6 +5002,9 @@
/* notification body */
"You can now chat with %@" = "Vous pouvez maintenant envoyer des messages à %@";
/* No comment provided by engineer. */
"You can send messages to %@ from Archived contacts." = "Vous pouvez envoyer des messages à %@ à partir des contacts archivés.";
/* No comment provided by engineer. */
"You can set lock screen notification preview via settings." = "Vous pouvez configurer l'aperçu des notifications sur l'écran de verrouillage via les paramètres.";
@@ -4858,6 +5020,9 @@
/* No comment provided by engineer. */
"You can start chat via app Settings / Database or by restarting the app" = "Vous pouvez lancer le chat via Paramètres / Base de données ou en redémarrant l'app";
/* No comment provided by engineer. */
"You can still view conversation with %@ in the list of chats." = "Vous pouvez toujours voir la conversation avec %@ dans la liste des discussions.";
/* No comment provided by engineer. */
"You can turn on SimpleX Lock via Settings." = "Vous pouvez activer SimpleX Lock dans les Paramètres.";
@@ -4909,9 +5074,18 @@
/* snd group event chat item */
"you left" = "vous avez quitté";
/* No comment provided by engineer. */
"You may migrate the exported database." = "Vous pouvez migrer la base de données exportée.";
/* No comment provided by engineer. */
"You may save the exported archive." = "Vous pouvez enregistrer l'archive exportée.";
/* No comment provided by engineer. */
"You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." = "Vous devez utiliser la version la plus récente de votre base de données de chat sur un seul appareil UNIQUEMENT, sinon vous risquez de ne plus recevoir les messages de certains contacts.";
/* No comment provided by engineer. */
"You need to allow your contact to call to be able to call them." = "Vous devez autoriser votre contact à appeler pour pouvoir l'appeler.";
/* No comment provided by engineer. */
"You need to allow your contact to send voice messages to be able to send them." = "Vous devez autoriser votre contact à envoyer des messages vocaux pour pouvoir en envoyer.";
+17 -17
View File
@@ -209,10 +209,10 @@
"%lld members" = "%lld tag";
/* No comment provided by engineer. */
"%lld messages blocked" = "%lld üzenet blokkolva";
"%lld messages blocked" = "%lld üzenet letiltva";
/* No comment provided by engineer. */
"%lld messages blocked by admin" = "%lld üzenet blokkolva az admin által";
"%lld messages blocked by admin" = "%lld üzenet letiltva az admin által";
/* No comment provided by engineer. */
"%lld messages marked deleted" = "%lld törlésre megjelölt üzenet";
@@ -683,28 +683,28 @@
"Black" = "Fekete";
/* No comment provided by engineer. */
"Block" = "Blokkolás";
"Block" = "Letiltás";
/* No comment provided by engineer. */
"Block for all" = "Letiltás mindenki számára";
/* No comment provided by engineer. */
"Block group members" = "Csoporttagok blokkolása";
"Block group members" = "Csoporttagok letiltása";
/* No comment provided by engineer. */
"Block member" = "Tag blokkolása";
"Block member" = "Tag letiltása";
/* No comment provided by engineer. */
"Block member for all?" = "Mindenki számára letiltja ezt a tagot?";
/* No comment provided by engineer. */
"Block member?" = "Tag blokkolása?";
"Block member?" = "Tag letiltása?";
/* marked deleted chat item preview text */
"blocked" = "blokkolva";
"blocked" = "letiltva";
/* rcv group event chat item */
"blocked %@" = "letiltotta őt: %@";
"blocked %@" = "letiltotta %@-t";
/* marked deleted chat item preview text */
"blocked by admin" = "letiltva az admin által";
@@ -1999,7 +1999,7 @@
"Error switching profile!" = "Hiba a profil váltásakor!";
/* No comment provided by engineer. */
"Error synchronizing connection" = "Hiba a kapcsolat szinkronizálása során";
"Error synchronizing connection" = "Hiba a kapcsolat szinkronizálása közben";
/* No comment provided by engineer. */
"Error updating group link" = "Hiba a csoport hivatkozás frissítésekor";
@@ -2363,7 +2363,7 @@
"ICE servers (one per line)" = "ICE-kiszolgálók (soronként egy)";
/* No comment provided by engineer. */
"If you can't meet in person, show QR code in a video call, or share the link." = "Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás során, vagy ossza meg a hivatkozást.";
"If you can't meet in person, show QR code in a video call, or share the link." = "Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás közben, vagy ossza meg a hivatkozást.";
/* No comment provided by engineer. */
"If you enter this passcode when opening the app, all app data will be irreversibly removed!" = "Ha az alkalmazás megnyitásakor megadja ezt a jelkódot, az összes alkalmazásadat véglegesen törlődik!";
@@ -3998,7 +3998,7 @@
"Server requires authorization to upload, check password" = "A kiszolgálónak engedélyre van szüksége a várólisták feltöltéséhez, ellenőrizze jelszavát";
/* No comment provided by engineer. */
"Server test failed!" = "Sikertelen kiszolgáló-teszt!";
"Server test failed!" = "Sikertelen kiszolgáló teszt!";
/* No comment provided by engineer. */
"Server type" = "Kiszolgáló típusa";
@@ -4187,10 +4187,10 @@
"Some file(s) were not exported:" = "Néhány fájl nem került exportálásra:";
/* No comment provided by engineer. */
"Some non-fatal errors occurred during import - you may see Chat console for more details." = "Néhány nem végzetes hiba történt az importálás során további részletekért a csevegési konzolban olvashat.";
"Some non-fatal errors occurred during import - you may see Chat console for more details." = "Néhány nem végzetes hiba történt az importálás közben további részletekért a csevegési konzolban olvashat.";
/* No comment provided by engineer. */
"Some non-fatal errors occurred during import:" = "Néhány nem végzetes hiba történt az importálás során:";
"Some non-fatal errors occurred during import:" = "Néhány nem végzetes hiba történt az importálás közben:";
/* notification title */
"Somebody" = "Valaki";
@@ -4394,7 +4394,7 @@
"The next generation of private messaging" = "A privát üzenetküldés következő generációja";
/* No comment provided by engineer. */
"The old database was not removed during the migration, it can be deleted." = "A régi adatbázis nem került eltávolításra az átköltöztetés során, így törölhető.";
"The old database was not removed during the migration, it can be deleted." = "A régi adatbázis nem került eltávolításra az átköltöztetés közben, így törölhető.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Profilja csak az ismerőseivel kerül megosztásra.";
@@ -4553,7 +4553,7 @@
"Unblock member?" = "Tag feloldása?";
/* rcv group event chat item */
"unblocked %@" = "%@ feloldva";
"unblocked %@" = "feloldotta %@ letiltását";
/* No comment provided by engineer. */
"Unexpected migration state" = "Váratlan átköltöztetési állapot";
@@ -4973,7 +4973,7 @@
"you are observer" = "megfigyelő szerep";
/* snd group event chat item */
"you blocked %@" = "blokkolta őt: %@";
"you blocked %@" = "ön letiltotta %@-t";
/* No comment provided by engineer. */
"You can accept calls from lock screen, without device and app authentication." = "Hívásokat fogadhat a lezárási képernyőről, eszköz- és alkalmazáshitelesítés nélkül.";
@@ -5105,7 +5105,7 @@
"you shared one-time link incognito" = "egyszer használatos hivatkozást osztott meg inkognitóban";
/* snd group event chat item */
"you unblocked %@" = "feloldotta %@ blokkolását";
"you unblocked %@" = "ön feloldotta %@ letiltását";
/* No comment provided by engineer. */
"You will be connected to group when the group host's device is online, please wait or check later!" = "Akkor lesz kapcsolódva a csoporthoz, amikor a csoport tulajdonosának eszköze online lesz, várjon, vagy ellenőrizze később!";
+1 -1
View File
@@ -4502,7 +4502,7 @@
"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Per verificare la crittografia end-to-end con il tuo contatto, confrontate (o scansionate) il codice sui vostri dispositivi.";
/* No comment provided by engineer. */
"Toggle chat list:" = "Cambia elenco chat:";
"Toggle chat list:" = "Cambia l'elenco delle chat:";
/* No comment provided by engineer. */
"Toggle incognito when connecting." = "Attiva/disattiva l'incognito quando ti colleghi.";
@@ -19,6 +19,7 @@ import chat.simplex.common.views.chatlist.*
import chat.simplex.common.views.helpers.*
import chat.simplex.common.views.onboarding.*
import chat.simplex.common.platform.*
import chat.simplex.res.MR
import kotlinx.coroutines.*
import java.lang.ref.WeakReference
@@ -149,7 +150,12 @@ fun processIntent(intent: Intent?) {
"android.intent.action.VIEW" -> {
val uri = intent.data
if (uri != null) {
chatModel.appOpenUrl.value = null to uri.toURI()
val transformedUri = uri.toURIOrNull()
if (transformedUri != null) {
chatModel.appOpenUrl.value = null to transformedUri
} else {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_parsing_uri_title), generalGetString(MR.strings.error_parsing_uri_desc))
}
}
}
}
@@ -18,5 +18,6 @@ val NotificationsMode.requiresIgnoringBattery
lateinit var APPLICATION_ID: String
fun Uri.toURI(): URI = URI(toString().replace("\n", ""))
fun Uri.toURIOrNull(): URI? = try { toURI() } catch (e: Exception) { null }
fun URI.toUri(): Uri = Uri.parse(toString())
@@ -15,13 +15,14 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.graphics.drawable.DrawableCompat
@@ -35,11 +36,12 @@ import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.model.ChatModel
import chat.simplex.common.ui.theme.CurrentColors
import chat.simplex.common.views.chat.*
import chat.simplex.common.views.helpers.SharedContent
import chat.simplex.common.views.helpers.generalGetString
import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
import dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import java.lang.reflect.Field
import java.net.URI
@@ -52,6 +54,7 @@ actual fun PlatformTextField(
showDeleteTextButton: MutableState<Boolean>,
userIsObserver: Boolean,
placeholder: String,
showVoiceButton: Boolean,
onMessageChange: (String) -> Unit,
onUpArrow: () -> Unit,
onFilesPasted: (List<URI>) -> Unit,
@@ -82,7 +85,15 @@ actual fun PlatformTextField(
freeFocus = true
}
}
LaunchedEffect(Unit) {
snapshotFlow { ModalManager.start.modalCount.value }
.filter { it > 0 }
.collect {
freeFocus = true
}
}
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
AndroidView(modifier = Modifier, factory = {
val editText = @SuppressLint("AppCompatCustomView") object: EditText(it) {
override fun setOnReceiveContentListener(
@@ -113,7 +124,8 @@ actual fun PlatformTextField(
editText.setTextColor(textColor.toArgb())
editText.textSize = textStyle.value.fontSize.value * appPrefs.fontScale.get()
editText.background = ColorDrawable(Color.Transparent.toArgb())
editText.setPadding(paddingStart, paddingTop, paddingEnd, paddingBottom)
editText.textDirection = if (isRtl) EditText.TEXT_DIRECTION_LOCALE else EditText.TEXT_DIRECTION_ANY_RTL
editText.setPaddingRelative(paddingStart, paddingTop, paddingEnd, paddingBottom)
editText.setText(cs.message)
editText.hint = placeholder
editText.setHintTextColor(hintColor.toArgb())
@@ -241,10 +241,15 @@ private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int,
}
actual fun getFileName(uri: URI): String? {
return androidAppContext.contentResolver.query(uri.toUri(), null, null, null, null)?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
cursor.getString(nameIndex)
return try {
androidAppContext.contentResolver.query(uri.toUri(), null, null, null, null)?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
// Can make an exception
cursor.getString(nameIndex)
}
} catch (e: Exception) {
null
}
}
@@ -333,7 +333,7 @@ fun StartPartOfScreen(settingsState: SettingsViewState) {
fun CenterPartOfScreen() {
val currentChatId = remember { ChatModel.chatId }
LaunchedEffect(Unit) {
snapshotFlow { currentChatId }
snapshotFlow { currentChatId.value }
.distinctUntilChanged()
.collect {
if (it != null) {
@@ -275,6 +275,11 @@ object ChatModel {
}
}
suspend fun addChatItem(rhId: Long?, cInfo: ChatInfo, cItem: ChatItem) {
// mark chat non deleted
if (cInfo is ChatInfo.Direct && cInfo.chatDeleted) {
val updatedContact = cInfo.contact.copy(chatDeleted = false)
updateContact(rhId, updatedContact)
}
// update previews
val i = getChatIndex(rhId, cInfo.id)
val chat: Chat
@@ -879,6 +884,11 @@ interface NamedChat {
val localAlias: String
val chatViewName: String
get() = localAlias.ifEmpty { displayName + (if (fullName == "" || fullName == displayName) "" else " / $fullName") }
fun anyNameContains(searchAnyCase: String): Boolean {
val s = searchAnyCase.trim().lowercase()
return chatViewName.lowercase().contains(s) || displayName.lowercase().contains(s) || fullName.lowercase().contains(s)
}
}
interface SomeChat {
@@ -1482,21 +1492,23 @@ data class GroupMember (
val memberContactId: Long? = null,
val memberContactProfileId: Long,
var activeConn: Connection? = null
) {
): NamedChat {
val id: String get() = "#$groupId @$groupMemberId"
val displayName: String
override val displayName: String
get() {
val p = memberProfile
val name = p.localAlias.ifEmpty { p.displayName }
return pastMember(name)
}
val fullName: String get() = memberProfile.fullName
val image: String? get() = memberProfile.image
override val fullName: String get() = memberProfile.fullName
override val image: String? get() = memberProfile.image
val contactLink: String? = memberProfile.contactLink
val verified get() = activeConn?.connectionCode != null
val blocked get() = blockedByAdmin || !memberSettings.showMessages
val chatViewName: String
override val localAlias: String = memberProfile.localAlias
override val chatViewName: String
get() {
val p = memberProfile
val name = p.localAlias.ifEmpty { p.displayName + (if (p.fullName == "" || p.fullName == p.displayName) "" else " / ${p.fullName}") }
@@ -2136,12 +2136,6 @@ object ChatController {
val cInfo = r.chatItem.chatInfo
val cItem = r.chatItem.chatItem
if (active(r.user)) {
if (cInfo is ChatInfo.Direct && cInfo.chatDeleted) {
val updatedContact = cInfo.contact.copy(chatDeleted = false)
withChats {
updateContact(rhId, updatedContact)
}
}
withChats {
addChatItem(rhId, cInfo, cItem)
}
@@ -2529,6 +2523,8 @@ object ChatController {
ModalManager.fullscreen.closeModals()
fun showAlert(chatError: ChatError) {
when {
r.rcStopReason is RemoteCtrlStopReason.Disconnected ->
{}
r.rcStopReason is RemoteCtrlStopReason.ConnectionFailed
&& r.rcStopReason.chatError is ChatError.ChatErrorAgent
&& r.rcStopReason.chatError.agentError is AgentErrorType.RCP
@@ -15,6 +15,7 @@ expect fun PlatformTextField(
showDeleteTextButton: MutableState<Boolean>,
userIsObserver: Boolean,
placeholder: String,
showVoiceButton: Boolean,
onMessageChange: (String) -> Unit,
onUpArrow: () -> Unit,
onFilesPasted: (List<URI>) -> Unit,
@@ -10,7 +10,6 @@ import androidx.compose.foundation.lazy.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.*
import androidx.compose.ui.draw.drawWithCache
@@ -49,26 +48,17 @@ import kotlin.math.sign
// staleChatId means the id that was before chatModel.chatId becomes null. It's needed for Android only to make transition from chat
// to chat list smooth. Otherwise, chat view will become blank right before the transition starts
fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -> Unit) {
val shouldReturn = remember { mutableStateOf(false) }
val remoteHostId = remember { derivedStateOf { chatModel.chats.value.firstOrNull { chat -> chat.chatInfo.id == staleChatId.value }?.remoteHostId } }
val showSearch = rememberSaveable { mutableStateOf(false) }
val activeChatInfo = remember {
derivedStateOf {
val info = chatModel.chats.value.firstOrNull { chat -> chat.chatInfo.id == staleChatId.value }?.chatInfo
if (info == null) {
shouldReturn.value = true
}
return@derivedStateOf info ?: ChatInfo.Direct.sampleData
}
}
val activeChatInfo = remember { derivedStateOf { chatModel.chats.value.firstOrNull { chat -> chat.chatInfo.id == staleChatId.value }?.chatInfo } }
val user = chatModel.currentUser.value
if (shouldReturn.value || user == null) {
val chatInfo = activeChatInfo.value
if (chatInfo == null || user == null) {
LaunchedEffect(Unit) {
chatModel.chatId.value = null
ModalManager.end.closeModals()
}
} else {
val chatInfo = activeChatInfo.value
val searchText = rememberSaveable { mutableStateOf("") }
val useLinkPreviews = chatModel.controller.appPrefs.privacyLinkPreviews.get()
val composeState = rememberSaveable(saver = ComposeState.saver()) {
@@ -96,21 +86,17 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
.collect { chatId ->
markUnreadChatAsRead(chatId)
showSearch.value = false
selectedChatItems.value = null
}
}
}
KeyChangeEffect(chatModel.chatId.value) {
if (chatModel.chatId.value != null) {
selectedChatItems.value = null
}
}
val view = LocalMultiplatformView()
val chatRh = remoteHostId.value
// We need to have real unreadCount value for displaying it inside top right button
// Having activeChat reloaded on every change in it is inefficient (UI lags)
val unreadCount = remember {
derivedStateOf {
chatModel.chats.value.firstOrNull { chat -> chat.chatInfo.id == chatModel.chatId.value }?.chatStats?.unreadCount ?: 0
chatModel.chats.value.firstOrNull { chat -> chat.chatInfo.id == activeChatInfo.value?.id }?.chatStats?.unreadCount ?: 0
}
}
val clipboard = LocalClipboardManager.current
@@ -267,9 +253,9 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
}
}
},
loadPrevMessages = {
if (chatModel.chatId.value != activeChatInfo.value.id) return@ChatLayout
val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout)
loadPrevMessages = { chatId ->
val c = chatModel.getChat(chatId)
if (chatModel.chatId.value != chatId) return@ChatLayout
val firstId = chatModel.chatItems.value.firstOrNull()?.id
if (c != null && firstId != null) {
withBGApi {
@@ -279,7 +265,6 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
},
deleteMessage = { itemId, mode ->
withBGApi {
val cInfo = chatInfo
val toDeleteItem = chatModel.chatItems.value.firstOrNull { it.id == itemId }
val toModerate = toDeleteItem?.memberToModerate(chatInfo)
val groupInfo = toModerate?.first
@@ -295,8 +280,8 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
} else {
chatModel.controller.apiDeleteChatItems(
chatRh,
type = cInfo.chatType,
id = cInfo.apiId,
type = chatInfo.chatType,
id = chatInfo.apiId,
itemIds = listOf(itemId),
mode = mode
)
@@ -307,9 +292,9 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
toChatItem = deleted.toChatItem?.chatItem
withChats {
if (toChatItem != null) {
upsertChatItem(chatRh, cInfo, toChatItem)
upsertChatItem(chatRh, chatInfo, toChatItem)
} else {
removeChatItem(chatRh, cInfo, deletedChatItem)
removeChatItem(chatRh, chatInfo, deletedChatItem)
}
}
}
@@ -472,7 +457,10 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
markRead = { range, unreadCountAfter ->
withBGApi {
withChats {
markChatItemsRead(chatRh, chatInfo, range, unreadCountAfter)
// It's important to call it on Main thread. Otherwise, composable crash occurs from time-to-time without useful stacktrace
withContext(Dispatchers.Main) {
markChatItemsRead(chatRh, chatInfo, range, unreadCountAfter)
}
ntfManager.cancelNotificationsForChat(chatInfo.id)
chatModel.controller.apiChatRead(
chatRh,
@@ -486,8 +474,8 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
changeNtfsState = { enabled, currentValue -> toggleNotifications(chatRh, chatInfo, enabled, chatModel, currentValue) },
onSearchValueChanged = { value ->
if (searchText.value == value) return@ChatLayout
if (chatModel.chatId.value != activeChatInfo.value.id) return@ChatLayout
val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout) ?: return@ChatLayout
val c = chatModel.getChat(chatInfo.id) ?: return@ChatLayout
if (chatModel.chatId.value != chatInfo.id) return@ChatLayout
withBGApi {
apiFindMessages(c, chatModel, value)
searchText.value = value
@@ -556,7 +544,7 @@ fun startChatCall(remoteHostId: Long?, chatInfo: ChatInfo, media: CallMediaType)
@Composable
fun ChatLayout(
remoteHostId: State<Long?>,
chatInfo: State<ChatInfo>,
chatInfo: State<ChatInfo?>,
unreadCount: State<Int>,
composeState: MutableState<ComposeState>,
composeView: (@Composable () -> Unit),
@@ -569,7 +557,7 @@ fun ChatLayout(
back: () -> Unit,
info: () -> Unit,
showMemberInfo: (GroupInfo, GroupMember) -> Unit,
loadPrevMessages: () -> Unit,
loadPrevMessages: (ChatId) -> Unit,
deleteMessage: (Long, CIDeleteMode) -> Unit,
deleteMessages: (List<Long>) -> Unit,
receiveFile: (Long) -> Unit,
@@ -601,12 +589,11 @@ fun ChatLayout(
) {
val scope = rememberCoroutineScope()
val attachmentDisabled = remember { derivedStateOf { composeState.value.attachmentDisabled } }
Box(
Modifier
.fillMaxWidth()
.desktopOnExternalDrag(
enabled = !attachmentDisabled.value && rememberUpdatedState(chatInfo.value).value.userCanSend,
enabled = remember(attachmentDisabled.value, chatInfo.value?.userCanSend) { mutableStateOf(!attachmentDisabled.value && chatInfo.value?.userCanSend == true) }.value,
onFiles = { paths -> composeState.onFilesAttached(paths.map { it.toURI() }) },
onImage = {
// TODO: file is not saved anywhere?!
@@ -644,7 +631,10 @@ fun ChatLayout(
Scaffold(
topBar = {
if (selectedChatItems.value == null) {
ChatInfoToolbar(chatInfo, back, info, startCall, endCall, addMembers, openGroupLink, changeNtfsState, onSearchValueChanged, showSearch)
val chatInfo = chatInfo.value
if (chatInfo != null) {
ChatInfoToolbar(chatInfo, back, info, startCall, endCall, addMembers, openGroupLink, changeNtfsState, onSearchValueChanged, showSearch)
}
} else {
SelectedItemsTopToolbar(selectedChatItems)
}
@@ -669,13 +659,17 @@ fun ChatLayout(
Modifier)
.padding(contentPadding)
) {
ChatItemsList(
remoteHostId, chatInfo, unreadCount, composeState, searchValue,
useLinkPreviews, linkMode, selectedChatItems, showMemberInfo, loadPrevMessages, deleteMessage, deleteMessages,
receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat, forwardItem,
updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember,
setReaction, showItemDetails, markRead, setFloatingButton, onComposed, developerTools, showViaProxy,
)
val remoteHostId = remember { remoteHostId }.value
val chatInfo = remember { chatInfo }.value
if (chatInfo != null) {
ChatItemsList(
remoteHostId, chatInfo, unreadCount, composeState, searchValue,
useLinkPreviews, linkMode, selectedChatItems, showMemberInfo, loadPrevMessages, deleteMessage, deleteMessages,
receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat, forwardItem,
updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember,
setReaction, showItemDetails, markRead, setFloatingButton, onComposed, developerTools, showViaProxy,
)
}
}
}
}
@@ -685,7 +679,7 @@ fun ChatLayout(
@Composable
fun ChatInfoToolbar(
chatInfo: State<ChatInfo>,
chatInfo: ChatInfo,
back: () -> Unit,
info: () -> Unit,
startCall: (CallMediaType) -> Unit,
@@ -710,7 +704,6 @@ fun ChatInfoToolbar(
if (appPlatform.isAndroid) {
BackHandler(onBack = onBackClicked)
}
val chatInfo = chatInfo.value
val barButtons = arrayListOf<@Composable RowScope.() -> Unit>()
val menuItems = arrayListOf<@Composable () -> Unit>()
val activeCall by remember { chatModel.activeCall }
@@ -915,22 +908,10 @@ private fun ContactVerifiedShield() {
Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(18.dp * fontSizeSqrtMultiplier).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary)
}
data class CIListState(val scrolled: Boolean, val itemCount: Int, val keyboardState: KeyboardState)
val CIListStateSaver = run {
val scrolledKey = "scrolled"
val countKey = "itemCount"
val keyboardKey = "keyboardState"
mapSaver(
save = { mapOf(scrolledKey to it.scrolled, countKey to it.itemCount, keyboardKey to it.keyboardState) },
restore = { CIListState(it[scrolledKey] as Boolean, it[countKey] as Int, it[keyboardKey] as KeyboardState) }
)
}
@Composable
fun BoxWithConstraintsScope.ChatItemsList(
remoteHostId: State<Long?>,
chatInfo: State<ChatInfo>,
remoteHostId: Long?,
chatInfo: ChatInfo,
unreadCount: State<Int>,
composeState: MutableState<ComposeState>,
searchValue: State<String>,
@@ -938,7 +919,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
linkMode: SimplexLinkMode,
selectedChatItems: MutableState<Set<Long>?>,
showMemberInfo: (GroupInfo, GroupMember) -> Unit,
loadPrevMessages: () -> Unit,
loadPrevMessages: (ChatId) -> Unit,
deleteMessage: (Long, CIDeleteMode) -> Unit,
deleteMessages: (List<Long>) -> Unit,
receiveFile: (Long) -> Unit,
@@ -964,8 +945,6 @@ fun BoxWithConstraintsScope.ChatItemsList(
) {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
val remoteHostId = remember { remoteHostId }.value
val chatInfo = remember { chatInfo }.value
ScrollToBottom(chatInfo.id, listState, chatModel.chatItems)
var prevSearchEmptiness by rememberSaveable { mutableStateOf(searchValue.value.isEmpty()) }
// Scroll to bottom when search value changes from something to nothing and back
@@ -980,7 +959,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
}
}
PreloadItems(listState, ChatPagination.UNTIL_PRELOAD_COUNT, loadPrevMessages)
PreloadItems(chatInfo.id, listState, ChatPagination.UNTIL_PRELOAD_COUNT, loadPrevMessages)
Spacer(Modifier.size(8.dp))
val reversedChatItems by remember { derivedStateOf { chatModel.chatItems.asReversed() } }
@@ -991,6 +970,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
scope.launch { listState.animateScrollToItem(kotlin.math.min(reversedChatItems.lastIndex, index + 1), -maxHeightRounded) }
}
}
// TODO: Having this block on desktop makes ChatItemsList() to recompose twice on chatModel.chatId update instead of once
LaunchedEffect(chatInfo.id) {
var stopListening = false
snapshotFlow { listState.layoutInfo.visibleItemsInfo.lastIndex }
@@ -1343,14 +1323,17 @@ fun BoxWithConstraintsScope.FloatingButtons(
@Composable
fun PreloadItems(
chatId: String,
listState: LazyListState,
remaining: Int = 10,
onLoadMore: () -> Unit,
onLoadMore: (ChatId) -> Unit,
) {
// Prevent situation when initial load and load more happens one after another after selecting a chat with long scroll position from previous selection
val allowLoad = remember { mutableStateOf(false) }
val chatId = rememberUpdatedState(chatId)
val onLoadMore = rememberUpdatedState(onLoadMore)
LaunchedEffect(Unit) {
snapshotFlow { chatModel.chatId.value }
snapshotFlow { chatId.value }
.filterNotNull()
.collect {
allowLoad.value = listState.layoutInfo.totalItemsCount == listState.layoutInfo.visibleItemsInfo.size
@@ -1370,7 +1353,7 @@ fun PreloadItems(
}
.filter { it > 0 }
.collect {
onLoadMore()
onLoadMore.value(chatId.value)
}
}
}
@@ -88,6 +88,7 @@ fun SendMsgView(
showDeleteTextButton,
userIsObserver,
if (clicksOnTextFieldDisabled) "" else placeholder,
showVoiceButton,
onMessageChange,
editPrevMessage,
onFilesPasted
@@ -89,7 +89,8 @@ fun getContactsToAdd(chatModel: ChatModel, search: String): List<Contact> {
.map { it.chatInfo }
.filterIsInstance<ChatInfo.Direct>()
.map { it.contact }
.filter { c -> c.sendMsgEnabled && !c.nextSendGrpInv && c.contactId !in memberContactIds && c.chatViewName.lowercase().contains(s) }
.filter { c -> c.sendMsgEnabled && !c.nextSendGrpInv && c.contactId !in memberContactIds && c.anyNameContains(s)
}
.sortedBy { it.displayName.lowercase() }
.toList()
}
@@ -278,7 +278,12 @@ fun GroupChatInfoLayout(
scope.launch { listState.scrollToItem(0) }
}
val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue()) }
val filteredMembers = remember(members) { derivedStateOf { members.filter { it.chatViewName.lowercase().contains(searchText.value.text.trim().lowercase()) } } }
val filteredMembers = remember(members) {
derivedStateOf {
val s = searchText.value.text.trim().lowercase()
if (s.isEmpty()) members else members.filter { m -> m.anyNameContains(s) }
}
}
// LALAL strange scrolling
LazyColumnWithScrollBar(
Modifier
@@ -421,7 +421,10 @@ fun SubscriptionStatusIndicator(click: (() -> Unit)) {
}
}
SimpleButtonFrame(click = click) {
SimpleButtonFrame(
click = click,
disabled = chatModel.chatRunning.value != true
) {
SubscriptionStatusIndicatorView(subs = subs, hasSess = hasSess)
}
}
@@ -698,7 +701,7 @@ private fun ChatList(chatModel: ChatModel, searchText: MutableState<TextFieldVal
}
}
private fun filteredChats(
fun filteredChats(
showUnreadAndFavorites: Boolean,
searchShowingSimplexLink: State<Boolean>,
searchChatFilteredBySimplexLink: State<String?>,
@@ -719,18 +722,16 @@ private fun filteredChats(
if (s.isEmpty()) {
chat.id == chatModel.chatId.value || filtered(chat)
} else {
(viewNameContains(cInfo, s) ||
cInfo.contact.profile.displayName.lowercase().contains(s) ||
cInfo.contact.fullName.lowercase().contains(s))
cInfo.anyNameContains(s)
})
is ChatInfo.Group -> if (s.isEmpty()) {
chat.id == chatModel.chatId.value || filtered(chat) || cInfo.groupInfo.membership.memberStatus == GroupMemberStatus.MemInvited
} else {
viewNameContains(cInfo, s)
cInfo.anyNameContains(s)
}
is ChatInfo.Local -> s.isEmpty() || viewNameContains(cInfo, s)
is ChatInfo.ContactRequest -> s.isEmpty() || viewNameContains(cInfo, s)
is ChatInfo.ContactConnection -> (s.isNotEmpty() && cInfo.contactConnection.localAlias.lowercase().contains(s)) || (s.isEmpty() && chat.id == chatModel.chatId.value)
is ChatInfo.Local -> s.isEmpty() || cInfo.anyNameContains(s)
is ChatInfo.ContactRequest -> s.isEmpty() || cInfo.anyNameContains(s)
is ChatInfo.ContactConnection -> (s.isNotEmpty() && cInfo.anyNameContains(s)) || (s.isEmpty() && chat.id == chatModel.chatId.value)
is ChatInfo.InvalidJSON -> chat.id == chatModel.chatId.value
}
}
@@ -742,6 +743,3 @@ private fun filtered(chat: Chat): Boolean =
(chat.chatInfo.chatSettings?.favorite ?: false) ||
chat.chatStats.unreadChat ||
(chat.chatInfo.ntfsEnabled && chat.chatStats.unreadCount > 0)
private fun viewNameContains(cInfo: ChatInfo, s: String): Boolean =
cInfo.chatViewName.lowercase().contains(s.lowercase())
@@ -203,12 +203,8 @@ private fun ShareList(
val oneHandUI = remember { appPrefs.oneHandUI.state }
val chats by remember(search) {
derivedStateOf {
val sorted = chatModel.chats.value.toList().sortedByDescending { it.chatInfo is ChatInfo.Local }
if (search.isEmpty()) {
sorted.filter { it.chatInfo.ready }
} else {
sorted.filter { it.chatInfo.ready && it.chatInfo.chatViewName.lowercase().contains(search.lowercase()) }
}
val sorted = chatModel.chats.value.toList().filter { it.chatInfo.ready }.sortedByDescending { it.chatInfo is ChatInfo.Local }
filteredChats(false, mutableStateOf(false), mutableStateOf(null), search, sorted)
}
}
LazyColumnWithScrollBar(
@@ -61,9 +61,6 @@ fun ContactListNavLinkView(chat: Chat, nextChatSelected: State<Boolean>, showDel
ContactType.CHAT_DELETED -> {
withApi {
openChat(rhId, chat.chatInfo, chatModel)
withChats {
updateContact(rhId, chat.chatInfo.contact.copy(chatDeleted = false))
}
ModalManager.start.closeModals()
}
}
@@ -10,7 +10,6 @@ import androidx.compose.material.TextFieldDefaults.indicatorLine
import androidx.compose.material.TextFieldDefaults.textFieldWithLabelPadding
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
@@ -25,10 +24,12 @@ import androidx.compose.ui.text.input.*
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.common.platform.*
import chat.simplex.res.MR
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun SearchTextField(
modifier: Modifier,
@@ -50,6 +51,25 @@ fun SearchTextField(
keyboard?.show()
}
}
if (appPlatform.isAndroid) {
LaunchedEffect(Unit) {
val modalCountOnOpen = ModalManager.start.modalCount.value
launch {
snapshotFlow { ModalManager.start.modalCount.value }
.filter { it > modalCountOnOpen }
.collect {
keyboard?.hide()
}
}
}
KeyChangeEffect(chatModel.chatId.value) {
if (chatModel.chatId.value != null) {
// Delay is needed here because when ChatView is being opened and keyboard is hiding, bottom sheet (to choose attachment) is visible on a screen
delay(300)
keyboard?.hide()
}
}
}
DisposableEffect(Unit) {
onDispose {
@@ -35,8 +35,10 @@ import java.net.URI
@Composable
fun AddGroupView(chatModel: ChatModel, rh: RemoteHostInfo?, close: () -> Unit, closeAll: () -> Unit) {
val rhId = rh?.remoteHostId
val view = LocalMultiplatformView()
AddGroupLayout(
createGroup = { incognito, groupProfile ->
hideKeyboard(view)
withBGApi {
val groupInfo = chatModel.controller.apiNewGroup(rhId, incognito, groupProfile)
if (groupInfo != null) {
@@ -491,9 +491,7 @@ private fun filterChat(chat: Chat, searchText: String, showUnreadAndFavorites: B
val cInfo = chat.chatInfo
if (searchText.isNotEmpty()) {
meetsPredicate = viewNameContains(cInfo, s) ||
if (cInfo is ChatInfo.Direct) (cInfo.contact.profile.displayName.lowercase().contains(s) ||
cInfo.contact.fullName.lowercase().contains(s)) else false
meetsPredicate = cInfo.anyNameContains(s)
}
if (showUnreadAndFavorites) {
@@ -503,9 +501,6 @@ private fun filterChat(chat: Chat, searchText: String, showUnreadAndFavorites: B
return meetsPredicate
}
private fun viewNameContains(cInfo: ChatInfo, s: String): Boolean =
cInfo.chatViewName.lowercase().contains(s.lowercase())
private val chatsByTypeComparator = Comparator<Chat> { chat1, chat2 ->
val chat1Type = chatContactType(chat1)
val chat2Type = chatContactType(chat2)
@@ -100,10 +100,14 @@ fun SettingsLayout(
) {
val scope = rememberCoroutineScope()
val closeSettings: () -> Unit = { scope.launch { drawerState.close() } }
val view = LocalMultiplatformView()
if (drawerState.isOpen) {
BackHandler {
closeSettings()
}
LaunchedEffect(Unit) {
hideKeyboard(view)
}
}
val theme = CurrentColors.collectAsState()
val uriHandler = LocalUriHandler.current
@@ -307,7 +307,7 @@ 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.hidden) && (s == "" || u.user.chatViewName.lowercase().contains(lower))) {
if ((u.user.activeUser || !u.user.hidden) && (s == "" || u.user.anyNameContains(lower))) {
true
} else {
correctPassword(u.user, s)
@@ -2065,4 +2065,6 @@
<string name="v6_0_upgrade_app_descr">نزّل الإصدارات الجديدة من GitHub.</string>
<string name="v6_0_upgrade_app">ترقية التطبيق تلقائيًا</string>
<string name="reset_all_hints">صفّر كافة التلميحات</string>
<string name="error_parsing_uri_desc">يُرجى التأكد من أن رابط SimpleX صحيح.</string>
<string name="error_parsing_uri_title">الرابط غير صالح</string>
</resources>
@@ -13,6 +13,8 @@
<string name="you_will_join_group">You will connect to all group members.</string>
<string name="connect_via_link_verb">Connect</string>
<string name="connect_via_link_incognito">Connect incognito</string>
<string name="error_parsing_uri_title">Invalid link</string>
<string name="error_parsing_uri_desc">Please check that SimpleX link is correct.</string>
<!-- MainActivity.kt -->
<string name="opening_database">Opening database…</string>
@@ -2149,4 +2149,6 @@
<string name="chat_database_exported_save">Sie können das exportierte Archiv speichern.</string>
<string name="reset_all_hints">Alle Hinweise zurücksetzen</string>
<string name="new_message">Neue Nachricht</string>
<string name="error_parsing_uri_desc">Bitte überprüfen Sie, ob der SimpleX-Link korrekt ist.</string>
<string name="error_parsing_uri_title">Ungültiger Link</string>
</resources>
@@ -1378,7 +1378,7 @@
<string name="rcv_group_event_open_chat">Abrir</string>
<string name="v5_3_encrypt_local_files">Cifra archivos almacenados y multimedia</string>
<string name="error_creating_member_contact">Error al establecer contacto con el miembro</string>
<string name="socks_proxy_setting_limitations"><![CDATA[<b>Recuerda</b>: los servidores de retransmisión están conectados mediante SOCKS proxy. Las llamadas y las previsualizaciones de enlaces usan conexión directa.]]></string>
<string name="socks_proxy_setting_limitations"><![CDATA[<b>Recuerda</b>: los servidores están conectados mediante proxy SOCKS, pero las llamadas y las previsualizaciones de enlaces usan conexión directa.]]></string>
<string name="encrypt_local_files">Cifra archivos locales</string>
<string name="v5_3_new_desktop_app">Nueva aplicación para ordenador!</string>
<string name="v5_3_new_interface_languages">6 idiomas nuevos para el interfaz</string>
@@ -1804,7 +1804,7 @@
<string name="protect_ip_address">Proteger dirección IP</string>
<string name="without_tor_or_vpn_ip_address_will_be_visible_to_file_servers">Sin Tor o VPN, tu dirección IP será visible para los servidores de archivos.</string>
<string name="settings_section_title_files">ARCHIVOS</string>
<string name="app_will_ask_to_confirm_unknown_file_servers">La aplicación pedirá confirmar las descargas desde servidores de archivos desconocidos (excepto .onion o cuando se active SOCKS proxy).</string>
<string name="app_will_ask_to_confirm_unknown_file_servers">La aplicación pedirá que confirmes las descargas desde servidores de archivos desconocidos (excepto si son .onion o cuando esté habilitado el proxy SOCKS).</string>
<string name="settings_section_title_chat_colors">Colores del chat</string>
<string name="settings_section_title_chat_theme">Tema del chat</string>
<string name="chat_theme_apply_to_mode">Aplicar a</string>
@@ -1947,7 +1947,7 @@
<string name="servers_info_messages_received">Mensajes recibidos</string>
<string name="servers_info_messages_sent">Mensajes enviados</string>
<string name="servers_info_missing">Sin información, intenta recargar</string>
<string name="servers_info_subscriptions_connections_pending">Pendiente</string>
<string name="servers_info_subscriptions_connections_pending">Pendientes</string>
<string name="servers_info_previously_connected_servers_section_header">Servidores conectados previamente</string>
<string name="servers_info_proxied_servers_section_header">Servidores con proxy</string>
<string name="servers_info_detailed_statistics_received_messages_header">Mensajes recibidos</string>
@@ -1961,20 +1961,20 @@
<string name="servers_info_reset_stats">Restablecer todas las estadísticas</string>
<string name="servers_info_reset_stats_alert_title">¿Restablecer todas las estadísticas?</string>
<string name="servers_info_detailed_statistics_sent_messages_header">Mensajes enviados</string>
<string name="servers_info_detailed_statistics_sent_messages_total">Total enviado</string>
<string name="servers_info_detailed_statistics_sent_messages_total">Total enviados</string>
<string name="downloaded_files">Archivos descargados</string>
<string name="download_errors">Errores de descarga</string>
<string name="duplicates_label">duplicados</string>
<string name="expired_label">expirado</string>
<string name="expired_label">expirados</string>
<string name="open_server_settings_button">Abrir configuración del servidor</string>
<string name="other_label">otros</string>
<string name="other_errors">otros errores</string>
<string name="proxied">Con proxy</string>
<string name="proxied">Como proxy</string>
<string name="reconnect">Reconectar</string>
<string name="secured">Aseguradas</string>
<string name="send_errors">Errores de envío</string>
<string name="sent_directly">Enviado directamente</string>
<string name="sent_via_proxy">Enviado mediante proxy</string>
<string name="sent_directly">Directamente</string>
<string name="sent_via_proxy">Mediante proxy</string>
<string name="server_address">Dirección del servidor</string>
<string name="size">Tamaño</string>
<string name="servers_info_subscriptions_connections_subscribed">Conexiones activas</string>
@@ -1984,10 +1984,10 @@
<string name="chunks_deleted">Bloques eliminados</string>
<string name="chunks_downloaded">Bloques descargados</string>
<string name="chunks_uploaded">Bloques subidos</string>
<string name="acknowledged">Reconocido</string>
<string name="acknowledgement_errors">Errores de reconocimiento</string>
<string name="acknowledged">Confirmaciones</string>
<string name="acknowledgement_errors">Errores de confirmación</string>
<string name="cant_call_contact_connecting_wait_alert_text">Conectando con el contacto, por favor espera o revisa más tarde.</string>
<string name="v6_0_connection_servers_status_descr">Estado de conexión y servidores.</string>
<string name="v6_0_connection_servers_status_descr">Estado de tu conexión y servidores.</string>
<string name="v6_0_connect_faster_descr">Conecta más rápido con tus amigos</string>
<string name="v6_0_connection_servers_status">Controla tu red</string>
<string name="v6_0_private_routing_descr">Protege tu dirección IP y tus conexiones.</string>
@@ -2023,7 +2023,7 @@
<string name="deleted_chats">Contactos archivados</string>
<string name="message_servers">Servidores de mensajes</string>
<string name="media_and_file_servers">Servidores de archivos y multimedia</string>
<string name="network_socks_proxy">SOCKS proxy</string>
<string name="network_socks_proxy">Proxy SOCKS</string>
<string name="privacy_media_blur_radius_off">No</string>
<string name="chat_database_exported_continue">Continuar</string>
<string name="chat_database_exported_not_all_files">Algunos archivos no han sido exportados</string>
@@ -2036,7 +2036,7 @@
<string name="cant_call_member_send_message_alert_text">Enviar mensaje para activar llamadas.</string>
<string name="v6_0_delete_many_messages_descr">Elimina hasta 20 mensajes a la vez.</string>
<string name="v6_0_reachable_chat_toolbar">Barra de herramientas accesible</string>
<string name="v6_0_your_contacts_descr">Archivar contactos para charlar más tarde.</string>
<string name="v6_0_your_contacts_descr">Archiva contactos para charlar más tarde.</string>
<string name="chat_database_exported_save">Puedes guardar el archivo exportado.</string>
<string name="privacy_media_blur_radius_strong">Fuerte</string>
<string name="moderate_messages_will_be_deleted_warning">Los mensajes serán eliminados para todos los miembros.</string>
@@ -2046,7 +2046,7 @@
<string name="you_can_still_view_conversation_with_contact">Aún puedes ver la conversación con %1$s en la lista de chats.</string>
<string name="chat_database_exported_migrate">Puedes migrar la base de datos exportada.</string>
<string name="network_option_tcp_connection">Conexión TCP</string>
<string name="v6_0_reachable_chat_toolbar_descr">Usa la aplicación con una mano.</string>
<string name="v6_0_reachable_chat_toolbar_descr">Usa la aplicación con una sola mano.</string>
<string name="proxy_destination_error_broker_host">La dirección del servidor de destino de %1$s es incompatible con la configuración del servidor de reenvío %2$s.</string>
<string name="proxy_destination_error_broker_version">La versión del servidor de destino de %1$s es incompatible con el servidor de reenvío %2$s.</string>
<string name="contact_list_header_title">Tus contactos</string>
@@ -2056,10 +2056,10 @@
<string name="proxy_destination_error_failed_to_connect">El servidor de reenvío %1$s no ha podido conectarse al servidor de destino %2$s. Por favor, intentalo más tarde.</string>
<string name="smp_proxy_error_broker_version">La versión del servidor de reenvío es incompatible con la configuración de red: %1$s.</string>
<string name="no_filtered_contacts">Ningún contacto filtrado</string>
<string name="v6_0_privacy_blur">Difuminar para más privacidad</string>
<string name="v6_0_privacy_blur">Difumina para mayor privacidad</string>
<string name="create_address_button">Crear</string>
<string name="one_hand_ui_card_title">Alternar lista de chats:</string>
<string name="v6_0_increase_font_size">Aumenta el tamaño de la fuente.</string>
<string name="v6_0_increase_font_size">Ajusta el tamaño de la fuente.</string>
<string name="v6_0_chat_list_media">Reproduce desde la lista de chats.</string>
<string name="v6_0_upgrade_app">Actualizar la aplicación automáticamente</string>
<string name="invite_friends_short">Invitar</string>
@@ -89,7 +89,7 @@
<string name="periodic_notifications_desc">L\'application récupère périodiquement les nouveaux messages - elle utilise un peu votre batterie chaque jour. L\'application n\'utilise pas les notifications push - les données de votre appareil ne sont pas envoyées aux serveurs.</string>
<string name="to_preserve_privacy_simplex_has_background_service_instead_of_push_notifications_it_uses_a_few_pc_battery"><![CDATA[Pour protéger votre vie privée, au lieu des notifications push, l\'application possède un <b>SimpleX service de fond</b> - il utilise quelques pour cent de la batterie par jour.]]></string>
<string name="hide_notification">Cacher</string>
<string name="settings_notification_preview_mode_title">Afficher l\'aperçu</string>
<string name="settings_notification_preview_mode_title">Aperçu affiché</string>
<string name="notification_preview_mode_contact">Nom du contact</string>
<string name="notification_preview_somebody">Contact masqué :</string>
<string name="notification_preview_new_message">nouveau message</string>
@@ -342,7 +342,7 @@
<string name="your_ICE_servers">Vos serveurs ICE</string>
<string name="configure_ICE_servers">Configurer les serveurs ICE</string>
<string name="network_settings">Paramètres réseau avancés</string>
<string name="network_settings_title">Paramètres réseau</string>
<string name="network_settings_title">Paramètres avancés</string>
<string name="network_enable_socks">Utiliser un proxy SOCKS \?</string>
<string name="network_disable_socks">Utiliser une connexion Internet directe \?</string>
<string name="network_disable_socks_info">Si vous confirmez, les serveurs de messagerie seront en mesure de voir votre adresse IP, votre fournisseur ainsi que les serveurs auxquels vous vous connectez.</string>
@@ -370,7 +370,7 @@
<string name="callstate_received_answer">réponse reçu…</string>
<string name="callstate_received_confirmation">confimation reçu…</string>
<string name="callstate_connecting">connexion…</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">Protocole et code open-source n\'importe qui peut heberger un serveur.</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">N\'importe qui peut heberger un serveur.</string>
<string name="to_protect_privacy_simplex_has_ids_for_queues">Pour protéger votre vie privée, au lieu d\'IDs utilisés par toutes les autres plateformes, SimpleX possède des IDs pour les queues de messages, distinctes pour chacun de vos contacts.</string>
<string name="read_more_in_github">Plus d\'informations sur notre GitHub.</string>
<string name="paste_the_link_you_received">Collez le lien que vous avez reçu</string>
@@ -440,11 +440,12 @@
<string name="callstate_waiting_for_confirmation">en attente de confirmation…</string>
<string name="callstate_connected">connecté</string>
<string name="callstate_ended">terminé</string>
<string name="next_generation_of_private_messaging">La nouvelle génération de messagerie privée</string>
<string name="next_generation_of_private_messaging">La nouvelle génération
\nde messagerie privée</string>
<string name="privacy_redefined">La vie privée redéfinie</string>
<string name="first_platform_without_user_ids">La 1ère plateforme sans aucun identifiant d\'utilisateur privée par design.</string>
<string name="immune_to_spam_and_abuse">Protégé du spam et des abus</string>
<string name="people_can_connect_only_via_links_you_share">On ne peut se connecter à vous quavec les liens que vous partagez.</string>
<string name="first_platform_without_user_ids">Aucun identifiant d\'utilisateur.</string>
<string name="immune_to_spam_and_abuse">Protégé du spam</string>
<string name="people_can_connect_only_via_links_you_share">Vous choisissez qui peut se connecter.</string>
<string name="decentralized">Décentralisé</string>
<string name="create_your_profile">Créez votre profil</string>
<string name="make_private_connection">Établir une connexion privée</string>
@@ -453,8 +454,8 @@
<string name="many_people_asked_how_can_it_deliver"><![CDATA[Beaucoup se demandent : <i>si SimpleX n\'a pas d\'identifiant d\'utilisateur, comment peut-il transmettre des messages \?</i>]]></string>
<string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages"><![CDATA[Seuls les appareils clients stockent les profils des utilisateurs, les contacts, les groupes et les messages envoyés avec un <b>chiffrement de bout en bout à deux couches</b>.]]></string>
<string name="read_more_in_github_with_link"><![CDATA[Pour en savoir plus, consultez notre <font color="#0088ff">GitHub repository</font>.]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Batterie peu utilisée</b>. Le service de fond vérifie les messages toutes les 10 minutes. Vous risquez de manquer des appels ou des messages urgents.]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Batterie plus utilisée </b> ! Le service de fond est toujours en cours d\'exécution - les notifications s\'affichent dès que les messages sont disponibles.]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Batterie peu utilisée</b>. L\'app vérifie les messages toutes les 10 minutes. Vous risquez de manquer des appels ou des messages urgents.]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Consomme davantage de batterie </b> L\'app fonctionne toujours en arrière-plan - les notifications s\'affichent instantanément.]]></string>
<string name="integrity_msg_skipped">%1$d message(s) manqué(s)</string>
<string name="integrity_msg_bad_id">ID de message incorrecte</string>
<string name="settings_section_title_settings">PARAMÈTRES</string>
@@ -567,7 +568,7 @@
<string name="you_sent_group_invitation">Vous avez envoyé une invitation de groupe</string>
<string name="rcv_group_event_member_left">a quitté</string>
<string name="icon_descr_speaker_on">Haut-parleur ON</string>
<string name="send_link_previews">Envoi d\'aperçus de liens</string>
<string name="send_link_previews">Aperçu des liens</string>
<string name="error_deleting_database">Erreur lors de la suppression de la base de données du chat</string>
<string name="error_stopping_chat">Erreur lors de l\'arrêt du chat</string>
<string name="error_exporting_chat_database">Erreur lors de l\'exportation de la base de données du chat</string>
@@ -1018,7 +1019,7 @@
<string name="videos_limit_title">Trop de vidéos !</string>
<string name="video_descr">Vidéo</string>
<string name="icon_descr_video_snd_complete">Vidéo envoyée</string>
<string name="video_will_be_received_when_contact_completes_uploading">La vidéo ne sera reçue que lorsque votre contact aura fini de la transférer.</string>
<string name="video_will_be_received_when_contact_completes_uploading">La vidéo ne sera reçue que lorsque votre contact aura fini la mettre en ligne.</string>
<string name="icon_descr_waiting_for_video">En attente de la vidéo</string>
<string name="waiting_for_video">En attente de la vidéo</string>
<string name="video_will_be_received_when_contact_is_online">La vidéo ne sera reçue que lorsque votre contact sera en ligne. Veuillez patienter ou vérifier plus tard !</string>
@@ -1028,8 +1029,8 @@
<string name="smp_server_test_delete_file">Supprimer le fichier</string>
<string name="error_saving_xftp_servers">Erreur lors de la sauvegarde des serveurs XFTP</string>
<string name="ensure_xftp_server_address_are_correct_format_and_unique">Assurez-vous que les adresses des serveurs XFTP sont au bon format, séparées par des lignes et qu\'elles ne sont pas dupliquées.</string>
<string name="error_xftp_test_server_auth">Le serveur requiert une autorisation pour uploader, vérifiez le mot de passe</string>
<string name="smp_server_test_upload_file">Transférer le fichier</string>
<string name="error_xftp_test_server_auth">Le serveur requiert une autorisation pour téléverser, vérifiez le mot de passe</string>
<string name="smp_server_test_upload_file">Téléverser le fichier</string>
<string name="xftp_servers">Serveurs XFTP</string>
<string name="your_XFTP_servers">Vos serveurs XFTP</string>
<string name="smp_server_test_compare_file">Comparer le fichier</string>
@@ -1240,13 +1241,13 @@
<string name="share_text_sent_at">Envoyé le : %s</string>
<string name="sent_message">Message envoyé</string>
<string name="item_info_no_text">aucun texte</string>
<string name="non_fatal_errors_occured_during_import">Des erreurs non fatales se sont produites lors de l\'importation - vous pouvez consulter la console de chat pour plus de détails.</string>
<string name="non_fatal_errors_occured_during_import">L\'importation a entraîné des erreurs non fatales:</string>
<string name="shutdown_alert_desc">Les notifications ne fonctionnent pas tant que vous ne relancez pas l\'application</string>
<string name="shutdown_alert_question">Arrêt \?</string>
<string name="settings_shutdown">Mise à l\'arrêt</string>
<string name="settings_restart_app">Redémarrer</string>
<string name="settings_section_title_app">APP</string>
<string name="abort_switch_receiving_address_confirm">Annuler</string>
<string name="abort_switch_receiving_address_confirm">Abandonner</string>
<string name="error_aborting_address_change">Erreur lors de l\'annulation du changement d\'adresse</string>
<string name="abort_switch_receiving_address_question">Abandonner le changement d\'adresse \?</string>
<string name="abort_switch_receiving_address">Annuler le changement d\'adresse</string>
@@ -1357,7 +1358,7 @@
<string name="connect_use_current_profile">Utiliser le profil actuel</string>
<string name="connect_use_new_incognito_profile">Utiliser un nouveau profil incognito</string>
<string name="privacy_message_draft">Brouillon de message</string>
<string name="privacy_show_last_messages">Voir les derniers messages</string>
<string name="privacy_show_last_messages">Aperçu des derniers messages</string>
<string name="rcv_group_event_2_members_connected">%s et %s sont connecté.es</string>
<string name="rcv_group_event_n_members_connected">%s, %s et %d autres membres sont connectés</string>
<string name="rcv_group_event_3_members_connected">%s, %s et %s sont connecté.es</string>
@@ -1640,7 +1641,7 @@
<string name="migrate_from_device_error_uploading_archive">Erreur lors de l\'envoi de l\'archive</string>
<string name="migrate_from_device_all_data_will_be_uploaded">Tous vos contacts, conversations et fichiers seront chiffrés en toute sécurité et transférés par morceaux vers les relais XFTP configurés.</string>
<string name="migrate_to_device_apply_onion">Appliquer</string>
<string name="migrate_from_device_archive_and_upload">Archiver et transférer</string>
<string name="migrate_from_device_archive_and_upload">Archiver et téléverser</string>
<string name="migrate_from_device_archiving_database">Archivage de la base de données</string>
<string name="migrate_from_device_archive_will_be_deleted"><![CDATA[<b>Avertissement</b>: l\'archive sera supprimée.]]></string>
<string name="migrate_from_device_using_on_two_device_breaks_encryption"><![CDATA[<b>Remarque</b>: l\'utilisation d\'une même base de données sur deux appareils interrompra le déchiffrement des messages provenant de vos connexions, par mesure de sécurité.]]></string>
@@ -1782,7 +1783,7 @@
<string name="network_smp_proxy_fallback_allow_downgrade">Autoriser la rétrogradation</string>
<string name="update_network_smp_proxy_mode_question">Mode de routage des messages</string>
<string name="network_smp_proxy_mode_never">Jamais</string>
<string name="network_smp_proxy_mode_unknown">Relais inconnus</string>
<string name="network_smp_proxy_mode_unknown">Serveurs inconnus</string>
<string name="network_smp_proxy_fallback_prohibit">Non</string>
<string name="network_smp_proxy_fallback_allow_protected">Lorsque l\'IP est masquée</string>
<string name="network_smp_proxy_fallback_allow">Oui</string>
@@ -1872,11 +1873,11 @@
<string name="all_users">Tous les profiles</string>
<string name="acknowledged">Reçu avec accusé de réception</string>
<string name="app_check_for_updates_download_completed_title">La mise à jour de l\'app est téléchargée</string>
<string name="completed">Terminé</string>
<string name="completed">Complétées</string>
<string name="current_user">Profil actuel</string>
<string name="decryption_errors">Erreurs de déchiffrement</string>
<string name="member_info_member_disabled">désactivé</string>
<string name="deleted">Supprimé</string>
<string name="deleted">Supprimées</string>
<string name="app_check_for_updates_notice_disable">Désactiver</string>
<string name="app_check_for_updates_download_started">Téléchargement de la mise à jour de l\'appli, ne pas fermer l\'appli</string>
<string name="app_check_for_updates_button_download">Téléchargement %s (%s)</string>
@@ -1970,17 +1971,17 @@
<string name="acknowledgement_errors">Erreurs d\'accusé de réception</string>
<string name="chunks_uploaded">Chunks téléversés</string>
<string name="connections">Connexions</string>
<string name="created">Créé</string>
<string name="created">Créées</string>
<string name="deletion_errors">Erreurs de suppression</string>
<string name="duplicates_label">doublons</string>
<string name="expired_label">expiré</string>
<string name="open_server_settings_button">Ouvrir les paramètres du serveur</string>
<string name="other_label">autre</string>
<string name="other_errors">autres erreurs</string>
<string name="secured">Sécurisé</string>
<string name="secured">Sécurisées</string>
<string name="send_errors">Erreurs d\'envoi</string>
<string name="size">Taille</string>
<string name="subscribed">Inscrit</string>
<string name="subscribed">Inscriptions</string>
<string name="subscription_errors">Erreurs d\'inscription</string>
<string name="subscription_results_ignored">Inscriptions ignorées</string>
<string name="uploaded_files">Fichiers téléversés</string>
@@ -2007,19 +2008,19 @@
<string name="info_view_search_button">rechercher</string>
<string name="info_view_video_button">vidéo</string>
<string name="contact_deleted">Contact supprimé !</string>
<string name="you_can_still_send_messages_to_contact">Vous pouvez toujours envoyer des messages à %1$s à partir des chats supprimés.</string>
<string name="deleted_chats">Discussions supprimées</string>
<string name="you_can_still_send_messages_to_contact">Vous pouvez envoyer des messages à %1$s à partir des contacts archivés.</string>
<string name="deleted_chats">Contacts archivés</string>
<string name="no_filtered_contacts">Pas de contacts filtrés</string>
<string name="paste_link">Coller le lien</string>
<string name="contact_list_header_title">Vos contacts</string>
<string name="one_hand_ui">Interface utilisateur à une main</string>
<string name="one_hand_ui">Barre d\'outils accessible</string>
<string name="cant_call_contact_deleted_alert_text">Le contact est supprimé.</string>
<string name="calls_prohibited_alert_title">Les appels ne sont pas autorisés!</string>
<string name="you_need_to_allow_calls">Vous devez autoriser votre contact à appeler pour pouvoir l\'appeler.</string>
<string name="cant_send_message_to_member_alert_title">Impossible d\'envoyer un message à ce membre du groupe</string>
<string name="you_can_still_view_conversation_with_contact">Vous pouvez toujours consulter la conversation avec %1$s dans la liste des conversation.</string>
<string name="allow_calls_question">Autoriser les appels?</string>
<string name="info_view_call_button">appel</string>
<string name="info_view_call_button">appeler</string>
<string name="cant_call_contact_alert_title">Impossible d\'appeler le contact</string>
<string name="cant_call_contact_connecting_wait_alert_text">Connexion au contact, veuillez patienter ou vérifier plus tard!</string>
<string name="cant_call_member_alert_title">Impossible d\'appeler ce membre du groupe</string>
@@ -2027,4 +2028,45 @@
<string name="action_button_add_members">Inviter</string>
<string name="calls_prohibited_ask_to_enable_calls_alert_text">Veuillez demander à votre contact d\'autoriser les appels.</string>
<string name="cant_call_member_send_message_alert_text">Envoyer un message pour activer les appels.</string>
<string name="v6_0_your_contacts_descr">Archiver les contacts pour discuter plus tard.</string>
<string name="v6_0_privacy_blur">Rendez les images floues et protégez-les contre les regards indiscrets.</string>
<string name="v6_0_connect_faster_descr">Connectez-vous à vos amis plus rapidement.</string>
<string name="v6_0_connection_servers_status_descr">État de la connexion et des serveurs.</string>
<string name="chat_database_exported_title">Exportation de la base de données des discussions</string>
<string name="chat_database_exported_continue">Poursuivre</string>
<string name="delete_messages_mark_deleted_warning">Les messages seront marqués comme étant à supprimer. Le(s) destinataire(s) pourra(ont) révéler ces messages.</string>
<string name="delete_members_messages__question">Supprimer %d messages de membres?</string>
<string name="compose_message_placeholder">Message</string>
<string name="v6_0_increase_font_size">Augmenter la taille de la police.</string>
<string name="create_address_button">Créer</string>
<string name="selected_chat_items_nothing_selected">Rien n\'est sélectionné</string>
<string name="error_parsing_uri_title">Lien invalide</string>
<string name="new_message">Nouveau message</string>
<string name="v6_0_new_media_options">Nouvelles options de médias</string>
<string name="invite_friends_short">Inviter</string>
<string name="v6_0_new_chat_experience">Nouvelle expérience de discussion 🎉</string>
<string name="v6_0_upgrade_app_descr">Téléchargez les nouvelles versions depuis GitHub.</string>
<string name="v6_0_private_routing_descr">Il protège votre adresse IP et vos connexions.</string>
<string name="v6_0_connection_servers_status">Maîtrisez votre réseau</string>
<string name="v6_0_delete_many_messages_descr">Supprimez jusqu\'à 20 messages à la fois.</string>
<string name="media_and_file_servers">Serveurs de fichiers et de médias</string>
<string name="message_servers">Serveurs de messages</string>
<string name="error_parsing_uri_desc">Veuillez vérifier que le lien SimpleX est exact.</string>
<string name="moderate_messages_will_be_deleted_warning">Les messages seront supprimés pour tous les membres.</string>
<string name="selected_chat_items_selected_n">%d sélectionné(s)</string>
<string name="v6_0_chat_list_media">Aperçu depuis la liste de conversation.</string>
<string name="moderate_messages_will_be_marked_warning">Les messages seront marqués comme modérés pour tous les membres.</string>
<string name="one_hand_ui_card_title">Afficher la liste des conversations:</string>
<string name="one_hand_ui_change_instruction">Vous pouvez choisir de le modifier dans les paramètres d\'apparence.</string>
<string name="reset_all_hints">Rétablir tous les conseils</string>
<string name="v6_0_upgrade_app">Mise à jour automatique de l\'app</string>
<string name="v6_0_reachable_chat_toolbar">Barre d\'outils accessible</string>
<string name="v6_0_reachable_chat_toolbar_descr">Utiliser l\'application d\'une main.</string>
<string name="select_verb">Choisir</string>
<string name="network_socks_proxy">proxy SOCKS</string>
<string name="chat_database_exported_save">Vous pouvez enregistrer l\'archive exportée.</string>
<string name="network_options_save_and_reconnect">Sauvegarder et se reconnecter</string>
<string name="network_option_tcp_connection">Connexion TCP</string>
<string name="chat_database_exported_not_all_files">Certains fichiers n\'ont pas été exportés</string>
<string name="chat_database_exported_migrate">Vous pouvez migrer la base de données exportée.</string>
</resources>
@@ -614,7 +614,7 @@
<string name="error_with_info">Hiba: %s</string>
<string name="v4_4_disappearing_messages">Eltűnő üzenetek</string>
<string name="auth_enable_simplex_lock">SimpleX zár bekapcsolása</string>
<string name="error_synchronizing_connection">Hiba a kapcsolat szinkronizálása során</string>
<string name="error_synchronizing_connection">Hiba a kapcsolat szinkronizálása közben</string>
<string name="error_creating_address">Hiba a cím létrehozásakor</string>
<string name="feature_enabled">engedélyezve</string>
<string name="error_loading_details">Hiba a részletek betöltésekor</string>
@@ -673,7 +673,7 @@
<string name="enter_one_ICE_server_per_line">ICE-kiszolgálók (soronként egy)</string>
<string name="if_you_cannot_meet_in_person_scan_QR_in_video_call_or_ask_for_invitation_link"><![CDATA[Ha nem tud személyesen találkozni, <b>beolvashatja a QR-kódot a videohívásban</b>, vagy az ismerőse megoszthat egy meghívó hivatkozást.]]></string>
<string name="if_you_enter_passcode_data_removed">Ha az alkalmazás megnyitásakor megadja ezt a jelkódot, az összes alkalmazásadat véglegesen törlődik!</string>
<string name="if_you_cant_meet_in_person">Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás során, vagy ossza meg a hivatkozást.</string>
<string name="if_you_cant_meet_in_person">Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás közben, vagy ossza meg a hivatkozást.</string>
<string name="if_you_cannot_meet_in_person_show_QR_in_video_call_or_via_another_channel"><![CDATA[Ha nem tud személyesen találkozni, <b>mutassa meg a QR-kódot a videohívásban</b>, vagy ossza meg a hivatkozást.]]></string>
<string name="network_disable_socks_info">Megerősítés esetén az üzenetküldő kiszolgálók látni fogják az IP-címét és a szolgáltatóját azt, hogy mely kiszolgálókhoz kapcsolódik.</string>
<string name="image_will_be_received_when_contact_completes_uploading">A kép akkor érkezik meg, amikor a küldője befejezte annak feltöltését.</string>
@@ -912,7 +912,7 @@
<string name="your_privacy">Adatvédelem</string>
<string name="your_simplex_contact_address">Az ön SimpleX címe</string>
<string name="alert_text_fragment_please_report_to_developers">Jelentse a fejlesztőknek.</string>
<string name="people_can_connect_only_via_links_you_share">Ön dönti el, hogy kivel beszélget</string>
<string name="people_can_connect_only_via_links_you_share">Ön dönti el, hogy kivel beszélget.</string>
<string name="prohibit_sending_disappearing">Az eltűnő üzenetek küldése le van tiltva.</string>
<string name="only_you_can_send_voice">Csak ön tud hangüzeneteket küldeni.</string>
<string name="update_network_settings_confirmation">Frissítés</string>
@@ -1270,7 +1270,7 @@
<string name="your_settings">Beállítások</string>
<string name="your_chat_database">Csevegési adatbázis</string>
<string name="rcv_group_event_member_deleted">%1$s eltávolítva</string>
<string name="smp_servers_test_failed">Sikertelen kiszolgáló-teszt!</string>
<string name="smp_servers_test_failed">Sikertelen kiszolgáló teszt!</string>
<string name="verify_connection">Kapcsolat ellenőrzése</string>
<string name="whats_new_read_more">Tudjon meg többet</string>
<string name="sender_cancelled_file_transfer">A fájl küldője visszavonta az átvitelt.</string>
@@ -1466,7 +1466,7 @@
<string name="group_invitation_tap_to_join_incognito">Koppintson az inkognitóban való kapcsolódáshoz</string>
<string name="set_password_to_export">Jelmondat beállítása az exportáláshoz</string>
<string name="receipts_groups_override_disabled">Kézbesítési jelentések le vannak tiltva a(z) %d csoportban</string>
<string name="non_fatal_errors_occured_during_import">Néhány nem végzetes hiba történt az importálás során:</string>
<string name="non_fatal_errors_occured_during_import">Néhány nem végzetes hiba történt az importálás közben:</string>
<string name="v4_5_italian_interface_descr">Köszönet a felhasználóknak - hozzájárulás a Weblaten!</string>
<string name="relay_server_if_necessary">Az átjátszó kiszolgáló csak szükség esetén kerül használatra. Egy másik fél megfigyelheti az IP-címet.</string>
<string name="v5_0_app_passcode_descr">Rendszerhitelesítés helyetti beállítás.</string>
@@ -1607,19 +1607,19 @@
<string name="v5_5_message_delivery_descr">Csökkentett akkumulátorhasználattal.</string>
<string name="v5_5_new_interface_languages">Magyar és török felhasználói felület</string>
<string name="v5_5_join_group_conversation_descr">A közelmúlt eseményei és továbbfejlesztett jegyzék bot.</string>
<string name="rcv_group_event_member_unblocked">%s letiltása feloldva</string>
<string name="snd_group_event_member_unblocked">%s letiltását visszavonta</string>
<string name="rcv_group_event_member_unblocked">feloldotta %s letiltását</string>
<string name="snd_group_event_member_unblocked">ön feloldotta %s letiltását</string>
<string name="member_info_member_blocked">letiltva</string>
<string name="blocked_by_admin_item_description">letiltva az admin által</string>
<string name="member_blocked_by_admin">Letiltva az admin által</string>
<string name="rcv_group_event_member_blocked">letiltotta őt: %s</string>
<string name="rcv_group_event_member_blocked">letiltotta %s-t</string>
<string name="block_for_all">Letiltás mindenki számára</string>
<string name="block_for_all_question">Mindenki számára letiltja ezt a tagot?</string>
<string name="blocked_by_admin_items_description">%d üzenet letiltva az admin által</string>
<string name="unblock_for_all">Letiltás feloldása mindenki számára</string>
<string name="unblock_for_all_question">Mindenki számára feloldja a tag letiltását?</string>
<string name="snd_group_event_member_blocked">letiltotta %s-t</string>
<string name="error_blocking_member_for_all">Hiba a tag mindenki számára való letiltása során</string>
<string name="snd_group_event_member_blocked">ön letiltotta %s-t</string>
<string name="error_blocking_member_for_all">Hiba a tag mindenki számára való letiltása közben</string>
<string name="message_too_large">Az üzenet túl nagy</string>
<string name="welcome_message_is_too_long">Az üdvözlő üzenet túl hosszú</string>
<string name="database_migration_in_progress">Az adatbázis átköltöztetése folyamatban van.
@@ -2061,4 +2061,6 @@
<string name="invite_friends_short">Meghívás</string>
<string name="v6_0_new_chat_experience">Új csevegési élmény 🎉</string>
<string name="new_message">Új üzenet</string>
<string name="error_parsing_uri_title">Érvénytelen hivatkozás</string>
<string name="error_parsing_uri_desc">Ellenőrizze, hogy a SimpleX hivatkozás helyes-e.</string>
</resources>
@@ -98,4 +98,6 @@
<string name="servers_info_sessions_connected">Terhubung</string>
<string name="completed">Selesai</string>
<string name="connected_mobile">Ponsel yang terhubung</string>
<string name="multicast_connect_automatically">Hubungkan secara otomatis</string>
<string name="callstate_connecting">menyambungkan…</string>
</resources>
@@ -2055,7 +2055,7 @@
<string name="v6_0_private_routing_descr">Protegge il tuo indirizzo IP e le connessioni.</string>
<string name="network_options_save_and_reconnect">Salva e riconnetti</string>
<string name="reset_all_hints">Ripristina tutti i suggerimenti</string>
<string name="one_hand_ui_card_title">Cambia elenco chat:</string>
<string name="one_hand_ui_card_title">Cambia l\'elenco delle chat:</string>
<string name="one_hand_ui_change_instruction">Puoi cambiarlo nelle impostazioni dell\'aspetto.</string>
<string name="v6_0_chat_list_media">Riproduci dall\'elenco delle chat.</string>
<string name="v6_0_increase_font_size">Aumenta la dimensione dei caratteri.</string>
@@ -2067,4 +2067,6 @@
<string name="create_address_button">Crea</string>
<string name="v6_0_upgrade_app_descr">Scarica nuove versioni da GitHub.</string>
<string name="new_message">Nuovo messaggio</string>
<string name="error_parsing_uri_title">Link non valido</string>
<string name="error_parsing_uri_desc">Controlla che il link SimpleX sia corretto.</string>
</resources>
@@ -1118,7 +1118,7 @@
<string name="color_title">Titel</string>
<string name="you_can_accept_or_reject_connection">Wanneer mensen vragen om verbinding te maken, kunt u dit accepteren of weigeren.</string>
<string name="you_wont_lose_your_contacts_if_delete_address">U raakt uw contacten niet kwijt als u later uw adres verwijdert.</string>
<string name="simplex_address">SimpleX cím</string>
<string name="simplex_address">SimpleX adres</string>
<string name="create_address_and_let_people_connect">Maak een adres aan zodat mensen contact met je kunnen opnemen.</string>
<string name="create_simplex_address">Maak een SimpleX adres aan</string>
<string name="share_with_contacts">Delen met contacten</string>
@@ -80,7 +80,7 @@
<string name="turning_off_service_and_periodic">Активована оптимізація батареї, вимикається фоновий сервіс і періодичні запити нових повідомлень. Ви можете знову увімкнути їх у налаштуваннях.</string>
<string name="back">Назад</string>
<string name="bold_text">жирний</string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Добре для акумулятора</b>. Сервіс фонового запуску перевіряє повідомлення кожні 10 хвилин. Ви можете пропустити виклики чи важливі повідомлення.]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Добре для акумулятора</b>. Додаток перевіряє повідомлення кожні 10 хвилин. Ви можете пропустити виклики чи важливі повідомлення.]]></string>
<string name="settings_audio_video_calls">Аудіо та відеовиклики</string>
<string name="icon_descr_audio_off">Аудіо вимкнено</string>
<string name="auth_unavailable">Аутентифікація недоступна</string>
@@ -248,7 +248,7 @@
<string name="saved_ICE_servers_will_be_removed">Збережені сервери WebRTC ICE будуть видалені.</string>
<string name="configure_ICE_servers">Налаштувати сервери ICE</string>
<string name="network_and_servers">Мережа та сервери</string>
<string name="network_settings_title">Налаштування мережі</string>
<string name="network_settings_title">Розширені налаштування</string>
<string name="network_enable_socks">Використовувати SOCKS-проксі?</string>
<string name="network_disable_socks">Використовувати прямий підключення до Інтернету?</string>
<string name="network_use_onion_hosts">Використовувати .onion-хости</string>
@@ -266,7 +266,7 @@
<string name="display_name">Введіть своє ім\'я:</string>
<string name="callstatus_in_progress">дзвінок в процесі</string>
<string name="callstate_starting">запуск…</string>
<string name="first_platform_without_user_ids">Перша платформа без ідентифікаторів користувачів – приватна за конструкцією.</string>
<string name="first_platform_without_user_ids">Ніяких ідентифікаторів користувачів.</string>
<string name="decentralized">Децентралізована</string>
<string name="use_chat">Використовувати чат</string>
<string name="onboarding_notifications_mode_subtitle">Це можна змінити пізніше в налаштуваннях.</string>
@@ -411,7 +411,7 @@
<string name="display_name__field">Ім\'я профілю:</string>
<string name="callstate_waiting_for_confirmation">очікування підтвердження…</string>
<string name="privacy_redefined">Приватність перевизначена</string>
<string name="people_can_connect_only_via_links_you_share">Люди можуть підключатися до вас лише за допомогою посилань, які ви надаєте.</string>
<string name="people_can_connect_only_via_links_you_share">Ви вирішуєте, хто може під\'єднатися.</string>
<string name="how_simplex_works">Як працює SimpleX</string>
<string name="read_more_in_github">Докладніше читайте в нашому репозиторії на GitHub.</string>
<string name="encrypted_audio_call">зашифрований e2e аудіовиклик</string>
@@ -659,7 +659,7 @@
<string name="you_control_servers_to_receive_your_contacts_to_send"><![CDATA[Ви контролюєте, через які сервери <b>отримувати</b> повідомлення, ваші контакти – сервери, які ви використовуєте для надсилання повідомлень їм.]]></string>
<string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages"><![CDATA[Тільки пристрої клієнта зберігають профілі користувачів, контакти, групи та повідомлення, відправлені за допомогою <b>шифрування на двох рівнях</b>.]]></string>
<string name="onboarding_notifications_mode_title">Приватні сповіщення</string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Споживає більше заряду акумулятора</b>! Фоновий сервіс завжди працює – сповіщення відображаються, як тільки повідомлення доступні.]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Споживає більше акумулятора</b>! Додаток завжди працює у фоновому режимі – сповіщення відображаються миттєво.]]></string>
<string name="paste_the_link_you_received">Вставте отримане посилання</string>
<string name="icon_descr_video_off">Відео вимкнено</string>
<string name="icon_descr_call_ended">Завершено виклик</string>
@@ -1053,7 +1053,7 @@
<string name="callstate_connecting">підключення…</string>
<string name="callstate_connected">підключено</string>
<string name="callstate_ended">завершено</string>
<string name="immune_to_spam_and_abuse">Стійка до спаму та зловживань</string>
<string name="immune_to_spam_and_abuse">Стійкий до спаму</string>
<string name="contact_wants_to_connect_via_call">%1$s хоче підключитися до вас через</string>
<string name="encrypted_video_call">зашифрований e2e відеовиклик</string>
<string name="ignore">Ігнорувати</string>
@@ -1172,8 +1172,9 @@
<string name="colored_text">кольоровий</string>
<string name="callstatus_ended">дзвінок завершено %1$s</string>
<string name="callstatus_error">помилка дзвінка</string>
<string name="next_generation_of_private_messaging">Наступне покоління приватного обміну повідомленнями</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">Відкритий протокол та код – кожен може запустити сервери.</string>
<string name="next_generation_of_private_messaging">Наступне покоління
\nприватних повідомлень</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">Кожен може хостити сервери.</string>
<string name="settings_developer_tools">Інструменти розробника</string>
<string name="settings_experimental_features">Експериментальні функції</string>
<string name="settings_section_title_calls">ДЗВІНКИ</string>
@@ -1234,7 +1235,7 @@
<string name="disable_onion_hosts_when_not_supported"><![CDATA[Встановіть <i>Використовувати .onion-хости</i> на Ні, якщо SOCKS-проксі їх не підтримує.]]></string>
<string name="show_dev_options">Показати:</string>
<string name="hide_dev_options">Сховати:</string>
<string name="non_fatal_errors_occured_during_import">Під час імпорту сталися деякі невідновні помилки - ви можете переглянути консоль чату для отримання більше деталей.</string>
<string name="non_fatal_errors_occured_during_import">Під час імпорту відбулися деякі непередбачувані помилки:</string>
<string name="enable_automatic_deletion_message">Цю дію неможливо відмінити - будуть видалені повідомлення, відправлені та отримані раніше вибраного часу. Це може зайняти декілька хвилин.</string>
<string name="you_have_to_enter_passphrase_every_time">Вам потрібно вводити ключову фразу кожен раз при запуску додатка - вона не зберігається на пристрої.</string>
<string name="change_database_passphrase_question">Змінити ключову фразу бази даних?</string>
@@ -1834,7 +1835,7 @@
<string name="simplex_links_not_allowed">Посилання SimpleX заборонені</string>
<string name="private_routing_show_message_status">Показати статус повідомлення</string>
<string name="private_routing_explanation">Щоб захистити вашу IP-адресу, приватна маршрутизація використовує ваші SMP-сервери для доставки повідомлень.</string>
<string name="network_smp_proxy_mode_unknown">Невідомі реле</string>
<string name="network_smp_proxy_mode_unknown">Невідомі сервери</string>
<string name="network_smp_proxy_mode_unprotected">Незахищений</string>
<string name="network_smp_proxy_fallback_allow_protected">Коли IP приховано</string>
<string name="network_smp_proxy_fallback_allow">Так</string>
@@ -1851,4 +1852,219 @@
<string name="message_queue_info_server_info">інформація про чергу на сервері: %1$s
\n
\nостаннє отримане повідомлення: %2$s</string>
<string name="proxy_destination_error_broker_host">Адреса сервера призначення %1$s несумісна з налаштуваннями сервера переадресації %2$s.</string>
<string name="file_error_no_file">Файл не знайдено — ймовірно, файл був видалений або скасований.</string>
<string name="scan_paste_link">Сканувати / Вставити посилання</string>
<string name="xftp_servers_configured">Налаштовані XFTP сервери</string>
<string name="app_check_for_updates_beta">Бета</string>
<string name="info_row_file_status">Статус файлу</string>
<string name="servers_info_messages_sent">Повідомлення надіслано</string>
<string name="servers_info_statistics_section_header">Статистика</string>
<string name="servers_info_previously_connected_servers_section_header">Попередньо підключені сервери</string>
<string name="file_error_auth">Помилковий ключ або невідома адреса чанка файлу - найбільш імовірно, що файл було видалено.</string>
<string name="error_parsing_uri_title">Недійсне посилання</string>
<string name="error_parsing_uri_desc">Будь ласка, перевірте, чи правильне посилання SimpleX.</string>
<string name="network_error_broker_host_desc">Адреса сервера несумісна з налаштуваннями мережі: %1$s.</string>
<string name="smp_proxy_error_connecting">Помилка підключення до сервера переадресації %1$s. Будь ласка, спробуйте пізніше.</string>
<string name="smp_proxy_error_broker_host">Адреса сервера переадресації несумісна з налаштуваннями мережі: %1$s.</string>
<string name="smp_proxy_error_broker_version">Версія сервера переадресації несумісна з налаштуваннями мережі: %1$s.</string>
<string name="private_routing_error">Помилка приватного маршрутизації</string>
<string name="proxy_destination_error_broker_version">Версія сервера призначення %1$s несумісна з сервером переадресації %2$s.</string>
<string name="please_try_later">Будь ласка, спробуйте пізніше.</string>
<string name="file_error_relay">Помилка сервера файлів: %1$s</string>
<string name="member_inactive_title">Учасник неактивний</string>
<string name="message_forwarded_title">Повідомлення переслано</string>
<string name="message_forwarded_desc">Поки що немає прямого з\'єднання, повідомлення пересилається адміністратором.</string>
<string name="selected_chat_items_selected_n">Вибрано %d</string>
<string name="compose_message_placeholder">Повідомлення</string>
<string name="file_error">Помилка файлу</string>
<string name="temporary_file_error">Тимчасова помилка файлу</string>
<string name="delete_contact_cannot_undo_warning">Контакт буде видалено - це неможливо скасувати!</string>
<string name="only_delete_conversation">Видалити лише розмову</string>
<string name="deleted_chats">Архівовані контакти</string>
<string name="app_check_for_updates_button_remind_later">Нагадати пізніше</string>
<string name="app_check_for_updates_stable">Стабільна</string>
<string name="v6_0_new_chat_experience">Новий досвід чату 🎉</string>
<string name="server_address">Адреса сервера</string>
<string name="confirm_delete_contact_question">Підтвердити видалення контакту?</string>
<string name="info_view_connect_button">підключитися</string>
<string name="proxy_destination_error_failed_to_connect">Сервер переадресації %1$s не зміг з\'єднатися з цільовим сервером %2$s. Будь ласка, спробуйте пізніше.</string>
<string name="member_inactive_desc">Повідомлення може бути доставлено пізніше, якщо учасник стане активним.</string>
<string name="selected_chat_items_nothing_selected">Нічого не вибрано</string>
<string name="open_server_settings_button">Відкрити налаштування сервера</string>
<string name="network_error_broker_version_desc">Версія сервера несумісна з вашим додатком: %1$s.</string>
<string name="moderate_messages_will_be_marked_warning">Повідомлення будуть позначені як модеровані для всіх учасників.</string>
<string name="v6_0_upgrade_app">Оновлювати додаток автоматично</string>
<string name="cannot_share_message_alert_title">Не вдалося надіслати повідомлення</string>
<string name="cannot_share_message_alert_text">Вибрані налаштування чату забороняють це повідомлення.</string>
<string name="share_text_file_status">Статус файлу: %s</string>
<string name="share_text_message_status">Статус повідомлення: %s</string>
<string name="new_message">Нове повідомлення</string>
<string name="create_address_button">Створити</string>
<string name="invite_friends_short">Запросити</string>
<string name="one_hand_ui_card_title">Перемикнути список чатів:</string>
<string name="one_hand_ui_change_instruction">Ви можете змінити це в налаштуваннях зовнішнього вигляду.</string>
<string name="info_row_message_status">Статус повідомлення</string>
<string name="v6_0_your_contacts_descr">Архівувати контакти, щоб поговорити пізніше.</string>
<string name="v6_0_chat_list_media">Відтворити зі списку чатів.</string>
<string name="v6_0_new_media_options">Нові опції медіа</string>
<string name="v6_0_privacy_blur">Розмиття для кращої конфіденційності.</string>
<string name="v6_0_increase_font_size">Збільшити розмір шрифту.</string>
<string name="v6_0_private_routing_descr">Він захищає вашу IP-адресу та з\'єднання.</string>
<string name="app_check_for_updates_notice_title">Перевірити, чи є оновлення</string>
<string name="v6_0_upgrade_app_descr">Завантажуйте нові версії з GitHub.</string>
<string name="allow_calls_question">Дозволити дзвінки?</string>
<string name="cant_call_contact_deleted_alert_text">Контакт видалено.</string>
<string name="network_option_tcp_connection">TCP з\'єднання</string>
<string name="appearance_zoom">Масштабування</string>
<string name="appearance_font_size">Розмір шрифту</string>
<string name="calls_prohibited_ask_to_enable_calls_alert_text">Будь ласка, попросіть вашого контакту увімкнути дзвінки.</string>
<string name="network_options_save_and_reconnect">Зберегти і перепідключитися</string>
<string name="v6_0_delete_many_messages_descr">Видалити до 20 повідомлень за один раз.</string>
<string name="v6_0_reachable_chat_toolbar">Доступна панель інструментів чату</string>
<string name="v6_0_reachable_chat_toolbar_descr">Користуватися застосунком однією рукою.</string>
<string name="v6_0_connect_faster_descr">З\'єднуйтеся з друзями швидше.</string>
<string name="v6_0_connection_servers_status">Керуйте своєю мережею</string>
<string name="servers_info_downloaded">Завантажено</string>
<string name="servers_info_reset_stats_alert_error_title">Помилка скидання статистики</string>
<string name="servers_info_reconnect_servers_title">Перепідключити сервери?</string>
<string name="servers_info_detailed_statistics_sent_messages_header">Надіслані повідомлення</string>
<string name="servers_info_reset_stats_alert_message">Статистика серверів буде скинута — це не можна буде відмінити!</string>
<string name="v6_0_connection_servers_status_descr">Статус з\'єднання та серверів.</string>
<string name="servers_info_detailed_statistics">Докладна статистика</string>
<string name="servers_info_detailed_statistics_receive_errors">Отримати помилки</string>
<string name="sent_directly">Надіслано безпосередньо</string>
<string name="servers_info_detailed_statistics_sent_messages_total">Надіслано загалом</string>
<string name="sent_via_proxy">Надіслано через проксі</string>
<string name="smp_server">Сервер SMP</string>
<string name="servers_info_starting_from">Починаючи з %s.</string>
<string name="servers_info_detailed_statistics_received_messages_header">Отримані повідомлення</string>
<string name="servers_info_detailed_statistics_received_total">Отримано загалом</string>
<string name="privacy_media_blur_radius">Розмити медіа</string>
<string name="privacy_media_blur_radius_medium">Середній</string>
<string name="privacy_media_blur_radius_off">Вимкнено</string>
<string name="privacy_media_blur_radius_soft">Слабке</string>
<string name="privacy_media_blur_radius_strong">Сильна</string>
<string name="member_info_member_disabled">вимкнено</string>
<string name="member_info_member_inactive">неактивний</string>
<string name="servers_info">Інформація про сервери</string>
<string name="servers_info_files_tab">Файли</string>
<string name="servers_info_missing">Ніякої інформації, спробуйте перезавантажити</string>
<string name="servers_info_subscriptions_connections_subscribed">Активні з\'єднання</string>
<string name="servers_info_sessions_connected">Підключено</string>
<string name="servers_info_connected_servers_section_header">Підключені сервери</string>
<string name="servers_info_sessions_connecting">Підключення</string>
<string name="servers_info_subscriptions_total">Всього</string>
<string name="servers_info_transport_sessions_section_header">Сесії передачі даних</string>
<string name="servers_info_proxied_servers_section_footer">Ви не підключені до цих серверів. Для доставки повідомлень до них використовується приватна маршрутизація.</string>
<string name="current_user">Поточний профіль</string>
<string name="servers_info_details">Деталі</string>
<string name="servers_info_sessions_errors">Помилки</string>
<string name="servers_info_subscriptions_section_header">Отримання повідомлення</string>
<string name="servers_info_messages_received">Повідомлення отримано</string>
<string name="servers_info_subscriptions_connections_pending">В очікуванні</string>
<string name="servers_info_proxied_servers_section_header">Проксіровані сервери</string>
<string name="servers_info_target">Показувати інформацію для</string>
<string name="servers_info_private_data_disclaimer">Починаючи з %s.
\nВсі дані зберігаються лише на вашому пристрою.</string>
<string name="servers_info_reconnect_server_message">Перепідключити сервер для примусової доставки повідомлень. Це використовує додатковий трафік.</string>
<string name="servers_info_reset_stats">Скинути всю статистику</string>
<string name="servers_info_reset_stats_alert_title">Скинути всю статистику?</string>
<string name="servers_info_modal_error_title">Помилка</string>
<string name="servers_info_reconnect_server_error">Помилка повторного підключення до сервера</string>
<string name="servers_info_reconnect_servers_error">Помилка повторного підключення до серверів</string>
<string name="servers_info_reconnect_servers_message">Перепідключити всі підключені сервери для примусової доставки повідомлень. Це використовує додатковий трафік.</string>
<string name="servers_info_reconnect_all_servers_button">Перепідключити всі сервери</string>
<string name="servers_info_reconnect_server_title">Перепідключити сервер?</string>
<string name="acknowledgement_errors">Помилки підтвердження</string>
<string name="duplicates_label">дублікати</string>
<string name="other_errors">інші помилки</string>
<string name="acknowledged">Підтверджено</string>
<string name="connections">Підключення</string>
<string name="decryption_errors">помилки розшифрування</string>
<string name="deleted">Видалено</string>
<string name="subscription_errors">Помилки підписки</string>
<string name="deletion_errors">Помилки видалення</string>
<string name="size">Розмір</string>
<string name="subscribed">Підписано</string>
<string name="subscription_results_ignored">Підписки проігноровані</string>
<string name="uploaded_files">Завантажені файли</string>
<string name="download_errors">Помилки завантаження</string>
<string name="downloaded_files">Завантажені файли</string>
<string name="upload_errors">Помилки завантаження</string>
<string name="chunks_deleted">Частини видалені</string>
<string name="chunks_downloaded">Частини завантажено</string>
<string name="chunks_uploaded">Частини завантажено</string>
<string name="remote_ctrl_connection_stopped_identity_desc">Ця посилання було використано на іншому мобільному пристрої, створіть нове посилання на комп\'ютері.</string>
<string name="copy_error">Помилка копіювання</string>
<string name="remote_ctrl_connection_stopped_desc">Будь ласка, перевірте, що мобільний пристрій і комп\'ютер підключені до однієї локальної мережі, і що брандмауер комп\'ютера дозволяє з\'єднання.
\nБудь ласка, повідомте про будь-які інші проблеми розробникам.</string>
<string name="toolbar_settings">Налаштування</string>
<string name="info_view_video_button">відеодзвінок</string>
<string name="info_view_message_button">повідомлення</string>
<string name="info_view_call_button">дзвінок</string>
<string name="keep_conversation">Зберегти розмову</string>
<string name="info_view_open_button">відкрити</string>
<string name="info_view_search_button">пошук</string>
<string name="you_can_still_view_conversation_with_contact">Ви все ще можете переглядати розмову з %1$s у списку чатів.</string>
<string name="contact_deleted">Контакт видалено!</string>
<string name="conversation_deleted">Розмову видалено!</string>
<string name="delete_without_notification">Видалити без сповіщення</string>
<string name="you_can_still_send_messages_to_contact">Ви можете надсилати повідомлення %1$s з архівованих контактів.</string>
<string name="smp_servers_configured">Налаштовані SMP сервери</string>
<string name="no_filtered_contacts">Ніяких відфільтрованих контактів</string>
<string name="smp_servers_other">Інші SMP сервери</string>
<string name="contact_list_header_title">Ваші контакти</string>
<string name="xftp_servers_other">Інші XFTP сервери</string>
<string name="subscription_percentage">Показати відсоток</string>
<string name="app_check_for_updates">Перевірити оновлення</string>
<string name="app_check_for_updates_disabled">Вимкнено</string>
<string name="app_check_for_updates_download_started">Завантаження оновлення додатку, не закривайте додаток</string>
<string name="app_check_for_updates_button_download">Завантажити %s (%s)</string>
<string name="app_check_for_updates_button_open">Відкрити розташування файлу</string>
<string name="app_check_for_updates_button_skip">Пропустити цю версію</string>
<string name="one_hand_ui">Доступна панель інструментів чату</string>
<string name="cant_call_contact_alert_title">Не можна зателефонувати контакту</string>
<string name="cant_call_contact_connecting_wait_alert_text">Підключення до контакту, будь ласка, зачекайте або перевірте пізніше!</string>
<string name="calls_prohibited_alert_title">Дзвінки заборонені!</string>
<string name="you_need_to_allow_calls">Вам необхідно дозволити контакту викликати вас, щоб ви могли самі їм дзвонити.</string>
<string name="cant_call_member_send_message_alert_text">Надіслати повідомлення, щоб увімкнути дзвінки.</string>
<string name="cant_call_member_alert_title">Не можна зателефонувати учаснику групи</string>
<string name="cant_send_message_to_member_alert_title">Не можна надіслати повідомлення учаснику групи</string>
<string name="attempts_label">спроби</string>
<string name="xftp_server">XFTP сервер</string>
<string name="reconnect">Перепідключитися</string>
<string name="created">Створено</string>
<string name="expired_label">закінчився</string>
<string name="secured">Захищений</string>
<string name="other_label">інший</string>
<string name="proxied">Проксірований</string>
<string name="send_errors">Надіслати помилки</string>
<string name="completed">Завершено</string>
<string name="all_users">Всі профілі</string>
<string name="servers_info_reset_stats_alert_confirm">Скинути</string>
<string name="servers_info_uploaded">Завантажено</string>
<string name="delete_members_messages__question">Видалити %d повідомлень учасників?</string>
<string name="delete_messages_mark_deleted_warning">Повідомлення будуть позначені для видалення. Одержувач(і) зможуть розкрити ці повідомлення.</string>
<string name="select_verb">Вибрати</string>
<string name="moderate_messages_will_be_deleted_warning">Повідомлення будуть видалені для всіх учасників.</string>
<string name="paste_link">Вставити посилання</string>
<string name="app_check_for_updates_notice_disable">Вимкнути</string>
<string name="app_check_for_updates_notice_desc">Щоб отримувати повідомлення про нові випуски, увімкніть періодичну перевірку стабільної або бета-версії.</string>
<string name="chat_database_exported_continue">Продовжити</string>
<string name="chat_database_exported_title">База даних чату експортована</string>
<string name="media_and_file_servers">Медіа та файлові сервери</string>
<string name="message_servers">Сервери повідомлень</string>
<string name="network_socks_proxy">SOCKS проксі</string>
<string name="chat_database_exported_not_all_files">Деякі файли не були експортовані</string>
<string name="chat_database_exported_migrate">Ви можете переїхати експортовану базу даних.</string>
<string name="chat_database_exported_save">Ви можете зберегти експортований архів.</string>
<string name="action_button_add_members">Запросити</string>
<string name="app_check_for_updates_download_completed_title">Оновлення додатку завантажено</string>
<string name="app_check_for_updates_installed_successfully_title">Встановлено успішно</string>
<string name="app_check_for_updates_button_install">Встановити оновлення</string>
<string name="app_check_for_updates_installed_successfully_desc">Будь ласка, перезапустіть додаток.</string>
<string name="reset_all_hints">Скинути всі підказки</string>
<string name="app_check_for_updates_update_available">Доступно оновлення: %s</string>
<string name="app_check_for_updates_canceled">Завантаження оновлення скасовано</string>
</resources>
@@ -567,4 +567,73 @@
<string name="v6_0_connect_faster_descr">Kết nối nhanh hơn với bạn bè.</string>
<string name="chat_database_exported_title">Cơ sở dữ liệu SimpleX Chat đã được xuất</string>
<string name="v6_0_your_contacts_descr">Lưu trữ các liên hệ để trò chuyện sau.</string>
<string name="disconnect_desktop_question">Ngắt kết nối máy tính?</string>
<string name="v6_0_delete_many_messages_descr">Xóa tối đa 20 tin nhắn cùng một lúc.</string>
<string name="remote_ctrl_disconnected_with_reason">Đã ngắt kết nối với lý do:%s</string>
<string name="remote_host_disconnected_from"><![CDATA[Đã ngắt kết nối khỏi thiết bị di động <b>%s</b> với lý do: %s]]></string>
<string name="disconnect_remote_hosts">Ngắt kết nối các thiết bị di động</string>
<string name="icon_descr_server_status_disconnected">Đã ngắt kết nối</string>
<string name="proxy_destination_error_broker_host">Địa chỉ máy chủ đích của %1$s không tương thích với thiết lập máy chủ chuyển tiếp %2$s.</string>
<string name="proxy_destination_error_broker_version">Phiên bản máy chủ đích của %1$s không tương thích với máy chủ chuyển tiếp %2$s.</string>
<string name="delete_without_notification">Xóa mà không thông báo</string>
<string name="multicast_discoverable_via_local_network">Có thể tìm thấy qua mạng cục bộ</string>
<string name="delete_members_messages__question">Xóa %d tin nhắn của các thành viên?</string>
<string name="ttl_months">%d tháng</string>
<string name="ttl_m">%dm</string>
<string name="network_smp_proxy_mode_never_description">KHÔNG sử dụng định tuyến riêng tư.</string>
<string name="v5_3_discover_join_groups">Khám phá và tham gia nhóm</string>
<string name="ttl_mth">%dmth</string>
<string name="disable_sending_recent_history">Không gửi lịch sử đến các thành viên mới.</string>
<string name="la_minutes">%d phút</string>
<string name="network_smp_proxy_fallback_prohibit_description">KHÔNG gửi tin nhắn trực tiếp, kể cả khi máy chủ của bạn hoặc máy chủ đích không hỗ trợ định tuyến riêng tư.</string>
<string name="ttl_month">%d tháng</string>
<string name="ttl_min">%d phút</string>
<string name="blocked_items_description">%d tin nhắn bị chặn</string>
<string name="blocked_by_admin_items_description">%d tin nhắn bị chặn bởi quản trị viên</string>
<string name="marked_deleted_items_description">%d tin nhắn được đánh dấu là đã xóa</string>
<string name="display_name_cannot_contain_whitespace">Tên hiển thị không thể chứa khoảng trắng.</string>
<string name="discover_on_network">Khám phá qua mạng cục bộ</string>
<string name="migrate_to_device_download_failed">Tải về không thành công</string>
<string name="dont_create_address">Không tạo địa chỉ</string>
<string name="dont_show_again">Không hiển thị lại</string>
<string name="smp_server_test_download_file">Tải về tệp tin</string>
<string name="migrate_to_device_downloading_archive">Đang tải về kho lưu trữ</string>
<string name="downgrade_and_open_chat">Hạ cấp và mở SimpleX Chat</string>
<string name="download_file">Tải về</string>
<string name="dont_enable_receipts">Không bật</string>
<string name="servers_info_downloaded">Đã tải về</string>
<string name="app_check_for_updates_download_started">Đang tải về bản cập nhật ứng dụng, đừng đóng ứng dụng</string>
<string name="downloaded_files">Các tập tin đã tải về</string>
<string name="download_errors">Lỗi tải về</string>
<string name="status_e2e_encrypted">mã hóa đầu cuối</string>
<string name="v6_0_upgrade_app_descr">Tải xuống các phiên bản mới từ GitHub.</string>
<string name="ttl_sec">%d giây</string>
<string name="ttl_s">%ds</string>
<string name="migrate_to_device_downloading_details">Đang tải xuống chi tiết liên kết</string>
<string name="failed_to_create_user_duplicate_title">Tên hiển thị trùng lặp!</string>
<string name="ttl_week">%d tuần</string>
<string name="ttl_weeks">%d tuần</string>
<string name="la_seconds">%d giây</string>
<string name="integrity_msg_duplicate">tin nhắn trùng lặp</string>
<string name="ttl_w">%dw</string>
<string name="encrypted_audio_call">cuộc gọi thoại mã hóa đầu cuối</string>
<string name="duplicates_label">các bản sao</string>
<string name="app_check_for_updates_button_download">Tải xuống %s (%s)</string>
<string name="feature_enabled_for_contact">đã bật cho liên hệ</string>
<string name="audio_device_earpiece">Tai nghe</string>
<string name="receipts_groups_enable_for_all">Bật cho tất cả các nhóm</string>
<string name="edit_image">Chỉnh sửa hình ảnh</string>
<string name="icon_descr_edited">đã chỉnh sửa</string>
<string name="receipts_contacts_enable_for_all">Bật cho tất cả</string>
<string name="feature_enabled">đã bật</string>
<string name="feature_enabled_for_you">đã bật cho bạn</string>
<string name="feature_enabled_for">Đã bật cho</string>
<string name="enable_camera_access">Cho phép truy cập camera</string>
<string name="encrypted_video_call">cuộc gọi video mã hóa đầu cuối</string>
<string name="allow_accepting_calls_from_lock_screen">Cho phép nhận cuộc gọi từ màn hình khóa thông qua Cài đặt.</string>
<string name="enable_receipts_all">Cho phép</string>
<string name="button_edit_group_profile">Chỉnh sửa hồ sơ nhóm</string>
<string name="enable_automatic_deletion_question">Cho phép xóa tin nhắn tự động?</string>
<string name="edit_verb">Chỉnh sửa</string>
<string name="icon_descr_email">Thư điện tử</string>
</resources>
@@ -2066,4 +2066,6 @@
<string name="invite_friends_short">邀请</string>
<string name="v6_0_new_chat_experience">新的聊天体验 🎉</string>
<string name="new_message">新消息</string>
<string name="error_parsing_uri_desc">请检查 Simple X 链接是否正确。</string>
<string name="error_parsing_uri_title">无效链接</string>
</resources>
@@ -47,6 +47,7 @@ actual fun PlatformTextField(
showDeleteTextButton: MutableState<Boolean>,
userIsObserver: Boolean,
placeholder: String,
showVoiceButton: Boolean,
onMessageChange: (String) -> Unit,
onUpArrow: () -> Unit,
onFilesPasted: (List<URI>) -> Unit,
@@ -56,7 +57,6 @@ actual fun PlatformTextField(
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val keyboard = LocalSoftwareKeyboardController.current
val padding = PaddingValues(0.dp, 12.dp, 50.dp, 0.dp)
LaunchedEffect(cs.contextItem) {
if (cs.contextItem !is ComposeContextItem.QuotedItem) return@LaunchedEffect
// In replying state
@@ -71,7 +71,20 @@ actual fun PlatformTextField(
keyboard?.hide()
}
}
val isRtl = remember(cs.message) { isRtl(cs.message.subSequence(0, min(50, cs.message.length))) }
val lastTimeWasRtlByCharacters = remember { mutableStateOf(isRtl(cs.message.subSequence(0, min(50, cs.message.length)))) }
val isRtlByCharacters = remember(cs.message) {
if (cs.message.isNotEmpty()) isRtl(cs.message.subSequence(0, min(50, cs.message.length))) else lastTimeWasRtlByCharacters.value
}
LaunchedEffect(isRtlByCharacters) {
lastTimeWasRtlByCharacters.value = isRtlByCharacters
}
val isLtrGlobally = LocalLayoutDirection.current == LayoutDirection.Ltr
// Different padding here is for a text that is considered RTL with non-RTL locale set globally.
// In this case padding from right side should be bigger
val startEndPadding = if (cs.message.isEmpty() && showVoiceButton && isRtlByCharacters && isLtrGlobally) 95.dp else 50.dp
val startPadding = if (isRtlByCharacters && isLtrGlobally) startEndPadding else 0.dp
val endPadding = if (isRtlByCharacters && isLtrGlobally) 0.dp else startEndPadding
val padding = PaddingValues(startPadding, 12.dp, endPadding, 0.dp)
var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = cs.message)) }
val textFieldValue = textFieldValueState.copy(text = cs.message)
val clipboard = LocalClipboardManager.current
@@ -165,9 +178,9 @@ actual fun PlatformTextField(
decorationBox = { innerTextField ->
Row(verticalAlignment = Alignment.Bottom) {
CompositionLocalProvider(
LocalLayoutDirection provides if (isRtl) LayoutDirection.Rtl else LocalLayoutDirection.current
LocalLayoutDirection provides if (isRtlByCharacters) LayoutDirection.Rtl else LocalLayoutDirection.current
) {
Column(Modifier.weight(1f).padding(start = 0.dp, end = 50.dp)) {
Column(Modifier.weight(1f).padding(start = startPadding, end = endPadding)) {
Spacer(Modifier.height(8.dp))
TextFieldDefaults.TextFieldDecorationBox(
value = textFieldValue.text,
@@ -186,7 +199,6 @@ actual fun PlatformTextField(
}
}
},
)
showDeleteTextButton.value = cs.message.split("\n").size >= 4 && !cs.inProgress
if (composeState.value.preview is ComposePreview.VoicePreview) {
+4 -4
View File
@@ -26,11 +26,11 @@ android.enableJetifier=true
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.jvm.target=11
android.version_name=6.0
android.version_code=230
android.version_name=6.0.1
android.version_code=232
desktop.version_name=6.0
desktop.version_code=61
desktop.version_name=6.0.1
desktop.version_code=62
kotlin.version=1.9.23
gradle.plugin.version=8.2.0
@@ -40,7 +40,9 @@ Many large tech companies prioritizing value extraction over value creation earn
### How is it funded and what is the business model?
We started working full-time on the project in 2021 when [Portman Wills](https://www.linkedin.com/in/portmanwills/) and [Peter Briffett](https://www.linkedin.com/in/peterbriffett/) (the founders of [Wagestream](https://wagestream.com/en/) where I led the engineering team) supported the company very early on, and several other angel investors joined later. In July 2022 SimpleX Chat raised a pre-seed funding from the VC fund [Village Global](https://www.villageglobal.vc) - its co-founder [Ben Casnocha](https://casnocha.com) was very excited about our vision of privacy-first fully decentralized messaging and community platform, both for the individual users and for the companies, independent of any crypto-currencies, that might grow to replace large centralized platforms, such as WhatsApp, Telegram and Signal.
We started working full-time on the project in 2021 when [Portman Wills](https://www.linkedin.com/in/portmanwills/) and [Peter Briffett](https://www.linkedin.com/in/peterbriffett/) (the founders of [Wagestream](https://wagestream.com/en/) where I led the engineering team) supported the company very early on, and several other angel investors joined later. In July 2022 SimpleX Chat raised a pre-seed funding from the VC fund [Village Global](https://www.villageglobal.vc) - its co-founder [Ben Casnocha](https://www.villageglobal.vc/team/ben-casnocha) was very excited about our vision of privacy-first fully decentralized messaging and community platform, both for the individual users and for the companies, independent of any crypto-currencies, that might grow to replace large centralized platforms, such as WhatsApp, Telegram and Signal.
> Edit: please see the comment from Ben Casnocha about this investment in [our post from August 14, 2024](./20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.md).
Overall we raised from our investors approximately $370,000 for a small share of the company to allow the project team working full time for almost two years, funding product design and development, infrastructure, and also [the security assessment by Trail of Bits](./20221108-simplex-chat-v4.2-security-audit-new-website.md). A large part of this money is not spent yet.
@@ -0,0 +1,247 @@
---
layout: layouts/article.html
title: "SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing."
date: 2024-08-14
image: images/20240814-reachable.png
previewBody: blog_previews/20240814.html
permalink: "/blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.html"
---
# SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing.
**Published:** Aug 14, 2024
[SimpleX Chat: vision and funding 2.0](#simplex-chat-vision-and-funding-20):
- [The past](#the-past-investment-from-village-global): investment from Village Global.
- [The present](#the-present-announcing-the-investment-from-jack-dorsey-and-asymmetric): announcing the investment from Jack Dorsey and Asymmetric Capital Partners.
- [The future](#the-future-faster-development-and-transition-to-non-profit-governance): faster development and the path to non-profit governance.
[What's new in v6.0](#whats-new-in-v60):
- Private message routing &mdash; now enabled by default.
- [New chat experience](#new-chat-experience):
- connect to your friends faster.
- [new reachable interface](#new-reachable-interface).
- archive contacts to chat later.
- new way to start chat.
- [moderate like a pro](#moderate-like-a-pro): delete many messages at once.
- new chat themes<sup>*</sup>
- increase font size<sup>**</sup>.
- [New media options](#new-media-options):
- play from the chat list.
- blur for better privacy.
- [share from other apps](#share-from-other-apps)<sup>*</sup>.
- [Improved networking and reduced battery usage](#improved-networking-and-reduced-battery-usage)
\* New for iOS app.
\*\* Android and desktop apps.
## SimpleX Chat: vision and funding 2.0
### The past: investment from Village Global
Last year [we announced](https://simplex.chat/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.html#how-is-it-funded-and-what-is-the-business-model) pre-seed funding from several angel investors and Village Global. Some of our users were very excited that we have funds to continue developing SimpleX network. But as some of Village Global LPs (Limited Partners) are [the founders of very large technology companies](https://www.villageglobal.vc), some of our users were worried about any negative influence this investment might have on the project.
[Ben Casnocha](https://www.villageglobal.vc/team/ben-casnocha), the founder and general partner of Village Global, commented on their investment:
> I believe in SimpleX Chat vision and teams ability to execute it. The growing number of Internet users who demand privacy of their data and contacts will make SimpleX Chat profitable, which is critically important for any sustainable organization.
>
> We are fortunate to have LPs who founded many iconic Internet ventures. But they dont have any influence on the 400+ companies we invested in. They are financial investors in our fund and exert no control or influence on any of the underlying portfolio companies.
>
> What's more, we believe that founders should lead their ventures, as it yields better results our investment in SimpleX Chat has no control provisions. We are happy to help, but we dont control any decisions nor have a board seat. Evgeny runs the company independently.
Ben, thank you for believing in our vision without it SimpleX Chat would simply not exist, as most other investors at the time did not believe that privacy could ever escape the niche of privacy enthusiasts and we already see the first signs of it happening.
### The present: announcing the investment from Jack Dorsey and Asymmetric
The Android app recently hit [100,000 downloads on Google Play Store](https://play.google.com/store/apps/details?id=chat.simplex.app), and our users naturally ask for improved reliability, privacy, security, better user experience and design all at the same time, and as soon as possible. This requires more funding.
We are very happy to announce that we now have funds to move faster we raised a $1.3 million pre-seed round led by [Jack Dorsey](https://en.wikipedia.org/wiki/Jack_Dorsey), with participation of [Asymmetric Capital Partners](https://www.acp.vc) (ACP) VC fund.
When Jack discovered SimpleX Chat last year, he [posted on Twitter](https://x.com/jack/status/1661681076983529479):
> Better than Signal? Looks promising.
> A few bugs and UX issues but great foundation. Love that its public domain.
And [on Nostr](https://primal.net/e/note1txz9xmmc456kwcg7zrsrtqrhn7as29ptuz0qulu452k8n85hsshqq6uh6q):
> A full day with @SimpleX Chat. Solid overall. TestFlight is not recommended. There are some scaling issues today. And not the most intuitive onboarding for everyone. Name still reminds everyone of herpes. All fixable. Its fast and doesnt require a phone number or email and I do believe people will eventually see the value of that. Finally, some competition for Signal, and in a permissionless way. And def a solid path so apps dont have to build their own DM experiences.
Jack, we are super lucky to have your support and investment thank you for believing in our ability to build a better messaging network! It is a hard work, and weve made a lot of progress since your note was written, and a lot of work is ongoing!
The ACP investment is strategically important it is a fund that only invests in B2B startups, and SimpleX Chat currently is mostly used by individual users. Making a private communication network sustainable requires its adoption by businesses, and we already see a growing usage by the small teams.
[Rob Biederman](https://www.acp.vc/team/rob-biederman) and [Sam Clayman](https://www.acp.vc/team/sam), the partners of ACP, commented:
> We believe that SimpleX Chat network can grow into a de facto Internet standard for private and secure communications for both businesses and individual users, unifying instant and email-like messaging into a single product.
>
> Emails no longer provide privacy and security that businesses require, particularly given the emerging threat of AI-led phishing and social engineering attacks. We look forward to SimpleX network providing a secure alternative.
I was lucky to have met Rob, Sam and the ACP team when I was presenting SimpleX Chat in London thank you all for your support and believing that the future of communication requires a single product, both for businesses and individual users.
### The future: faster development and the path to non-profit governance
Jack Dorsey and ACP support enable us to make huge product improvements, thanks to a bigger team, and provide us with medium-term funding to get to the next stage of product and business evolution. Like with Village Global, this is a financial investment, without control or board seat provisions so the users can be certain that SimpleX remains true to our vision of privacy first communication network.
We already added two great engineers to the team and are about to hire a UX/UI designer.
[Trail of Bits](https://www.trailofbits.com/about/) has just completed the protocols design security review and will be doing implementation security review in the end of the year. We will publish the first report soon.
This year we will launch group improvements that we presented in the [live-stream last year](https://www.youtube.com/watch?v=7yjQFmhAftE). While the main problem explained in this video was solved with the current design, the issue of group scalability remains to send a message to a group your client needs to send it to each member, creating substantial traffic.
We will also launch long-form email-like messaging over SimpleX network this year, together with optional short public addresses that show profile you are connecting to before the connection this is important for any public users and businesses.
The last but not the least, we started the work with [Heather Meeker](https://www.techlawpartners.com/heather), a great legal expert on intellectual property matters and one of the earliest advocates of the open-source software development in businesses, to setup open-source governance model, to some extent similar to how Matrix did it. We believe, and our investors agree, that it would both increase the company value and also create more value for the users community.
## What's new in v6.0
v6.0 is one of our biggest releases ever, with a lot of focus on UX and stability improvements, and the new features the users asked for.
The private message routing [we announced before](./20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md) is now enabled for all users by default it protects users IP addresses and sessions from the destination servers.
### New chat experience
#### Connect to your friends faster
This version includes messaging protocol improvements that reduce twice the number of messages required for two users to connect. Not only it means connecting faster and using less traffic, this change allows to start sending messages sooner, so you would see "connecting" in the list of the chats for a much shorter time than before.
It will be improved further in the next version: you will be able to send messages straight after using the invitation link, without waiting for your contact to be online.
#### New reachable interface
<img src="./images/20240814-reachable.png" width="288" class="float-to-right">
Like with the most innovative mobile browsers (e.g., Safari and Firefox), SimpleX Chat users now can use the app with one hand by moving the toolbar and search bar to the bottom of the screen, and ordering the chats with the most recent conversations in the bottom too, where they can be more easily reached on a mobile screen.
This layout is enabled by default, and you can disable it right from the list of chats when you install the new version if you prefer to use conventional UI.
Give it a try our experience is that that after less than a day of using it, it starts feeling as the only right way. You can always toggle it in the Appearance settings.
#### Archive contacts to chat later
<img src="./images/20240814-delete-contact-2.png" width="288" class="float-to-right"> &nbsp; <img src="./images/20240814-delete-contact-1.png" width="288" class="float-to-right">
Now you have two new options when deleting a conversation:
- only delete conversation, and archive contact. We will add archiving conversation without clearing it in the next version, as some users of our beta version asked.
- delete contact but keep the conversation.
Also, deleting a contact now requires double confirmation, so you are less likely to delete the contact accidentally. This deletion is irreversible, and the only way to re-connect would be using a new link.
#### New way to start chat
<img src="./images/20240814-new-message.png" width="288" class="float-to-right">
When you tap pencil button, you will see a large *New message* sheet, that adds new functions to the options you had before.
Old options:
- *Add contact* to create a new 1-time invitation link,
- *Scan / paste link*: to use the link you received. It can be 1-time invitation, a public SimpleX address, or a link to join the group.
- *Create group*
New options:
- Open archived chats.
- Accept pending contact requests.
- Connect to preset public addresses (we will add an option to add your own addresses here too).
- Search for your contacts.
#### New chat themes
We released the new themes [for Android and desktop apps](./20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md) in the previous version, and now they are available for iOS too.
You can set different themes for different chat profiles you have, and for different conversations it can help avoid mistakes about which conversation you are in.
Also, these themes are compatible between platforms, so you can import the theme created on Android into iOS app and vice versa.
#### Moderate like a pro
<img src="./images/20240814-delete-messages.png" width="288" class="float-to-right">
As much as we disagree with the attacks on the freedom of speech on the society level all people must be able to express their opinions we also believe that the small community owners should have full control over which content is allowed and which is not. But as communities grow, bad actors begin to join in order to disrupt, subvert and troll the conversations. So, the moderation tools are critical for small public communities to thrive.
SimpleX Chat already has several moderation tools available for community owners:
- Moderate individual messages.
- Set the default role of the new members to "observer" &mdash; they won't be able to send messages until you allow it. In addition to that, by enabling default messages for admins and owners only you can reach out to the new members and ask some questions before allowing to send messages.
- Block messages of a member for yourself only.
- Block a member for all other members &mdash; only admins and group owners can do that.
With this version you can now select multiple messages at once and delete or moderate them, depending on your role in the community. The current version limits the number of messages that can be deleted to 20 &mdash; this limit will be increased to 200 messages in the next version.
Also, this version makes profile images of the blocked members blurred, to prevent the abuse via inappropriate profile images.
#### Increase font size
Android and desktop apps now allow to increase font size inside the app, without changing the system settings. Desktop app also allows to zoom the whole screen &mdash; it can be helpful on some systems with a limited support of high density displays.
These settings can be changed via Appearance settings.
### New media options
#### Play from the chat list
<img src="./images/20240814-play.png" width="288" class="float-to-right">
Now you can interact with the media directly from the list of the chats.
This is very convenient when somebody sends you a voice message or a video, they can be played directly from the list of chats, without opening a conversation. Similarly, an image can be opened, a file can be saved, and the link with preview can be opened in the browser.
And, in some circumstances, this is also more private, as you can interact with the media, without opening the whole conversation.
We will add the option to return missed calls from the chat list in the next version.
#### Blur for better privacy
You can set all images and videos to blur in your app, and unblur them on tap (or on hover in desktop app). The blur level can be set in Privacy and security settings.
#### Share from other apps
<img src="./images/20240814-share.png" width="288" class="float-to-right">
Not much to brag about, as most iOS messaging apps allow it, and users expected it to be possible since the beginning.
But iOS makes it much harder to develop the capability to share into the app than Android, so it's only in this version you can share images, videos, files and links into SimpleX Chat from other apps.
### Improved networking and reduced battery usage
This version includes the statistics of how your app communicates with all servers when sending and receiving messages and files. This information also includes the status of connection to all servers from which you receive messages &mdash; whether the connection is authorized to push messages from server to your device, and the share of these active connections.
Please note, that when you send a message to a group, your app has to send it to each member separately, so sent message statistics account for that &mdash; it may seem to be quite a large number if you actively participate in some large groups. Also, message counts not only include visible messages you receive and send, but also any service messages, reactions, message updates, message deletions, etc. &mdash; this is the correct reflection of how much traffic your app uses.
This information is only available to your device, we do NOT collect this information, even in the aggregate form.
While the main reason we added this information is to reduce traffic and battery usage, to be able to identify any cases of high traffic, this version already reduced a lot battery and traffic usage, as reported by several beta-version users.
## SimpleX network
Some links to answer the most common questions:
[How can SimpleX deliver messages without user identifiers](./20220511-simplex-chat-v2-images-files.md#the-first-messaging-platform-without-user-identifiers).
[What are the risks to have identifiers assigned to the users](./20220711-simplex-chat-v3-released-ios-notifications-audio-video-calls-database-export-import-protocol-improvements.md#why-having-users-identifiers-is-bad-for-the-users).
[Technical details and limitations](https://github.com/simplex-chat/simplex-chat#privacy-technical-details-and-limitations).
[Frequently asked questions](../docs/FAQ.md).
Please also see our [website](https://simplex.chat).
## Please support us with your donations
Huge thank you to everybody who donated to SimpleX Chat!
You might ask: *Why do you need donations if you've just raised the investment?*
Prioritizing users privacy and security, and also raising the investment, would have been impossible without your support and donations.
Also, funding the work to transition the protocols to non-profit governance model would not have been possible without the donations we received from the users.
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 &mdash; 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
+22
View File
@@ -1,5 +1,27 @@
# Blog
Aug 14, 2024 [SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing](./20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.md)
[SimpleX Chat: vision and funding 2.0](#simplex-chat-vision-and-funding-20): past, present, future.
Announcing the investment from Jack Dorsey and Asymmetric.
What's new in v6.0:
- Private message routing - now enabled by default
- New chat experience:
- connect to your friends faster.
- new reachable interface.
- and much more!
- Improved networking and reduced battery usage
---
Jul 4, 2024 [The Future of Privacy: Enforcing Privacy Standards](./20240704-future-of-privacy-enforcing-privacy-standards.md)
It's time we shift the focus: privacy should be a non-negotiable duty of technology providers, not just a right users must fight to protect, and not something that users can be asked to consent away as a condition of access to a service.
---
Jun 4, 2024 [SimpleX network: private message routing, v5.8 released with IP address protection and chat themes](./20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md)
What's new in v5.8:
Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

+1 -1
View File
@@ -1,5 +1,5 @@
name: simplex-chat
version: 6.0.0.7
version: 6.0.0.8
#synopsis:
#description:
homepage: https://github.com/simplex-chat/simplex-chat#readme
@@ -38,6 +38,31 @@
</description>
<releases>
<release version="6.0.0" date="2024-08-12">
<url type="details">https://github.com/simplex-chat/simplex-chat/releases/tag/v6.0.0</url>
<description>
<p>New chat experience:</p>
<ol>
<li>connect to your friends faster.</li>
<li>archive contacts to chat later.</li>
<li>delete up to 20 messages at once.</li>
<li>increase font size.</li>
</ol>
<p>New media options:</p>
<ol>
<li>play from the chat list.</li>
<li>blur for better privacy.</li>
</ol>
<p>Private routing:</p>
<ol>
<li>it protects your IP address and connections and is now enabled by default.</li>
</ol>
<p>Connection and servers information:</p>
<ol>
<li>to control your network status and usage.</li>
</ol>
</description>
</release>
<release version="5.8.2" date="2024-07-02">
<url type="details">https://github.com/simplex-chat/simplex-chat/releases/tag/v5.8.2</url>
<description>
+1 -1
View File
@@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack
name: simplex-chat
version: 6.0.0.7
version: 6.0.0.8
category: Web, System, Services, Cryptography
homepage: https://github.com/simplex-chat/simplex-chat#readme
author: simplex.chat
+2 -2
View File
@@ -415,8 +415,8 @@ responseToView hu@(currentRH, user_) ChatConfig {logLevel, showReactions, showRe
CRCustomChatResponse u r -> ttyUser' u $ map plain $ T.lines r
where
ttyUser :: User -> [StyledString] -> [StyledString]
ttyUser user@User {showNtfs, activeUser} ss
| showNtfs || activeUser = ttyUserPrefix user ss
ttyUser user@User {showNtfs, activeUser, viewPwdHash} ss
| (showNtfs && isNothing viewPwdHash) || activeUser = ttyUserPrefix user ss
| otherwise = []
ttyUserPrefix :: User -> [StyledString] -> [StyledString]
ttyUserPrefix _ [] = []
+2
View File
@@ -2032,6 +2032,8 @@ testUserPrivacy =
bob <# "alisa> hello"
bob #> "@alisa hey"
alice <# "bob> hey"
bob #> "@alice hey"
(alice, "[user: alice] ") ^<# "bob> hey"
-- hide user profile
alice ##> "/hide user my_password"
userHidden alice "current "
+1 -1
View File
@@ -78,7 +78,7 @@
"smp-protocol": "Протокол SMP",
"chat-protocol": "Протокол чату",
"donate": "Пожертвувати",
"copyright-label": "© 2020-2023 SimpleX | Проект з відкритим кодом",
"copyright-label": "© 2020-2024 SimpleX | Проект з відкритим кодом",
"simplex-chat-protocol": "Протокол чату SimpleX",
"terminal-cli": "Термінал CLI",
"hero-header": "Приватність переосмислена",
@@ -0,0 +1,18 @@
<p><strong>SimpleX Chat vision and funding 2.0:</strong> past, present, future.</p>
<p class="mb-[12px]">Announcing the investment from Jack Dorsey and Asymmetric.</p>
<p><strong>v6.0 is released:</strong></p>
<ul class="mb-[12px]">
<li>Private message routing - enabled by default</li>
<li>
<p>New chat experience:</p>
<ul>
<li>connect to your friends faster.</li>
<li>new reachable interface.</li>
<li>and much more!</li>
</ul>
</li>
<li>Improved networking and battery usage</li>
</ul>
+6
View File
@@ -232,4 +232,10 @@ h6 {
#article ol>li::marker {
font-weight: 500;
}
#article blockquote {
padding-left: 1em;
border-left: 2px solid #c0c0c0;
font-style: italic;
}