Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82c4d77c73 | |||
| 25938af62f | |||
| edfcced1fa | |||
| 5bff5a855e | |||
| 46a60d979b | |||
| f6ef57534f | |||
| 1e4479f736 | |||
| 789c762c81 | |||
| e9baeba31f | |||
| 2d5bbcdd61 | |||
| c3f67aff69 | |||
| 7cb3a499b2 | |||
| 32e7fd72d3 | |||
| 915bbed400 | |||
| 2ae5a8bffd | |||
| cd1550a14d | |||
| c72c461306 | |||
| 38fa4c231f | |||
| cb683d0706 | |||
| 84ae39b012 | |||
| 6a12f2dec8 | |||
| d1f704d160 | |||
| 9871ebb3b1 | |||
| 02c404593c | |||
| 1d9c5b7a0b |
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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))")
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))")
|
||||
|
||||
@@ -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 & file servers" xml:space="preserve">
|
||||
<source>Media & 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">
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 l’autorise.";
|
||||
|
||||
@@ -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.";
|
||||
|
||||
|
||||
@@ -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!";
|
||||
|
||||
@@ -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 qu’avec 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) {
|
||||
|
||||
@@ -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 — 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 team’s 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 don’t 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 don’t 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 it’s 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. It’s fast and doesn’t 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 don’t 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 we’ve 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"> <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" — 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 — 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 — 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 — 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 — 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 — 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. — 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 — 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
|
||||
@@ -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:
|
||||
|
||||
|
After Width: | Height: | Size: 213 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 874 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 412 KiB |
|
After Width: | Height: | Size: 300 KiB |
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 _ [] = []
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||