diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d7322cd92f..8a3e19535d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,10 +78,10 @@ jobs: uses: actions/checkout@v3 - name: Setup Haskell - uses: haskell/actions/setup@v2 + uses: haskell-actions/setup@v2 with: - ghc-version: "8.10.7" - cabal-version: "latest" + ghc-version: "9.6.2" + cabal-version: "3.10.1.0" - name: Cache dependencies uses: actions/cache@v3 @@ -125,7 +125,9 @@ jobs: shell: bash run: | cabal build --enable-tests - echo "::set-output name=bin_path::$(cabal list-bin simplex-chat)" + path=$(cabal list-bin simplex-chat) + echo "bin_path=$path" >> $GITHUB_OUTPUT + echo "bin_hash=$(echo SHA2-512\(${{ matrix.asset_name }}\)= $(openssl sha512 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT - name: Unix upload CLI binary to release if: startsWith(github.ref, 'refs/tags/v') && matrix.os != 'windows-latest' @@ -136,6 +138,16 @@ jobs: asset_name: ${{ matrix.asset_name }} tag: ${{ github.ref }} + - name: Unix update CLI binary hash + if: startsWith(github.ref, 'refs/tags/v') && matrix.os != 'windows-latest' + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + append_body: true + body: | + ${{ steps.unix_cli_build.outputs.bin_hash }} + - name: Setup Java if: startsWith(github.ref, 'refs/tags/v') uses: actions/setup-java@v3 @@ -152,7 +164,9 @@ jobs: scripts/desktop/build-lib-linux.sh cd apps/multiplatform ./gradlew packageDeb - echo "::set-output name=package_path::$(echo $PWD/release/main/deb/simplex_*_amd64.deb)" + path=$(echo $PWD/release/main/deb/simplex_*_amd64.deb) + echo "package_path=$path" >> $GITHUB_OUTPUT + echo "package_hash=$(echo SHA2-512\(${{ matrix.desktop_asset_name }}\)= $(openssl sha512 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT - name: Linux make AppImage id: linux_appimage_build @@ -160,7 +174,9 @@ jobs: shell: bash run: | scripts/desktop/make-appimage-linux.sh - echo "::set-output name=appimage_path::$(echo $PWD/apps/multiplatform/release/main/*imple*.AppImage)" + path=$(echo $PWD/apps/multiplatform/release/main/*imple*.AppImage) + echo "appimage_path=$path" >> $GITHUB_OUTPUT + echo "appimage_hash=$(echo SHA2-512\(simplex-desktop-x86_64.AppImage\)= $(openssl sha512 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT - name: Mac build desktop id: mac_desktop_build @@ -171,8 +187,10 @@ jobs: APPLE_SIMPLEX_NOTARIZATION_APPLE_ID: ${{ secrets.APPLE_SIMPLEX_NOTARIZATION_APPLE_ID }} APPLE_SIMPLEX_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_SIMPLEX_NOTARIZATION_PASSWORD }} run: | - scripts/desktop/build-desktop-mac-ci.sh - echo "::set-output name=package_path::$(echo $PWD/release/main/dmg/SimpleX-*.dmg)" + scripts/ci/build-desktop-mac.sh + path=$(echo $PWD/apps/multiplatform/release/main/dmg/SimpleX-*.dmg) + echo "package_path=$path" >> $GITHUB_OUTPUT + echo "package_hash=$(echo SHA2-512\(${{ matrix.desktop_asset_name }}\)= $(openssl sha512 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT - name: Linux upload desktop package to release if: startsWith(github.ref, 'refs/tags/v') && (matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04') @@ -183,6 +201,16 @@ jobs: asset_name: ${{ matrix.desktop_asset_name }} tag: ${{ github.ref }} + - name: Linux update desktop package hash + if: startsWith(github.ref, 'refs/tags/v') && (matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04') + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + append_body: true + body: | + ${{ steps.linux_desktop_build.outputs.package_hash }} + - name: Linux upload AppImage to release if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'ubuntu-20.04' uses: svenstaro/upload-release-action@v2 @@ -192,6 +220,16 @@ jobs: asset_name: simplex-desktop-x86_64.AppImage tag: ${{ github.ref }} + - name: Linux update AppImage hash + if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'ubuntu-20.04' + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + append_body: true + body: | + ${{ steps.linux_appimage_build.outputs.appimage_hash }} + - name: Mac upload desktop package to release if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'macos-latest' uses: svenstaro/upload-release-action@v2 @@ -201,6 +239,16 @@ jobs: asset_name: ${{ matrix.desktop_asset_name }} tag: ${{ github.ref }} + - name: Mac update desktop package hash + if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'macos-latest' + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + append_body: true + body: | + ${{ steps.mac_desktop_build.outputs.package_hash }} + - name: Unix test if: matrix.os != 'windows-latest' timeout-minutes: 30 @@ -210,21 +258,22 @@ jobs: # Unix / # / Windows - - # * In powershell multiline commands do not fail if individual commands fail - https://github.community/t/multiline-commands-on-windows-do-not-fail-if-individual-commands-fail/16753 - # * And GitHub Actions does not support parameterizing shell in a matrix job - https://github.community/t/using-matrix-to-specify-shell-is-it-possible/17065 + # rm -rf dist-newstyle/src/direct-sq* is here because of the bug in cabal's dependency which prevents second build from finishing - name: Windows build id: windows_build if: matrix.os == 'windows-latest' - shell: cmd + shell: bash run: | + rm -rf dist-newstyle/src/direct-sq* + sed -i "s/, unix /--, unix /" simplex-chat.cabal cabal build --enable-tests - cabal list-bin simplex-chat > tmp_bin_path - set /p bin_path= < tmp_bin_path - echo ::set-output name=bin_path::%bin_path% + rm -rf dist-newstyle/src/direct-sq* + path=$(cabal list-bin simplex-chat | tail -n 1) + echo "bin_path=$path" >> $GITHUB_OUTPUT + echo "bin_hash=$(echo SHA2-512\(${{ matrix.asset_name }}\)= $(openssl sha512 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT - - name: Windows upload binary to release + - name: Windows upload CLI binary to release if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'windows-latest' uses: svenstaro/upload-release-action@v2 with: @@ -233,4 +282,14 @@ jobs: asset_name: ${{ matrix.asset_name }} tag: ${{ github.ref }} + - name: Windows update CLI binary hash + if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'windows-latest' + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + append_body: true + body: | + ${{ steps.windows_build.outputs.bin_hash }} + # Windows / diff --git a/apps/ios/Shared/ContentView.swift b/apps/ios/Shared/ContentView.swift index 46c36ab197..3dbcf47004 100644 --- a/apps/ios/Shared/ContentView.swift +++ b/apps/ios/Shared/ContentView.swift @@ -35,7 +35,7 @@ struct ContentView: View { var id: String { switch self { - case .connectViaUrl: return "connectViaUrl \(link)" + case let .connectViaUrl(_, link): return "connectViaUrl \(link)" } } } @@ -285,18 +285,20 @@ struct ContentView: View { } func connectViaUrl() { - let m = ChatModel.shared - if let url = m.appOpenUrl { - m.appOpenUrl = nil - var path = url.path - logger.debug("ContentView.connectViaUrl path: \(path)") - if (path == "/contact" || path == "/invitation") { - path.removeFirst() - let action: ConnReqType = path == "contact" ? .contact : .invitation - let link = url.absoluteString.replacingOccurrences(of: "///\(path)", with: "/\(path)") - chatListActionSheet = .connectViaUrl(action: action, link: link) - } else { - AlertManager.shared.showAlert(Alert(title: Text("Error: URL is invalid"))) + dismissAllSheets() { + let m = ChatModel.shared + if let url = m.appOpenUrl { + m.appOpenUrl = nil + var path = url.path + logger.debug("ContentView.connectViaUrl path: \(path)") + if (path == "/contact" || path == "/invitation") { + path.removeFirst() + let action: ConnReqType = path == "contact" ? .contact : .invitation + let link = url.absoluteString.replacingOccurrences(of: "///\(path)", with: "/\(path)") + chatListActionSheet = .connectViaUrl(action: action, link: link) + } else { + AlertManager.shared.showAlert(Alert(title: Text("Error: URL is invalid"))) + } } } } diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 7a625bae63..aef8711f34 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -15,6 +15,12 @@ import SimpleXChat private var chatController: chat_ctrl? +// currentChatVersion in core +public let CURRENT_CHAT_VERSION: Int = 2 + +// version range that supports establishing direct connection with a group member (xGrpDirectInvVRange in core) +public let CREATE_MEMBER_CONTACT_VRANGE = VersionRange(minVersion: 2, maxVersion: CURRENT_CHAT_VERSION) + enum TerminalItem: Identifiable { case cmd(Date, ChatCommand) case resp(Date, ChatResponse) @@ -1090,6 +1096,18 @@ func apiGetGroupLink(_ groupId: Int64) throws -> (String, GroupMemberRole)? { } } +func apiCreateMemberContact(_ groupId: Int64, _ groupMemberId: Int64) async throws -> Contact { + let r = await chatSendCmd(.apiCreateMemberContact(groupId: groupId, groupMemberId: groupMemberId)) + if case let .newMemberContact(_, contact, _, _) = r { return contact } + throw r +} + +func apiSendMemberContactInvitation(_ contactId: Int64, _ msg: MsgContent) async throws -> Contact { + let r = await chatSendCmd(.apiSendMemberContactInvitation(contactId: contactId, msg: msg), bgDelay: msgDelay) + if case let .newMemberContactSentInv(_, contact, _, _) = r { return contact } + throw r +} + func apiGetVersion() throws -> CoreVersionInfo { let r = chatSendCmdSync(.showVersion) if case let .versionInfo(info, _, _) = r { return info } @@ -1487,6 +1505,12 @@ func processReceivedMsg(_ res: ChatResponse) async { m.updateGroup(groupInfo) } } + case let .newMemberContactReceivedInv(user, contact, _, _): + if active(user) { + await MainActor.run { + m.updateContact(contact) + } + } case let .rcvFileAccepted(user, aChatItem): // usually rcvFileAccepted is a response, but it's also an event for XFTP files auto-accepted from NSE await chatItemSimpleUpdate(user, aChatItem) case let .rcvFileStart(user, aChatItem): diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index 3b0861feb1..e7a5978044 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -164,6 +164,7 @@ struct ChatInfoView: View { // synchronizeConnectionButtonForce() // } } + .disabled(!contact.ready) if let contactLink = contact.contactLink { Section { @@ -180,30 +181,33 @@ struct ChatInfoView: View { } } - Section("Servers") { - networkStatusRow() - .onTapGesture { - alert = .networkStatusAlert - } - if let connStats = connectionStats { - Button("Change receiving address") { - alert = .switchAddressAlert - } - .disabled( - connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil } - || connStats.ratchetSyncSendProhibited - ) - if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) { - Button("Abort changing address") { - alert = .abortSwitchAddressAlert + if contact.ready { + Section("Servers") { + networkStatusRow() + .onTapGesture { + alert = .networkStatusAlert + } + if let connStats = connectionStats { + Button("Change receiving address") { + alert = .switchAddressAlert } .disabled( - connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch } + !contact.ready + || connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil } || connStats.ratchetSyncSendProhibited ) + if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) { + Button("Abort changing address") { + alert = .abortSwitchAddressAlert + } + .disabled( + connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch } + || connStats.ratchetSyncSendProhibited + ) + } + smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }) + smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }) } - smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }) - smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }) } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift index 1c32f36c9c..359633a5f5 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift @@ -84,7 +84,7 @@ struct CIFileView: View { Task { logger.debug("CIFileView fileAction - in .rcvInvitation, in Task") if let user = ChatModel.shared.currentUser { - let encrypted = file.fileProtocol == .xftp && privacyEncryptLocalFilesGroupDefault.get() + let encrypted = privacyEncryptLocalFilesGroupDefault.get() await receiveFile(user: user, fileId: file.fileId, encrypted: encrypted) } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIMemberCreatedContactView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIMemberCreatedContactView.swift new file mode 100644 index 0000000000..a204d83f1e --- /dev/null +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIMemberCreatedContactView.swift @@ -0,0 +1,79 @@ +// +// CIMemberCreatedContactView.swift +// SimpleX (iOS) +// +// Created by spaced4ndy on 19.09.2023. +// Copyright © 2023 SimpleX Chat. All rights reserved. +// + +import SwiftUI +import SimpleXChat + +struct CIMemberCreatedContactView: View { + var chatItem: ChatItem + + var body: some View { + HStack(alignment: .bottom, spacing: 0) { + switch chatItem.chatDir { + case let .groupRcv(groupMember): + if let contactId = groupMember.memberContactId { + memberCreatedContactView(openText: "Open") + .onTapGesture { + dismissAllSheets(animated: true) + DispatchQueue.main.async { + ChatModel.shared.chatId = "@\(contactId)" + } + } + } else { + memberCreatedContactView() + } + default: + EmptyView() + } + } + .padding(.leading, 6) + .padding(.bottom, 6) + .textSelection(.disabled) + } + + private func memberCreatedContactView(openText: LocalizedStringKey? = nil) -> some View { + var r = eventText() + if let openText { + r = r + + Text(openText) + .fontWeight(.medium) + .foregroundColor(.accentColor) + + Text(" ") + } + r = r + chatItem.timestampText + .fontWeight(.light) + .foregroundColor(.secondary) + return r.font(.caption) + } + + private func eventText() -> Text { + if let member = chatItem.memberDisplayName { + return Text(member + " " + chatItem.content.text + " ") + .fontWeight(.light) + .foregroundColor(.secondary) + } else { + return Text(chatItem.content.text + " ") + .fontWeight(.light) + .foregroundColor(.secondary) + } + } +} + +struct CIMemberCreatedContactView_Previews: PreviewProvider { + static var previews: some View { + let content = CIContent.rcvGroupEvent(rcvGroupEvent: .memberCreatedContact) + let chatItem = ChatItem( + chatDir: .groupRcv(groupMember: GroupMember.sampleData), + meta: CIMeta.getSample(1, .now, content.text, .rcvRead), + content: content, + quotedItem: nil, + file: nil + ) + CIMemberCreatedContactView(chatItem: chatItem) + } +} diff --git a/apps/ios/Shared/Views/Chat/ChatItemView.swift b/apps/ios/Shared/Views/Chat/ChatItemView.swift index 5d816ac64a..5ec61a8c2b 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemView.swift @@ -74,6 +74,7 @@ struct ChatItemContentView: View { case let .rcvGroupInvitation(groupInvitation, memberRole): groupInvitationItemView(groupInvitation, memberRole) case let .sndGroupInvitation(groupInvitation, memberRole): groupInvitationItemView(groupInvitation, memberRole) case .rcvGroupEvent(.memberConnected): CIEventView(eventText: membersConnectedItemText) + case .rcvGroupEvent(.memberCreatedContact): CIMemberCreatedContactView(chatItem: chatItem) case .rcvGroupEvent: eventItemView() case .sndGroupEvent: eventItemView() case .rcvConnEvent: eventItemView() diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 2a0cd4f2c2..81a063dcfc 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -64,6 +64,7 @@ struct ChatView: View { Spacer(minLength: 0) + connectingText() ComposeView( chat: chat, composeState: $composeState, @@ -149,6 +150,7 @@ struct ChatView: View { HStack { if contact.allowsFeature(.calls) { callButton(contact, .audio, imageName: "phone") + .disabled(!contact.ready) } Menu { if contact.allowsFeature(.calls) { @@ -157,9 +159,11 @@ struct ChatView: View { } label: { Label("Video call", systemImage: "video") } + .disabled(!contact.ready) } searchButton() toggleNtfsButton(chat) + .disabled(!contact.ready) } label: { Image(systemName: "ellipsis") } @@ -313,6 +317,19 @@ struct ChatView: View { } .scaleEffect(x: 1, y: -1, anchor: .center) } + + @ViewBuilder private func connectingText() -> some View { + if case let .direct(contact) = chat.chatInfo, + !contact.ready, + !contact.nextSendGrpInv { + Text("connecting…") + .font(.caption) + .foregroundColor(.secondary) + .padding(.top) + } else { + EmptyView() + } + } private func floatingButtons(_ proxy: ScrollViewProxy) -> some View { let counts = chatModel.unreadChatItemCounts(itemsInView: itemsInView) diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift index c999c9dca0..3328da8dbe 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift @@ -257,6 +257,9 @@ struct ComposeView: View { var body: some View { VStack(spacing: 0) { + if chat.chatInfo.contact?.nextSendGrpInv ?? false { + ContextInvitingContactMemberView() + } contextItemView() switch (composeState.editing, composeState.preview) { case (true, .filePreview): EmptyView() @@ -270,7 +273,7 @@ struct ComposeView: View { Image(systemName: "paperclip") .resizable() } - .disabled(composeState.attachmentDisabled || !chat.userCanSend) + .disabled(composeState.attachmentDisabled || !chat.userCanSend || (chat.chatInfo.contact?.nextSendGrpInv ?? false)) .frame(width: 25, height: 25) .padding(.bottom, 12) .padding(.leading, 12) @@ -298,6 +301,7 @@ struct ComposeView: View { composeState.liveMessage = nil chatModel.removeLiveDummy() }, + nextSendGrpInv: chat.chatInfo.contact?.nextSendGrpInv ?? false, voiceMessageAllowed: chat.chatInfo.featureEnabled(.voice), showEnableVoiceMessagesAlert: chat.chatInfo.showEnableVoiceMessagesAlert, startVoiceMessageRecording: { @@ -617,7 +621,9 @@ struct ComposeView: View { if liveMessage != nil { composeState = composeState.copy(liveMessage: nil) } await sending() } - if case let .editingItem(ci) = composeState.contextItem { + if chat.chatInfo.contact?.nextSendGrpInv ?? false { + await sendMemberContactInvitation() + } else if case let .editingItem(ci) = composeState.contextItem { sent = await updateMessage(ci, live: live) } else if let liveMessage = liveMessage, liveMessage.sentMsg != nil { sent = await updateMessage(liveMessage.chatItem, live: live) @@ -669,6 +675,19 @@ struct ComposeView: View { await MainActor.run { composeState.inProgress = true } } + func sendMemberContactInvitation() async { + do { + let mc = checkLinkPreview() + let contact = try await apiSendMemberContactInvitation(chat.chatInfo.apiId, mc) + await MainActor.run { + self.chatModel.updateContact(contact) + } + } catch { + logger.error("ChatView.sendMemberContactInvitation error: \(error.localizedDescription)") + AlertManager.shared.showAlertMsg(title: "Error sending member contact invitation", message: "Error: \(responseError(error))") + } + } + func updateMessage(_ ei: ChatItem, live: Bool) async -> ChatItem? { if let oldMsgContent = ei.content.msgContent { do { diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextInvitingContactMemberView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextInvitingContactMemberView.swift new file mode 100644 index 0000000000..acb4f6d3e1 --- /dev/null +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextInvitingContactMemberView.swift @@ -0,0 +1,32 @@ +// +// ContextInvitingContactMemberView.swift +// SimpleX (iOS) +// +// Created by spaced4ndy on 18.09.2023. +// Copyright © 2023 SimpleX Chat. All rights reserved. +// + +import SwiftUI + +struct ContextInvitingContactMemberView: View { + @Environment(\.colorScheme) var colorScheme + + var body: some View { + HStack { + Image(systemName: "message") + .foregroundColor(.secondary) + Text("Send direct message to connect") + } + .padding(12) + .frame(minHeight: 50) + .frame(maxWidth: .infinity, alignment: .leading) + .background(colorScheme == .light ? sentColorLight : sentColorDark) + .padding(.top, 8) + } +} + +struct ContextInvitingContactMemberView_Previews: PreviewProvider { + static var previews: some View { + ContextInvitingContactMemberView() + } +} diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift index 73c7286925..6eed51788e 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift @@ -17,6 +17,7 @@ struct SendMessageView: View { var sendLiveMessage: (() async -> Void)? = nil var updateLiveMessage: (() async -> Void)? = nil var cancelLiveMessage: (() -> Void)? = nil + var nextSendGrpInv: Bool = false var showVoiceMessageButton: Bool = true var voiceMessageAllowed: Bool = true var showEnableVoiceMessagesAlert: ChatInfo.ShowEnableVoiceMessagesAlert = .other @@ -118,7 +119,9 @@ struct SendMessageView: View { @ViewBuilder private func composeActionButtons() -> some View { let vmrs = composeState.voiceMessageRecordingState - if showVoiceMessageButton + if nextSendGrpInv { + inviteMemberContactButton() + } else if showVoiceMessageButton && composeState.message.isEmpty && !composeState.editing && composeState.liveMessage == nil @@ -162,6 +165,24 @@ struct SendMessageView: View { .padding([.top, .trailing], 4) } + private func inviteMemberContactButton() -> some View { + Button { + sendMessage(nil) + } label: { + Image(systemName: "arrow.up.circle.fill") + .resizable() + .foregroundColor(sendButtonColor) + .frame(width: sendButtonSize, height: sendButtonSize) + .opacity(sendButtonOpacity) + } + .disabled( + !composeState.sendEnabled || + composeState.inProgress + ) + .frame(width: 29, height: 29) + .padding([.bottom, .trailing], 4) + } + private func sendMessageButton() -> some View { Button { sendMessage(nil) diff --git a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift index 6842e93f05..5ec14f5be1 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift @@ -22,6 +22,7 @@ struct GroupMemberInfoView: View { @State private var connectToMemberDialog: Bool = false @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false @State private var justOpened = true + @State private var progressIndicator = false enum GroupMemberInfoViewAlert: Identifiable { case removeMemberAlert(mem: GroupMember) @@ -65,146 +66,154 @@ struct GroupMemberInfoView: View { } private func groupMemberInfoView() -> some View { - VStack { - List { - groupMemberInfoHeader(member) - .listRowBackground(Color.clear) + ZStack { + VStack { + List { + groupMemberInfoHeader(member) + .listRowBackground(Color.clear) - if member.memberActive { - Section { - if let contactId = member.memberContactId { - if let chat = knownDirectChat(contactId) { + if member.memberActive { + Section { + if let contactId = member.memberContactId, let chat = knownDirectChat(contactId) { knownDirectChatButton(chat) } else if groupInfo.fullGroupPreferences.directMessages.on { - newDirectChatButton(contactId) + if let contactId = member.memberContactId { + newDirectChatButton(contactId) + } else if member.activeConn?.peerChatVRange.isCompatibleRange(CREATE_MEMBER_CONTACT_VRANGE) ?? false { + createMemberContactButton() + } } + if let code = connectionCode { verifyCodeButton(code) } + if let connStats = connectionStats, + connStats.ratchetSyncAllowed { + synchronizeConnectionButton() + } + // } else if developerTools { + // synchronizeConnectionButtonForce() + // } } - if let code = connectionCode { verifyCodeButton(code) } - if let connStats = connectionStats, - connStats.ratchetSyncAllowed { - synchronizeConnectionButton() - } -// } else if developerTools { -// synchronizeConnectionButtonForce() -// } } - } - if let contactLink = member.contactLink { - Section { - QRCode(uri: contactLink) - Button { - showShareSheet(items: [contactLink]) - } label: { - Label("Share address", systemImage: "square.and.arrow.up") - } - if let contactId = member.memberContactId { - if knownDirectChat(contactId) == nil && !groupInfo.fullGroupPreferences.directMessages.on { + if let contactLink = member.contactLink { + Section { + QRCode(uri: contactLink) + Button { + showShareSheet(items: [contactLink]) + } label: { + Label("Share address", systemImage: "square.and.arrow.up") + } + if let contactId = member.memberContactId { + if knownDirectChat(contactId) == nil && !groupInfo.fullGroupPreferences.directMessages.on { + connectViaAddressButton(contactLink) + } + } else { connectViaAddressButton(contactLink) } - } else { - connectViaAddressButton(contactLink) + } header: { + Text("Address") + } footer: { + Text("You can share this address with your contacts to let them connect with **\(member.displayName)**.") } - } header: { - Text("Address") - } footer: { - Text("You can share this address with your contacts to let them connect with **\(member.displayName)**.") } - } - Section("Member") { - infoRow("Group", groupInfo.displayName) + Section("Member") { + infoRow("Group", groupInfo.displayName) - if let roles = member.canChangeRoleTo(groupInfo: groupInfo) { - Picker("Change role", selection: $newRole) { - ForEach(roles) { role in - Text(role.text) + if let roles = member.canChangeRoleTo(groupInfo: groupInfo) { + Picker("Change role", selection: $newRole) { + ForEach(roles) { role in + Text(role.text) + } } + .frame(height: 36) + } else { + infoRow("Role", member.memberRole.text) + } + + // TODO invited by - need to get contact by contact id + if let conn = member.activeConn { + let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel) + infoRow("Connection", connLevelDesc) } - .frame(height: 36) - } else { - infoRow("Role", member.memberRole.text) } - // TODO invited by - need to get contact by contact id - if let conn = member.activeConn { - let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel) - infoRow("Connection", connLevelDesc) - } - } - - if let connStats = connectionStats { - Section("Servers") { - // TODO network connection status - Button("Change receiving address") { - alert = .switchAddressAlert - } - .disabled( - connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil } - || connStats.ratchetSyncSendProhibited - ) - if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) { - Button("Abort changing address") { - alert = .abortSwitchAddressAlert + if let connStats = connectionStats { + Section("Servers") { + // TODO network connection status + Button("Change receiving address") { + alert = .switchAddressAlert } .disabled( - connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch } + connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil } || connStats.ratchetSyncSendProhibited ) + if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) { + Button("Abort changing address") { + alert = .abortSwitchAddressAlert + } + .disabled( + connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch } + || connStats.ratchetSyncSendProhibited + ) + } + smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }) + smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }) } - smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }) - smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }) } - } - if member.canBeRemoved(groupInfo: groupInfo) { - Section { - removeMemberButton(member) + if member.canBeRemoved(groupInfo: groupInfo) { + Section { + removeMemberButton(member) + } } - } - if developerTools { - Section("For console") { - infoRow("Local name", member.localDisplayName) - infoRow("Database ID", "\(member.groupMemberId)") + if developerTools { + Section("For console") { + infoRow("Local name", member.localDisplayName) + infoRow("Database ID", "\(member.groupMemberId)") + } + } + } + .navigationBarHidden(true) + .onAppear { + if #unavailable(iOS 16) { + // this condition prevents re-setting picker + if !justOpened { return } + } + newRole = member.memberRole + do { + let (_, stats) = try apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId) + let (mem, code) = member.memberActive ? try apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil) + member = mem + connectionStats = stats + connectionCode = code + } catch let error { + logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))") + } + justOpened = false + } + .onChange(of: newRole) { _ in + if newRole != member.memberRole { + alert = .changeMemberRoleAlert(mem: member, role: newRole) } } } - .navigationBarHidden(true) - .onAppear { - if #unavailable(iOS 16) { - // this condition prevents re-setting picker - if !justOpened { return } - } - newRole = member.memberRole - do { - let (_, stats) = try apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId) - let (mem, code) = member.memberActive ? try apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil) - member = mem - connectionStats = stats - connectionCode = code - } catch let error { - logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))") - } - justOpened = false - } - .onChange(of: newRole) { _ in - if newRole != member.memberRole { - alert = .changeMemberRoleAlert(mem: member, role: newRole) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .alert(item: $alert) { alertItem in + switch(alertItem) { + case let .removeMemberAlert(mem): return removeMemberAlert(mem) + case let .changeMemberRoleAlert(mem, _): return changeMemberRoleAlert(mem) + case .switchAddressAlert: return switchAddressAlert(switchMemberAddress) + case .abortSwitchAddressAlert: return abortSwitchAddressAlert(abortSwitchMemberAddress) + case .syncConnectionForceAlert: return syncConnectionForceAlert({ syncMemberConnection(force: true) }) + case let .connRequestSentAlert(type): return connReqSentAlert(type) + case let .error(title, error): return Alert(title: Text(title), message: Text(error)) + case let .other(alert): return alert } } - } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .alert(item: $alert) { alertItem in - switch(alertItem) { - case let .removeMemberAlert(mem): return removeMemberAlert(mem) - case let .changeMemberRoleAlert(mem, _): return changeMemberRoleAlert(mem) - case .switchAddressAlert: return switchAddressAlert(switchMemberAddress) - case .abortSwitchAddressAlert: return abortSwitchAddressAlert(abortSwitchMemberAddress) - case .syncConnectionForceAlert: return syncConnectionForceAlert({ syncMemberConnection(force: true) }) - case let .connRequestSentAlert(type): return connReqSentAlert(type) - case let .error(title, error): return Alert(title: Text(title), message: Text(error)) - case let .other(alert): return alert + + if progressIndicator { + ProgressView().scaleEffect(2) } } } @@ -260,6 +269,33 @@ struct GroupMemberInfoView: View { } } + func createMemberContactButton() -> some View { + Button { + progressIndicator = true + Task { + do { + let memberContact = try await apiCreateMemberContact(groupInfo.apiId, member.groupMemberId) + await MainActor.run { + progressIndicator = false + chatModel.addChat(Chat(chatInfo: .direct(contact: memberContact))) + dismissAllSheets(animated: true) + chatModel.chatId = memberContact.id + chatModel.setContactNetworkStatus(memberContact, .connected) + } + } catch let error { + logger.error("createMemberContactButton apiCreateMemberContact error: \(responseError(error))") + let a = getErrorAlert(error, "Error creating member contact") + await MainActor.run { + progressIndicator = false + alert = .error(title: a.title, error: a.message) + } + } + } + } label: { + Label("Send direct message", systemImage: "message") + } + } + private func groupMemberInfoHeader(_ mem: GroupMember) -> some View { VStack { ProfileImage(imageStr: mem.image, color: Color(uiColor: .tertiarySystemFill)) diff --git a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift index 025c765a72..e7580530b6 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift @@ -49,11 +49,10 @@ struct ChatListNavLink: View { } @ViewBuilder private func contactNavLink(_ contact: Contact) -> some View { - let v = NavLinkPlain( + NavLinkPlain( tag: chat.chatInfo.id, selection: $chatModel.chatId, - label: { ChatPreviewView(chat: chat) }, - disabled: !contact.ready + label: { ChatPreviewView(chat: chat) } ) .swipeActions(edge: .leading, allowsFullSwipe: true) { markReadButton() @@ -76,14 +75,6 @@ struct ChatListNavLink: View { .tint(.red) } .frame(height: rowHeights[dynamicTypeSize]) - - if contact.ready { - v - } else { - v.onTapGesture { - AlertManager.shared.showAlert(pendingContactAlert(chat, contact)) - } - } } @ViewBuilder private func groupNavLink(_ groupInfo: GroupInfo) -> some View { diff --git a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift index eccf0b5b42..3ac8fada74 100644 --- a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift @@ -181,7 +181,11 @@ struct ChatPreviewView: View { switch (chat.chatInfo) { case let .direct(contact): if !contact.ready { - chatPreviewInfoText("connecting…") + if contact.nextSendGrpInv { + chatPreviewInfoText("send direct message") + } else { + chatPreviewInfoText("connecting…") + } } case let .group(groupInfo): switch (groupInfo.membership.memberStatus) { diff --git a/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift b/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift index 83ab69278a..966284b0c9 100644 --- a/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift +++ b/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift @@ -251,7 +251,38 @@ private let versionDescriptions: [VersionDescription] = [ description: "- more stable message delivery.\n- a bit better groups.\n- and more!" ), ] - ) + ), + VersionDescription( + version: "v5.3", + post: URL(string: "https://simplex.chat/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.html"), + features: [ + FeatureDescription( + icon: "desktopcomputer", + title: "New desktop app!", + description: "Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" + ), + FeatureDescription( + icon: "lock", + title: "Encrypt stored files & media", + description: "App encrypts new local files (except videos)." + ), + FeatureDescription( + icon: "magnifyingglass", + title: "Discover and join groups", + description: "- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable." + ), + FeatureDescription( + icon: "theatermasks", + title: "Simplified incognito mode", + description: "Toggle incognito when connecting." + ), + FeatureDescription( + icon: "character", + title: "\(4) new interface languages", + description: "Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" + ), + ] + ), ] private let lastVersion = versionDescriptions.last!.version @@ -321,12 +352,15 @@ struct WhatsNewView: View { private func featureDescription(_ icon: String, _ title: LocalizedStringKey, _ description: LocalizedStringKey) -> some View { VStack(alignment: .leading, spacing: 4) { HStack(alignment: .center, spacing: 4) { - Image(systemName: icon).foregroundColor(.secondary) + Image(systemName: icon) + .symbolRenderingMode(.monochrome) + .foregroundColor(.secondary) .frame(minWidth: 30, alignment: .center) Text(title).font(.title3).bold() } Text(description) .multilineTextAlignment(.leading) + .lineLimit(10) } } diff --git a/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift b/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift index 554daaebb1..8e8885b518 100644 --- a/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift @@ -53,7 +53,7 @@ struct AdvancedNetworkSettings: View { timeoutSettingPicker("TCP connection timeout", selection: $netCfg.tcpConnectTimeout, values: [5_000000, 7_500000, 10_000000, 15_000000, 20_000000, 30_000000, 45_000000], label: secondsLabel) timeoutSettingPicker("Protocol timeout", selection: $netCfg.tcpTimeout, values: [3_000000, 5_000000, 7_000000, 10_000000, 15_000000, 20_000000, 30_000000], label: secondsLabel) - timeoutSettingPicker("Protocol timeout per KB", selection: $netCfg.tcpTimeoutPerKb, values: [10_000, 20_000, 40_000, 75_000, 100_000], label: secondsLabel) + timeoutSettingPicker("Protocol timeout per KB", selection: $netCfg.tcpTimeoutPerKb, values: [15_000, 30_000, 60_000, 90_000, 120_000], label: secondsLabel) timeoutSettingPicker("PING interval", selection: $netCfg.smpPingInterval, values: [120_000000, 300_000000, 600_000000, 1200_000000, 2400_000000, 3600_000000], label: secondsLabel) intSettingPicker("PING count", selection: $netCfg.smpPingCount, values: [1, 2, 3, 5, 8], label: "") Toggle("Enable TCP keep-alive", isOn: $enableKeepAlive) diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/Shared/Assets.xcassets/AccentColor.colorset/Contents.json b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/Shared/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000000..59aaf6069d --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/Shared/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,15 @@ +{ + "colors" : [ + { + "idiom" : "universal", + "locale" : "bg" + } + ], + "properties" : { + "localizable" : true + }, + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/Shared/Assets.xcassets/Contents.json b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/Shared/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/Shared/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff index 4015cea6dd..2bf06561a2 100644 --- a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff @@ -2,2591 +2,2783 @@
- +
- + - + No comment provided by engineer. - + - + No comment provided by engineer. - + - + No comment provided by engineer. - + - + No comment provided by engineer. - + ( - ( + ( No comment provided by engineer. - + (can be copied) - (може да се копира) + (може да се копира) No comment provided by engineer. - + !1 colored! - !1 цветно! + !1 цветно! No comment provided by engineer. - - #secret# - #тайно# - No comment provided by engineer. + + # %@ + # %@ + copied message info title, # <title> - - %@ - %@ - No comment provided by engineer. - - - %@ %@ - %@ %@ - No comment provided by engineer. - - - %@ (current) - %@ (текущ) - No comment provided by engineer. - - - %@ (current): - %@ (текущ): + + ## History + ## История copied message info - - %@ / %@ - %@ / %@ + + ## In reply to + ## В отговор на + copied message info + + + #secret# + #тайно# No comment provided by engineer. - + + %@ + %@ + No comment provided by engineer. + + + %@ %@ + %@ %@ + No comment provided by engineer. + + + %@ (current) + %@ (текущ) + No comment provided by engineer. + + + %@ (current): + %@ (текущ): + copied message info + + + %@ / %@ + %@ / %@ + No comment provided by engineer. + + + %@ and %@ connected + %@ и %@ са свързани + No comment provided by engineer. + + %1$@ at %2$@: - %1$@ в %2$@: + %1$@ в %2$@: copied message info, <sender> at <time> - + %@ is connected! - %@ е свързан! + %@ е свързан! notification title - + %@ is not verified - %@ не е потвърдено + %@ не е потвърдено No comment provided by engineer. - + %@ is verified - %@ е потвърдено + %@ е потвърдено No comment provided by engineer. - + %@ servers - %@ сървъри + %@ сървъри No comment provided by engineer. - + %@ wants to connect! - %@ иска да се свърже! + %@ иска да се свърже! notification title - + + %@, %@ and %lld other members connected + %@, %@ и %lld други членове са свързани + No comment provided by engineer. + + %@: - %@: + %@: copied message info - + %d days - %d дни + %d дни time interval - + %d hours - %d часа + %d часа time interval - + %d min - %d мин. + %d мин. time interval - + %d months - %d месеца + %d месеца time interval - + %d sec - %d сек. + %d сек. time interval - + %d skipped message(s) - %d пропуснато(и) съобщение(я) + %d пропуснато(и) съобщение(я) integrity error chat item - + %d weeks - %d седмици + %d седмици time interval - + %lld - %lld + %lld No comment provided by engineer. - + %lld %@ - %lld %@ + %lld %@ No comment provided by engineer. - + %lld contact(s) selected - %lld избран(и) контакт(а) + %lld избран(и) контакт(а) No comment provided by engineer. - + %lld file(s) with total size of %@ - %lld файл(а) с общ размер от %@ + %lld файл(а) с общ размер от %@ No comment provided by engineer. - + %lld members - %lld членове + %lld членове No comment provided by engineer. - + %lld minutes - %lld минути + %lld минути No comment provided by engineer. - + + %lld new interface languages + %lld нови езици на интерфейса + No comment provided by engineer. + + %lld second(s) - %lld секунда(и) + %lld секунда(и) No comment provided by engineer. - + %lld seconds - %lld секунди + %lld секунди No comment provided by engineer. - + %lldd - %lldд + %lldд No comment provided by engineer. - + %lldh - %lldч + %lldч No comment provided by engineer. - + %lldk - %lldk + %lldk No comment provided by engineer. - + %lldm - %lldм + %lldм No comment provided by engineer. - + %lldmth - %lldмесц. + %lldмесц. No comment provided by engineer. - + %llds - %lldс + %lldс No comment provided by engineer. - + %lldw - %lldсед. + %lldсед. No comment provided by engineer. - + %u messages failed to decrypt. - %u съобщения не успяха да се декриптират. + %u съобщения не успяха да се декриптират. No comment provided by engineer. - + %u messages skipped. - %u пропуснати съобщения. + %u пропуснати съобщения. No comment provided by engineer. - + ( - ( + ( No comment provided by engineer. - + ) - ) + ) No comment provided by engineer. - + **Add new contact**: to create your one-time QR Code or link for your contact. - **Добави нов контакт**: за да създадете своя еднократен QR код или линк за вашия контакт. + **Добави нов контакт**: за да създадете своя еднократен QR код или линк за вашия контакт. No comment provided by engineer. - + **Create link / QR code** for your contact to use. - **Създай линк / QR код**, който вашият контакт да използва. + **Създай линк / QR код**, който вашият контакт да използва. No comment provided by engineer. - + **More private**: check new messages every 20 minutes. Device token is shared with SimpleX Chat server, but not how many contacts or messages you have. - **По поверително**: проверявайте новите съобщения на всеки 20 минути. Токенът на устройството се споделя със сървъра за чат SimpleX, но не и колко контакти или съобщения имате. + **По поверително**: проверявайте новите съобщения на всеки 20 минути. Токенът на устройството се споделя със сървъра за чат SimpleX, но не и колко контакти или съобщения имате. No comment provided by engineer. - + **Most private**: do not use SimpleX Chat notifications server, check messages periodically in the background (depends on how often you use the app). - **Най-поверително**: не използвайте сървъра за известия SimpleX Chat, периодично проверявайте съобщенията във фонов режим (зависи от това колко често използвате приложението). + **Най-поверително**: не използвайте сървъра за известия SimpleX Chat, периодично проверявайте съобщенията във фонов режим (зависи от това колко често използвате приложението). No comment provided by engineer. - + **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Поставете получения линк** или го отворете в браузъра и докоснете **Отваряне в мобилно приложение**. + **Поставете получения линк** или го отворете в браузъра и докоснете **Отваряне в мобилно приложение**. No comment provided by engineer. - + **Please note**: you will NOT be able to recover or change passphrase if you lose it. - **Моля, обърнете внимание**: НЯМА да можете да възстановите или промените паролата, ако я загубите. + **Моля, обърнете внимание**: НЯМА да можете да възстановите или промените паролата, ако я загубите. No comment provided by engineer. - + **Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from. - **Препоръчително**: токенът на устройството и известията се изпращат до сървъра за уведомяване на SimpleX Chat, но не и съдържанието, размерът на съобщението или от кого е. + **Препоръчително**: токенът на устройството и известията се изпращат до сървъра за уведомяване на SimpleX Chat, но не и съдържанието, размерът на съобщението или от кого е. No comment provided by engineer. - + **Scan QR code**: to connect to your contact in person or via video call. - **Сканирай QR код**: за да се свържете с вашия контакт лично или чрез видеообаждане. + **Сканирай QR код**: за да се свържете с вашия контакт лично или чрез видеообаждане. No comment provided by engineer. - + **Warning**: Instant push notifications require passphrase saved in Keychain. - **Внимание**: Незабавните push известия изискват парола, запазена в Keychain. + **Внимание**: Незабавните push известия изискват парола, запазена в Keychain. No comment provided by engineer. - + **e2e encrypted** audio call - **e2e криптиран**аудио разговор + **e2e криптиран**аудио разговор No comment provided by engineer. - + **e2e encrypted** video call - **e2e криптирано** видео разговор + **e2e криптирано** видео разговор No comment provided by engineer. - + \*bold* - \*удебелен* + \*удебелен* No comment provided by engineer. - + , - , + , No comment provided by engineer. - + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + - свържете се с [директория за услуги](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjd LW3%23%2F%3Fv%3D1-2%26dh %3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (БЕТА)! +- потвърждениe за доставка (до 20 члена). +- по-бързо и по-стабилно. + No comment provided by engineer. + + + - more stable message delivery. +- a bit better groups. +- and more! + - по-стабилна доставка на съобщения. +- малко по-добри групи. +- и още! + No comment provided by engineer. + + - voice messages up to 5 minutes. - custom time to disappear. - editing history. - - гласови съобщения до 5 минути. + - гласови съобщения до 5 минути. - персонализирано време за изчезване. - история на редактиране. No comment provided by engineer. - + . - . + . No comment provided by engineer. - + 0s - 0s + 0s No comment provided by engineer. - + 1 day - 1 ден + 1 ден time interval - + 1 hour - 1 час + 1 час time interval - + 1 minute - 1 минута + 1 минута No comment provided by engineer. - + 1 month - 1 месец + 1 месец time interval - + 1 week - 1 седмица + 1 седмица time interval - + 1-time link - 1-кратен линк + Еднократен линк No comment provided by engineer. - + 5 minutes - 5 минути + 5 минути No comment provided by engineer. - + 6 - 6 + 6 No comment provided by engineer. - + 30 seconds - 30 секунди + 30 секунди No comment provided by engineer. - + : - : + : No comment provided by engineer. - + <p>Hi!</p> <p><a href="%@">Connect to me via SimpleX Chat</a></p> - <p>Здравейте!</p> + <p>Здравейте!</p> <p><a href="%@">Свържете се с мен чрез SimpleX Chat</a></p> email text - + + A few more things + Още няколко неща + No comment provided by engineer. + + A new contact - Нов контакт + Нов контакт notification title - - A random profile will be sent to the contact that you received this link from + + A new random profile will be shared. + Нов автоматично генериран профил ще бъде споделен. No comment provided by engineer. - - A random profile will be sent to your contact - No comment provided by engineer. - - + A separate TCP connection will be used **for each chat profile you have in the app**. - Ще се използва отделна TCP връзка **за всеки чатпрофил, който имате в приложението**. + Ще се използва отделна TCP връзка **за всеки чатпрофил, който имате в приложението**. No comment provided by engineer. - + A separate TCP connection will be used **for each contact and group member**. **Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail. - Ще се използва отделна TCP връзка **за всеки контакт и член на групата**. + Ще се използва отделна TCP връзка **за всеки контакт и член на групата**. **Моля, обърнете внимание**: ако имате много връзки, консумацията на батерията и трафика може да бъде значително по-висока и някои връзки може да се провалят. No comment provided by engineer. - + Abort - Откажи + Откажи No comment provided by engineer. - + Abort changing address - Откажи смяна на адрес + Откажи смяна на адрес No comment provided by engineer. - + Abort changing address? - Откажи смяна на адрес? + Откажи смяна на адрес? No comment provided by engineer. - + About SimpleX - За SimpleX + За SimpleX No comment provided by engineer. - + About SimpleX Chat - За SimpleX Chat + За SimpleX Chat No comment provided by engineer. - + About SimpleX address - Повече за SimpleX адреса + Повече за SimpleX адреса No comment provided by engineer. - + Accent color - Основен цвят + Основен цвят No comment provided by engineer. - + Accept - Приеми + Приеми accept contact request via notification accept incoming call via notification - - Accept contact + + Accept connection request? + Приемане на заявка за връзка? No comment provided by engineer. - + Accept contact request from %@? - Приемане на заявка за контакт от %@? + Приемане на заявка за контакт от %@? notification body - + Accept incognito - Приеми инкогнито - No comment provided by engineer. + Приеми инкогнито + accept contact request via notification - + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. - Добавете адрес към вашия профил, така че вашите контакти да могат да го споделят с други хора. Актуализацията на профила ще бъде изпратена до вашите контакти. + Добавете адрес към вашия профил, така че вашите контакти да могат да го споделят с други хора. Актуализацията на профила ще бъде изпратена до вашите контакти. No comment provided by engineer. - + Add preset servers - Добави предварително зададени сървъри + Добави предварително зададени сървъри No comment provided by engineer. - + Add profile - Добави профил + Добави профил No comment provided by engineer. - + Add servers by scanning QR codes. - Добави сървъри чрез сканиране на QR кодове. + Добави сървъри чрез сканиране на QR кодове. No comment provided by engineer. - + Add server… - Добави сървър… + Добави сървър… No comment provided by engineer. - + Add to another device - Добави към друго устройство + Добави към друго устройство No comment provided by engineer. - + Add welcome message - Добави съобщение при посрещане + Добави съобщение при посрещане No comment provided by engineer. - + Address - Адрес + Адрес No comment provided by engineer. - + Address change will be aborted. Old receiving address will be used. - Промяната на адреса ще бъде прекъсната. Ще се използва старият адрес за получаване. + Промяната на адреса ще бъде прекъсната. Ще се използва старият адрес за получаване. No comment provided by engineer. - + Admins can create the links to join groups. - Админите могат да създадат линкове за присъединяване към групи. + Админите могат да създадат линкове за присъединяване към групи. No comment provided by engineer. - + Advanced network settings - Разширени мрежови настройки + Разширени мрежови настройки No comment provided by engineer. - + All app data is deleted. - Всички данни от приложението бяха изтрити. + Всички данни от приложението бяха изтрити. No comment provided by engineer. - + All chats and messages will be deleted - this cannot be undone! - Всички чатове и съобщения ще бъдат изтрити - това не може да бъде отменено! + Всички чатове и съобщения ще бъдат изтрити - това не може да бъде отменено! No comment provided by engineer. - + All data is erased when it is entered. - Всички данни се изтриват при въвеждане. + Всички данни се изтриват при въвеждане. No comment provided by engineer. - + All group members will remain connected. - Всички членове на групата ще останат свързани. + Всички членове на групата ще останат свързани. No comment provided by engineer. - + All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. - Всички съобщения ще бъдат изтрити - това не може да бъде отменено! Съобщенията ще бъдат изтрити САМО за вас. + Всички съобщения ще бъдат изтрити - това не може да бъде отменено! Съобщенията ще бъдат изтрити САМО за вас. No comment provided by engineer. - + All your contacts will remain connected. - Всички ваши контакти ще останат свързани. + Всички ваши контакти ще останат свързани. No comment provided by engineer. - + All your contacts will remain connected. Profile update will be sent to your contacts. - Всички ваши контакти ще останат свързани. Актуализацията на профила ще бъде изпратена до вашите контакти. + Всички ваши контакти ще останат свързани. Актуализацията на профила ще бъде изпратена до вашите контакти. No comment provided by engineer. - + Allow - Позволи + Позволи No comment provided by engineer. - + Allow calls only if your contact allows them. - Позволи обаждания само ако вашият контакт ги разрешава. + Позволи обаждания само ако вашият контакт ги разрешава. No comment provided by engineer. - + Allow disappearing messages only if your contact allows it to you. - Позволи изчезващи съобщения само ако вашият контакт ги разрешава. + Позволи изчезващи съобщения само ако вашият контакт ги разрешава. No comment provided by engineer. Allow irreversible message deletion only if your contact allows it to you. + Позволи необратимо изтриване на съобщение само ако вашият контакт го рарешава. No comment provided by engineer. - + Allow message reactions only if your contact allows them. - Позволи реакции на съобщения само ако вашият контакт ги разрешава. + Позволи реакции на съобщения само ако вашият контакт ги разрешава. No comment provided by engineer. - + Allow message reactions. - Позволи реакции на съобщения. + Позволи реакции на съобщения. No comment provided by engineer. - + Allow sending direct messages to members. - Позволи изпращането на лични съобщения до членовете. + Позволи изпращането на лични съобщения до членовете. No comment provided by engineer. Allow sending disappearing messages. + Разреши изпращането на изчезващи съобщения. No comment provided by engineer. - + Allow to irreversibly delete sent messages. - Позволи необратимо изтриване на изпратените съобщения. + Позволи необратимо изтриване на изпратените съобщения. No comment provided by engineer. - + Allow to send files and media. - Позволи изпращане на файлове и медия. + Позволи изпращане на файлове и медия. No comment provided by engineer. - + Allow to send voice messages. - Позволи изпращане на гласови съобщения. + Позволи изпращане на гласови съобщения. No comment provided by engineer. - + Allow voice messages only if your contact allows them. - Позволи гласови съобщения само ако вашият контакт ги разрешава. + Позволи гласови съобщения само ако вашият контакт ги разрешава. No comment provided by engineer. - + Allow voice messages? - Позволи гласови съобщения? + Позволи гласови съобщения? No comment provided by engineer. - + Allow your contacts adding message reactions. - Позволи на вашите контакти да добавят реакции към съобщения. + Позволи на вашите контакти да добавят реакции към съобщения. No comment provided by engineer. - + Allow your contacts to call you. - Позволи на вашите контакти да ви се обаждат. + Позволи на вашите контакти да ви се обаждат. No comment provided by engineer. - + Allow your contacts to irreversibly delete sent messages. - Позволи на вашите контакти да изтриват необратимо изпратените съобщения. + Позволи на вашите контакти да изтриват необратимо изпратените съобщения. No comment provided by engineer. - + Allow your contacts to send disappearing messages. - Позволи на вашите контакти да изпращат изчезващи съобщения. + Позволи на вашите контакти да изпращат изчезващи съобщения. No comment provided by engineer. - + Allow your contacts to send voice messages. - Позволи на вашите контакти да изпращат гласови съобщения. + Позволи на вашите контакти да изпращат гласови съобщения. No comment provided by engineer. Already connected? + Вече сте свързани? No comment provided by engineer. - + Always use relay - Винаги използвай реле + Винаги използвай реле No comment provided by engineer. - + An empty chat profile with the provided name is created, and the app opens as usual. - Създаен беше празен профил за чат с предоставеното име и приложението се отвари както обикновено. + Създаен беше празен профил за чат с предоставеното име и приложението се отвари както обикновено. No comment provided by engineer. - + Answer call - Отговор на повикване + Отговор на повикване No comment provided by engineer. App build: %@ + Компилация на приложението: %@ + No comment provided by engineer. + + + App encrypts new local files (except videos). + Приложението криптира нови локални файлове (с изключение на видеоклипове). No comment provided by engineer. App icon + Икона на приложението No comment provided by engineer. - + App passcode - Код за достъп до приложението + Код за достъп до приложението No comment provided by engineer. - + App passcode is replaced with self-destruct passcode. - Кода за достъп до приложение се заменя с код за самоунищожение. + Кода за достъп до приложение се заменя с код за самоунищожение. No comment provided by engineer. - + App version - Версия на приложението + Версия на приложението No comment provided by engineer. - + App version: v%@ - Версия на приложението: v%@ + Версия на приложението: v%@ No comment provided by engineer. - + Appearance - Изглед + Изглед No comment provided by engineer. - + Attach - Прикачи + Прикачи No comment provided by engineer. - + Audio & video calls - Аудио и видео разговори + Аудио и видео разговори No comment provided by engineer. - + Audio and video calls - Аудио и видео разговори + Аудио и видео разговори No comment provided by engineer. - + Audio/video calls - Аудио/видео разговори + Аудио/видео разговори chat feature - + Audio/video calls are prohibited. - Аудио/видео разговорите са забранени. + Аудио/видео разговорите са забранени. No comment provided by engineer. - + Authentication cancelled - Идентификацията е отменена + Идентификацията е отменена PIN entry - + Authentication failed - Неуспешна идентификация + Неуспешна идентификация No comment provided by engineer. Authentication is required before the call is connected, but you may miss calls. + Изисква се идентификацията, преди да се осъществи обаждането, но може да пропуснете повиквания. No comment provided by engineer. - + Authentication unavailable - Идентификацията е недостъпна + Идентификацията е недостъпна No comment provided by engineer. - + Auto-accept - Автоматично приемане + Автоматично приемане No comment provided by engineer. - + Auto-accept contact requests - Автоматично приемане на заявки за контакт + Автоматично приемане на заявки за контакт No comment provided by engineer. - + Auto-accept images - Автоматично приемане на изображения + Автоматично приемане на изображения No comment provided by engineer. - + Back - Назад + Назад No comment provided by engineer. - + Bad message ID - Лошо ID на съобщението + Лошо ID на съобщението No comment provided by engineer. - + Bad message hash - Лош хеш на съобщението + Лош хеш на съобщението No comment provided by engineer. - + Better messages - По-добри съобщения + По-добри съобщения No comment provided by engineer. - + Both you and your contact can add message reactions. - И вие, и вашият контакт можете да добавяте реакции към съобщението. + И вие, и вашият контакт можете да добавяте реакции към съобщението. No comment provided by engineer. - + Both you and your contact can irreversibly delete sent messages. - И вие, и вашият контакт можете да изтриете необратимо изпратените съобщения. + И вие, и вашият контакт можете да изтриете необратимо изпратените съобщения. No comment provided by engineer. - + Both you and your contact can make calls. - И вие, и вашият контакт можете да осъществявате обаждания. + И вие, и вашият контакт можете да осъществявате обаждания. No comment provided by engineer. - + Both you and your contact can send disappearing messages. - И вие, и вашият контакт можете да изпращате изчезващи съобщения. + И вие, и вашият контакт можете да изпращате изчезващи съобщения. No comment provided by engineer. - + Both you and your contact can send voice messages. - И вие, и вашият контакт можете да изпращате гласови съобщения. + И вие, и вашият контакт можете да изпращате гласови съобщения. + No comment provided by engineer. + + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Български, финландски, тайландски и украински - благодарение на потребителите и [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! 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). + Чрез чат профил (по подразбиране) или [чрез връзка](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (БЕТА). No comment provided by engineer. - + Call already ended! - Разговорът вече приключи! + Разговорът вече приключи! No comment provided by engineer. Calls + Обаждания No comment provided by engineer. - + Can't delete user profile! - Потребителският профил не може да се изтрие! + Потребителският профил не може да се изтрие! No comment provided by engineer. - + Can't invite contact! - Не може да покани контакта! + Не може да покани контакта! No comment provided by engineer. - + Can't invite contacts! - Не може да поканят контактите! + Не може да поканят контактите! No comment provided by engineer. - + Cancel - Отказ + Отказ No comment provided by engineer. Cannot access keychain to save database password + Няма достъп до Keychain за запазване на паролата за базата данни No comment provided by engineer. - + Cannot receive file - Файлът не може да бъде получен + Файлът не може да бъде получен No comment provided by engineer. - + Change - Промени + Промени No comment provided by engineer. - + Change database passphrase? - Промяна на паролата на базата данни? + Промяна на паролата на базата данни? No comment provided by engineer. - + Change lock mode - Промяна на режима на заключване + Промяна на режима на заключване authentication reason Change member role? + Промяна на ролята на члена? No comment provided by engineer. - + Change passcode - Промени kодa за достъп + Промени kодa за достъп authentication reason - + Change receiving address - Промени адреса за получаване + Промени адреса за получаване No comment provided by engineer. - + Change receiving address? - Промени адреса за получаване? + Промени адреса за получаване? No comment provided by engineer. - + Change role - Промени ролята + Промени ролята No comment provided by engineer. - + Change self-destruct mode - Промени режима на самоунищожение + Промени режима на самоунищожение authentication reason - + Change self-destruct passcode - Промени кода за достъп за самоунищожение + Промени кода за достъп за самоунищожение authentication reason set passcode view - + Chat archive - Архив на чата + Архив на чата No comment provided by engineer. - + Chat console - Конзола + Конзола No comment provided by engineer. Chat database + База данни за чата No comment provided by engineer. - + Chat database deleted - Базата данни на чата е изтрита + Базата данни на чата е изтрита No comment provided by engineer. - + Chat database imported - Базата данни на чат е импортирана + Базата данни на чат е импортирана No comment provided by engineer. - + Chat is running - Чатът работи + Чатът работи No comment provided by engineer. - + Chat is stopped - Чатът е спрян + Чатът е спрян No comment provided by engineer. - + Chat preferences - Чат настройки + Чат настройки No comment provided by engineer. - + Chats - Чатове + Чатове No comment provided by engineer. - + Check server address and try again. - Проверете адреса на сървъра и опитайте отново. + Проверете адреса на сървъра и опитайте отново. No comment provided by engineer. - + Chinese and Spanish interface - Китайски и Испански интерфейс + Китайски и Испански интерфейс No comment provided by engineer. Choose file + Избери файл No comment provided by engineer. Choose from library + Избери от библиотеката No comment provided by engineer. - + Clear - Изчисти + Изчисти No comment provided by engineer. Clear conversation + Изчисти разговора No comment provided by engineer. Clear conversation? + Изчисти разговора? No comment provided by engineer. - + Clear verification - Изчисти проверката + Изчисти проверката No comment provided by engineer. Colors + Цветове No comment provided by engineer. - + Compare file - Сравни файл + Сравни файл server test step - + Compare security codes with your contacts. - Сравнете кодовете за сигурност с вашите контакти. + Сравнете кодовете за сигурност с вашите контакти. No comment provided by engineer. - + Configure ICE servers - Конфигурирай ICE сървъри + Конфигурирай ICE сървъри No comment provided by engineer. - + Confirm - Потвърди + Потвърди No comment provided by engineer. - + Confirm Passcode - Потвърди kодa за достъп + Потвърди kодa за достъп No comment provided by engineer. - + Confirm database upgrades - Потвърди актуализаациите на базата данни + Потвърди актуализаациите на базата данни No comment provided by engineer. - + Confirm new passphrase… - Потвърди новата парола… + Потвърди новата парола… No comment provided by engineer. - + Confirm password - Потвърди парола + Потвърди парола No comment provided by engineer. - + Connect - Свързване + Свързване server test step - - Connect via contact link? + + Connect directly + Свързване директно No comment provided by engineer. - + + Connect incognito + Свързване инкогнито + No comment provided by engineer. + + + Connect via contact link + Свързване чрез линк на контакта + No comment provided by engineer. + + Connect via group link? - Свързване чрез групов линк? + Свързване чрез групов линк? No comment provided by engineer. - + Connect via link - Свърване чрез линк + Свърване чрез линк No comment provided by engineer. - + Connect via link / QR code - Свърване чрез линк/QR код + Свърване чрез линк/QR код No comment provided by engineer. - - Connect via one-time link? + + Connect via one-time link + Свързване чрез еднократен линк за връзка No comment provided by engineer. Connecting to server… + Свързване със сървъра… No comment provided by engineer. Connecting to server… (error: %@) + Свързване със сървър…(грешка: %@) No comment provided by engineer. - + Connection - Връзка + Връзка No comment provided by engineer. - + Connection error - Грешка при свързване + Грешка при свързване No comment provided by engineer. - + Connection error (AUTH) - Грешка при свързване (AUTH) + Грешка при свързване (AUTH) No comment provided by engineer. - - Connection request - No comment provided by engineer. - - + Connection request sent! - Заявката за връзка е изпратена! + Заявката за връзка е изпратена! No comment provided by engineer. - + Connection timeout - Времето на изчакване за установяване на връзката изтече + Времето на изчакване за установяване на връзката изтече No comment provided by engineer. - + Contact allows - Контактът позволява + Контактът позволява No comment provided by engineer. - + Contact already exists - Контактът вече съществува + Контактът вече съществува No comment provided by engineer. - + Contact and all messages will be deleted - this cannot be undone! - Контактът и всички съобщения ще бъдат изтрити - това не може да бъде отменено! + Контактът и всички съобщения ще бъдат изтрити - това не може да бъде отменено! No comment provided by engineer. - + Contact hidden: - Контактът е скрит: + Контактът е скрит: notification Contact is connected + Контактът е свързан notification - + Contact is not connected yet! - Контактът все още не е свързан! + Контактът все още не е свързан! No comment provided by engineer. - + Contact name - Име на контакт + Име на контакт No comment provided by engineer. - + Contact preferences - Настройки за контакт + Настройки за контакт No comment provided by engineer. - + Contacts - Контакти + Контакти No comment provided by engineer. - + Contacts can mark messages for deletion; you will be able to view them. - Контактите могат да маркират съобщения за изтриване; ще можете да ги разглеждате. + Контактите могат да маркират съобщения за изтриване; ще можете да ги разглеждате. No comment provided by engineer. - + Continue - Продължи + Продължи No comment provided by engineer. - + Copy - Копирай + Копирай chat item action Core version: v%@ + Версия на ядрото: v%@ No comment provided by engineer. - + Create - Създай + Създай No comment provided by engineer. - + Create SimpleX address - Създай SimpleX адрес + Създай SimpleX адрес No comment provided by engineer. - + Create an address to let people connect with you. - Създайте адрес, за да позволите на хората да се свързват с вас. + Създайте адрес, за да позволите на хората да се свързват с вас. No comment provided by engineer. - + Create file - Създай файл + Създай файл server test step - + Create group link - Създай групов линк + Създай групов линк No comment provided by engineer. - + Create link - Създай линк + Създай линк No comment provided by engineer. - + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + Създайте нов профил в [настолното приложение](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + + Create one-time invitation link - Създай линк за еднократна покана + Създай линк за еднократна покана No comment provided by engineer. - + Create queue - Създай опашка + Създай опашка server test step - + Create secret group - Създай тайна група + Създай тайна група No comment provided by engineer. - + Create your profile - Създай своя профил + Създай своя профил No comment provided by engineer. Created on %@ + Създаден на %@ No comment provided by engineer. - + Current Passcode - Текущ kод за достъп + Текущ kод за достъп No comment provided by engineer. - + Current passphrase… - Текуща парола… + Текуща парола… No comment provided by engineer. Currently maximum supported file size is %@. + В момента максималният поддържан размер на файла е %@. No comment provided by engineer. - + Custom time - Персонализирано време + Персонализирано време No comment provided by engineer. - + Dark - Тъмна + Тъмна No comment provided by engineer. - + Database ID - ID в базата данни + ID в базата данни No comment provided by engineer. - + Database ID: %d - ID в базата данни: %d + ID в базата данни: %d copied message info - + Database IDs and Transport isolation option. - Идентификатори в базата данни и опция за изолация на транспорта. + Идентификатори в базата данни и опция за изолация на транспорта. No comment provided by engineer. - + Database downgrade - Понижаване на версията на базата данни + Понижаване на версията на базата данни No comment provided by engineer. - + Database encrypted! - Базата данни е криптирана! + Базата данни е криптирана! No comment provided by engineer. Database encryption passphrase will be updated and stored in the keychain. - No comment provided by engineer. - - - Database encryption passphrase will be updated. - - Паролата за криптиране на базата данни ще бъде актуализирана. + Паролата за криптиране на базата данни ще бъде актуализирана и съхранена в Keychain. No comment provided by engineer. - + + Database encryption passphrase will be updated. + + Паролата за криптиране на базата данни ще бъде актуализирана. + + No comment provided by engineer. + + Database error - Грешка в базата данни + Грешка в базата данни No comment provided by engineer. - + Database is encrypted using a random passphrase, you can change it. - Базата данни е криптирана с произволна парола, можете да я промените. + Базата данни е криптирана с автоматично генерирана парола, можете да я промените. No comment provided by engineer. - + Database is encrypted using a random passphrase. Please change it before exporting. - Базата данни е криптирана с произволна парола. Моля, променете я преди експортиране. + Базата данни е криптирана с автоматично генерирана парола. Моля, променете я преди експортиране. No comment provided by engineer. - + Database passphrase - Парола за базата данни + Парола за базата данни No comment provided by engineer. - + Database passphrase & export - Парола за базата данни и експортиране + Парола за базата данни и експортиране No comment provided by engineer. Database passphrase is different from saved in the keychain. + Паролата на базата данни е различна от записаната в Keychain. No comment provided by engineer. - + Database passphrase is required to open chat. - Изисква се паролата за базата данни, за да се отвори чата. + Изисква се паролата за базата данни, за да се отвори чата. No comment provided by engineer. - + Database upgrade - Актуализация на базата данни + Актуализация на базата данни No comment provided by engineer. Database will be encrypted and the passphrase stored in the keychain. + Базата данни ще бъде криптирана и паролата ще бъде съхранена в Keychain. + No comment provided by engineer. - + Database will be encrypted. - Базата данни ще бъде криптирана. + Базата данни ще бъде криптирана. No comment provided by engineer. Database will be migrated when the app restarts + Базата данни ще бъде мигрирана, когато приложението се рестартира No comment provided by engineer. - + Decentralized - Децентрализиран + Децентрализиран No comment provided by engineer. - + Decryption error - Грешка при декриптиране + Грешка при декриптиране message decrypt error item - + Delete - Изтрий + Изтрий chat item action - + Delete Contact - Изтрий контакт + Изтрий контакт No comment provided by engineer. - + Delete address - Изтрий адрес + Изтрий адрес No comment provided by engineer. - + Delete address? - Изтрий адрес? + Изтрий адрес? No comment provided by engineer. - + Delete after - Изтрий след + Изтрий след No comment provided by engineer. - + Delete all files - Изтрий всички файлове + Изтрий всички файлове No comment provided by engineer. - + Delete archive - Изтрий архив + Изтрий архив No comment provided by engineer. - + Delete chat archive? - Изтриване на архива на чата? + Изтриване на архива на чата? No comment provided by engineer. - + Delete chat profile - Изтрий чат профила + Изтрий чат профила No comment provided by engineer. - + Delete chat profile? - Изтриване на чат профила? + Изтриване на чат профила? No comment provided by engineer. Delete connection + Изтрий връзката No comment provided by engineer. - + Delete contact - Изтрий контакт + Изтрий контакт No comment provided by engineer. - + Delete contact? - Изтрий контакт? + Изтрий контакт? No comment provided by engineer. - + Delete database - Изтрий базата данни + Изтрий базата данни No comment provided by engineer. - + Delete file - Изтрий файл + Изтрий файл server test step - + Delete files and media? - Изтрий файлове и медия? + Изтрий файлове и медия? No comment provided by engineer. - + Delete files for all chat profiles - Изтрий файловете за всички чат профили + Изтрий файловете за всички чат профили No comment provided by engineer. - + Delete for everyone - Изтрий за всички + Изтрий за всички chat feature - + Delete for me - Изтрий за мен + Изтрий за мен No comment provided by engineer. - + Delete group - Изтрий група + Изтрий група No comment provided by engineer. - + Delete group? - Изтрий група? + Изтрий група? No comment provided by engineer. Delete invitation + Изтрий поканата No comment provided by engineer. - + Delete link - Изтрий линк + Изтрий линк No comment provided by engineer. - + Delete link? - Изтрий линк? + Изтрий линк? No comment provided by engineer. - + Delete member message? - Изтрий съобщението на члена? + Изтрий съобщението на члена? No comment provided by engineer. - + Delete message? - Изтрий съобщението? + Изтрий съобщението? No comment provided by engineer. - + Delete messages - Изтрий съобщенията + Изтрий съобщенията No comment provided by engineer. - + Delete messages after - Изтрий съобщенията след + Изтрий съобщенията след No comment provided by engineer. Delete old database + Изтрий старата база данни No comment provided by engineer. Delete old database? + Изтрий старата база данни? No comment provided by engineer. - + Delete pending connection - Изтрий предстоящата връзка + Изтрий предстоящата връзка No comment provided by engineer. - + Delete pending connection? - Изтрий предстоящата връзка? + Изтрий предстоящата връзка? No comment provided by engineer. - + Delete profile - Изтрий профил + Изтрий профил No comment provided by engineer. - + Delete queue - Изтрий опашка + Изтрий опашка server test step Delete user profile? + Изтрий потребителския профил? No comment provided by engineer. - + Deleted at - Изтрито на + Изтрито на No comment provided by engineer. - + Deleted at: %@ - Изтрито на: %@ + Изтрито на: %@ copied message info - + + Delivery + Доставка + No comment provided by engineer. + + Delivery receipts are disabled! - Потвърждениeто за доставка е деактивирано! + Потвърждениeто за доставка е деактивирано! No comment provided by engineer. - - Delivery receipts will be enabled for all contacts in all visible chat profiles. - No comment provided by engineer. - - - Delivery receipts will be enabled for all contacts. - No comment provided by engineer. - - + Delivery receipts! - Потвърждениe за доставка! + Потвърждениe за доставка! No comment provided by engineer. - + Description - Описание + Описание No comment provided by engineer. Develop + Разработване No comment provided by engineer. - + Developer tools - Инструменти за разработчици + Инструменти за разработчици No comment provided by engineer. Device + Устройство No comment provided by engineer. - + Device authentication is disabled. Turning off SimpleX Lock. - Идентификацията на устройството е деактивирано. Изключване на SimpleX заключване. + Идентификацията на устройството е деактивирано. Изключване на SimpleX заключване. No comment provided by engineer. - + Device authentication is not enabled. You can turn on SimpleX Lock via Settings, once you enable device authentication. - Идентификацията на устройството не е активирана. Можете да включите SimpleX заключване през Настройки, след като активирате идентификацията на устройството. + Идентификацията на устройството не е активирана. Можете да включите SimpleX заключване през Настройки, след като активирате идентификацията на устройството. No comment provided by engineer. - + Different names, avatars and transport isolation. - Различни имена, аватари и транспортна изолация. + Различни имена, аватари и транспортна изолация. No comment provided by engineer. - + Direct messages - Лични съобщения + Лични съобщения chat feature - + Direct messages between members are prohibited in this group. - Личните съобщения между членовете са забранени в тази група. + Личните съобщения между членовете са забранени в тази група. No comment provided by engineer. - + + Disable (keep overrides) + Деактивиране (запазване на промените) + No comment provided by engineer. + + Disable SimpleX Lock - Деактивирай SimpleX заключване + Деактивирай SimpleX заключване authentication reason - - Disappearing message - Изчезващо съобщение + + Disable for all + Деактивиране за всички No comment provided by engineer. - + + Disappearing message + Изчезващо съобщение + No comment provided by engineer. + + Disappearing messages - Изчезващи съобщения + Изчезващи съобщения chat feature - + Disappearing messages are prohibited in this chat. - Изчезващите съобщения са забранени в този чат. + Изчезващите съобщения са забранени в този чат. No comment provided by engineer. - + Disappearing messages are prohibited in this group. - Изчезващите съобщения са забранени в тази група. + Изчезващите съобщения са забранени в тази група. No comment provided by engineer. - + Disappears at - Изчезва в + Изчезва в No comment provided by engineer. - + Disappears at: %@ - Изчезва в: %@ + Изчезва в: %@ copied message info - + Disconnect - Прекъсни връзката + Прекъсни връзката server test step - - Display name - Показвано Име + + Discover and join groups + Открийте и се присъединете към групи No comment provided by engineer. - + + Display name + Показвано Име + No comment provided by engineer. + + Display name: - Показвано име: + Показвано име: No comment provided by engineer. Do NOT use SimpleX for emergency calls. + НЕ използвайте SimpleX за спешни повиквания. No comment provided by engineer. Do it later + Отложи No comment provided by engineer. - + Don't create address - Не създавай адрес + Не създавай адрес No comment provided by engineer. - + + Don't enable + Не активирай + No comment provided by engineer. + + Don't show again - Не показвай отново + Не показвай отново No comment provided by engineer. - + Downgrade and open chat - Понижи версията и отвори чата + Понижи версията и отвори чата No comment provided by engineer. - + Download file - Свали файл + Свали файл server test step - + Duplicate display name! - Дублирано показвано име! + Дублирано показвано име! No comment provided by engineer. - + Duration - Продължителност + Продължителност No comment provided by engineer. - + Edit - Редактирай + Редактирай chat item action - + Edit group profile - Редактирай групов профил + Редактирай групов профил No comment provided by engineer. - + Enable - Активирай + Активирай No comment provided by engineer. - + + Enable (keep overrides) + Активиране (запазване на промените) + No comment provided by engineer. + + Enable SimpleX Lock - Активирай SimpleX заключване + Активирай SimpleX заключване authentication reason - + Enable TCP keep-alive - Активирай TCP keep-alive + Активирай TCP keep-alive No comment provided by engineer. - + Enable automatic message deletion? - Активиране на автоматично изтриване на съобщения? + Активиране на автоматично изтриване на съобщения? + No comment provided by engineer. + + + Enable for all + Активиране за всички No comment provided by engineer. Enable instant notifications? + Активирай незабавни известия? No comment provided by engineer. - - Enable later via Settings - No comment provided by engineer. - - + Enable lock - Активирай заключване + Активирай заключване No comment provided by engineer. Enable notifications + Активирай известията No comment provided by engineer. - + Enable periodic notifications? - Активирай периодични известия? + Активирай периодични известия? No comment provided by engineer. - + Enable self-destruct - Активирай самоунищожение + Активирай самоунищожение No comment provided by engineer. - + Enable self-destruct passcode - Активирай kод за достъп за самоунищожение + Активирай kод за достъп за самоунищожение set passcode view - + Encrypt - Криптирай + Криптирай No comment provided by engineer. - + Encrypt database? - Криптиране на база данни? + Криптиране на база данни? No comment provided by engineer. - + + Encrypt local files + Криптирай локални файлове + No comment provided by engineer. + + + Encrypt stored files & media + Криптиране на съхранените файлове и медия + No comment provided by engineer. + + Encrypted database - Криптирана база данни + Криптирана база данни No comment provided by engineer. - + Encrypted message or another event - Криптирано съобщение или друго събитие + Криптирано съобщение или друго събитие notification - + Encrypted message: database error - Криптирано съобщение: грешка в базата данни + Криптирано съобщение: грешка в базата данни notification - + Encrypted message: database migration error - Криптирано съобщение: грешка при мигрирането на база данни + Криптирано съобщение: грешка при мигрирането на база данни notification - + Encrypted message: keychain error - Криптирано съобщение: грешка в keychain + Криптирано съобщение: грешка в keychain notification - + Encrypted message: no passphrase - Криптирано съобщение: няма парола + Криптирано съобщение: няма парола notification - + Encrypted message: unexpected error - Криптирано съобщение: неочаквана грешка + Криптирано съобщение: неочаквана грешка notification - + Enter Passcode - Въведете kодa за достъп + Въведете kодa за достъп No comment provided by engineer. - + Enter correct passphrase. - Въведи правилна парола. + Въведи правилна парола. No comment provided by engineer. - + Enter passphrase… - Въведи парола… + Въведи парола… No comment provided by engineer. - + Enter password above to show! - Въведете парола по-горе, за да се покаже! + Въведете парола по-горе, за да се покаже! No comment provided by engineer. - + Enter server manually - Въведи сървъра ръчно + Въведи сървъра ръчно No comment provided by engineer. - + Enter welcome message… - Въведи съобщение при посрещане… + Въведи съобщение при посрещане… placeholder - + Enter welcome message… (optional) - Въведи съобщение при посрещане…(незадължително) + Въведи съобщение при посрещане…(незадължително) placeholder - + Error - Грешка при свързване със сървъра + Грешка при свързване със сървъра No comment provided by engineer. - + Error aborting address change - Грешка при отказване на промяна на адреса + Грешка при отказване на промяна на адреса No comment provided by engineer. - + Error accepting contact request - Грешка при приемане на заявка за контакт + Грешка при приемане на заявка за контакт No comment provided by engineer. - + Error accessing database file - Грешка при достъпа до файла с базата данни + Грешка при достъпа до файла с базата данни No comment provided by engineer. - + Error adding member(s) - Грешка при добавяне на член(ове) + Грешка при добавяне на член(ове) No comment provided by engineer. - + Error changing address - Грешка при промяна на адреса + Грешка при промяна на адреса No comment provided by engineer. - + Error changing role - Грешка при промяна на ролята + Грешка при промяна на ролята No comment provided by engineer. - + Error changing setting - Грешка при промяна на настройката + Грешка при промяна на настройката No comment provided by engineer. - + Error creating address - Грешка при създаване на адрес + Грешка при създаване на адрес No comment provided by engineer. - + Error creating group - Грешка при създаване на група + Грешка при създаване на група No comment provided by engineer. - + Error creating group link - Грешка при създаване на групов линк + Грешка при създаване на групов линк No comment provided by engineer. - + + Error creating member contact + No comment provided by engineer. + + Error creating profile! - Грешка при създаване на профил! + Грешка при създаване на профил! No comment provided by engineer. - + + Error decrypting file + Грешка при декриптирането на файла + No comment provided by engineer. + + Error deleting chat database - Грешка при изтриване на чат базата данни + Грешка при изтриване на чат базата данни No comment provided by engineer. - + Error deleting chat! - Грешка при изтриването на чата! + Грешка при изтриването на чата! No comment provided by engineer. - + Error deleting connection - Грешка при изтриване на връзката + Грешка при изтриване на връзката No comment provided by engineer. - + Error deleting contact - Грешка при изтриване на контакт + Грешка при изтриване на контакт No comment provided by engineer. - + Error deleting database - Грешка при изтриване на базата данни + Грешка при изтриване на базата данни No comment provided by engineer. - + Error deleting old database - Грешка при изтриване на старата база данни + Грешка при изтриване на старата база данни No comment provided by engineer. - + Error deleting token - Грешка при изтриването на токена + Грешка при изтриването на токена No comment provided by engineer. - + Error deleting user profile - Грешка при изтриване на потребителския профил + Грешка при изтриване на потребителския профил No comment provided by engineer. - + + Error enabling delivery receipts! + Грешка при активирането на потвърждениeто за доставка! + No comment provided by engineer. + + Error enabling notifications - Грешка при активирането на известията + Грешка при активирането на известията No comment provided by engineer. - + Error encrypting database - Грешка при криптиране на базата данни + Грешка при криптиране на базата данни No comment provided by engineer. - + Error exporting chat database - Грешка при експортиране на чат базата данни + Грешка при експортиране на чат базата данни No comment provided by engineer. - + Error importing chat database - Грешка при импортиране на чат базата данни + Грешка при импортиране на чат базата данни No comment provided by engineer. - + Error joining group - Грешка при присъединяване към група + Грешка при присъединяване към група No comment provided by engineer. - + Error loading %@ servers - Грешка при зареждане на %@ сървъри + Грешка при зареждане на %@ сървъри No comment provided by engineer. - + Error receiving file - Грешка при получаване на файл + Грешка при получаване на файл No comment provided by engineer. - + Error removing member - Грешка при отстраняване на член + Грешка при отстраняване на член No comment provided by engineer. - + Error saving %@ servers - Грешка при запазване на %@ сървъра + Грешка при запазване на %@ сървъра No comment provided by engineer. - + Error saving ICE servers - Грешка при запазване на ICE сървърите + Грешка при запазване на ICE сървърите No comment provided by engineer. - + Error saving group profile - Грешка при запазване на профила на групата + Грешка при запазване на профила на групата No comment provided by engineer. - + Error saving passcode - Грешка при запазване на кода за достъп + Грешка при запазване на кода за достъп No comment provided by engineer. Error saving passphrase to keychain + Грешка при запазване на парола в Кeychain No comment provided by engineer. - + Error saving user password - Грешка при запазване на потребителска парола + Грешка при запазване на потребителска парола No comment provided by engineer. - + Error sending email - Грешка при изпращане на имейл + Грешка при изпращане на имейл No comment provided by engineer. - + + Error sending member contact invitation + No comment provided by engineer. + + Error sending message - Грешка при изпращане на съобщение + Грешка при изпращане на съобщение No comment provided by engineer. - + + Error setting delivery receipts! + Грешка при настройването на потвърждениeто за доставка!! + No comment provided by engineer. + + Error starting chat - Грешка при стартиране на чата + Грешка при стартиране на чата No comment provided by engineer. - + Error stopping chat - Грешка при спиране на чата + Грешка при спиране на чата No comment provided by engineer. - + Error switching profile! - Грешка при смяна на профил! + Грешка при смяна на профил! No comment provided by engineer. - + Error synchronizing connection - Грешка при синхронизиране на връзката + Грешка при синхронизиране на връзката No comment provided by engineer. - + Error updating group link - Грешка при актуализиране на груповия линк + Грешка при актуализиране на груповия линк No comment provided by engineer. - + Error updating message - Грешка при актуализиране на съобщението + Грешка при актуализиране на съобщението No comment provided by engineer. - + Error updating settings - Грешка при актуализиране на настройките + Грешка при актуализиране на настройките No comment provided by engineer. - + Error updating user privacy - Грешка при актуализиране на поверителността на потребителя + Грешка при актуализиране на поверителността на потребителя No comment provided by engineer. - + Error: - Грешка: + Грешка: No comment provided by engineer. - + Error: %@ - Грешка: %@ + Грешка: %@ No comment provided by engineer. - + Error: URL is invalid - Грешка: URL адресът е невалиден + Грешка: URL адресът е невалиден No comment provided by engineer. - + Error: no database file - Грешка: няма файл с база данни + Грешка: няма файл с база данни No comment provided by engineer. - + + Even when disabled in the conversation. + Дори когато е деактивиран в разговора. + No comment provided by engineer. + + Exit without saving - Изход без запазване + Изход без запазване No comment provided by engineer. - + Export database - Експортирай база данни + Експортирай база данни No comment provided by engineer. - + Export error: - Грешка при експортиране: + Грешка при експортиране: No comment provided by engineer. - + Exported database archive. - Експортиран архив на базата данни. + Експортиран архив на базата данни. No comment provided by engineer. - - Exporting database archive... - No comment provided by engineer. - - + Exporting database archive… - Експортиране на архив на базата данни… + Експортиране на архив на базата данни… No comment provided by engineer. - + Failed to remove passphrase - Премахването на паролата е неуспешно + Премахването на паролата е неуспешно No comment provided by engineer. - + Fast and no wait until the sender is online! - Бързо и без чакане, докато подателят е онлайн! + Бързо и без чакане, докато подателят е онлайн! No comment provided by engineer. - + Favorite - Любим + Любим No comment provided by engineer. - + File will be deleted from servers. - Файлът ще бъде изтрит от сървърите. + Файлът ще бъде изтрит от сървърите. No comment provided by engineer. - + File will be received when your contact completes uploading it. - Файлът ще бъде получен, когато вашият контакт завърши качването му. + Файлът ще бъде получен, когато вашият контакт завърши качването му. No comment provided by engineer. - + File will be received when your contact is online, please wait or check later! - Файлът ще бъде получен, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно! + Файлът ще бъде получен, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно! No comment provided by engineer. - + File: %@ - Файл: %@ + Файл: %@ No comment provided by engineer. - + Files & media - Файлове и медия + Файлове и медия No comment provided by engineer. - + Files and media - Файлове и медия + Файлове и медия chat feature - + Files and media are prohibited in this group. - Файловете и медията са забранени в тази група. + Файловете и медията са забранени в тази група. No comment provided by engineer. - + Files and media prohibited! - Файловете и медията са забранени! + Файловете и медията са забранени! No comment provided by engineer. - + + Filter unread and favorite chats. + Филтрирайте непрочетените и любимите чатове. + No comment provided by engineer. + + Finally, we have them! 🚀 - Най-накрая ги имаме! 🚀 + Най-накрая ги имаме! 🚀 No comment provided by engineer. - + + Find chats faster + Намирайте чатове по-бързо + No comment provided by engineer. + + Fix - Поправи + Поправи No comment provided by engineer. - + Fix connection - Поправи връзката + Поправи връзката No comment provided by engineer. - + Fix connection? - Поправи връзката? + Поправи връзката? No comment provided by engineer. - + + Fix encryption after restoring backups. + Оправяне на криптирането след възстановяване от резервни копия. + No comment provided by engineer. + + Fix not supported by contact - Поправката не се поддържа от контакта + Поправката не се поддържа от контакта No comment provided by engineer. - + Fix not supported by group member - Поправката не се поддържа от члена на групата + Поправката не се поддържа от члена на групата No comment provided by engineer. - + For console - За конзолата + За конзолата No comment provided by engineer. - + French interface - Френски интерфейс + Френски интерфейс No comment provided by engineer. - + Full link - Цял линк + Цял линк No comment provided by engineer. - + Full name (optional) - Пълно име (незадължително) + Пълно име (незадължително) No comment provided by engineer. - + Full name: - Пълно име: + Пълно име: No comment provided by engineer. - + Fully re-implemented - work in background! - Напълно преработено - работi във фонов режим! + Напълно преработено - работи във фонов режим! No comment provided by engineer. - + Further reduced battery usage - Допълнително намален разход на батерията + Допълнително намален разход на батерията No comment provided by engineer. - + GIFs and stickers - GIF файлове и стикери + GIF файлове и стикери No comment provided by engineer. - + Group - Група + Група No comment provided by engineer. - + Group display name - Показвано име на групата + Показвано име на групата No comment provided by engineer. - + Group full name (optional) - Пълно име на групата (незадължително) + Пълно име на групата (незадължително) No comment provided by engineer. - + Group image - Групово изображение + Групово изображение No comment provided by engineer. - + Group invitation - Групова покана + Групова покана No comment provided by engineer. - + Group invitation expired - Груповата покана е изтекла + Груповата покана е изтекла No comment provided by engineer. - + Group invitation is no longer valid, it was removed by sender. - Груповата покана вече е невалидна, премахната е от подателя. + Груповата покана вече е невалидна, премахната е от подателя. No comment provided by engineer. - + Group link - Групов линк + Групов линк No comment provided by engineer. - + Group links - Групови линкове + Групови линкове No comment provided by engineer. - + Group members can add message reactions. - Членовете на групата могат да добавят реакции към съобщенията. + Членовете на групата могат да добавят реакции към съобщенията. No comment provided by engineer. - + Group members can irreversibly delete sent messages. - Членовете на групата могат необратимо да изтриват изпратените съобщения. + Членовете на групата могат необратимо да изтриват изпратените съобщения. No comment provided by engineer. - + Group members can send direct messages. - Членовете на групата могат да изпращат лични съобщения. + Членовете на групата могат да изпращат лични съобщения. No comment provided by engineer. - + Group members can send disappearing messages. - Членовете на групата могат да изпращат изчезващи съобщения. + Членовете на групата могат да изпращат изчезващи съобщения. No comment provided by engineer. - + Group members can send files and media. - Членовете на групата могат да изпращат файлове и медия. + Членовете на групата могат да изпращат файлове и медия. No comment provided by engineer. - + Group members can send voice messages. - Членовете на групата могат да изпращат гласови съобщения. + Членовете на групата могат да изпращат гласови съобщения. No comment provided by engineer. - + Group message: - Групово съобщение: + Групово съобщение: notification - + Group moderation - Групово модериране + Групово модериране No comment provided by engineer. - + Group preferences - Групови настройки + Групови настройки No comment provided by engineer. - + Group profile - Групов профил + Групов профил No comment provided by engineer. - + Group profile is stored on members' devices, not on the servers. - Груповият профил се съхранява на устройствата на членовете, а не на сървърите. + Груповият профил се съхранява на устройствата на членовете, а не на сървърите. No comment provided by engineer. - + Group welcome message - Съобщение при посрещане в групата + Съобщение при посрещане в групата No comment provided by engineer. - + Group will be deleted for all members - this cannot be undone! - Групата ще бъде изтрита за всички членове - това не може да бъде отменено! + Групата ще бъде изтрита за всички членове - това не може да бъде отменено! No comment provided by engineer. - + Group will be deleted for you - this cannot be undone! - Групата ще бъде изтрита за вас - това не може да бъде отменено! + Групата ще бъде изтрита за вас - това не може да бъде отменено! No comment provided by engineer. - + Help - Помощ + Помощ No comment provided by engineer. - + Hidden - Скрит + Скрит No comment provided by engineer. - + Hidden chat profiles - Скрити чат профили + Скрити чат профили No comment provided by engineer. - + Hidden profile password - Парола за скрит профил + Парола за скрит профил No comment provided by engineer. - + Hide - Скрий + Скрий chat item action - + Hide app screen in the recent apps. - Скриване на екрана на приложението в изгледа на скоро отворнените приложения. + Скриване на екрана на приложението в изгледа на скоро отворнените приложения. No comment provided by engineer. - + Hide profile - Скрий профила + Скрий профила No comment provided by engineer. - + Hide: - Скрий: + Скрий: No comment provided by engineer. - + History - История - copied message info + История + No comment provided by engineer. - + How SimpleX works - Как работи SimpleX + Как работи SimpleX No comment provided by engineer. - + How it works - Как работи + Как работи No comment provided by engineer. - + How to - Информация + Информация No comment provided by engineer. - + How to use it - Как се използва + Как се използва No comment provided by engineer. - + How to use your servers - Как да използвате вашите сървъри + Как да използвате вашите сървъри No comment provided by engineer. - + ICE servers (one per line) - ICE сървъри (по един на ред) + ICE сървъри (по един на ред) No comment provided by engineer. - + If you can't meet in person, show QR code in a video call, or share the link. - Ако не можете да се срещнете лично, покажете QR код във видеоразговора или споделете линка. + Ако не можете да се срещнете лично, покажете QR код във видеоразговора или споделете линка. No comment provided by engineer. If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. + Ако не можете да се срещнете на живо, можете да **сканирате QR код във видеообаждането** или вашият контакт може да сподели линк за покана. No comment provided by engineer. - + If you enter this passcode when opening the app, all app data will be irreversibly removed! - Ако въведете този kод за достъп, когато отваряте приложението, всички данни от приложението ще бъдат необратимо изтрити! + Ако въведете този kод за достъп, когато отваряте приложението, всички данни от приложението ще бъдат необратимо изтрити! No comment provided by engineer. - + If you enter your self-destruct passcode while opening the app: - Ако въведете kодa за достъп за самоунищожение, докато отваряте приложението: + Ако въведете kодa за достъп за самоунищожение, докато отваряте приложението: No comment provided by engineer. If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app). + Ако трябва да използвате чата сега, докоснете **Отложи** отдолу (ще ви бъде предложено да мигрирате базата данни, когато рестартирате приложението). No comment provided by engineer. - + Ignore - Игнорирай + Игнорирай No comment provided by engineer. - + Image will be received when your contact completes uploading it. - Изображението ще бъде получено, когато вашият контакт завърши качването му. + Изображението ще бъде получено, когато вашият контакт завърши качването му. No comment provided by engineer. - + Image will be received when your contact is online, please wait or check later! - Изображението ще бъде получено, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно! + Изображението ще бъде получено, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно! No comment provided by engineer. - + Immediately - Веднага + Веднага No comment provided by engineer. - + Immune to spam and abuse - Защитен от спам и злоупотреби + Защитен от спам и злоупотреби No comment provided by engineer. - + Import - Импортиране + Импортиране No comment provided by engineer. - + Import chat database? - Импортиране на чат база данни? + Импортиране на чат база данни? No comment provided by engineer. - + Import database - Импортиране на база данни + Импортиране на база данни No comment provided by engineer. - + Improved privacy and security - Подобрена поверителност и сигурност + Подобрена поверителност и сигурност No comment provided by engineer. - + Improved server configuration - Подобрена конфигурация на сървъра + Подобрена конфигурация на сървъра No comment provided by engineer. - + In reply to - В отговор на - copied message info + В отговор на + No comment provided by engineer. - + Incognito - Инкогнито + Инкогнито No comment provided by engineer. - + Incognito mode - Режим инкогнито + Режим инкогнито No comment provided by engineer. - - Incognito mode is not supported here - your main profile will be sent to group members + + Incognito mode protects your privacy by using a new random profile for each contact. + Режимът инкогнито защитава вашата поверителност, като използва нов автоматично генериран профил за всеки контакт. No comment provided by engineer. - - Incognito mode protects the privacy of your main profile name and image — for each new contact a new random profile is created. - No comment provided by engineer. - - + Incoming audio call - Входящо аудио повикване + Входящо аудио повикване notification - + Incoming call - Входящо повикване + Входящо повикване notification - + Incoming video call - Входящо видео повикване + Входящо видео повикване notification - + Incompatible database version - Несъвместима версия на базата данни + Несъвместима версия на базата данни No comment provided by engineer. - + Incorrect passcode - Неправилен kод за достъп + Неправилен kод за достъп PIN entry - + Incorrect security code! - Неправилен код за сигурност! + Неправилен код за сигурност! No comment provided by engineer. - + Info - Информация + Информация chat item action - + Initial role - Първоначална роля + Първоначална роля No comment provided by engineer. - + Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat) - Инсталирайте [SimpleX Chat за терминал](https://github.com/simplex-chat/simplex-chat) + Инсталирайте [SimpleX Chat за терминал](https://github.com/simplex-chat/simplex-chat) No comment provided by engineer. Instant push notifications will be hidden! + Незабавните push известия ще бъдат скрити! + No comment provided by engineer. - + Instantly - Мигновено + Мигновено No comment provided by engineer. - + Interface - Интерфейс + Интерфейс No comment provided by engineer. - + Invalid connection link - Невалиден линк за връзка + Невалиден линк за връзка No comment provided by engineer. - + Invalid server address! - Невалиден адрес на сървъра! + Невалиден адрес на сървъра! No comment provided by engineer. - + + Invalid status + Невалиден статус + item status text + + Invitation expired! - Поканата е изтекла! + Поканата е изтекла! No comment provided by engineer. - + Invite friends - Покани приятели + Покани приятели No comment provided by engineer. - + Invite members - Покани членове + Покани членове No comment provided by engineer. - + Invite to group - Покани в групата + Покани в групата No comment provided by engineer. - + Irreversible message deletion - Необратимо изтриване на съобщение + Необратимо изтриване на съобщение No comment provided by engineer. - + Irreversible message deletion is prohibited in this chat. - Необратимото изтриване на съобщения е забранено в този чат. + Необратимото изтриване на съобщения е забранено в този чат. No comment provided by engineer. - + Irreversible message deletion is prohibited in this group. - Необратимото изтриване на съобщения е забранено в тази група. + Необратимото изтриване на съобщения е забранено в тази група. No comment provided by engineer. - + It allows having many anonymous connections without any shared data between them in a single chat profile. - Позволява да имате много анонимни връзки без споделени данни между тях в един чат профил . + Позволява да имате много анонимни връзки без споделени данни между тях в един чат профил . No comment provided by engineer. - + It can happen when you or your connection used the old database backup. - Това може да се случи, когато вие или вашата връзка използвате старо резервно копие на базата данни. + Това може да се случи, когато вие или вашата връзка използвате старо резервно копие на базата данни. No comment provided by engineer. - + It can happen when: 1. The messages expired in the sending client after 2 days or on the server after 30 days. 2. Message decryption failed, because you or your contact used old database backup. 3. The connection was compromised. - Това може да се случи, когато: + Това може да се случи, когато: 1. Времето за пазене на съобщенията е изтекло - в изпращащия клиент е 2 дена а на сървъра е 30. 2. Декриптирането на съобщението е неуспешно, защото вие или вашият контакт сте използвали старо копие на базата данни. 3. Връзката е била компрометирана. @@ -2594,3019 +2786,3534 @@ It seems like you are already connected via this link. If it is not the case, there was an error (%@). + Изглежда, че вече сте свързани чрез този линк. Ако не е така, има грешка (%@). No comment provided by engineer. - + Italian interface - Италиански интерфейс + Италиански интерфейс No comment provided by engineer. - + Japanese interface - Японски интерфейс + Японски интерфейс No comment provided by engineer. - + Join - Присъединяване + Присъединяване No comment provided by engineer. - + Join group - Влез в групата + Влез в групата No comment provided by engineer. - + Join incognito - Влез инкогнито + Влез инкогнито No comment provided by engineer. - + Joining group - Присъединяване към групата + Присъединяване към групата No comment provided by engineer. - + + Keep your connections + Запазете връзките си + No comment provided by engineer. + + KeyChain error - KeyChain грешка + KeyChain грешка No comment provided by engineer. - + Keychain error - Keychain грешка + Keychain грешка No comment provided by engineer. - + LIVE - НА ЖИВО + НА ЖИВО No comment provided by engineer. - + Large file! - Голям файл! + Голям файл! No comment provided by engineer. - + Learn more - Научете повече + Научете повече No comment provided by engineer. - + Leave - Напусни + Напусни No comment provided by engineer. - + Leave group - Напусни групата + Напусни групата No comment provided by engineer. - + Leave group? - Напусни групата? + Напусни групата? No comment provided by engineer. - + Let's talk in SimpleX Chat - Нека да поговорим в SimpleX Chat + Нека да поговорим в SimpleX Chat email subject - + Light - Светла + Светла No comment provided by engineer. - + Limitations - Ограничения + Ограничения No comment provided by engineer. - + Live message! - Съобщение на живо! + Съобщение на живо! No comment provided by engineer. - + Live messages - Съобщения на живо + Съобщения на живо No comment provided by engineer. - + Local name - Локално име + Локално име No comment provided by engineer. - + Local profile data only - Само данни за локален профил + Само данни за локален профил No comment provided by engineer. - + Lock after - Заключване след + Заключване след No comment provided by engineer. - + Lock mode - Режим на заключване + Режим на заключване No comment provided by engineer. - + Make a private connection - Добави поверителна връзка + Добави поверителна връзка No comment provided by engineer. - + + Make one message disappear + Накарайте едно съобщение да изчезне + No comment provided by engineer. + + Make profile private! - Направи профила поверителен! + Направи профила поверителен! No comment provided by engineer. - + Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@). - Уверете се, че %@ сървърните адреси са в правилен формат, разделени на редове и не се дублират (%@). + Уверете се, че %@ сървърните адреси са в правилен формат, разделени на редове и не се дублират (%@). No comment provided by engineer. - + Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated. - Уверете се, че адресите на WebRTC ICE сървъра са в правилен формат, разделени на редове и не са дублирани. + Уверете се, че адресите на WebRTC ICE сървъра са в правилен формат, разделени на редове и не са дублирани. No comment provided by engineer. - + Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?* - Много хора попитаха: *ако SimpleX няма потребителски идентификатори, как може да доставя съобщения?* + Много хора попитаха: *ако SimpleX няма потребителски идентификатори, как може да доставя съобщения?* No comment provided by engineer. - + Mark deleted for everyone - Маркирай като изтрито за всички + Маркирай като изтрито за всички No comment provided by engineer. - + Mark read - Маркирай като прочетено + Маркирай като прочетено No comment provided by engineer. - + Mark verified - Маркирай като проверено + Маркирай като проверено No comment provided by engineer. - + Markdown in messages - Форматиране на съобщения + Форматиране на съобщения No comment provided by engineer. - + Max 30 seconds, received instantly. - Макс. 30 секунди, получено незабавно. + Макс. 30 секунди, получено незабавно. No comment provided by engineer. - + Member - Член + Член No comment provided by engineer. - + Member role will be changed to "%@". All group members will be notified. - Ролята на члена ще бъде променена на "%@". Всички членове на групата ще бъдат уведомени. + Ролята на члена ще бъде променена на "%@". Всички членове на групата ще бъдат уведомени. No comment provided by engineer. - + Member role will be changed to "%@". The member will receive a new invitation. - Ролята на члена ще бъде променена на "%@". Членът ще получи нова покана. + Ролята на члена ще бъде променена на "%@". Членът ще получи нова покана. No comment provided by engineer. - + Member will be removed from group - this cannot be undone! - Членът ще бъде премахнат от групата - това не може да бъде отменено! + Членът ще бъде премахнат от групата - това не може да бъде отменено! No comment provided by engineer. - + Message delivery error - Грешка при доставката на съобщението + Грешка при доставката на съобщението + item status text + + + Message delivery receipts! + Потвърждениe за доставка на съобщения! No comment provided by engineer. - + Message draft - Чернова на съобщение + Чернова на съобщение No comment provided by engineer. - + Message reactions - Реакции на съобщения + Реакции на съобщения chat feature - + Message reactions are prohibited in this chat. - Реакциите на съобщения са забранени в този чат. + Реакциите на съобщения са забранени в този чат. No comment provided by engineer. - + Message reactions are prohibited in this group. - Реакциите на съобщения са забранени в тази група. + Реакциите на съобщения са забранени в тази група. No comment provided by engineer. - + Message text - Текст на съобщението + Текст на съобщението No comment provided by engineer. - + Messages - Съобщения + Съобщения No comment provided by engineer. - + Messages & files - Съобщения и файлове + Съобщения и файлове No comment provided by engineer. - - Migrating database archive... - No comment provided by engineer. - - + Migrating database archive… - Архивът на базата данни се мигрира… + Архивът на базата данни се мигрира… No comment provided by engineer. - + Migration error: - Грешка при мигриране: + Грешка при мигриране: No comment provided by engineer. Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat). + Мигрирането е неуспешно. Докоснете **Пропускане** по-долу, за да продължите да използвате текущата база данни. Моля, докладвайте проблема на разработчиците на приложението чрез чат или имейл [chat@simplex.chat](mailto:chat@simplex.chat). No comment provided by engineer. Migration is completed + Миграцията е завършена No comment provided by engineer. Migrations: %@ + Миграции: %@ No comment provided by engineer. Moderate + Модерирай chat item action Moderated at + Модерирано в No comment provided by engineer. Moderated at: %@ + Модерирано в: %@ copied message info - + More improvements are coming soon! - Очаквайте скоро още подобрения! + Очаквайте скоро още подобрения! No comment provided by engineer. - + + Most likely this connection is deleted. + Най-вероятно тази връзка е изтрита. + item status description + + Most likely this contact has deleted the connection with you. - Най-вероятно този контакт е изтрил връзката с вас. + Най-вероятно този контакт е изтрил връзката с вас. No comment provided by engineer. - + Multiple chat profiles - Множество профили за чат + Множество профили за чат No comment provided by engineer. - + Mute - Без звук + Без звук No comment provided by engineer. - + Muted when inactive! - Без звук при неактивност! + Без звук при неактивност! No comment provided by engineer. - + Name - Име + Име No comment provided by engineer. - + Network & servers - Мрежа и сървъри + Мрежа и сървъри No comment provided by engineer. - + Network settings - Мрежови настройки + Мрежови настройки No comment provided by engineer. - + Network status - Състояние на мрежата + Състояние на мрежата No comment provided by engineer. - + New Passcode - Нов kод за достъп + Нов kод за достъп No comment provided by engineer. - + New contact request - Нова заявка за контакт + Нова заявка за контакт notification New contact: + Нов контакт: notification - + New database archive - Нов архив на база данни + Нов архив на база данни No comment provided by engineer. - + + New desktop app! + Ново настолно приложение! + No comment provided by engineer. + + New display name - Ново показвано име + Ново показвано име No comment provided by engineer. New in %@ + Ново в %@ No comment provided by engineer. - + New member role - Нова членска роля + Нова членска роля No comment provided by engineer. - + New message - Ново съобщение + Ново съобщение notification - + New passphrase… - Нова парола… + Нова парола… No comment provided by engineer. - + No - Не + Не No comment provided by engineer. No app password + Приложението няма kод за достъп Authentication unavailable - + No contacts selected - Няма избрани контакти + Няма избрани контакти No comment provided by engineer. - + No contacts to add - Няма контакти за добавяне + Няма контакти за добавяне + No comment provided by engineer. + + + No delivery information + Няма информация за доставката No comment provided by engineer. No device token! + Няма токен за устройство! No comment provided by engineer. - + No filtered chats - Няма филтрирани чатове + Няма филтрирани чатове No comment provided by engineer. - + Group not found! - Групата не е намерена! + Групата не е намерена! No comment provided by engineer. - + No history - Няма история + Няма история No comment provided by engineer. No permission to record voice message + Няма разрешение за запис на гласово съобщение No comment provided by engineer. - + No received or sent files - Няма получени или изпратени файлове + Няма получени или изпратени файлове No comment provided by engineer. - + Notifications - Известия + Известия No comment provided by engineer. Notifications are disabled! + Известията са деактивирани! No comment provided by engineer. - + Now admins can: - delete members' messages. - disable members ("observer" role) - Сега администраторите могат: + Сега администраторите могат: - да изтриват съобщения на членове. - да деактивират членове (роля "наблюдател") No comment provided by engineer. - + Off - Изключено + Изключено No comment provided by engineer. - + Off (Local) - Изключено (Локално) + Изключено (Локално) No comment provided by engineer. - + Ok - Ок + Ок No comment provided by engineer. - + Old database - Стара база данни + Стара база данни No comment provided by engineer. - + Old database archive - Стар архив на база данни + Стар архив на база данни No comment provided by engineer. - + One-time invitation link - Линк за еднократна покана + Линк за еднократна покана No comment provided by engineer. - + Onion hosts will be required for connection. Requires enabling VPN. - За свързване ще са необходими Onion хостове. Изисква се активиране на VPN. + За свързване ще са необходими Onion хостове. Изисква се активиране на VPN. No comment provided by engineer. - + Onion hosts will be used when available. Requires enabling VPN. - Ще се използват Onion хостове, когато са налични. Изисква се активиране на VPN. + Ще се използват Onion хостове, когато са налични. Изисква се активиране на VPN. No comment provided by engineer. - + Onion hosts will not be used. - Няма се използват Onion хостове. + Няма се използват Onion хостове. No comment provided by engineer. Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**. + Само потребителските устройства съхраняват потребителски профили, контакти, групи и съобщения, изпратени с **двуслойно криптиране от край до край**. No comment provided by engineer. - + Only group owners can change group preferences. - Само собствениците на групата могат да променят груповите настройки. + Само собствениците на групата могат да променят груповите настройки. No comment provided by engineer. - + Only group owners can enable files and media. - Само собствениците на групата могат да активират файлове и медията. + Само собствениците на групата могат да активират файлове и медията. No comment provided by engineer. - + Only group owners can enable voice messages. - Само собствениците на групата могат да активират гласови съобщения. + Само собствениците на групата могат да активират гласови съобщения. No comment provided by engineer. - + Only you can add message reactions. - Само вие можете да добавяте реакции на съобщенията. + Само вие можете да добавяте реакции на съобщенията. No comment provided by engineer. - + Only you can irreversibly delete messages (your contact can mark them for deletion). - Само вие можете необратимо да изтриете съобщения (вашият контакт може да ги маркира за изтриване). + Само вие можете необратимо да изтриете съобщения (вашият контакт може да ги маркира за изтриване). No comment provided by engineer. - + Only you can make calls. - Само вие можете да извършвате разговори. + Само вие можете да извършвате разговори. No comment provided by engineer. - + Only you can send disappearing messages. - Само вие можете да изпращате изчезващи съобщения. + Само вие можете да изпращате изчезващи съобщения. No comment provided by engineer. - + Only you can send voice messages. - Само вие можете да изпращате гласови съобщения. + Само вие можете да изпращате гласови съобщения. No comment provided by engineer. - + Only your contact can add message reactions. - Само вашият контакт може да добавя реакции на съобщенията. + Само вашият контакт може да добавя реакции на съобщенията. No comment provided by engineer. - + Only your contact can irreversibly delete messages (you can mark them for deletion). - Само вашият контакт може необратимо да изтрие съобщения (можете да ги маркирате за изтриване). + Само вашият контакт може необратимо да изтрие съобщения (можете да ги маркирате за изтриване). No comment provided by engineer. - + Only your contact can make calls. - Само вашият контакт може да извършва разговори. + Само вашият контакт може да извършва разговори. No comment provided by engineer. - + Only your contact can send disappearing messages. - Само вашият контакт може да изпраща изчезващи съобщения. + Само вашият контакт може да изпраща изчезващи съобщения. No comment provided by engineer. - + Only your contact can send voice messages. - Само вашият контакт може да изпраща гласови съобщения. + Само вашият контакт може да изпраща гласови съобщения. No comment provided by engineer. - + + Open + No comment provided by engineer. + + Open Settings - Отвори настройки + Отвори настройки No comment provided by engineer. - + Open chat - Отвори чат + Отвори чат No comment provided by engineer. - + Open chat console - Отвори конзолата + Отвори конзолата authentication reason Open user profiles + Отвори потребителските профили authentication reason Open-source protocol and code – anybody can run the servers. + Протокол и код с отворен код – всеки може да оперира собствени сървъри. No comment provided by engineer. Opening database… + Отваряне на база данни… No comment provided by engineer. Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. + Отварянето на линка в браузъра може да намали поверителността и сигурността на връзката. Несигурните SimpleX линкове ще бъдат червени. No comment provided by engineer. PING count + PING бройка No comment provided by engineer. PING interval + PING интервал No comment provided by engineer. Passcode + Код за достъп No comment provided by engineer. Passcode changed! + Кодът за достъп е променен! No comment provided by engineer. Passcode entry + Въвеждане на код за достъп No comment provided by engineer. Passcode not changed! + Кодът за достъп не е променен! No comment provided by engineer. Passcode set! + Кодът за достъп е зададен! No comment provided by engineer. Password to show + Парола за показване No comment provided by engineer. Paste + Постави No comment provided by engineer. Paste image + Постави изображение No comment provided by engineer. Paste received link + Постави получения линк No comment provided by engineer. - - Paste the link you received into the box below to connect with your contact. - No comment provided by engineer. + + Paste the link you received to connect with your contact. + Поставете линка, който сте получили, за да се свържете с вашия контакт. + placeholder People can connect to you only via the links you share. + Хората могат да се свържат с вас само чрез ликовете, които споделяте. No comment provided by engineer. Periodically + Периодично No comment provided by engineer. Permanent decryption error + Постоянна грешка при декриптиране message decrypt error item Please ask your contact to enable sending voice messages. + Моля, попитайте вашия контакт, за да активирате изпращане на гласови съобщения. No comment provided by engineer. Please check that you used the correct link or ask your contact to send you another one. + Моля, проверете дали сте използвали правилния линк или поискайте вашия контакт, за да ви изпрати друг. No comment provided by engineer. Please check your network connection with %@ and try again. + Моля, проверете мрежовата си връзка с %@ и опитайте отново. No comment provided by engineer. Please check yours and your contact preferences. + Моля, проверете вашите настройки и тези вашия за контакт. No comment provided by engineer. Please contact group admin. + Моля, свържете се с груповия администартор. No comment provided by engineer. Please enter correct current passphrase. + Моля, въведете правилната текуща парола. No comment provided by engineer. Please enter the previous password after restoring database backup. This action can not be undone. + Моля, въведете предишната парола след възстановяване на резервното копие на базата данни. Това действие не може да бъде отменено. No comment provided by engineer. Please remember or store it securely - there is no way to recover a lost passcode! + Моля, запомнете го или го съхранявайте на сигурно място - няма начин да възстановите изгубен код за достъп! No comment provided by engineer. Please report it to the developers. + Моля, докладвайте го на разработчиците. No comment provided by engineer. Please restart the app and migrate the database to enable push notifications. + Моля, рестартирайте приложението и мигрирайте базата данни, за да активирате push известия. No comment provided by engineer. Please store passphrase securely, you will NOT be able to access chat if you lose it. + Моля, съхранявайте паролата на сигурно място, НЯМА да имате достъп до чата, ако я загубите. No comment provided by engineer. Please store passphrase securely, you will NOT be able to change it if you lose it. + Моля, съхранявайте паролата на сигурно място, НЯМА да можете да я промените, ако я загубите. No comment provided by engineer. Polish interface + Полски интерфейс No comment provided by engineer. Possibly, certificate fingerprint in server address is incorrect + Въжможно е пръстовият отпечатък на сертификата в адреса на сървъра да е неправилен server test error Preserve the last message draft, with attachments. + Запазете последната чернова на съобщението с прикачени файлове. No comment provided by engineer. Preset server + Предварително зададен сървър No comment provided by engineer. Preset server address + Предварително зададен адрес на сървъра No comment provided by engineer. Preview + Визуализация No comment provided by engineer. Privacy & security + Поверителност и сигурност No comment provided by engineer. Privacy redefined + Поверителността преосмислена No comment provided by engineer. Private filenames + Поверителни имена на файлове No comment provided by engineer. Profile and server connections + Профилни и сървърни връзки No comment provided by engineer. Profile image + Профилно изображение No comment provided by engineer. Profile password + Профилна парола No comment provided by engineer. Profile update will be sent to your contacts. + Актуализацията на профила ще бъде изпратена до вашите контакти. No comment provided by engineer. Prohibit audio/video calls. + Забрани аудио/видео разговорите. No comment provided by engineer. Prohibit irreversible message deletion. + Забрани необратимото изтриване на съобщения. No comment provided by engineer. Prohibit message reactions. + Забрани реакциите на съобщенията. No comment provided by engineer. Prohibit messages reactions. + Забрани реакциите на съобщенията. No comment provided by engineer. Prohibit sending direct messages to members. + Забрани изпращането на лични съобщения до членовете. No comment provided by engineer. Prohibit sending disappearing messages. + Забрани изпращането на изчезващи съобщения. No comment provided by engineer. Prohibit sending files and media. + Забрани изпращането на файлове и медия. No comment provided by engineer. Prohibit sending voice messages. + Забрани изпращането на гласови съобщения. No comment provided by engineer. Protect app screen + Защити екрана на приложението No comment provided by engineer. Protect your chat profiles with a password! + Защитете чат профилите с парола! No comment provided by engineer. Protocol timeout + Време за изчакване на протокола No comment provided by engineer. Protocol timeout per KB + Време за изчакване на протокола за KB No comment provided by engineer. Push notifications + Push известия No comment provided by engineer. Rate the app + Оценете приложението No comment provided by engineer. React… + Реагирай… chat item menu Read + Прочетено No comment provided by engineer. Read more + Прочетете още No comment provided by engineer. Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). + Прочетете повече в [Ръководство за потребителя](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). + Прочетете повече в [Ръководство на потребителя](https://simplex.chat/docs/guide/readme.html#connect-to-friends). No comment provided by engineer. Read more in our GitHub repository. + Прочетете повече в нашето хранилище в GitHub. No comment provided by engineer. Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme). + Прочетете повече в нашето [GitHub хранилище](https://github.com/simplex-chat/simplex-chat#readme). + No comment provided by engineer. + + + Receipts are disabled + Потвърждениeто за доставка е деактивирано No comment provided by engineer. Received at + Получено в No comment provided by engineer. Received at: %@ + Получено в: %@ copied message info Received file event + Събитие за получен файл notification Received message + Получено съобщение message info title Receiving address will be changed to a different server. Address change will complete after sender comes online. + Получаващият адрес ще бъде променен към друг сървър. Промяната на адреса ще завърши, след като подателят е онлайн. No comment provided by engineer. Receiving file will be stopped. + Получаващият се файл ще бъде спрян. No comment provided by engineer. Receiving via + Получаване чрез No comment provided by engineer. Recipients see updates as you type them. + Получателите виждат актуализации, докато ги въвеждате. No comment provided by engineer. Reconnect all connected servers to force message delivery. It uses additional traffic. + Повторно се свържете с всички свързани сървъри, за да принудите доставката на съобщенията. Използва се допълнителен трафик. No comment provided by engineer. Reconnect servers? + Повторно свърване със сървърите? No comment provided by engineer. Record updated at + Записът е актуализиран на No comment provided by engineer. Record updated at: %@ + Записът е актуализиран на: %@ copied message info Reduced battery usage + Намалена консумация на батерията No comment provided by engineer. Reject + Отхвърляне reject incoming call via notification - - Reject contact (sender NOT notified) + + Reject (sender NOT notified) + Отхвърляне (подателят НЕ бива уведомен) No comment provided by engineer. Reject contact request + Отхвърли заявката за контакт No comment provided by engineer. Relay server is only used if necessary. Another party can observe your IP address. + Реле сървър се използва само ако е необходимо. Друга страна може да наблюдава вашия IP адрес. No comment provided by engineer. Relay server protects your IP address, but it can observe the duration of the call. + Relay сървърът защитава вашия IP адрес, но може да наблюдава продължителността на разговора. No comment provided by engineer. Remove + Премахване No comment provided by engineer. Remove member + Острани член No comment provided by engineer. Remove member? + Острани член? No comment provided by engineer. Remove passphrase from keychain? + Премахване на паролата от keychain? No comment provided by engineer. Renegotiate + Предоговоряне No comment provided by engineer. Renegotiate encryption + Предоговори криптирането No comment provided by engineer. Renegotiate encryption? + Предоговори криптирането? No comment provided by engineer. Reply + Отговори chat item action Required + Задължително No comment provided by engineer. Reset + Нулиране No comment provided by engineer. Reset colors + Нулирай цветовете No comment provided by engineer. Reset to defaults + Възстановяване на настройките по подразбиране No comment provided by engineer. Restart the app to create a new chat profile + Рестартирайте приложението, за да създадете нов чат профил No comment provided by engineer. Restart the app to use imported chat database + Рестартирайте приложението, за да използвате импортирана чат база данни No comment provided by engineer. Restore + Възстанови No comment provided by engineer. Restore database backup + Възстанови резервно копие на база данни No comment provided by engineer. Restore database backup? + Възстанови резервно копие на база данни? No comment provided by engineer. Restore database error + Грешка при възстановяване на базата данни No comment provided by engineer. Reveal + Покажи chat item action Revert + Отмени промените No comment provided by engineer. Revoke + Отзови No comment provided by engineer. Revoke file + Отзови файл cancel file action Revoke file? + Отзови файл? No comment provided by engineer. Role + Роля No comment provided by engineer. Run chat + Стартиране на чат No comment provided by engineer. SMP servers + SMP сървъри No comment provided by engineer. Save + Запази chat item action Save (and notify contacts) + Запази (и уведоми контактите) No comment provided by engineer. Save and notify contact + Запази и уведоми контакта No comment provided by engineer. Save and notify group members + Запази и уведоми членовете на групата No comment provided by engineer. Save and update group profile + Запази и актуализирай профила на групата No comment provided by engineer. Save archive + Запази архив No comment provided by engineer. Save auto-accept settings + Запази настройките за автоматично приемане No comment provided by engineer. Save group profile + Запази профила на групата No comment provided by engineer. Save passphrase and open chat + Запази паролата и отвори чата No comment provided by engineer. Save passphrase in Keychain + Запази паролата в Keychain No comment provided by engineer. Save preferences? + Запази настройките? No comment provided by engineer. Save profile password + Запази паролата на профила No comment provided by engineer. Save servers + Запази сървърите No comment provided by engineer. Save servers? + Запази сървърите? No comment provided by engineer. Save settings? + Запази настройките? No comment provided by engineer. Save welcome message? + Запази съобщението при посрещане? No comment provided by engineer. Saved WebRTC ICE servers will be removed + Запазените WebRTC ICE сървъри ще бъдат премахнати No comment provided by engineer. Scan QR code + Сканирай QR код No comment provided by engineer. Scan code + Сканирай код No comment provided by engineer. Scan security code from your contact's app. + Сканирайте кода за сигурност от приложението на вашия контакт. No comment provided by engineer. Scan server QR code + Сканирай QR кода на сървъра No comment provided by engineer. Search + Търсене No comment provided by engineer. Secure queue + Сигурна опашка server test step Security assessment + Оценка на сигурността No comment provided by engineer. Security code + Код за сигурност No comment provided by engineer. Select + Избери No comment provided by engineer. Self-destruct + Самоунищожение No comment provided by engineer. Self-destruct passcode + Код за достъп за самоунищожение No comment provided by engineer. Self-destruct passcode changed! + Кодът за достъп за самоунищожение е променен! No comment provided by engineer. Self-destruct passcode enabled! + Кодът за достъп за самоунищожение е активиран! No comment provided by engineer. Send + Изпрати No comment provided by engineer. Send a live message - it will update for the recipient(s) as you type it + Изпратете съобщение на живо - то ще се актуализира за получателя(ите), докато го пишете No comment provided by engineer. Send delivery receipts to + Изпращайте потвърждениe за доставка на No comment provided by engineer. Send direct message + Изпрати лично съобщение + No comment provided by engineer. + + + Send direct message to connect No comment provided by engineer. Send disappearing message + Изпрати изчезващо съобщение No comment provided by engineer. Send link previews + Изпрати визуализация на линковете No comment provided by engineer. Send live message + Изпрати съобщение на живо No comment provided by engineer. Send notifications + Изпращай известия No comment provided by engineer. Send notifications: + Изпратени известия: No comment provided by engineer. Send questions and ideas + Изпращайте въпроси и идеи No comment provided by engineer. Send receipts + Изпращане на потвърждениe за доставка No comment provided by engineer. Send them from gallery or custom keyboards. + Изпрати от галерия или персонализирани клавиатури. No comment provided by engineer. Sender cancelled file transfer. + Подателят отмени прехвърлянето на файла. No comment provided by engineer. Sender may have deleted the connection request. + Подателят може да е изтрил заявката за връзка. + No comment provided by engineer. + + + Sending delivery receipts will be enabled for all contacts in all visible chat profiles. + Изпращането на потвърждениe за доставка ще бъде активирано за всички контакти във всички видими чат профили. + No comment provided by engineer. + + + Sending delivery receipts will be enabled for all contacts. + Изпращането на потвърждениe за доставка ще бъде активирано за всички контакти. No comment provided by engineer. Sending file will be stopped. + Изпращането на файла ще бъде спряно. + No comment provided by engineer. + + + Sending receipts is disabled for %lld contacts + Изпращането на потвърждениe за доставка е деактивирано за %lld контакта + No comment provided by engineer. + + + Sending receipts is disabled for %lld groups + Изпращането на потвърждениe за доставка е деактивирано за %lld групи + No comment provided by engineer. + + + Sending receipts is enabled for %lld contacts + Изпращането на потвърждениe за доставка е активирано за %lld контакта + No comment provided by engineer. + + + Sending receipts is enabled for %lld groups + Изпращането на потвърждениe за доставка е активирано за %lld групи No comment provided by engineer. Sending via + Изпращане чрез No comment provided by engineer. Sent at + Изпратено на No comment provided by engineer. Sent at: %@ + Изпратено на: %@ copied message info Sent file event + Събитие за изпратен файл notification Sent message + Изпратено съобщение message info title Sent messages will be deleted after set time. + Изпратените съобщения ще бъдат изтрити след зададеното време. No comment provided by engineer. Server requires authorization to create queues, check password + Сървърът изисква оторизация за създаване на опашки, проверете паролата server test error Server requires authorization to upload, check password + Сървърът изисква оторизация за качване, проверете паролата server test error Server test failed! + Тестът на сървъра е неуспешен! No comment provided by engineer. Servers + Сървъри No comment provided by engineer. Set 1 day + Задай 1 ден No comment provided by engineer. Set contact name… + Задай име на контакт… No comment provided by engineer. Set group preferences + Задай групови настройки No comment provided by engineer. Set it instead of system authentication. + Задайте го вместо системната идентификация. No comment provided by engineer. Set passcode + Задай kод за достъп No comment provided by engineer. Set passphrase to export + Задай парола за експортиране No comment provided by engineer. Set the message shown to new members! + Задай съобщението, показано на новите членове! No comment provided by engineer. Set timeouts for proxy/VPN + Задай време за изчакване за прокси/VPN No comment provided by engineer. Settings + Настройки No comment provided by engineer. Share + Сподели chat item action Share 1-time link + Сподели еднократен линк No comment provided by engineer. Share address + Сподели адрес No comment provided by engineer. Share address with contacts? + Сподели адреса с контактите? No comment provided by engineer. Share link + Сподели линк No comment provided by engineer. Share one-time invitation link + Сподели линк за еднократна покана No comment provided by engineer. Share with contacts + Сподели с контактите No comment provided by engineer. Show calls in phone history + Показване на обажданията в хронологията на телефона No comment provided by engineer. Show developer options + Покажи опциите за разработчици + No comment provided by engineer. + + + Show last messages + Показване на последните съобщения в листа с чатовете No comment provided by engineer. Show preview + Показване на визуализация No comment provided by engineer. Show: + Покажи: No comment provided by engineer. SimpleX Address + SimpleX Адрес No comment provided by engineer. SimpleX Chat security was audited by Trail of Bits. + Сигурността на SimpleX Chat беше одитирана от Trail of Bits. No comment provided by engineer. SimpleX Lock + SimpleX заключване No comment provided by engineer. SimpleX Lock mode + Режим на SimpleX заключване No comment provided by engineer. SimpleX Lock not enabled! + SimpleX заключване не е активирано! No comment provided by engineer. SimpleX Lock turned on + SimpleX заключване е включено No comment provided by engineer. SimpleX address + SimpleX адрес No comment provided by engineer. SimpleX contact address + SimpleX адрес за контакт simplex link type SimpleX encrypted message or connection event + SimpleX криптирано съобщение или събитие за връзка notification SimpleX group link + SimpleX групов линк simplex link type SimpleX links + SimpleX линкове No comment provided by engineer. SimpleX one-time invitation + Еднократна покана за SimpleX simplex link type + + Simplified incognito mode + Опростен режим инкогнито + No comment provided by engineer. + Skip + Пропускане No comment provided by engineer. Skipped messages + Пропуснати съобщения No comment provided by engineer. - - Small groups (max 10) + + Small groups (max 20) + Малки групи (максимум 20) No comment provided by engineer. Some non-fatal errors occurred during import - you may see Chat console for more details. + Някои не-фатални грешки са възникнали по време на импортиране - може да видите конзолата за повече подробности. No comment provided by engineer. Somebody + Някой notification title Start a new chat + Започни нов чат No comment provided by engineer. Start chat + Започни чат No comment provided by engineer. Start migration + Започни миграция No comment provided by engineer. Stop + Спри No comment provided by engineer. Stop SimpleX + Спри SimpleX authentication reason Stop chat to enable database actions + Спрете чата, за да активирате действията с базата данни No comment provided by engineer. Stop chat to export, import or delete chat database. You will not be able to receive and send messages while the chat is stopped. + Спрете чата, за да експортирате, импортирате или изтриете чат базата данни. Няма да можете да получавате и изпращате съобщения, докато чатът е спрян. No comment provided by engineer. Stop chat? + Спри чата? No comment provided by engineer. Stop file + Спри файл cancel file action Stop receiving file? + Спри получаването на файла? No comment provided by engineer. Stop sending file? + Спри изпращането на файла? No comment provided by engineer. Stop sharing + Спри споделянето No comment provided by engineer. Stop sharing address? + Спри споделянето на адреса? No comment provided by engineer. Submit + Изпрати No comment provided by engineer. Support SimpleX Chat + Подкрепете SimpleX Chat No comment provided by engineer. System + Системен No comment provided by engineer. System authentication + Системна идентификация No comment provided by engineer. TCP connection timeout + Времето на изчакване за установяване на TCP връзка No comment provided by engineer. TCP_KEEPCNT + TCP_KEEPCNT No comment provided by engineer. TCP_KEEPIDLE + TCP_KEEPIDLE No comment provided by engineer. TCP_KEEPINTVL + TCP_KEEPINTVL No comment provided by engineer. Take picture + Направи снимка No comment provided by engineer. Tap button + Докосни бутона No comment provided by engineer. Tap to activate profile. + Докосни за активиране на профил. No comment provided by engineer. Tap to join + Докосни за вход No comment provided by engineer. Tap to join incognito + Докосни за инкогнито вход No comment provided by engineer. Tap to start a new chat + Докосни за започване на нов чат No comment provided by engineer. Test failed at step %@. + Тестът е неуспешен на стъпка %@. server test failure Test server + Тествай сървър No comment provided by engineer. Test servers + Тествай сървърите No comment provided by engineer. Tests failed! + Тестовете са неуспешни! No comment provided by engineer. Thank you for installing SimpleX Chat! + Благодарим Ви, че инсталирахте SimpleX Chat! No comment provided by engineer. Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Благодарение на потребителите – [допринесете през Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! No comment provided by engineer. Thanks to the users – contribute via Weblate! + Благодарение на потребителите – допринесете през Weblate! No comment provided by engineer. The 1st platform without any user identifiers – private by design. + Първата платформа без никакви потребителски идентификатори – поверителна по дизайн. No comment provided by engineer. The ID of the next message is incorrect (less or equal to the previous). It can happen because of some bug or when the connection is compromised. + Неправилно ID на следващото съобщение (по-малко или еднакво с предишното). +Това може да се случи поради някаква грешка или когато връзката е компрометирана. No comment provided by engineer. The app can notify you when you receive messages or contact requests - please open settings to enable. + Приложението може да ви уведоми, когато получите съобщения или заявки за контакт - моля, отворете настройките, за да активирате. No comment provided by engineer. The attempt to change database passphrase was not completed. + Опитът за промяна на паролата на базата данни не беше завършен. No comment provided by engineer. The connection you accepted will be cancelled! + Връзката, която приехте, ще бъде отказана! No comment provided by engineer. The contact you shared this link with will NOT be able to connect! + Контактът, с когото споделихте този линк, НЯМА да може да се свърже! No comment provided by engineer. The created archive is available via app Settings / Database / Old database archive. + Създаденият архив е достъпен чрез Настройки на приложението / База данни / Стар архив на база данни. No comment provided by engineer. The encryption is working and the new encryption agreement is not required. It may result in connection errors! + Криптирането работи и новото споразумение за криптиране не е необходимо. Това може да доведе до грешки при свързване! No comment provided by engineer. The group is fully decentralized – it is visible only to the members. + Групата е напълно децентрализирана – видима е само за членовете. No comment provided by engineer. The hash of the previous message is different. + Хешът на предишното съобщение е различен. No comment provided by engineer. The message will be deleted for all members. + Съобщението ще бъде изтрито за всички членове. No comment provided by engineer. The message will be marked as moderated for all members. + Съобщението ще бъде маркирано като модерирано за всички членове. No comment provided by engineer. The next generation of private messaging + Ново поколение поверителни съобщения No comment provided by engineer. The old database was not removed during the migration, it can be deleted. + Старата база данни не бе премахната по време на миграцията, тя може да бъде изтрита. No comment provided by engineer. The profile is only shared with your contacts. + Профилът се споделя само с вашите контакти. + No comment provided by engineer. + + + The second tick we missed! ✅ + Втората отметка, която пропуснахме! ✅ No comment provided by engineer. The sender will NOT be notified + Подателят НЯМА да бъде уведомен No comment provided by engineer. The servers for new connections of your current chat profile **%@**. + Сървърите за нови връзки на текущия ви чат профил **%@**. No comment provided by engineer. Theme + Тема No comment provided by engineer. There should be at least one user profile. + Трябва да има поне един потребителски профил. No comment provided by engineer. There should be at least one visible user profile. + Трябва да има поне един видим потребителски профил. No comment provided by engineer. These settings are for your current profile **%@**. + Тези настройки са за текущия ви профил **%@**. No comment provided by engineer. - - They can be overridden in contact and group settings + + They can be overridden in contact and group settings. + Те могат да бъдат променени в настройките за всеки контакт и група. No comment provided by engineer. This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain. + Това действие не може да бъде отменено - всички получени и изпратени файлове и медия ще бъдат изтрити. Снимките с ниска разделителна способност ще бъдат запазени. No comment provided by engineer. This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes. + Това действие не може да бъде отменено - съобщенията, изпратени и получени по-рано от избраното, ще бъдат изтрити. Може да отнеме няколко минути. No comment provided by engineer. This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost. + Това действие не може да бъде отменено - вашият профил, контакти, съобщения и файлове ще бъдат безвъзвратно загубени. + No comment provided by engineer. + + + This group has over %lld members, delivery receipts are not sent. + Тази група има над %lld членове, потвърждения за доставка не се изпращат. No comment provided by engineer. This group no longer exists. + Тази група вече не съществува. No comment provided by engineer. This setting applies to messages in your current chat profile **%@**. + Тази настройка се прилага за съобщения в текущия ви профил **%@**. No comment provided by engineer. To ask any questions and to receive updates: + За да задавате въпроси и да получавате актуализации: No comment provided by engineer. To connect, your contact can scan QR code or use the link in the app. - No comment provided by engineer. - - - To find the profile used for an incognito connection, tap the contact or group name on top of the chat. + За да се свърже, вашият контакт може да сканира QR код или да използва линка в приложението. No comment provided by engineer. To make a new connection + За да направите нова връзка No comment provided by engineer. To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts. + За да се защити поверителността, вместо потребителски идентификатори, използвани от всички други платформи, SimpleX има идентификатори за опашки от съобщения, отделни за всеки от вашите контакти. No comment provided by engineer. To protect timezone, image/voice files use UTC. + За да не се разкрива часовата зона, файловете с изображения/глас използват UTC. No comment provided by engineer. To protect your information, turn on SimpleX Lock. You will be prompted to complete authentication before this feature is enabled. + За да защитите информацията си, включете SimpleX заключване. +Ще бъдете подканени да извършите идентификация, преди тази функция да бъде активирана. No comment provided by engineer. To record voice message please grant permission to use Microphone. + За да запишете гласово съобщение, моля, дайте разрешение за използване на микрофон. No comment provided by engineer. To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page. + За да разкриете своя скрит профил, въведете пълна парола в полето за търсене на страницата **Вашите чат профили**. No comment provided by engineer. To support instant push notifications the chat database has to be migrated. + За поддръжка на незабавни push известия, базата данни за чат трябва да бъде мигрирана. No comment provided by engineer. To verify end-to-end encryption with your contact compare (or scan) the code on your devices. + За да проверите криптирането от край до край с вашия контакт, сравнете (или сканирайте) кода на вашите устройства. + No comment provided by engineer. + + + Toggle incognito when connecting. + Избор на инкогнито при свързване. No comment provided by engineer. Transport isolation + Транспортна изолация No comment provided by engineer. Trying to connect to the server used to receive messages from this contact (error: %@). + Опит за свързване със сървъра, използван за получаване на съобщения от този контакт (грешка: %@). No comment provided by engineer. Trying to connect to the server used to receive messages from this contact. + Опит за свързване със сървъра, използван за получаване на съобщения от този контакт. No comment provided by engineer. Turn off + Изключи No comment provided by engineer. Turn off notifications? + Изключи известията? No comment provided by engineer. Turn on + Включи No comment provided by engineer. Unable to record voice message + Не може да се запише гласово съобщение No comment provided by engineer. Unexpected error: %@ - No comment provided by engineer. + Неочаквана грешка: %@ + item status description Unexpected migration state + Неочаквано състояние на миграция No comment provided by engineer. Unfav. + Премахни от любимите No comment provided by engineer. Unhide + Покажи No comment provided by engineer. Unhide chat profile + Покажи чат профила No comment provided by engineer. Unhide profile + Покажи профила No comment provided by engineer. Unit + Мерна единица No comment provided by engineer. Unknown caller + Неизвестен номер callkit banner Unknown database error: %@ + Неизвестна грешка в базата данни: %@ No comment provided by engineer. Unknown error + Непозната грешка No comment provided by engineer. Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions. + Освен ако не използвате интерфейса за повикване на iOS, активирайте режима "Не безпокой", за да избегнете прекъсвания. No comment provided by engineer. Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. To connect, please ask your contact to create another connection link and check that you have a stable network connection. + Освен ако вашият контакт не е изтрил връзката или този линк вече е бил използван, това може да е грешка - моля, докладвайте. +За да се свържете, моля, помолете вашия контакт да създаде друг линк за връзка и проверете дали имате стабилна мрежова връзка. No comment provided by engineer. Unlock + Отключи No comment provided by engineer. Unlock app + Отключи приложението authentication reason Unmute + Уведомявай No comment provided by engineer. Unread + Непрочетено No comment provided by engineer. Update + Актуализация No comment provided by engineer. Update .onion hosts setting? + Актуализиране на настройката за .onion хостове? No comment provided by engineer. Update database passphrase + Актуализирай паролата на базата данни No comment provided by engineer. Update network settings? + Актуализиране на мрежовите настройки? No comment provided by engineer. Update transport isolation mode? + Актуализиране на режима на изолация на транспорта? No comment provided by engineer. Updating settings will re-connect the client to all servers. + Актуализирането на настройките ще свърже отново клиента към всички сървъри. No comment provided by engineer. Updating this setting will re-connect the client to all servers. + Актуализирането на тази настройка ще свърже повторно клиента към всички сървъри. No comment provided by engineer. Upgrade and open chat + Актуализирай и отвори чата No comment provided by engineer. Upload file + Качи файл server test step Use .onion hosts + Използвай .onion хостове No comment provided by engineer. Use SimpleX Chat servers? + Използвай сървърите на SimpleX Chat? No comment provided by engineer. Use chat + Използвай чата + No comment provided by engineer. + + + Use current profile + Използвай текущия профил No comment provided by engineer. Use for new connections + Използвай за нови връзки No comment provided by engineer. Use iOS call interface + Използвай интерфейса за повикване на iOS + No comment provided by engineer. + + + Use new incognito profile + Използвай нов инкогнито профил No comment provided by engineer. Use server + Използвай сървър No comment provided by engineer. User profile + Потребителски профил No comment provided by engineer. Using .onion hosts requires compatible VPN provider. + Използването на .onion хостове изисква съвместим VPN доставчик. No comment provided by engineer. Using SimpleX Chat servers. + Използват се сървърите на SimpleX Chat. No comment provided by engineer. Verify connection security + Потвръди сигурността на връзката No comment provided by engineer. Verify security code + Потвръди кода за сигурност No comment provided by engineer. Via browser + Чрез браузър No comment provided by engineer. Video call + Видео разговор No comment provided by engineer. Video will be received when your contact completes uploading it. + Видеото ще бъде получено, когато вашият контакт завърши качването му. No comment provided by engineer. Video will be received when your contact is online, please wait or check later! + Видеото ще бъде получено, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно! No comment provided by engineer. Videos and files up to 1gb + Видео и файлове до 1gb No comment provided by engineer. View security code + Виж кода за сигурност No comment provided by engineer. Voice messages + Гласови съобщения chat feature Voice messages are prohibited in this chat. + Гласовите съобщения са забранени в този чат. No comment provided by engineer. Voice messages are prohibited in this group. + Гласовите съобщения са забранени в тази група. No comment provided by engineer. Voice messages prohibited! + Гласовите съобщения са забранени! No comment provided by engineer. Voice message… + Гласово съобщение… No comment provided by engineer. Waiting for file + Изчаква се получаването на файла No comment provided by engineer. Waiting for image + Изчаква се получаването на изображението No comment provided by engineer. Waiting for video + Изчаква се получаването на видеото No comment provided by engineer. Warning: you may lose some data! + Предупреждение: Може да загубите някои данни! No comment provided by engineer. WebRTC ICE servers + WebRTC ICE сървъри No comment provided by engineer. Welcome %@! + Добре дошли %@! No comment provided by engineer. Welcome message + Съобщение при посрещане No comment provided by engineer. What's new + Какво е новото No comment provided by engineer. When available + Когато са налични No comment provided by engineer. When people request to connect, you can accept or reject it. + Когато хората искат да се свържат с вас, можете да ги приемете или отхвърлите. No comment provided by engineer. When you share an incognito profile with somebody, this profile will be used for the groups they invite you to. + Когато споделяте инкогнито профил с някого, този профил ще се използва за групите, в които той ви кани. No comment provided by engineer. With optional welcome message. + С незадължително съобщение при посрещане. No comment provided by engineer. Wrong database passphrase + Грешна парола за базата данни No comment provided by engineer. Wrong passphrase! + Грешна парола! No comment provided by engineer. XFTP servers + XFTP сървъри No comment provided by engineer. You + Вие No comment provided by engineer. You accepted connection + Вие приехте връзката No comment provided by engineer. You allow + Вие позволявате No comment provided by engineer. You already have a chat profile with the same display name. Please choose another name. + Вече имате чат профил със същото показвано име. Моля, изберете друго име. No comment provided by engineer. You are already connected to %@. + Вече сте вече свързани с %@. No comment provided by engineer. You are connected to the server used to receive messages from this contact. + Вие сте свързани към сървъра, използван за получаване на съобщения от този контакт. No comment provided by engineer. You are invited to group + Поканени сте в групата No comment provided by engineer. You can accept calls from lock screen, without device and app authentication. + Можете да приемате обаждания от заключен екран, без идентификация на устройство и приложението. No comment provided by engineer. You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. + Можете също да се свържете, като натиснете върху линка. Ако се отвори в браузъра, натиснете върху бутона **Отваряне в мобилно приложение**. No comment provided by engineer. You can create it later + Можете да го създадете по-късно + No comment provided by engineer. + + + You can enable later via Settings + Можете да активирате по-късно през Настройки No comment provided by engineer. You can enable them later via app Privacy & Security settings. + Можете да ги активирате по-късно през настройките за "Поверителност и сигурност" на приложението. No comment provided by engineer. You can hide or mute a user profile - swipe it to the right. + Можете да скриете или заглушите известията за потребителски профил - плъзнете надясно. No comment provided by engineer. You can now send messages to %@ + Вече можете да изпращате съобщения до %@ notification body You can set lock screen notification preview via settings. + Можете да зададете визуализация на известията на заключен екран през настройките. No comment provided by engineer. You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + Можете да споделите линк или QR код - всеки ще може да се присъедини към групата. Няма да загубите членовете на групата, ако по-късно я изтриете. No comment provided by engineer. You can share this address with your contacts to let them connect with **%@**. + Можете да споделите този адрес с вашите контакти, за да им позволите да се свържат с **%@**. No comment provided by engineer. You can share your address as a link or QR code - anybody can connect to you. + Можете да споделите адреса си като линк или QR код - всеки може да се свърже с вас. No comment provided by engineer. You can start chat via app Settings / Database or by restarting the app + Можете да започнете чат през Настройки на приложението / База данни или като рестартирате приложението No comment provided by engineer. You can turn on SimpleX Lock via Settings. + Можете да включите SimpleX заключване през Настройки. No comment provided by engineer. You can use markdown to format messages: + Можете да използвате markdown за форматиране на съобщенията: No comment provided by engineer. You can't send messages! + Не може да изпращате съобщения! No comment provided by engineer. You control through which server(s) **to receive** the messages, your contacts – the servers you use to message them. + Вие контролирате през кой сървър(и) **да получавате** съобщенията, вашите контакти – сървърите, които използвате, за да им изпращате съобщения. No comment provided by engineer. You could not be verified; please try again. + Не можахте да бъдете потвърдени; Моля, опитайте отново. No comment provided by engineer. You have no chats + Нямате чатове No comment provided by engineer. You have to enter passphrase every time the app starts - it is not stored on the device. + Трябва да въвеждате парола при всяко стартиране на приложението - тя не се съхранява на устройството. No comment provided by engineer. - - You invited your contact + + You invited a contact + Вие поканихте контакта No comment provided by engineer. You joined this group + Вие се присъединихте към тази група No comment provided by engineer. You joined this group. Connecting to inviting group member. + Вие се присъединихте към тази група. Свързване с поканващия член на групата. 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. + Трябва да използвате най-новата версия на вашата чат база данни САМО на едно устройство, в противен случай може да спрете да получавате съобщения от някои контакти. No comment provided by engineer. You need to allow your contact to send voice messages to be able to send them. + Трябва да разрешите на вашия контакт да изпраща гласови съобщения, за да можете да ги изпращате. No comment provided by engineer. You rejected group invitation + Отхвърлихте поканата за групата No comment provided by engineer. You sent group invitation + Изпратихте покана за групата No comment provided by engineer. You will be connected to group when the group host's device is online, please wait or check later! + Ще бъдете свързани с групата, когато устройството на домакина на групата е онлайн, моля, изчакайте или проверете по-късно! No comment provided by engineer. You will be connected when your connection request is accepted, please wait or check later! + Ще бъдете свързани, когато заявката ви за връзка бъде приета, моля, изчакайте или проверете по-късно! No comment provided by engineer. You will be connected when your contact's device is online, please wait or check later! + Ще бъдете свързани, когато устройството на вашия контакт е онлайн, моля, изчакайте или проверете по-късно! No comment provided by engineer. You will be required to authenticate when you start or resume the app after 30 seconds in background. + Ще трябва да се идентифицирате, когато стартирате или възобновите приложението след 30 секунди във фонов режим. No comment provided by engineer. You will join a group this link refers to and connect to its group members. + Ще се присъедините към групата, към която този линк препраща, и ще се свържете с нейните членове. No comment provided by engineer. You will still receive calls and notifications from muted profiles when they are active. + Все още ще получавате обаждания и известия от заглушени профили, когато са активни. No comment provided by engineer. You will stop receiving messages from this group. Chat history will be preserved. + Ще спрете да получавате съобщения от тази група. Историята на чата ще бъде запазена. No comment provided by engineer. You won't lose your contacts if you later delete your address. + Няма да загубите контактите си, ако по-късно изтриете адреса си. No comment provided by engineer. You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile + Опитвате се да поканите контакт, с когото сте споделили инкогнито профил, в групата, в която използвате основния си профил No comment provided by engineer. You're using an incognito profile for this group - to prevent sharing your main profile inviting contacts is not allowed + Използвате инкогнито профил за тази група - за да се предотврати споделянето на основния ви профил, поканите на контакти не са разрешени No comment provided by engineer. Your %@ servers + Вашите %@ сървъри No comment provided by engineer. Your ICE servers + Вашите ICE сървъри No comment provided by engineer. Your SMP servers + Вашите SMP сървъри No comment provided by engineer. Your SimpleX address + Вашият SimpleX адрес No comment provided by engineer. Your XFTP servers + Вашите XFTP сървъри No comment provided by engineer. Your calls + Вашите обаждания No comment provided by engineer. Your chat database + Вашата чат база данни No comment provided by engineer. Your chat database is not encrypted - set passphrase to encrypt it. + Вашата чат база данни не е криптирана - задайте парола, за да я криптирате. No comment provided by engineer. Your chat profile will be sent to group members - No comment provided by engineer. - - - Your chat profile will be sent to your contact + Вашият чат профил ще бъде изпратен на членовете на групата No comment provided by engineer. Your chat profiles + Вашите чат профили No comment provided by engineer. Your contact needs to be online for the connection to complete. You can cancel this connection and remove the contact (and try later with a new link). + Вашият контакт трябва да бъде онлайн, за да осъществите връзката. +Можете да откажете тази връзка и да премахнете контакта (и да опитате по -късно с нов линк). No comment provided by engineer. Your contact sent a file that is larger than currently supported maximum size (%@). + Вашият контакт изпрати файл, който е по-голям от поддържания в момента максимален размер (%@). No comment provided by engineer. Your contacts can allow full message deletion. + Вашите контакти могат да позволят пълното изтриване на съобщението. No comment provided by engineer. Your contacts in SimpleX will see it. You can change it in Settings. + Вашите контакти в SimpleX ще го видят. +Можете да го промените в Настройки. No comment provided by engineer. Your contacts will remain connected. + Вашите контакти ще останат свързани. No comment provided by engineer. Your current chat database will be DELETED and REPLACED with the imported one. + Вашата текуща чат база данни ще бъде ИЗТРИТА и ЗАМЕНЕНА с импортираната. No comment provided by engineer. Your current profile + Вашият текущ профил No comment provided by engineer. Your preferences + Вашите настройки No comment provided by engineer. Your privacy + Вашата поверителност + No comment provided by engineer. + + + Your profile **%@** will be shared. + Вашият профил **%@** ще бъде споделен. No comment provided by engineer. Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile. - No comment provided by engineer. - - - Your profile will be sent to the contact that you received this link from + Вашият профил се съхранява на вашето устройство и се споделя само с вашите контакти. +SimpleX сървърите не могат да видят вашия профил. No comment provided by engineer. Your profile, contacts and delivered messages are stored on your device. + Вашият профил, контакти и доставени съобщения се съхраняват на вашето устройство. No comment provided by engineer. Your random profile + Вашият автоматично генериран профил No comment provided by engineer. Your server + Вашият сървър No comment provided by engineer. Your server address + Вашият адрес на сървъра No comment provided by engineer. Your settings + Вашите настройки No comment provided by engineer. [Contribute](https://github.com/simplex-chat/simplex-chat#contribute) + [Допринеси](https://github.com/simplex-chat/simplex-chat#contribute) No comment provided by engineer. [Send us email](mailto:chat@simplex.chat) + [Изпратете ни имейл](mailto:chat@simplex.chat) No comment provided by engineer. [Star on GitHub](https://github.com/simplex-chat/simplex-chat) + [Звезда в GitHub](https://github.com/simplex-chat/simplex-chat) No comment provided by engineer. \_italic_ + \_курсив_ No comment provided by engineer. \`a + b` + \`a + b` No comment provided by engineer. above, then choose: + по-горе, след това избери: No comment provided by engineer. accepted call + обаждането прието call status admin + админ member role agreeing encryption for %@… + съгласуване на криптиране за %@… chat item text agreeing encryption… + съгласуване на криптиране… chat item text always + винаги pref value audio call (not e2e encrypted) + аудио разговор (не е e2e криптиран) No comment provided by engineer. bad message ID + лошо ID на съобщението integrity error chat item bad message hash + лош хеш на съобщението integrity error chat item bold + удебелен No comment provided by engineer. call error + грешка при повикване call status call in progress + в момента тече разговор call status calling… + повикване… call status cancelled %@ + отменен %@ feature offered item changed address for you + променен е адреса за вас chat item text changed role of %1$@ to %2$@ + променена роля от %1$@ на %2$@ rcv group event chat item changed your role to %@ + променена е вашата ролята на %@ rcv group event chat item changing address for %@… + промяна на адреса за %@… chat item text changing address… + промяна на адреса… chat item text colored + цветен No comment provided by engineer. complete + завършен No comment provided by engineer. connect to SimpleX Chat developers. + свържете се с разработчиците на SimpleX Chat. No comment provided by engineer. connected + свързан No comment provided by engineer. + + connected directly + rcv group event chat item + connecting + свързване No comment provided by engineer. connecting (accepted) + свързване (прието) No comment provided by engineer. connecting (announced) + свързване (обявено) No comment provided by engineer. connecting (introduced) + свързване (представен) No comment provided by engineer. connecting (introduction invitation) + свързване (покана за представяне) No comment provided by engineer. connecting call… + разговорът се свързва… call status connecting… + свързване… chat list item title connection established + установена е връзка chat list item title (it should not be shown connection:%@ + връзка:%@ connection information contact has e2e encryption + контактът има e2e криптиране No comment provided by engineer. contact has no e2e encryption + контактът няма e2e криптиране No comment provided by engineer. creator + създател No comment provided by engineer. custom + персонализиран dropdown time picker choice database version is newer than the app, but no down migration for: %@ + версията на базата данни е по-нова от приложението, но няма миграция надолу за: %@ No comment provided by engineer. days + дни time unit default (%@) + по подразбиране (%@) pref value default (no) + по подразбиране (не) No comment provided by engineer. default (yes) + по подразбиране (да) No comment provided by engineer. deleted + изтрит deleted chat item deleted group + групата изтрита rcv group event chat item different migration in the app/database: %@ / %@ + различна миграция в приложението/базата данни: %@ / %@ No comment provided by engineer. direct + директна connection level description + + disabled + деактивирано + No comment provided by engineer. + duplicate message + дублирано съобщение integrity error chat item e2e encrypted + e2e криптиран No comment provided by engineer. enabled + активирано enabled status enabled for contact + активирано за контакт enabled status enabled for you + активирано за вас enabled status encryption agreed + криптирането е съгласувано chat item text encryption agreed for %@ + криптирането е съгласувано за %@ chat item text encryption ok + криптирането работи chat item text encryption ok for %@ + криптирането работи за %@ chat item text encryption re-negotiation allowed + разрешено повторно договаряне на криптиране chat item text encryption re-negotiation allowed for %@ + разрешено повторно договаряне на криптиране за %@ chat item text encryption re-negotiation required + необходимо е повторно договаряне на криптиране chat item text encryption re-negotiation required for %@ + необходимо е повторно договаряне на криптиране за %@ chat item text ended + приключен No comment provided by engineer. ended call %@ + приключи разговор %@ call status error + грешка + No comment provided by engineer. + + + event happened + събитие се случи No comment provided by engineer. group deleted + групата е изтрита No comment provided by engineer. group profile updated + профилът на групата е актуализиран snd group event chat item hours + часове time unit iOS Keychain is used to securely store passphrase - it allows receiving push notifications. + iOS Keychain се използва за сигурно съхраняване на парола - позволява получаване на push известия. No comment provided by engineer. iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications. + iOS Keychain ще се използва за сигурно съхраняване на паролата, след като рестартирате приложението или промените паролата - това ще позволи получаването на push известия. No comment provided by engineer. incognito via contact address link + инкогнито чрез линк с адрес за контакт chat list item description incognito via group link + инкогнито чрез групов линк chat list item description incognito via one-time link + инкогнито чрез еднократен линк за връзка chat list item description indirect (%d) + индиректна (%d) connection level description invalid chat + невалиден чат invalid chat data invalid chat data + невалидни данни за чат No comment provided by engineer. invalid data + невалидни данни invalid chat item invitation to group %@ + покана за група %@ group name invited + поканен No comment provided by engineer. invited %@ + поканен %@ rcv group event chat item invited to connect + поканен да се свърже chat list item title invited via your group link + поканен чрез вашия групов линк rcv group event chat item italic + курсив No comment provided by engineer. join as %@ + присъединяване като %@ No comment provided by engineer. left + напусна rcv group event chat item - + marked deleted - маркирано като изтрито + маркирано като изтрито marked deleted chat item preview text - + member - член + член member role - + connected - свързан + свързан rcv group event chat item message received + получено съобщение notification - + minutes - минути + минути time unit - + missed call - пропуснато повикване + пропуснато повикване call status - + moderated - модерирано + модерирано moderated chat item moderated by %@ + модерирано от %@ No comment provided by engineer. - + months - месеци + месеци time unit - + never - никога + никога No comment provided by engineer. - + new message - ново съобщение + ново съобщение notification - + no - не + не pref value - + no e2e encryption - липсва e2e криптиране + липсва e2e криптиране No comment provided by engineer. - + no text - няма текст + няма текст copied message info in history - + observer - наблюдател + наблюдател member role - + off - изключено + изключено enabled status group pref value offered %@ + предлага %@ feature offered item offered %1$@: %2$@ + предлага %1$@: %2$@ feature offered item on + включено group pref value or chat with the developers + или пишете на разработчиците No comment provided by engineer. owner + собственик member role peer-to-peer + peer-to-peer No comment provided by engineer. received answer… + получен отговор… No comment provided by engineer. received confirmation… + получено потвърждение… No comment provided by engineer. rejected call + отхвърлено повикване call status removed + отстранен No comment provided by engineer. removed %@ + отстранен %@ rcv group event chat item removed you + ви острани rcv group event chat item sec + сек. network option seconds + секунди time unit secret + таен No comment provided by engineer. security code changed + кодът за сигурност е променен chat item text + + send direct message + No comment provided by engineer. + starting… + стартиране… No comment provided by engineer. - + strike - зачеркнат + зачеркнат No comment provided by engineer. this contact + този контакт notification title unknown + неизвестен connection info updated group profile + актуализиран профил на групата rcv group event chat item v%@ (%@) + v%@ (%@) No comment provided by engineer. via contact address link + чрез линк с адрес за контакт chat list item description via group link + чрез групов линк chat list item description - + via one-time link - чрез еднократен линк за връзка + чрез еднократен линк за връзка chat list item description - + via relay - чрез реле + чрез реле No comment provided by engineer. - + video call (not e2e encrypted) - видео разговор (не е e2e криптиран) + видео разговор (не е e2e криптиран) No comment provided by engineer. - + waiting for answer… - чака се отговор… + чака се отговор… No comment provided by engineer. - + waiting for confirmation… - чака се за потвърждение… + чака се за потвърждение… No comment provided by engineer. - + wants to connect to you! - иска да се свърже с вас! + иска да се свърже с вас! No comment provided by engineer. - + weeks - седмици + седмици time unit - + yes - да + да pref value - + you are invited to group - вие сте поканени в групата + вие сте поканени в групата No comment provided by engineer. - + you are observer - вие сте наблюдател + вие сте наблюдател No comment provided by engineer. - + you changed address - променихте адреса + променихте адреса chat item text - + you changed address for %@ - променихте адреса за %@ + променихте адреса за %@ chat item text - + you changed role for yourself to %@ - променихте ролята си на %@ + променихте ролята си на %@ snd group event chat item - + you changed role of %1$@ to %2$@ - променихте ролята на %1$@ на %2$@ + променихте ролята на %1$@ на %2$@ snd group event chat item - + you left - вие напуснахте + вие напуснахте snd group event chat item - + you removed %@ - премахнахте %@ + премахнахте %@ snd group event chat item - + you shared one-time link - споделихте еднократен линк за връзка + споделихте еднократен линк за връзка chat list item description - + you shared one-time link incognito - споделихте еднократен инкогнито линк за връзка + споделихте еднократен инкогнито линк за връзка chat list item description - + you: - вие: + вие: No comment provided by engineer. - + \~strike~ - \~зачеркнат~ - No comment provided by engineer. - - - # %@ - # %@ - copied message info title, # <title> - - - ## History - ## История - copied message info - - - ## In reply to - ## В отговор на - copied message info - - - A few more things - Още няколко неща - No comment provided by engineer. - - - A new random profile will be shared. - Нов произволен профил ще бъде споделен. - No comment provided by engineer. - - - - more stable message delivery. -- a bit better groups. -- and more! - - по-стабилна доставка на съобщения. -- малко по-добри групи. -- и още! - No comment provided by engineer. - - - Accept connection request? - Приемане на заявка за връзка? - No comment provided by engineer. - - - Connect incognito - Свързване инкогнито - No comment provided by engineer. - - - Connect via one-time link - Свързване чрез еднократен линк за връзка - No comment provided by engineer. - - - Delivery - Доставка - No comment provided by engineer. - - - Disable (keep overrides) - Деактивиране (запазване на промените) - No comment provided by engineer. - - - Disable for all - Деактивиране за всички - No comment provided by engineer. - - - Error enabling delivery receipts! - Грешка при активирането на потвърждениeто за доставка! - No comment provided by engineer. - - - Even when disabled in the conversation. - Дори когато е деактивиран в разговора. - No comment provided by engineer. - - - Fix encryption after restoring backups. - Оправяне на криптирането след възстановяване от резервни копия. - No comment provided by engineer. - - - Incognito mode protects your privacy by using a new random profile for each contact. - Режимът инкогнито защитава вашата поверителност, като използва нов произволен профил за всеки контакт. - No comment provided by engineer. - - - Don't enable - Не активирай - No comment provided by engineer. - - - Filter unread and favorite chats. - Филтрирайте непрочетените и любимите чатове. - No comment provided by engineer. - - - Find chats faster - Намирайте чатове по-бързо - No comment provided by engineer. - - - Enable (keep overrides) - Активиране (запазване на промените) - No comment provided by engineer. - - - Enable for all - Активиране за всички - No comment provided by engineer. - - - Error setting delivery receipts! - Грешка при настройването на потвърждениeто за доставка!! - No comment provided by engineer. - - - Invalid status - Невалиден статус - item status text - - - Keep your connections - Запазете връзките си - No comment provided by engineer. - - - Make one message disappear - Накарайте едно съобщение да изчезне - No comment provided by engineer. - - - Message delivery receipts! - Потвърждениe за доставка на съобщения! - No comment provided by engineer. - - - %@ and %@ connected - %@ и %@ са свързани - No comment provided by engineer. - - - No delivery information - Няма информация за доставката + \~зачеркнат~ No comment provided by engineer.
- +
- + SimpleX - SimpleX + SimpleX Bundle name - + SimpleX needs camera access to scan QR codes to connect to other users and for video calls. - SimpleX се нуждае от достъп до камерата, за да сканира QR кодове, за да се свърже с други потребители и за видео разговори. + SimpleX се нуждае от достъп до камерата, за да сканира QR кодове, за да се свърже с други потребители и за видео разговори. Privacy - Camera Usage Description - + SimpleX uses Face ID for local authentication - SimpleX използва Face ID за локалнa идентификация + SimpleX използва Face ID за локалнa идентификация Privacy - Face ID Usage Description - + SimpleX needs microphone access for audio and video calls, and to record voice messages. - SimpleX се нуждае от достъп до микрофона за аудио и видео разговори и за запис на гласови съобщения. + SimpleX се нуждае от достъп до микрофона за аудио и видео разговори и за запис на гласови съобщения. Privacy - Microphone Usage Description - + SimpleX needs access to Photo Library for saving captured and received media - SimpleX се нуждае от достъп до фотобиблиотека за запазване на заснета и получена медия + SimpleX се нуждае от достъп до фотобиблиотека за запазване на заснета и получена медия Privacy - Photo Library Additions Usage Description
- +
- + SimpleX NSE - SimpleX NSE + SimpleX NSE Bundle display name - + SimpleX NSE - SimpleX NSE + SimpleX NSE Bundle name - + Copyright © 2022 SimpleX Chat. All rights reserved. - Авторско право © 2022 SimpleX Chat. Всички права запазени. + Авторско право © 2022 SimpleX Chat. Всички права запазени. Copyright (human-readable) diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/Shared/Assets.xcassets/AccentColor.colorset/Contents.json b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/Shared/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000000..aaa7f79bc8 --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/Shared/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,23 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.000", + "alpha" : "1.000", + "blue" : "1.000", + "green" : "0.533" + } + }, + "idiom" : "universal" + } + ], + "properties" : { + "localizable" : true + }, + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/Shared/Assets.xcassets/Contents.json b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/Shared/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/Shared/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/SimpleX NSE/en.lproj/InfoPlist.strings b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/SimpleX NSE/en.lproj/InfoPlist.strings new file mode 100644 index 0000000000..124ddbcc33 --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/SimpleX NSE/en.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SimpleX NSE"; +/* Bundle name */ +"CFBundleName" = "SimpleX NSE"; +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 SimpleX Chat. All rights reserved."; diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/en.lproj/Localizable.strings b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/en.lproj/Localizable.strings new file mode 100644 index 0000000000..cf485752ea --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/en.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* No comment provided by engineer. */ +"_italic_" = "\\_italic_"; + +/* No comment provided by engineer. */ +"**Add new contact**: to create your one-time QR Code for your contact." = "**Add new contact**: to create your one-time QR Code or link for your contact."; + +/* No comment provided by engineer. */ +"*bold*" = "\\*bold*"; + +/* No comment provided by engineer. */ +"`a + b`" = "\\`a + b`"; + +/* No comment provided by engineer. */ +"~strike~" = "\\~strike~"; + +/* call status */ +"connecting call" = "connecting call…"; + +/* No comment provided by engineer. */ +"Connecting server…" = "Connecting to server…"; + +/* No comment provided by engineer. */ +"Connecting server… (error: %@)" = "Connecting to server… (error: %@)"; + +/* rcv group event chat item */ +"member connected" = "connected"; + +/* No comment provided by engineer. */ +"No group!" = "Group not found!"; + diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/en.lproj/SimpleX--iOS--InfoPlist.strings b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/en.lproj/SimpleX--iOS--InfoPlist.strings new file mode 100644 index 0000000000..3af673b19f --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Source Contents/en.lproj/SimpleX--iOS--InfoPlist.strings @@ -0,0 +1,10 @@ +/* Bundle name */ +"CFBundleName" = "SimpleX"; +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls."; +/* Privacy - Face ID Usage Description */ +"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication"; +/* Privacy - Microphone Usage Description */ +"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages."; +/* Privacy - Photo Library Additions Usage Description */ +"NSPhotoLibraryAddUsageDescription" = "SimpleX needs access to Photo Library for saving captured and received media"; diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/contents.json b/apps/ios/SimpleX Localizations/bg.xcloc/contents.json new file mode 100644 index 0000000000..23e8239ce8 --- /dev/null +++ b/apps/ios/SimpleX Localizations/bg.xcloc/contents.json @@ -0,0 +1,12 @@ +{ + "developmentRegion" : "en", + "project" : "SimpleX.xcodeproj", + "targetLocale" : "bg", + "toolInfo" : { + "toolBuildNumber" : "15A240d", + "toolID" : "com.apple.dt.xcode", + "toolName" : "Xcode", + "toolVersion" : "15.0" + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff index 8e90ae4594..bbfd95e6bf 100644 --- a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff +++ b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,10 @@ %lld minut No comment provided by engineer. + + %lld new interface languages + No comment provided by engineer. + %lld second(s) %lld vteřin @@ -327,6 +331,12 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +710,10 @@ Sestavení aplikace: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + No comment provided by engineer. + App icon Ikona aplikace @@ -835,6 +849,10 @@ Hlasové zprávy můžete posílat vy i váš kontakt. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). Podle chat profilu (výchozí) nebo [podle připojení](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). @@ -1231,6 +1249,10 @@ Vytvořit odkaz No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Vytvořit jednorázovou pozvánku @@ -1684,6 +1706,10 @@ Odpojit server test step + + Discover and join groups + No comment provided by engineer. + Display name Zobrazované jméno @@ -1823,6 +1849,10 @@ Encrypt local files No comment provided by engineer. + + Encrypt stored files & media + No comment provided by engineer. + Encrypted database Zašifrovaná databáze @@ -1948,6 +1978,10 @@ Chyba při vytváření odkazu skupiny No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! Chyba při vytváření profilu! @@ -2077,6 +2111,10 @@ Chyba odesílání e-mailu No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Chyba při odesílání zprávy @@ -3090,6 +3128,10 @@ Archiv nové databáze No comment provided by engineer. + + New desktop app! + No comment provided by engineer. + New display name Nově zobrazované jméno @@ -3303,6 +3345,10 @@ Hlasové zprávy může odesílat pouze váš kontakt. No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings Otevřít nastavení @@ -4037,6 +4083,10 @@ Odeslat přímou zprávu No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Poslat mizící zprávu @@ -4334,6 +4384,10 @@ Jednorázová pozvánka SimpleX simplex link type + + Simplified incognito mode + No comment provided by engineer. + Skip Přeskočit @@ -4726,6 +4780,10 @@ Před zapnutím této funkce budete vyzváni k dokončení ověření. Chcete-li ověřit koncové šifrování u svého kontaktu, porovnejte (nebo naskenujte) kód na svých zařízeních. No comment provided by engineer. + + Toggle incognito when connecting. + No comment provided by engineer. + Transport isolation Izolace transportu @@ -5571,6 +5629,10 @@ Servery SimpleX nevidí váš profil. připojeno No comment provided by engineer. + + connected directly + rcv group event chat item + connecting připojování @@ -6030,6 +6092,10 @@ Servery SimpleX nevidí váš profil. bezpečnostní kód změněn chat item text + + send direct message + No comment provided by engineer. + starting… začíná… @@ -6174,7 +6240,7 @@ Servery SimpleX nevidí váš profil.
- +
@@ -6206,7 +6272,7 @@ Servery SimpleX nevidí váš profil.
- +
diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/contents.json b/apps/ios/SimpleX Localizations/cs.xcloc/contents.json index 7cdd89546c..5c7c929ee3 100644 --- a/apps/ios/SimpleX Localizations/cs.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/cs.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "cs", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff index fe164da9a9..114b7f3e73 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,10 @@ %lld Minuten No comment provided by engineer. + + %lld new interface languages + No comment provided by engineer. + %lld second(s) %lld Sekunde(n) @@ -327,6 +331,12 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +710,10 @@ App Build: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + No comment provided by engineer. + App icon App-Icon @@ -835,6 +849,10 @@ Sowohl Ihr Kontakt, als auch Sie können Sprachnachrichten senden. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). Per Chat-Profil (Voreinstellung) oder [per Verbindung](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). @@ -1231,6 +1249,10 @@ Link erzeugen No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Einmal-Einladungslink erstellen @@ -1684,6 +1706,10 @@ Trennen server test step + + Discover and join groups + No comment provided by engineer. + Display name Angezeigter Name @@ -1821,6 +1847,11 @@ Encrypt local files + Lokale Dateien verschlüsseln + No comment provided by engineer. + + + Encrypt stored files & media No comment provided by engineer. @@ -1948,6 +1979,10 @@ Fehler beim Erzeugen des Gruppen-Links No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! Fehler beim Erstellen des Profils! @@ -1955,6 +1990,7 @@ Error decrypting file + Fehler beim Entschlüsseln der Datei No comment provided by engineer. @@ -2077,6 +2113,10 @@ Fehler beim Senden der eMail No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Fehler beim Senden der Nachricht @@ -3090,6 +3130,10 @@ Neues Datenbankarchiv No comment provided by engineer. + + New desktop app! + No comment provided by engineer. + New display name Neuer Anzeigename @@ -3304,6 +3348,10 @@ Nur Ihr Kontakt kann Sprachnachrichten versenden. No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings Geräte-Einstellungen öffnen @@ -4039,6 +4087,10 @@ Direktnachricht senden No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Verschwindende Nachricht senden @@ -4339,6 +4391,10 @@ SimpleX-Einmal-Einladung simplex link type + + Simplified incognito mode + No comment provided by engineer. + Skip Überspringen @@ -4733,6 +4789,10 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt Um die Ende-zu-Ende-Verschlüsselung mit Ihrem Kontakt zu überprüfen, müssen Sie den Sicherheitscode in Ihren Apps vergleichen oder scannen. No comment provided by engineer. + + Toggle incognito when connecting. + No comment provided by engineer. + Transport isolation Transport-Isolation @@ -5581,6 +5641,10 @@ SimpleX-Server können Ihr Profil nicht einsehen. Verbunden No comment provided by engineer. + + connected directly + rcv group event chat item + connecting verbinde @@ -6042,6 +6106,10 @@ SimpleX-Server können Ihr Profil nicht einsehen. Sicherheitscode wurde geändert chat item text + + send direct message + No comment provided by engineer. + starting… Verbindung wird gestartet… @@ -6186,7 +6254,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.
- +
@@ -6218,7 +6286,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.
- +
diff --git a/apps/ios/SimpleX Localizations/de.xcloc/contents.json b/apps/ios/SimpleX Localizations/de.xcloc/contents.json index 1572e74b06..11924b71f5 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/de.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "de", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff index 5374efbf0f..0aeeecfbe6 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,11 @@ %lld minutes No comment provided by engineer. + + %lld new interface languages + %lld new interface languages + No comment provided by engineer. + %lld second(s) %lld second(s) @@ -327,6 +332,15 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +714,11 @@ App build: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + App encrypts new local files (except videos). + No comment provided by engineer. + App icon App icon @@ -835,6 +854,11 @@ Both you and your contact can send voice messages. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). @@ -1231,6 +1255,11 @@ Create link No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Create one-time invitation link @@ -1684,6 +1713,11 @@ Disconnect server test step + + Discover and join groups + Discover and join groups + No comment provided by engineer. + Display name Display name @@ -1824,6 +1858,11 @@ Encrypt local files No comment provided by engineer. + + Encrypt stored files & media + Encrypt stored files & media + No comment provided by engineer. + Encrypted database Encrypted database @@ -1949,6 +1988,11 @@ Error creating group link No comment provided by engineer. + + Error creating member contact + Error creating member contact + No comment provided by engineer. + Error creating profile! Error creating profile! @@ -2079,6 +2123,11 @@ Error sending email No comment provided by engineer. + + Error sending member contact invitation + Error sending member contact invitation + No comment provided by engineer. + Error sending message Error sending message @@ -3092,6 +3141,11 @@ New database archive No comment provided by engineer. + + New desktop app! + New desktop app! + No comment provided by engineer. + New display name New display name @@ -3306,6 +3360,11 @@ Only your contact can send voice messages. No comment provided by engineer. + + Open + Open + No comment provided by engineer. + Open Settings Open Settings @@ -4041,6 +4100,11 @@ Send direct message No comment provided by engineer. + + Send direct message to connect + Send direct message to connect + No comment provided by engineer. + Send disappearing message Send disappearing message @@ -4341,6 +4405,11 @@ SimpleX one-time invitation simplex link type + + Simplified incognito mode + Simplified incognito mode + No comment provided by engineer. + Skip Skip @@ -4735,6 +4804,11 @@ You will be prompted to complete authentication before this feature is enabled.< To verify end-to-end encryption with your contact compare (or scan) the code on your devices. No comment provided by engineer. + + Toggle incognito when connecting. + Toggle incognito when connecting. + No comment provided by engineer. + Transport isolation Transport isolation @@ -5583,6 +5657,11 @@ SimpleX servers cannot see your profile. connected No comment provided by engineer. + + connected directly + connected directly + rcv group event chat item + connecting connecting @@ -6044,6 +6123,11 @@ SimpleX servers cannot see your profile. security code changed chat item text + + send direct message + send direct message + No comment provided by engineer. + starting… starting… @@ -6188,7 +6272,7 @@ SimpleX servers cannot see your profile.
- +
@@ -6220,7 +6304,7 @@ SimpleX servers cannot see your profile.
- +
diff --git a/apps/ios/SimpleX Localizations/en.xcloc/contents.json b/apps/ios/SimpleX Localizations/en.xcloc/contents.json index b0d8ba8afc..7d429820ee 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/en.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "en", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff index 84325c1180..85f02bba1a 100644 --- a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff +++ b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,10 @@ %lld minutos No comment provided by engineer. + + %lld new interface languages + No comment provided by engineer. + %lld second(s) %lld segundo(s) @@ -327,6 +331,12 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +710,10 @@ Compilación app: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + No comment provided by engineer. + App icon Icono aplicación @@ -835,6 +849,10 @@ Tanto tú como tu contacto podéis enviar mensajes de voz. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). Mediante perfil (por defecto) o [por conexión](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). @@ -1231,6 +1249,10 @@ Crear enlace No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Crea enlace de invitación de un uso @@ -1636,7 +1658,7 @@ Disable (keep overrides) - Desactivar (conservar anulaciones) + Desactivar (conservando anulaciones) No comment provided by engineer. @@ -1684,6 +1706,10 @@ Desconectar server test step + + Discover and join groups + No comment provided by engineer. + Display name Nombre mostrado @@ -1823,6 +1849,10 @@ Encrypt local files No comment provided by engineer. + + Encrypt stored files & media + No comment provided by engineer. + Encrypted database Base de datos cifrada @@ -1948,6 +1978,10 @@ Error al crear enlace de grupo No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! ¡Error al crear perfil! @@ -2077,6 +2111,10 @@ Error al enviar email No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Error al enviar mensaje @@ -3090,6 +3128,10 @@ Nuevo archivo de bases de datos No comment provided by engineer. + + New desktop app! + No comment provided by engineer. + New display name Nuevo nombre mostrado @@ -3304,6 +3346,10 @@ Sólo tu contacto puede enviar mensajes de voz. No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings Abrir Configuración @@ -4039,6 +4085,10 @@ Enviar mensaje directo No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Enviar mensaje temporal @@ -4339,6 +4389,10 @@ Invitación SimpleX de un uso simplex link type + + Simplified incognito mode + No comment provided by engineer. + Skip Omitir @@ -4733,6 +4787,10 @@ Se te pedirá que completes la autenticación antes de activar esta función.Para comprobar el cifrado de extremo a extremo con tu contacto compara (o escanea) el código en tus dispositivos. No comment provided by engineer. + + Toggle incognito when connecting. + No comment provided by engineer. + Transport isolation Aislamiento de transporte @@ -5582,6 +5640,10 @@ Los servidores de SimpleX no pueden ver tu perfil. conectado No comment provided by engineer. + + connected directly + rcv group event chat item + connecting conectando @@ -5779,6 +5841,7 @@ Los servidores de SimpleX no pueden ver tu perfil. event happened + evento ocurrido No comment provided by engineer. @@ -6042,6 +6105,10 @@ Los servidores de SimpleX no pueden ver tu perfil. código de seguridad cambiado chat item text + + send direct message + No comment provided by engineer. + starting… inicializando… @@ -6186,7 +6253,7 @@ Los servidores de SimpleX no pueden ver tu perfil.
- +
@@ -6218,7 +6285,7 @@ Los servidores de SimpleX no pueden ver tu perfil.
- +
diff --git a/apps/ios/SimpleX Localizations/es.xcloc/contents.json b/apps/ios/SimpleX Localizations/es.xcloc/contents.json index 949db15697..c7d2c05ffa 100644 --- a/apps/ios/SimpleX Localizations/es.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/es.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "es", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff index a03c478767..c7e970f6ff 100644 --- a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff +++ b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff @@ -2,6394 +2,6306 @@
- +
- + - + No comment provided by engineer. - + - + No comment provided by engineer. - + - + No comment provided by engineer. - + - + No comment provided by engineer. - + ( - ( + ( No comment provided by engineer. - + (can be copied) - (voidaan kopioida) + (voidaan kopioida) No comment provided by engineer. - + !1 colored! - !1 värillinen! + !1 värillinen! No comment provided by engineer. - + + # %@ + # %@ + copied message info title, # <title> + + + ## History + ## Historia + copied message info + + + ## In reply to + ## vastauksena + copied message info + + #secret# - #salaisuus# + #salaisuus# No comment provided by engineer. - + %@ - % @ + % @ No comment provided by engineer. - + %@ %@ - %@ % @ + %@ % @ No comment provided by engineer. - - %@ / %@ - %@ / % @ - No comment provided by engineer. - - - %@ is connected! - %@ on yhdistetty! - notification title - - - %@ is not verified - %@ ei ole vahvistettu - No comment provided by engineer. - - - %@ is verified - %@ on vahvistettu - No comment provided by engineer. - - - %@ wants to connect! - %@ haluaa muodostaa yhteyden! - notification title - - - %d days - %d päivää - message ttl - - - %d hours - %d tuntia - message ttl - - - %d min - %d min - message ttl - - - %d months - %d kuukautta - message ttl - - - %d sec - %d sek - message ttl - - - %d skipped message(s) - %d ohitettua viestiä - integrity error chat item - - - %lld - %lld - No comment provided by engineer. - - - %lld %@ - %lld %@ - No comment provided by engineer. - - - %lld contact(s) selected - %lld kontaktia valittu - No comment provided by engineer. - - - %lld file(s) with total size of %@ - %lld tiedosto(a), joiden kokonaiskoko on %@ - No comment provided by engineer. - - - %lld members - %lld jäsenet - No comment provided by engineer. - - - %lld second(s) - %lld sekunti(a) - No comment provided by engineer. - - - %lldd - %lldd - No comment provided by engineer. - - - %lldh - %lldh - No comment provided by engineer. - - - %lldk - %lldk - No comment provided by engineer. - - - %lldm - %lldm - No comment provided by engineer. - - - %lldmth - %lldmth - No comment provided by engineer. - - - %llds - %llds - No comment provided by engineer. - - - %lldw - %lldw - No comment provided by engineer. - - - ( - ( - No comment provided by engineer. - - - ) - ) - No comment provided by engineer. - - - **Add new contact**: to create your one-time QR Code or link for your contact. - **Lisää uusi kontakti**: luo kertakäyttöinen QR-koodi tai linkki kontaktille. - No comment provided by engineer. - - - **Create link / QR code** for your contact to use. - **Luo linkki / QR-koodi* kontaktille. - No comment provided by engineer. - - - **More private**: check new messages every 20 minutes. Device token is shared with SimpleX Chat server, but not how many contacts or messages you have. - **Yksityisempi**: tarkista uudet viestit 20 minuutin välein. Laitetunnus jaetaan SimpleX Chat -palvelimen kanssa, mutta ei sitä, kuinka monta yhteystietoa tai viestiä sinulla on. - No comment provided by engineer. - - - **Most private**: do not use SimpleX Chat notifications server, check messages periodically in the background (depends on how often you use the app). - **Yksityisin**: älä käytä SimpleX Chat -ilmoituspalvelinta, tarkista viestit ajoittain taustalla (riippuu siitä, kuinka usein käytät sovellusta). - No comment provided by engineer. - - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Liitä vastaanotettu linkki** tai avaa se selaimessa ja napauta **Avaa mobiilisovelluksessa**. - No comment provided by engineer. - - - **Please note**: you will NOT be able to recover or change passphrase if you lose it. - **Huomaa**: et voi palauttaa tai muuttaa tunnuslausetta, jos kadotat sen. - No comment provided by engineer. - - - **Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from. - **Suositus**: laitetunnus ja ilmoitukset lähetetään SimpleX Chat -ilmoituspalvelimelle, mutta ei viestin sisältöä, kokoa tai sitä, keneltä se on peräisin. - No comment provided by engineer. - - - **Scan QR code**: to connect to your contact in person or via video call. - **Skannaa QR-koodi**: muodosta yhteys kontaktiisi henkilökohtaisesti tai videopuhelun kautta. - No comment provided by engineer. - - - **Warning**: Instant push notifications require passphrase saved in Keychain. - **Varoitus**: Välittömät push-ilmoitukset vaativat tunnuslauseen, joka on tallennettu Keychainiin. - No comment provided by engineer. - - - **e2e encrypted** audio call - **e2e-salattu** äänipuhelu - No comment provided by engineer. - - - **e2e encrypted** video call - **e2e-salattu** videopuhelu - No comment provided by engineer. - - - \*bold* - \*bold* - No comment provided by engineer. - - - , - , - No comment provided by engineer. - - - . - . - No comment provided by engineer. - - - 1 day - 1 päivä - message ttl - - - 1 hour - 1 tunti - message ttl - - - 1 month - 1 kuukausi - message ttl - - - 1 week - 1 viikko - message ttl - - - 2 weeks - message ttl - - - 6 - 6 - No comment provided by engineer. - - - : - : - No comment provided by engineer. - - - A new contact - Uusi kontakti - notification title - - - A random profile will be sent to the contact that you received this link from - Satunnainen profiili lähetetään kontaktille, jolta sait tämän linkin - No comment provided by engineer. - - - A random profile will be sent to your contact - Satunnainen profiili lähetetään kontaktillesi - No comment provided by engineer. - - - A separate TCP connection will be used **for each chat profile you have in the app**. - Erillistä TCP-yhteyttä käytetään **jokaiselle sovelluksessa olevalle chat-profiilille**. - No comment provided by engineer. - - - A separate TCP connection will be used **for each contact and group member**. -**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail. - Jokaiselle kontaktille ja ryhmän jäsenelle käytetään erillistä TCP-yhteyttä**. -**Huomaa**: jos kontakteja on useita, akun ja liikenteen kulutus voi olla huomattavasti suurempi ja jotkin yhteydet voivat epäonnistua. - No comment provided by engineer. - - - About SimpleX - Tietoja SimpleX:stä - No comment provided by engineer. - - - About SimpleX Chat - Tietoja SimpleX Chatistä - No comment provided by engineer. - - - Accent color - Korostusväri - No comment provided by engineer. - - - Accept - Hyväksy - accept contact request via notification - accept incoming call via notification - - - Accept contact - Hyväksy kontakti - No comment provided by engineer. - - - Accept contact request from %@? - Hyväksy kontaktipyyntö %@:ltä? - notification body - - - Accept incognito - Hyväksy tuntematon - No comment provided by engineer. - - - Accept requests - No comment provided by engineer. - - - Add preset servers - Lisää esiasetettuja palvelimia - No comment provided by engineer. - - - Add profile - Lisää profiili - No comment provided by engineer. - - - Add servers by scanning QR codes. - Lisää palvelimia skannaamalla QR-koodeja. - No comment provided by engineer. - - - Add server… - Lisää palvelin… - No comment provided by engineer. - - - Add to another device - Lisää toiseen laitteeseen - No comment provided by engineer. - - - Add welcome message - Lisää tervetuloviesti - No comment provided by engineer. - - - Admins can create the links to join groups. - Ylläpitäjät voivat luoda linkkejä ryhmiin liittymiseen. - No comment provided by engineer. - - - Advanced network settings - Verkon lisäasetukset - No comment provided by engineer. - - - All chats and messages will be deleted - this cannot be undone! - Kaikki keskustelut ja viestit poistetaan - tätä ei voi kumota! - No comment provided by engineer. - - - All group members will remain connected. - Kaikki ryhmän jäsenet pysyvät yhteydessä. - No comment provided by engineer. - - - All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. - Kaikki viestit poistetaan - tätä ei voi kumota! Viestit poistuvat VAIN sinulta. - No comment provided by engineer. - - - All your contacts will remain connected - No comment provided by engineer. - - - Allow - Salli - No comment provided by engineer. - - - Allow disappearing messages only if your contact allows it to you. - Salli katoavat viestit vain, jos kontaktisi sallii sen sinulle. - No comment provided by engineer. - - - Allow irreversible message deletion only if your contact allows it to you. - Salli peruuttamaton viestien poisto vain, jos kontaktisi sallii ne sinulle. - No comment provided by engineer. - - - Allow sending direct messages to members. - Salli yksityisviestien lähettäminen jäsenille. - No comment provided by engineer. - - - Allow sending disappearing messages. - Salli katoavien viestien lähettäminen. - No comment provided by engineer. - - - Allow to irreversibly delete sent messages. - Salli lähetettyjen viestien peruuttamaton poistaminen. - No comment provided by engineer. - - - Allow to send voice messages. - Salli ääniviestien lähettäminen. - No comment provided by engineer. - - - Allow voice messages only if your contact allows them. - Salli ääniviestit vain, jos kontaktisi sallii ne. - No comment provided by engineer. - - - Allow voice messages? - Salli ääniviestit? - No comment provided by engineer. - - - Allow your contacts to irreversibly delete sent messages. - Salli kontaktiesi poistaa lähetetyt viestit peruuttamattomasti. - No comment provided by engineer. - - - Allow your contacts to send disappearing messages. - Salli kontaktiesi lähettää katoavia viestejä. - No comment provided by engineer. - - - Allow your contacts to send voice messages. - Salli kontaktiesi lähettää ääniviestejä. - No comment provided by engineer. - - - Already connected? - Oletko jo muodostanut yhteyden? - No comment provided by engineer. - - - Always use relay - Käytä aina relettä - No comment provided by engineer. - - - Answer call - Vastaa puheluun - No comment provided by engineer. - - - App build: %@ - Sovellusversio: %@ - No comment provided by engineer. - - - App icon - Sovelluksen kuvake - No comment provided by engineer. - - - App version - Sovellusversio - No comment provided by engineer. - - - App version: v%@ - Sovellusversio: v%@ - No comment provided by engineer. - - - Appearance - Ulkonäkö - No comment provided by engineer. - - - Attach - Liitä - No comment provided by engineer. - - - Audio & video calls - Ääni- ja videopuhelut - No comment provided by engineer. - - - Audio and video calls - Ääni- ja videopuhelut - No comment provided by engineer. - - - Authentication failed - Tunnistautuminen epäonnistui - No comment provided by engineer. - - - Authentication is required before the call is connected, but you may miss calls. - Tunnistautuminen vaaditaan ennen kuin puhelu yhdistetään, mutta puheluita voi jäädä vastaamatta. - No comment provided by engineer. - - - Authentication unavailable - Tunnistautuminen ei ole käytettävissä - No comment provided by engineer. - - - Auto-accept contact requests - Hyväksy yhteydenottopyynnöt automaattisesti - No comment provided by engineer. - - - Auto-accept images - Hyväksy kuvat automaattisesti - No comment provided by engineer. - - - Automatically - No comment provided by engineer. - - - Back - Takaisin - No comment provided by engineer. - - - Both you and your contact can irreversibly delete sent messages. - Sekä sinä että kontaktisi voitte peruuttamattomasti poistaa lähetetyt viestit. - No comment provided by engineer. - - - Both you and your contact can send disappearing messages. - Sekä sinä että kontaktisi voitte lähettää katoavia viestejä. - No comment provided by engineer. - - - Both you and your contact can send voice messages. - Sekä sinä että kontaktisi voitte lähettää ääniviestejä. - 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). - Chat-profiilin mukaan (oletus) tai [yhteyden mukaan](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). - No comment provided by engineer. - - - Call already ended! - Puhelu on jo päättynyt! - No comment provided by engineer. - - - Calls - Puhelut - No comment provided by engineer. - - - Can't delete user profile! - Käyttäjäprofiilia ei voi poistaa! - No comment provided by engineer. - - - Can't invite contact! - Kontaktia ei voi kutsua! - No comment provided by engineer. - - - Can't invite contacts! - Kontakteja ei voi kutsua! - No comment provided by engineer. - - - Cancel - Peruuta - No comment provided by engineer. - - - Cannot access keychain to save database password - Ei pääsyä avainnippuun tietokannan salasanan tallentamiseksi - No comment provided by engineer. - - - Cannot receive file - Tiedostoa ei voi vastaanottaa - No comment provided by engineer. - - - Change - Muuta - No comment provided by engineer. - - - Change database passphrase? - Muutetaanko tietokannan tunnuslause? - No comment provided by engineer. - - - Change member role? - Vaihda jäsenroolia? - No comment provided by engineer. - - - Change receiving address - Vaihda vastaanotto-osoitetta - No comment provided by engineer. - - - Change receiving address? - Vaihda vastaanotto-osoite? - No comment provided by engineer. - - - Change role - Vaihda rooli - No comment provided by engineer. - - - Chat archive - Chat-arkisto - No comment provided by engineer. - - - Chat console - Chat-konsoli - No comment provided by engineer. - - - Chat database - Chat-tietokanta - No comment provided by engineer. - - - Chat database deleted - Chat-tietokanta poistettu - No comment provided by engineer. - - - Chat database imported - Chat-tietokanta tuotu - No comment provided by engineer. - - - Chat is running - Chat on käynnissä - No comment provided by engineer. - - - Chat is stopped - Chat on pysäytetty - No comment provided by engineer. - - - Chat preferences - Chat-asetukset - No comment provided by engineer. - - - Chats - Keskustelut - No comment provided by engineer. - - - Check server address and try again. - Tarkista palvelimen osoite ja yritä uudelleen. - No comment provided by engineer. - - - Chinese and Spanish interface - Kiinalainen ja espanjalainen käyttöliittymä - No comment provided by engineer. - - - Choose file - Valitse tiedosto - No comment provided by engineer. - - - Choose from library - Valitse kirjastosta - No comment provided by engineer. - - - Clear - Tyhjennä - No comment provided by engineer. - - - Clear conversation - Tyhjennä keskustelu - No comment provided by engineer. - - - Clear conversation? - Tyhjennä keskustelu? - No comment provided by engineer. - - - Clear verification - Tyhjennä vahvistus - No comment provided by engineer. - - - Colors - Värit - No comment provided by engineer. - - - Compare security codes with your contacts. - Vertaa turvakoodeja kontaktiesi kanssa. - No comment provided by engineer. - - - Configure ICE servers - Määritä ICE-palvelimet - No comment provided by engineer. - - - Confirm - Vahvista - No comment provided by engineer. - - - Confirm new passphrase… - Vahvista uusi tunnuslause… - No comment provided by engineer. - - - Confirm password - Vahvista salasana - No comment provided by engineer. - - - Connect - Yhdistä - server test step - - - Connect via contact link? - Yhdistetäänkö kontaktilinkin kautta? - No comment provided by engineer. - - - Connect via group link? - Yhdistetäänkö ryhmälinkin kautta? - No comment provided by engineer. - - - Connect via link - Yhdistä linkin kautta - No comment provided by engineer. - - - Connect via link / QR code - Yhdistä linkillä / QR-koodilla - No comment provided by engineer. - - - Connect via one-time link? - Yhdistä kertalinkillä? - No comment provided by engineer. - - - Connecting to server… - Yhteyden muodostaminen palvelimeen… - No comment provided by engineer. - - - Connecting to server… (error: %@) - Yhteyden muodostaminen palvelimeen... (virhe: %@) - No comment provided by engineer. - - - Connection - Yhteys - No comment provided by engineer. - - - Connection error - Yhteysvirhe - No comment provided by engineer. - - - Connection error (AUTH) - Yhteysvirhe (AUTH) - No comment provided by engineer. - - - Connection request - Yhteyspyyntö - No comment provided by engineer. - - - Connection request sent! - Yhteyspyyntö lähetetty! - No comment provided by engineer. - - - Connection timeout - Yhteyden aikakatkaisu - No comment provided by engineer. - - - Contact allows - Kontakti sallii - No comment provided by engineer. - - - Contact already exists - Kontakti on jo olemassa - No comment provided by engineer. - - - Contact and all messages will be deleted - this cannot be undone! - Kontakti ja kaikki viestit poistetaan - tätä ei voi perua! - No comment provided by engineer. - - - Contact hidden: - Kontakti piilotettu: - notification - - - Contact is connected - Kontakti on yhdistetty - notification - - - Contact is not connected yet! - Kontaktia ei ole vielä yhdistetty! - No comment provided by engineer. - - - Contact name - Kontaktin nimi - No comment provided by engineer. - - - Contact preferences - Kontaktin asetukset - No comment provided by engineer. - - - Contact requests - No comment provided by engineer. - - - Contacts can mark messages for deletion; you will be able to view them. - Kontaktit voivat merkitä viestit poistettaviksi; voit katsella niitä. - No comment provided by engineer. - - - Copy - Kopioi - chat item action - - - Core built at: %@ - No comment provided by engineer. - - - Core version: v%@ - Ydinversio: v%@ - No comment provided by engineer. - - - Create - Luo - No comment provided by engineer. - - - Create address - No comment provided by engineer. - - - Create group link - Luo ryhmälinkki - No comment provided by engineer. - - - Create link - Luo linkki - No comment provided by engineer. - - - Create one-time invitation link - Luo kertakutsulinkki - No comment provided by engineer. - - - Create queue - Luo jono - server test step - - - Create secret group - Luo salainen ryhmä - No comment provided by engineer. - - - Create your profile - Luo profiilisi - No comment provided by engineer. - - - Created on %@ - Luotu %@ - No comment provided by engineer. - - - Current passphrase… - Nykyinen tunnuslause… - No comment provided by engineer. - - - Currently maximum supported file size is %@. - Nykyinen tuettu enimmäistiedostokoko on %@. - No comment provided by engineer. - - - Dark - Tumma - No comment provided by engineer. - - - Database ID - Tietokannan tunnus - No comment provided by engineer. - - - Database encrypted! - Tietokanta salattu! - No comment provided by engineer. - - - Database encryption passphrase will be updated and stored in the keychain. - - Tietokannan salaustunnuslause päivitetään ja tallennetaan avainnippuun. - - No comment provided by engineer. - - - Database encryption passphrase will be updated. - - Tietokannan salauksen tunnuslause päivitetään. - - No comment provided by engineer. - - - Database error - Tietokantavirhe - No comment provided by engineer. - - - Database is encrypted using a random passphrase, you can change it. - Tietokanta on salattu satunnaisella tunnuslauseella, voit muuttaa sitä. - No comment provided by engineer. - - - Database is encrypted using a random passphrase. Please change it before exporting. - Tietokanta on salattu satunnaisella tunnuslauseella. Vaihda se ennen vientiä. - No comment provided by engineer. - - - Database passphrase - Tietokannan tunnuslause - No comment provided by engineer. - - - Database passphrase & export - Tietokannan tunnuslause ja vienti - No comment provided by engineer. - - - Database passphrase is different from saved in the keychain. - Tietokannan tunnuslause eroaa avainnippuun tallennetusta. - No comment provided by engineer. - - - Database passphrase is required to open chat. - Keskustelun avaamiseen tarvitaan tietokannan tunnuslause. - No comment provided by engineer. - - - Database will be encrypted and the passphrase stored in the keychain. - - Tietokanta salataan ja tunnuslause tallennetaan avainnippuun. - - No comment provided by engineer. - - - Database will be encrypted. - - Tietokanta salataan. - - No comment provided by engineer. - - - Database will be migrated when the app restarts - Tietokanta siirretään, kun sovellus käynnistyy uudelleen - No comment provided by engineer. - - - Decentralized - Hajautettu - No comment provided by engineer. - - - Delete - Poista - chat item action - - - Delete Contact - Poista kontakti - No comment provided by engineer. - - - Delete address - Poista osoite - No comment provided by engineer. - - - Delete address? - Poista osoite? - No comment provided by engineer. - - - Delete after - Poista jälkeen - No comment provided by engineer. - - - Delete all files - Poista kaikki tiedostot - No comment provided by engineer. - - - Delete archive - Poista arkisto - No comment provided by engineer. - - - Delete chat archive? - Poista keskusteluarkisto? - No comment provided by engineer. - - - Delete chat profile? - Poista keskusteluprofiili? - No comment provided by engineer. - - - Delete connection - Poista yhteys - No comment provided by engineer. - - - Delete contact - Poista kontakti - No comment provided by engineer. - - - Delete contact? - Poista kontakti? - No comment provided by engineer. - - - Delete database - Poista tietokanta - No comment provided by engineer. - - - Delete files and media? - Poista tiedostot ja media? - No comment provided by engineer. - - - Delete files for all chat profiles - Poista tiedostot kaikista keskusteluprofiileista - No comment provided by engineer. - - - Delete for everyone - Poista kaikilta - chat feature - - - Delete for me - Poista minulta - No comment provided by engineer. - - - Delete group - Poista ryhmä - No comment provided by engineer. - - - Delete group? - Poista ryhmä? - No comment provided by engineer. - - - Delete invitation - Poista kutsu - No comment provided by engineer. - - - Delete link - Poista linkki - No comment provided by engineer. - - - Delete link? - Poista linkki? - No comment provided by engineer. - - - Delete member message? - Poista jäsenviesti? - No comment provided by engineer. - - - Delete message? - Poista viesti? - No comment provided by engineer. - - - Delete messages - Poista viestit - No comment provided by engineer. - - - Delete messages after - Poista viestit tämän jälkeen - No comment provided by engineer. - - - Delete old database - Poista vanha tietokanta - No comment provided by engineer. - - - Delete old database? - Poista vanha tietokanta? - No comment provided by engineer. - - - Delete pending connection - Poista vireillä oleva yhteys - No comment provided by engineer. - - - Delete pending connection? - Poistetaanko odottava yhteys? - No comment provided by engineer. - - - Delete queue - Poista jono - server test step - - - Delete user profile? - Poista käyttäjäprofiili? - No comment provided by engineer. - - - Description - Kuvaus - No comment provided by engineer. - - - Develop - Kehitä - No comment provided by engineer. - - - Developer tools - Kehittäjätyökalut - No comment provided by engineer. - - - Device - Laite - No comment provided by engineer. - - - Device authentication is disabled. Turning off SimpleX Lock. - Laitteen todennus on poistettu käytöstä. SimpleX Lock kytketään pois päältä. - No comment provided by engineer. - - - Device authentication is not enabled. You can turn on SimpleX Lock via Settings, once you enable device authentication. - Laitteen todennus ei ole käytössä. Voit ottaa SimpleX Lockin käyttöön Asetuksista, kun olet ottanut laitteen todennuksen käyttöön. - No comment provided by engineer. - - - Different names, avatars and transport isolation. - Eri nimet, avatarit ja kuljetuseristys. - No comment provided by engineer. - - - Direct messages - Yksityisviestit - chat feature - - - Direct messages between members are prohibited in this group. - Yksityisviestit jäsenten välillä ovat kiellettyjä tässä ryhmässä. - No comment provided by engineer. - - - Disable SimpleX Lock - Poista SimpleX Lock käytöstä - authentication reason - - - Disappearing messages - Tuhoutuvat viestit - chat feature - - - Disappearing messages are prohibited in this chat. - Katoavat viestit ovat kiellettyjä tässä keskustelussa. - No comment provided by engineer. - - - Disappearing messages are prohibited in this group. - Katoavat viestit ovat kiellettyjä tässä ryhmässä. - No comment provided by engineer. - - - Disconnect - Katkaise - server test step - - - Display name - Näyttönimi - No comment provided by engineer. - - - Display name: - Näyttönimi: - No comment provided by engineer. - - - Do NOT use SimpleX for emergency calls. - Älä käytä SimpleX-sovellusta hätäpuheluihin. - No comment provided by engineer. - - - Do it later - Tee myöhemmin - No comment provided by engineer. - - - Don't show again - Älä näytä uudelleen - No comment provided by engineer. - - - Duplicate display name! - Päällekkäinen näyttönimi! - No comment provided by engineer. - - - Edit - Muokkaa - chat item action - - - Edit group profile - Muokkaa ryhmäprofiilia - No comment provided by engineer. - - - Enable - Salli - No comment provided by engineer. - - - Enable SimpleX Lock - Ota SimpleX Lock käyttöön - authentication reason - - - Enable TCP keep-alive - Ota TCP-säilytys käyttöön - No comment provided by engineer. - - - Enable automatic message deletion? - Ota automaattinen viestien poisto käyttöön? - No comment provided by engineer. - - - Enable instant notifications? - Salli välittömät ilmoitukset? - No comment provided by engineer. - - - Enable notifications - Salli ilmoitukset - No comment provided by engineer. - - - Enable periodic notifications? - Salli säännölliset ilmoitukset? - No comment provided by engineer. - - - Encrypt - Salaa - No comment provided by engineer. - - - Encrypt database? - Salaa tietokanta? - No comment provided by engineer. - - - Encrypted database - Salattu tietokanta - No comment provided by engineer. - - - Encrypted message or another event - Salattu viesti tai muu tapahtuma - notification - - - Encrypted message: database error - Salattu viesti: tietokantavirhe - notification - - - Encrypted message: keychain error - Salattu viesti: avainnipun virhe - notification - - - Encrypted message: no passphrase - Salattu viesti: ei tunnuslausetta - notification - - - Encrypted message: unexpected error - Salattu viesti: odottamaton virhe - notification - - - Enter correct passphrase. - Anna oikea tunnuslause. - No comment provided by engineer. - - - Enter passphrase… - Syötä tunnuslause… - No comment provided by engineer. - - - Enter password above to show! - Kirjoita yllä oleva salasana näyttääksesi! - No comment provided by engineer. - - - Enter server manually - Syötä palvelin manuaalisesti - No comment provided by engineer. - - - Error - Virhe - No comment provided by engineer. - - - Error accepting contact request - Virhe kontaktipyynnön hyväksymisessä - No comment provided by engineer. - - - Error accessing database file - Virhe tietokantatiedoston käyttämisessä - No comment provided by engineer. - - - Error adding member(s) - Virhe lisättäessä jäseniä - No comment provided by engineer. - - - Error changing address - Virhe osoitteenvaihdossa - No comment provided by engineer. - - - Error changing role - Virhe roolin vaihdossa - No comment provided by engineer. - - - Error changing setting - Virhe asetuksen muuttamisessa - No comment provided by engineer. - - - Error creating address - Virhe osoitteen luomisessa - No comment provided by engineer. - - - Error creating group - Virhe ryhmän luomisessa - No comment provided by engineer. - - - Error creating group link - Virhe ryhmälinkin luomisessa - No comment provided by engineer. - - - Error creating profile! - Virhe profiilin luomisessa! - No comment provided by engineer. - - - Error deleting chat database - Virhe keskustelujen tietokannan poistamisessa - No comment provided by engineer. - - - Error deleting chat! - Virhe keskutelun poistamisessa! - No comment provided by engineer. - - - Error deleting connection - Virhe yhteyden poistamisessa - No comment provided by engineer. - - - Error deleting contact - Virhe kontaktin poistamisessa - No comment provided by engineer. - - - Error deleting database - Virhe tietokannan poistamisessa - No comment provided by engineer. - - - Error deleting old database - Virhe vanhan tietokannan poistamisessa - No comment provided by engineer. - - - Error deleting token - Virhe tokenin poistamisessa - No comment provided by engineer. - - - Error deleting user profile - Virhe käyttäjäprofiilin poistamisessa - No comment provided by engineer. - - - Error enabling notifications - Virhe ilmoitusten käyttöönotossa - No comment provided by engineer. - - - Error encrypting database - Virhe tietokannan salauksessa - No comment provided by engineer. - - - Error exporting chat database - Virhe vietäessä keskustelujen tietokantaa - No comment provided by engineer. - - - Error importing chat database - Virhe keskustelujen tietokannan tuonnissa - No comment provided by engineer. - - - Error joining group - Virhe ryhmään liittymisessä - No comment provided by engineer. - - - Error receiving file - Virhe tiedoston vastaanottamisessa - No comment provided by engineer. - - - Error removing member - Virhe poistettaessa jäsentä - No comment provided by engineer. - - - Error saving ICE servers - Virhe ICE-palvelimien tallentamisessa - No comment provided by engineer. - - - Error saving SMP servers - No comment provided by engineer. - - - Error saving group profile - Virhe ryhmäprofiilin tallentamisessa - No comment provided by engineer. - - - Error saving passphrase to keychain - Virhe tunnuslauseen tallentamisessa avainnippuun - No comment provided by engineer. - - - Error saving user password - Virhe käyttäjän salasanan tallentamisessa - No comment provided by engineer. - - - Error sending message - Virhe viestin lähettämisessä - No comment provided by engineer. - - - Error starting chat - Virhe käynnistettäessä keskustelua - No comment provided by engineer. - - - Error stopping chat - Virhe keskustelun lopettamisessa - No comment provided by engineer. - - - Error switching profile! - Virhe profiilin vaihdossa! - No comment provided by engineer. - - - Error updating group link - Virhe ryhmälinkin päivittämisessä - No comment provided by engineer. - - - Error updating message - Virhe viestin päivityksessä - No comment provided by engineer. - - - Error updating settings - Virhe asetusten päivittämisessä - No comment provided by engineer. - - - Error updating user privacy - Virhe päivitettäessä käyttäjän tietosuojaa - No comment provided by engineer. - - - Error: %@ - Virhe: %@ - No comment provided by engineer. - - - Error: URL is invalid - Virhe: URL on virheellinen - No comment provided by engineer. - - - Error: no database file - Virhe: ei tietokantatiedostoa - No comment provided by engineer. - - - Exit without saving - Poistu tallentamatta - No comment provided by engineer. - - - Export database - Vie tietokanta - No comment provided by engineer. - - - Export error: - Vientivirhe: - No comment provided by engineer. - - - Exported database archive. - Viety tietokanta-arkisto. - No comment provided by engineer. - - - Exporting database archive... - No comment provided by engineer. - - - Failed to remove passphrase - Tunnuslauseen poisto epäonnistui - No comment provided by engineer. - - - File will be received when your contact is online, please wait or check later! - Tiedosto vastaanotetaan, kun kontakti on online-tilassa, odota tai tarkista myöhemmin! - No comment provided by engineer. - - - File: %@ - Tiedosto: %@ - No comment provided by engineer. - - - Files & media - Tiedostot & media - No comment provided by engineer. - - - For console - Konsoliin - No comment provided by engineer. - - - French interface - Ranskalainen käyttöliittymä - No comment provided by engineer. - - - Full link - Koko linkki - No comment provided by engineer. - - - Full name (optional) - Koko nimi (valinnainen) - No comment provided by engineer. - - - Full name: - Koko nimi: - No comment provided by engineer. - - - Fully re-implemented - work in background! - Täysin uudistettu - toimii taustalla! - No comment provided by engineer. - - - Further reduced battery usage - Entistä pienempi akun käyttö - No comment provided by engineer. - - - GIFs and stickers - GIFit ja tarrat - No comment provided by engineer. - - - Group - Ryhmä - No comment provided by engineer. - - - Group display name - Ryhmän näyttönimi - No comment provided by engineer. - - - Group full name (optional) - Ryhmän näyttönimi (valinnainen) - No comment provided by engineer. - - - Group image - Ryhmäkuva - No comment provided by engineer. - - - Group invitation - Ryhmän kutsu - No comment provided by engineer. - - - Group invitation expired - Vanhentunut ryhmäkutsu - No comment provided by engineer. - - - Group invitation is no longer valid, it was removed by sender. - Ryhmäkutsu ei ole enää voimassa, lähettäjä poisti sen. - No comment provided by engineer. - - - Group link - Ryhmälinkki - No comment provided by engineer. - - - Group links - Ryhmälinkit - No comment provided by engineer. - - - Group members can irreversibly delete sent messages. - Ryhmän jäsenet voivat poistaa lähetetyt viestit peruuttamattomasti. - No comment provided by engineer. - - - Group members can send direct messages. - Ryhmän jäsenet voivat lähettää suoraviestejä. - No comment provided by engineer. - - - Group members can send disappearing messages. - Ryhmän jäsenet voivat lähettää katoavia viestejä. - No comment provided by engineer. - - - Group members can send voice messages. - Ryhmän jäsenet voivat lähettää ääniviestejä. - No comment provided by engineer. - - - Group message: - Ryhmäviesti: - notification - - - Group moderation - Ryhmän moderointi - No comment provided by engineer. - - - Group preferences - Ryhmän asetukset - No comment provided by engineer. - - - Group profile - Ryhmäprofiili - No comment provided by engineer. - - - Group profile is stored on members' devices, not on the servers. - Ryhmäprofiili tallennetaan jäsenten laitteille, ei palvelimille. - No comment provided by engineer. - - - Group welcome message - Ryhmän tervetuloviesti - No comment provided by engineer. - - - Group will be deleted for all members - this cannot be undone! - Ryhmä poistetaan kaikilta jäseniltä - tätä ei voi kumota! - No comment provided by engineer. - - - Group will be deleted for you - this cannot be undone! - Ryhmä poistetaan sinulta - tätä ei voi perua! - No comment provided by engineer. - - - Help - Apua - No comment provided by engineer. - - - Hidden - Piilotettu - No comment provided by engineer. - - - Hidden chat profiles - Piilotetut keskusteluprofiilit - No comment provided by engineer. - - - Hidden profile password - Piilotettu profiilin salasana - No comment provided by engineer. - - - Hide - Piilota - chat item action - - - Hide app screen in the recent apps. - Piilota sovellusnäyttö viimeisimmissä sovelluksissa. - No comment provided by engineer. - - - Hide profile - Piilota profiili - No comment provided by engineer. - - - How SimpleX works - Miten SimpleX toimii - No comment provided by engineer. - - - How it works - Kuinka se toimii - No comment provided by engineer. - - - How to - Miten - No comment provided by engineer. - - - How to use it - Kuinka sitä käytetään - No comment provided by engineer. - - - How to use your servers - Miten käytät palvelimiasi - No comment provided by engineer. - - - ICE servers (one per line) - ICE-palvelimet (yksi per rivi) - No comment provided by engineer. - - - If you can't meet in person, **show QR code in the video call**, or share the link. - No comment provided by engineer. - - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Jos et voi tavata henkilökohtaisesti, voit **skannata QR-koodin videopuhelussa** tai kontaktisi voi jakaa kutsulinkin. - No comment provided by engineer. - - - If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app). - Jos haluat käyttää keskustelua nyt, napauta **Tee se myöhemmin** alla (sinulle tarjotaan tietokannan siirtämistä, kun käynnistät sovelluksen uudelleen). - No comment provided by engineer. - - - Ignore - Sivuuta - No comment provided by engineer. - - - Image will be received when your contact is online, please wait or check later! - Kuva vastaanotetaan, kun kontaktisi on verkossa, odota tai tarkista myöhemmin! - No comment provided by engineer. - - - Immune to spam and abuse - Immuuni roskapostille ja väärinkäytöksille - No comment provided by engineer. - - - Import - Tuo - No comment provided by engineer. - - - Import chat database? - Tuo keskustelujen-tietokanta? - No comment provided by engineer. - - - Import database - Tuo tietokanta - No comment provided by engineer. - - - Improved privacy and security - Parannettu yksityisyys ja turvallisuus - No comment provided by engineer. - - - Improved server configuration - Parannettu palvelimen kokoonpano - No comment provided by engineer. - - - Incognito - Incognito - No comment provided by engineer. - - - Incognito mode - Incognito-tila - No comment provided by engineer. - - - Incognito mode is not supported here - your main profile will be sent to group members - No comment provided by engineer. - - - Incognito mode protects the privacy of your main profile name and image — for each new contact a new random profile is created. - No comment provided by engineer. - - - Incoming audio call - Saapuva äänipuhelu - notification - - - Incoming call - Saapuva puhelu - notification - - - Incoming video call - Saapuva videopuhelu - notification - - - Incorrect security code! - Väärä turvakoodi! - No comment provided by engineer. - - - Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat) - Asenna [SimpleX Chat terminaalille](https://github.com/simplex-chat/simplex-chat) - No comment provided by engineer. - - - Instant push notifications will be hidden! - - Välittömät push-ilmoitukset ovat piilossa! - - No comment provided by engineer. - - - Instantly - Heti - No comment provided by engineer. - - - Interface - Käyttöliittymä - No comment provided by engineer. - - - Invalid connection link - Virheellinen yhteyslinkki - No comment provided by engineer. - - - Invalid server address! - Virheellinen palvelinosoite! - No comment provided by engineer. - - - Invitation expired! - Vanhentunut kutsu! - No comment provided by engineer. - - - Invite members - Kutsu jäseniä - No comment provided by engineer. - - - Invite to group - Kutsu ryhmään - No comment provided by engineer. - - - Irreversible message deletion - Peruuttamaton viestin poisto - No comment provided by engineer. - - - Irreversible message deletion is prohibited in this chat. - Viestien peruuttamaton poisto on kielletty tässä keskustelussa. - No comment provided by engineer. - - - Irreversible message deletion is prohibited in this group. - Viestien peruuttamaton poisto on kielletty tässä ryhmässä. - No comment provided by engineer. - - - It allows having many anonymous connections without any shared data between them in a single chat profile. - Se mahdollistaa useiden nimettömien yhteyksien muodostamisen yhdessä keskusteluprofiilissa ilman, että niiden välillä on jaettuja tietoja. - No comment provided by engineer. - - - It can happen when: -1. The messages expire on the server if they were not received for 30 days, -2. The server you use to receive the messages from this contact was updated and restarted. -3. The connection is compromised. -Please connect to the developers via Settings to receive the updates about the servers. -We will be adding server redundancy to prevent lost messages. - 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 (%@). - Näyttäisi, että olet jo yhteydessä tämän linkin kautta. Jos näin ei ole, tapahtui virhe (%@). - No comment provided by engineer. - - - Italian interface - Italialainen käyttöliittymä - No comment provided by engineer. - - - Join - Liity - No comment provided by engineer. - - - Join group - Liity ryhmään - No comment provided by engineer. - - - Join incognito - Liity incognito-tilassa - No comment provided by engineer. - - - Joining group - Liittyy ryhmään - No comment provided by engineer. - - - Keychain error - Avainnipun virhe - No comment provided by engineer. - - - LIVE - LIVE - No comment provided by engineer. - - - Large file! - Suuri tiedosto! - No comment provided by engineer. - - - Leave - Poistu - No comment provided by engineer. - - - Leave group - Poistu ryhmästä - No comment provided by engineer. - - - Leave group? - Poistu ryhmästä? - No comment provided by engineer. - - - Light - Vaalea - No comment provided by engineer. - - - Limitations - Rajoitukset - No comment provided by engineer. - - - Live message! - Live-viesti! - No comment provided by engineer. - - - Live messages - Live-viestit - No comment provided by engineer. - - - Local name - Paikallinen nimi - No comment provided by engineer. - - - Local profile data only - Vain paikalliset profiilitiedot - No comment provided by engineer. - - - Make a private connection - Luo yksityinen yhteys - No comment provided by engineer. - - - Make profile private! - Tee profiilista yksityinen! - No comment provided by engineer. - - - Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@). - No comment provided by engineer. - - - Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated. - Varmista, että WebRTC ICE -palvelinosoitteet ovat oikeassa muodossa, rivieroteltuina ja että ne eivät ole päällekkäisiä. - No comment provided by engineer. - - - Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?* - Monet ihmiset kysyivät: *Jos SimpleX:llä ei ole käyttäjätunnuksia, miten se voi toimittaa viestejä?* - No comment provided by engineer. - - - Mark deleted for everyone - Merkitse poistetuksi kaikilta - No comment provided by engineer. - - - Mark read - Merkitse luetuksi - No comment provided by engineer. - - - Mark verified - Merkitse vahvistetuksi - No comment provided by engineer. - - - Markdown in messages - Markdown viesteissä - No comment provided by engineer. - - - Max 30 seconds, received instantly. - Enintään 30 sekuntia, vastaanotetaan välittömästi. - No comment provided by engineer. - - - Member - Jäsen - No comment provided by engineer. - - - Member role will be changed to "%@". All group members will be notified. - Jäsenen rooli muuttuu muotoon "%@". Kaikille ryhmän jäsenille ilmoitetaan asiasta. - No comment provided by engineer. - - - Member role will be changed to "%@". The member will receive a new invitation. - Jäsenen rooli muutetaan muotoon "%@". Jäsen saa uuden kutsun. - No comment provided by engineer. - - - Member will be removed from group - this cannot be undone! - Jäsen poistetaan ryhmästä - tätä ei voi perua! - No comment provided by engineer. - - - Message delivery error - Viestin toimitusvirhe - No comment provided by engineer. - - - Message draft - Viestiluonnos - No comment provided by engineer. - - - Message text - Viestin teksti - No comment provided by engineer. - - - Messages - Viestit - No comment provided by engineer. - - - Migrating database archive... - No comment provided by engineer. - - - Migration error: - Siirtovirhe: - No comment provided by engineer. - - - Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat). - Siirto epäonnistui. Jatka nykyisen tietokannan käyttöä napauttamalla alla **Poistu**. Ilmoita ongelmasta sovelluskehittäjille keskustelussa tai sähköpostitse [chat@simplex.chat](mailto:chat@simplex.chat). - No comment provided by engineer. - - - Migration is completed - Siirto on valmis - No comment provided by engineer. - - - Moderate - Moderoi - chat item action - - - More improvements are coming soon! - Lisää parannuksia on tulossa pian! - No comment provided by engineer. - - - Most likely this contact has deleted the connection with you. - Todennäköisesti tämä kontakti on poistanut yhteyden sinuun. - No comment provided by engineer. - - - Multiple chat profiles - Useita keskusteluprofiileja - No comment provided by engineer. - - - Mute - Mykistä - No comment provided by engineer. - - - Muted when inactive! - Mykistetty ei-aktiivisena! - No comment provided by engineer. - - - Name - Nimi - No comment provided by engineer. - - - Network & servers - Verkko ja palvelimet - No comment provided by engineer. - - - Network settings - Verkkoasetukset - No comment provided by engineer. - - - Network status - Verkon tila - No comment provided by engineer. - - - New contact request - Uusi kontaktipyyntö - notification - - - New contact: - Uusi kontakti: - notification - - - New database archive - Uusi tietokanta-arkisto - No comment provided by engineer. - - - New in %@ - Uutta %@ - No comment provided by engineer. - - - New member role - Uusi jäsenrooli - No comment provided by engineer. - - - New message - Uusi viesti - notification - - - New passphrase… - Uusi tunnuslause… - No comment provided by engineer. - - - No - Ei - No comment provided by engineer. - - - No contacts selected - Kontakteja ei ole valittu - No comment provided by engineer. - - - No contacts to add - Ei lisättäviä kontakteja - No comment provided by engineer. - - - No device token! - Ei laitetunnusta! - No comment provided by engineer. - - - Group not found! - Ryhmää ei löydy! - No comment provided by engineer. - - - No permission to record voice message - Ei lupaa ääniviestin tallentamiseen - No comment provided by engineer. - - - No received or sent files - Ei vastaanotettuja tai lähetettyjä tiedostoja - No comment provided by engineer. - - - Notifications - Ilmoitukset - No comment provided by engineer. - - - Notifications are disabled! - Ilmoitukset on poistettu käytöstä! - No comment provided by engineer. - - - Now admins can: -- delete members' messages. -- disable members ("observer" role) - Nyt järjestelmänvalvojat voivat: -- poistaa jäsenten viestit. -- poista jäsenet käytöstä ("tarkkailija" rooli) - No comment provided by engineer. - - - Off (Local) - Pois (Paikallinen) - No comment provided by engineer. - - - Ok - Ok - No comment provided by engineer. - - - Old database - Vanha tietokanta - No comment provided by engineer. - - - Old database archive - Vanha tietokanta-arkisto - No comment provided by engineer. - - - One-time invitation link - Kertakutsulinkki - No comment provided by engineer. - - - Onion hosts will be required for connection. Requires enabling VPN. - Yhteyden muodostamiseen tarvitaan Onion-isäntiä. Edellyttää VPN:n sallimista. - No comment provided by engineer. - - - Onion hosts will be used when available. Requires enabling VPN. - Onion-isäntiä käytetään, kun niitä on saatavilla. Edellyttää VPN:n sallimista. - No comment provided by engineer. - - - Onion hosts will not be used. - Onion-isäntiä ei käytetä. - No comment provided by engineer. - - - Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**. - Vain asiakaslaitteet tallentavat käyttäjäprofiileja, yhteystietoja, ryhmiä ja viestejä, jotka on lähetetty **kaksinkertaisella päästä päähän -salauksella**. - No comment provided by engineer. - - - Only group owners can change group preferences. - Vain ryhmän omistajat voivat muuttaa ryhmän asetuksia. - No comment provided by engineer. - - - Only group owners can enable voice messages. - Vain ryhmän omistajat voivat ottaa ääniviestit käyttöön. - No comment provided by engineer. - - - Only you can irreversibly delete messages (your contact can mark them for deletion). - Vain sinä voit poistaa viestejä peruuttamattomasti (kontaktisi voi merkitä ne poistettavaksi). - No comment provided by engineer. - - - Only you can send disappearing messages. - Vain sinä voit lähettää katoavia viestejä. - No comment provided by engineer. - - - Only you can send voice messages. - Vain sinä voit lähettää ääniviestejä. - No comment provided by engineer. - - - Only your contact can irreversibly delete messages (you can mark them for deletion). - Vain kontaktisi voi poistaa viestejä peruuttamattomasti (voit merkitä ne poistettavaksi). - No comment provided by engineer. - - - Only your contact can send disappearing messages. - Vain kontaktisi voi lähettää katoavia viestejä. - No comment provided by engineer. - - - Only your contact can send voice messages. - Vain kontaktisi voi lähettää ääniviestejä. - No comment provided by engineer. - - - Open Settings - Avaa Asetukset - No comment provided by engineer. - - - Open chat - Avaa keskustelu - No comment provided by engineer. - - - Open chat console - Avaa keskustelukonsoli - authentication reason - - - Open user profiles - Avaa käyttäjäprofiilit - authentication reason - - - Open-source protocol and code – anybody can run the servers. - Avoimen lähdekoodin protokolla ja koodi - kuka tahansa voi käyttää palvelimia. - No comment provided by engineer. - - - Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. - Linkin avaaminen selaimessa voi heikentää yhteyden yksityisyyttä ja turvallisuutta. Epäluotetut SimpleX-linkit näkyvät punaisina. - No comment provided by engineer. - - - PING count - PING-määrä - No comment provided by engineer. - - - PING interval - PING-väli - No comment provided by engineer. - - - Password to show - Salasana näytettäväksi - No comment provided by engineer. - - - Paste - Liitä - No comment provided by engineer. - - - Paste image - Liitä kuva - No comment provided by engineer. - - - Paste received link - Liitä vastaanotettu linkki - No comment provided by engineer. - - - Paste the link you received into the box below to connect with your contact. - No comment provided by engineer. - - - People can connect to you only via the links you share. - Ihmiset voivat ottaa sinuun yhteyttä vain jakamiesi linkkien kautta. - No comment provided by engineer. - - - Periodically - Ajoittain - No comment provided by engineer. - - - Please ask your contact to enable sending voice messages. - Pyydä kontaktiasi sallimaan ääniviestien lähettäminen. - No comment provided by engineer. - - - Please check that you used the correct link or ask your contact to send you another one. - Tarkista, että käytit oikeaa linkkiä tai pyydä kontaktiasi lähettämään sinulle uusi linkki. - No comment provided by engineer. - - - Please check your network connection with %@ and try again. - Tarkista verkkoyhteytesi %@:lla ja yritä uudelleen. - No comment provided by engineer. - - - Please check yours and your contact preferences. - Tarkista omasi ja kontaktin asetukset. - No comment provided by engineer. - - - Please contact group admin. - Ota yhteyttä ryhmän ylläpitäjään. - No comment provided by engineer. - - - Please enter correct current passphrase. - Anna oikea nykyinen tunnuslause. - No comment provided by engineer. - - - Please enter the previous password after restoring database backup. This action can not be undone. - Anna edellinen salasana tietokannan varmuuskopion palauttamisen jälkeen. Tätä toimintoa ei voi kumota. - No comment provided by engineer. - - - Please restart the app and migrate the database to enable push notifications. - Käynnistä sovellus uudelleen ja siirrä tietokanta push-ilmoitusten ottamiseksi käyttöön. - No comment provided by engineer. - - - Please store passphrase securely, you will NOT be able to access chat if you lose it. - Säilytä tunnuslause turvallisesti, ET pääse keskusteluihin, jos kadotat sen. - No comment provided by engineer. - - - Please store passphrase securely, you will NOT be able to change it if you lose it. - Säilytä tunnuslause turvallisesti, ET voi muuttaa sitä, jos kadotat sen. - No comment provided by engineer. - - - Possibly, certificate fingerprint in server address is incorrect - Palvelimen osoitteen varmenteen sormenjälki on mahdollisesti virheellinen - server test error - - - Preserve the last message draft, with attachments. - Säilytä viimeinen viestiluonnos liitteineen. - No comment provided by engineer. - - - Preset server - Esiasetettu palvelin - No comment provided by engineer. - - - Preset server address - Esiasetettu palvelimen osoite - No comment provided by engineer. - - - Privacy & security - Yksityisyys ja turvallisuus - No comment provided by engineer. - - - Privacy redefined - Yksityisyys uudelleen määritettynä - No comment provided by engineer. - - - Private filenames - Yksityiset tiedostonimet - No comment provided by engineer. - - - Profile and server connections - Profiili- ja palvelinyhteydet - No comment provided by engineer. - - - Profile image - Profiilikuva - No comment provided by engineer. - - - Prohibit irreversible message deletion. - Estä peruuttamaton viestien poistaminen. - No comment provided by engineer. - - - Prohibit sending direct messages to members. - Estä suorien viestien lähettäminen jäsenille. - No comment provided by engineer. - - - Prohibit sending disappearing messages. - Estä katoavien viestien lähettäminen. - No comment provided by engineer. - - - Prohibit sending voice messages. - Estä ääniviestien lähettäminen. - No comment provided by engineer. - - - Protect app screen - Suojaa sovellusnäyttö - No comment provided by engineer. - - - Protect your chat profiles with a password! - Suojaa keskusteluprofiilisi salasanalla! - No comment provided by engineer. - - - Protocol timeout - Protokollan aikakatkaisu - No comment provided by engineer. - - - Push notifications - Push-ilmoitukset - No comment provided by engineer. - - - Rate the app - Arvioi sovellus - No comment provided by engineer. - - - Read - Lue - No comment provided by engineer. - - - Read more in our GitHub repository. - Lue lisää GitHub-tietovarastostamme. - No comment provided by engineer. - - - Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme). - Lue lisää [GitHub-arkistosta](https://github.com/simplex-chat/simplex-chat#readme). - No comment provided by engineer. - - - Received file event - Tiedoston vastaanottotapahtuma - notification - - - Receiving via - Vastaanotto kautta - No comment provided by engineer. - - - Recipients see updates as you type them. - Vastaanottajat näkevät päivitykset, kun kirjoitat niitä. - No comment provided by engineer. - - - Reduced battery usage - Pienempi akun käyttö - No comment provided by engineer. - - - Reject - Hylkää - reject incoming call via notification - - - Reject contact (sender NOT notified) - No comment provided by engineer. - - - Reject contact request - Hylkää yhteyspyyntö - No comment provided by engineer. - - - Relay server is only used if necessary. Another party can observe your IP address. - Välityspalvelinta käytetään vain tarvittaessa. Toinen osapuoli voi tarkkailla IP-osoitettasi. - No comment provided by engineer. - - - Relay server protects your IP address, but it can observe the duration of the call. - Välityspalvelin suojaa IP-osoitteesi, mutta se voi tarkkailla puhelun kestoa. - No comment provided by engineer. - - - Remove - Poista - No comment provided by engineer. - - - Remove member - Poista jäsen - No comment provided by engineer. - - - Remove member? - Poista jäsen? - No comment provided by engineer. - - - Remove passphrase from keychain? - Poista tunnuslause avainnipusta? - No comment provided by engineer. - - - Reply - Vastaa - chat item action - - - Required - Pakollinen - No comment provided by engineer. - - - Reset - Oletustilaan - No comment provided by engineer. - - - Reset colors - Oletusvärit - No comment provided by engineer. - - - Reset to defaults - Palauta oletusasetukset - No comment provided by engineer. - - - Restart the app to create a new chat profile - Käynnistä sovellus uudelleen uuden keskusteluprofiilin luomiseksi - No comment provided by engineer. - - - Restart the app to use imported chat database - Käynnistä sovellus uudelleen käyttääksesi tuotua keskustelujen-tietokantaa - No comment provided by engineer. - - - Restore - Palauta - No comment provided by engineer. - - - Restore database backup - Palauta tietokannan varmuuskopio - No comment provided by engineer. - - - Restore database backup? - Palauta tietokannan varmuuskopio? - No comment provided by engineer. - - - Restore database error - Virhe tietokannan palauttamisessa - No comment provided by engineer. - - - Reveal - Paljasta - chat item action - - - Revert - Palauta - No comment provided by engineer. - - - Role - Rooli - No comment provided by engineer. - - - Run chat - Käynnistä chat - No comment provided by engineer. - - - SMP servers - SMP-palvelimet - No comment provided by engineer. - - - Save - Tallenna - chat item action - - - Save (and notify contacts) - Tallenna (ja ilmoita kontakteille) - No comment provided by engineer. - - - Save and notify contact - Tallenna ja ilmoita kontaktille - No comment provided by engineer. - - - Save and notify group members - Tallenna ja ilmoita ryhmän jäsenille - No comment provided by engineer. - - - Save and update group profile - Tallenna ja päivitä ryhmäprofiili - No comment provided by engineer. - - - Save archive - Tallenna arkisto - No comment provided by engineer. - - - Save group profile - Tallenna ryhmäprofiili - No comment provided by engineer. - - - Save passphrase and open chat - Tallenna tunnuslause ja avaa keskustelu - No comment provided by engineer. - - - Save passphrase in Keychain - Tallenna tunnuslause Avainnippuun - No comment provided by engineer. - - - Save preferences? - Tallenna asetukset? - No comment provided by engineer. - - - Save profile password - Tallenna profiilin salasana - No comment provided by engineer. - - - Save servers - Tallenna palvelimet - No comment provided by engineer. - - - Save servers? - Tallenna palvelimet? - No comment provided by engineer. - - - Save welcome message? - Tallenna tervetuloviesti? - No comment provided by engineer. - - - Saved WebRTC ICE servers will be removed - Tallennetut WebRTC ICE -palvelimet poistetaan - No comment provided by engineer. - - - Scan QR code - Skannaa QR-koodi - No comment provided by engineer. - - - Scan code - Skannaa koodi - No comment provided by engineer. - - - Scan security code from your contact's app. - Skannaa turvakoodi kontaktisi sovelluksesta. - No comment provided by engineer. - - - Scan server QR code - Skannaa palvelimen QR-koodi - No comment provided by engineer. - - - Search - Haku - No comment provided by engineer. - - - Secure queue - Turvallinen jono - server test step - - - Security assessment - Turvallisuusarviointi - No comment provided by engineer. - - - Security code - Turvakoodi - No comment provided by engineer. - - - Send - Lähetä - No comment provided by engineer. - - - Send a live message - it will update for the recipient(s) as you type it - Lähetä live-viesti - se päivittyy vastaanottajille, kun kirjoitat sitä - No comment provided by engineer. - - - Send direct message - Lähetä yksityisviesti - No comment provided by engineer. - - - Send link previews - Lähetä linkkien esikatselu - No comment provided by engineer. - - - Send live message - Lähetä live-viesti - No comment provided by engineer. - - - Send notifications - Lähetys ilmoitukset - No comment provided by engineer. - - - Send notifications: - Lähetys ilmoitukset: - No comment provided by engineer. - - - Send questions and ideas - Lähetä kysymyksiä ja ideoita - No comment provided by engineer. - - - Send them from gallery or custom keyboards. - Lähetä ne galleriasta tai mukautetuista näppäimistöistä. - No comment provided by engineer. - - - Sender cancelled file transfer. - Lähettäjä peruutti tiedoston siirron. - No comment provided by engineer. - - - Sender may have deleted the connection request. - Lähettäjä on saattanut poistaa yhteyspyynnön. - No comment provided by engineer. - - - Sending via - Lähetetään kautta - No comment provided by engineer. - - - Sent file event - Lähetetty tiedosto tapahtuma - notification - - - Sent messages will be deleted after set time. - Lähetetyt viestit poistetaan asetetun ajan kuluttua. - No comment provided by engineer. - - - Server requires authorization to create queues, check password - Palvelin vaatii valtuutuksen jonojen luomiseen, tarkista salasana - server test error - - - Server test failed! - Palvelintesti epäonnistui! - No comment provided by engineer. - - - Servers - Palvelimet - No comment provided by engineer. - - - Set 1 day - Aseta 1 päivä - No comment provided by engineer. - - - Set contact name… - Aseta kontaktin nimi… - No comment provided by engineer. - - - Set group preferences - Aseta ryhmän asetukset - No comment provided by engineer. - - - Set passphrase to export - Aseta tunnuslause vientiä varten - No comment provided by engineer. - - - Set the message shown to new members! - Aseta uusille jäsenille näytettävä viesti! - No comment provided by engineer. - - - Set timeouts for proxy/VPN - Aseta aikakatkaisut välityspalvelimelle/VPN:lle - No comment provided by engineer. - - - Settings - Asetukset - No comment provided by engineer. - - - Share - Jaa - chat item action - - - Share invitation link - No comment provided by engineer. - - - Share link - Jaa linkki - No comment provided by engineer. - - - Share one-time invitation link - Jaa kertakutsulinkki - No comment provided by engineer. - - - Show QR code - No comment provided by engineer. - - - Show calls in phone history - Näytä puhelut puhelinhistoriassa - No comment provided by engineer. - - - Show preview - Näytä esikatselu - No comment provided by engineer. - - - SimpleX Chat security was audited by Trail of Bits. - Trail of Bits on tarkastanut SimpleX Chatin tietoturvan. - No comment provided by engineer. - - - SimpleX Lock - SimpleX Lock - No comment provided by engineer. - - - SimpleX Lock turned on - SimpleX Lock päällä - No comment provided by engineer. - - - SimpleX contact address - SimpleX-yhteystiedot - simplex link type - - - SimpleX encrypted message or connection event - SimpleX-salattu viesti tai yhteystapahtuma - notification - - - SimpleX group link - SimpleX-ryhmän linkki - simplex link type - - - SimpleX links - SimpleX-linkit - No comment provided by engineer. - - - SimpleX one-time invitation - SimpleX-kertakutsu - simplex link type - - - Skip - Ohita - No comment provided by engineer. - - - Skipped messages - Ohitetut viestit - No comment provided by engineer. - - - Somebody - Joku - notification title - - - Start a new chat - Aloita uusi keskustelu - No comment provided by engineer. - - - Start chat - Aloita keskustelu - No comment provided by engineer. - - - Start migration - Aloita siirto - No comment provided by engineer. - - - Stop - Lopeta - No comment provided by engineer. - - - Stop SimpleX - Lopeta SimpleX - authentication reason - - - Stop chat to enable database actions - Pysäytä keskustelu tietokantatoimien mahdollistamiseksi - No comment provided by engineer. - - - Stop chat to export, import or delete chat database. You will not be able to receive and send messages while the chat is stopped. - Pysäytä keskustelut viedäksesi, tuodaksesi tai poistaaksesi keskustelujen tietokannan. Et voi vastaanottaa ja lähettää viestejä, kun keskustelut on pysäytetty. - No comment provided by engineer. - - - Stop chat? - Lopeta keskustelu? - No comment provided by engineer. - - - Support SimpleX Chat - SimpleX Chat tuki - No comment provided by engineer. - - - System - Järjestelmä - No comment provided by engineer. - - - TCP connection timeout - TCP-yhteyden aikakatkaisu - No comment provided by engineer. - - - TCP_KEEPCNT - TCP_KEEPCNT - No comment provided by engineer. - - - TCP_KEEPIDLE - TCP_KEEPIDLE - No comment provided by engineer. - - - TCP_KEEPINTVL - TCP_KEEPINTVL - No comment provided by engineer. - - - Take picture - Ota kuva - No comment provided by engineer. - - - Tap button - Napauta painiketta - No comment provided by engineer. - - - Tap to activate profile. - Aktivoi profiili napauttamalla. - No comment provided by engineer. - - - Tap to join - Liity napauttamalla - No comment provided by engineer. - - - Tap to join incognito - Napauta liittyäksesi incognito-tilassa - No comment provided by engineer. - - - Tap to start a new chat - Aloita uusi keskustelu napauttamalla - No comment provided by engineer. - - - Test failed at step %@. - Testi epäonnistui vaiheessa %@. - server test failure - - - Test server - Testipalvelin - No comment provided by engineer. - - - Test servers - Testipalvelimet - No comment provided by engineer. - - - Tests failed! - Testit epäonnistuivat! - No comment provided by engineer. - - - Thank you for installing SimpleX Chat! - Kiitos SimpleX Chatin asentamisesta! - No comment provided by engineer. - - - Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! - Kiitos käyttäjille - [osallistu Weblaten avulla](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! - No comment provided by engineer. - - - Thanks to the users – contribute via Weblate! - Kiitokset käyttäjille – osallistu Weblaten kautta! - No comment provided by engineer. - - - The 1st platform without any user identifiers – private by design. - Ensimmäinen alusta ilman käyttäjätunnisteita – suunniteltu yksityiseksi. - No comment provided by engineer. - - - The app can notify you when you receive messages or contact requests - please open settings to enable. - Sovellus voi ilmoittaa sinulle, kun saat viestejä tai yhteydenottopyyntöjä - avaa asetukset ottaaksesi ne käyttöön. - No comment provided by engineer. - - - The attempt to change database passphrase was not completed. - Tietokannan tunnuslauseen muuttamista ei suoritettu loppuun. - No comment provided by engineer. - - - The connection you accepted will be cancelled! - Hyväksymäsi yhteys peruuntuu! - No comment provided by engineer. - - - The contact you shared this link with will NOT be able to connect! - Kontakti, jolle jaoit tämän linkin, EI voi muodostaa yhteyttä! - No comment provided by engineer. - - - The created archive is available via app Settings / Database / Old database archive. - Luotu arkisto on käytettävissä sovelluksen Asetukset / Tietokanta / Vanha tietokanta-arkisto kautta. - No comment provided by engineer. - - - The group is fully decentralized – it is visible only to the members. - Ryhmä on täysin hajautettu - se näkyy vain jäsenille. - No comment provided by engineer. - - - The message will be deleted for all members. - Viesti poistetaan kaikilta jäseniltä. - No comment provided by engineer. - - - The message will be marked as moderated for all members. - Viesti merkitään moderoiduksi kaikille jäsenille. - No comment provided by engineer. - - - The next generation of private messaging - Seuraavan sukupolven yksityisviestit - No comment provided by engineer. - - - The old database was not removed during the migration, it can be deleted. - Vanhaa tietokantaa ei poistettu siirron aikana, se voidaan kuitenkin poistaa. - No comment provided by engineer. - - - The profile is only shared with your contacts. - Profiili jaetaan vain kontaktiesi kanssa. - No comment provided by engineer. - - - The sender will NOT be notified - Lähettäjälle EI ilmoiteta - No comment provided by engineer. - - - The servers for new connections of your current chat profile **%@**. - Palvelimet nykyisen keskusteluprofiilisi uusille yhteyksille **%@**. - No comment provided by engineer. - - - Theme - Teema - No comment provided by engineer. - - - There should be at least one user profile. - Käyttäjäprofiileja tulee olla vähintään yksi. - No comment provided by engineer. - - - There should be at least one visible user profile. - Näkyviä käyttäjäprofiileja tulee olla vähintään yksi. - No comment provided by engineer. - - - This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain. - Tätä toimintoa ei voi kumota - kaikki vastaanotetut ja lähetetyt tiedostot ja media poistetaan. Matalan resoluution kuvat säilyvät. - No comment provided by engineer. - - - This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes. - Tätä toimintoa ei voi kumota - valittua aikaisemmin lähetetyt ja vastaanotetut viestit poistetaan. Tämä voi kestää useita minuutteja. - No comment provided by engineer. - - - This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost. - Tätä toimintoa ei voi kumota - profiilisi, kontaktisi, viestisi ja tiedostosi poistuvat peruuttamattomasti. - No comment provided by engineer. - - - This feature is experimental! It will only work if the other client has version 4.2 installed. You should see the message in the conversation once the address change is completed – please check that you can still receive messages from this contact (or group member). - No comment provided by engineer. - - - This group no longer exists. - Tätä ryhmää ei enää ole olemassa. - No comment provided by engineer. - - - This setting applies to messages in your current chat profile **%@**. - Tämä asetus koskee nykyisen keskusteluprofiilisi viestejä *%@**. - No comment provided by engineer. - - - To ask any questions and to receive updates: - Voit esittää kysymyksiä ja saada päivityksiä: - No comment provided by engineer. - - - To find the profile used for an incognito connection, tap the contact or group name on top of the chat. - No comment provided by engineer. - - - To make a new connection - Uuden yhteyden luominen - No comment provided by engineer. - - - To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts. - Yksityisyyden suojaamiseksi kaikkien muiden alustojen käyttämien käyttäjätunnusten sijaan SimpleX käyttää viestijonojen tunnisteita, jotka ovat kaikille kontakteille erillisiä. - No comment provided by engineer. - - - To protect timezone, image/voice files use UTC. - Aikavyöhykkeen suojaamiseksi kuva-/äänitiedostot käyttävät UTC:tä. - No comment provided by engineer. - - - To protect your information, turn on SimpleX Lock. -You will be prompted to complete authentication before this feature is enabled. - Suojaa tietosi ottamalla SimpleX Lock käyttöön. -Sinua kehotetaan suorittamaan todennus loppuun, ennen kuin tämä ominaisuus otetaan käyttöön. - No comment provided by engineer. - - - To record voice message please grant permission to use Microphone. - Jos haluat nauhoittaa ääniviestin, anna lupa käyttää mikrofonia. - No comment provided by engineer. - - - To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page. - Voit paljastaa piilotetun profiilisi syöttämällä koko salasanan hakukenttään **Keskusteluprofiilisi** -sivulla. - No comment provided by engineer. - - - To support instant push notifications the chat database has to be migrated. - Keskustelujen-tietokanta on siirrettävä välittömien push-ilmoitusten tukemiseksi. - No comment provided by engineer. - - - To verify end-to-end encryption with your contact compare (or scan) the code on your devices. - Voit tarkistaa päästä päähän -salauksen kontaktisi kanssa vertaamalla (tai skannaamalla) laitteidenne koodia. - No comment provided by engineer. - - - Transport isolation - Kuljetuksen eristäminen - No comment provided by engineer. - - - Trying to connect to the server used to receive messages from this contact (error: %@). - Yritetään muodostaa yhteyttä palvelimeen, jota käytetään tämän kontaktin viestien vastaanottamiseen (virhe: %@). - No comment provided by engineer. - - - Trying to connect to the server used to receive messages from this contact. - Yritetään muodostaa yhteys palvelimeen, jota käytetään viestien vastaanottamiseen tältä kontaktilta. - No comment provided by engineer. - - - Turn off - Sammuta - No comment provided by engineer. - - - Turn off notifications? - Kytke ilmoitukset pois päältä? - No comment provided by engineer. - - - Turn on - Kytke päälle - No comment provided by engineer. - - - Unable to record voice message - Ääniviestiä ei voi tallentaa - No comment provided by engineer. - - - Unexpected error: %@ - Odottamaton virhe: %@ - No comment provided by engineer. - - - Unexpected migration state - Odottamaton siirtotila - No comment provided by engineer. - - - Unhide - Näytä - No comment provided by engineer. - - - Unknown caller - Tuntematon soittaja - callkit banner - - - Unknown database error: %@ - Tuntematon tietokantavirhe: %@ - No comment provided by engineer. - - - Unknown error - Tuntematon virhe - No comment provided by engineer. - - - Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions. - Ellet käytä iOS:n puhelinkäyttöliittymää, ota Älä häiritse -tila käyttöön keskeytysten välttämiseksi. - No comment provided by engineer. - - - Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. -To connect, please ask your contact to create another connection link and check that you have a stable network connection. - Ellei yhteyshenkilösi poistanut yhteyttä tai tämä linkki oli jo käytössä, se voi olla virhe - ilmoita siitä. -Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja tarkista, että verkkoyhteytesi on vakaa. - No comment provided by engineer. - - - Unlock - Avaa - authentication reason - - - Unmute - Poista mykistys - No comment provided by engineer. - - - Unread - Lukematon - No comment provided by engineer. - - - Update - Päivitä - No comment provided by engineer. - - - Update .onion hosts setting? - Päivitä .onion-isäntien asetus? - No comment provided by engineer. - - - Update database passphrase - Päivitä tietokannan tunnuslause - No comment provided by engineer. - - - Update network settings? - Päivitä verkkoasetukset? - No comment provided by engineer. - - - Update transport isolation mode? - Päivitä kuljetuksen eristystila? - No comment provided by engineer. - - - Updating settings will re-connect the client to all servers. - Asetusten päivittäminen yhdistää asiakkaan uudelleen kaikkiin palvelimiin. - No comment provided by engineer. - - - Updating this setting will re-connect the client to all servers. - Tämän asetuksen päivittäminen yhdistää asiakkaan uudelleen kaikkiin palvelimiin. - No comment provided by engineer. - - - Use .onion hosts - Käytä .onion-isäntiä - No comment provided by engineer. - - - Use SimpleX Chat servers? - Käytä SimpleX Chat palvelimia? - No comment provided by engineer. - - - Use chat - Käytä chattia - No comment provided by engineer. - - - Use for new connections - Käytä uusiin yhteyksiin - No comment provided by engineer. - - - Use iOS call interface - Käytä iOS:n puhelujen käyttöliittymää - No comment provided by engineer. - - - Use server - Käytä palvelinta - No comment provided by engineer. - - - User profile - Käyttäjäprofiili - No comment provided by engineer. - - - Using .onion hosts requires compatible VPN provider. - .onion-isäntien käyttäminen vaatii yhteensopivan VPN-palveluntarjoajan. - No comment provided by engineer. - - - Using SimpleX Chat servers. - Käyttää SimpleX Chat -palvelimia. - No comment provided by engineer. - - - Verify connection security - Tarkista yhteyden suojaus - No comment provided by engineer. - - - Verify security code - Tarkista turvakoodi - No comment provided by engineer. - - - Via browser - Selaimella - No comment provided by engineer. - - - Video call - Videopuhelu - No comment provided by engineer. - - - View security code - Näytä turvakoodi - No comment provided by engineer. - - - Voice messages - Ääniviestit - chat feature - - - Voice messages are prohibited in this chat. - Ääniviestit ovat kiellettyjä tässä keskustelussa. - No comment provided by engineer. - - - Voice messages are prohibited in this group. - Ääniviestit ovat kiellettyjä tässä ryhmässä. - No comment provided by engineer. - - - Voice messages prohibited! - Ääniviestit kielletty! - No comment provided by engineer. - - - Voice message… - Ääniviesti… - No comment provided by engineer. - - - Waiting for file - Odottaa tiedostoa - No comment provided by engineer. - - - Waiting for image - Odottaa kuvaa - No comment provided by engineer. - - - WebRTC ICE servers - WebRTC ICE -palvelimet - No comment provided by engineer. - - - Welcome %@! - Tervetuloa %@! - No comment provided by engineer. - - - Welcome message - Tervetuloviesti - No comment provided by engineer. - - - What's new - Uusimmat - No comment provided by engineer. - - - When available - Kun saatavilla - No comment provided by engineer. - - - When you share an incognito profile with somebody, this profile will be used for the groups they invite you to. - Kun jaat inkognitoprofiilin jonkun kanssa, tätä profiilia käytetään ryhmissä, joihin tämä sinut kutsuu. - No comment provided by engineer. - - - With optional welcome message. - Valinnaisella tervetuloviestillä. - No comment provided by engineer. - - - Wrong database passphrase - Väärä tietokannan tunnuslause - No comment provided by engineer. - - - Wrong passphrase! - Väärä tunnuslause! - No comment provided by engineer. - - - You - Sinä - No comment provided by engineer. - - - You accepted connection - Hyväksyit yhteyden - No comment provided by engineer. - - - You allow - Sallit - No comment provided by engineer. - - - You already have a chat profile with the same display name. Please choose another name. - Sinulla on jo keskusteluprofiili samalla näyttönimellä. Valitse toinen nimi. - No comment provided by engineer. - - - You are already connected to %@. - Olet jo muodostanut yhteyden %@:n kanssa. - No comment provided by engineer. - - - You are connected to the server used to receive messages from this contact. - Olet yhteydessä palvelimeen, jota käytetään vastaanottamaan viestejä tältä kontaktilta. - No comment provided by engineer. - - - You are invited to group - Sinut on kutsuttu ryhmään - No comment provided by engineer. - - - You can accept calls from lock screen, without device and app authentication. - Voit vastaanottaa puheluita lukitusnäytöltä ilman laitteen ja sovelluksen todennusta. - No comment provided by engineer. - - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Voit myös muodostaa yhteyden klikkaamalla linkkiä. Jos se avautuu selaimessa, napsauta **Avaa mobiilisovelluksessa**-painiketta. - No comment provided by engineer. - - - You can hide or mute a user profile - swipe it to the right. -SimpleX Lock must be enabled. - No comment provided by engineer. - - - You can now send messages to %@ - Voit nyt lähettää viestejä %@:lle - notification body - - - You can set lock screen notification preview via settings. - Voit määrittää lukitusnäytön ilmoituksen esikatselun asetuksista. - No comment provided by engineer. - - - You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. - Voit jakaa linkin tai QR-koodin - kuka tahansa voi liittyä ryhmään. Et menetä ryhmän jäseniä, jos poistat sen myöhemmin. - No comment provided by engineer. - - - You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it. - No comment provided by engineer. - - - You can start chat via app Settings / Database or by restarting the app - Voit aloittaa keskustelun sovelluksen Asetukset / Tietokanta kautta tai käynnistämällä sovelluksen uudelleen - No comment provided by engineer. - - - You can use markdown to format messages: - Voit käyttää markdownia viestien muotoiluun: - No comment provided by engineer. - - - You can't send messages! - Et voi lähettää viestejä! - No comment provided by engineer. - - - You control through which server(s) **to receive** the messages, your contacts – the servers you use to message them. - Sinä hallitset, minkä palvelim(i)en kautta **viestit vastaanotetaan**, kontaktisi - palvelimet, joita käytät viestien lähettämiseen niille. - No comment provided by engineer. - - - You could not be verified; please try again. - Sinua ei voitu todentaa; yritä uudelleen. - No comment provided by engineer. - - - You have no chats - Sinulla ei ole keskusteluja - No comment provided by engineer. - - - You have to enter passphrase every time the app starts - it is not stored on the device. - Sinun on annettava tunnuslause aina, kun sovellus käynnistyy - sitä ei tallenneta laitteeseen. - No comment provided by engineer. - - - You invited your contact - No comment provided by engineer. - - - You joined this group - Liityit tähän ryhmään - No comment provided by engineer. - - - You joined this group. Connecting to inviting group member. - Liityit tähän ryhmään. Muodostetaan yhteyttä ryhmän jäsenten kutsumiseksi. - 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. - Sinun tulee käyttää keskustelujen-tietokannan uusinta versiota AINOSTAAN yhdessä laitteessa, muuten saatat lakata vastaanottamasta viestejä joiltakin kontakteilta. - No comment provided by engineer. - - - You need to allow your contact to send voice messages to be able to send them. - Sinun on sallittava kontaktiesi lähettää ääniviestejä, jotta voit lähettää niitä. - No comment provided by engineer. - - - You rejected group invitation - Hylkäsit ryhmäkutsun - No comment provided by engineer. - - - You sent group invitation - Lähetit ryhmäkutsun - No comment provided by engineer. - - - You will be connected to group when the group host's device is online, please wait or check later! - Sinut yhdistetään ryhmään, kun ryhmän isännän laite on online-tilassa, odota tai tarkista myöhemmin! - No comment provided by engineer. - - - You will be connected when your connection request is accepted, please wait or check later! - Sinut yhdistetään, kun yhteyspyyntösi on hyväksytty, odota tai tarkista myöhemmin! - No comment provided by engineer. - - - You will be connected when your contact's device is online, please wait or check later! - Sinut yhdistetään, kun kontaktisi laite on online-tilassa, odota tai tarkista myöhemmin! - No comment provided by engineer. - - - You will be required to authenticate when you start or resume the app after 30 seconds in background. - Sinun on tunnistauduttava, kun käynnistät sovelluksen tai jatkat sen käyttöä 30 sekunnin tauon jälkeen. - No comment provided by engineer. - - - You will join a group this link refers to and connect to its group members. - Liityt ryhmään, johon tämä linkki viittaa, ja muodostat yhteyden sen ryhmän jäseniin. - No comment provided by engineer. - - - You will still receive calls and notifications from muted profiles when they are active. - Saat edelleen puheluita ja ilmoituksia mykistetyiltä profiileilta, kun ne ovat aktiivisia. - No comment provided by engineer. - - - You will stop receiving messages from this group. Chat history will be preserved. - Et enää saa viestejä tästä ryhmästä. Keskusteluhistoria säilytetään. - No comment provided by engineer. - - - You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile - Yrität kutsua kontaktia, jonka kanssa olet jakanut inkognito-profiilin, ryhmään, jossa käytät pääprofiiliasi - No comment provided by engineer. - - - You're using an incognito profile for this group - to prevent sharing your main profile inviting contacts is not allowed - Käytät tässä ryhmässä incognito-profiilia. Kontaktien kutsuminen ei ole sallittua, jotta pääprofiilisi ei tule jaetuksi - No comment provided by engineer. - - - Your ICE servers - ICE-palvelimesi - No comment provided by engineer. - - - Your SMP servers - SMP-palvelimesi - No comment provided by engineer. - - - Your SimpleX contact address - No comment provided by engineer. - - - Your calls - Puhelusi - No comment provided by engineer. - - - Your chat database - Keskustelut-tietokantasi - No comment provided by engineer. - - - Your chat database is not encrypted - set passphrase to encrypt it. - Keskustelut-tietokantasi ei ole salattu - aseta tunnuslause sen salaamiseksi. - No comment provided by engineer. - - - Your chat profile will be sent to group members - Keskusteluprofiilisi lähetetään ryhmän jäsenille - No comment provided by engineer. - - - Your chat profile will be sent to your contact - No comment provided by engineer. - - - Your chat profiles - Keskusteluprofiilisi - No comment provided by engineer. - - - Your chats - No comment provided by engineer. - - - Your contact address - No comment provided by engineer. - - - Your contact can scan it from the app. - No comment provided by engineer. - - - Your contact needs to be online for the connection to complete. -You can cancel this connection and remove the contact (and try later with a new link). - Kontaktin tulee olla online-tilassa, jotta yhteys voidaan muodostaa. -Voit peruuttaa tämän yhteyden ja poistaa kontaktin (ja yrittää myöhemmin uudella linkillä). - No comment provided by engineer. - - - Your contact sent a file that is larger than currently supported maximum size (%@). - Yhteyshenkilösi lähetti tiedoston, joka on suurempi kuin tällä hetkellä tuettu enimmäiskoko (%@). - No comment provided by engineer. - - - Your contacts can allow full message deletion. - Kontaktisi voivat sallia viestien täydellisen poistamisen. - No comment provided by engineer. - - - Your current chat database will be DELETED and REPLACED with the imported one. - Nykyinen keskustelut-tietokantasi poistetaan ja korvataan tuodulla tietokannalla. - No comment provided by engineer. - - - Your current profile - Nykyinen profiilisi - No comment provided by engineer. - - - Your preferences - Asetuksesi - No comment provided by engineer. - - - Your privacy - Yksityisyytesi - No comment provided by engineer. - - - Your profile is stored on your device and shared only with your contacts. -SimpleX servers cannot see your profile. - Profiilisi tallennetaan laitteeseesi ja jaetaan vain yhteystietojesi kanssa. -SimpleX-palvelimet eivät näe profiiliasi. - No comment provided by engineer. - - - Your profile will be sent to the contact that you received this link from - No comment provided by engineer. - - - Your profile, contacts and delivered messages are stored on your device. - Profiilisi, kontaktisi ja toimitetut viestit tallennetaan laitteellesi. - No comment provided by engineer. - - - Your random profile - Satunnainen profiilisi - No comment provided by engineer. - - - Your server - Palvelimesi - No comment provided by engineer. - - - Your server address - Palvelimesi osoite - No comment provided by engineer. - - - Your settings - Asetuksesi - No comment provided by engineer. - - - [Contribute](https://github.com/simplex-chat/simplex-chat#contribute) - [Osallistu](https://github.com/simplex-chat/simplex-chat#contribute) - No comment provided by engineer. - - - [Send us email](mailto:chat@simplex.chat) - [Lähetä meille sähköpostia](mailto:chat@simplex.chat) - No comment provided by engineer. - - - [Star on GitHub](https://github.com/simplex-chat/simplex-chat) - [Tähti GitHubissa](https://github.com/simplex-chat/simplex-chat) - No comment provided by engineer. - - - \_italic_ - \_italic_ - No comment provided by engineer. - - - \`a + b` - \`a + b` - No comment provided by engineer. - - - above, then choose: - edellä, valitse sitten: - No comment provided by engineer. - - - accepted call - hyväksytty puhelu - call status - - - admin - ylläpitäjä - member role - - - always - aina - pref value - - - audio call (not e2e encrypted) - äänipuhelu (ei e2e-salattu) - No comment provided by engineer. - - - bad message ID - virheellinen viestin tunniste - integrity error chat item - - - bad message hash - virheellinen viestin tarkiste - integrity error chat item - - - bold - lihavoitu - No comment provided by engineer. - - - call error - soittovirhe - call status - - - call in progress - puhelu käynnissä - call status - - - calling… - soittaa… - call status - - - cancelled %@ - peruutettu %@ - feature offered item - - - changed address for you - muuttunut osoite sinulle - chat item text - - - changed role of %1$@ to %2$@ - %1$@:n roolin muuttui %2$@:ksi - rcv group event chat item - - - changed your role to %@ - roolisi muuttui %@:ksi - rcv group event chat item - - - changing address for %@... - chat item text - - - changing address... - chat item text - - - colored - värillinen - No comment provided by engineer. - - - complete - valmis - No comment provided by engineer. - - - connect to SimpleX Chat developers. - ole yhteydessä SimpleX Chat -kehittäjiin. - No comment provided by engineer. - - - connected - yhdistetty - No comment provided by engineer. - - - connecting - yhdistää - No comment provided by engineer. - - - connecting (accepted) - yhdistäminen (hyväksytty) - No comment provided by engineer. - - - connecting (announced) - yhdistäminen (ilmoitettu) - No comment provided by engineer. - - - connecting (introduced) - yhdistäminen (esitelty) - No comment provided by engineer. - - - connecting (introduction invitation) - yhdistäminen (esittelykutsu) - No comment provided by engineer. - - - connecting call… - yhdistää puhelun… - call status - - - connecting… - yhdistää… - chat list item title - - - connection established - yhteys luotu - chat list item title (it should not be shown - - - connection:%@ - yhteys:%@ - connection information - - - contact has e2e encryption - kontaktilla on e2e-salaus - No comment provided by engineer. - - - contact has no e2e encryption - kontaktilla ei ole e2e-salausta - No comment provided by engineer. - - - creator - luoja - No comment provided by engineer. - - - default (%@) - oletusarvo (%@) - pref value - - - deleted - poistettu - deleted chat item - - - deleted group - poistettu ryhmä - rcv group event chat item - - - direct - suora - connection level description - - - duplicate message - päällekkäinen viesti - integrity error chat item - - - e2e encrypted - e2e-salattu - No comment provided by engineer. - - - enabled - käytössä - enabled status - - - enabled for contact - käytössä kontaktille - enabled status - - - enabled for you - käytössä sinulle - enabled status - - - ended - päättyi - No comment provided by engineer. - - - ended call %@ - puhelu päättyi %@:lle - call status - - - error - virhe - No comment provided by engineer. - - - group deleted - ryhmä poistettu - No comment provided by engineer. - - - group profile updated - ryhmäprofiili päivitetty - snd group event chat item - - - iOS Keychain is used to securely store passphrase - it allows receiving push notifications. - iOS-Avainnippua käytetään tunnuslauseen turvalliseen tallentamiseen - se mahdollistaa push-ilmoitusten vastaanottamisen. - No comment provided by engineer. - - - iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications. - iOS-Avainnippua käytetään tunnuslauseen turvalliseen tallentamiseen sen muuttamisen tai sovelluksen uudelleen käynnistämisen jälkeen - se mahdollistaa push-ilmoitusten vastaanottamisen. - No comment provided by engineer. - - - incognito via contact address link - incognito kontaktilinkin kautta - chat list item description - - - incognito via group link - incognito ryhmälinkin kautta - chat list item description - - - incognito via one-time link - incognito kertalinkillä - chat list item description - - - indirect (%d) - epäsuora (%d) - connection level description - - - invalid chat - virheellinen keskustelu - invalid chat data - - - invalid chat data - virheelliset keskustelu-tiedot - No comment provided by engineer. - - - invalid data - virheelliset tiedot - invalid chat item - - - invitation to group %@ - kutsu ryhmään %@ - group name - - - invited - kutsuttu - No comment provided by engineer. - - - invited %@ - kutsuttu %@ - rcv group event chat item - - - invited to connect - kutsuttu yhteydenpitoon - chat list item title - - - invited via your group link - kutsuttu ryhmäsi linkin kautta - rcv group event chat item - - - italic - kursivoitu - No comment provided by engineer. - - - join as %@ - Liity %@:nä - No comment provided by engineer. - - - left - poistunut - rcv group event chat item - - - marked deleted - merkitty poistetuksi - marked deleted chat item preview text - - - member - jäsen - member role - - - connected - yhdistetty - rcv group event chat item - - - message received - viesti vastaanotettu - notification - - - missed call - vastaamaton puhelu - call status - - - moderated - moderoitu - moderated chat item - - - moderated by %@ - %@ moderoi - No comment provided by engineer. - - - never - ei koskaan - No comment provided by engineer. - - - new message - uusi viesti - notification - - - no - ei - pref value - - - no e2e encryption - ei e2e-salausta - No comment provided by engineer. - - - observer - tarkkailija - member role - - - off - pois - enabled status - group pref value - - - offered %@ - tarjottu %@ - feature offered item - - - offered %1$@: %2$@ - tarjottu %1$@: %2$@ - feature offered item - - - on - päällä - group pref value - - - or chat with the developers - tai keskustele kehittäjien kanssa - No comment provided by engineer. - - - owner - omistaja - member role - - - peer-to-peer - vertais - No comment provided by engineer. - - - received answer… - vastaus saatu… - No comment provided by engineer. - - - received confirmation… - vahvistus saatu… - No comment provided by engineer. - - - rejected call - hylätty puhelu - call status - - - removed - poistettu - No comment provided by engineer. - - - removed %@ - %@ poistettu - rcv group event chat item - - - removed you - poisti sinut - rcv group event chat item - - - sec - sek - network option - - - secret - salainen - No comment provided by engineer. - - - starting… - alkaa… - No comment provided by engineer. - - - strike - soita - No comment provided by engineer. - - - this contact - tämä kontakti - notification title - - - unknown - tuntematon - connection info - - - updated group profile - päivitetty ryhmäprofiili - rcv group event chat item - - - v%@ (%@) - v%@ (%@) - No comment provided by engineer. - - - via contact address link - kontaktiosoitelinkillä - chat list item description - - - via group link - ryhmälinkillä - chat list item description - - - via one-time link - kertalinkillä - chat list item description - - - via relay - releellä - No comment provided by engineer. - - - video call (not e2e encrypted) - videopuhelu (ei e2e-salattu) - No comment provided by engineer. - - - waiting for answer… - odottaa vastaamista… - No comment provided by engineer. - - - waiting for confirmation… - odottaa vahvistusta… - No comment provided by engineer. - - - wants to connect to you! - haluaa olla yhteydessä sinuun! - No comment provided by engineer. - - - yes - kyllä - pref value - - - you are invited to group - sinut on kutsuttu ryhmään - No comment provided by engineer. - - - you are observer - olet tarkkailija - No comment provided by engineer. - - - you changed address - muutit osoitetta - chat item text - - - you changed address for %@ - muutit osoitetta %@:ksi - chat item text - - - you changed role for yourself to %@ - vaihdoit roolin itsellesi %@:ksi - snd group event chat item - - - you changed role of %1$@ to %2$@ - olet vaihtanut %1$@:n roolin %2$@:ksi - snd group event chat item - - - you left - lähdit - snd group event chat item - - - you removed %@ - poistit %@ - snd group event chat item - - - you shared one-time link - jaoit kertalinkin - chat list item description - - - you shared one-time link incognito - jaoit kertalinkin incognito-tilassa - chat list item description - - - you: - sinä: - No comment provided by engineer. - - - \~strike~ - \~strike~ - No comment provided by engineer. - - + %@ (current) - %@ (nykyinen) + %@ (nykyinen) No comment provided by engineer. - + %@ (current): - % (nykyinen): + % (nykyinen): copied message info - + + %@ / %@ + %@ / % @ + No comment provided by engineer. + + + %@ and %@ connected + %@ ja %@ yhdistetty + No comment provided by engineer. + + + %1$@ at %2$@: + %1$@ klo %2$@: + copied message info, <sender> at <time> + + + %@ is connected! + %@ on yhdistetty! + notification title + + + %@ is not verified + %@ ei ole vahvistettu + No comment provided by engineer. + + + %@ is verified + %@ on vahvistettu + No comment provided by engineer. + + %@ servers - %@ palvelimet + %@ palvelimet No comment provided by engineer. - - %lld minutes - %lld minuuttia + + %@ wants to connect! + %@ haluaa muodostaa yhteyden! + notification title + + + %@, %@ and %lld other members connected + %@, %@ ja %lld muut jäsenet yhdistetty No comment provided by engineer. - + %@: - %@: + %@: copied message info - - %d weeks - %d viikkoa + + %d days + %d päivää time interval - + + %d hours + %d tuntia + time interval + + + %d min + %d min + time interval + + + %d months + %d kuukautta + time interval + + + %d sec + %d sek + time interval + + + %d skipped message(s) + %d ohitettua viestiä + integrity error chat item + + + %d weeks + %d viikkoa + time interval + + + %lld + %lld + No comment provided by engineer. + + + %lld %@ + %lld %@ + No comment provided by engineer. + + + %lld contact(s) selected + %lld kontaktia valittu + No comment provided by engineer. + + + %lld file(s) with total size of %@ + %lld tiedosto(a), joiden kokonaiskoko on %@ + No comment provided by engineer. + + + %lld members + %lld jäsenet + No comment provided by engineer. + + + %lld minutes + %lld minuuttia + No comment provided by engineer. + + + %lld new interface languages + No comment provided by engineer. + + + %lld second(s) + %lld sekunti(a) + No comment provided by engineer. + + %lld seconds - %lld sekuntia + %lld sekuntia No comment provided by engineer. - - 5 minutes - 5 minuuttia + + %lldd + %lldd No comment provided by engineer. - - 30 seconds - 30 sekuntia + + %lldh + %lldh No comment provided by engineer. - - %u messages skipped. - %u viestit ohitettu. + + %lldk + %lldk No comment provided by engineer. - + + %lldm + %lldm + No comment provided by engineer. + + + %lldmth + %lldmth + No comment provided by engineer. + + + %llds + %llds + No comment provided by engineer. + + + %lldw + %lldw + No comment provided by engineer. + + %u messages failed to decrypt. - %u viestien salauksen purku epäonnistui. + %u viestien salauksen purku epäonnistui. No comment provided by engineer. - - Abort - Keskeytä + + %u messages skipped. + %u viestit ohitettu. No comment provided by engineer. - - Address change will be aborted. Old receiving address will be used. - Osoitteenmuutos keskeytetään. Käytetään vanhaa vastaanotto-osoitetta. + + ( + ( No comment provided by engineer. - - Abort changing address - Keskeytä osoitteenvaihto + + ) + ) No comment provided by engineer. - - Abort changing address? - Keskeytä osoitteenvaihto? + + **Add new contact**: to create your one-time QR Code or link for your contact. + **Lisää uusi kontakti**: luo kertakäyttöinen QR-koodi tai linkki kontaktille. No comment provided by engineer. - - Allow to send files and media. - Salli tiedostojen ja median lähettäminen. + + **Create link / QR code** for your contact to use. + **Luo linkki / QR-koodi* kontaktille. No comment provided by engineer. - - Allow your contacts to call you. - Salli kontaktiesi soittaa sinulle. + + **More private**: check new messages every 20 minutes. Device token is shared with SimpleX Chat server, but not how many contacts or messages you have. + **Yksityisempi**: tarkista uudet viestit 20 minuutin välein. Laitetunnus jaetaan SimpleX Chat -palvelimen kanssa, mutta ei sitä, kuinka monta yhteystietoa tai viestiä sinulla on. No comment provided by engineer. - - Audio/video calls - Ääni/videopuhelut - chat feature - - - Better messages - Parempia viestejä + + **Most private**: do not use SimpleX Chat notifications server, check messages periodically in the background (depends on how often you use the app). + **Yksityisin**: älä käytä SimpleX Chat -ilmoituspalvelinta, tarkista viestit ajoittain taustalla (riippuu siitä, kuinka usein käytät sovellusta). No comment provided by engineer. - - Both you and your contact can add message reactions. - Sekä sinä että kontaktisi voivat käyttää viestireaktioita. + + **Paste received link** or open it in the browser and tap **Open in mobile app**. + **Liitä vastaanotettu linkki** tai avaa se selaimessa ja napauta **Avaa mobiilisovelluksessa**. No comment provided by engineer. - - Change self-destruct mode - Vaihda itsetuhotilaa - authentication reason - - - Change self-destruct passcode - Vaihda itsetuhoutuva pääsykoodi - authentication reason - set passcode view - - - Continue - Jatka + + **Please note**: you will NOT be able to recover or change passphrase if you lose it. + **Huomaa**: et voi palauttaa tai muuttaa tunnuslausetta, jos kadotat sen. No comment provided by engineer. - - Create file - Luo tiedosto - server test step - - - Current Passcode - Nykyinen pääsykoodi + + **Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from. + **Suositus**: laitetunnus ja ilmoitukset lähetetään SimpleX Chat -ilmoituspalvelimelle, mutta ei viestin sisältöä, kokoa tai sitä, keneltä se on peräisin. No comment provided by engineer. - - Change passcode - Vaihda pääsykoodi - authentication reason - - - Compare file - Vertaa tiedostoa - server test step - - - Confirm Passcode - Vahvista pääsykoodi + + **Scan QR code**: to connect to your contact in person or via video call. + **Skannaa QR-koodi**: muodosta yhteys kontaktiisi henkilökohtaisesti tai videopuhelun kautta. No comment provided by engineer. - - Confirm database upgrades - Vahvista tietokannan päivitykset + + **Warning**: Instant push notifications require passphrase saved in Keychain. + **Varoitus**: Välittömät push-ilmoitukset vaativat tunnuslauseen, joka on tallennettu Keychainiin. No comment provided by engineer. - - Allow message reactions. - Salli viestireaktiot. + + **e2e encrypted** audio call + **e2e-salattu** äänipuhelu No comment provided by engineer. - - App passcode is replaced with self-destruct passcode. - Sovelluksen pääsykoodi korvataan itsetuhoutuvalla pääsykoodilla. + + **e2e encrypted** video call + **e2e-salattu** videopuhelu No comment provided by engineer. - + + \*bold* + \*bold* + No comment provided by engineer. + + + , + , + No comment provided by engineer. + + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + + - more stable message delivery. - a bit better groups. - and more! - - vakaampi viestien toimitus. + - vakaampi viestien toimitus. - hieman paremmat ryhmät. - ja paljon muuta! No comment provided by engineer. - - All your contacts will remain connected. - Kaikki kontaktisi pysyvät yhteydessä. - No comment provided by engineer. - - - All your contacts will remain connected. Profile update will be sent to your contacts. - Kaikki kontaktisi pysyvät yhteydessä. Profiilipäivitys lähetetään kontakteillesi. - No comment provided by engineer. - - - Create an address to let people connect with you. - Luo osoite, jolla ihmiset voivat ottaa sinuun yhteyttä. - No comment provided by engineer. - - - 0s - 0s - No comment provided by engineer. - - - Address - Osoite - No comment provided by engineer. - - - App passcode - Sovelluksen pääsykoodi - No comment provided by engineer. - - - Audio/video calls are prohibited. - Ääni-/videopuhelut ovat kiellettyjä. - No comment provided by engineer. - - - <p>Hi!</p> -<p><a href="%@">Connect to me via SimpleX Chat</a></p> - <p> Hei! </p> -<p> <a href="%@"> Ollaan yhteydessä SimpleX Chatin kautta</a></p> - email text - - - Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. - Lisää osoite profiiliisi, jotta kontaktisi voivat jakaa sen muiden kanssa. Profiilipäivitys lähetetään kontakteillesi. - No comment provided by engineer. - - - Auto-accept - Hyväksy automaattisesti - No comment provided by engineer. - - - Bad message ID - Virheellinen viestin tunniste - No comment provided by engineer. - - - Change lock mode - Vaihda lukitustilaa - authentication reason - - - A few more things - Muutama asia lisää - No comment provided by engineer. - - - All data is erased when it is entered. - Kaikki tiedot poistetaan, kun se syötetään. - No comment provided by engineer. - - - Allow calls only if your contact allows them. - Salli puhelut vain, jos kontaktisi sallii ne. - No comment provided by engineer. - - - Allow message reactions only if your contact allows them. - Salli reaktiot viesteihin vain, jos kontaktisi sallii ne. - No comment provided by engineer. - - - Allow your contacts adding message reactions. - Salli kontaktiesi lisätä viestireaktioita. - No comment provided by engineer. - - - An empty chat profile with the provided name is created, and the app opens as usual. - Luodaan tyhjä chat-profiili annetulla nimellä, ja sovellus avautuu normaalisti. - No comment provided by engineer. - - - Authentication cancelled - Tunnistautuminen peruutettu - PIN entry - - - Bad message hash - Virheellinen viestin tarkiste - No comment provided by engineer. - - - Create SimpleX address - Luo SimpleX-osoite - No comment provided by engineer. - - - About SimpleX address - Tietoja SimpleX osoitteesta - No comment provided by engineer. - - + - voice messages up to 5 minutes. - custom time to disappear. - editing history. - - ääniviestit enintään 5 minuuttia. + - ääniviestit enintään 5 minuuttia. - mukautettu katoamisaika. - historian muokkaaminen. No comment provided by engineer. - + + . + . + No comment provided by engineer. + + + 0s + 0s + No comment provided by engineer. + + + 1 day + 1 päivä + time interval + + + 1 hour + 1 tunti + time interval + + 1 minute - 1 minuutti + 1 minuutti No comment provided by engineer. - + + 1 month + 1 kuukausi + time interval + + + 1 week + 1 viikko + time interval + + 1-time link - Kertakäyttölinkki + Kertakäyttölinkki No comment provided by engineer. - - Both you and your contact can make calls. - Sekä sinä että kontaktisi voitte soittaa puheluita. + + 5 minutes + 5 minuuttia No comment provided by engineer. - - All app data is deleted. - Kaikki sovelluksen tiedot poistetaan. + + 6 + 6 No comment provided by engineer. - - Contacts - Kontaktit + + 30 seconds + 30 sekuntia No comment provided by engineer. - - # %@ - # %@ - copied message info title, # <title> - - - ## History - ## Historia - copied message info - - - ## In reply to - ## vastauksena - copied message info - - - %@ and %@ connected - %@ ja %@ yhdistetty + + : + : No comment provided by engineer. - - You can hide or mute a user profile - swipe it to the right. - Voit piilottaa tai mykistää käyttäjäprofiilin pyyhkäisemällä sitä oikealle. + + <p>Hi!</p> +<p><a href="%@">Connect to me via SimpleX Chat</a></p> + <p> Hei! </p> +<p> <a href="%@"> Ollaan yhteydessä SimpleX Chatin kautta</a></p> + email text + + + A few more things + Muutama asia lisää No comment provided by engineer. - - Database upgrade - Tietokannan päivitys - No comment provided by engineer. + + A new contact + Uusi kontakti + notification title - - Deleted at - Poistettu klo - No comment provided by engineer. - - - Deleted at: %@ - Poistettu klo: %@ - copied message info - - - Duration - Kesto - No comment provided by engineer. - - - Files and media are prohibited in this group. - Tiedostot ja media ovat tässä ryhmässä kiellettyjä. - No comment provided by engineer. - - - Incompatible database version - Yhteensopimaton tietokantaversio - No comment provided by engineer. - - - Moderated at: %@ - Moderoitu klo: %@ - copied message info - - - New display name - Uusi näyttönimi - No comment provided by engineer. - - - Only your contact can add message reactions. - Vain kontaktisi voi lisätä viestireaktioita. - No comment provided by engineer. - - - Only your contact can make calls. - Vain kontaktisi voi soittaa puheluita. - No comment provided by engineer. - - - Polish interface - Puolalainen käyttöliittymä - No comment provided by engineer. - - - Select - Valitse - No comment provided by engineer. - - - Sent at: %@ - Lähetetty klo: %@ - copied message info - - - Set passcode - Aseta pääsykoodi - No comment provided by engineer. - - - Share address - Jaa osoite - No comment provided by engineer. - - - Share with contacts - Jaa kontaktien kanssa - No comment provided by engineer. - - - no text - ei tekstiä - copied message info in history - - - seconds - sekuntia - time unit - - - weeks - viikkoa - time unit - - - Database IDs and Transport isolation option. - Tietokantatunnukset ja kuljetuseristysvaihtoehto. - No comment provided by engineer. - - - Database downgrade - Tietokannan alentaminen - No comment provided by engineer. - - - Downgrade and open chat - Alenna ja avaa keskustelu - No comment provided by engineer. - - - Enter Passcode - Syötä pääsykoodi - No comment provided by engineer. - - - File will be received when your contact completes uploading it. - Tiedosto vastaanotetaan, kun kontaktisi on ladannut sen. - No comment provided by engineer. - - - Image will be received when your contact completes uploading it. - Kuva vastaanotetaan, kun kontaktisi on ladannut sen. - No comment provided by engineer. - - - Immediately - Heti - No comment provided by engineer. - - - Incorrect passcode - Väärä pääsykoodi - PIN entry - - - KeyChain error - Avainnipun virhe - No comment provided by engineer. - - - Messages & files - Viestit ja tiedostot - No comment provided by engineer. - - - Migrations: %@ - Siirrot: %@ - No comment provided by engineer. - - - No app password - Ei sovelluksen salasanaa - Authentication unavailable - - - Passcode entry - Pääsykoodin syöttö - No comment provided by engineer. - - - Passcode not changed! - Pääsykoodia ei ole muutettu! - No comment provided by engineer. - - - Passcode set! - Pääsykoodi asetettu! - No comment provided by engineer. - - - Show developer options - Näytä kehittäjävaihtoehdot - No comment provided by engineer. - - - SimpleX Lock mode - SimpleX Lock -tila - No comment provided by engineer. - - - Upgrade and open chat - Päivitä ja avaa keskustelu - No comment provided by engineer. - - - Video will be received when your contact is online, please wait or check later! - Video vastaanotetaan, kun kontaktisi on online-tilassa, odota tai tarkista myöhemmin! - No comment provided by engineer. - - - Warning: you may lose some data! - Varoitus: saatat menettää joitain tietoja! - No comment provided by engineer. - - - XFTP servers - XFTP-palvelimet - No comment provided by engineer. - - - different migration in the app/database: %@ / %@ - eri siirtyminen sovelluksessa/tietokannassa: %@ / %@ - No comment provided by engineer. - - + A new random profile will be shared. - Uusi satunnainen profiili jaetaan. + Uusi satunnainen profiili jaetaan. No comment provided by engineer. - + + A separate TCP connection will be used **for each chat profile you have in the app**. + Erillistä TCP-yhteyttä käytetään **jokaiselle sovelluksessa olevalle chat-profiilille**. + No comment provided by engineer. + + + A separate TCP connection will be used **for each contact and group member**. +**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail. + Jokaiselle kontaktille ja ryhmän jäsenelle käytetään erillistä TCP-yhteyttä**. +**Huomaa**: jos kontakteja on useita, akun ja liikenteen kulutus voi olla huomattavasti suurempi ja jotkin yhteydet voivat epäonnistua. + No comment provided by engineer. + + + Abort + Keskeytä + No comment provided by engineer. + + + Abort changing address + Keskeytä osoitteenvaihto + No comment provided by engineer. + + + Abort changing address? + Keskeytä osoitteenvaihto? + No comment provided by engineer. + + + About SimpleX + Tietoja SimpleX:stä + No comment provided by engineer. + + + About SimpleX Chat + Tietoja SimpleX Chatistä + No comment provided by engineer. + + + About SimpleX address + Tietoja SimpleX osoitteesta + No comment provided by engineer. + + + Accent color + Korostusväri + No comment provided by engineer. + + + Accept + Hyväksy + accept contact request via notification + accept incoming call via notification + + Accept connection request? - Hyväksy yhteyspyyntö? + Hyväksy yhteyspyyntö? No comment provided by engineer. - - Connect directly - Yhdistä suoraan + + Accept contact request from %@? + Hyväksy kontaktipyyntö %@:ltä? + notification body + + + Accept incognito + Hyväksy tuntematon + accept contact request via notification + + + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. + Lisää osoite profiiliisi, jotta kontaktisi voivat jakaa sen muiden kanssa. Profiilipäivitys lähetetään kontakteillesi. No comment provided by engineer. - - Connect incognito - Yhdistä Incognito + + Add preset servers + Lisää esiasetettuja palvelimia No comment provided by engineer. - - Custom time - Mukautettu aika + + Add profile + Lisää profiili No comment provided by engineer. - - Don't create address - Älä luo osoitetta + + Add servers by scanning QR codes. + Lisää palvelimia skannaamalla QR-koodeja. No comment provided by engineer. - - Encrypted message: database migration error - Salattu viesti: tietokannan siirtovirhe - notification - - - Fix connection - Korjaa yhteys + + Add server… + Lisää palvelin… No comment provided by engineer. - - Fix connection? - Korjaa yhteys? + + Add to another device + Lisää toiseen laitteeseen No comment provided by engineer. - - Fix not supported by contact - Kontakti ei tue korjausta + + Add welcome message + Lisää tervetuloviesti No comment provided by engineer. - - Fix not supported by group member - Ryhmän jäsen ei tue korjausta + + Address + Osoite No comment provided by engineer. - - Only you can add message reactions. - Vain sinä voit lisätä viestireaktioita. + + Address change will be aborted. Old receiving address will be used. + Osoitteenmuutos keskeytetään. Käytetään vanhaa vastaanotto-osoitetta. No comment provided by engineer. - - Only you can make calls. - Vain sinä voit soittaa puheluita. + + Admins can create the links to join groups. + Ylläpitäjät voivat luoda linkkejä ryhmiin liittymiseen. No comment provided by engineer. - - Paste the link you received to connect with your contact. - Liitä saamasi linkki, jonka avulla voit muodostaa yhteyden kontaktiisi. - placeholder - - - Please remember or store it securely - there is no way to recover a lost passcode! - Muista tai säilytä se turvallisesti - kadonnutta pääsykoodia ei voi palauttaa! + + Advanced network settings + Verkon lisäasetukset No comment provided by engineer. - - Profile update will be sent to your contacts. - Profiilipäivitys lähetetään kontakteillesi. + + All app data is deleted. + Kaikki sovelluksen tiedot poistetaan. No comment provided by engineer. - - Prohibit sending files and media. - Estä tiedostojen ja median lähettäminen. + + All chats and messages will be deleted - this cannot be undone! + Kaikki keskustelut ja viestit poistetaan - tätä ei voi kumota! No comment provided by engineer. - - Receipts are disabled - Kuittaukset pois käytöstä + + All data is erased when it is entered. + Kaikki tiedot poistetaan, kun se syötetään. No comment provided by engineer. - - Record updated at: %@ - Tietue päivitetty klo: %@ - copied message info - - - Reject (sender NOT notified) - Hylkää (lähettäjälle EI ilmoiteta) + + All group members will remain connected. + Kaikki ryhmän jäsenet pysyvät yhteydessä. No comment provided by engineer. - - Renegotiate encryption - Uudelleenneuvottele salaus + + All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. + Kaikki viestit poistetaan - tätä ei voi kumota! Viestit poistuvat VAIN sinulta. No comment provided by engineer. - - Save settings? - Tallenna asetukset? + + All your contacts will remain connected. + Kaikki kontaktisi pysyvät yhteydessä. No comment provided by engineer. - - Self-destruct - Itsetuho + + All your contacts will remain connected. Profile update will be sent to your contacts. + Kaikki kontaktisi pysyvät yhteydessä. Profiilipäivitys lähetetään kontakteillesi. No comment provided by engineer. - - Send disappearing message - Lähetä katoava viesti + + Allow + Salli No comment provided by engineer. - - Send receipts - Lähetä kuittaukset + + Allow calls only if your contact allows them. + Salli puhelut vain, jos kontaktisi sallii ne. No comment provided by engineer. - - Sending receipts is disabled for %lld groups - Kuittien lähettäminen ei ole käytössä %lld ryhmille + + Allow disappearing messages only if your contact allows it to you. + Salli katoavat viestit vain, jos kontaktisi sallii sen sinulle. No comment provided by engineer. - - Show: - Näytä: + + Allow irreversible message deletion only if your contact allows it to you. + Salli peruuttamaton viestien poisto vain, jos kontaktisi sallii ne sinulle. No comment provided by engineer. - - SimpleX address - SimpleX-osoite + + Allow message reactions only if your contact allows them. + Salli reaktiot viesteihin vain, jos kontaktisi sallii ne. No comment provided by engineer. - - Some non-fatal errors occurred during import - you may see Chat console for more details. - Tuonnin aikana tapahtui joitakin ei-vakavia virheitä – saatat nähdä Chat-konsolissa lisätietoja. + + Allow message reactions. + Salli viestireaktiot. No comment provided by engineer. - - They can be overridden in contact and group settings. - Ne voidaan ohittaa kontakti- ja ryhmäasetuksissa. + + Allow sending direct messages to members. + Salli yksityisviestien lähettäminen jäsenille. No comment provided by engineer. - - This group has over %lld members, delivery receipts are not sent. - Tässä ryhmässä on yli %lld jäsentä, lähetyskuittauksia ei lähetetä. + + Allow sending disappearing messages. + Salli katoavien viestien lähettäminen. No comment provided by engineer. - - Use new incognito profile - Käytä uutta incognito-profiilia + + Allow to irreversibly delete sent messages. + Salli lähetettyjen viestien peruuttamaton poistaminen. No comment provided by engineer. - - Waiting for video - Odottaa videota + + Allow to send files and media. + Salli tiedostojen ja median lähettäminen. No comment provided by engineer. - - You invited a contact - Kutsuit kontaktin + + Allow to send voice messages. + Salli ääniviestien lähettäminen. No comment provided by engineer. - - agreeing encryption… - hyväksyy salausta… - chat item text - - - disabled - ei käytössä + + Allow voice messages only if your contact allows them. + Salli ääniviestit vain, jos kontaktisi sallii ne. No comment provided by engineer. - - encryption ok for %@ - salaus ok %@:lle - chat item text - - - encryption re-negotiation allowed - salauksen uudelleenneuvottelu sallittu - chat item text - - - minutes - minuuttia - time unit - - - Initial role - Alkuperäinen rooli + + Allow voice messages? + Salli ääniviestit? No comment provided by engineer. - - Don't enable - Älä salli + + Allow your contacts adding message reactions. + Salli kontaktiesi lisätä viestireaktioita. No comment provided by engineer. - - Enable lock - Ota lukitus käyttöön + + Allow your contacts to call you. + Salli kontaktiesi soittaa sinulle. No comment provided by engineer. - - Enable self-destruct - Ota itsetuho käyttöön + + Allow your contacts to irreversibly delete sent messages. + Salli kontaktiesi poistaa lähetetyt viestit peruuttamattomasti. No comment provided by engineer. - - Error enabling delivery receipts! - Virhe toimituskuittauksien sallimisessa! + + Allow your contacts to send disappearing messages. + Salli kontaktiesi lähettää katoavia viestejä. No comment provided by engineer. - - Error setting delivery receipts! - Virhe toimituskuittauksien asettamisessa! + + Allow your contacts to send voice messages. + Salli kontaktiesi lähettää ääniviestejä. No comment provided by engineer. - - Sent message - Lähetetty viesti - message info title - - - Server requires authorization to upload, check password - Palvelin vaatii valtuutuksen tiedoston lataamiseksi, tarkista salasana - server test error - - - Set it instead of system authentication. - Aseta se järjestelmän todennuksen sijaan. + + Already connected? + Oletko jo muodostanut yhteyden? No comment provided by engineer. - - Share address with contacts? - Jaa osoite kontakteille? + + Always use relay + Käytä aina relettä No comment provided by engineer. - - Share 1-time link - Jaa kertakäyttölinkki + + An empty chat profile with the provided name is created, and the app opens as usual. + Luodaan tyhjä chat-profiili annetulla nimellä, ja sovellus avautuu normaalisti. No comment provided by engineer. - - Show last messages - Näytä viimeiset viestit + + Answer call + Vastaa puheluun No comment provided by engineer. - - Stop receiving file? - Lopeta tiedoston vastaanottaminen? + + App build: %@ + Sovellusversio: %@ No comment provided by engineer. - - SimpleX Lock not enabled! - SimpleX Lock ei ole käytössä! + + App encrypts new local files (except videos). No comment provided by engineer. - - Small groups (max 20) - Pienryhmät (max 20) + + App icon + Sovelluksen kuvake No comment provided by engineer. - - Stop sending file? - Lopeta tiedoston lähettäminen? + + App passcode + Sovelluksen pääsykoodi No comment provided by engineer. - - Submit - Lähetä + + App passcode is replaced with self-destruct passcode. + Sovelluksen pääsykoodi korvataan itsetuhoutuvalla pääsykoodilla. No comment provided by engineer. - - System authentication - Järjestelmän todennus + + App version + Sovellusversio No comment provided by engineer. - - These settings are for your current profile **%@**. - Nämä asetukset koskevat nykyistä profiiliasi **%@**. + + App version: v%@ + Sovellusversio: v%@ No comment provided by engineer. - - Passcode - Pääsykoodi + + Appearance + Ulkonäkö No comment provided by engineer. - - Please report it to the developers. - Ilmoita siitä kehittäjille. + + Attach + Liitä No comment provided by engineer. - - Profile password - Profiilin salasana + + Audio & video calls + Ääni- ja videopuhelut No comment provided by engineer. - - Prohibit audio/video calls. - Estä ääni- ja videopuhelut. + + Audio and video calls + Ääni- ja videopuhelut No comment provided by engineer. - - Prohibit message reactions. - Estä viestireaktiot. - No comment provided by engineer. - - - Prohibit messages reactions. - Estä viestireaktiot. - No comment provided by engineer. - - - React… - Reagoi… - chat item menu - - - Read more - Lue lisää - No comment provided by engineer. - - - Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). - Lue lisää [Käyttöoppaasta](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). - No comment provided by engineer. - - - Received message - Vastaanotettu viesti - message info title - - - Invite friends - Kutsu ystäviä - No comment provided by engineer. - - - Invalid status - Virheellinen tila - item status text - - - Files and media - Tiedostot ja media + + Audio/video calls + Ääni/videopuhelut chat feature - - Files and media prohibited! - Tiedostot ja media kielletty! + + Audio/video calls are prohibited. + Ääni-/videopuhelut ovat kiellettyjä. No comment provided by engineer. - - Finally, we have them! 🚀 - Vihdoinkin meillä! 🚀 + + Authentication cancelled + Tunnistautuminen peruutettu + PIN entry + + + Authentication failed + Tunnistautuminen epäonnistui No comment provided by engineer. - - Filter unread and favorite chats. - Suodata lukemattomia- ja suosikkikeskusteluja. + + Authentication is required before the call is connected, but you may miss calls. + Tunnistautuminen vaaditaan ennen kuin puhelu yhdistetään, mutta puheluita voi jäädä vastaamatta. No comment provided by engineer. - - Fix - Korjaa + + Authentication unavailable + Tunnistautuminen ei ole käytettävissä No comment provided by engineer. - - Find chats faster - Löydä keskustelut nopeammin + + Auto-accept + Hyväksy automaattisesti No comment provided by engineer. - - Group members can add message reactions. - Ryhmän jäsenet voivat lisätä viestireaktioita. + + Auto-accept contact requests + Hyväksy yhteydenottopyynnöt automaattisesti No comment provided by engineer. - - If you enter your self-destruct passcode while opening the app: - Jos syötät itsetuhoutuvan pääsykoodin sovellusta avattaessa: + + Auto-accept images + Hyväksy kuvat automaattisesti No comment provided by engineer. - - Japanese interface - Japanilainen käyttöliittymä + + Back + Takaisin No comment provided by engineer. - - Make one message disappear - Hävitä yksi viesti + + Bad message ID + Virheellinen viestin tunniste No comment provided by engineer. - - Message reactions are prohibited in this group. - Viestireaktiot ovat kiellettyjä tässä ryhmässä. + + Bad message hash + Virheellinen viestin tarkiste No comment provided by engineer. - - Sending delivery receipts will be enabled for all contacts in all visible chat profiles. - Toimituskuittauksien lähettäminen otetaan käyttöön kaikille kontakteille näkyvissä keskusteluprofiileissa. + + Better messages + Parempia viestejä No comment provided by engineer. - - Sending delivery receipts will be enabled for all contacts. - Toimituskuittauksien lähettäminen otetaan käyttöön kaikille kontakteille. + + Both you and your contact can add message reactions. + Sekä sinä että kontaktisi voivat käyttää viestireaktioita. No comment provided by engineer. - - Sending receipts is disabled for %lld contacts - Kuittauksien lähettäminen ei ole käytössä %lld kontakteille + + Both you and your contact can irreversibly delete sent messages. + Sekä sinä että kontaktisi voitte peruuttamattomasti poistaa lähetetyt viestit. No comment provided by engineer. - - Sent at - Lähetetty klo + + Both you and your contact can make calls. + Sekä sinä että kontaktisi voitte soittaa puheluita. No comment provided by engineer. - - Unhide chat profile - Näytä keskusteluprofiili + + Both you and your contact can send disappearing messages. + Sekä sinä että kontaktisi voitte lähettää katoavia viestejä. No comment provided by engineer. - - Upload file - Lataa tiedosto - server test step - - - Use current profile - Käytä nykyistä profiilia + + Both you and your contact can send voice messages. + Sekä sinä että kontaktisi voitte lähettää ääniviestejä. No comment provided by engineer. - - You can share your address as a link or QR code - anybody can connect to you. - Voit jakaa osoitteesi linkkinä tai QR-koodina - kuka tahansa voi muodostaa yhteyden sinuun. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! No comment provided by engineer. - - You can turn on SimpleX Lock via Settings. - Voit ottaa SimpleX Lockin käyttöön Asetusten kautta. + + By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). + Chat-profiilin mukaan (oletus) tai [yhteyden mukaan](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). No comment provided by engineer. - - Your contacts will remain connected. - Kontaktisi pysyvät yhdistettyinä. + + Call already ended! + Puhelu on jo päättynyt! No comment provided by engineer. - - Decryption error - Salauksen purkuvirhe - message decrypt error item - - - Delete chat profile - Poista keskusteluprofiili + + Calls + Puhelut No comment provided by engineer. - - Let's talk in SimpleX Chat - Jutellaan SimpleX Chatissa - email subject - - - Your SimpleX address - SimpleX-osoitteesi + + Can't delete user profile! + Käyttäjäprofiilia ei voi poistaa! No comment provided by engineer. - - Unit - Yksikkö + + Can't invite contact! + Kontaktia ei voi kutsua! No comment provided by engineer. - - Enter welcome message… (optional) - Kirjoita tervetuloviesti... (valinnainen) - placeholder - - - The hash of the previous message is different. - Edellisen viestin tarkiste on erilainen. + + Can't invite contacts! + Kontakteja ei voi kutsua! No comment provided by engineer. - - Unlock app - Avaa sovellus + + Cancel + Peruuta + No comment provided by engineer. + + + Cannot access keychain to save database password + Ei pääsyä avainnippuun tietokannan salasanan tallentamiseksi + No comment provided by engineer. + + + Cannot receive file + Tiedostoa ei voi vastaanottaa + No comment provided by engineer. + + + Change + Muuta + No comment provided by engineer. + + + Change database passphrase? + Muutetaanko tietokannan tunnuslause? + No comment provided by engineer. + + + Change lock mode + Vaihda lukitustilaa authentication reason - - You can create it later - Voit luoda sen myöhemmin + + Change member role? + Vaihda jäsenroolia? No comment provided by engineer. - - Delete file - Poista tiedosto + + Change passcode + Vaihda pääsykoodi + authentication reason + + + Change receiving address + Vaihda vastaanotto-osoitetta + No comment provided by engineer. + + + Change receiving address? + Vaihda vastaanotto-osoite? + No comment provided by engineer. + + + Change role + Vaihda rooli + No comment provided by engineer. + + + Change self-destruct mode + Vaihda itsetuhotilaa + authentication reason + + + Change self-destruct passcode + Vaihda itsetuhoutuva pääsykoodi + authentication reason + set passcode view + + + Chat archive + Chat-arkisto + No comment provided by engineer. + + + Chat console + Chat-konsoli + No comment provided by engineer. + + + Chat database + Chat-tietokanta + No comment provided by engineer. + + + Chat database deleted + Chat-tietokanta poistettu + No comment provided by engineer. + + + Chat database imported + Chat-tietokanta tuotu + No comment provided by engineer. + + + Chat is running + Chat on käynnissä + No comment provided by engineer. + + + Chat is stopped + Chat on pysäytetty + No comment provided by engineer. + + + Chat preferences + Chat-asetukset + No comment provided by engineer. + + + Chats + Keskustelut + No comment provided by engineer. + + + Check server address and try again. + Tarkista palvelimen osoite ja yritä uudelleen. + No comment provided by engineer. + + + Chinese and Spanish interface + Kiinalainen ja espanjalainen käyttöliittymä + No comment provided by engineer. + + + Choose file + Valitse tiedosto + No comment provided by engineer. + + + Choose from library + Valitse kirjastosta + No comment provided by engineer. + + + Clear + Tyhjennä + No comment provided by engineer. + + + Clear conversation + Tyhjennä keskustelu + No comment provided by engineer. + + + Clear conversation? + Tyhjennä keskustelu? + No comment provided by engineer. + + + Clear verification + Tyhjennä vahvistus + No comment provided by engineer. + + + Colors + Värit + No comment provided by engineer. + + + Compare file + Vertaa tiedostoa server test step - - Delivery receipts are disabled! - Toimituskuittaukset poissa käytöstä! + + Compare security codes with your contacts. + Vertaa turvakoodeja kontaktiesi kanssa. No comment provided by engineer. - - Disable (keep overrides) - Poista käytöstä (pidä ohitukset) + + Configure ICE servers + Määritä ICE-palvelimet No comment provided by engineer. - - Disable for all - Poista käytöstä kaikilta + + Confirm + Vahvista No comment provided by engineer. - - Disappearing message - Tuhoutuva viesti + + Confirm Passcode + Vahvista pääsykoodi No comment provided by engineer. - - Disappears at: %@ - Katoaa klo: %@ - copied message info - - - Enable (keep overrides) - Salli (pidä ohitukset) + + Confirm database upgrades + Vahvista tietokannan päivitykset No comment provided by engineer. - - Error synchronizing connection - Virhe yhteyden synkronoinnissa + + Confirm new passphrase… + Vahvista uusi tunnuslause… No comment provided by engineer. - - Even when disabled in the conversation. - Jopa kun ei käytössä keskustelussa. + + Confirm password + Vahvista salasana No comment provided by engineer. - - Favorite - Suosikki + + Connect + Yhdistä + server test step + + + Connect directly + Yhdistä suoraan No comment provided by engineer. - - File will be deleted from servers. - Tiedosto poistetaan palvelimilta. + + Connect incognito + Yhdistä Incognito No comment provided by engineer. - - Fix encryption after restoring backups. - Korjaa salaus varmuuskopioiden palauttamisen jälkeen. + + Connect via contact link + Yhdistä kontaktilinkillä No comment provided by engineer. - - If you enter this passcode when opening the app, all app data will be irreversibly removed! - Jos syötät tämän pääsykoodin sovellusta avatessasi, kaikki sovelluksen tiedot poistetaan peruuttamattomasti! + + Connect via group link? + Yhdistetäänkö ryhmälinkin kautta? No comment provided by engineer. - - Info - Tiedot + + Connect via link + Yhdistä linkin kautta + No comment provided by engineer. + + + Connect via link / QR code + Yhdistä linkillä / QR-koodilla + No comment provided by engineer. + + + Connect via one-time link + Yhdistä kertalinkillä + No comment provided by engineer. + + + Connecting to server… + Yhteyden muodostaminen palvelimeen… + No comment provided by engineer. + + + Connecting to server… (error: %@) + Yhteyden muodostaminen palvelimeen... (virhe: %@) + No comment provided by engineer. + + + Connection + Yhteys + No comment provided by engineer. + + + Connection error + Yhteysvirhe + No comment provided by engineer. + + + Connection error (AUTH) + Yhteysvirhe (AUTH) + No comment provided by engineer. + + + Connection request sent! + Yhteyspyyntö lähetetty! + No comment provided by engineer. + + + Connection timeout + Yhteyden aikakatkaisu + No comment provided by engineer. + + + Contact allows + Kontakti sallii + No comment provided by engineer. + + + Contact already exists + Kontakti on jo olemassa + No comment provided by engineer. + + + Contact and all messages will be deleted - this cannot be undone! + Kontakti ja kaikki viestit poistetaan - tätä ei voi perua! + No comment provided by engineer. + + + Contact hidden: + Kontakti piilotettu: + notification + + + Contact is connected + Kontakti on yhdistetty + notification + + + Contact is not connected yet! + Kontaktia ei ole vielä yhdistetty! + No comment provided by engineer. + + + Contact name + Kontaktin nimi + No comment provided by engineer. + + + Contact preferences + Kontaktin asetukset + No comment provided by engineer. + + + Contacts + Kontaktit + No comment provided by engineer. + + + Contacts can mark messages for deletion; you will be able to view them. + Kontaktit voivat merkitä viestit poistettaviksi; voit katsella niitä. + No comment provided by engineer. + + + Continue + Jatka + No comment provided by engineer. + + + Copy + Kopioi chat item action - - Migrating database archive… - Siirretään tietokannan arkistoa… + + Core version: v%@ + Ydinversio: v%@ No comment provided by engineer. - - No filtered chats - Ei suodatettuja keskusteluja + + Create + Luo No comment provided by engineer. - - Only group owners can enable files and media. - Vain ryhmän omistajat voivat sallia tiedostoja ja mediaa. + + Create SimpleX address + Luo SimpleX-osoite No comment provided by engineer. - - Passcode changed! - Pääsykoodi vaihdettu! + + Create an address to let people connect with you. + Luo osoite, jolla ihmiset voivat ottaa sinuun yhteyttä. No comment provided by engineer. - - Permanent decryption error - Pysyvä salauksen purkuvirhe - message decrypt error item + + Create file + Luo tiedosto + server test step - - Protocol timeout per KB - Protokollan aikakatkaisu per KB + + Create group link + Luo ryhmälinkki No comment provided by engineer. - - Receiving address will be changed to a different server. Address change will complete after sender comes online. - Vastaanotto-osoite vaihdetaan toiseen palvelimeen. Osoitteenmuutos tehdään sen jälkeen, kun lähettäjä tulee verkkoon. + + Create link + Luo linkki No comment provided by engineer. - - Reconnect servers? - Yhdistä palvelimet uudelleen? + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Record updated at - Tietue päivitetty klo + + Create one-time invitation link + Luo kertakutsulinkki No comment provided by engineer. - - Renegotiate - Neuvottele uudelleen + + Create queue + Luo jono + server test step + + + Create secret group + Luo salainen ryhmä No comment provided by engineer. - - Send delivery receipts to - Lähetä toimituskuittaukset vastaanottajalle + + Create your profile + Luo profiilisi No comment provided by engineer. - - Self-destruct passcode changed! - Itsetuhoutuva pääsykoodi vaihdettu! + + Created on %@ + Luotu %@ No comment provided by engineer. - - Sending file will be stopped. - Tiedoston lähettäminen lopetetaan. + + Current Passcode + Nykyinen pääsykoodi No comment provided by engineer. - - Stop file - Pysäytä tiedosto - cancel file action - - - Stop sharing - Lopeta jakaminen + + Current passphrase… + Nykyinen tunnuslause… No comment provided by engineer. - - Stop sharing address? - Lopeta osoitteen jakaminen? + + Currently maximum supported file size is %@. + Nykyinen tuettu enimmäistiedostokoko on %@. No comment provided by engineer. - - The second tick we missed! ✅ - Toinen kuittaus, joka uupui! ✅ + + Custom time + Mukautettu aika No comment provided by engineer. - - To connect, your contact can scan QR code or use the link in the app. - Kontaktisi voi muodostaa yhteyden skannaamalla QR-koodin tai käyttämällä sovelluksessa olevaa linkkiä. + + Dark + Tumma No comment provided by engineer. - - Unfav. - Epäsuotuisa. + + Database ID + Tietokannan tunnus No comment provided by engineer. - - Unhide profile - Näytä profiili - No comment provided by engineer. - - - Videos and files up to 1gb - Videot ja tiedostot 1 Gt asti - No comment provided by engineer. - - - When people request to connect, you can accept or reject it. - Kun ihmiset pyytävät yhteyden muodostamista, voit hyväksyä tai hylätä sen. - No comment provided by engineer. - - - You can enable them later via app Privacy & Security settings. - Voit ottaa ne käyttöön myöhemmin sovelluksen Yksityisyys & Turvallisuus -asetuksista. - No comment provided by engineer. - - - You won't lose your contacts if you later delete your address. - Et menetä kontaktejasi, jos poistat osoitteesi myöhemmin. - No comment provided by engineer. - - - Your %@ servers - %@-palvelimesi - No comment provided by engineer. - - - Your XFTP servers - XFTP-palvelimesi - No comment provided by engineer. - - - changing address for %@… - osoitteen muuttaminen %@:lle… - chat item text - - - changing address… - muuttamassa osoitetta… - chat item text - - - default (no) - oletusarvo (ei) - No comment provided by engineer. - - - default (yes) - oletusarvo (kyllä) - No comment provided by engineer. - - - database version is newer than the app, but no down migration for: %@ - tietokantaversio on uudempi kuin sovellus, mutta ei alaspäin siirtymistä varten: %@ - No comment provided by engineer. - - - encryption agreed for %@ - salaus sovittu %@:lle - chat item text - - - encryption ok - salaus ok - chat item text - - - encryption agreed - salaus sovittu - chat item text - - - encryption re-negotiation required for %@ - tarvitaan salauksen uudelleenneuvottelu %@:lle - chat item text - - - hours - tuntia - time unit - - - months - kuukautta - time unit - - - Enable self-destruct passcode - Ota itsetuhoava pääsykoodi käyttöön - set passcode view - - - Hide: - Piilota: - No comment provided by engineer. - - - Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). - Lue lisää [Käyttöoppaasta](https://simplex.chat/docs/guide/readme.html#connect-to-friends). - No comment provided by engineer. - - - Received at - Vastaanotettu klo - No comment provided by engineer. - - - Received at: %@ - Vastaanotettu klo: %@ + + Database ID: %d + Tietokannan tunnus: %d copied message info - + + Database IDs and Transport isolation option. + Tietokantatunnukset ja kuljetuseristysvaihtoehto. + No comment provided by engineer. + + + Database downgrade + Tietokannan alentaminen + No comment provided by engineer. + + + Database encrypted! + Tietokanta salattu! + No comment provided by engineer. + + + Database encryption passphrase will be updated and stored in the keychain. + + Tietokannan salaustunnuslause päivitetään ja tallennetaan avainnippuun. + + No comment provided by engineer. + + + Database encryption passphrase will be updated. + + Tietokannan salauksen tunnuslause päivitetään. + + No comment provided by engineer. + + + Database error + Tietokantavirhe + No comment provided by engineer. + + + Database is encrypted using a random passphrase, you can change it. + Tietokanta on salattu satunnaisella tunnuslauseella, voit muuttaa sitä. + No comment provided by engineer. + + + Database is encrypted using a random passphrase. Please change it before exporting. + Tietokanta on salattu satunnaisella tunnuslauseella. Vaihda se ennen vientiä. + No comment provided by engineer. + + + Database passphrase + Tietokannan tunnuslause + No comment provided by engineer. + + + Database passphrase & export + Tietokannan tunnuslause ja vienti + No comment provided by engineer. + + + Database passphrase is different from saved in the keychain. + Tietokannan tunnuslause eroaa avainnippuun tallennetusta. + No comment provided by engineer. + + + Database passphrase is required to open chat. + Keskustelun avaamiseen tarvitaan tietokannan tunnuslause. + No comment provided by engineer. + + + Database upgrade + Tietokannan päivitys + No comment provided by engineer. + + + Database will be encrypted and the passphrase stored in the keychain. + + Tietokanta salataan ja tunnuslause tallennetaan avainnippuun. + + No comment provided by engineer. + + + Database will be encrypted. + + Tietokanta salataan. + + No comment provided by engineer. + + + Database will be migrated when the app restarts + Tietokanta siirretään, kun sovellus käynnistyy uudelleen + No comment provided by engineer. + + + Decentralized + Hajautettu + No comment provided by engineer. + + + Decryption error + Salauksen purkuvirhe + message decrypt error item + + + Delete + Poista + chat item action + + + Delete Contact + Poista kontakti + No comment provided by engineer. + + + Delete address + Poista osoite + No comment provided by engineer. + + + Delete address? + Poista osoite? + No comment provided by engineer. + + + Delete after + Poista jälkeen + No comment provided by engineer. + + + Delete all files + Poista kaikki tiedostot + No comment provided by engineer. + + + Delete archive + Poista arkisto + No comment provided by engineer. + + + Delete chat archive? + Poista keskusteluarkisto? + No comment provided by engineer. + + + Delete chat profile + Poista keskusteluprofiili + No comment provided by engineer. + + + Delete chat profile? + Poista keskusteluprofiili? + No comment provided by engineer. + + + Delete connection + Poista yhteys + No comment provided by engineer. + + + Delete contact + Poista kontakti + No comment provided by engineer. + + + Delete contact? + Poista kontakti? + No comment provided by engineer. + + + Delete database + Poista tietokanta + No comment provided by engineer. + + + Delete file + Poista tiedosto + server test step + + + Delete files and media? + Poista tiedostot ja media? + No comment provided by engineer. + + + Delete files for all chat profiles + Poista tiedostot kaikista keskusteluprofiileista + No comment provided by engineer. + + + Delete for everyone + Poista kaikilta + chat feature + + + Delete for me + Poista minulta + No comment provided by engineer. + + + Delete group + Poista ryhmä + No comment provided by engineer. + + + Delete group? + Poista ryhmä? + No comment provided by engineer. + + + Delete invitation + Poista kutsu + No comment provided by engineer. + + + Delete link + Poista linkki + No comment provided by engineer. + + + Delete link? + Poista linkki? + No comment provided by engineer. + + + Delete member message? + Poista jäsenviesti? + No comment provided by engineer. + + + Delete message? + Poista viesti? + No comment provided by engineer. + + + Delete messages + Poista viestit + No comment provided by engineer. + + + Delete messages after + Poista viestit tämän jälkeen + No comment provided by engineer. + + + Delete old database + Poista vanha tietokanta + No comment provided by engineer. + + + Delete old database? + Poista vanha tietokanta? + No comment provided by engineer. + + + Delete pending connection + Poista vireillä oleva yhteys + No comment provided by engineer. + + + Delete pending connection? + Poistetaanko odottava yhteys? + No comment provided by engineer. + + Delete profile - Poista profiili + Poista profiili No comment provided by engineer. - - Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@). - Varmista, että %@-palvelinosoitteet ovat oikeassa muodossa, että ne on erotettu toisistaan riveittäin ja että ne eivät ole päällekkäisiä (%@). + + Delete queue + Poista jono + server test step + + + Delete user profile? + Poista käyttäjäprofiili? No comment provided by engineer. - - Receiving file will be stopped. - Tiedoston vastaanotto pysäytetään. + + Deleted at + Poistettu klo No comment provided by engineer. - - Revoke file - Peruuta tiedosto - cancel file action + + Deleted at: %@ + Poistettu klo: %@ + copied message info - - Revoke file? - Peruuta tiedosto? + + Delivery + Toimitus No comment provided by engineer. - - %1$@ at %2$@: - %1$@ klo %2$@: - copied message info, <sender> at <time> + + Delivery receipts are disabled! + Toimituskuittaukset poissa käytöstä! + No comment provided by engineer. - + Delivery receipts! - Toimituskuittaukset! + Toimituskuittaukset! No comment provided by engineer. - + + Description + Kuvaus + No comment provided by engineer. + + + Develop + Kehitä + No comment provided by engineer. + + + Developer tools + Kehittäjätyökalut + No comment provided by engineer. + + + Device + Laite + No comment provided by engineer. + + + Device authentication is disabled. Turning off SimpleX Lock. + Laitteen todennus on poistettu käytöstä. SimpleX Lock kytketään pois päältä. + No comment provided by engineer. + + + Device authentication is not enabled. You can turn on SimpleX Lock via Settings, once you enable device authentication. + Laitteen todennus ei ole käytössä. Voit ottaa SimpleX Lockin käyttöön Asetuksista, kun olet ottanut laitteen todennuksen käyttöön. + No comment provided by engineer. + + + Different names, avatars and transport isolation. + Eri nimet, avatarit ja kuljetuseristys. + No comment provided by engineer. + + + Direct messages + Yksityisviestit + chat feature + + + Direct messages between members are prohibited in this group. + Yksityisviestit jäsenten välillä ovat kiellettyjä tässä ryhmässä. + No comment provided by engineer. + + + Disable (keep overrides) + Poista käytöstä (pidä ohitukset) + No comment provided by engineer. + + + Disable SimpleX Lock + Poista SimpleX Lock käytöstä + authentication reason + + + Disable for all + Poista käytöstä kaikilta + No comment provided by engineer. + + + Disappearing message + Tuhoutuva viesti + No comment provided by engineer. + + + Disappearing messages + Tuhoutuvat viestit + chat feature + + + Disappearing messages are prohibited in this chat. + Katoavat viestit ovat kiellettyjä tässä keskustelussa. + No comment provided by engineer. + + + Disappearing messages are prohibited in this group. + Katoavat viestit ovat kiellettyjä tässä ryhmässä. + No comment provided by engineer. + + + Disappears at + Katoaa klo + No comment provided by engineer. + + + Disappears at: %@ + Katoaa klo: %@ + copied message info + + + Disconnect + Katkaise + server test step + + + Discover and join groups + No comment provided by engineer. + + + Display name + Näyttönimi + No comment provided by engineer. + + + Display name: + Näyttönimi: + No comment provided by engineer. + + + Do NOT use SimpleX for emergency calls. + Älä käytä SimpleX-sovellusta hätäpuheluihin. + No comment provided by engineer. + + + Do it later + Tee myöhemmin + No comment provided by engineer. + + + Don't create address + Älä luo osoitetta + No comment provided by engineer. + + + Don't enable + Älä salli + No comment provided by engineer. + + + Don't show again + Älä näytä uudelleen + No comment provided by engineer. + + + Downgrade and open chat + Alenna ja avaa keskustelu + No comment provided by engineer. + + + Download file + Lataa tiedosto + server test step + + + Duplicate display name! + Päällekkäinen näyttönimi! + No comment provided by engineer. + + + Duration + Kesto + No comment provided by engineer. + + + Edit + Muokkaa + chat item action + + + Edit group profile + Muokkaa ryhmäprofiilia + No comment provided by engineer. + + + Enable + Salli + No comment provided by engineer. + + + Enable (keep overrides) + Salli (pidä ohitukset) + No comment provided by engineer. + + + Enable SimpleX Lock + Ota SimpleX Lock käyttöön + authentication reason + + + Enable TCP keep-alive + Ota TCP-säilytys käyttöön + No comment provided by engineer. + + + Enable automatic message deletion? + Ota automaattinen viestien poisto käyttöön? + No comment provided by engineer. + + + Enable for all + Salli kaikille + No comment provided by engineer. + + + Enable instant notifications? + Salli välittömät ilmoitukset? + No comment provided by engineer. + + + Enable lock + Ota lukitus käyttöön + No comment provided by engineer. + + + Enable notifications + Salli ilmoitukset + No comment provided by engineer. + + + Enable periodic notifications? + Salli säännölliset ilmoitukset? + No comment provided by engineer. + + + Enable self-destruct + Ota itsetuho käyttöön + No comment provided by engineer. + + + Enable self-destruct passcode + Ota itsetuhoava pääsykoodi käyttöön + set passcode view + + + Encrypt + Salaa + No comment provided by engineer. + + + Encrypt database? + Salaa tietokanta? + No comment provided by engineer. + + + Encrypt local files + Salaa paikalliset tiedostot + No comment provided by engineer. + + + Encrypt stored files & media + No comment provided by engineer. + + + Encrypted database + Salattu tietokanta + No comment provided by engineer. + + + Encrypted message or another event + Salattu viesti tai muu tapahtuma + notification + + + Encrypted message: database error + Salattu viesti: tietokantavirhe + notification + + + Encrypted message: database migration error + Salattu viesti: tietokannan siirtovirhe + notification + + + Encrypted message: keychain error + Salattu viesti: avainnipun virhe + notification + + + Encrypted message: no passphrase + Salattu viesti: ei tunnuslausetta + notification + + + Encrypted message: unexpected error + Salattu viesti: odottamaton virhe + notification + + + Enter Passcode + Syötä pääsykoodi + No comment provided by engineer. + + + Enter correct passphrase. + Anna oikea tunnuslause. + No comment provided by engineer. + + + Enter passphrase… + Syötä tunnuslause… + No comment provided by engineer. + + + Enter password above to show! + Kirjoita yllä oleva salasana näyttääksesi! + No comment provided by engineer. + + + Enter server manually + Syötä palvelin manuaalisesti + No comment provided by engineer. + + + Enter welcome message… + Kirjoita tervetuloviesti… + placeholder + + + Enter welcome message… (optional) + Kirjoita tervetuloviesti... (valinnainen) + placeholder + + + Error + Virhe + No comment provided by engineer. + + + Error aborting address change + Virhe osoitteenmuutoksen keskeytyksessä + No comment provided by engineer. + + + Error accepting contact request + Virhe kontaktipyynnön hyväksymisessä + No comment provided by engineer. + + + Error accessing database file + Virhe tietokantatiedoston käyttämisessä + No comment provided by engineer. + + + Error adding member(s) + Virhe lisättäessä jäseniä + No comment provided by engineer. + + + Error changing address + Virhe osoitteenvaihdossa + No comment provided by engineer. + + + Error changing role + Virhe roolin vaihdossa + No comment provided by engineer. + + + Error changing setting + Virhe asetuksen muuttamisessa + No comment provided by engineer. + + + Error creating address + Virhe osoitteen luomisessa + No comment provided by engineer. + + + Error creating group + Virhe ryhmän luomisessa + No comment provided by engineer. + + + Error creating group link + Virhe ryhmälinkin luomisessa + No comment provided by engineer. + + + Error creating member contact + No comment provided by engineer. + + + Error creating profile! + Virhe profiilin luomisessa! + No comment provided by engineer. + + + Error decrypting file + Virhe tiedoston salauksen purussa + No comment provided by engineer. + + + Error deleting chat database + Virhe keskustelujen tietokannan poistamisessa + No comment provided by engineer. + + + Error deleting chat! + Virhe keskutelun poistamisessa! + No comment provided by engineer. + + + Error deleting connection + Virhe yhteyden poistamisessa + No comment provided by engineer. + + + Error deleting contact + Virhe kontaktin poistamisessa + No comment provided by engineer. + + + Error deleting database + Virhe tietokannan poistamisessa + No comment provided by engineer. + + + Error deleting old database + Virhe vanhan tietokannan poistamisessa + No comment provided by engineer. + + + Error deleting token + Virhe tokenin poistamisessa + No comment provided by engineer. + + + Error deleting user profile + Virhe käyttäjäprofiilin poistamisessa + No comment provided by engineer. + + + Error enabling delivery receipts! + Virhe toimituskuittauksien sallimisessa! + No comment provided by engineer. + + + Error enabling notifications + Virhe ilmoitusten käyttöönotossa + No comment provided by engineer. + + + Error encrypting database + Virhe tietokannan salauksessa + No comment provided by engineer. + + + Error exporting chat database + Virhe vietäessä keskustelujen tietokantaa + No comment provided by engineer. + + + Error importing chat database + Virhe keskustelujen tietokannan tuonnissa + No comment provided by engineer. + + + Error joining group + Virhe ryhmään liittymisessä + No comment provided by engineer. + + + Error loading %@ servers + Virhe %@-palvelimien lataamisessa + No comment provided by engineer. + + + Error receiving file + Virhe tiedoston vastaanottamisessa + No comment provided by engineer. + + + Error removing member + Virhe poistettaessa jäsentä + No comment provided by engineer. + + + Error saving %@ servers + Virhe %@ palvelimien tallentamisessa + No comment provided by engineer. + + + Error saving ICE servers + Virhe ICE-palvelimien tallentamisessa + No comment provided by engineer. + + + Error saving group profile + Virhe ryhmäprofiilin tallentamisessa + No comment provided by engineer. + + + Error saving passcode + Virhe pääsykoodin tallentamisessa + No comment provided by engineer. + + + Error saving passphrase to keychain + Virhe tunnuslauseen tallentamisessa avainnippuun + No comment provided by engineer. + + + Error saving user password + Virhe käyttäjän salasanan tallentamisessa + No comment provided by engineer. + + + Error sending email + Virhe sähköpostin lähettämisessä + No comment provided by engineer. + + + Error sending member contact invitation + No comment provided by engineer. + + + Error sending message + Virhe viestin lähettämisessä + No comment provided by engineer. + + + Error setting delivery receipts! + Virhe toimituskuittauksien asettamisessa! + No comment provided by engineer. + + + Error starting chat + Virhe käynnistettäessä keskustelua + No comment provided by engineer. + + + Error stopping chat + Virhe keskustelun lopettamisessa + No comment provided by engineer. + + + Error switching profile! + Virhe profiilin vaihdossa! + No comment provided by engineer. + + + Error synchronizing connection + Virhe yhteyden synkronoinnissa + No comment provided by engineer. + + + Error updating group link + Virhe ryhmälinkin päivittämisessä + No comment provided by engineer. + + + Error updating message + Virhe viestin päivityksessä + No comment provided by engineer. + + + Error updating settings + Virhe asetusten päivittämisessä + No comment provided by engineer. + + + Error updating user privacy + Virhe päivitettäessä käyttäjän tietosuojaa + No comment provided by engineer. + + + Error: + Virhe: + No comment provided by engineer. + + + Error: %@ + Virhe: %@ + No comment provided by engineer. + + + Error: URL is invalid + Virhe: URL on virheellinen + No comment provided by engineer. + + + Error: no database file + Virhe: ei tietokantatiedostoa + No comment provided by engineer. + + + Even when disabled in the conversation. + Jopa kun ei käytössä keskustelussa. + No comment provided by engineer. + + + Exit without saving + Poistu tallentamatta + No comment provided by engineer. + + + Export database + Vie tietokanta + No comment provided by engineer. + + + Export error: + Vientivirhe: + No comment provided by engineer. + + + Exported database archive. + Viety tietokanta-arkisto. + No comment provided by engineer. + + + Exporting database archive… + Tietokanta-arkiston vienti… + No comment provided by engineer. + + + Failed to remove passphrase + Tunnuslauseen poisto epäonnistui + No comment provided by engineer. + + + Fast and no wait until the sender is online! + Nopea ja ei odotusta, kunnes lähettäjä on online-tilassa! + No comment provided by engineer. + + + Favorite + Suosikki + No comment provided by engineer. + + + File will be deleted from servers. + Tiedosto poistetaan palvelimilta. + No comment provided by engineer. + + + File will be received when your contact completes uploading it. + Tiedosto vastaanotetaan, kun kontaktisi on ladannut sen. + No comment provided by engineer. + + + File will be received when your contact is online, please wait or check later! + Tiedosto vastaanotetaan, kun kontakti on online-tilassa, odota tai tarkista myöhemmin! + No comment provided by engineer. + + + File: %@ + Tiedosto: %@ + No comment provided by engineer. + + + Files & media + Tiedostot & media + No comment provided by engineer. + + + Files and media + Tiedostot ja media + chat feature + + + Files and media are prohibited in this group. + Tiedostot ja media ovat tässä ryhmässä kiellettyjä. + No comment provided by engineer. + + + Files and media prohibited! + Tiedostot ja media kielletty! + No comment provided by engineer. + + + Filter unread and favorite chats. + Suodata lukemattomia- ja suosikkikeskusteluja. + No comment provided by engineer. + + + Finally, we have them! 🚀 + Vihdoinkin meillä! 🚀 + No comment provided by engineer. + + + Find chats faster + Löydä keskustelut nopeammin + No comment provided by engineer. + + + Fix + Korjaa + No comment provided by engineer. + + + Fix connection + Korjaa yhteys + No comment provided by engineer. + + + Fix connection? + Korjaa yhteys? + No comment provided by engineer. + + + Fix encryption after restoring backups. + Korjaa salaus varmuuskopioiden palauttamisen jälkeen. + No comment provided by engineer. + + + Fix not supported by contact + Kontakti ei tue korjausta + No comment provided by engineer. + + + Fix not supported by group member + Ryhmän jäsen ei tue korjausta + No comment provided by engineer. + + + For console + Konsoliin + No comment provided by engineer. + + + French interface + Ranskalainen käyttöliittymä + No comment provided by engineer. + + + Full link + Koko linkki + No comment provided by engineer. + + + Full name (optional) + Koko nimi (valinnainen) + No comment provided by engineer. + + + Full name: + Koko nimi: + No comment provided by engineer. + + + Fully re-implemented - work in background! + Täysin uudistettu - toimii taustalla! + No comment provided by engineer. + + + Further reduced battery usage + Entistä pienempi akun käyttö + No comment provided by engineer. + + + GIFs and stickers + GIFit ja tarrat + No comment provided by engineer. + + + Group + Ryhmä + No comment provided by engineer. + + + Group display name + Ryhmän näyttönimi + No comment provided by engineer. + + + Group full name (optional) + Ryhmän näyttönimi (valinnainen) + No comment provided by engineer. + + + Group image + Ryhmäkuva + No comment provided by engineer. + + + Group invitation + Ryhmän kutsu + No comment provided by engineer. + + + Group invitation expired + Vanhentunut ryhmäkutsu + No comment provided by engineer. + + + Group invitation is no longer valid, it was removed by sender. + Ryhmäkutsu ei ole enää voimassa, lähettäjä poisti sen. + No comment provided by engineer. + + + Group link + Ryhmälinkki + No comment provided by engineer. + + + Group links + Ryhmälinkit + No comment provided by engineer. + + + Group members can add message reactions. + Ryhmän jäsenet voivat lisätä viestireaktioita. + No comment provided by engineer. + + + Group members can irreversibly delete sent messages. + Ryhmän jäsenet voivat poistaa lähetetyt viestit peruuttamattomasti. + No comment provided by engineer. + + + Group members can send direct messages. + Ryhmän jäsenet voivat lähettää suoraviestejä. + No comment provided by engineer. + + + Group members can send disappearing messages. + Ryhmän jäsenet voivat lähettää katoavia viestejä. + No comment provided by engineer. + + + Group members can send files and media. + Ryhmän jäsenet voivat lähettää tiedostoja ja mediaa. + No comment provided by engineer. + + + Group members can send voice messages. + Ryhmän jäsenet voivat lähettää ääniviestejä. + No comment provided by engineer. + + + Group message: + Ryhmäviesti: + notification + + + Group moderation + Ryhmän moderointi + No comment provided by engineer. + + + Group preferences + Ryhmän asetukset + No comment provided by engineer. + + + Group profile + Ryhmäprofiili + No comment provided by engineer. + + + Group profile is stored on members' devices, not on the servers. + Ryhmäprofiili tallennetaan jäsenten laitteille, ei palvelimille. + No comment provided by engineer. + + + Group welcome message + Ryhmän tervetuloviesti + No comment provided by engineer. + + + Group will be deleted for all members - this cannot be undone! + Ryhmä poistetaan kaikilta jäseniltä - tätä ei voi kumota! + No comment provided by engineer. + + + Group will be deleted for you - this cannot be undone! + Ryhmä poistetaan sinulta - tätä ei voi perua! + No comment provided by engineer. + + + Help + Apua + No comment provided by engineer. + + + Hidden + Piilotettu + No comment provided by engineer. + + + Hidden chat profiles + Piilotetut keskusteluprofiilit + No comment provided by engineer. + + + Hidden profile password + Piilotettu profiilin salasana + No comment provided by engineer. + + + Hide + Piilota + chat item action + + + Hide app screen in the recent apps. + Piilota sovellusnäyttö viimeisimmissä sovelluksissa. + No comment provided by engineer. + + + Hide profile + Piilota profiili + No comment provided by engineer. + + + Hide: + Piilota: + No comment provided by engineer. + + + History + Historia + No comment provided by engineer. + + + How SimpleX works + Miten SimpleX toimii + No comment provided by engineer. + + + How it works + Kuinka se toimii + No comment provided by engineer. + + + How to + Miten + No comment provided by engineer. + + + How to use it + Kuinka sitä käytetään + No comment provided by engineer. + + + How to use your servers + Miten käytät palvelimiasi + No comment provided by engineer. + + + ICE servers (one per line) + ICE-palvelimet (yksi per rivi) + No comment provided by engineer. + + + If you can't meet in person, show QR code in a video call, or share the link. + Jos et voi tavata henkilökohtaisesti, näytä QR-koodi videopuhelussa tai jaa linkki. + No comment provided by engineer. + + + If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. + Jos et voi tavata henkilökohtaisesti, voit **skannata QR-koodin videopuhelussa** tai kontaktisi voi jakaa kutsulinkin. + No comment provided by engineer. + + + If you enter this passcode when opening the app, all app data will be irreversibly removed! + Jos syötät tämän pääsykoodin sovellusta avatessasi, kaikki sovelluksen tiedot poistetaan peruuttamattomasti! + No comment provided by engineer. + + + If you enter your self-destruct passcode while opening the app: + Jos syötät itsetuhoutuvan pääsykoodin sovellusta avattaessa: + No comment provided by engineer. + + + If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app). + Jos haluat käyttää keskustelua nyt, napauta **Tee se myöhemmin** alla (sinulle tarjotaan tietokannan siirtämistä, kun käynnistät sovelluksen uudelleen). + No comment provided by engineer. + + + Ignore + Sivuuta + No comment provided by engineer. + + + Image will be received when your contact completes uploading it. + Kuva vastaanotetaan, kun kontaktisi on ladannut sen. + No comment provided by engineer. + + + Image will be received when your contact is online, please wait or check later! + Kuva vastaanotetaan, kun kontaktisi on verkossa, odota tai tarkista myöhemmin! + No comment provided by engineer. + + + Immediately + Heti + No comment provided by engineer. + + + Immune to spam and abuse + Immuuni roskapostille ja väärinkäytöksille + No comment provided by engineer. + + + Import + Tuo + No comment provided by engineer. + + + Import chat database? + Tuo keskustelujen-tietokanta? + No comment provided by engineer. + + + Import database + Tuo tietokanta + No comment provided by engineer. + + + Improved privacy and security + Parannettu yksityisyys ja turvallisuus + No comment provided by engineer. + + + Improved server configuration + Parannettu palvelimen kokoonpano + No comment provided by engineer. + + + In reply to + Vastauksena + No comment provided by engineer. + + + Incognito + Incognito + No comment provided by engineer. + + + Incognito mode + Incognito-tila + No comment provided by engineer. + + + Incognito mode protects your privacy by using a new random profile for each contact. + Incognito-tila suojaa yksityisyyttäsi käyttämällä uutta satunnaista profiilia jokaiselle kontaktille. + No comment provided by engineer. + + + Incoming audio call + Saapuva äänipuhelu + notification + + + Incoming call + Saapuva puhelu + notification + + + Incoming video call + Saapuva videopuhelu + notification + + + Incompatible database version + Yhteensopimaton tietokantaversio + No comment provided by engineer. + + + Incorrect passcode + Väärä pääsykoodi + PIN entry + + + Incorrect security code! + Väärä turvakoodi! + No comment provided by engineer. + + + Info + Tiedot + chat item action + + + Initial role + Alkuperäinen rooli + No comment provided by engineer. + + + Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat) + Asenna [SimpleX Chat terminaalille](https://github.com/simplex-chat/simplex-chat) + No comment provided by engineer. + + + Instant push notifications will be hidden! + + Välittömät push-ilmoitukset ovat piilossa! + + No comment provided by engineer. + + + Instantly + Heti + No comment provided by engineer. + + + Interface + Käyttöliittymä + No comment provided by engineer. + + + Invalid connection link + Virheellinen yhteyslinkki + No comment provided by engineer. + + + Invalid server address! + Virheellinen palvelinosoite! + No comment provided by engineer. + + + Invalid status + Virheellinen tila + item status text + + + Invitation expired! + Vanhentunut kutsu! + No comment provided by engineer. + + + Invite friends + Kutsu ystäviä + No comment provided by engineer. + + + Invite members + Kutsu jäseniä + No comment provided by engineer. + + + Invite to group + Kutsu ryhmään + No comment provided by engineer. + + + Irreversible message deletion + Peruuttamaton viestin poisto + No comment provided by engineer. + + + Irreversible message deletion is prohibited in this chat. + Viestien peruuttamaton poisto on kielletty tässä keskustelussa. + No comment provided by engineer. + + + Irreversible message deletion is prohibited in this group. + Viestien peruuttamaton poisto on kielletty tässä ryhmässä. + No comment provided by engineer. + + + It allows having many anonymous connections without any shared data between them in a single chat profile. + Se mahdollistaa useiden nimettömien yhteyksien muodostamisen yhdessä keskusteluprofiilissa ilman, että niiden välillä on jaettuja tietoja. + No comment provided by engineer. + + + It can happen when you or your connection used the old database backup. + Se voi tapahtua, kun sinä tai kontaktisi käytitte vanhaa varmuuskopiota tietokannasta. + No comment provided by engineer. + + It can happen when: 1. The messages expired in the sending client after 2 days or on the server after 30 days. 2. Message decryption failed, because you or your contact used old database backup. 3. The connection was compromised. - Se voi tapahtua, kun: + Se voi tapahtua, kun: 1. Viestit vanhenivat lähettävässä päätelaitteessa kahden päivän päästä tai palvelimella 30 päivän kuluttua. 2. Viestin salauksen purku epäonnistui, koska sinä tai kontaktisi käytitte vanhaa varmuuskopiota tietokannasta. 3. Yhteys vaarantui. No comment provided by engineer. - - Preview - Esikatselu + + It seems like you are already connected via this link. If it is not the case, there was an error (%@). + Näyttäisi, että olet jo yhteydessä tämän linkin kautta. Jos näin ei ole, tapahtui virhe (%@). No comment provided by engineer. - - SimpleX Address - SimpleX-osoite + + Italian interface + Italialainen käyttöliittymä No comment provided by engineer. - - %@, %@ and %lld other members connected - %@, %@ ja %lld muut jäsenet yhdistetty + + Japanese interface + Japanilainen käyttöliittymä No comment provided by engineer. - - Connect via contact link - Yhdistä kontaktilinkillä + + Join + Liity No comment provided by engineer. - - Connect via one-time link - Yhdistä kertalinkillä + + Join group + Liity ryhmään No comment provided by engineer. - - Database ID: %d - Tietokannan tunnus: %d - copied message info - - - Delivery - Toimitus + + Join incognito + Liity incognito-tilassa No comment provided by engineer. - - Disappears at - Katoaa klo + + Joining group + Liittyy ryhmään No comment provided by engineer. - - Download file - Lataa tiedosto - server test step - - - Enable for all - Salli kaikille - No comment provided by engineer. - - - Enter welcome message… - Kirjoita tervetuloviesti… - placeholder - - - Error aborting address change - Virhe osoitteenmuutoksen keskeytyksessä - No comment provided by engineer. - - - Error loading %@ servers - Virhe %@-palvelimien lataamisessa - No comment provided by engineer. - - - Error saving %@ servers - Virhe %@ palvelimien tallentamisessa - No comment provided by engineer. - - - Error saving passcode - Virhe pääsykoodin tallentamisessa - No comment provided by engineer. - - - Error sending email - Virhe sähköpostin lähettämisessä - No comment provided by engineer. - - - Error: - Virhe: - No comment provided by engineer. - - - Exporting database archive… - Tietokanta-arkiston vienti… - No comment provided by engineer. - - - Fast and no wait until the sender is online! - Nopea ja ei odotusta, kunnes lähettäjä on online-tilassa! - No comment provided by engineer. - - - Group members can send files and media. - Ryhmän jäsenet voivat lähettää tiedostoja ja mediaa. - No comment provided by engineer. - - - History - Historia - No comment provided by engineer. - - - If you can't meet in person, show QR code in a video call, or share the link. - Jos et voi tavata henkilökohtaisesti, näytä QR-koodi videopuhelussa tai jaa linkki. - No comment provided by engineer. - - - In reply to - Vastauksena - No comment provided by engineer. - - - Incognito mode protects your privacy by using a new random profile for each contact. - Incognito-tila suojaa yksityisyyttäsi käyttämällä uutta satunnaista profiilia jokaiselle kontaktille. - No comment provided by engineer. - - - It can happen when you or your connection used the old database backup. - Se voi tapahtua, kun sinä tai kontaktisi käytitte vanhaa varmuuskopiota tietokannasta. - No comment provided by engineer. - - + Keep your connections - Pidä kontaktisi + Pidä kontaktisi No comment provided by engineer. - + + KeyChain error + Avainnipun virhe + No comment provided by engineer. + + + Keychain error + Avainnipun virhe + No comment provided by engineer. + + + LIVE + LIVE + No comment provided by engineer. + + + Large file! + Suuri tiedosto! + No comment provided by engineer. + + Learn more - Lue lisää + Lue lisää No comment provided by engineer. - + + Leave + Poistu + No comment provided by engineer. + + + Leave group + Poistu ryhmästä + No comment provided by engineer. + + + Leave group? + Poistu ryhmästä? + No comment provided by engineer. + + + Let's talk in SimpleX Chat + Jutellaan SimpleX Chatissa + email subject + + + Light + Vaalea + No comment provided by engineer. + + + Limitations + Rajoitukset + No comment provided by engineer. + + + Live message! + Live-viesti! + No comment provided by engineer. + + + Live messages + Live-viestit + No comment provided by engineer. + + + Local name + Paikallinen nimi + No comment provided by engineer. + + + Local profile data only + Vain paikalliset profiilitiedot + No comment provided by engineer. + + Lock after - Lukitse jälkeen + Lukitse jälkeen No comment provided by engineer. - + Lock mode - Lukitustila + Lukitustila No comment provided by engineer. - + + Make a private connection + Luo yksityinen yhteys + No comment provided by engineer. + + + Make one message disappear + Hävitä yksi viesti + No comment provided by engineer. + + + Make profile private! + Tee profiilista yksityinen! + No comment provided by engineer. + + + Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@). + Varmista, että %@-palvelinosoitteet ovat oikeassa muodossa, että ne on erotettu toisistaan riveittäin ja että ne eivät ole päällekkäisiä (%@). + No comment provided by engineer. + + + Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated. + Varmista, että WebRTC ICE -palvelinosoitteet ovat oikeassa muodossa, rivieroteltuina ja että ne eivät ole päällekkäisiä. + No comment provided by engineer. + + + Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?* + Monet ihmiset kysyivät: *Jos SimpleX:llä ei ole käyttäjätunnuksia, miten se voi toimittaa viestejä?* + No comment provided by engineer. + + + Mark deleted for everyone + Merkitse poistetuksi kaikilta + No comment provided by engineer. + + + Mark read + Merkitse luetuksi + No comment provided by engineer. + + + Mark verified + Merkitse vahvistetuksi + No comment provided by engineer. + + + Markdown in messages + Markdown viesteissä + No comment provided by engineer. + + + Max 30 seconds, received instantly. + Enintään 30 sekuntia, vastaanotetaan välittömästi. + No comment provided by engineer. + + + Member + Jäsen + No comment provided by engineer. + + + Member role will be changed to "%@". All group members will be notified. + Jäsenen rooli muuttuu muotoon "%@". Kaikille ryhmän jäsenille ilmoitetaan asiasta. + No comment provided by engineer. + + + Member role will be changed to "%@". The member will receive a new invitation. + Jäsenen rooli muutetaan muotoon "%@". Jäsen saa uuden kutsun. + No comment provided by engineer. + + + Member will be removed from group - this cannot be undone! + Jäsen poistetaan ryhmästä - tätä ei voi perua! + No comment provided by engineer. + + + Message delivery error + Viestin toimitusvirhe + item status text + + Message delivery receipts! - Viestien toimituskuittaukset! + Viestien toimituskuittaukset! No comment provided by engineer. - + + Message draft + Viestiluonnos + No comment provided by engineer. + + Message reactions - Viestireaktiot + Viestireaktiot chat feature - + Message reactions are prohibited in this chat. - Viestireaktiot ovat kiellettyjä tässä keskustelussa. + Viestireaktiot ovat kiellettyjä tässä keskustelussa. No comment provided by engineer. - + + Message reactions are prohibited in this group. + Viestireaktiot ovat kiellettyjä tässä ryhmässä. + No comment provided by engineer. + + + Message text + Viestin teksti + No comment provided by engineer. + + + Messages + Viestit + No comment provided by engineer. + + + Messages & files + Viestit ja tiedostot + No comment provided by engineer. + + + Migrating database archive… + Siirretään tietokannan arkistoa… + No comment provided by engineer. + + + Migration error: + Siirtovirhe: + No comment provided by engineer. + + + Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat). + Siirto epäonnistui. Jatka nykyisen tietokannan käyttöä napauttamalla alla **Poistu**. Ilmoita ongelmasta sovelluskehittäjille keskustelussa tai sähköpostitse [chat@simplex.chat](mailto:chat@simplex.chat). + No comment provided by engineer. + + + Migration is completed + Siirto on valmis + No comment provided by engineer. + + + Migrations: %@ + Siirrot: %@ + No comment provided by engineer. + + + Moderate + Moderoi + chat item action + + Moderated at - Moderoitu klo + Moderoitu klo No comment provided by engineer. - + + Moderated at: %@ + Moderoitu klo: %@ + copied message info + + + More improvements are coming soon! + Lisää parannuksia on tulossa pian! + No comment provided by engineer. + + Most likely this connection is deleted. - Todennäköisesti tämä yhteys on poistettu. + Todennäköisesti tämä yhteys on poistettu. item status description - + + Most likely this contact has deleted the connection with you. + Todennäköisesti tämä kontakti on poistanut yhteyden sinuun. + No comment provided by engineer. + + + Multiple chat profiles + Useita keskusteluprofiileja + No comment provided by engineer. + + + Mute + Mykistä + No comment provided by engineer. + + + Muted when inactive! + Mykistetty ei-aktiivisena! + No comment provided by engineer. + + + Name + Nimi + No comment provided by engineer. + + + Network & servers + Verkko ja palvelimet + No comment provided by engineer. + + + Network settings + Verkkoasetukset + No comment provided by engineer. + + + Network status + Verkon tila + No comment provided by engineer. + + New Passcode - Uusi pääsykoodi + Uusi pääsykoodi No comment provided by engineer. - + + New contact request + Uusi kontaktipyyntö + notification + + + New contact: + Uusi kontakti: + notification + + + New database archive + Uusi tietokanta-arkisto + No comment provided by engineer. + + + New desktop app! + No comment provided by engineer. + + + New display name + Uusi näyttönimi + No comment provided by engineer. + + + New in %@ + Uutta %@ + No comment provided by engineer. + + + New member role + Uusi jäsenrooli + No comment provided by engineer. + + + New message + Uusi viesti + notification + + + New passphrase… + Uusi tunnuslause… + No comment provided by engineer. + + + No + Ei + No comment provided by engineer. + + + No app password + Ei sovelluksen salasanaa + Authentication unavailable + + + No contacts selected + Kontakteja ei ole valittu + No comment provided by engineer. + + + No contacts to add + Ei lisättäviä kontakteja + No comment provided by engineer. + + No delivery information - Ei toimitustietoja + Ei toimitustietoja No comment provided by engineer. - + + No device token! + Ei laitetunnusta! + No comment provided by engineer. + + + No filtered chats + Ei suodatettuja keskusteluja + No comment provided by engineer. + + + Group not found! + Ryhmää ei löydy! + No comment provided by engineer. + + No history - Ei historiaa + Ei historiaa No comment provided by engineer. - + + No permission to record voice message + Ei lupaa ääniviestin tallentamiseen + No comment provided by engineer. + + + No received or sent files + Ei vastaanotettuja tai lähetettyjä tiedostoja + No comment provided by engineer. + + + Notifications + Ilmoitukset + No comment provided by engineer. + + + Notifications are disabled! + Ilmoitukset on poistettu käytöstä! + No comment provided by engineer. + + + Now admins can: +- delete members' messages. +- disable members ("observer" role) + Nyt järjestelmänvalvojat voivat: +- poistaa jäsenten viestit. +- poista jäsenet käytöstä ("tarkkailija" rooli) + No comment provided by engineer. + + Off - Pois + Pois No comment provided by engineer. - + + Off (Local) + Pois (Paikallinen) + No comment provided by engineer. + + + Ok + Ok + No comment provided by engineer. + + + Old database + Vanha tietokanta + No comment provided by engineer. + + + Old database archive + Vanha tietokanta-arkisto + No comment provided by engineer. + + + One-time invitation link + Kertakutsulinkki + No comment provided by engineer. + + + Onion hosts will be required for connection. Requires enabling VPN. + Yhteyden muodostamiseen tarvitaan Onion-isäntiä. Edellyttää VPN:n sallimista. + No comment provided by engineer. + + + Onion hosts will be used when available. Requires enabling VPN. + Onion-isäntiä käytetään, kun niitä on saatavilla. Edellyttää VPN:n sallimista. + No comment provided by engineer. + + + Onion hosts will not be used. + Onion-isäntiä ei käytetä. + No comment provided by engineer. + + + Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**. + Vain asiakaslaitteet tallentavat käyttäjäprofiileja, yhteystietoja, ryhmiä ja viestejä, jotka on lähetetty **kaksinkertaisella päästä päähän -salauksella**. + No comment provided by engineer. + + + Only group owners can change group preferences. + Vain ryhmän omistajat voivat muuttaa ryhmän asetuksia. + No comment provided by engineer. + + + Only group owners can enable files and media. + Vain ryhmän omistajat voivat sallia tiedostoja ja mediaa. + No comment provided by engineer. + + + Only group owners can enable voice messages. + Vain ryhmän omistajat voivat ottaa ääniviestit käyttöön. + No comment provided by engineer. + + + Only you can add message reactions. + Vain sinä voit lisätä viestireaktioita. + No comment provided by engineer. + + + Only you can irreversibly delete messages (your contact can mark them for deletion). + Vain sinä voit poistaa viestejä peruuttamattomasti (kontaktisi voi merkitä ne poistettavaksi). + No comment provided by engineer. + + + Only you can make calls. + Vain sinä voit soittaa puheluita. + No comment provided by engineer. + + + Only you can send disappearing messages. + Vain sinä voit lähettää katoavia viestejä. + No comment provided by engineer. + + + Only you can send voice messages. + Vain sinä voit lähettää ääniviestejä. + No comment provided by engineer. + + + Only your contact can add message reactions. + Vain kontaktisi voi lisätä viestireaktioita. + No comment provided by engineer. + + + Only your contact can irreversibly delete messages (you can mark them for deletion). + Vain kontaktisi voi poistaa viestejä peruuttamattomasti (voit merkitä ne poistettavaksi). + No comment provided by engineer. + + + Only your contact can make calls. + Vain kontaktisi voi soittaa puheluita. + No comment provided by engineer. + + + Only your contact can send disappearing messages. + Vain kontaktisi voi lähettää katoavia viestejä. + No comment provided by engineer. + + + Only your contact can send voice messages. + Vain kontaktisi voi lähettää ääniviestejä. + No comment provided by engineer. + + + Open + No comment provided by engineer. + + + Open Settings + Avaa Asetukset + No comment provided by engineer. + + + Open chat + Avaa keskustelu + No comment provided by engineer. + + + Open chat console + Avaa keskustelukonsoli + authentication reason + + + Open user profiles + Avaa käyttäjäprofiilit + authentication reason + + + Open-source protocol and code – anybody can run the servers. + Avoimen lähdekoodin protokolla ja koodi - kuka tahansa voi käyttää palvelimia. + No comment provided by engineer. + + Opening database… - Avataan tietokantaa… + Avataan tietokantaa… No comment provided by engineer. - + + Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. + Linkin avaaminen selaimessa voi heikentää yhteyden yksityisyyttä ja turvallisuutta. Epäluotetut SimpleX-linkit näkyvät punaisina. + No comment provided by engineer. + + + PING count + PING-määrä + No comment provided by engineer. + + + PING interval + PING-väli + No comment provided by engineer. + + + Passcode + Pääsykoodi + No comment provided by engineer. + + + Passcode changed! + Pääsykoodi vaihdettu! + No comment provided by engineer. + + + Passcode entry + Pääsykoodin syöttö + No comment provided by engineer. + + + Passcode not changed! + Pääsykoodia ei ole muutettu! + No comment provided by engineer. + + + Passcode set! + Pääsykoodi asetettu! + No comment provided by engineer. + + + Password to show + Salasana näytettäväksi + No comment provided by engineer. + + + Paste + Liitä + No comment provided by engineer. + + + Paste image + Liitä kuva + No comment provided by engineer. + + + Paste received link + Liitä vastaanotettu linkki + No comment provided by engineer. + + + Paste the link you received to connect with your contact. + Liitä saamasi linkki, jonka avulla voit muodostaa yhteyden kontaktiisi. + placeholder + + + People can connect to you only via the links you share. + Ihmiset voivat ottaa sinuun yhteyttä vain jakamiesi linkkien kautta. + No comment provided by engineer. + + + Periodically + Ajoittain + No comment provided by engineer. + + + Permanent decryption error + Pysyvä salauksen purkuvirhe + message decrypt error item + + + Please ask your contact to enable sending voice messages. + Pyydä kontaktiasi sallimaan ääniviestien lähettäminen. + No comment provided by engineer. + + + Please check that you used the correct link or ask your contact to send you another one. + Tarkista, että käytit oikeaa linkkiä tai pyydä kontaktiasi lähettämään sinulle uusi linkki. + No comment provided by engineer. + + + Please check your network connection with %@ and try again. + Tarkista verkkoyhteytesi %@:lla ja yritä uudelleen. + No comment provided by engineer. + + + Please check yours and your contact preferences. + Tarkista omasi ja kontaktin asetukset. + No comment provided by engineer. + + + Please contact group admin. + Ota yhteyttä ryhmän ylläpitäjään. + No comment provided by engineer. + + + Please enter correct current passphrase. + Anna oikea nykyinen tunnuslause. + No comment provided by engineer. + + + Please enter the previous password after restoring database backup. This action can not be undone. + Anna edellinen salasana tietokannan varmuuskopion palauttamisen jälkeen. Tätä toimintoa ei voi kumota. + No comment provided by engineer. + + + Please remember or store it securely - there is no way to recover a lost passcode! + Muista tai säilytä se turvallisesti - kadonnutta pääsykoodia ei voi palauttaa! + No comment provided by engineer. + + + Please report it to the developers. + Ilmoita siitä kehittäjille. + No comment provided by engineer. + + + Please restart the app and migrate the database to enable push notifications. + Käynnistä sovellus uudelleen ja siirrä tietokanta push-ilmoitusten ottamiseksi käyttöön. + No comment provided by engineer. + + + Please store passphrase securely, you will NOT be able to access chat if you lose it. + Säilytä tunnuslause turvallisesti, ET pääse keskusteluihin, jos kadotat sen. + No comment provided by engineer. + + + Please store passphrase securely, you will NOT be able to change it if you lose it. + Säilytä tunnuslause turvallisesti, ET voi muuttaa sitä, jos kadotat sen. + No comment provided by engineer. + + + Polish interface + Puolalainen käyttöliittymä + No comment provided by engineer. + + + Possibly, certificate fingerprint in server address is incorrect + Palvelimen osoitteen varmenteen sormenjälki on mahdollisesti virheellinen + server test error + + + Preserve the last message draft, with attachments. + Säilytä viimeinen viestiluonnos liitteineen. + No comment provided by engineer. + + + Preset server + Esiasetettu palvelin + No comment provided by engineer. + + + Preset server address + Esiasetettu palvelimen osoite + No comment provided by engineer. + + + Preview + Esikatselu + No comment provided by engineer. + + + Privacy & security + Yksityisyys ja turvallisuus + No comment provided by engineer. + + + Privacy redefined + Yksityisyys uudelleen määritettynä + No comment provided by engineer. + + + Private filenames + Yksityiset tiedostonimet + No comment provided by engineer. + + + Profile and server connections + Profiili- ja palvelinyhteydet + No comment provided by engineer. + + + Profile image + Profiilikuva + No comment provided by engineer. + + + Profile password + Profiilin salasana + No comment provided by engineer. + + + Profile update will be sent to your contacts. + Profiilipäivitys lähetetään kontakteillesi. + No comment provided by engineer. + + + Prohibit audio/video calls. + Estä ääni- ja videopuhelut. + No comment provided by engineer. + + + Prohibit irreversible message deletion. + Estä peruuttamaton viestien poistaminen. + No comment provided by engineer. + + + Prohibit message reactions. + Estä viestireaktiot. + No comment provided by engineer. + + + Prohibit messages reactions. + Estä viestireaktiot. + No comment provided by engineer. + + + Prohibit sending direct messages to members. + Estä suorien viestien lähettäminen jäsenille. + No comment provided by engineer. + + + Prohibit sending disappearing messages. + Estä katoavien viestien lähettäminen. + No comment provided by engineer. + + + Prohibit sending files and media. + Estä tiedostojen ja median lähettäminen. + No comment provided by engineer. + + + Prohibit sending voice messages. + Estä ääniviestien lähettäminen. + No comment provided by engineer. + + + Protect app screen + Suojaa sovellusnäyttö + No comment provided by engineer. + + + Protect your chat profiles with a password! + Suojaa keskusteluprofiilisi salasanalla! + No comment provided by engineer. + + + Protocol timeout + Protokollan aikakatkaisu + No comment provided by engineer. + + + Protocol timeout per KB + Protokollan aikakatkaisu per KB + No comment provided by engineer. + + + Push notifications + Push-ilmoitukset + No comment provided by engineer. + + + Rate the app + Arvioi sovellus + No comment provided by engineer. + + + React… + Reagoi… + chat item menu + + + Read + Lue + No comment provided by engineer. + + + Read more + Lue lisää + No comment provided by engineer. + + + Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). + Lue lisää [Käyttöoppaasta](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). + No comment provided by engineer. + + + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). + Lue lisää [Käyttöoppaasta](https://simplex.chat/docs/guide/readme.html#connect-to-friends). + No comment provided by engineer. + + + Read more in our GitHub repository. + Lue lisää GitHub-tietovarastostamme. + No comment provided by engineer. + + + Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme). + Lue lisää [GitHub-arkistosta](https://github.com/simplex-chat/simplex-chat#readme). + No comment provided by engineer. + + + Receipts are disabled + Kuittaukset pois käytöstä + No comment provided by engineer. + + + Received at + Vastaanotettu klo + No comment provided by engineer. + + + Received at: %@ + Vastaanotettu klo: %@ + copied message info + + + Received file event + Tiedoston vastaanottotapahtuma + notification + + + Received message + Vastaanotettu viesti + message info title + + + Receiving address will be changed to a different server. Address change will complete after sender comes online. + Vastaanotto-osoite vaihdetaan toiseen palvelimeen. Osoitteenmuutos tehdään sen jälkeen, kun lähettäjä tulee verkkoon. + No comment provided by engineer. + + + Receiving file will be stopped. + Tiedoston vastaanotto pysäytetään. + No comment provided by engineer. + + + Receiving via + Vastaanotto kautta + No comment provided by engineer. + + + Recipients see updates as you type them. + Vastaanottajat näkevät päivitykset, kun kirjoitat niitä. + No comment provided by engineer. + + Reconnect all connected servers to force message delivery. It uses additional traffic. - Yhdistä kaikki yhdistetyt palvelimet uudelleen pakottaaksesi viestin toimituksen. Tämä käyttää ylimääräistä liikennettä. + Yhdistä kaikki yhdistetyt palvelimet uudelleen pakottaaksesi viestin toimituksen. Tämä käyttää ylimääräistä liikennettä. No comment provided by engineer. - + + Reconnect servers? + Yhdistä palvelimet uudelleen? + No comment provided by engineer. + + + Record updated at + Tietue päivitetty klo + No comment provided by engineer. + + + Record updated at: %@ + Tietue päivitetty klo: %@ + copied message info + + + Reduced battery usage + Pienempi akun käyttö + No comment provided by engineer. + + + Reject + Hylkää + reject incoming call via notification + + + Reject (sender NOT notified) + Hylkää (lähettäjälle EI ilmoiteta) + No comment provided by engineer. + + + Reject contact request + Hylkää yhteyspyyntö + No comment provided by engineer. + + + Relay server is only used if necessary. Another party can observe your IP address. + Välityspalvelinta käytetään vain tarvittaessa. Toinen osapuoli voi tarkkailla IP-osoitettasi. + No comment provided by engineer. + + + Relay server protects your IP address, but it can observe the duration of the call. + Välityspalvelin suojaa IP-osoitteesi, mutta se voi tarkkailla puhelun kestoa. + No comment provided by engineer. + + + Remove + Poista + No comment provided by engineer. + + + Remove member + Poista jäsen + No comment provided by engineer. + + + Remove member? + Poista jäsen? + No comment provided by engineer. + + + Remove passphrase from keychain? + Poista tunnuslause avainnipusta? + No comment provided by engineer. + + + Renegotiate + Neuvottele uudelleen + No comment provided by engineer. + + + Renegotiate encryption + Uudelleenneuvottele salaus + No comment provided by engineer. + + Renegotiate encryption? - Uudelleenneuvottele salaus? + Uudelleenneuvottele salaus? No comment provided by engineer. - - Sending receipts is enabled for %lld contacts - Kuittauksien lähettäminen on käytössä %lld kontakteille + + Reply + Vastaa + chat item action + + + Required + Pakollinen No comment provided by engineer. - - Sending receipts is enabled for %lld groups - Kuittauksien lähettäminen on käytössä %lld ryhmille + + Reset + Oletustilaan No comment provided by engineer. - + + Reset colors + Oletusvärit + No comment provided by engineer. + + + Reset to defaults + Palauta oletusasetukset + No comment provided by engineer. + + + Restart the app to create a new chat profile + Käynnistä sovellus uudelleen uuden keskusteluprofiilin luomiseksi + No comment provided by engineer. + + + Restart the app to use imported chat database + Käynnistä sovellus uudelleen käyttääksesi tuotua keskustelujen-tietokantaa + No comment provided by engineer. + + + Restore + Palauta + No comment provided by engineer. + + + Restore database backup + Palauta tietokannan varmuuskopio + No comment provided by engineer. + + + Restore database backup? + Palauta tietokannan varmuuskopio? + No comment provided by engineer. + + + Restore database error + Virhe tietokannan palauttamisessa + No comment provided by engineer. + + + Reveal + Paljasta + chat item action + + + Revert + Palauta + No comment provided by engineer. + + Revoke - Peruuta + Peruuta No comment provided by engineer. - + + Revoke file + Peruuta tiedosto + cancel file action + + + Revoke file? + Peruuta tiedosto? + No comment provided by engineer. + + + Role + Rooli + No comment provided by engineer. + + + Run chat + Käynnistä chat + No comment provided by engineer. + + + SMP servers + SMP-palvelimet + No comment provided by engineer. + + + Save + Tallenna + chat item action + + + Save (and notify contacts) + Tallenna (ja ilmoita kontakteille) + No comment provided by engineer. + + + Save and notify contact + Tallenna ja ilmoita kontaktille + No comment provided by engineer. + + + Save and notify group members + Tallenna ja ilmoita ryhmän jäsenille + No comment provided by engineer. + + + Save and update group profile + Tallenna ja päivitä ryhmäprofiili + No comment provided by engineer. + + + Save archive + Tallenna arkisto + No comment provided by engineer. + + Save auto-accept settings - Tallenna automaattisen hyväksynnän asetukset + Tallenna automaattisen hyväksynnän asetukset No comment provided by engineer. - + + Save group profile + Tallenna ryhmäprofiili + No comment provided by engineer. + + + Save passphrase and open chat + Tallenna tunnuslause ja avaa keskustelu + No comment provided by engineer. + + + Save passphrase in Keychain + Tallenna tunnuslause Avainnippuun + No comment provided by engineer. + + + Save preferences? + Tallenna asetukset? + No comment provided by engineer. + + + Save profile password + Tallenna profiilin salasana + No comment provided by engineer. + + + Save servers + Tallenna palvelimet + No comment provided by engineer. + + + Save servers? + Tallenna palvelimet? + No comment provided by engineer. + + + Save settings? + Tallenna asetukset? + No comment provided by engineer. + + + Save welcome message? + Tallenna tervetuloviesti? + No comment provided by engineer. + + + Saved WebRTC ICE servers will be removed + Tallennetut WebRTC ICE -palvelimet poistetaan + No comment provided by engineer. + + + Scan QR code + Skannaa QR-koodi + No comment provided by engineer. + + + Scan code + Skannaa koodi + No comment provided by engineer. + + + Scan security code from your contact's app. + Skannaa turvakoodi kontaktisi sovelluksesta. + No comment provided by engineer. + + + Scan server QR code + Skannaa palvelimen QR-koodi + No comment provided by engineer. + + + Search + Haku + No comment provided by engineer. + + + Secure queue + Turvallinen jono + server test step + + + Security assessment + Turvallisuusarviointi + No comment provided by engineer. + + + Security code + Turvakoodi + No comment provided by engineer. + + + Select + Valitse + No comment provided by engineer. + + + Self-destruct + Itsetuho + No comment provided by engineer. + + Self-destruct passcode - Itsetuhoutuva pääsykoodi + Itsetuhoutuva pääsykoodi No comment provided by engineer. - + + Self-destruct passcode changed! + Itsetuhoutuva pääsykoodi vaihdettu! + No comment provided by engineer. + + Self-destruct passcode enabled! - Itsetuhoutuva pääsykoodi käytössä! + Itsetuhoutuva pääsykoodi käytössä! No comment provided by engineer. - + + Send + Lähetä + No comment provided by engineer. + + + Send a live message - it will update for the recipient(s) as you type it + Lähetä live-viesti - se päivittyy vastaanottajille, kun kirjoitat sitä + No comment provided by engineer. + + + Send delivery receipts to + Lähetä toimituskuittaukset vastaanottajalle + No comment provided by engineer. + + + Send direct message + Lähetä yksityisviesti + No comment provided by engineer. + + + Send direct message to connect + No comment provided by engineer. + + + Send disappearing message + Lähetä katoava viesti + No comment provided by engineer. + + + Send link previews + Lähetä linkkien esikatselu + No comment provided by engineer. + + + Send live message + Lähetä live-viesti + No comment provided by engineer. + + + Send notifications + Lähetys ilmoitukset + No comment provided by engineer. + + + Send notifications: + Lähetys ilmoitukset: + No comment provided by engineer. + + + Send questions and ideas + Lähetä kysymyksiä ja ideoita + No comment provided by engineer. + + + Send receipts + Lähetä kuittaukset + No comment provided by engineer. + + + Send them from gallery or custom keyboards. + Lähetä ne galleriasta tai mukautetuista näppäimistöistä. + No comment provided by engineer. + + + Sender cancelled file transfer. + Lähettäjä peruutti tiedoston siirron. + No comment provided by engineer. + + + Sender may have deleted the connection request. + Lähettäjä on saattanut poistaa yhteyspyynnön. + No comment provided by engineer. + + + Sending delivery receipts will be enabled for all contacts in all visible chat profiles. + Toimituskuittauksien lähettäminen otetaan käyttöön kaikille kontakteille näkyvissä keskusteluprofiileissa. + No comment provided by engineer. + + + Sending delivery receipts will be enabled for all contacts. + Toimituskuittauksien lähettäminen otetaan käyttöön kaikille kontakteille. + No comment provided by engineer. + + + Sending file will be stopped. + Tiedoston lähettäminen lopetetaan. + No comment provided by engineer. + + + Sending receipts is disabled for %lld contacts + Kuittauksien lähettäminen ei ole käytössä %lld kontakteille + No comment provided by engineer. + + + Sending receipts is disabled for %lld groups + Kuittien lähettäminen ei ole käytössä %lld ryhmille + No comment provided by engineer. + + + Sending receipts is enabled for %lld contacts + Kuittauksien lähettäminen on käytössä %lld kontakteille + No comment provided by engineer. + + + Sending receipts is enabled for %lld groups + Kuittauksien lähettäminen on käytössä %lld ryhmille + No comment provided by engineer. + + + Sending via + Lähetetään kautta + No comment provided by engineer. + + + Sent at + Lähetetty klo + No comment provided by engineer. + + + Sent at: %@ + Lähetetty klo: %@ + copied message info + + + Sent file event + Lähetetty tiedosto tapahtuma + notification + + + Sent message + Lähetetty viesti + message info title + + + Sent messages will be deleted after set time. + Lähetetyt viestit poistetaan asetetun ajan kuluttua. + No comment provided by engineer. + + + Server requires authorization to create queues, check password + Palvelin vaatii valtuutuksen jonojen luomiseen, tarkista salasana + server test error + + + Server requires authorization to upload, check password + Palvelin vaatii valtuutuksen tiedoston lataamiseksi, tarkista salasana + server test error + + + Server test failed! + Palvelintesti epäonnistui! + No comment provided by engineer. + + + Servers + Palvelimet + No comment provided by engineer. + + + Set 1 day + Aseta 1 päivä + No comment provided by engineer. + + + Set contact name… + Aseta kontaktin nimi… + No comment provided by engineer. + + + Set group preferences + Aseta ryhmän asetukset + No comment provided by engineer. + + + Set it instead of system authentication. + Aseta se järjestelmän todennuksen sijaan. + No comment provided by engineer. + + + Set passcode + Aseta pääsykoodi + No comment provided by engineer. + + + Set passphrase to export + Aseta tunnuslause vientiä varten + No comment provided by engineer. + + + Set the message shown to new members! + Aseta uusille jäsenille näytettävä viesti! + No comment provided by engineer. + + + Set timeouts for proxy/VPN + Aseta aikakatkaisut välityspalvelimelle/VPN:lle + No comment provided by engineer. + + + Settings + Asetukset + No comment provided by engineer. + + + Share + Jaa + chat item action + + + Share 1-time link + Jaa kertakäyttölinkki + No comment provided by engineer. + + + Share address + Jaa osoite + No comment provided by engineer. + + + Share address with contacts? + Jaa osoite kontakteille? + No comment provided by engineer. + + + Share link + Jaa linkki + No comment provided by engineer. + + + Share one-time invitation link + Jaa kertakutsulinkki + No comment provided by engineer. + + + Share with contacts + Jaa kontaktien kanssa + No comment provided by engineer. + + + Show calls in phone history + Näytä puhelut puhelinhistoriassa + No comment provided by engineer. + + + Show developer options + Näytä kehittäjävaihtoehdot + No comment provided by engineer. + + + Show last messages + Näytä viimeiset viestit + No comment provided by engineer. + + + Show preview + Näytä esikatselu + No comment provided by engineer. + + + Show: + Näytä: + No comment provided by engineer. + + + SimpleX Address + SimpleX-osoite + No comment provided by engineer. + + + SimpleX Chat security was audited by Trail of Bits. + Trail of Bits on tarkastanut SimpleX Chatin tietoturvan. + No comment provided by engineer. + + + SimpleX Lock + SimpleX Lock + No comment provided by engineer. + + + SimpleX Lock mode + SimpleX Lock -tila + No comment provided by engineer. + + + SimpleX Lock not enabled! + SimpleX Lock ei ole käytössä! + No comment provided by engineer. + + + SimpleX Lock turned on + SimpleX Lock päällä + No comment provided by engineer. + + + SimpleX address + SimpleX-osoite + No comment provided by engineer. + + + SimpleX contact address + SimpleX-yhteystiedot + simplex link type + + + SimpleX encrypted message or connection event + SimpleX-salattu viesti tai yhteystapahtuma + notification + + + SimpleX group link + SimpleX-ryhmän linkki + simplex link type + + + SimpleX links + SimpleX-linkit + No comment provided by engineer. + + + SimpleX one-time invitation + SimpleX-kertakutsu + simplex link type + + + Simplified incognito mode + No comment provided by engineer. + + + Skip + Ohita + No comment provided by engineer. + + + Skipped messages + Ohitetut viestit + No comment provided by engineer. + + + Small groups (max 20) + Pienryhmät (max 20) + No comment provided by engineer. + + + Some non-fatal errors occurred during import - you may see Chat console for more details. + Tuonnin aikana tapahtui joitakin ei-vakavia virheitä – saatat nähdä Chat-konsolissa lisätietoja. + No comment provided by engineer. + + + Somebody + Joku + notification title + + + Start a new chat + Aloita uusi keskustelu + No comment provided by engineer. + + + Start chat + Aloita keskustelu + No comment provided by engineer. + + + Start migration + Aloita siirto + No comment provided by engineer. + + + Stop + Lopeta + No comment provided by engineer. + + + Stop SimpleX + Lopeta SimpleX + authentication reason + + + Stop chat to enable database actions + Pysäytä keskustelu tietokantatoimien mahdollistamiseksi + No comment provided by engineer. + + + Stop chat to export, import or delete chat database. You will not be able to receive and send messages while the chat is stopped. + Pysäytä keskustelut viedäksesi, tuodaksesi tai poistaaksesi keskustelujen tietokannan. Et voi vastaanottaa ja lähettää viestejä, kun keskustelut on pysäytetty. + No comment provided by engineer. + + + Stop chat? + Lopeta keskustelu? + No comment provided by engineer. + + + Stop file + Pysäytä tiedosto + cancel file action + + + Stop receiving file? + Lopeta tiedoston vastaanottaminen? + No comment provided by engineer. + + + Stop sending file? + Lopeta tiedoston lähettäminen? + No comment provided by engineer. + + + Stop sharing + Lopeta jakaminen + No comment provided by engineer. + + + Stop sharing address? + Lopeta osoitteen jakaminen? + No comment provided by engineer. + + + Submit + Lähetä + No comment provided by engineer. + + + Support SimpleX Chat + SimpleX Chat tuki + No comment provided by engineer. + + + System + Järjestelmä + No comment provided by engineer. + + + System authentication + Järjestelmän todennus + No comment provided by engineer. + + + TCP connection timeout + TCP-yhteyden aikakatkaisu + No comment provided by engineer. + + + TCP_KEEPCNT + TCP_KEEPCNT + No comment provided by engineer. + + + TCP_KEEPIDLE + TCP_KEEPIDLE + No comment provided by engineer. + + + TCP_KEEPINTVL + TCP_KEEPINTVL + No comment provided by engineer. + + + Take picture + Ota kuva + No comment provided by engineer. + + + Tap button + Napauta painiketta + No comment provided by engineer. + + + Tap to activate profile. + Aktivoi profiili napauttamalla. + No comment provided by engineer. + + + Tap to join + Liity napauttamalla + No comment provided by engineer. + + + Tap to join incognito + Napauta liittyäksesi incognito-tilassa + No comment provided by engineer. + + + Tap to start a new chat + Aloita uusi keskustelu napauttamalla + No comment provided by engineer. + + + Test failed at step %@. + Testi epäonnistui vaiheessa %@. + server test failure + + + Test server + Testipalvelin + No comment provided by engineer. + + + Test servers + Testipalvelimet + No comment provided by engineer. + + + Tests failed! + Testit epäonnistuivat! + No comment provided by engineer. + + + Thank you for installing SimpleX Chat! + Kiitos SimpleX Chatin asentamisesta! + No comment provided by engineer. + + + Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Kiitos käyttäjille - [osallistu Weblaten avulla](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + No comment provided by engineer. + + + Thanks to the users – contribute via Weblate! + Kiitokset käyttäjille – osallistu Weblaten kautta! + No comment provided by engineer. + + + The 1st platform without any user identifiers – private by design. + Ensimmäinen alusta ilman käyttäjätunnisteita – suunniteltu yksityiseksi. + No comment provided by engineer. + + The ID of the next message is incorrect (less or equal to the previous). It can happen because of some bug or when the connection is compromised. - Seuraavan viestin tunnus on väärä (pienempi tai yhtä suuri kuin edellisen). + Seuraavan viestin tunnus on väärä (pienempi tai yhtä suuri kuin edellisen). Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut. No comment provided by engineer. - + + The app can notify you when you receive messages or contact requests - please open settings to enable. + Sovellus voi ilmoittaa sinulle, kun saat viestejä tai yhteydenottopyyntöjä - avaa asetukset ottaaksesi ne käyttöön. + No comment provided by engineer. + + + The attempt to change database passphrase was not completed. + Tietokannan tunnuslauseen muuttamista ei suoritettu loppuun. + No comment provided by engineer. + + + The connection you accepted will be cancelled! + Hyväksymäsi yhteys peruuntuu! + No comment provided by engineer. + + + The contact you shared this link with will NOT be able to connect! + Kontakti, jolle jaoit tämän linkin, EI voi muodostaa yhteyttä! + No comment provided by engineer. + + + The created archive is available via app Settings / Database / Old database archive. + Luotu arkisto on käytettävissä sovelluksen Asetukset / Tietokanta / Vanha tietokanta-arkisto kautta. + No comment provided by engineer. + + The encryption is working and the new encryption agreement is not required. It may result in connection errors! - Salaus toimii ja uutta salaussopimusta ei tarvita. Tämä voi johtaa yhteysvirheisiin! + Salaus toimii ja uutta salaussopimusta ei tarvita. Tämä voi johtaa yhteysvirheisiin! No comment provided by engineer. - + + The group is fully decentralized – it is visible only to the members. + Ryhmä on täysin hajautettu - se näkyy vain jäsenille. + No comment provided by engineer. + + + The hash of the previous message is different. + Edellisen viestin tarkiste on erilainen. + No comment provided by engineer. + + + The message will be deleted for all members. + Viesti poistetaan kaikilta jäseniltä. + No comment provided by engineer. + + + The message will be marked as moderated for all members. + Viesti merkitään moderoiduksi kaikille jäsenille. + No comment provided by engineer. + + + The next generation of private messaging + Seuraavan sukupolven yksityisviestit + No comment provided by engineer. + + + The old database was not removed during the migration, it can be deleted. + Vanhaa tietokantaa ei poistettu siirron aikana, se voidaan kuitenkin poistaa. + No comment provided by engineer. + + + The profile is only shared with your contacts. + Profiili jaetaan vain kontaktiesi kanssa. + No comment provided by engineer. + + + The second tick we missed! ✅ + Toinen kuittaus, joka uupui! ✅ + No comment provided by engineer. + + + The sender will NOT be notified + Lähettäjälle EI ilmoiteta + No comment provided by engineer. + + + The servers for new connections of your current chat profile **%@**. + Palvelimet nykyisen keskusteluprofiilisi uusille yhteyksille **%@**. + No comment provided by engineer. + + + Theme + Teema + No comment provided by engineer. + + + There should be at least one user profile. + Käyttäjäprofiileja tulee olla vähintään yksi. + No comment provided by engineer. + + + There should be at least one visible user profile. + Näkyviä käyttäjäprofiileja tulee olla vähintään yksi. + No comment provided by engineer. + + + These settings are for your current profile **%@**. + Nämä asetukset koskevat nykyistä profiiliasi **%@**. + No comment provided by engineer. + + + They can be overridden in contact and group settings. + Ne voidaan ohittaa kontakti- ja ryhmäasetuksissa. + No comment provided by engineer. + + + This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain. + Tätä toimintoa ei voi kumota - kaikki vastaanotetut ja lähetetyt tiedostot ja media poistetaan. Matalan resoluution kuvat säilyvät. + No comment provided by engineer. + + + This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes. + Tätä toimintoa ei voi kumota - valittua aikaisemmin lähetetyt ja vastaanotetut viestit poistetaan. Tämä voi kestää useita minuutteja. + No comment provided by engineer. + + + This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost. + Tätä toimintoa ei voi kumota - profiilisi, kontaktisi, viestisi ja tiedostosi poistuvat peruuttamattomasti. + No comment provided by engineer. + + + This group has over %lld members, delivery receipts are not sent. + Tässä ryhmässä on yli %lld jäsentä, lähetyskuittauksia ei lähetetä. + No comment provided by engineer. + + + This group no longer exists. + Tätä ryhmää ei enää ole olemassa. + No comment provided by engineer. + + + This setting applies to messages in your current chat profile **%@**. + Tämä asetus koskee nykyisen keskusteluprofiilisi viestejä *%@**. + No comment provided by engineer. + + + To ask any questions and to receive updates: + Voit esittää kysymyksiä ja saada päivityksiä: + No comment provided by engineer. + + + To connect, your contact can scan QR code or use the link in the app. + Kontaktisi voi muodostaa yhteyden skannaamalla QR-koodin tai käyttämällä sovelluksessa olevaa linkkiä. + No comment provided by engineer. + + + To make a new connection + Uuden yhteyden luominen + No comment provided by engineer. + + + To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts. + Yksityisyyden suojaamiseksi kaikkien muiden alustojen käyttämien käyttäjätunnusten sijaan SimpleX käyttää viestijonojen tunnisteita, jotka ovat kaikille kontakteille erillisiä. + No comment provided by engineer. + + + To protect timezone, image/voice files use UTC. + Aikavyöhykkeen suojaamiseksi kuva-/äänitiedostot käyttävät UTC:tä. + No comment provided by engineer. + + + To protect your information, turn on SimpleX Lock. +You will be prompted to complete authentication before this feature is enabled. + Suojaa tietosi ottamalla SimpleX Lock käyttöön. +Sinua kehotetaan suorittamaan todennus loppuun, ennen kuin tämä ominaisuus otetaan käyttöön. + No comment provided by engineer. + + + To record voice message please grant permission to use Microphone. + Jos haluat nauhoittaa ääniviestin, anna lupa käyttää mikrofonia. + No comment provided by engineer. + + + To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page. + Voit paljastaa piilotetun profiilisi syöttämällä koko salasanan hakukenttään **Keskusteluprofiilisi** -sivulla. + No comment provided by engineer. + + + To support instant push notifications the chat database has to be migrated. + Keskustelujen-tietokanta on siirrettävä välittömien push-ilmoitusten tukemiseksi. + No comment provided by engineer. + + + To verify end-to-end encryption with your contact compare (or scan) the code on your devices. + Voit tarkistaa päästä päähän -salauksen kontaktisi kanssa vertaamalla (tai skannaamalla) laitteidenne koodia. + No comment provided by engineer. + + + Toggle incognito when connecting. + No comment provided by engineer. + + + Transport isolation + Kuljetuksen eristäminen + No comment provided by engineer. + + + Trying to connect to the server used to receive messages from this contact (error: %@). + Yritetään muodostaa yhteyttä palvelimeen, jota käytetään tämän kontaktin viestien vastaanottamiseen (virhe: %@). + No comment provided by engineer. + + + Trying to connect to the server used to receive messages from this contact. + Yritetään muodostaa yhteys palvelimeen, jota käytetään viestien vastaanottamiseen tältä kontaktilta. + No comment provided by engineer. + + + Turn off + Sammuta + No comment provided by engineer. + + + Turn off notifications? + Kytke ilmoitukset pois päältä? + No comment provided by engineer. + + + Turn on + Kytke päälle + No comment provided by engineer. + + + Unable to record voice message + Ääniviestiä ei voi tallentaa + No comment provided by engineer. + + + Unexpected error: %@ + Odottamaton virhe: %@ + item status description + + + Unexpected migration state + Odottamaton siirtotila + No comment provided by engineer. + + + Unfav. + Epäsuotuisa. + No comment provided by engineer. + + + Unhide + Näytä + No comment provided by engineer. + + + Unhide chat profile + Näytä keskusteluprofiili + No comment provided by engineer. + + + Unhide profile + Näytä profiili + No comment provided by engineer. + + + Unit + Yksikkö + No comment provided by engineer. + + + Unknown caller + Tuntematon soittaja + callkit banner + + + Unknown database error: %@ + Tuntematon tietokantavirhe: %@ + No comment provided by engineer. + + + Unknown error + Tuntematon virhe + No comment provided by engineer. + + + Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions. + Ellet käytä iOS:n puhelinkäyttöliittymää, ota Älä häiritse -tila käyttöön keskeytysten välttämiseksi. + No comment provided by engineer. + + + Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. +To connect, please ask your contact to create another connection link and check that you have a stable network connection. + Ellei yhteyshenkilösi poistanut yhteyttä tai tämä linkki oli jo käytössä, se voi olla virhe - ilmoita siitä. +Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja tarkista, että verkkoyhteytesi on vakaa. + No comment provided by engineer. + + + Unlock + Avaa + No comment provided by engineer. + + + Unlock app + Avaa sovellus + authentication reason + + + Unmute + Poista mykistys + No comment provided by engineer. + + + Unread + Lukematon + No comment provided by engineer. + + + Update + Päivitä + No comment provided by engineer. + + + Update .onion hosts setting? + Päivitä .onion-isäntien asetus? + No comment provided by engineer. + + + Update database passphrase + Päivitä tietokannan tunnuslause + No comment provided by engineer. + + + Update network settings? + Päivitä verkkoasetukset? + No comment provided by engineer. + + + Update transport isolation mode? + Päivitä kuljetuksen eristystila? + No comment provided by engineer. + + + Updating settings will re-connect the client to all servers. + Asetusten päivittäminen yhdistää asiakkaan uudelleen kaikkiin palvelimiin. + No comment provided by engineer. + + + Updating this setting will re-connect the client to all servers. + Tämän asetuksen päivittäminen yhdistää asiakkaan uudelleen kaikkiin palvelimiin. + No comment provided by engineer. + + + Upgrade and open chat + Päivitä ja avaa keskustelu + No comment provided by engineer. + + + Upload file + Lataa tiedosto + server test step + + + Use .onion hosts + Käytä .onion-isäntiä + No comment provided by engineer. + + + Use SimpleX Chat servers? + Käytä SimpleX Chat palvelimia? + No comment provided by engineer. + + + Use chat + Käytä chattia + No comment provided by engineer. + + + Use current profile + Käytä nykyistä profiilia + No comment provided by engineer. + + + Use for new connections + Käytä uusiin yhteyksiin + No comment provided by engineer. + + + Use iOS call interface + Käytä iOS:n puhelujen käyttöliittymää + No comment provided by engineer. + + + Use new incognito profile + Käytä uutta incognito-profiilia + No comment provided by engineer. + + + Use server + Käytä palvelinta + No comment provided by engineer. + + + User profile + Käyttäjäprofiili + No comment provided by engineer. + + + Using .onion hosts requires compatible VPN provider. + .onion-isäntien käyttäminen vaatii yhteensopivan VPN-palveluntarjoajan. + No comment provided by engineer. + + + Using SimpleX Chat servers. + Käyttää SimpleX Chat -palvelimia. + No comment provided by engineer. + + + Verify connection security + Tarkista yhteyden suojaus + No comment provided by engineer. + + + Verify security code + Tarkista turvakoodi + No comment provided by engineer. + + + Via browser + Selaimella + No comment provided by engineer. + + + Video call + Videopuhelu + No comment provided by engineer. + + Video will be received when your contact completes uploading it. - Video vastaanotetaan, kun kontaktisi on ladannut sen. + Video vastaanotetaan, kun kontaktisi on ladannut sen. No comment provided by engineer. - + + Video will be received when your contact is online, please wait or check later! + Video vastaanotetaan, kun kontaktisi on online-tilassa, odota tai tarkista myöhemmin! + No comment provided by engineer. + + + Videos and files up to 1gb + Videot ja tiedostot 1 Gt asti + No comment provided by engineer. + + + View security code + Näytä turvakoodi + No comment provided by engineer. + + + Voice messages + Ääniviestit + chat feature + + + Voice messages are prohibited in this chat. + Ääniviestit ovat kiellettyjä tässä keskustelussa. + No comment provided by engineer. + + + Voice messages are prohibited in this group. + Ääniviestit ovat kiellettyjä tässä ryhmässä. + No comment provided by engineer. + + + Voice messages prohibited! + Ääniviestit kielletty! + No comment provided by engineer. + + + Voice message… + Ääniviesti… + No comment provided by engineer. + + + Waiting for file + Odottaa tiedostoa + No comment provided by engineer. + + + Waiting for image + Odottaa kuvaa + No comment provided by engineer. + + + Waiting for video + Odottaa videota + No comment provided by engineer. + + + Warning: you may lose some data! + Varoitus: saatat menettää joitain tietoja! + No comment provided by engineer. + + + WebRTC ICE servers + WebRTC ICE -palvelimet + No comment provided by engineer. + + + Welcome %@! + Tervetuloa %@! + No comment provided by engineer. + + + Welcome message + Tervetuloviesti + No comment provided by engineer. + + + What's new + Uusimmat + No comment provided by engineer. + + + When available + Kun saatavilla + No comment provided by engineer. + + + When people request to connect, you can accept or reject it. + Kun ihmiset pyytävät yhteyden muodostamista, voit hyväksyä tai hylätä sen. + No comment provided by engineer. + + + When you share an incognito profile with somebody, this profile will be used for the groups they invite you to. + Kun jaat inkognitoprofiilin jonkun kanssa, tätä profiilia käytetään ryhmissä, joihin tämä sinut kutsuu. + No comment provided by engineer. + + + With optional welcome message. + Valinnaisella tervetuloviestillä. + No comment provided by engineer. + + + Wrong database passphrase + Väärä tietokannan tunnuslause + No comment provided by engineer. + + + Wrong passphrase! + Väärä tunnuslause! + No comment provided by engineer. + + + XFTP servers + XFTP-palvelimet + No comment provided by engineer. + + + You + Sinä + No comment provided by engineer. + + + You accepted connection + Hyväksyit yhteyden + No comment provided by engineer. + + + You allow + Sallit + No comment provided by engineer. + + + You already have a chat profile with the same display name. Please choose another name. + Sinulla on jo keskusteluprofiili samalla näyttönimellä. Valitse toinen nimi. + No comment provided by engineer. + + + You are already connected to %@. + Olet jo muodostanut yhteyden %@:n kanssa. + No comment provided by engineer. + + + You are connected to the server used to receive messages from this contact. + Olet yhteydessä palvelimeen, jota käytetään vastaanottamaan viestejä tältä kontaktilta. + No comment provided by engineer. + + + You are invited to group + Sinut on kutsuttu ryhmään + No comment provided by engineer. + + + You can accept calls from lock screen, without device and app authentication. + Voit vastaanottaa puheluita lukitusnäytöltä ilman laitteen ja sovelluksen todennusta. + No comment provided by engineer. + + + You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. + Voit myös muodostaa yhteyden klikkaamalla linkkiä. Jos se avautuu selaimessa, napsauta **Avaa mobiilisovelluksessa**-painiketta. + No comment provided by engineer. + + + You can create it later + Voit luoda sen myöhemmin + No comment provided by engineer. + + You can enable later via Settings - Voit ottaa käyttöön myöhemmin asetusten kautta + Voit ottaa käyttöön myöhemmin asetusten kautta No comment provided by engineer. - + + You can enable them later via app Privacy & Security settings. + Voit ottaa ne käyttöön myöhemmin sovelluksen Yksityisyys & Turvallisuus -asetuksista. + No comment provided by engineer. + + + You can hide or mute a user profile - swipe it to the right. + Voit piilottaa tai mykistää käyttäjäprofiilin pyyhkäisemällä sitä oikealle. + No comment provided by engineer. + + + You can now send messages to %@ + Voit nyt lähettää viestejä %@:lle + notification body + + + You can set lock screen notification preview via settings. + Voit määrittää lukitusnäytön ilmoituksen esikatselun asetuksista. + No comment provided by engineer. + + + You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + Voit jakaa linkin tai QR-koodin - kuka tahansa voi liittyä ryhmään. Et menetä ryhmän jäseniä, jos poistat sen myöhemmin. + No comment provided by engineer. + + You can share this address with your contacts to let them connect with **%@**. - Voit jakaa tämän osoitteen kontaktiesi kanssa, jotta ne voivat muodostaa yhteyden **%@** kanssa. + Voit jakaa tämän osoitteen kontaktiesi kanssa, jotta ne voivat muodostaa yhteyden **%@** kanssa. No comment provided by engineer. - + + You can share your address as a link or QR code - anybody can connect to you. + Voit jakaa osoitteesi linkkinä tai QR-koodina - kuka tahansa voi muodostaa yhteyden sinuun. + No comment provided by engineer. + + + You can start chat via app Settings / Database or by restarting the app + Voit aloittaa keskustelun sovelluksen Asetukset / Tietokanta kautta tai käynnistämällä sovelluksen uudelleen + No comment provided by engineer. + + + You can turn on SimpleX Lock via Settings. + Voit ottaa SimpleX Lockin käyttöön Asetusten kautta. + No comment provided by engineer. + + + You can use markdown to format messages: + Voit käyttää markdownia viestien muotoiluun: + No comment provided by engineer. + + + You can't send messages! + Et voi lähettää viestejä! + No comment provided by engineer. + + + You control through which server(s) **to receive** the messages, your contacts – the servers you use to message them. + Sinä hallitset, minkä palvelim(i)en kautta **viestit vastaanotetaan**, kontaktisi - palvelimet, joita käytät viestien lähettämiseen niille. + No comment provided by engineer. + + + You could not be verified; please try again. + Sinua ei voitu todentaa; yritä uudelleen. + No comment provided by engineer. + + + You have no chats + Sinulla ei ole keskusteluja + No comment provided by engineer. + + + You have to enter passphrase every time the app starts - it is not stored on the device. + Sinun on annettava tunnuslause aina, kun sovellus käynnistyy - sitä ei tallenneta laitteeseen. + No comment provided by engineer. + + + You invited a contact + Kutsuit kontaktin + No comment provided by engineer. + + + You joined this group + Liityit tähän ryhmään + No comment provided by engineer. + + + You joined this group. Connecting to inviting group member. + Liityit tähän ryhmään. Muodostetaan yhteyttä ryhmän jäsenten kutsumiseksi. + 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. + Sinun tulee käyttää keskustelujen-tietokannan uusinta versiota AINOSTAAN yhdessä laitteessa, muuten saatat lakata vastaanottamasta viestejä joiltakin kontakteilta. + No comment provided by engineer. + + + You need to allow your contact to send voice messages to be able to send them. + Sinun on sallittava kontaktiesi lähettää ääniviestejä, jotta voit lähettää niitä. + No comment provided by engineer. + + + You rejected group invitation + Hylkäsit ryhmäkutsun + No comment provided by engineer. + + + You sent group invitation + Lähetit ryhmäkutsun + No comment provided by engineer. + + + You will be connected to group when the group host's device is online, please wait or check later! + Sinut yhdistetään ryhmään, kun ryhmän isännän laite on online-tilassa, odota tai tarkista myöhemmin! + No comment provided by engineer. + + + You will be connected when your connection request is accepted, please wait or check later! + Sinut yhdistetään, kun yhteyspyyntösi on hyväksytty, odota tai tarkista myöhemmin! + No comment provided by engineer. + + + You will be connected when your contact's device is online, please wait or check later! + Sinut yhdistetään, kun kontaktisi laite on online-tilassa, odota tai tarkista myöhemmin! + No comment provided by engineer. + + + You will be required to authenticate when you start or resume the app after 30 seconds in background. + Sinun on tunnistauduttava, kun käynnistät sovelluksen tai jatkat sen käyttöä 30 sekunnin tauon jälkeen. + No comment provided by engineer. + + + You will join a group this link refers to and connect to its group members. + Liityt ryhmään, johon tämä linkki viittaa, ja muodostat yhteyden sen ryhmän jäseniin. + No comment provided by engineer. + + + You will still receive calls and notifications from muted profiles when they are active. + Saat edelleen puheluita ja ilmoituksia mykistetyiltä profiileilta, kun ne ovat aktiivisia. + No comment provided by engineer. + + + You will stop receiving messages from this group. Chat history will be preserved. + Et enää saa viestejä tästä ryhmästä. Keskusteluhistoria säilytetään. + No comment provided by engineer. + + + You won't lose your contacts if you later delete your address. + Et menetä kontaktejasi, jos poistat osoitteesi myöhemmin. + No comment provided by engineer. + + + You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile + Yrität kutsua kontaktia, jonka kanssa olet jakanut inkognito-profiilin, ryhmään, jossa käytät pääprofiiliasi + No comment provided by engineer. + + + You're using an incognito profile for this group - to prevent sharing your main profile inviting contacts is not allowed + Käytät tässä ryhmässä incognito-profiilia. Kontaktien kutsuminen ei ole sallittua, jotta pääprofiilisi ei tule jaetuksi + No comment provided by engineer. + + + Your %@ servers + %@-palvelimesi + No comment provided by engineer. + + + Your ICE servers + ICE-palvelimesi + No comment provided by engineer. + + + Your SMP servers + SMP-palvelimesi + No comment provided by engineer. + + + Your SimpleX address + SimpleX-osoitteesi + No comment provided by engineer. + + + Your XFTP servers + XFTP-palvelimesi + No comment provided by engineer. + + + Your calls + Puhelusi + No comment provided by engineer. + + + Your chat database + Keskustelut-tietokantasi + No comment provided by engineer. + + + Your chat database is not encrypted - set passphrase to encrypt it. + Keskustelut-tietokantasi ei ole salattu - aseta tunnuslause sen salaamiseksi. + No comment provided by engineer. + + + Your chat profile will be sent to group members + Keskusteluprofiilisi lähetetään ryhmän jäsenille + No comment provided by engineer. + + + Your chat profiles + Keskusteluprofiilisi + No comment provided by engineer. + + + Your contact needs to be online for the connection to complete. +You can cancel this connection and remove the contact (and try later with a new link). + Kontaktin tulee olla online-tilassa, jotta yhteys voidaan muodostaa. +Voit peruuttaa tämän yhteyden ja poistaa kontaktin (ja yrittää myöhemmin uudella linkillä). + No comment provided by engineer. + + + Your contact sent a file that is larger than currently supported maximum size (%@). + Yhteyshenkilösi lähetti tiedoston, joka on suurempi kuin tällä hetkellä tuettu enimmäiskoko (%@). + No comment provided by engineer. + + + Your contacts can allow full message deletion. + Kontaktisi voivat sallia viestien täydellisen poistamisen. + No comment provided by engineer. + + Your contacts in SimpleX will see it. You can change it in Settings. - Kontaktisi SimpleX:ssä näkevät sen. + Kontaktisi SimpleX:ssä näkevät sen. Voit muuttaa sitä Asetuksista. No comment provided by engineer. - - Your profile **%@** will be shared. - Profiilisi **%@** jaetaan. + + Your contacts will remain connected. + Kontaktisi pysyvät yhdistettyinä. No comment provided by engineer. - + + Your current chat database will be DELETED and REPLACED with the imported one. + Nykyinen keskustelut-tietokantasi poistetaan ja korvataan tuodulla tietokannalla. + No comment provided by engineer. + + + Your current profile + Nykyinen profiilisi + No comment provided by engineer. + + + Your preferences + Asetuksesi + No comment provided by engineer. + + + Your privacy + Yksityisyytesi + No comment provided by engineer. + + + Your profile **%@** will be shared. + Profiilisi **%@** jaetaan. + No comment provided by engineer. + + + Your profile is stored on your device and shared only with your contacts. +SimpleX servers cannot see your profile. + Profiilisi tallennetaan laitteeseesi ja jaetaan vain yhteystietojesi kanssa. +SimpleX-palvelimet eivät näe profiiliasi. + No comment provided by engineer. + + + Your profile, contacts and delivered messages are stored on your device. + Profiilisi, kontaktisi ja toimitetut viestit tallennetaan laitteellesi. + No comment provided by engineer. + + + Your random profile + Satunnainen profiilisi + No comment provided by engineer. + + + Your server + Palvelimesi + No comment provided by engineer. + + + Your server address + Palvelimesi osoite + No comment provided by engineer. + + + Your settings + Asetuksesi + No comment provided by engineer. + + + [Contribute](https://github.com/simplex-chat/simplex-chat#contribute) + [Osallistu](https://github.com/simplex-chat/simplex-chat#contribute) + No comment provided by engineer. + + + [Send us email](mailto:chat@simplex.chat) + [Lähetä meille sähköpostia](mailto:chat@simplex.chat) + No comment provided by engineer. + + + [Star on GitHub](https://github.com/simplex-chat/simplex-chat) + [Tähti GitHubissa](https://github.com/simplex-chat/simplex-chat) + No comment provided by engineer. + + + \_italic_ + \_italic_ + No comment provided by engineer. + + + \`a + b` + \`a + b` + No comment provided by engineer. + + + above, then choose: + edellä, valitse sitten: + No comment provided by engineer. + + + accepted call + hyväksytty puhelu + call status + + + admin + ylläpitäjä + member role + + agreeing encryption for %@… - salauksesta sovitaan %@:lle… + salauksesta sovitaan %@:lle… chat item text - + + agreeing encryption… + hyväksyy salausta… + chat item text + + + always + aina + pref value + + + audio call (not e2e encrypted) + äänipuhelu (ei e2e-salattu) + No comment provided by engineer. + + + bad message ID + virheellinen viestin tunniste + integrity error chat item + + + bad message hash + virheellinen viestin tarkiste + integrity error chat item + + + bold + lihavoitu + No comment provided by engineer. + + + call error + soittovirhe + call status + + + call in progress + puhelu käynnissä + call status + + + calling… + soittaa… + call status + + + cancelled %@ + peruutettu %@ + feature offered item + + + changed address for you + muuttunut osoite sinulle + chat item text + + + changed role of %1$@ to %2$@ + %1$@:n roolin muuttui %2$@:ksi + rcv group event chat item + + + changed your role to %@ + roolisi muuttui %@:ksi + rcv group event chat item + + + changing address for %@… + osoitteen muuttaminen %@:lle… + chat item text + + + changing address… + muuttamassa osoitetta… + chat item text + + + colored + värillinen + No comment provided by engineer. + + + complete + valmis + No comment provided by engineer. + + + connect to SimpleX Chat developers. + ole yhteydessä SimpleX Chat -kehittäjiin. + No comment provided by engineer. + + + connected + yhdistetty + No comment provided by engineer. + + + connected directly + rcv group event chat item + + + connecting + yhdistää + No comment provided by engineer. + + + connecting (accepted) + yhdistäminen (hyväksytty) + No comment provided by engineer. + + + connecting (announced) + yhdistäminen (ilmoitettu) + No comment provided by engineer. + + + connecting (introduced) + yhdistäminen (esitelty) + No comment provided by engineer. + + + connecting (introduction invitation) + yhdistäminen (esittelykutsu) + No comment provided by engineer. + + + connecting call… + yhdistää puhelun… + call status + + + connecting… + yhdistää… + chat list item title + + + connection established + yhteys luotu + chat list item title (it should not be shown + + + connection:%@ + yhteys:%@ + connection information + + + contact has e2e encryption + kontaktilla on e2e-salaus + No comment provided by engineer. + + + contact has no e2e encryption + kontaktilla ei ole e2e-salausta + No comment provided by engineer. + + + creator + luoja + No comment provided by engineer. + + custom - mukautettu + mukautettu dropdown time picker choice - - days - päivää - time unit - - - encryption re-negotiation allowed for %@ - salauksen uudelleenneuvottelu sallittu %@:lle - chat item text - - - encryption re-negotiation required - tarvitaan salauksen uudelleenneuvottelu - chat item text - - - event happened - tapahtuma tapahtui + + database version is newer than the app, but no down migration for: %@ + tietokantaversio on uudempi kuin sovellus, mutta ei alaspäin siirtymistä varten: %@ No comment provided by engineer. - - security code changed - turvakoodi on muuttunut + + days + päivää + time unit + + + default (%@) + oletusarvo (%@) + pref value + + + default (no) + oletusarvo (ei) + No comment provided by engineer. + + + default (yes) + oletusarvo (kyllä) + No comment provided by engineer. + + + deleted + poistettu + deleted chat item + + + deleted group + poistettu ryhmä + rcv group event chat item + + + different migration in the app/database: %@ / %@ + eri siirtyminen sovelluksessa/tietokannassa: %@ / %@ + No comment provided by engineer. + + + direct + suora + connection level description + + + disabled + ei käytössä + No comment provided by engineer. + + + duplicate message + päällekkäinen viesti + integrity error chat item + + + e2e encrypted + e2e-salattu + No comment provided by engineer. + + + enabled + käytössä + enabled status + + + enabled for contact + käytössä kontaktille + enabled status + + + enabled for you + käytössä sinulle + enabled status + + + encryption agreed + salaus sovittu chat item text + + encryption agreed for %@ + salaus sovittu %@:lle + chat item text + + + encryption ok + salaus ok + chat item text + + + encryption ok for %@ + salaus ok %@:lle + chat item text + + + encryption re-negotiation allowed + salauksen uudelleenneuvottelu sallittu + chat item text + + + encryption re-negotiation allowed for %@ + salauksen uudelleenneuvottelu sallittu %@:lle + chat item text + + + encryption re-negotiation required + tarvitaan salauksen uudelleenneuvottelu + chat item text + + + encryption re-negotiation required for %@ + tarvitaan salauksen uudelleenneuvottelu %@:lle + chat item text + + + ended + päättyi + No comment provided by engineer. + + + ended call %@ + puhelu päättyi %@:lle + call status + + + error + virhe + No comment provided by engineer. + + + event happened + tapahtuma tapahtui + No comment provided by engineer. + + + group deleted + ryhmä poistettu + No comment provided by engineer. + + + group profile updated + ryhmäprofiili päivitetty + snd group event chat item + + + hours + tuntia + time unit + + + iOS Keychain is used to securely store passphrase - it allows receiving push notifications. + iOS-Avainnippua käytetään tunnuslauseen turvalliseen tallentamiseen - se mahdollistaa push-ilmoitusten vastaanottamisen. + No comment provided by engineer. + + + iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications. + iOS-Avainnippua käytetään tunnuslauseen turvalliseen tallentamiseen sen muuttamisen tai sovelluksen uudelleen käynnistämisen jälkeen - se mahdollistaa push-ilmoitusten vastaanottamisen. + No comment provided by engineer. + + + incognito via contact address link + incognito kontaktilinkin kautta + chat list item description + + + incognito via group link + incognito ryhmälinkin kautta + chat list item description + + + incognito via one-time link + incognito kertalinkillä + chat list item description + + + indirect (%d) + epäsuora (%d) + connection level description + + + invalid chat + virheellinen keskustelu + invalid chat data + + + invalid chat data + virheelliset keskustelu-tiedot + No comment provided by engineer. + + + invalid data + virheelliset tiedot + invalid chat item + + + invitation to group %@ + kutsu ryhmään %@ + group name + + + invited + kutsuttu + No comment provided by engineer. + + + invited %@ + kutsuttu %@ + rcv group event chat item + + + invited to connect + kutsuttu yhteydenpitoon + chat list item title + + + invited via your group link + kutsuttu ryhmäsi linkin kautta + rcv group event chat item + + + italic + kursivoitu + No comment provided by engineer. + + + join as %@ + Liity %@:nä + No comment provided by engineer. + + + left + poistunut + rcv group event chat item + + + marked deleted + merkitty poistetuksi + marked deleted chat item preview text + + + member + jäsen + member role + + + connected + yhdistetty + rcv group event chat item + + + message received + viesti vastaanotettu + notification + + + minutes + minuuttia + time unit + + + missed call + vastaamaton puhelu + call status + + + moderated + moderoitu + moderated chat item + + + moderated by %@ + %@ moderoi + No comment provided by engineer. + + + months + kuukautta + time unit + + + never + ei koskaan + No comment provided by engineer. + + + new message + uusi viesti + notification + + + no + ei + pref value + + + no e2e encryption + ei e2e-salausta + No comment provided by engineer. + + + no text + ei tekstiä + copied message info in history + + + observer + tarkkailija + member role + + + off + pois + enabled status + group pref value + + + offered %@ + tarjottu %@ + feature offered item + + + offered %1$@: %2$@ + tarjottu %1$@: %2$@ + feature offered item + + + on + päällä + group pref value + + + or chat with the developers + tai keskustele kehittäjien kanssa + No comment provided by engineer. + + + owner + omistaja + member role + + + peer-to-peer + vertais + No comment provided by engineer. + + + received answer… + vastaus saatu… + No comment provided by engineer. + + + received confirmation… + vahvistus saatu… + No comment provided by engineer. + + + rejected call + hylätty puhelu + call status + + + removed + poistettu + No comment provided by engineer. + + + removed %@ + %@ poistettu + rcv group event chat item + + + removed you + poisti sinut + rcv group event chat item + + + sec + sek + network option + + + seconds + sekuntia + time unit + + + secret + salainen + No comment provided by engineer. + + + security code changed + turvakoodi on muuttunut + chat item text + + + send direct message + No comment provided by engineer. + + + starting… + alkaa… + No comment provided by engineer. + + + strike + soita + No comment provided by engineer. + + + this contact + tämä kontakti + notification title + + + unknown + tuntematon + connection info + + + updated group profile + päivitetty ryhmäprofiili + rcv group event chat item + + + v%@ (%@) + v%@ (%@) + No comment provided by engineer. + + + via contact address link + kontaktiosoitelinkillä + chat list item description + + + via group link + ryhmälinkillä + chat list item description + + + via one-time link + kertalinkillä + chat list item description + + + via relay + releellä + No comment provided by engineer. + + + video call (not e2e encrypted) + videopuhelu (ei e2e-salattu) + No comment provided by engineer. + + + waiting for answer… + odottaa vastaamista… + No comment provided by engineer. + + + waiting for confirmation… + odottaa vahvistusta… + No comment provided by engineer. + + + wants to connect to you! + haluaa olla yhteydessä sinuun! + No comment provided by engineer. + + + weeks + viikkoa + time unit + + + yes + kyllä + pref value + + + you are invited to group + sinut on kutsuttu ryhmään + No comment provided by engineer. + + + you are observer + olet tarkkailija + No comment provided by engineer. + + + you changed address + muutit osoitetta + chat item text + + + you changed address for %@ + muutit osoitetta %@:ksi + chat item text + + + you changed role for yourself to %@ + vaihdoit roolin itsellesi %@:ksi + snd group event chat item + + + you changed role of %1$@ to %2$@ + olet vaihtanut %1$@:n roolin %2$@:ksi + snd group event chat item + + + you left + lähdit + snd group event chat item + + + you removed %@ + poistit %@ + snd group event chat item + + + you shared one-time link + jaoit kertalinkin + chat list item description + + + you shared one-time link incognito + jaoit kertalinkin incognito-tilassa + chat list item description + + + you: + sinä: + No comment provided by engineer. + + + \~strike~ + \~strike~ + No comment provided by engineer. +
- +
- + SimpleX - SimpleX + SimpleX Bundle name - + SimpleX needs camera access to scan QR codes to connect to other users and for video calls. - SimpleX tarvitsee pääsyn kameraan, jotta se voi skannata QR-koodeja muodostaakseen yhteyden muihin käyttäjiin ja videopuheluita varten. + SimpleX tarvitsee pääsyn kameraan, jotta se voi skannata QR-koodeja muodostaakseen yhteyden muihin käyttäjiin ja videopuheluita varten. Privacy - Camera Usage Description - + SimpleX uses Face ID for local authentication - SimpleX käyttää Face ID:tä paikalliseen todennukseen + SimpleX käyttää Face ID:tä paikalliseen todennukseen Privacy - Face ID Usage Description - + SimpleX needs microphone access for audio and video calls, and to record voice messages. - SimpleX tarvitsee mikrofonia ääni- ja videopuheluita ja ääniviestien tallentamista varten. + SimpleX tarvitsee mikrofonia ääni- ja videopuheluita ja ääniviestien tallentamista varten. Privacy - Microphone Usage Description - + SimpleX needs access to Photo Library for saving captured and received media - SimpleX tarvitsee pääsyn valokuvakirjastoon kuvattujen ja vastaanotettujen medioiden tallentamista varten + SimpleX tarvitsee pääsyn valokuvakirjastoon kuvattujen ja vastaanotettujen medioiden tallentamista varten Privacy - Photo Library Additions Usage Description
- +
- + SimpleX NSE - SimpleX NSE + SimpleX NSE Bundle display name - + SimpleX NSE - SimpleX NSE + SimpleX NSE Bundle name - + Copyright © 2022 SimpleX Chat. All rights reserved. - Copyright © 2022 SimpleX Chat. Kaikki oikeudet pidätetään. + Copyright © 2022 SimpleX Chat. Kaikki oikeudet pidätetään. Copyright (human-readable) diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/contents.json b/apps/ios/SimpleX Localizations/fi.xcloc/contents.json index c46e0f6a71..0e3ae6dc56 100644 --- a/apps/ios/SimpleX Localizations/fi.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/fi.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "fi", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff index 95de1b8b27..78f7fca921 100644 --- a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff +++ b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,11 @@ %lld minutes No comment provided by engineer. + + %lld new interface languages + %lld nouvelles langues d'interface + No comment provided by engineer. + %lld second(s) %lld seconde·s @@ -327,6 +332,15 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + - connexion au [service d'annuaire](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA) ! +- les accusés de réception (jusqu'à 20 membres). +- plus rapide et plus stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +714,11 @@ Build de l'app : %@ No comment provided by engineer. + + App encrypts new local files (except videos). + L'application chiffre les nouveaux fichiers locaux (sauf les vidéos). + No comment provided by engineer. + App icon Icône de l'app @@ -835,6 +854,11 @@ Vous et votre contact êtes tous deux en mesure d'envoyer des messages vocaux. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Bulgare, finnois, thaïlandais et ukrainien - grâce aux utilisateurs et à [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat) ! + 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). @@ -1231,6 +1255,11 @@ Créer un lien No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + Créer un nouveau profil sur [l'application de bureau](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Créer un lien d'invitation unique @@ -1684,6 +1713,11 @@ Se déconnecter server test step + + Discover and join groups + Découvrir et rejoindre des groupes + No comment provided by engineer. + Display name Nom affiché @@ -1821,6 +1855,12 @@ Encrypt local files + Chiffrer les fichiers locaux + No comment provided by engineer. + + + Encrypt stored files & media + Chiffrement des fichiers et des médias stockés No comment provided by engineer. @@ -1948,6 +1988,10 @@ Erreur lors de la création du lien du groupe No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! Erreur lors de la création du profil ! @@ -1955,6 +1999,7 @@ Error decrypting file + Erreur lors du déchiffrement du fichier No comment provided by engineer. @@ -2077,6 +2122,10 @@ Erreur lors de l'envoi de l'e-mail No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Erreur lors de l'envoi du message @@ -3090,6 +3139,11 @@ Nouvelle archive de base de données No comment provided by engineer. + + New desktop app! + Nouvelle application de bureau ! + No comment provided by engineer. + New display name Nouveau nom d'affichage @@ -3304,6 +3358,10 @@ Seul votre contact peut envoyer des messages vocaux. No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings Ouvrir les Paramètres @@ -4039,6 +4097,10 @@ Envoi de message direct No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Envoyer un message éphémère @@ -4339,6 +4401,11 @@ Invitation unique SimpleX simplex link type + + Simplified incognito mode + Mode incognito simplifié + No comment provided by engineer. + Skip Passer @@ -4733,6 +4800,11 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s 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 incognito when connecting. + Basculer en mode incognito lors de la connexion. + No comment provided by engineer. + Transport isolation Transport isolé @@ -5581,6 +5653,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. connecté No comment provided by engineer. + + connected directly + rcv group event chat item + connecting connexion @@ -6042,6 +6118,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. code de sécurité modifié chat item text + + send direct message + No comment provided by engineer. + starting… lancement… @@ -6186,7 +6266,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.
- +
@@ -6218,7 +6298,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.
- +
diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/contents.json b/apps/ios/SimpleX Localizations/fr.xcloc/contents.json index 4bc0ea1ff3..7df7c8ed26 100644 --- a/apps/ios/SimpleX Localizations/fr.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/fr.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "fr", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff index fb6ea10da1..2e9b9a3264 100644 --- a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff +++ b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,11 @@ %lld minuti No comment provided by engineer. + + %lld new interface languages + %lld nuove lingue dell'interfaccia + No comment provided by engineer. + %lld second(s) %lld secondo/i @@ -327,6 +332,15 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + - connessione al [servizio directory](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- ricevute di consegna (fino a 20 membri). +- più veloce e più stabile. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +714,11 @@ Build dell'app: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + L'app cripta i nuovi file locali (eccetto i video). + No comment provided by engineer. + App icon Icona app @@ -835,6 +854,11 @@ Sia tu che il tuo contatto potete inviare messaggi vocali. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Bulgaro, finlandese, tailandese e ucraino - grazie agli utenti e a [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). Per profilo di chat (predefinito) o [per connessione](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). @@ -1231,6 +1255,11 @@ Crea link No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + Crea un nuovo profilo nell'[app desktop](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Crea link di invito una tantum @@ -1684,6 +1713,11 @@ Disconnetti server test step + + Discover and join groups + Scopri ed unisciti ai gruppi + No comment provided by engineer. + Display name Nome da mostrare @@ -1821,6 +1855,12 @@ Encrypt local files + Cripta i file locali + No comment provided by engineer. + + + Encrypt stored files & media + Crittografia di file e media memorizzati No comment provided by engineer. @@ -1948,6 +1988,10 @@ Errore nella creazione del link del gruppo No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! Errore nella creazione del profilo! @@ -1955,6 +1999,7 @@ Error decrypting file + Errore decifrando il file No comment provided by engineer. @@ -2077,6 +2122,10 @@ Errore nell'invio dell'email No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Errore nell'invio del messaggio @@ -3090,6 +3139,11 @@ Nuovo archivio database No comment provided by engineer. + + New desktop app! + Nuova app desktop! + No comment provided by engineer. + New display name Nuovo nome da mostrare @@ -3304,6 +3358,10 @@ Solo il tuo contatto può inviare messaggi vocali. No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings Apri le impostazioni @@ -4039,6 +4097,10 @@ Invia messaggio diretto No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Invia messaggio a tempo @@ -4339,6 +4401,11 @@ Invito SimpleX una tantum simplex link type + + Simplified incognito mode + Modalità incognito semplificata + No comment provided by engineer. + Skip Salta @@ -4733,6 +4800,11 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio 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 incognito when connecting. + Attiva/disattiva l'incognito quando ti colleghi. + No comment provided by engineer. + Transport isolation Isolamento del trasporto @@ -5581,6 +5653,10 @@ I server di SimpleX non possono vedere il tuo profilo. connesso/a No comment provided by engineer. + + connected directly + rcv group event chat item + connecting in connessione @@ -6042,6 +6118,10 @@ I server di SimpleX non possono vedere il tuo profilo. codice di sicurezza modificato chat item text + + send direct message + No comment provided by engineer. + starting… avvio… @@ -6186,7 +6266,7 @@ I server di SimpleX non possono vedere il tuo profilo.
- +
@@ -6218,7 +6298,7 @@ I server di SimpleX non possono vedere il tuo profilo.
- +
diff --git a/apps/ios/SimpleX Localizations/it.xcloc/contents.json b/apps/ios/SimpleX Localizations/it.xcloc/contents.json index 09cce11594..2ad653d36f 100644 --- a/apps/ios/SimpleX Localizations/it.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/it.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "it", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff index c7460be601..27d7cb54f6 100644 --- a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff +++ b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,10 @@ %lld 分 No comment provided by engineer. + + %lld new interface languages + No comment provided by engineer. + %lld second(s) %lld 秒 @@ -327,6 +331,12 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +710,10 @@ アプリのビルド: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + No comment provided by engineer. + App icon アプリのアイコン @@ -835,6 +849,10 @@ あなたと連絡相手が音声メッセージを送信できます。 No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). チャット プロファイル経由 (デフォルト) または [接続経由](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). @@ -1231,6 +1249,10 @@ リンクを生成する No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link 使い捨ての招待リンクを生成する @@ -1683,6 +1705,10 @@ 切断 server test step + + Discover and join groups + No comment provided by engineer. + Display name 表示名 @@ -1820,6 +1846,11 @@ Encrypt local files + ローカルファイルを暗号化する + No comment provided by engineer. + + + Encrypt stored files & media No comment provided by engineer. @@ -1947,6 +1978,10 @@ グループリンク生成にエラー発生 No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! プロフィール作成にエラー発生! @@ -1954,6 +1989,7 @@ Error decrypting file + ファイルの復号エラー No comment provided by engineer. @@ -2075,6 +2111,10 @@ メールの送信にエラー発生 No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message メッセージ送信にエラー発生 @@ -3086,6 +3126,10 @@ 新しいデータベースのアーカイブ No comment provided by engineer. + + New desktop app! + No comment provided by engineer. + New display name 新たな表示名 @@ -3300,6 +3344,10 @@ 音声メッセージを送れるのはあなたの連絡相手だけです。 No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings 設定を開く @@ -4033,6 +4081,10 @@ ダイレクトメッセージを送信 No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message 消えるメッセージを送信 @@ -4326,6 +4378,10 @@ SimpleX使い捨て招待リンク simplex link type + + Simplified incognito mode + No comment provided by engineer. + Skip スキップ @@ -4719,6 +4775,10 @@ You will be prompted to complete authentication before this feature is enabled.< エンドツーエンド暗号化を確認するには、ご自分の端末と連絡先の端末のコードを比べます (スキャンします)。 No comment provided by engineer. + + Toggle incognito when connecting. + No comment provided by engineer. + Transport isolation トランスポート隔離 @@ -5567,6 +5627,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 接続中 No comment provided by engineer. + + connected directly + rcv group event chat item + connecting 接続待ち @@ -6028,6 +6092,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 セキュリティコードが変更されました chat item text + + send direct message + No comment provided by engineer. + starting… 接続中… @@ -6172,7 +6240,7 @@ SimpleX サーバーはあなたのプロファイルを参照できません。
- +
@@ -6204,7 +6272,7 @@ SimpleX サーバーはあなたのプロファイルを参照できません。
- +
diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/contents.json b/apps/ios/SimpleX Localizations/ja.xcloc/contents.json index c3f6f3dfa7..7d3c224e68 100644 --- a/apps/ios/SimpleX Localizations/ja.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/ja.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "ja", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff index 7882a062e7..233b1d0ba1 100644 --- a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff +++ b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,11 @@ %lld minuten No comment provided by engineer. + + %lld new interface languages + %lld nieuwe interface-talen + No comment provided by engineer. + %lld second(s) %lld seconde(n) @@ -269,7 +274,7 @@ **Create link / QR code** for your contact to use. - **Maak een link / QR-code aan** die uw contactpersoon kan gebruiken. + **Maak een link / QR-code aan** die uw contact kan gebruiken. No comment provided by engineer. @@ -299,7 +304,7 @@ **Scan QR code**: to connect to your contact in person or via video call. - **Scan QR-code**: om persoonlijk of via een video gesprek verbinding te maken met uw contactpersoon. + **Scan QR-code**: om persoonlijk of via een video gesprek verbinding te maken met uw contact. No comment provided by engineer. @@ -327,6 +332,15 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + - verbinding maken met [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- ontvangst bevestiging(tot 20 leden). +- sneller en stabieler. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -482,7 +496,7 @@ Accept connection request? - Accepteer contactpersoon + Accepteer contact No comment provided by engineer. @@ -592,22 +606,22 @@ Allow calls only if your contact allows them. - Sta oproepen alleen toe als uw contact persoon dit toestaat. + Sta oproepen alleen toe als uw contact dit toestaat. No comment provided by engineer. Allow disappearing messages only if your contact allows it to you. - Sta verdwijnende berichten alleen toe als uw contactpersoon dit toestaat. + Sta verdwijnende berichten alleen toe als uw contact dit toestaat. No comment provided by engineer. Allow irreversible message deletion only if your contact allows it to you. - Sta het onomkeerbaar verwijderen van berichten alleen toe als uw contactpersoon dit toestaat. + Sta het onomkeerbaar verwijderen van berichten alleen toe als uw contact dit toestaat. No comment provided by engineer. Allow message reactions only if your contact allows them. - Sta berichtreacties alleen toe als uw contactpersoon dit toestaat. + Sta berichtreacties alleen toe als uw contact dit toestaat. No comment provided by engineer. @@ -642,7 +656,7 @@ Allow voice messages only if your contact allows them. - Sta spraak berichten alleen toe als uw contactpersoon ze toestaat. + Sta spraak berichten alleen toe als uw contact ze toestaat. No comment provided by engineer. @@ -700,6 +714,11 @@ App build: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + App versleutelt nieuwe lokale bestanden (behalve video's). + No comment provided by engineer. + App icon App icon @@ -812,27 +831,32 @@ Both you and your contact can add message reactions. - Zowel u als uw contactpersoon kunnen berichtreacties toevoegen. + Zowel u als uw contact kunnen berichtreacties toevoegen. No comment provided by engineer. Both you and your contact can irreversibly delete sent messages. - Zowel jij als je contactpersoon kunnen verzonden berichten onherroepelijk verwijderen. + Zowel jij als je contact kunnen verzonden berichten onherroepelijk verwijderen. No comment provided by engineer. Both you and your contact can make calls. - Zowel u als uw contact persoon kunnen bellen. + Zowel u als uw contact kunnen bellen. No comment provided by engineer. Both you and your contact can send disappearing messages. - Zowel jij als je contactpersoon kunnen verdwijnende berichten sturen. + Zowel jij als je contact kunnen verdwijnende berichten sturen. No comment provided by engineer. Both you and your contact can send voice messages. - Zowel jij als je contactpersoon kunnen spraak berichten verzenden. + Zowel jij als je contact kunnen spraak berichten verzenden. + No comment provided by engineer. + + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Bulgaars, Fins, Thais en Oekraïens - dankzij de gebruikers en [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! No comment provided by engineer. @@ -1231,6 +1255,11 @@ Maak link No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + Maak een nieuw profiel aan in [desktop-app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Maak een eenmalige uitnodiging link @@ -1684,6 +1713,11 @@ verbinding verbreken server test step + + Discover and join groups + Ontdek en sluit je aan bij groepen + No comment provided by engineer. + Display name Weergavenaam @@ -1821,6 +1855,12 @@ Encrypt local files + Versleutel lokale bestanden + No comment provided by engineer. + + + Encrypt stored files & media + Versleutel opgeslagen bestanden en media No comment provided by engineer. @@ -1948,6 +1988,10 @@ Fout bij maken van groep link No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! Fout bij aanmaken van profiel! @@ -1955,6 +1999,7 @@ Error decrypting file + Fout bij het ontsleutelen van bestand No comment provided by engineer. @@ -2077,6 +2122,10 @@ Fout bij het verzenden van e-mail No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Fout bij verzenden van bericht @@ -2199,12 +2248,12 @@ File will be received when your contact completes uploading it. - Het bestand wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid. + Het bestand wordt gedownload wanneer uw contact het uploaden heeft voltooid. No comment provided by engineer. File will be received when your contact is online, please wait or check later! - Het bestand wordt ontvangen wanneer uw contact persoon online is, even geduld a.u.b. of controleer later! + Het bestand wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of controleer later! No comment provided by engineer. @@ -2514,7 +2563,7 @@ If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Als u elkaar niet persoonlijk kunt ontmoeten, kunt u **de QR-code scannen in het video gesprek**, of uw contactpersoon kan een uitnodiging link delen. + Als u elkaar niet persoonlijk kunt ontmoeten, kunt u **de QR-code scannen in het video gesprek**, of uw contact kan een uitnodiging link delen. No comment provided by engineer. @@ -2539,7 +2588,7 @@ Image will be received when your contact completes uploading it. - De afbeelding wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid. + De afbeelding wordt gedownload wanneer uw contact het uploaden heeft voltooid. No comment provided by engineer. @@ -2731,7 +2780,7 @@ 3. The connection was compromised. Het kan gebeuren wanneer: 1. De berichten zijn na 2 dagen verlopen bij de verzendende client of na 30 dagen op de server. -2. Decodering van het bericht is mislukt, omdat u of uw contactpersoon een oude databaseback-up heeft gebruikt. +2. Decodering van het bericht is mislukt, omdat u of uw contact een oude databaseback-up heeft gebruikt. 3. De verbinding is verbroken. No comment provided by engineer. @@ -3090,6 +3139,11 @@ Nieuw database archief No comment provided by engineer.
+ + New desktop app! + Nieuwe desktop app! + No comment provided by engineer. + New display name Nieuwe weergavenaam @@ -3261,7 +3315,7 @@ Only you can irreversibly delete messages (your contact can mark them for deletion). - Alleen jij kunt berichten onomkeerbaar verwijderen (je contactpersoon kan ze markeren voor verwijdering). + Alleen jij kunt berichten onomkeerbaar verwijderen (je contact kan ze markeren voor verwijdering). No comment provided by engineer. @@ -3281,12 +3335,12 @@ Only your contact can add message reactions. - Alleen uw contactpersoon kan berichtreacties toevoegen. + Alleen uw contact kan berichtreacties toevoegen. No comment provided by engineer. Only your contact can irreversibly delete messages (you can mark them for deletion). - Alleen uw contactpersoon kan berichten onherroepelijk verwijderen (u kunt ze markeren voor verwijdering). + Alleen uw contact kan berichten onherroepelijk verwijderen (u kunt ze markeren voor verwijdering). No comment provided by engineer. @@ -3296,12 +3350,16 @@ Only your contact can send disappearing messages. - Alleen uw contactpersoon kan verdwijnende berichten verzenden. + Alleen uw contact kan verdwijnende berichten verzenden. No comment provided by engineer. Only your contact can send voice messages. - Alleen uw contactpersoon kan spraak berichten verzenden. + Alleen uw contact kan spraak berichten verzenden. + No comment provided by engineer. + + + Open No comment provided by engineer. @@ -3396,7 +3454,7 @@ Paste the link you received to connect with your contact. - Plak de link die je hebt ontvangen in het vak hieronder om verbinding te maken met je contactpersoon. + Plak de link die je hebt ontvangen in het vak hieronder om verbinding te maken met je contact. placeholder @@ -3416,12 +3474,12 @@ Please ask your contact to enable sending voice messages. - Vraag uw contactpersoon om het verzenden van spraak berichten in te schakelen. + Vraag uw contact om het verzenden van spraak berichten in te schakelen. No comment provided by engineer. Please check that you used the correct link or ask your contact to send you another one. - Controleer of u de juiste link heeft gebruikt of vraag uw contactpersoon om u een andere te sturen. + Controleer of u de juiste link heeft gebruikt of vraag uw contact om u een andere te sturen. No comment provided by engineer. @@ -3966,7 +4024,7 @@ Scan security code from your contact's app. - Scan de beveiligingscode van de app van uw contactpersoon. + Scan de beveiligingscode van de app van uw contact. No comment provided by engineer. @@ -4039,6 +4097,10 @@ Direct bericht sturen No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Stuur een verdwijnend bericht @@ -4339,6 +4401,11 @@ Eenmalige SimpleX uitnodiging simplex link type + + Simplified incognito mode + Vereenvoudigde incognitomodus + No comment provided by engineer. + Skip Overslaan @@ -4688,7 +4755,7 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast. To connect, your contact can scan QR code or use the link in the app. - Om verbinding te maken, kan uw contact persoon de QR-code scannen of de link in de app gebruiken. + Om verbinding te maken, kan uw contact de QR-code scannen of de link in de app gebruiken. No comment provided by engineer. @@ -4730,7 +4797,12 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc To verify end-to-end encryption with your contact compare (or scan) the code on your devices. - Vergelijk (of scan) de code op uw apparaten om end-to-end-codering met uw contactpersoon te verifiëren. + Vergelijk (of scan) de code op uw apparaten om end-to-end-codering met uw contact te verifiëren. + No comment provided by engineer. + + + Toggle incognito when connecting. + Schakel incognito in tijdens het verbinden. No comment provided by engineer. @@ -4826,8 +4898,8 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. To connect, please ask your contact to create another connection link and check that you have a stable network connection. - Tenzij uw contactpersoon de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft. -Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft. + Tenzij uw contact de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft. +Om verbinding te maken, vraagt u uw contact om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft. No comment provided by engineer. @@ -4972,7 +5044,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link Video will be received when your contact completes uploading it. - De video wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid. + De video wordt gedownload wanneer uw contact het uploaden heeft voltooid. No comment provided by engineer. @@ -5222,7 +5294,7 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link You invited a contact - Je hebt je contactpersoon uitgenodigd + Je hebt je contact uitgenodigd No comment provided by engineer. @@ -5358,13 +5430,13 @@ Om verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link Your contact needs to be online for the connection to complete. You can cancel this connection and remove the contact (and try later with a new link). - Uw contactpersoon moet online zijn om de verbinding te voltooien. -U kunt deze verbinding verbreken en het contact verwijderen (en later proberen met een nieuwe link). + Uw contact moet online zijn om de verbinding te voltooien. +U kunt deze verbinding verbreken en het contact verwijderen en later proberen met een nieuwe link. No comment provided by engineer. Your contact sent a file that is larger than currently supported maximum size (%@). - Uw contactpersoon heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%@). + Uw contact heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%@). No comment provided by engineer. @@ -5581,6 +5653,10 @@ SimpleX servers kunnen uw profiel niet zien. verbonden No comment provided by engineer. + + connected directly + rcv group event chat item + connecting Verbinden @@ -5808,7 +5884,7 @@ SimpleX servers kunnen uw profiel niet zien. incognito via contact address link - incognito via contact adres link + incognito via contactadres link chat list item description @@ -6042,6 +6118,10 @@ SimpleX servers kunnen uw profiel niet zien. beveiligingscode gewijzigd chat item text + + send direct message + No comment provided by engineer. + starting… beginnen… @@ -6074,7 +6154,7 @@ SimpleX servers kunnen uw profiel niet zien. via contact address link - via contact adres link + via contactadres link chat list item description @@ -6186,7 +6266,7 @@ SimpleX servers kunnen uw profiel niet zien.
- +
@@ -6218,7 +6298,7 @@ SimpleX servers kunnen uw profiel niet zien.
- +
diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/contents.json b/apps/ios/SimpleX Localizations/nl.xcloc/contents.json index f6e41f93c7..20246f53d4 100644 --- a/apps/ios/SimpleX Localizations/nl.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/nl.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "nl", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff index 7402249c01..2e0e2de446 100644 --- a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff +++ b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,11 @@ %lld minut No comment provided by engineer. + + %lld new interface languages + %lld nowe języki interfejsu + No comment provided by engineer. + %lld second(s) %lld sekund(y) @@ -327,6 +332,15 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + - połącz do [serwera katalogowego](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- potwierdzenie dostarczenia (do 20 członków). +- szybszy i bardziej stabilny. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +714,11 @@ Kompilacja aplikacji: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + Aplikacja szyfruje nowe lokalne pliki (bez filmów). + No comment provided by engineer. + App icon Ikona aplikacji @@ -835,6 +854,11 @@ Zarówno Ty, jak i Twój kontakt możecie wysyłać wiadomości głosowe. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Bułgarski, fiński, tajski i ukraiński – dzięki użytkownikom i [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). Według profilu czatu (domyślnie) lub [według połączenia](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). @@ -1231,6 +1255,11 @@ Utwórz link No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + Utwórz nowy profil w [aplikacji desktopowej](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Utwórz jednorazowy link do zaproszenia @@ -1684,6 +1713,11 @@ Rozłącz server test step + + Discover and join groups + Odkrywaj i dołączaj do grup + No comment provided by engineer. + Display name Wyświetlana nazwa @@ -1821,6 +1855,12 @@ Encrypt local files + Zaszyfruj lokalne pliki + No comment provided by engineer. + + + Encrypt stored files & media + Szyfruj przechowywane pliki i media No comment provided by engineer. @@ -1948,6 +1988,10 @@ Błąd tworzenia linku grupy No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! Błąd tworzenia profilu! @@ -1955,6 +1999,7 @@ Error decrypting file + Błąd odszyfrowania pliku No comment provided by engineer. @@ -2077,6 +2122,10 @@ Błąd wysyłania e-mail No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Błąd wysyłania wiadomości @@ -3090,6 +3139,11 @@ Nowe archiwum bazy danych No comment provided by engineer. + + New desktop app! + Nowa aplikacja desktopowa! + No comment provided by engineer. + New display name Nowa wyświetlana nazwa @@ -3304,6 +3358,10 @@ Tylko Twój kontakt może wysyłać wiadomości głosowe. No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings Otwórz Ustawienia @@ -4039,6 +4097,10 @@ Wyślij wiadomość bezpośrednią No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Wyślij znikającą wiadomość @@ -4339,6 +4401,11 @@ Zaproszenie jednorazowe SimpleX simplex link type + + Simplified incognito mode + Uproszczony tryb incognito + No comment provided by engineer. + Skip Pomiń @@ -4733,6 +4800,11 @@ Przed włączeniem tej funkcji zostanie wyświetlony monit uwierzytelniania.Aby zweryfikować szyfrowanie end-to-end z Twoim kontaktem porównaj (lub zeskanuj) kod na waszych urządzeniach. No comment provided by engineer. + + Toggle incognito when connecting. + Przełącz incognito przy połączeniu. + No comment provided by engineer. + Transport isolation Izolacja transportu @@ -5581,6 +5653,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. połączony No comment provided by engineer. + + connected directly + rcv group event chat item + connecting łączenie @@ -6042,6 +6118,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. kod bezpieczeństwa zmieniony chat item text + + send direct message + No comment provided by engineer. + starting… uruchamianie… @@ -6186,7 +6266,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.
- +
@@ -6218,7 +6298,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.
- +
diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/contents.json b/apps/ios/SimpleX Localizations/pl.xcloc/contents.json index 5c9c3b4bd7..22043b831d 100644 --- a/apps/ios/SimpleX Localizations/pl.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/pl.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "pl", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff index eec4fd40de..54841f241e 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -2,7 +2,7 @@
- +
@@ -197,6 +197,11 @@ %lld минуты No comment provided by engineer. + + %lld new interface languages + %lld новых языков интерфейса + No comment provided by engineer. + %lld second(s) %lld секунд @@ -327,6 +332,15 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + - соединиться с [каталогом групп](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- отчеты о доставке (до 20 членов). +- быстрее и стабильнее. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -700,6 +714,11 @@ Сборка приложения: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + Приложение шифрует новые локальные файлы (кроме видео). + No comment provided by engineer. + App icon Иконка @@ -835,6 +854,11 @@ Вы и Ваш контакт можете отправлять голосовые сообщения. No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Болгарский, финский, тайский и украинский - благодаря пользователям и [Weblate] (https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). По профилю чата или [по соединению](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (БЕТА). @@ -1231,6 +1255,11 @@ Создать ссылку No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + Создайте новый профиль в [приложении для компьютера](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link Создать ссылку-приглашение @@ -1684,6 +1713,11 @@ Разрыв соединения server test step + + Discover and join groups + Найдите и вступите в группы + No comment provided by engineer. + Display name Имя профиля @@ -1821,6 +1855,12 @@ Encrypt local files + Шифровать локальные файлы + No comment provided by engineer. + + + Encrypt stored files & media + Шифруйте сохраненные файлы и медиа No comment provided by engineer. @@ -1948,6 +1988,10 @@ Ошибка при создании ссылки группы No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! Ошибка создания профиля! @@ -1955,6 +1999,7 @@ Error decrypting file + Ошибка расшифровки файла No comment provided by engineer. @@ -2077,6 +2122,10 @@ Ошибка отправки email No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message Ошибка при отправке сообщения @@ -3090,6 +3139,11 @@ Новый архив чата No comment provided by engineer. + + New desktop app! + Приложение для компьютера! + No comment provided by engineer. + New display name Новое имя @@ -3304,6 +3358,10 @@ Только Ваш контакт может отправлять голосовые сообщения. No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings Открыть Настройки @@ -4039,6 +4097,10 @@ Отправить сообщение No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message Отправить исчезающее сообщение @@ -4339,6 +4401,11 @@ SimpleX одноразовая ссылка simplex link type + + Simplified incognito mode + Упрощенный режим Инкогнито + No comment provided by engineer. + Skip Пропустить @@ -4733,6 +4800,11 @@ You will be prompted to complete authentication before this feature is enabled.< Чтобы подтвердить end-to-end шифрование с Вашим контактом сравните (или сканируйте) код безопасности на Ваших устройствах. No comment provided by engineer. + + Toggle incognito when connecting. + Установите режим Инкогнито при соединении. + No comment provided by engineer. + Transport isolation Отдельные сессии для @@ -5581,6 +5653,10 @@ SimpleX серверы не могут получить доступ к Ваше соединение установлено No comment provided by engineer. + + connected directly + rcv group event chat item + connecting соединяется @@ -6042,6 +6118,10 @@ SimpleX серверы не могут получить доступ к Ваше код безопасности изменился chat item text + + send direct message + No comment provided by engineer. + starting… инициализация… @@ -6186,7 +6266,7 @@ SimpleX серверы не могут получить доступ к Ваше
- +
@@ -6218,7 +6298,7 @@ SimpleX серверы не могут получить доступ к Ваше
- +
diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/contents.json b/apps/ios/SimpleX Localizations/ru.xcloc/contents.json index 14ed778b8b..2d5d76dd8f 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/ru.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "ru", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff index 11bde620f3..19681b3150 100644 --- a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff +++ b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff @@ -2,7 +2,7 @@
- +
@@ -192,6 +192,10 @@ %lld นาที No comment provided by engineer. + + %lld new interface languages + No comment provided by engineer. + %lld second(s) %lld วินาที @@ -322,6 +326,12 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -693,6 +703,10 @@ รุ่นแอป: %@ No comment provided by engineer. + + App encrypts new local files (except videos). + No comment provided by engineer. + App icon ไอคอนแอป @@ -828,6 +842,10 @@ ทั้งคุณและผู้ติดต่อของคุณสามารถส่งข้อความเสียงได้ No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). ตามโปรไฟล์แชท (ค่าเริ่มต้น) หรือ [โดยการเชื่อมต่อ](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (เบต้า) @@ -1220,6 +1238,10 @@ สร้างลิงค์ No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link สร้างลิงก์เชิญแบบใช้ครั้งเดียว @@ -1672,6 +1694,10 @@ ตัดการเชื่อมต่อ server test step + + Discover and join groups + No comment provided by engineer. + Display name ชื่อที่แสดง @@ -1811,6 +1837,10 @@ Encrypt local files No comment provided by engineer. + + Encrypt stored files & media + No comment provided by engineer. + Encrypted database Encrypt ฐานข้อมูลเรียบร้อยแล้ว @@ -1936,6 +1966,10 @@ เกิดข้อผิดพลาดในการสร้างลิงก์กลุ่ม No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! เกิดข้อผิดพลาดในการสร้างโปรไฟล์! @@ -2065,6 +2099,10 @@ เกิดข้อผิดพลาดในการส่งอีเมล No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message เกิดข้อผิดพลาดในการส่งข้อความ @@ -3075,6 +3113,10 @@ ฐานข้อมูลใหม่สำหรับการเก็บถาวร No comment provided by engineer. + + New desktop app! + No comment provided by engineer. + New display name ชื่อที่แสดงใหม่ @@ -3288,6 +3330,10 @@ ผู้ติดต่อของคุณเท่านั้นที่สามารถส่งข้อความเสียงได้ No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings เปิดการตั้งค่า @@ -4020,6 +4066,10 @@ ส่งข้อความโดยตรง No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message ส่งข้อความแบบที่หายไป @@ -4317,6 +4367,10 @@ คำเชิญ SimpleX แบบครั้งเดียว simplex link type + + Simplified incognito mode + No comment provided by engineer. + Skip ข้าม @@ -4709,6 +4763,10 @@ You will be prompted to complete authentication before this feature is enabled.< ในการตรวจสอบการเข้ารหัสแบบ encrypt จากต้นจนจบ กับผู้ติดต่อของคุณ ให้เปรียบเทียบ (หรือสแกน) รหัสบนอุปกรณ์ของคุณ No comment provided by engineer. + + Toggle incognito when connecting. + No comment provided by engineer. + Transport isolation การแยกการขนส่ง @@ -5553,6 +5611,10 @@ SimpleX servers cannot see your profile. เชื่อมต่อสำเร็จ No comment provided by engineer. + + connected directly + rcv group event chat item + connecting กำลังเชื่อมต่อ @@ -6012,6 +6074,10 @@ SimpleX servers cannot see your profile. เปลี่ยนรหัสความปลอดภัยแล้ว chat item text + + send direct message + No comment provided by engineer. + starting… กำลังเริ่มต้น… @@ -6156,7 +6222,7 @@ SimpleX servers cannot see your profile.
- +
@@ -6188,7 +6254,7 @@ SimpleX servers cannot see your profile.
- +
diff --git a/apps/ios/SimpleX Localizations/th.xcloc/contents.json b/apps/ios/SimpleX Localizations/th.xcloc/contents.json index e81c22aadd..b60f9edb3e 100644 --- a/apps/ios/SimpleX Localizations/th.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/th.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "th", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff index 52c69fbfac..4947bf80c5 100644 --- a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff +++ b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff @@ -2,6410 +2,6304 @@
- +
- + - + No comment provided by engineer. - + - + No comment provided by engineer. - + - + No comment provided by engineer. - + - + No comment provided by engineer. - + ( - ( + ( No comment provided by engineer. - + (can be copied) - (можна скопіювати) + (можна скопіювати) No comment provided by engineer. - + !1 colored! - !1 кольоровий! + !1 кольоровий! No comment provided by engineer. - + + # %@ + # %@ + copied message info title, # <title> + + + ## History + ## Історія + copied message info + + + ## In reply to + ## У відповідь на + copied message info + + #secret# - #секрет# + #секрет# No comment provided by engineer. - + %@ - %@ + %@ No comment provided by engineer. - + %@ %@ - %@ %@ + %@ %@ No comment provided by engineer. - - %@ / %@ - %@ / %@ - No comment provided by engineer. - - - %@ is connected! - %@ підключено! - notification title - - - %@ is not verified - %@ не перевірено - No comment provided by engineer. - - - %@ is verified - %@ перевірено - No comment provided by engineer. - - - %@ wants to connect! - %@ хоче підключитися! - notification title - - - %d days - %d днів - message ttl - - - %d hours - %d годин - message ttl - - - %d min - %d хв - message ttl - - - %d months - %d місяців - message ttl - - - %d sec - %d сек - message ttl - - - %d skipped message(s) - %d пропущено повідомлення(ь) - integrity error chat item - - - %lld - %lld - No comment provided by engineer. - - - %lld %@ - %lld %@ - No comment provided by engineer. - - - %lld contact(s) selected - %lld контакт(и) вибрані - No comment provided by engineer. - - - %lld file(s) with total size of %@ - %lld файл(и) загальним розміром %@ - No comment provided by engineer. - - - %lld members - %lld учасників - No comment provided by engineer. - - - %lld second(s) - %lld секунд(и) - No comment provided by engineer. - - - %lldd - %lldd - No comment provided by engineer. - - - %lldh - %lldh - No comment provided by engineer. - - - %lldk - %lldk - No comment provided by engineer. - - - %lldm - %lldm - No comment provided by engineer. - - - %lldmth - %lldmth - No comment provided by engineer. - - - %llds - %llds - No comment provided by engineer. - - - %lldw - %lldw - No comment provided by engineer. - - - ( - ( - No comment provided by engineer. - - - ) - ) - No comment provided by engineer. - - - **Add new contact**: to create your one-time QR Code or link for your contact. - **Додати новий контакт**: щоб створити одноразовий QR-код або посилання для свого контакту. - No comment provided by engineer. - - - **Create link / QR code** for your contact to use. - **Створіть посилання / QR-код** для використання вашим контактом. - No comment provided by engineer. - - - **More private**: check new messages every 20 minutes. Device token is shared with SimpleX Chat server, but not how many contacts or messages you have. - **Більш приватний**: перевіряти нові повідомлення кожні 20 хвилин. Серверу SimpleX Chat передається токен пристрою, але не кількість контактів або повідомлень, які ви маєте. - No comment provided by engineer. - - - **Most private**: do not use SimpleX Chat notifications server, check messages periodically in the background (depends on how often you use the app). - **Найбільш приватний**: не використовуйте сервер сповіщень SimpleX Chat, періодично перевіряйте повідомлення у фоновому режимі (залежить від того, як часто ви користуєтесь додатком). - No comment provided by engineer. - - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Вставте отримане посилання** або відкрийте його в браузері і натисніть **Відкрити в мобільному додатку**. - No comment provided by engineer. - - - **Please note**: you will NOT be able to recover or change passphrase if you lose it. - **Зверніть увагу: ви НЕ зможете відновити або змінити пароль, якщо втратите його. - No comment provided by engineer. - - - **Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from. - **Рекомендується**: токен пристрою та сповіщення надсилаються на сервер сповіщень SimpleX Chat, але не вміст повідомлення, його розмір або від кого воно надійшло. - No comment provided by engineer. - - - **Scan QR code**: to connect to your contact in person or via video call. - **Відскануйте QR-код**: щоб з'єднатися з вашим контактом особисто або за допомогою відеодзвінка. - No comment provided by engineer. - - - **Warning**: Instant push notifications require passphrase saved in Keychain. - **Попередження**: Для отримання миттєвих пуш-сповіщень потрібна парольна фраза, збережена у брелоку. - No comment provided by engineer. - - - **e2e encrypted** audio call - **e2e encrypted** аудіодзвінок - No comment provided by engineer. - - - **e2e encrypted** video call - **e2e encrypted** відеодзвінок - No comment provided by engineer. - - - \*bold* - \*жирний* - No comment provided by engineer. - - - , - , - No comment provided by engineer. - - - . - . - No comment provided by engineer. - - - 1 day - 1 день - message ttl - - - 1 hour - 1 година - message ttl - - - 1 month - 1 місяць - message ttl - - - 1 week - 1 тиждень - message ttl - - - 2 weeks - message ttl - - - 6 - 6 - No comment provided by engineer. - - - : - : - No comment provided by engineer. - - - A new contact - Новий контакт - notification title - - - A random profile will be sent to the contact that you received this link from - Випадковий профіль буде надіслано контакту, від якого ви отримали це посилання - No comment provided by engineer. - - - A random profile will be sent to your contact - Випадковий профіль буде надіслано на ваш контакт - No comment provided by engineer. - - - A separate TCP connection will be used **for each chat profile you have in the app**. - Для кожного профілю чату, який ви маєте в додатку, буде використовуватися окреме TCP-з'єднання. - No comment provided by engineer. - - - A separate TCP connection will be used **for each contact and group member**. -**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail. - Для кожного контакту та учасника групи буде використовуватися окреме TCP-з'єднання. -**Зверніть увагу: якщо у вас багато з'єднань, споживання заряду акумулятора і трафіку може бути значно вищим, а деякі з'єднання можуть обірватися. - No comment provided by engineer. - - - About SimpleX - Про SimpleX - No comment provided by engineer. - - - About SimpleX Chat - Про чат SimpleX - No comment provided by engineer. - - - Accent color - Акцентний колір - No comment provided by engineer. - - - Accept - Прийняти - accept contact request via notification - accept incoming call via notification - - - Accept contact - Прийняти контакт - No comment provided by engineer. - - - Accept contact request from %@? - Прийняти запит на контакт від %@? - notification body - - - Accept incognito - Прийняти інкогніто - No comment provided by engineer. - - - Accept requests - No comment provided by engineer. - - - Add preset servers - Додавання попередньо встановлених серверів - No comment provided by engineer. - - - Add profile - Додати профіль - No comment provided by engineer. - - - Add servers by scanning QR codes. - Додайте сервери, відсканувавши QR-код. - No comment provided by engineer. - - - Add server… - Додати сервер… - No comment provided by engineer. - - - Add to another device - Додати до іншого пристрою - No comment provided by engineer. - - - Admins can create the links to join groups. - Адміни можуть створювати посилання для приєднання до груп. - No comment provided by engineer. - - - Advanced network settings - Розширені налаштування мережі - No comment provided by engineer. - - - All chats and messages will be deleted - this cannot be undone! - Всі чати та повідомлення будуть видалені - це неможливо скасувати! - No comment provided by engineer. - - - All group members will remain connected. - Всі учасники групи залишаться на зв'язку. - No comment provided by engineer. - - - All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. - Всі повідомлення будуть видалені - це неможливо скасувати! Повідомлення будуть видалені ТІЛЬКИ для вас. - No comment provided by engineer. - - - All your contacts will remain connected - No comment provided by engineer. - - - Allow - Дозволити - No comment provided by engineer. - - - Allow disappearing messages only if your contact allows it to you. - Дозволяйте зникати повідомленням, тільки якщо контакт дозволяє вам це робити. - No comment provided by engineer. - - - Allow irreversible message deletion only if your contact allows it to you. - Дозволяйте безповоротне видалення повідомлень, тільки якщо контакт дозволяє вам це зробити. - No comment provided by engineer. - - - Allow sending direct messages to members. - Дозволяє надсилати прямі повідомлення користувачам. - No comment provided by engineer. - - - Allow sending disappearing messages. - Дозволити надсилання зникаючих повідомлень. - No comment provided by engineer. - - - Allow to irreversibly delete sent messages. - Дозволяє безповоротно видаляти надіслані повідомлення. - No comment provided by engineer. - - - Allow to send voice messages. - Дозволити надсилати голосові повідомлення. - No comment provided by engineer. - - - Allow voice messages only if your contact allows them. - Дозволяйте голосові повідомлення, тільки якщо ваш контакт дозволяє їх. - No comment provided by engineer. - - - Allow voice messages? - Дозволити голосові повідомлення? - No comment provided by engineer. - - - Allow your contacts to irreversibly delete sent messages. - Дозвольте вашим контактам безповоротно видаляти надіслані повідомлення. - No comment provided by engineer. - - - Allow your contacts to send disappearing messages. - Дозвольте своїм контактам надсилати зникаючі повідомлення. - No comment provided by engineer. - - - Allow your contacts to send voice messages. - Дозвольте своїм контактам надсилати голосові повідомлення. - No comment provided by engineer. - - - Already connected? - Вже підключено? - No comment provided by engineer. - - - Always use relay - Завжди використовуйте реле - No comment provided by engineer. - - - Answer call - Відповісти на дзвінок - No comment provided by engineer. - - - App build: %@ - Збірка програми: %@ - No comment provided by engineer. - - - App icon - Іконка програми - No comment provided by engineer. - - - App version - Версія програми - No comment provided by engineer. - - - App version: v%@ - Версія програми: v%@ - No comment provided by engineer. - - - Appearance - Зовнішній вигляд - No comment provided by engineer. - - - Attach - Прикріпити - No comment provided by engineer. - - - Audio & video calls - Аудіо та відео дзвінки - No comment provided by engineer. - - - Authentication failed - Не вдалося пройти автентифікацію - No comment provided by engineer. - - - Authentication is required before the call is connected, but you may miss calls. - Перед з'єднанням дзвінка потрібно пройти автентифікацію, але ви можете пропустити дзвінки. - No comment provided by engineer. - - - Authentication unavailable - Автентифікація недоступна - No comment provided by engineer. - - - Auto-accept contact requests - Автоматичне прийняття запитів на контакт - No comment provided by engineer. - - - Auto-accept images - Автоматичне прийняття зображень - No comment provided by engineer. - - - Automatically - No comment provided by engineer. - - - Back - Назад - No comment provided by engineer. - - - Both you and your contact can irreversibly delete sent messages. - І ви, і ваш контакт можете безповоротно видалити надіслані повідомлення. - No comment provided by engineer. - - - Both you and your contact can send disappearing messages. - Ви і ваш контакт можете надсилати зникаючі повідомлення. - No comment provided by engineer. - - - Both you and your contact can send voice messages. - Надсилати голосові повідомлення можете як ви, так і ваш контакт. - 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). - Через профіль чату (за замовчуванням) або [за з'єднанням](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). - No comment provided by engineer. - - - Call already ended! - Дзвінок вже закінчився! - No comment provided by engineer. - - - Calls - Дзвінки - No comment provided by engineer. - - - Can't invite contact! - Не вдається запросити контакт! - No comment provided by engineer. - - - Can't invite contacts! - Неможливо запросити контакти! - No comment provided by engineer. - - - Cancel - Скасувати - No comment provided by engineer. - - - Cannot access keychain to save database password - Не вдається отримати доступ до зв'язки ключів для збереження пароля до бази даних - No comment provided by engineer. - - - Cannot receive file - Не вдається отримати файл - No comment provided by engineer. - - - Change - Зміна - No comment provided by engineer. - - - Change database passphrase? - Змінити пароль до бази даних? - No comment provided by engineer. - - - Change member role? - Змінити роль учасника? - No comment provided by engineer. - - - Change receiving address - Змінити адресу отримання - No comment provided by engineer. - - - Change receiving address? - Змінити адресу отримання? - No comment provided by engineer. - - - Change role - Змінити роль - No comment provided by engineer. - - - Chat archive - Архів чату - No comment provided by engineer. - - - Chat console - Консоль чату - No comment provided by engineer. - - - Chat database - База даних чату - No comment provided by engineer. - - - Chat database deleted - Видалено базу даних чату - No comment provided by engineer. - - - Chat database imported - Імпорт бази даних чату - No comment provided by engineer. - - - Chat is running - Чат запущено - No comment provided by engineer. - - - Chat is stopped - Чат зупинено - No comment provided by engineer. - - - Chat preferences - Налаштування чату - No comment provided by engineer. - - - Chats - Чати - No comment provided by engineer. - - - Check server address and try again. - Перевірте адресу сервера та спробуйте ще раз. - No comment provided by engineer. - - - Choose file - Виберіть файл - No comment provided by engineer. - - - Choose from library - Виберіть з бібліотеки - No comment provided by engineer. - - - Clear - Чисто - No comment provided by engineer. - - - Clear conversation - Ясна розмова - No comment provided by engineer. - - - Clear conversation? - Відверта розмова? - No comment provided by engineer. - - - Clear verification - Очистити перевірку - No comment provided by engineer. - - - Colors - Кольори - No comment provided by engineer. - - - Compare security codes with your contacts. - Порівняйте коди безпеки зі своїми контактами. - No comment provided by engineer. - - - Configure ICE servers - Налаштування серверів ICE - No comment provided by engineer. - - - Confirm - Підтвердити - No comment provided by engineer. - - - Confirm new passphrase… - Підтвердіть нову парольну фразу… - No comment provided by engineer. - - - Connect - Підключіться - server test step - - - Connect via contact link? - Підключитися за контактним посиланням? - No comment provided by engineer. - - - Connect via group link? - Підключитися за груповим посиланням? - No comment provided by engineer. - - - Connect via link - Підключіться за посиланням - No comment provided by engineer. - - - Connect via link / QR code - Підключитися за посиланням / QR-кодом - No comment provided by engineer. - - - Connect via one-time link? - Підключитися за одноразовим посиланням? - No comment provided by engineer. - - - Connecting to server… - Підключення до сервера… - No comment provided by engineer. - - - Connecting to server… (error: %@) - Підключення до сервера... (помилка: %@) - No comment provided by engineer. - - - Connection - Підключення - No comment provided by engineer. - - - Connection error - Помилка підключення - No comment provided by engineer. - - - Connection error (AUTH) - Помилка підключення (AUTH) - No comment provided by engineer. - - - Connection request - Запит на підключення - No comment provided by engineer. - - - Connection request sent! - Запит на підключення відправлено! - No comment provided by engineer. - - - Connection timeout - Тайм-аут з'єднання - No comment provided by engineer. - - - Contact allows - Контакт дозволяє - No comment provided by engineer. - - - Contact already exists - Контакт вже існує - No comment provided by engineer. - - - Contact and all messages will be deleted - this cannot be undone! - Контакт і всі повідомлення будуть видалені - це неможливо скасувати! - No comment provided by engineer. - - - Contact hidden: - Контакт приховано: - notification - - - Contact is connected - Контакт підключений - notification - - - Contact is not connected yet! - Контакт ще не підключено! - No comment provided by engineer. - - - Contact name - Ім'я контактної особи - No comment provided by engineer. - - - Contact preferences - Налаштування контактів - No comment provided by engineer. - - - Contact requests - No comment provided by engineer. - - - Contacts can mark messages for deletion; you will be able to view them. - Контакти можуть позначати повідомлення для видалення; ви зможете їх переглянути. - No comment provided by engineer. - - - Copy - Копіювати - chat item action - - - Core built at: %@ - No comment provided by engineer. - - - Core version: v%@ - Основна версія: v%@ - No comment provided by engineer. - - - Create - Створити - No comment provided by engineer. - - - Create address - No comment provided by engineer. - - - Create group link - Створити групове посилання - No comment provided by engineer. - - - Create link - Створити посилання - No comment provided by engineer. - - - Create one-time invitation link - Створіть одноразове посилання-запрошення - No comment provided by engineer. - - - Create queue - Створити чергу - server test step - - - Create secret group - Створити секретну групу - No comment provided by engineer. - - - Create your profile - Створіть свій профіль - No comment provided by engineer. - - - Created on %@ - Створено %@ - No comment provided by engineer. - - - Current passphrase… - Поточна парольна фраза… - No comment provided by engineer. - - - Currently maximum supported file size is %@. - Наразі максимальний підтримуваний розмір файлу - %@. - No comment provided by engineer. - - - Dark - Темний - No comment provided by engineer. - - - Database ID - Ідентифікатор бази даних - No comment provided by engineer. - - - Database encrypted! - База даних зашифрована! - No comment provided by engineer. - - - Database encryption passphrase will be updated and stored in the keychain. - - Парольна фраза шифрування бази даних буде оновлена та збережена у в’язці ключів. - - No comment provided by engineer. - - - Database encryption passphrase will be updated. - - Ключову фразу шифрування бази даних буде оновлено. - - No comment provided by engineer. - - - Database error - Помилка в базі даних - No comment provided by engineer. - - - Database is encrypted using a random passphrase, you can change it. - База даних зашифрована за допомогою випадкової парольної фрази, яку ви можете змінити. - No comment provided by engineer. - - - Database is encrypted using a random passphrase. Please change it before exporting. - База даних зашифрована за допомогою випадкової парольної фрази. Будь ласка, змініть його перед експортом. - No comment provided by engineer. - - - Database passphrase - Ключова фраза бази даних - No comment provided by engineer. - - - Database passphrase & export - Ключова фраза бази даних та експорт - No comment provided by engineer. - - - Database passphrase is different from saved in the keychain. - Парольна фраза бази даних відрізняється від збереженої у в’язці ключів. - No comment provided by engineer. - - - Database passphrase is required to open chat. - Для відкриття чату потрібно ввести пароль до бази даних. - No comment provided by engineer. - - - Database will be encrypted and the passphrase stored in the keychain. - - База даних буде зашифрована, а парольна фраза збережена у в’язці ключів. - - No comment provided by engineer. - - - Database will be encrypted. - - База даних буде зашифрована. - - No comment provided by engineer. - - - Database will be migrated when the app restarts - База даних буде перенесена під час перезапуску програми - No comment provided by engineer. - - - Decentralized - Децентралізований - No comment provided by engineer. - - - Delete - Видалити - chat item action - - - Delete Contact - Видалити контакт - No comment provided by engineer. - - - Delete address - Видалити адресу - No comment provided by engineer. - - - Delete address? - Видалити адресу? - No comment provided by engineer. - - - Delete after - Видалити після - No comment provided by engineer. - - - Delete all files - Видалити всі файли - No comment provided by engineer. - - - Delete archive - Видалити архів - No comment provided by engineer. - - - Delete chat archive? - Видалити архів чату? - No comment provided by engineer. - - - Delete chat profile? - Видалити профіль чату? - No comment provided by engineer. - - - Delete connection - Видалити підключення - No comment provided by engineer. - - - Delete contact - Видалити контакт - No comment provided by engineer. - - - Delete contact? - Видалити контакт? - No comment provided by engineer. - - - Delete database - Видалити базу даних - No comment provided by engineer. - - - Delete files and media? - Видаляти файли та медіа? - No comment provided by engineer. - - - Delete files for all chat profiles - Видалення файлів для всіх профілів чату - No comment provided by engineer. - - - Delete for everyone - Видалити для всіх - chat feature - - - Delete for me - Видалити для мене - No comment provided by engineer. - - - Delete group - Видалити групу - No comment provided by engineer. - - - Delete group? - Видалити групу? - No comment provided by engineer. - - - Delete invitation - Видалити запрошення - No comment provided by engineer. - - - Delete link - Видалити посилання - No comment provided by engineer. - - - Delete link? - Видалити посилання? - No comment provided by engineer. - - - Delete member message? - Видалити повідомлення учасника? - No comment provided by engineer. - - - Delete message? - Видалити повідомлення? - No comment provided by engineer. - - - Delete messages - Видалити повідомлення - No comment provided by engineer. - - - Delete messages after - Видаляйте повідомлення після - No comment provided by engineer. - - - Delete old database - Видалення старої бази даних - No comment provided by engineer. - - - Delete old database? - Видалити стару базу даних? - No comment provided by engineer. - - - Delete pending connection - Видалити очікуване з'єднання - No comment provided by engineer. - - - Delete pending connection? - Видалити очікуване з'єднання? - No comment provided by engineer. - - - Delete queue - Видалити чергу - server test step - - - Delete user profile? - Видалити профіль користувача? - No comment provided by engineer. - - - Description - Опис - No comment provided by engineer. - - - Develop - Розробник - No comment provided by engineer. - - - Developer tools - Інструменти для розробників - No comment provided by engineer. - - - Device - Пристрій - No comment provided by engineer. - - - Device authentication is disabled. Turning off SimpleX Lock. - Автентифікацію пристрою вимкнено. Вимкнення SimpleX Lock. - No comment provided by engineer. - - - Device authentication is not enabled. You can turn on SimpleX Lock via Settings, once you enable device authentication. - Автентифікація пристрою не ввімкнена. Ви можете увімкнути SimpleX Lock у Налаштуваннях, коли увімкнете автентифікацію пристрою. - No comment provided by engineer. - - - Different names, avatars and transport isolation. - Різні імена, аватарки та транспортна ізоляція. - No comment provided by engineer. - - - Direct messages - Прямі повідомлення - chat feature - - - Direct messages between members are prohibited in this group. - У цій групі заборонені прямі повідомлення між учасниками. - No comment provided by engineer. - - - Disable SimpleX Lock - Вимкнути SimpleX Lock - authentication reason - - - Disappearing messages - Зникаючі повідомлення - chat feature - - - Disappearing messages are prohibited in this chat. - Зникаючі повідомлення в цьому чаті заборонені. - No comment provided by engineer. - - - Disappearing messages are prohibited in this group. - У цій групі заборонено зникаючі повідомлення. - No comment provided by engineer. - - - Disconnect - Від'єднати - server test step - - - Display name - Відображуване ім'я - No comment provided by engineer. - - - Display name: - Відображуване ім'я: - No comment provided by engineer. - - - Do NOT use SimpleX for emergency calls. - НЕ використовуйте SimpleX для екстрених викликів. - No comment provided by engineer. - - - Do it later - Зробіть це пізніше - No comment provided by engineer. - - - Duplicate display name! - Дублююче ім'я користувача! - No comment provided by engineer. - - - Edit - Редагувати - chat item action - - - Edit group profile - Редагування профілю групи - No comment provided by engineer. - - - Enable - Увімкнути - No comment provided by engineer. - - - Enable SimpleX Lock - Увімкнути SimpleX Lock - authentication reason - - - Enable TCP keep-alive - Увімкнути TCP keep-alive - No comment provided by engineer. - - - Enable automatic message deletion? - Увімкнути автоматичне видалення повідомлень? - No comment provided by engineer. - - - Enable instant notifications? - Увімкнути миттєві сповіщення? - No comment provided by engineer. - - - Enable notifications - Увімкнути сповіщення - No comment provided by engineer. - - - Enable periodic notifications? - Увімкнути періодичні сповіщення? - No comment provided by engineer. - - - Encrypt - Зашифрувати - No comment provided by engineer. - - - Encrypt database? - Зашифрувати базу даних? - No comment provided by engineer. - - - Encrypted database - Зашифрована база даних - No comment provided by engineer. - - - Encrypted message or another event - Зашифроване повідомлення або інша подія - notification - - - Encrypted message: database error - Зашифроване повідомлення: помилка бази даних - notification - - - Encrypted message: keychain error - Зашифроване повідомлення: помилка ланцюжка ключів - notification - - - Encrypted message: no passphrase - Зашифроване повідомлення: без ключової фрази - notification - - - Encrypted message: unexpected error - Зашифроване повідомлення: несподівана помилка - notification - - - Enter correct passphrase. - Введіть правильну парольну фразу. - No comment provided by engineer. - - - Enter passphrase… - Введіть пароль… - No comment provided by engineer. - - - Enter server manually - Увійдіть на сервер вручну - No comment provided by engineer. - - - Error - Помилка - No comment provided by engineer. - - - Error accepting contact request - Помилка при прийнятті запиту на контакт - No comment provided by engineer. - - - Error accessing database file - Помилка доступу до файлу бази даних - No comment provided by engineer. - - - Error adding member(s) - Помилка додавання користувача(ів) - No comment provided by engineer. - - - Error changing address - Помилка зміни адреси - No comment provided by engineer. - - - Error changing role - Помилка зміни ролі - No comment provided by engineer. - - - Error changing setting - Помилка зміни налаштування - No comment provided by engineer. - - - Error creating address - Помилка створення адреси - No comment provided by engineer. - - - Error creating group - Помилка створення групи - No comment provided by engineer. - - - Error creating group link - Помилка створення посилання на групу - No comment provided by engineer. - - - Error creating profile! - Помилка створення профілю! - No comment provided by engineer. - - - Error deleting chat database - Помилка видалення бази даних чату - No comment provided by engineer. - - - Error deleting chat! - Помилка видалення чату! - No comment provided by engineer. - - - Error deleting connection - Помилка видалення з'єднання - No comment provided by engineer. - - - Error deleting contact - Помилка видалення контакту - No comment provided by engineer. - - - Error deleting database - Помилка видалення бази даних - No comment provided by engineer. - - - Error deleting old database - Помилка видалення старої бази даних - No comment provided by engineer. - - - Error deleting token - Помилка видалення токена - No comment provided by engineer. - - - Error deleting user profile - Помилка видалення профілю користувача - No comment provided by engineer. - - - Error enabling notifications - Помилка увімкнення сповіщень - No comment provided by engineer. - - - Error encrypting database - Помилка шифрування бази даних - No comment provided by engineer. - - - Error exporting chat database - Помилка експорту бази даних чату - No comment provided by engineer. - - - Error importing chat database - Помилка імпорту бази даних чату - No comment provided by engineer. - - - Error joining group - Помилка приєднання до групи - No comment provided by engineer. - - - Error receiving file - Помилка отримання файлу - No comment provided by engineer. - - - Error removing member - Помилка видалення учасника - No comment provided by engineer. - - - Error saving ICE servers - Помилка збереження серверів ICE - No comment provided by engineer. - - - Error saving SMP servers - No comment provided by engineer. - - - Error saving group profile - Помилка збереження профілю групи - No comment provided by engineer. - - - Error saving passphrase to keychain - Помилка збереження пароля на keychain - No comment provided by engineer. - - - Error sending message - Помилка надсилання повідомлення - No comment provided by engineer. - - - Error starting chat - Помилка запуску чату - No comment provided by engineer. - - - Error stopping chat - Помилка зупинки чату - No comment provided by engineer. - - - Error switching profile! - Помилка перемикання профілю! - No comment provided by engineer. - - - Error updating group link - Помилка оновлення посилання на групу - No comment provided by engineer. - - - Error updating message - Повідомлення про помилку оновлення - No comment provided by engineer. - - - Error updating settings - Помилка оновлення налаштувань - No comment provided by engineer. - - - Error: %@ - Помилка: %@ - No comment provided by engineer. - - - Error: URL is invalid - Помилка: URL-адреса невірна - No comment provided by engineer. - - - Error: no database file - Помилка: немає файлу бази даних - No comment provided by engineer. - - - Exit without saving - Вихід без збереження - No comment provided by engineer. - - - Export database - Експорт бази даних - No comment provided by engineer. - - - Export error: - Помилка експорту: - No comment provided by engineer. - - - Exported database archive. - Експортований архів бази даних. - No comment provided by engineer. - - - Exporting database archive... - Експорт архіву бази даних... - No comment provided by engineer. - - - Failed to remove passphrase - Не вдалося видалити парольну фразу - No comment provided by engineer. - - - File will be received when your contact is online, please wait or check later! - Файл буде отримано, коли ваш контакт буде онлайн, будь ласка, зачекайте або перевірте пізніше! - No comment provided by engineer. - - - File: %@ - Файл: %@ - No comment provided by engineer. - - - Files & media - Файли та медіа - No comment provided by engineer. - - - For console - Для консолі - No comment provided by engineer. - - - French interface - Французький інтерфейс - No comment provided by engineer. - - - Full link - Повне посилання - No comment provided by engineer. - - - Full name (optional) - Повне ім'я (необов'язково) - No comment provided by engineer. - - - Full name: - Повне ім'я: - No comment provided by engineer. - - - GIFs and stickers - GIF-файли та наклейки - No comment provided by engineer. - - - Group - Група - No comment provided by engineer. - - - Group display name - Назва групи для відображення - No comment provided by engineer. - - - Group full name (optional) - Повна назва групи (необов'язково) - No comment provided by engineer. - - - Group image - Зображення групи - No comment provided by engineer. - - - Group invitation - Групове запрошення - No comment provided by engineer. - - - Group invitation expired - Термін дії групового запрошення закінчився - No comment provided by engineer. - - - Group invitation is no longer valid, it was removed by sender. - Групове запрошення більше не дійсне, воно було видалено відправником. - No comment provided by engineer. - - - Group link - Посилання на групу - No comment provided by engineer. - - - Group links - Групові посилання - No comment provided by engineer. - - - Group members can irreversibly delete sent messages. - Учасники групи можуть безповоротно видаляти надіслані повідомлення. - No comment provided by engineer. - - - Group members can send direct messages. - Учасники групи можуть надсилати прямі повідомлення. - No comment provided by engineer. - - - Group members can send disappearing messages. - Учасники групи можуть надсилати зникаючі повідомлення. - No comment provided by engineer. - - - Group members can send voice messages. - Учасники групи можуть надсилати голосові повідомлення. - No comment provided by engineer. - - - Group message: - Групове повідомлення: - notification - - - Group preferences - Параметри груп - No comment provided by engineer. - - - Group profile - Профіль групи - No comment provided by engineer. - - - Group profile is stored on members' devices, not on the servers. - Профіль групи зберігається на пристроях учасників, а не на серверах. - No comment provided by engineer. - - - Group will be deleted for all members - this cannot be undone! - Група буде видалена для всіх учасників - це неможливо скасувати! - No comment provided by engineer. - - - Group will be deleted for you - this cannot be undone! - Група буде видалена для вас - це не може бути скасовано! - No comment provided by engineer. - - - Help - Довідка - No comment provided by engineer. - - - Hidden - Приховано - No comment provided by engineer. - - - Hide - Приховати - chat item action - - - Hide app screen in the recent apps. - Приховати екран програми в останніх програмах. - No comment provided by engineer. - - - How SimpleX works - Як працює SimpleX - No comment provided by engineer. - - - How it works - Як це працює - No comment provided by engineer. - - - How to - Як зробити - No comment provided by engineer. - - - How to use it - Як ним користуватися - No comment provided by engineer. - - - How to use your servers - Як користуватися вашими серверами - No comment provided by engineer. - - - ICE servers (one per line) - Сервери ICE (по одному на лінію) - No comment provided by engineer. - - - If you can't meet in person, **show QR code in the video call**, or share the link. - No comment provided by engineer. - - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Якщо ви не можете зустрітися особисто, ви можете **сканувати QR-код у відеодзвінку**, або ваш контакт може поділитися посиланням на запрошення. - No comment provided by engineer. - - - If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app). - Якщо вам потрібно скористатися чатом зараз, натисніть **Зробити це пізніше** нижче (вам буде запропоновано перенести базу даних при перезапуску програми). - No comment provided by engineer. - - - Ignore - Ігнорувати - No comment provided by engineer. - - - Image will be received when your contact is online, please wait or check later! - Зображення буде отримано, коли ваш контакт буде онлайн, будь ласка, зачекайте або перевірте пізніше! - No comment provided by engineer. - - - Immune to spam and abuse - Імунітет до спаму та зловживань - No comment provided by engineer. - - - Import - Імпорт - No comment provided by engineer. - - - Import chat database? - Імпортувати базу даних чату? - No comment provided by engineer. - - - Import database - Імпорт бази даних - No comment provided by engineer. - - - Improved privacy and security - Покращена конфіденційність та безпека - No comment provided by engineer. - - - Improved server configuration - Покращена конфігурація сервера - No comment provided by engineer. - - - Incognito - Інкогніто - No comment provided by engineer. - - - Incognito mode - Режим інкогніто - No comment provided by engineer. - - - Incognito mode is not supported here - your main profile will be sent to group members - Режим інкогніто тут не підтримується - ваш основний профіль буде надіслано учасникам групи - No comment provided by engineer. - - - Incognito mode protects the privacy of your main profile name and image — for each new contact a new random profile is created. - Режим інкогніто захищає конфіденційність імені та зображення вашого основного профілю - для кожного нового контакту створюється новий випадковий профіль. - No comment provided by engineer. - - - Incoming audio call - Вхідний аудіовиклик - notification - - - Incoming call - Вхідний дзвінок - notification - - - Incoming video call - Вхідний відеодзвінок - notification - - - Incorrect security code! - Неправильний код безпеки! - No comment provided by engineer. - - - Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat) - Встановіть [SimpleX Chat для терміналу](https://github.com/simplex-chat/simplex-chat) - No comment provided by engineer. - - - Instant push notifications will be hidden! - - Миттєві пуш-сповіщення будуть приховані! - - No comment provided by engineer. - - - Instantly - Миттєво - No comment provided by engineer. - - - Interface - Інтерфейс - No comment provided by engineer. - - - Invalid connection link - Неправильне посилання для підключення - No comment provided by engineer. - - - Invalid server address! - Неправильна адреса сервера! - No comment provided by engineer. - - - Invitation expired! - Термін дії запрошення закінчився! - No comment provided by engineer. - - - Invite members - Запросити учасників - No comment provided by engineer. - - - Invite to group - Запросити до групи - No comment provided by engineer. - - - Irreversible message deletion - Безповоротне видалення повідомлення - No comment provided by engineer. - - - Irreversible message deletion is prohibited in this chat. - У цьому чаті заборонено безповоротне видалення повідомлень. - No comment provided by engineer. - - - Irreversible message deletion is prohibited in this group. - У цій групі заборонено безповоротне видалення повідомлень. - No comment provided by engineer. - - - It allows having many anonymous connections without any shared data between them in a single chat profile. - Це дозволяє мати багато анонімних з'єднань без будь-яких спільних даних між ними в одному профілі чату. - No comment provided by engineer. - - - It can happen when: -1. The messages expire on the server if they were not received for 30 days, -2. The server you use to receive the messages from this contact was updated and restarted. -3. The connection is compromised. -Please connect to the developers via Settings to receive the updates about the servers. -We will be adding server redundancy to prevent lost messages. - 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 (%@). - Схоже, що ви вже підключені за цим посиланням. Якщо це не так, сталася помилка (%@). - No comment provided by engineer. - - - Italian interface - Італійський інтерфейс - No comment provided by engineer. - - - Join - Приєднуйтесь - No comment provided by engineer. - - - Join group - Приєднуйтесь до групи - No comment provided by engineer. - - - Join incognito - Приєднуйтесь інкогніто - No comment provided by engineer. - - - Joining group - Приєднання до групи - No comment provided by engineer. - - - Keychain error - помилка KeyChain - No comment provided by engineer. - - - LIVE - НАЖИВО - No comment provided by engineer. - - - Large file! - Великий файл! - No comment provided by engineer. - - - Leave - Залишити - No comment provided by engineer. - - - Leave group - Покинути групу - No comment provided by engineer. - - - Leave group? - Покинути групу? - No comment provided by engineer. - - - Light - Світлий - No comment provided by engineer. - - - Limitations - Обмеження - No comment provided by engineer. - - - Live message! - Живе повідомлення! - No comment provided by engineer. - - - Live messages - Живі повідомлення - No comment provided by engineer. - - - Local name - Місцева назва - No comment provided by engineer. - - - Local profile data only - Тільки локальні дані профілю - No comment provided by engineer. - - - Make a private connection - Створіть приватне з'єднання - No comment provided by engineer. - - - Make sure SMP server addresses are in correct format, line separated and are not duplicated (%@). - No comment provided by engineer. - - - Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated. - Переконайтеся, що адреси серверів WebRTC ICE мають правильний формат, розділені рядками і не дублюються. - No comment provided by engineer. - - - Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?* - Багато людей запитували: *якщо SimpleX не має ідентифікаторів користувачів, як він може доставляти повідомлення?* - No comment provided by engineer. - - - Mark deleted for everyone - Позначити видалено для всіх - No comment provided by engineer. - - - Mark read - Позначити прочитано - No comment provided by engineer. - - - Mark verified - Позначити перевірено - No comment provided by engineer. - - - Markdown in messages - Виправлення в повідомленнях - No comment provided by engineer. - - - Max 30 seconds, received instantly. - Максимум 30 секунд, отримується миттєво. - No comment provided by engineer. - - - Member - Учасник - No comment provided by engineer. - - - Member role will be changed to "%@". All group members will be notified. - Роль учасника буде змінено на "%@". Всі учасники групи будуть повідомлені про це. - No comment provided by engineer. - - - Member role will be changed to "%@". The member will receive a new invitation. - Роль учасника буде змінено на "%@". Учасник отримає нове запрошення. - No comment provided by engineer. - - - Member will be removed from group - this cannot be undone! - Учасник буде видалений з групи - це неможливо скасувати! - No comment provided by engineer. - - - Message delivery error - Помилка доставки повідомлення - No comment provided by engineer. - - - Message draft - Чернетка повідомлення - No comment provided by engineer. - - - Message text - Текст повідомлення - No comment provided by engineer. - - - Messages - Повідомлення - No comment provided by engineer. - - - Migrating database archive... - Перенесення архіву бази даних... - No comment provided by engineer. - - - Migration error: - Помилка міграції: - No comment provided by engineer. - - - Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat). - Міграція не вдалася. Натисніть **Пропустити** нижче, щоб продовжити використовувати поточну базу даних. Будь ласка, повідомте про проблему розробникам програми через чат або електронну пошту [chat@simplex.chat](mailto:chat@simplex.chat). - No comment provided by engineer. - - - Migration is completed - Міграцію завершено - No comment provided by engineer. - - - Moderate - Модерується - chat item action - - - More improvements are coming soon! - Незабаром буде ще більше покращень! - No comment provided by engineer. - - - Most likely this contact has deleted the connection with you. - Швидше за все, цей контакт видалив зв'язок з вами. - No comment provided by engineer. - - - Multiple chat profiles - Кілька профілів чату - No comment provided by engineer. - - - Mute - Вимкнути звук - No comment provided by engineer. - - - Name - Ім'я - No comment provided by engineer. - - - Network & servers - Мережа та сервери - No comment provided by engineer. - - - Network settings - Налаштування мережі - No comment provided by engineer. - - - Network status - Стан мережі - No comment provided by engineer. - - - New contact request - Новий запит на контакт - notification - - - New contact: - Новий контакт: - notification - - - New database archive - Новий архів бази даних - No comment provided by engineer. - - - New in %@ - Нове в %@ - No comment provided by engineer. - - - New member role - Нова роль учасника - No comment provided by engineer. - - - New message - Нове повідомлення - notification - - - New passphrase… - Новий пароль… - No comment provided by engineer. - - - No - Ні - No comment provided by engineer. - - - No contacts selected - Не вибрано жодного контакту - No comment provided by engineer. - - - No contacts to add - Немає контактів для додавання - No comment provided by engineer. - - - No device token! - Токен пристрою відсутній! - No comment provided by engineer. - - - Group not found! - Групу не знайдено! - No comment provided by engineer. - - - No permission to record voice message - Немає дозволу на запис голосового повідомлення - No comment provided by engineer. - - - No received or sent files - Немає отриманих або відправлених файлів - No comment provided by engineer. - - - Notifications - Сповіщення - No comment provided by engineer. - - - Notifications are disabled! - Сповіщення вимкнено! - No comment provided by engineer. - - - Off (Local) - Вимкнено (локально) - No comment provided by engineer. - - - Ok - Гаразд - No comment provided by engineer. - - - Old database - Стара база даних - No comment provided by engineer. - - - Old database archive - Старий архів бази даних - No comment provided by engineer. - - - One-time invitation link - Посилання на одноразове запрошення - No comment provided by engineer. - - - Onion hosts will be required for connection. Requires enabling VPN. - Для підключення будуть потрібні хости onion. Потрібно увімкнути VPN. - No comment provided by engineer. - - - Onion hosts will be used when available. Requires enabling VPN. - Onion хости будуть використовуватися, коли вони будуть доступні. Потрібно увімкнути VPN. - No comment provided by engineer. - - - Onion hosts will not be used. - Onion хости не будуть використовуватися. - No comment provided by engineer. - - - Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**. - Тільки клієнтські пристрої зберігають профілі користувачів, контакти, групи та повідомлення, надіслані за допомогою **2-шарового наскрізного шифрування**. - No comment provided by engineer. - - - Only group owners can change group preferences. - Тільки власники груп можуть змінювати налаштування групи. - No comment provided by engineer. - - - Only group owners can enable voice messages. - Тільки власники груп можуть вмикати голосові повідомлення. - No comment provided by engineer. - - - Only you can irreversibly delete messages (your contact can mark them for deletion). - Тільки ви можете безповоротно видалити повідомлення (ваш контакт може позначити їх для видалення). - No comment provided by engineer. - - - Only you can send disappearing messages. - Тільки ви можете надсилати зникаючі повідомлення. - No comment provided by engineer. - - - Only you can send voice messages. - Тільки ви можете надсилати голосові повідомлення. - No comment provided by engineer. - - - Only your contact can irreversibly delete messages (you can mark them for deletion). - Тільки ваш контакт може безповоротно видалити повідомлення (ви можете позначити їх для видалення). - No comment provided by engineer. - - - Only your contact can send disappearing messages. - Тільки ваш контакт може надсилати зникаючі повідомлення. - No comment provided by engineer. - - - Only your contact can send voice messages. - Тільки ваш контакт може надсилати голосові повідомлення. - No comment provided by engineer. - - - Open Settings - Відкрийте Налаштування - No comment provided by engineer. - - - Open chat - Відкритий чат - No comment provided by engineer. - - - Open chat console - Відкрийте консоль чату - authentication reason - - - Open user profiles - Відкрити профілі користувачів - authentication reason - - - Open-source protocol and code – anybody can run the servers. - Протокол і код з відкритим вихідним кодом - будь-хто може запускати сервери. - No comment provided by engineer. - - - Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. - Відкриття посилання в браузері може знизити конфіденційність і безпеку з'єднання. Ненадійні посилання SimpleX будуть червоного кольору. - No comment provided by engineer. - - - PING count - Кількість PING - No comment provided by engineer. - - - PING interval - Інтервал PING - No comment provided by engineer. - - - Paste - Вставити - No comment provided by engineer. - - - Paste image - Вставити зображення - No comment provided by engineer. - - - Paste received link - Вставте отримане посилання - No comment provided by engineer. - - - Paste the link you received into the box below to connect with your contact. - Вставте отримане посилання у поле нижче, щоб зв'язатися з вашим контактом. - No comment provided by engineer. - - - People can connect to you only via the links you share. - Люди можуть зв'язатися з вами лише за посиланнями, якими ви ділитеся. - No comment provided by engineer. - - - Periodically - Періодично - No comment provided by engineer. - - - Please ask your contact to enable sending voice messages. - Будь ласка, попросіть вашого контакту увімкнути відправку голосових повідомлень. - No comment provided by engineer. - - - Please check that you used the correct link or ask your contact to send you another one. - Будь ласка, перевірте, чи ви скористалися правильним посиланням, або попросіть контактну особу надіслати вам інше. - No comment provided by engineer. - - - Please check your network connection with %@ and try again. - Будь ласка, перевірте підключення до мережі за допомогою %@ і спробуйте ще раз. - No comment provided by engineer. - - - Please check yours and your contact preferences. - Будь ласка, перевірте свої та контактні налаштування. - No comment provided by engineer. - - - Please contact group admin. - Зверніться до адміністратора групи. - No comment provided by engineer. - - - Please enter correct current passphrase. - Будь ласка, введіть правильний поточний пароль. - No comment provided by engineer. - - - Please enter the previous password after restoring database backup. This action can not be undone. - Будь ласка, введіть попередній пароль після відновлення резервної копії бази даних. Ця дія не може бути скасована. - No comment provided by engineer. - - - Please restart the app and migrate the database to enable push notifications. - Будь ласка, перезапустіть додаток і перенесіть базу даних, щоб увімкнути push-сповіщення. - No comment provided by engineer. - - - Please store passphrase securely, you will NOT be able to access chat if you lose it. - Будь ласка, зберігайте пароль надійно, ви НЕ зможете отримати доступ до чату, якщо втратите його. - No comment provided by engineer. - - - Please store passphrase securely, you will NOT be able to change it if you lose it. - Будь ласка, зберігайте пароль надійно, ви НЕ зможете змінити його, якщо втратите. - No comment provided by engineer. - - - Possibly, certificate fingerprint in server address is incorrect - Можливо, в адресі сервера неправильно вказано відбиток сертифіката - server test error - - - Preserve the last message draft, with attachments. - Зберегти чернетку останнього повідомлення з вкладеннями. - No comment provided by engineer. - - - Preset server - Попередньо встановлений сервер - No comment provided by engineer. - - - Preset server address - Попередньо встановлена адреса сервера - No comment provided by engineer. - - - Privacy & security - Конфіденційність і безпека - No comment provided by engineer. - - - Privacy redefined - Конфіденційність переглянута - No comment provided by engineer. - - - Private filenames - Приватні імена файлів - No comment provided by engineer. - - - Profile and server connections - З'єднання профілю та сервера - No comment provided by engineer. - - - Profile image - Зображення профілю - No comment provided by engineer. - - - Prohibit irreversible message deletion. - Заборонити незворотне видалення повідомлень. - No comment provided by engineer. - - - Prohibit sending direct messages to members. - Заборонити надсилати прямі повідомлення учасникам. - No comment provided by engineer. - - - Prohibit sending disappearing messages. - Заборонити надсилання зникаючих повідомлень. - No comment provided by engineer. - - - Prohibit sending voice messages. - Заборонити надсилання голосових повідомлень. - No comment provided by engineer. - - - Protect app screen - Захистіть екран програми - No comment provided by engineer. - - - Protocol timeout - Тайм-аут протоколу - No comment provided by engineer. - - - Push notifications - Push-повідомлення - No comment provided by engineer. - - - Rate the app - Оцініть додаток - No comment provided by engineer. - - - Read - Читати - No comment provided by engineer. - - - Read more in our GitHub repository. - Читайте більше в нашому репозиторії на GitHub. - No comment provided by engineer. - - - Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme). - Читайте більше в нашому [GitHub репозиторії](https://github.com/simplex-chat/simplex-chat#readme). - No comment provided by engineer. - - - Received file event - Подія отримання файлу - notification - - - Receiving via - Отримання через - No comment provided by engineer. - - - Recipients see updates as you type them. - Одержувачі бачать оновлення, коли ви їх вводите. - No comment provided by engineer. - - - Reduced battery usage - Зменшення використання акумулятора - No comment provided by engineer. - - - Reject - Відхилити - reject incoming call via notification - - - Reject contact (sender NOT notified) - Відхилити контакт (відправника НЕ повідомлено) - No comment provided by engineer. - - - Reject contact request - Відхилити запит на контакт - No comment provided by engineer. - - - Relay server is only used if necessary. Another party can observe your IP address. - Релейний сервер використовується тільки в разі потреби. Інша сторона може бачити вашу IP-адресу. - No comment provided by engineer. - - - Relay server protects your IP address, but it can observe the duration of the call. - Сервер ретрансляції захищає вашу IP-адресу, але він може спостерігати за тривалістю дзвінка. - No comment provided by engineer. - - - Remove - Видалити - No comment provided by engineer. - - - Remove member - Видалити учасника - No comment provided by engineer. - - - Remove member? - Видалити учасника? - No comment provided by engineer. - - - Remove passphrase from keychain? - Видалити парольну фразу з брелока? - No comment provided by engineer. - - - Reply - Відповісти - chat item action - - - Required - Потрібно - No comment provided by engineer. - - - Reset - Перезавантаження - No comment provided by engineer. - - - Reset colors - Скинути кольори - No comment provided by engineer. - - - Reset to defaults - Відновити налаштування за замовчуванням - No comment provided by engineer. - - - Restart the app to create a new chat profile - Перезапустіть програму, щоб створити новий профіль чату - No comment provided by engineer. - - - Restart the app to use imported chat database - Перезапустіть програму, щоб використовувати імпортовану базу даних чату - No comment provided by engineer. - - - Restore - Відновити - No comment provided by engineer. - - - Restore database backup - Відновлення резервної копії бази даних - No comment provided by engineer. - - - Restore database backup? - Відновити резервну копію бази даних? - No comment provided by engineer. - - - Restore database error - Відновлення помилки бази даних - No comment provided by engineer. - - - Reveal - Показувати - chat item action - - - Revert - Повернутися - No comment provided by engineer. - - - Role - Роль - No comment provided by engineer. - - - Run chat - Запустити чат - No comment provided by engineer. - - - SMP servers - Сервери SMP - No comment provided by engineer. - - - Save - Зберегти - chat item action - - - Save (and notify contacts) - Зберегти (і повідомити контактам) - No comment provided by engineer. - - - Save and notify contact - Зберегти та повідомити контакт - No comment provided by engineer. - - - Save and notify group members - Зберегти та повідомити учасників групи - No comment provided by engineer. - - - Save archive - Зберегти архів - No comment provided by engineer. - - - Save group profile - Зберегти профіль групи - No comment provided by engineer. - - - Save passphrase and open chat - Збережіть пароль і відкрийте чат - No comment provided by engineer. - - - Save passphrase in Keychain - Збережіть парольну фразу в Keychain - No comment provided by engineer. - - - Save preferences? - Зберегти налаштування? - No comment provided by engineer. - - - Save servers - Зберегти сервери - No comment provided by engineer. - - - Saved WebRTC ICE servers will be removed - Збережені сервери WebRTC ICE буде видалено - No comment provided by engineer. - - - Scan QR code - Відскануйте QR-код - No comment provided by engineer. - - - Scan code - Сканувати код - No comment provided by engineer. - - - Scan security code from your contact's app. - Відскануйте код безпеки з додатку вашого контакту. - No comment provided by engineer. - - - Scan server QR code - Відскануйте QR-код сервера - No comment provided by engineer. - - - Search - Пошук - No comment provided by engineer. - - - Secure queue - Безпечна черга - server test step - - - Security assessment - Оцінка безпеки - No comment provided by engineer. - - - Security code - Код безпеки - No comment provided by engineer. - - - Send - Надіслати - No comment provided by engineer. - - - Send a live message - it will update for the recipient(s) as you type it - Надішліть повідомлення в реальному часі - воно буде оновлюватися для одержувача (одержувачів), поки ви його вводите - No comment provided by engineer. - - - Send direct message - Надішліть пряме повідомлення - No comment provided by engineer. - - - Send link previews - Надіслати попередній перегляд за посиланням - No comment provided by engineer. - - - Send live message - Надіслати живе повідомлення - No comment provided by engineer. - - - Send notifications - Надсилати сповіщення - No comment provided by engineer. - - - Send notifications: - Надсилати сповіщення: - No comment provided by engineer. - - - Send questions and ideas - Надсилайте запитання та ідеї - No comment provided by engineer. - - - Send them from gallery or custom keyboards. - Надсилайте їх із галереї чи власних клавіатур. - No comment provided by engineer. - - - Sender cancelled file transfer. - Відправник скасував передачу файлу. - No comment provided by engineer. - - - Sender may have deleted the connection request. - Можливо, відправник видалив запит на підключення. - No comment provided by engineer. - - - Sending via - Надсилання через - No comment provided by engineer. - - - Sent file event - Подія надісланого файлу - notification - - - Sent messages will be deleted after set time. - Надіслані повідомлення будуть видалені через встановлений час. - No comment provided by engineer. - - - Server requires authorization to create queues, check password - Сервер вимагає авторизації для створення черг, перевірте пароль - server test error - - - Server test failed! - Тест сервера завершився невдало! - No comment provided by engineer. - - - Servers - Сервери - No comment provided by engineer. - - - Set 1 day - Встановити 1 день - No comment provided by engineer. - - - Set contact name… - Встановити ім'я контакту… - No comment provided by engineer. - - - Set group preferences - Встановіть налаштування групи - No comment provided by engineer. - - - Set passphrase to export - Встановити ключову фразу для експорту - No comment provided by engineer. - - - Set timeouts for proxy/VPN - Встановлення таймаутів для проксі/VPN - No comment provided by engineer. - - - Settings - Налаштування - No comment provided by engineer. - - - Share - Поділіться - chat item action - - - Share invitation link - No comment provided by engineer. - - - Share link - Поділіться посиланням - No comment provided by engineer. - - - Share one-time invitation link - Поділіться посиланням на одноразове запрошення - No comment provided by engineer. - - - Show QR code - No comment provided by engineer. - - - Show calls in phone history - Показувати дзвінки в історії дзвінків - No comment provided by engineer. - - - Show preview - Показати попередній перегляд - No comment provided by engineer. - - - SimpleX Chat security was audited by Trail of Bits. - Безпека SimpleX Chat була перевірена компанією Trail of Bits. - No comment provided by engineer. - - - SimpleX Lock - SimpleX Lock - No comment provided by engineer. - - - SimpleX Lock turned on - SimpleX Lock увімкнено - No comment provided by engineer. - - - SimpleX contact address - Контактна адреса SimpleX - simplex link type - - - SimpleX encrypted message or connection event - Зашифроване повідомлення SimpleX або подія підключення - notification - - - SimpleX group link - Посилання на групу SimpleX - simplex link type - - - SimpleX links - Посилання SimpleX - No comment provided by engineer. - - - SimpleX one-time invitation - Одноразове запрошення SimpleX - simplex link type - - - Skip - Пропустити - No comment provided by engineer. - - - Skipped messages - Пропущені повідомлення - No comment provided by engineer. - - - Somebody - Хтось - notification title - - - Start a new chat - Почніть новий чат - No comment provided by engineer. - - - Start chat - Почати чат - No comment provided by engineer. - - - Start migration - Почати міграцію - No comment provided by engineer. - - - Stop - Зупинити - No comment provided by engineer. - - - Stop SimpleX - Зупинити SimpleX - authentication reason - - - Stop chat to enable database actions - Зупиніть чат, щоб увімкнути дії з базою даних - No comment provided by engineer. - - - Stop chat to export, import or delete chat database. You will not be able to receive and send messages while the chat is stopped. - Зупиніть чат, щоб експортувати, імпортувати або видалити базу даних чату. Ви не зможете отримувати та надсилати повідомлення, поки чат зупинено. - No comment provided by engineer. - - - Stop chat? - Зупинити чат? - No comment provided by engineer. - - - Support SimpleX Chat - Підтримка чату SimpleX - No comment provided by engineer. - - - System - Система - No comment provided by engineer. - - - TCP connection timeout - Тайм-аут TCP-з'єднання - No comment provided by engineer. - - - TCP_KEEPCNT - TCP_KEEPCNT - No comment provided by engineer. - - - TCP_KEEPIDLE - TCP_KEEPIDLE - No comment provided by engineer. - - - TCP_KEEPINTVL - TCP_KEEPINTVL - No comment provided by engineer. - - - Take picture - Сфотографуйте - No comment provided by engineer. - - - Tap button - Натисніть кнопку - No comment provided by engineer. - - - Tap to join - Натисніть, щоб приєднатися - No comment provided by engineer. - - - Tap to join incognito - Натисніть, щоб приєднатися інкогніто - No comment provided by engineer. - - - Tap to start a new chat - Натисніть, щоб почати новий чат - No comment provided by engineer. - - - Test failed at step %@. - Тест завершився невдало на кроці %@. - server test failure - - - Test server - Тестовий сервер - No comment provided by engineer. - - - Test servers - Тестові сервери - No comment provided by engineer. - - - Tests failed! - Тести не пройшли! - No comment provided by engineer. - - - Thank you for installing SimpleX Chat! - Дякуємо, що встановили SimpleX Chat! - No comment provided by engineer. - - - Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! - Дякуємо користувачам - [внесок через Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! - No comment provided by engineer. - - - Thanks to the users – contribute via Weblate! - Дякуємо користувачам - зробіть свій внесок через Weblate! - No comment provided by engineer. - - - The 1st platform without any user identifiers – private by design. - Перша платформа без жодних ідентифікаторів користувачів – приватна за дизайном. - No comment provided by engineer. - - - The app can notify you when you receive messages or contact requests - please open settings to enable. - Додаток може сповіщати вас, коли ви отримуєте повідомлення або запити на контакт - будь ласка, відкрийте налаштування, щоб увімкнути цю функцію. - No comment provided by engineer. - - - The attempt to change database passphrase was not completed. - Спроба змінити пароль до бази даних не була завершена. - No comment provided by engineer. - - - The connection you accepted will be cancelled! - Прийняте вами з'єднання буде скасовано! - No comment provided by engineer. - - - The contact you shared this link with will NOT be able to connect! - Контакт, з яким ви поділилися цим посиланням, НЕ зможе підключитися! - No comment provided by engineer. - - - The created archive is available via app Settings / Database / Old database archive. - Створений архів доступний через Налаштування програми / База даних / Старий архів бази даних. - No comment provided by engineer. - - - The group is fully decentralized – it is visible only to the members. - Група повністю децентралізована - її бачать лише учасники. - No comment provided by engineer. - - - The message will be deleted for all members. - Повідомлення буде видалено для всіх учасників. - No comment provided by engineer. - - - The message will be marked as moderated for all members. - Повідомлення буде позначено як модероване для всіх учасників. - No comment provided by engineer. - - - The next generation of private messaging - Наступне покоління приватних повідомлень - No comment provided by engineer. - - - The old database was not removed during the migration, it can be deleted. - Стара база даних не була видалена під час міграції, її можна видалити. - No comment provided by engineer. - - - The profile is only shared with your contacts. - Профіль доступний лише вашим контактам. - No comment provided by engineer. - - - The sender will NOT be notified - Відправник НЕ буде повідомлений - No comment provided by engineer. - - - The servers for new connections of your current chat profile **%@**. - Сервери для нових підключень вашого поточного профілю чату **%@**. - No comment provided by engineer. - - - Theme - Тема - No comment provided by engineer. - - - This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain. - Цю дію неможливо скасувати - всі отримані та надіслані файли і медіа будуть видалені. Зображення з низькою роздільною здатністю залишаться. - No comment provided by engineer. - - - This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes. - Цю дію неможливо скасувати - повідомлення, надіслані та отримані раніше, ніж вибрані, будуть видалені. Це може зайняти кілька хвилин. - No comment provided by engineer. - - - This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost. - Цю дію неможливо скасувати - ваш профіль, контакти, повідомлення та файли будуть безповоротно втрачені. - No comment provided by engineer. - - - This feature is experimental! It will only work if the other client has version 4.2 installed. You should see the message in the conversation once the address change is completed – please check that you can still receive messages from this contact (or group member). - No comment provided by engineer. - - - This group no longer exists. - Цієї групи більше не існує. - No comment provided by engineer. - - - This setting applies to messages in your current chat profile **%@**. - Це налаштування застосовується до повідомлень у вашому поточному профілі чату **%@**. - No comment provided by engineer. - - - To ask any questions and to receive updates: - Задати будь-які питання та отримувати новини: - No comment provided by engineer. - - - To find the profile used for an incognito connection, tap the contact or group name on top of the chat. - Щоб знайти профіль, який використовується для з'єднання інкогніто, торкніться імені контакту або групи у верхній частині чату. - No comment provided by engineer. - - - To make a new connection - Щоб створити нове з'єднання - No comment provided by engineer. - - - To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts. - Щоб захистити конфіденційність, замість ідентифікаторів користувачів, які використовуються на всіх інших платформах, SimpleX має ідентифікатори для черг повідомлень, окремі для кожного з ваших контактів. - No comment provided by engineer. - - - To protect timezone, image/voice files use UTC. - Для захисту часового поясу у файлах зображень/голосу використовується UTC. - No comment provided by engineer. - - - To protect your information, turn on SimpleX Lock. -You will be prompted to complete authentication before this feature is enabled. - Щоб захистити вашу інформацію, увімкніть SimpleX Lock. -Перед увімкненням цієї функції вам буде запропоновано пройти автентифікацію. - No comment provided by engineer. - - - To record voice message please grant permission to use Microphone. - Щоб записати голосове повідомлення, будь ласка, надайте дозвіл на використання мікрофону. - No comment provided by engineer. - - - To support instant push notifications the chat database has to be migrated. - Для підтримки миттєвих push-повідомлень необхідно перенести базу даних чату. - No comment provided by engineer. - - - To verify end-to-end encryption with your contact compare (or scan) the code on your devices. - Щоб перевірити наскрізне шифрування з вашим контактом, порівняйте (або відскануйте) код на ваших пристроях. - No comment provided by engineer. - - - Transport isolation - Транспортна ізоляція - No comment provided by engineer. - - - Trying to connect to the server used to receive messages from this contact (error: %@). - Спроба з'єднатися з сервером, який використовується для отримання повідомлень від цього контакту (помилка: %@). - No comment provided by engineer. - - - Trying to connect to the server used to receive messages from this contact. - Спроба з'єднатися з сервером, який використовується для отримання повідомлень від цього контакту. - No comment provided by engineer. - - - Turn off - Вимкнути - No comment provided by engineer. - - - Turn off notifications? - Вимкнути сповіщення? - No comment provided by engineer. - - - Turn on - Ввімкнути - No comment provided by engineer. - - - Unable to record voice message - Не вдається записати голосове повідомлення - No comment provided by engineer. - - - Unexpected error: %@ - Неочікувана помилка: %@ - No comment provided by engineer. - - - Unexpected migration state - Неочікуваний стан міграції - No comment provided by engineer. - - - Unknown caller - Невідомий абонент - callkit banner - - - Unknown database error: %@ - Невідома помилка бази даних: %@ - No comment provided by engineer. - - - Unknown error - Невідома помилка - No comment provided by engineer. - - - Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions. - Якщо ви не користуєтеся інтерфейсом виклику iOS, увімкніть режим "Не турбувати", щоб уникнути переривань. - No comment provided by engineer. - - - Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. -To connect, please ask your contact to create another connection link and check that you have a stable network connection. - Якщо ваш контакт не видалив з'єднання або якщо це посилання вже використовувалося, це може бути помилкою - будь ласка, повідомте про це. -Щоб підключитися, попросіть вашого контакта створити інше посилання і перевірте, чи маєте ви стабільне з'єднання з мережею. - No comment provided by engineer. - - - Unlock - Розблокувати - authentication reason - - - Unmute - Увімкнути звук - No comment provided by engineer. - - - Unread - Непрочитане - No comment provided by engineer. - - - Update - Оновлення - No comment provided by engineer. - - - Update .onion hosts setting? - Оновити налаштування хостів .onion? - No comment provided by engineer. - - - Update database passphrase - Оновити парольну фразу бази даних - No comment provided by engineer. - - - Update network settings? - Оновити налаштування мережі? - No comment provided by engineer. - - - Update transport isolation mode? - Оновити режим транспортної ізоляції? - No comment provided by engineer. - - - Updating settings will re-connect the client to all servers. - Оновлення налаштувань призведе до перепідключення клієнта до всіх серверів. - No comment provided by engineer. - - - Updating this setting will re-connect the client to all servers. - Оновлення цього параметра призведе до перепідключення клієнта до всіх серверів. - No comment provided by engineer. - - - Use .onion hosts - Використовуйте хости .onion - No comment provided by engineer. - - - Use SimpleX Chat servers? - Використовувати сервери SimpleX Chat? - No comment provided by engineer. - - - Use chat - Використовуйте чат - No comment provided by engineer. - - - Use for new connections - Використовуйте для нових з'єднань - No comment provided by engineer. - - - Use iOS call interface - Використовуйте інтерфейс виклику iOS - No comment provided by engineer. - - - Use server - Використовувати сервер - No comment provided by engineer. - - - User profile - Профіль користувача - No comment provided by engineer. - - - Using .onion hosts requires compatible VPN provider. - Для використання хостів .onion потрібен сумісний VPN-провайдер. - No comment provided by engineer. - - - Using SimpleX Chat servers. - Використання серверів SimpleX Chat. - No comment provided by engineer. - - - Verify connection security - Перевірте безпеку з'єднання - No comment provided by engineer. - - - Verify security code - Підтвердіть код безпеки - No comment provided by engineer. - - - Via browser - Через браузер - No comment provided by engineer. - - - Video call - Відеодзвінок - No comment provided by engineer. - - - View security code - Переглянути код безпеки - No comment provided by engineer. - - - Voice messages - Голосові повідомлення - chat feature - - - Voice messages are prohibited in this chat. - Голосові повідомлення в цьому чаті заборонені. - No comment provided by engineer. - - - Voice messages are prohibited in this group. - Голосові повідомлення в цій групі заборонені. - No comment provided by engineer. - - - Voice messages prohibited! - Голосові повідомлення заборонені! - No comment provided by engineer. - - - Voice message… - Голосове повідомлення… - No comment provided by engineer. - - - Waiting for file - Очікування файлу - No comment provided by engineer. - - - Waiting for image - Очікування зображення - No comment provided by engineer. - - - WebRTC ICE servers - Сервери WebRTC ICE - No comment provided by engineer. - - - Welcome %@! - Ласкаво просимо %@! - No comment provided by engineer. - - - Welcome message - Вітальне повідомлення - No comment provided by engineer. - - - What's new - Що нового - No comment provided by engineer. - - - When available - За наявності - No comment provided by engineer. - - - When you share an incognito profile with somebody, this profile will be used for the groups they invite you to. - Коли ви ділитеся з кимось своїм профілем інкогніто, цей профіль буде використовуватися для груп, до яких вас запрошують. - No comment provided by engineer. - - - With optional welcome message. - З необов'язковим вітальним повідомленням. - No comment provided by engineer. - - - Wrong database passphrase - Неправильний пароль до бази даних - No comment provided by engineer. - - - Wrong passphrase! - Неправильний пароль! - No comment provided by engineer. - - - You - Ти - No comment provided by engineer. - - - You accepted connection - Ви прийняли підключення - No comment provided by engineer. - - - You allow - Ви дозволяєте - No comment provided by engineer. - - - You already have a chat profile with the same display name. Please choose another name. - Ви вже маєте профіль у чаті з таким самим іменем. Будь ласка, виберіть інше ім'я. - No comment provided by engineer. - - - You are already connected to %@. - Ви вже підключені до %@. - No comment provided by engineer. - - - You are connected to the server used to receive messages from this contact. - Ви підключені до сервера, який використовується для отримання повідомлень від цього контакту. - No comment provided by engineer. - - - You are invited to group - Запрошуємо вас до групи - No comment provided by engineer. - - - You can accept calls from lock screen, without device and app authentication. - Ви можете приймати дзвінки з екрана блокування без автентифікації пристрою та програми. - No comment provided by engineer. - - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Ви також можете підключитися за посиланням. Якщо воно відкриється в браузері, натисніть кнопку **Відкрити в мобільному додатку**. - No comment provided by engineer. - - - You can now send messages to %@ - Тепер ви можете надсилати повідомлення на адресу %@ - notification body - - - You can set lock screen notification preview via settings. - Ви можете налаштувати попередній перегляд сповіщень на екрані блокування за допомогою налаштувань. - No comment provided by engineer. - - - You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. - Ви можете поділитися посиланням або QR-кодом - будь-хто зможе приєднатися до групи. Ви не втратите учасників групи, якщо згодом видалите її. - No comment provided by engineer. - - - You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it. - No comment provided by engineer. - - - You can start chat via app Settings / Database or by restarting the app - Запустити чат можна через Налаштування програми / База даних або перезапустивши програму - No comment provided by engineer. - - - You can use markdown to format messages: - Ви можете використовувати розмітку для форматування повідомлень: - No comment provided by engineer. - - - You can't send messages! - Ви не можете надсилати повідомлення! - No comment provided by engineer. - - - You control through which server(s) **to receive** the messages, your contacts – the servers you use to message them. - Ви контролюєте, через який(і) сервер(и) **отримувати** повідомлення, ваші контакти - сервери, які ви використовуєте для надсилання їм повідомлень. - No comment provided by engineer. - - - You could not be verified; please try again. - Вас не вдалося верифікувати, спробуйте ще раз. - No comment provided by engineer. - - - You have no chats - У вас немає чатів - No comment provided by engineer. - - - You have to enter passphrase every time the app starts - it is not stored on the device. - Вам доведеться вводити парольну фразу щоразу під час запуску програми - вона не зберігається на пристрої. - No comment provided by engineer. - - - You invited your contact - No comment provided by engineer. - - - You joined this group - Ви приєдналися до цієї групи - No comment provided by engineer. - - - You joined this group. Connecting to inviting group member. - Ви приєдналися до цієї групи. Підключення до запрошеного учасника групи. - 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. - Ви повинні використовувати найновішу версію бази даних чату ТІЛЬКИ на одному пристрої, інакше ви можете перестати отримувати повідомлення від деяких контактів. - No comment provided by engineer. - - - You need to allow your contact to send voice messages to be able to send them. - Щоб мати змогу надсилати голосові повідомлення, вам потрібно дозволити контакту надсилати їх. - No comment provided by engineer. - - - You rejected group invitation - Ви відхилили запрошення до групи - No comment provided by engineer. - - - You sent group invitation - Ви надіслали запрошення до групи - No comment provided by engineer. - - - You will be connected to group when the group host's device is online, please wait or check later! - Ви будете підключені до групи, коли пристрій господаря групи буде в мережі, будь ласка, зачекайте або перевірте пізніше! - No comment provided by engineer. - - - You will be connected when your connection request is accepted, please wait or check later! - Ви будете підключені, коли ваш запит на підключення буде прийнято, будь ласка, зачекайте або перевірте пізніше! - No comment provided by engineer. - - - You will be connected when your contact's device is online, please wait or check later! - Ви будете з'єднані, коли пристрій вашого контакту буде онлайн, будь ласка, зачекайте або перевірте пізніше! - No comment provided by engineer. - - - You will be required to authenticate when you start or resume the app after 30 seconds in background. - Вам потрібно буде пройти автентифікацію при запуску або відновленні програми після 30 секунд роботи у фоновому режимі. - No comment provided by engineer. - - - You will join a group this link refers to and connect to its group members. - Ви приєднаєтеся до групи, на яку посилається це посилання, і з'єднаєтеся з її учасниками. - No comment provided by engineer. - - - You will stop receiving messages from this group. Chat history will be preserved. - Ви перестанете отримувати повідомлення від цієї групи. Історія чату буде збережена. - No comment provided by engineer. - - - You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile - Ви намагаєтеся запросити контакт, з яким ви поділилися профілем інкогніто, до групи, в якій ви використовуєте свій основний профіль - No comment provided by engineer. - - - You're using an incognito profile for this group - to prevent sharing your main profile inviting contacts is not allowed - Ви використовуєте профіль інкогніто для цієї групи - щоб запобігти поширенню вашого основного профілю, запрошення контактів заборонено - No comment provided by engineer. - - - Your ICE servers - Ваші сервери ICE - No comment provided by engineer. - - - Your SMP servers - Ваші SMP-сервери - No comment provided by engineer. - - - Your SimpleX contact address - No comment provided by engineer. - - - Your calls - Твої дзвінки - No comment provided by engineer. - - - Your chat database - Ваша база даних чату - No comment provided by engineer. - - - Your chat database is not encrypted - set passphrase to encrypt it. - Ваша база даних чату не зашифрована - встановіть ключову фразу, щоб зашифрувати її. - No comment provided by engineer. - - - Your chat profile will be sent to group members - Ваш профіль у чаті буде надіслано учасникам групи - No comment provided by engineer. - - - Your chat profile will be sent to your contact - No comment provided by engineer. - - - Your chat profiles - Ваші профілі чату - No comment provided by engineer. - - - Your chat profiles are stored locally, only on your device. - No comment provided by engineer. - - - Your chats - No comment provided by engineer. - - - Your contact address - No comment provided by engineer. - - - Your contact can scan it from the app. - No comment provided by engineer. - - - Your contact needs to be online for the connection to complete. -You can cancel this connection and remove the contact (and try later with a new link). - Для завершення з'єднання ваш контакт має бути онлайн. -Ви можете скасувати це з'єднання і видалити контакт (і спробувати пізніше з новим посиланням). - No comment provided by engineer. - - - Your contact sent a file that is larger than currently supported maximum size (%@). - Ваш контакт надіслав файл, розмір якого перевищує підтримуваний на цей момент максимальний розмір (%@). - No comment provided by engineer. - - - Your contacts can allow full message deletion. - Ваші контакти можуть дозволити повне видалення повідомлень. - No comment provided by engineer. - - - Your current chat database will be DELETED and REPLACED with the imported one. - Ваша поточна база даних чату буде ВИДАЛЕНА і ЗАМІНЕНА імпортованою. - No comment provided by engineer. - - - Your current profile - Ваш поточний профіль - No comment provided by engineer. - - - Your preferences - Ваші уподобання - No comment provided by engineer. - - - Your privacy - Ваша конфіденційність - No comment provided by engineer. - - - Your profile is stored on your device and shared only with your contacts. -SimpleX servers cannot see your profile. - Ваш профіль зберігається на вашому пристрої і доступний лише вашим контактам. -Сервери SimpleX не бачать ваш профіль. - No comment provided by engineer. - - - Your profile will be sent to the contact that you received this link from - No comment provided by engineer. - - - Your profile, contacts and delivered messages are stored on your device. - Ваш профіль, контакти та доставлені повідомлення зберігаються на вашому пристрої. - No comment provided by engineer. - - - Your random profile - Ваш випадковий профіль - No comment provided by engineer. - - - Your server - Ваш сервер - No comment provided by engineer. - - - Your server address - Адреса вашого сервера - No comment provided by engineer. - - - Your settings - Ваші налаштування - No comment provided by engineer. - - - [Contribute](https://github.com/simplex-chat/simplex-chat#contribute) - [Внесок](https://github.com/simplex-chat/simplex-chat#contribute) - No comment provided by engineer. - - - [Send us email](mailto:chat@simplex.chat) - [Напишіть нам електронною поштою](mailto:chat@simplex.chat) - No comment provided by engineer. - - - [Star on GitHub](https://github.com/simplex-chat/simplex-chat) - [Зірка на GitHub](https://github.com/simplex-chat/simplex-chat) - No comment provided by engineer. - - - \_italic_ - \_курсив_ - No comment provided by engineer. - - - \`a + b` - \`a + b` - No comment provided by engineer. - - - above, then choose: - вище, а потім обирайте: - No comment provided by engineer. - - - accepted call - прийнято виклик - call status - - - admin - адмін - member role - - - always - завжди - pref value - - - audio call (not e2e encrypted) - аудіовиклик (без шифрування e2e) - No comment provided by engineer. - - - bad message ID - невірний ідентифікатор повідомлення - integrity error chat item - - - bad message hash - невірний хеш повідомлення - integrity error chat item - - - bold - жирний - No comment provided by engineer. - - - call error - помилка дзвінка - call status - - - call in progress - виклик у процесі - call status - - - calling… - дзвоніть… - call status - - - cancelled %@ - скасовано %@ - feature offered item - - - changed address for you - змінили для вас адресу - chat item text - - - changed role of %1$@ to %2$@ - змінено роль %1$@ на %2$@ - rcv group event chat item - - - changed your role to %@ - змінили свою роль на %@ - rcv group event chat item - - - changing address for %@... - chat item text - - - changing address... - chat item text - - - colored - кольоровий - No comment provided by engineer. - - - complete - завершено - No comment provided by engineer. - - - connect to SimpleX Chat developers. - зв'язатися з розробниками SimpleX Chat. - No comment provided by engineer. - - - connected - з'єднаний - No comment provided by engineer. - - - connecting - з'єднання - No comment provided by engineer. - - - connecting (accepted) - з'єднання (прийнято) - No comment provided by engineer. - - - connecting (announced) - з'єднання (оголошено) - No comment provided by engineer. - - - connecting (introduced) - з'єднання (введено) - No comment provided by engineer. - - - connecting (introduction invitation) - з'єднання (вступне запрошення) - No comment provided by engineer. - - - connecting call… - підключення дзвінка… - call status - - - connecting… - з'єднання… - chat list item title - - - connection established - з'єднання встановлене - chat list item title (it should not be shown - - - connection:%@ - з'єднання:%@ - connection information - - - contact has e2e encryption - контакт має шифрування e2e - No comment provided by engineer. - - - contact has no e2e encryption - контакт не має шифрування e2e - No comment provided by engineer. - - - creator - творець - No comment provided by engineer. - - - default (%@) - за замовчуванням (%@) - pref value - - - deleted - видалено - deleted chat item - - - deleted group - видалено групу - rcv group event chat item - - - direct - прямо - connection level description - - - duplicate message - дублююче повідомлення - integrity error chat item - - - e2e encrypted - e2e зашифрований - No comment provided by engineer. - - - enabled - увімкнено - enabled status - - - enabled for contact - увімкнено для контакту - enabled status - - - enabled for you - увімкнено для вас - enabled status - - - ended - закінчився - No comment provided by engineer. - - - ended call %@ - закінчився виклик %@ - call status - - - error - помилка - No comment provided by engineer. - - - group deleted - групу видалено - No comment provided by engineer. - - - group profile updated - оновлено профіль групи - snd group event chat item - - - iOS Keychain is used to securely store passphrase - it allows receiving push notifications. - iOS Keychain використовується для безпечного зберігання пароля - це дає змогу отримувати миттєві повідомлення. - No comment provided by engineer. - - - iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications. - Пароль бази даних буде безпечно збережено в iOS Keychain після запуску чату або зміни пароля - це дасть змогу отримувати миттєві повідомлення. - No comment provided by engineer. - - - incognito via contact address link - інкогніто за посиланням на контактну адресу - chat list item description - - - incognito via group link - інкогніто через групове посилання - chat list item description - - - incognito via one-time link - інкогніто за одноразовим посиланням - chat list item description - - - indirect (%d) - непрямий (%d) - connection level description - - - invalid chat - недійсний чат - invalid chat data - - - invalid chat data - невірні дані чату - No comment provided by engineer. - - - invalid data - невірні дані - invalid chat item - - - invitation to group %@ - запрошення до групи %@ - group name - - - invited - запрошені - No comment provided by engineer. - - - invited %@ - запрошений %@ - rcv group event chat item - - - invited to connect - запрошуємо приєднатися - chat list item title - - - invited via your group link - запрошені за посиланням у вашій групі - rcv group event chat item - - - italic - курсив - No comment provided by engineer. - - - join as %@ - приєднатися як %@ - No comment provided by engineer. - - - left - ліворуч - rcv group event chat item - - - marked deleted - з позначкою видалено - marked deleted chat item preview text - - - member - учасник - member role - - - connected - з'єднаний - rcv group event chat item - - - message received - повідомлення отримано - notification - - - missed call - пропущений дзвінок - call status - - - moderated - модерується - moderated chat item - - - moderated by %@ - модерується %@ - No comment provided by engineer. - - - never - ніколи - No comment provided by engineer. - - - new message - нове повідомлення - notification - - - no - ні - pref value - - - no e2e encryption - без шифрування e2e - No comment provided by engineer. - - - observer - спостерігач - member role - - - off - вимкнено - enabled status - group pref value - - - offered %@ - запропоновано %@ - feature offered item - - - offered %1$@: %2$@ - запропонував %1$@: %2$@ - feature offered item - - - on - увімкнено - group pref value - - - or chat with the developers - або поспілкуйтеся з розробниками - No comment provided by engineer. - - - owner - власник - member role - - - peer-to-peer - одноранговий - No comment provided by engineer. - - - received answer… - отримали відповідь… - No comment provided by engineer. - - - received confirmation… - отримали підтвердження… - No comment provided by engineer. - - - rejected call - відхилений виклик - call status - - - removed - видалено - No comment provided by engineer. - - - removed %@ - видалено %@ - rcv group event chat item - - - removed you - прибрали вас - rcv group event chat item - - - sec - сек - network option - - - secret - таємниця - No comment provided by engineer. - - - starting… - починаючи… - No comment provided by engineer. - - - strike - закреслено - No comment provided by engineer. - - - this contact - цей контакт - notification title - - - unknown - невідомий - connection info - - - updated group profile - оновлений профіль групи - rcv group event chat item - - - v%@ (%@) - v%@ (%@) - No comment provided by engineer. - - - via contact address link - за посиланням на контактну адресу - chat list item description - - - via group link - за посиланням на групу - chat list item description - - - via one-time link - за одноразовим посиланням - chat list item description - - - via relay - за допомогою ретранслятора - No comment provided by engineer. - - - video call (not e2e encrypted) - відеодзвінок (без шифрування e2e) - No comment provided by engineer. - - - waiting for answer… - в очікуванні відповіді… - No comment provided by engineer. - - - waiting for confirmation… - чекаємо на підтвердження… - No comment provided by engineer. - - - wants to connect to you! - хоче зв'язатися з вами! - No comment provided by engineer. - - - yes - так - pref value - - - you are invited to group - вас запрошують до групи - No comment provided by engineer. - - - you are observer - ви спостерігач - No comment provided by engineer. - - - you changed address - ви змінили адресу - chat item text - - - you changed address for %@ - ви змінили адресу на %@ - chat item text - - - you changed role for yourself to %@ - ви змінили роль для себе на %@ - snd group event chat item - - - you changed role of %1$@ to %2$@ - ви змінили роль %1$@ на %2$@ - snd group event chat item - - - you left - ти пішов - snd group event chat item - - - you removed %@ - ви видалили %@ - snd group event chat item - - - you shared one-time link - ви поділилися одноразовим посиланням - chat list item description - - - you shared one-time link incognito - ви поділилися одноразовим посиланням інкогніто - chat list item description - - - you: - ти: - No comment provided by engineer. - - - \~strike~ - \~закреслити~ - No comment provided by engineer. - - - %@ servers - %@ сервери - No comment provided by engineer. - - - %lld seconds - %lld секунд - No comment provided by engineer. - - - Audio and video calls - Аудіо та відеодзвінки - No comment provided by engineer. - - - Authentication cancelled - Аутентифікацію скасовано - PIN entry - - - Can't delete user profile! - Не можу видалити профіль користувача! - No comment provided by engineer. - - - Change lock mode - Зміна режиму блокування - authentication reason - - - Create file - Створити файл - server test step - - - Database upgrade - Оновлення бази даних - No comment provided by engineer. - - - Delete chat profile - Видалити профіль чату - No comment provided by engineer. - - - Delete file - Видалити файл - server test step - - - Change passcode - Змінити пароль - authentication reason - - - Allow message reactions. - Дозволити реакцію на повідомлення. - No comment provided by engineer. - - - App passcode is replaced with self-destruct passcode. - Пароль програми замінено на пароль самознищення. - No comment provided by engineer. - - - Both you and your contact can add message reactions. - Реакції на повідомлення можете додавати як ви, так і ваш контакт. - No comment provided by engineer. - - - Change self-destruct passcode - Змінити пароль самознищення - authentication reason - set passcode view - - - Chinese and Spanish interface - Інтерфейс китайською та іспанською мовами - No comment provided by engineer. - - - Compare file - Порівняти файл - server test step - - - Confirm Passcode - Підтвердити пароль - No comment provided by engineer. - - - Confirm password - Підтвердити пароль - No comment provided by engineer. - - - Confirm database upgrades - Підтвердити оновлення бази даних - No comment provided by engineer. - - - Database downgrade - Пониження версії бази даних - No comment provided by engineer. - - - Current Passcode - Поточний пароль - No comment provided by engineer. - - - Database IDs and Transport isolation option. - Ідентифікатори бази даних та опція ізоляції транспорту. - No comment provided by engineer. - - - 5 minutes - 5 хвилин - No comment provided by engineer. - - - 30 seconds - 30 секунд - No comment provided by engineer. - - - Allow your contacts adding message reactions. - Дозвольте вашим контактам додавати реакції на повідомлення. - No comment provided by engineer. - - - Change self-destruct mode - Змінити режим самознищення - authentication reason - - + %@ (current) - %@ (поточний) + %@ (поточний) No comment provided by engineer. - + %@ (current): - %@ (поточний): + %@ (поточний): copied message info - + + %@ / %@ + %@ / %@ + No comment provided by engineer. + + + %@ and %@ connected + %@ і %@ підключено + No comment provided by engineer. + + + %1$@ at %2$@: + %1$@ за %2$@: + copied message info, <sender> at <time> + + + %@ is connected! + %@ підключено! + notification title + + + %@ is not verified + %@ не перевірено + No comment provided by engineer. + + + %@ is verified + %@ перевірено + No comment provided by engineer. + + + %@ servers + %@ сервери + No comment provided by engineer. + + + %@ wants to connect! + %@ хоче підключитися! + notification title + + + %@, %@ and %lld other members connected + %@, %@ та %lld інші підключені учасники + No comment provided by engineer. + + %@: - %@: + %@: copied message info - - %d weeks - %d тижнів + + %d days + %d днів time interval - + + %d hours + %d годин + time interval + + + %d min + %d хв + time interval + + + %d months + %d місяців + time interval + + + %d sec + %d сек + time interval + + + %d skipped message(s) + %d пропущено повідомлення(ь) + integrity error chat item + + + %d weeks + %d тижнів + time interval + + + %lld + %lld + No comment provided by engineer. + + + %lld %@ + %lld %@ + No comment provided by engineer. + + + %lld contact(s) selected + %lld контакт(и) вибрані + No comment provided by engineer. + + + %lld file(s) with total size of %@ + %lld файл(и) загальним розміром %@ + No comment provided by engineer. + + + %lld members + %lld учасників + No comment provided by engineer. + + + %lld minutes + %lld хвилин + No comment provided by engineer. + + + %lld new interface languages + No comment provided by engineer. + + + %lld second(s) + %lld секунд(и) + No comment provided by engineer. + + + %lld seconds + %lld секунд + No comment provided by engineer. + + + %lldd + %lldd + No comment provided by engineer. + + + %lldh + %lldh + No comment provided by engineer. + + + %lldk + %lldk + No comment provided by engineer. + + + %lldm + %lldm + No comment provided by engineer. + + + %lldmth + %lldmth + No comment provided by engineer. + + + %llds + %llds + No comment provided by engineer. + + + %lldw + %lldw + No comment provided by engineer. + + + %u messages failed to decrypt. + %u повідомлень не вдалося розшифрувати. + No comment provided by engineer. + + %u messages skipped. - %u повідомлень пропущено. + %u повідомлень пропущено. No comment provided by engineer. - - 0s - 0с + + ( + ( No comment provided by engineer. - - 1 minute - 1 хвилина + + ) + ) No comment provided by engineer. - - Allow message reactions only if your contact allows them. - Дозволяйте реакції на повідомлення, тільки якщо ваш контакт дозволяє їх. + + **Add new contact**: to create your one-time QR Code or link for your contact. + **Додати новий контакт**: щоб створити одноразовий QR-код або посилання для свого контакту. No comment provided by engineer. - - An empty chat profile with the provided name is created, and the app opens as usual. - Створюється порожній профіль чату з вказаним ім'ям, і додаток відкривається у звичайному режимі. + + **Create link / QR code** for your contact to use. + **Створіть посилання / QR-код** для використання вашим контактом. No comment provided by engineer. - - All your contacts will remain connected. - Всі ваші контакти залишаться на зв'язку. + + **More private**: check new messages every 20 minutes. Device token is shared with SimpleX Chat server, but not how many contacts or messages you have. + **Більш приватний**: перевіряти нові повідомлення кожні 20 хвилин. Серверу SimpleX Chat передається токен пристрою, але не кількість контактів або повідомлень, які ви маєте. No comment provided by engineer. - - Custom time - Індивідуальний час + + **Most private**: do not use SimpleX Chat notifications server, check messages periodically in the background (depends on how often you use the app). + **Найбільш приватний**: не використовуйте сервер сповіщень SimpleX Chat, періодично перевіряйте повідомлення у фоновому режимі (залежить від того, як часто ви користуєтесь додатком). No comment provided by engineer. - - Database ID: %d - Ідентифікатор бази даних: %d - copied message info - - - 1-time link - 1-разове посилання + + **Paste received link** or open it in the browser and tap **Open in mobile app**. + **Вставте отримане посилання** або відкрийте його в браузері і натисніть **Відкрити в мобільному додатку**. No comment provided by engineer. - - Address - Адреса + + **Please note**: you will NOT be able to recover or change passphrase if you lose it. + **Зверніть увагу: ви НЕ зможете відновити або змінити пароль, якщо втратите його. No comment provided by engineer. - - About SimpleX address - Про адресу SimpleX + + **Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from. + **Рекомендується**: токен пристрою та сповіщення надсилаються на сервер сповіщень SimpleX Chat, але не вміст повідомлення, його розмір або від кого воно надійшло. No comment provided by engineer. - - Allow calls only if your contact allows them. - Дозволяйте дзвінки, тільки якщо ваш контакт дозволяє їх. + + **Scan QR code**: to connect to your contact in person or via video call. + **Відскануйте QR-код**: щоб з'єднатися з вашим контактом особисто або за допомогою відеодзвінка. No comment provided by engineer. - - Allow your contacts to call you. - Дозвольте вашим контактам телефонувати вам. + + **Warning**: Instant push notifications require passphrase saved in Keychain. + **Попередження**: Для отримання миттєвих пуш-сповіщень потрібна парольна фраза, збережена у брелоку. No comment provided by engineer. - - App passcode - Пароль додатку + + **e2e encrypted** audio call + **e2e encrypted** аудіодзвінок No comment provided by engineer. - - Audio/video calls - Аудіо/відео дзвінки - chat feature - - - Auto-accept - Автоприйняття + + **e2e encrypted** video call + **e2e encrypted** відеодзвінок No comment provided by engineer. - - Audio/video calls are prohibited. - Аудіо/відео дзвінки заборонені. + + \*bold* + \*жирний* No comment provided by engineer. - - Bad message ID - Неправильний ідентифікатор повідомлення + + , + , No comment provided by engineer. - - Bad message hash - Поганий хеш повідомлення + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. No comment provided by engineer. - - Both you and your contact can make calls. - Дзвонити можете як ви, так і ваш контакт. + + - more stable message delivery. +- a bit better groups. +- and more! + - стабільніша доставка повідомлень. +- трохи кращі групи. +- і багато іншого! No comment provided by engineer. - - Create SimpleX address - Створіть адресу SimpleX - No comment provided by engineer. - - - Continue - Продовжуйте - No comment provided by engineer. - - - Create an address to let people connect with you. - Створіть адресу, щоб люди могли з вами зв'язатися. - No comment provided by engineer. - - - Decryption error - Помилка розшифровки - No comment provided by engineer. - - + - voice messages up to 5 minutes. - custom time to disappear. - editing history. - - голосові повідомлення до 5 хвилин. + - голосові повідомлення до 5 хвилин. - користувальницький час зникнення. - історія редагування. No comment provided by engineer. - - All data is erased when it is entered. - Всі дані стираються при введенні. + + . + . No comment provided by engineer. - - Better messages - Кращі повідомлення + + 0s + 0с No comment provided by engineer. - - %u messages failed to decrypt. - %u повідомлень не вдалося розшифрувати. + + 1 day + 1 день + time interval + + + 1 hour + 1 година + time interval + + + 1 minute + 1 хвилина No comment provided by engineer. - - %lld minutes - %lld хвилин + + 1 month + 1 місяць + time interval + + + 1 week + 1 тиждень + time interval + + + 1-time link + 1-разове посилання No comment provided by engineer. - + + 5 minutes + 5 хвилин + No comment provided by engineer. + + + 6 + 6 + No comment provided by engineer. + + + 30 seconds + 30 секунд + No comment provided by engineer. + + + : + : + No comment provided by engineer. + + <p>Hi!</p> <p><a href="%@">Connect to me via SimpleX Chat</a></p> - <p>Привіт!</p> + <p>Привіт!</p> <p><a href="%@"> Зв'яжіться зі мною через SimpleX Chat</a></p> email text - - Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. - Додайте адресу до свого профілю, щоб ваші контакти могли поділитися нею з іншими людьми. Повідомлення про оновлення профілю буде надіслано вашим контактам. + + A few more things + Ще кілька речей No comment provided by engineer. - - Add welcome message - Додати вітальне повідомлення + + A new contact + Новий контакт + notification title + + + A new random profile will be shared. + Буде створено новий випадковий профіль. No comment provided by engineer. - - All app data is deleted. - Всі дані програми видаляються. + + A separate TCP connection will be used **for each chat profile you have in the app**. + Для кожного профілю чату, який ви маєте в додатку, буде використовуватися окреме TCP-з'єднання. No comment provided by engineer. - - All your contacts will remain connected. Profile update will be sent to your contacts. - Всі ваші контакти залишаться на зв'язку. Повідомлення про оновлення профілю буде надіслано вашим контактам. + + A separate TCP connection will be used **for each contact and group member**. +**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail. + Для кожного контакту та учасника групи буде використовуватися окреме TCP-з'єднання. +**Зверніть увагу: якщо у вас багато з'єднань, споживання заряду акумулятора і трафіку може бути значно вищим, а деякі з'єднання можуть обірватися. No comment provided by engineer. - - Delete profile - Видалити профіль - No comment provided by engineer. - - - Enable lock - Увімкнути блокування - No comment provided by engineer. - - - Enter Passcode - Введіть пароль - No comment provided by engineer. - - - Error aborting address change - Помилка скасування зміни адреси - No comment provided by engineer. - - - Favorite - Улюблений - No comment provided by engineer. - - - File will be received when your contact completes uploading it. - Файл буде отримано, коли ваш контакт завершить завантаження. - No comment provided by engineer. - - - Further reduced battery usage - Подальше зменшення використання акумулятора - No comment provided by engineer. - - - Group members can add message reactions. - Учасники групи можуть додавати реакції на повідомлення. - No comment provided by engineer. - - - Hidden chat profiles - Приховані профілі чату - No comment provided by engineer. - - - If you can't meet in person, show QR code in a video call, or share the link. - Якщо ви не можете зустрітися особисто, покажіть QR-код у відеодзвінку або поділіться посиланням. - No comment provided by engineer. - - - If you enter your self-destruct passcode while opening the app: - Якщо ви введете пароль самознищення під час відкриття програми: - No comment provided by engineer. - - - Info - Інформація - chat item action - - - Invite friends - Запросити друзів - No comment provided by engineer. - - - Finally, we have them! 🚀 - Нарешті, вони у нас є! 🚀 - No comment provided by engineer. - - - History - Історія - copied message info - - - If you enter this passcode when opening the app, all app data will be irreversibly removed! - Якщо ви введете цей пароль при відкритті програми, всі дані програми будуть безповоротно видалені! - No comment provided by engineer. - - - Image will be received when your contact completes uploading it. - Зображення буде отримано, коли ваш контакт завершить завантаження. - No comment provided by engineer. - - - Don't create address - Не створювати адресу - No comment provided by engineer. - - - Abort changing address? - Скасувати зміну адреси? - No comment provided by engineer. - - + Abort - Скасувати + Скасувати No comment provided by engineer. - - Enable self-destruct - Увімкнути самознищення - No comment provided by engineer. - - + Abort changing address - Скасувати зміну адреси + Скасувати зміну адреси No comment provided by engineer. - + + Abort changing address? + Скасувати зміну адреси? + No comment provided by engineer. + + + About SimpleX + Про SimpleX + No comment provided by engineer. + + + About SimpleX Chat + Про чат SimpleX + No comment provided by engineer. + + + About SimpleX address + Про адресу SimpleX + No comment provided by engineer. + + + Accent color + Акцентний колір + No comment provided by engineer. + + + Accept + Прийняти + accept contact request via notification + accept incoming call via notification + + + Accept connection request? + Прийняти запит на підключення? + No comment provided by engineer. + + + Accept contact request from %@? + Прийняти запит на контакт від %@? + notification body + + + Accept incognito + Прийняти інкогніто + accept contact request via notification + + + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. + Додайте адресу до свого профілю, щоб ваші контакти могли поділитися нею з іншими людьми. Повідомлення про оновлення профілю буде надіслано вашим контактам. + No comment provided by engineer. + + + Add preset servers + Додавання попередньо встановлених серверів + No comment provided by engineer. + + + Add profile + Додати профіль + No comment provided by engineer. + + + Add servers by scanning QR codes. + Додайте сервери, відсканувавши QR-код. + No comment provided by engineer. + + + Add server… + Додати сервер… + No comment provided by engineer. + + + Add to another device + Додати до іншого пристрою + No comment provided by engineer. + + + Add welcome message + Додати вітальне повідомлення + No comment provided by engineer. + + + Address + Адреса + No comment provided by engineer. + + Address change will be aborted. Old receiving address will be used. - Зміна адреси буде скасована. Буде використано стару адресу отримання. + Зміна адреси буде скасована. Буде використано стару адресу отримання. No comment provided by engineer. - - Disappearing message - Зникаюче повідомлення + + Admins can create the links to join groups. + Адміни можуть створювати посилання для приєднання до груп. No comment provided by engineer. - - Disappears at: %@ - Зникає за: %@ - copied message info - - - Enter welcome message… (optional) - Введіть вітальне повідомлення... (необов'язково) - placeholder - - - Enable self-destruct passcode - Увімкнути пароль самознищення - set passcode view - - - Don't show again - Більше не показувати + + Advanced network settings + Розширені налаштування мережі No comment provided by engineer. - - Downgrade and open chat - Пониження та відкритий чат + + All app data is deleted. + Всі дані програми видаляються. No comment provided by engineer. - - Download file - Завантажити файл - server test step - - - Enter password above to show! - Введіть пароль вище, щоб показати! + + All chats and messages will be deleted - this cannot be undone! + Всі чати та повідомлення будуть видалені - це неможливо скасувати! No comment provided by engineer. - - Error loading %@ servers - Помилка завантаження %@ серверів + + All data is erased when it is entered. + Всі дані стираються при введенні. No comment provided by engineer. - - Error saving %@ servers - Помилка збереження %@ серверів + + All group members will remain connected. + Всі учасники групи залишаться на зв'язку. No comment provided by engineer. - - Error saving passcode - Помилка збереження пароля + + All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. + Всі повідомлення будуть видалені - це неможливо скасувати! Повідомлення будуть видалені ТІЛЬКИ для вас. No comment provided by engineer. - - Error saving user password - Помилка збереження пароля користувача + + All your contacts will remain connected. + Всі ваші контакти залишаться на зв'язку. No comment provided by engineer. - - Error: - Помилка: + + All your contacts will remain connected. Profile update will be sent to your contacts. + Всі ваші контакти залишаться на зв'язку. Повідомлення про оновлення профілю буде надіслано вашим контактам. No comment provided by engineer. - - Error updating user privacy - Помилка оновлення конфіденційності користувача + + Allow + Дозволити No comment provided by engineer. - - Fully re-implemented - work in background! - Повністю перероблено - робота у фоновому режимі! + + Allow calls only if your contact allows them. + Дозволяйте дзвінки, тільки якщо ваш контакт дозволяє їх. No comment provided by engineer. - - Group moderation - Модерація груп + + Allow disappearing messages only if your contact allows it to you. + Дозволяйте зникати повідомленням, тільки якщо контакт дозволяє вам це робити. No comment provided by engineer. - - Group welcome message - Привітальне повідомлення групи + + Allow irreversible message deletion only if your contact allows it to you. + Дозволяйте безповоротне видалення повідомлень, тільки якщо контакт дозволяє вам це зробити. No comment provided by engineer. - - Hidden profile password - Прихований пароль до профілю + + Allow message reactions only if your contact allows them. + Дозволяйте реакції на повідомлення, тільки якщо ваш контакт дозволяє їх. No comment provided by engineer. - - Hide: - Приховати: + + Allow message reactions. + Дозволити реакцію на повідомлення. No comment provided by engineer. - - Immediately - Негайно + + Allow sending direct messages to members. + Дозволяє надсилати прямі повідомлення користувачам. No comment provided by engineer. - - Incorrect passcode - Неправильний пароль - PIN entry - - - Incompatible database version - Несумісна версія бази даних + + Allow sending disappearing messages. + Дозволити надсилання зникаючих повідомлень. No comment provided by engineer. - - Initial role - Початкова роль + + Allow to irreversibly delete sent messages. + Дозволяє безповоротно видаляти надіслані повідомлення. No comment provided by engineer. - - Disappears at - Зникає за + + Allow to send files and media. + Дозволяє надсилати файли та медіа. No comment provided by engineer. - - Duration - Тривалість + + Allow to send voice messages. + Дозволити надсилати голосові повідомлення. No comment provided by engineer. - - Encrypted message: database migration error - Зашифроване повідомлення: помилка міграції бази даних - notification - - - Enter welcome message… - Введіть вітальне повідомлення… - placeholder - - - Error sending email - Помилка надсилання електронного листа + + Allow voice messages only if your contact allows them. + Дозволяйте голосові повідомлення, тільки якщо ваш контакт дозволяє їх. No comment provided by engineer. - - File will be deleted from servers. - Файл буде видалено з серверів. + + Allow voice messages? + Дозволити голосові повідомлення? No comment provided by engineer. - - Fast and no wait until the sender is online! - Швидко і без очікування, поки відправник буде онлайн! + + Allow your contacts adding message reactions. + Дозвольте вашим контактам додавати реакції на повідомлення. No comment provided by engineer. - - Hide profile - Приховати профіль + + Allow your contacts to call you. + Дозвольте вашим контактам телефонувати вам. No comment provided by engineer. - - Deleted at: %@ - Видалено за: %@ - copied message info - - - Deleted at - Видалено за + + Allow your contacts to irreversibly delete sent messages. + Дозвольте вашим контактам безповоротно видаляти надіслані повідомлення. No comment provided by engineer. - - KeyChain error - помилка KeyChain + + Allow your contacts to send disappearing messages. + Дозвольте своїм контактам надсилати зникаючі повідомлення. No comment provided by engineer. - - Lock mode - Режим блокування + + Allow your contacts to send voice messages. + Дозвольте своїм контактам надсилати голосові повідомлення. No comment provided by engineer. - - Message reactions - Реакції на повідомлення + + Already connected? + Вже підключено? + No comment provided by engineer. + + + Always use relay + Завжди використовуйте реле + No comment provided by engineer. + + + An empty chat profile with the provided name is created, and the app opens as usual. + Створюється порожній профіль чату з вказаним ім'ям, і додаток відкривається у звичайному режимі. + No comment provided by engineer. + + + Answer call + Відповісти на дзвінок + No comment provided by engineer. + + + App build: %@ + Збірка програми: %@ + No comment provided by engineer. + + + App encrypts new local files (except videos). + No comment provided by engineer. + + + App icon + Іконка програми + No comment provided by engineer. + + + App passcode + Пароль додатку + No comment provided by engineer. + + + App passcode is replaced with self-destruct passcode. + Пароль програми замінено на пароль самознищення. + No comment provided by engineer. + + + App version + Версія програми + No comment provided by engineer. + + + App version: v%@ + Версія програми: v%@ + No comment provided by engineer. + + + Appearance + Зовнішній вигляд + No comment provided by engineer. + + + Attach + Прикріпити + No comment provided by engineer. + + + Audio & video calls + Аудіо та відео дзвінки + No comment provided by engineer. + + + Audio and video calls + Аудіо та відеодзвінки + No comment provided by engineer. + + + Audio/video calls + Аудіо/відео дзвінки chat feature - + + Audio/video calls are prohibited. + Аудіо/відео дзвінки заборонені. + No comment provided by engineer. + + + Authentication cancelled + Аутентифікацію скасовано + PIN entry + + + Authentication failed + Не вдалося пройти автентифікацію + No comment provided by engineer. + + + Authentication is required before the call is connected, but you may miss calls. + Перед з'єднанням дзвінка потрібно пройти автентифікацію, але ви можете пропустити дзвінки. + No comment provided by engineer. + + + Authentication unavailable + Автентифікація недоступна + No comment provided by engineer. + + + Auto-accept + Автоприйняття + No comment provided by engineer. + + + Auto-accept contact requests + Автоматичне прийняття запитів на контакт + No comment provided by engineer. + + + Auto-accept images + Автоматичне прийняття зображень + No comment provided by engineer. + + + Back + Назад + No comment provided by engineer. + + + Bad message ID + Неправильний ідентифікатор повідомлення + No comment provided by engineer. + + + Bad message hash + Поганий хеш повідомлення + No comment provided by engineer. + + + Better messages + Кращі повідомлення + No comment provided by engineer. + + + Both you and your contact can add message reactions. + Реакції на повідомлення можете додавати як ви, так і ваш контакт. + No comment provided by engineer. + + + Both you and your contact can irreversibly delete sent messages. + І ви, і ваш контакт можете безповоротно видалити надіслані повідомлення. + No comment provided by engineer. + + + Both you and your contact can make calls. + Дзвонити можете як ви, так і ваш контакт. + No comment provided by engineer. + + + Both you and your contact can send disappearing messages. + Ви і ваш контакт можете надсилати зникаючі повідомлення. + No comment provided by engineer. + + + Both you and your contact can send voice messages. + Надсилати голосові повідомлення можете як ви, так і ваш контакт. + No comment provided by engineer. + + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). + Через профіль чату (за замовчуванням) або [за з'єднанням](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA). + No comment provided by engineer. + + + Call already ended! + Дзвінок вже закінчився! + No comment provided by engineer. + + + Calls + Дзвінки + No comment provided by engineer. + + + Can't delete user profile! + Не можу видалити профіль користувача! + No comment provided by engineer. + + + Can't invite contact! + Не вдається запросити контакт! + No comment provided by engineer. + + + Can't invite contacts! + Неможливо запросити контакти! + No comment provided by engineer. + + + Cancel + Скасувати + No comment provided by engineer. + + + Cannot access keychain to save database password + Не вдається отримати доступ до зв'язки ключів для збереження пароля до бази даних + No comment provided by engineer. + + + Cannot receive file + Не вдається отримати файл + No comment provided by engineer. + + + Change + Зміна + No comment provided by engineer. + + + Change database passphrase? + Змінити пароль до бази даних? + No comment provided by engineer. + + + Change lock mode + Зміна режиму блокування + authentication reason + + + Change member role? + Змінити роль учасника? + No comment provided by engineer. + + + Change passcode + Змінити пароль + authentication reason + + + Change receiving address + Змінити адресу отримання + No comment provided by engineer. + + + Change receiving address? + Змінити адресу отримання? + No comment provided by engineer. + + + Change role + Змінити роль + No comment provided by engineer. + + + Change self-destruct mode + Змінити режим самознищення + authentication reason + + + Change self-destruct passcode + Змінити пароль самознищення + authentication reason + set passcode view + + + Chat archive + Архів чату + No comment provided by engineer. + + + Chat console + Консоль чату + No comment provided by engineer. + + + Chat database + База даних чату + No comment provided by engineer. + + + Chat database deleted + Видалено базу даних чату + No comment provided by engineer. + + + Chat database imported + Імпорт бази даних чату + No comment provided by engineer. + + + Chat is running + Чат запущено + No comment provided by engineer. + + + Chat is stopped + Чат зупинено + No comment provided by engineer. + + + Chat preferences + Налаштування чату + No comment provided by engineer. + + + Chats + Чати + No comment provided by engineer. + + + Check server address and try again. + Перевірте адресу сервера та спробуйте ще раз. + No comment provided by engineer. + + + Chinese and Spanish interface + Інтерфейс китайською та іспанською мовами + No comment provided by engineer. + + + Choose file + Виберіть файл + No comment provided by engineer. + + + Choose from library + Виберіть з бібліотеки + No comment provided by engineer. + + + Clear + Чисто + No comment provided by engineer. + + + Clear conversation + Ясна розмова + No comment provided by engineer. + + + Clear conversation? + Відверта розмова? + No comment provided by engineer. + + + Clear verification + Очистити перевірку + No comment provided by engineer. + + + Colors + Кольори + No comment provided by engineer. + + + Compare file + Порівняти файл + server test step + + + Compare security codes with your contacts. + Порівняйте коди безпеки зі своїми контактами. + No comment provided by engineer. + + + Configure ICE servers + Налаштування серверів ICE + No comment provided by engineer. + + + Confirm + Підтвердити + No comment provided by engineer. + + + Confirm Passcode + Підтвердити пароль + No comment provided by engineer. + + + Confirm database upgrades + Підтвердити оновлення бази даних + No comment provided by engineer. + + + Confirm new passphrase… + Підтвердіть нову парольну фразу… + No comment provided by engineer. + + + Confirm password + Підтвердити пароль + No comment provided by engineer. + + + Connect + Підключіться + server test step + + + Connect directly + Підключіться безпосередньо + No comment provided by engineer. + + + Connect incognito + Підключайтеся інкогніто + No comment provided by engineer. + + + Connect via contact link + Підключіться за контактним посиланням + No comment provided by engineer. + + + Connect via group link? + Підключитися за груповим посиланням? + No comment provided by engineer. + + + Connect via link + Підключіться за посиланням + No comment provided by engineer. + + + Connect via link / QR code + Підключитися за посиланням / QR-кодом + No comment provided by engineer. + + + Connect via one-time link + Під'єднатися за одноразовим посиланням + No comment provided by engineer. + + + Connecting to server… + Підключення до сервера… + No comment provided by engineer. + + + Connecting to server… (error: %@) + Підключення до сервера... (помилка: %@) + No comment provided by engineer. + + + Connection + Підключення + No comment provided by engineer. + + + Connection error + Помилка підключення + No comment provided by engineer. + + + Connection error (AUTH) + Помилка підключення (AUTH) + No comment provided by engineer. + + + Connection request sent! + Запит на підключення відправлено! + No comment provided by engineer. + + + Connection timeout + Тайм-аут з'єднання + No comment provided by engineer. + + + Contact allows + Контакт дозволяє + No comment provided by engineer. + + + Contact already exists + Контакт вже існує + No comment provided by engineer. + + + Contact and all messages will be deleted - this cannot be undone! + Контакт і всі повідомлення будуть видалені - це неможливо скасувати! + No comment provided by engineer. + + + Contact hidden: + Контакт приховано: + notification + + + Contact is connected + Контакт підключений + notification + + + Contact is not connected yet! + Контакт ще не підключено! + No comment provided by engineer. + + + Contact name + Ім'я контактної особи + No comment provided by engineer. + + + Contact preferences + Налаштування контактів + No comment provided by engineer. + + + Contacts + Контакти + No comment provided by engineer. + + + Contacts can mark messages for deletion; you will be able to view them. + Контакти можуть позначати повідомлення для видалення; ви зможете їх переглянути. + No comment provided by engineer. + + + Continue + Продовжуйте + No comment provided by engineer. + + + Copy + Копіювати + chat item action + + + Core version: v%@ + Основна версія: v%@ + No comment provided by engineer. + + + Create + Створити + No comment provided by engineer. + + + Create SimpleX address + Створіть адресу SimpleX + No comment provided by engineer. + + + Create an address to let people connect with you. + Створіть адресу, щоб люди могли з вами зв'язатися. + No comment provided by engineer. + + + Create file + Створити файл + server test step + + + Create group link + Створити групове посилання + No comment provided by engineer. + + + Create link + Створити посилання + No comment provided by engineer. + + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + + + Create one-time invitation link + Створіть одноразове посилання-запрошення + No comment provided by engineer. + + + Create queue + Створити чергу + server test step + + + Create secret group + Створити секретну групу + No comment provided by engineer. + + + Create your profile + Створіть свій профіль + No comment provided by engineer. + + + Created on %@ + Створено %@ + No comment provided by engineer. + + + Current Passcode + Поточний пароль + No comment provided by engineer. + + + Current passphrase… + Поточна парольна фраза… + No comment provided by engineer. + + + Currently maximum supported file size is %@. + Наразі максимальний підтримуваний розмір файлу - %@. + No comment provided by engineer. + + + Custom time + Індивідуальний час + No comment provided by engineer. + + + Dark + Темний + No comment provided by engineer. + + + Database ID + Ідентифікатор бази даних + No comment provided by engineer. + + + Database ID: %d + Ідентифікатор бази даних: %d + copied message info + + + Database IDs and Transport isolation option. + Ідентифікатори бази даних та опція ізоляції транспорту. + No comment provided by engineer. + + + Database downgrade + Пониження версії бази даних + No comment provided by engineer. + + + Database encrypted! + База даних зашифрована! + No comment provided by engineer. + + + Database encryption passphrase will be updated and stored in the keychain. + + Парольна фраза шифрування бази даних буде оновлена та збережена у в’язці ключів. + + No comment provided by engineer. + + + Database encryption passphrase will be updated. + + Ключову фразу шифрування бази даних буде оновлено. + + No comment provided by engineer. + + + Database error + Помилка в базі даних + No comment provided by engineer. + + + Database is encrypted using a random passphrase, you can change it. + База даних зашифрована за допомогою випадкової парольної фрази, яку ви можете змінити. + No comment provided by engineer. + + + Database is encrypted using a random passphrase. Please change it before exporting. + База даних зашифрована за допомогою випадкової парольної фрази. Будь ласка, змініть його перед експортом. + No comment provided by engineer. + + + Database passphrase + Ключова фраза бази даних + No comment provided by engineer. + + + Database passphrase & export + Ключова фраза бази даних та експорт + No comment provided by engineer. + + + Database passphrase is different from saved in the keychain. + Парольна фраза бази даних відрізняється від збереженої у в’язці ключів. + No comment provided by engineer. + + + Database passphrase is required to open chat. + Для відкриття чату потрібно ввести пароль до бази даних. + No comment provided by engineer. + + + Database upgrade + Оновлення бази даних + No comment provided by engineer. + + + Database will be encrypted and the passphrase stored in the keychain. + + База даних буде зашифрована, а парольна фраза збережена у в’язці ключів. + + No comment provided by engineer. + + + Database will be encrypted. + + База даних буде зашифрована. + + No comment provided by engineer. + + + Database will be migrated when the app restarts + База даних буде перенесена під час перезапуску програми + No comment provided by engineer. + + + Decentralized + Децентралізований + No comment provided by engineer. + + + Decryption error + Помилка розшифровки + message decrypt error item + + + Delete + Видалити + chat item action + + + Delete Contact + Видалити контакт + No comment provided by engineer. + + + Delete address + Видалити адресу + No comment provided by engineer. + + + Delete address? + Видалити адресу? + No comment provided by engineer. + + + Delete after + Видалити після + No comment provided by engineer. + + + Delete all files + Видалити всі файли + No comment provided by engineer. + + + Delete archive + Видалити архів + No comment provided by engineer. + + + Delete chat archive? + Видалити архів чату? + No comment provided by engineer. + + + Delete chat profile + Видалити профіль чату + No comment provided by engineer. + + + Delete chat profile? + Видалити профіль чату? + No comment provided by engineer. + + + Delete connection + Видалити підключення + No comment provided by engineer. + + + Delete contact + Видалити контакт + No comment provided by engineer. + + + Delete contact? + Видалити контакт? + No comment provided by engineer. + + + Delete database + Видалити базу даних + No comment provided by engineer. + + + Delete file + Видалити файл + server test step + + + Delete files and media? + Видаляти файли та медіа? + No comment provided by engineer. + + + Delete files for all chat profiles + Видалення файлів для всіх профілів чату + No comment provided by engineer. + + + Delete for everyone + Видалити для всіх + chat feature + + + Delete for me + Видалити для мене + No comment provided by engineer. + + + Delete group + Видалити групу + No comment provided by engineer. + + + Delete group? + Видалити групу? + No comment provided by engineer. + + + Delete invitation + Видалити запрошення + No comment provided by engineer. + + + Delete link + Видалити посилання + No comment provided by engineer. + + + Delete link? + Видалити посилання? + No comment provided by engineer. + + + Delete member message? + Видалити повідомлення учасника? + No comment provided by engineer. + + + Delete message? + Видалити повідомлення? + No comment provided by engineer. + + + Delete messages + Видалити повідомлення + No comment provided by engineer. + + + Delete messages after + Видаляйте повідомлення після + No comment provided by engineer. + + + Delete old database + Видалення старої бази даних + No comment provided by engineer. + + + Delete old database? + Видалити стару базу даних? + No comment provided by engineer. + + + Delete pending connection + Видалити очікуване з'єднання + No comment provided by engineer. + + + Delete pending connection? + Видалити очікуване з'єднання? + No comment provided by engineer. + + + Delete profile + Видалити профіль + No comment provided by engineer. + + + Delete queue + Видалити чергу + server test step + + + Delete user profile? + Видалити профіль користувача? + No comment provided by engineer. + + + Deleted at + Видалено за + No comment provided by engineer. + + + Deleted at: %@ + Видалено за: %@ + copied message info + + + Delivery + Доставка + No comment provided by engineer. + + + Delivery receipts are disabled! + Квитанції про доставку відключені! + No comment provided by engineer. + + + Delivery receipts! + Квитанції про доставку! + No comment provided by engineer. + + + Description + Опис + No comment provided by engineer. + + + Develop + Розробник + No comment provided by engineer. + + + Developer tools + Інструменти для розробників + No comment provided by engineer. + + + Device + Пристрій + No comment provided by engineer. + + + Device authentication is disabled. Turning off SimpleX Lock. + Автентифікацію пристрою вимкнено. Вимкнення SimpleX Lock. + No comment provided by engineer. + + + Device authentication is not enabled. You can turn on SimpleX Lock via Settings, once you enable device authentication. + Автентифікація пристрою не ввімкнена. Ви можете увімкнути SimpleX Lock у Налаштуваннях, коли увімкнете автентифікацію пристрою. + No comment provided by engineer. + + + Different names, avatars and transport isolation. + Різні імена, аватарки та транспортна ізоляція. + No comment provided by engineer. + + + Direct messages + Прямі повідомлення + chat feature + + + Direct messages between members are prohibited in this group. + У цій групі заборонені прямі повідомлення між учасниками. + No comment provided by engineer. + + + Disable (keep overrides) + Вимкнути (зберегти перевизначення) + No comment provided by engineer. + + + Disable SimpleX Lock + Вимкнути SimpleX Lock + authentication reason + + + Disable for all + Вимкнути для всіх + No comment provided by engineer. + + + Disappearing message + Зникаюче повідомлення + No comment provided by engineer. + + + Disappearing messages + Зникаючі повідомлення + chat feature + + + Disappearing messages are prohibited in this chat. + Зникаючі повідомлення в цьому чаті заборонені. + No comment provided by engineer. + + + Disappearing messages are prohibited in this group. + У цій групі заборонено зникаючі повідомлення. + No comment provided by engineer. + + + Disappears at + Зникає за + No comment provided by engineer. + + + Disappears at: %@ + Зникає за: %@ + copied message info + + + Disconnect + Від'єднати + server test step + + + Discover and join groups + No comment provided by engineer. + + + Display name + Відображуване ім'я + No comment provided by engineer. + + + Display name: + Відображуване ім'я: + No comment provided by engineer. + + + Do NOT use SimpleX for emergency calls. + НЕ використовуйте SimpleX для екстрених викликів. + No comment provided by engineer. + + + Do it later + Зробіть це пізніше + No comment provided by engineer. + + + Don't create address + Не створювати адресу + No comment provided by engineer. + + + Don't enable + Не вмикати + No comment provided by engineer. + + + Don't show again + Більше не показувати + No comment provided by engineer. + + + Downgrade and open chat + Пониження та відкритий чат + No comment provided by engineer. + + + Download file + Завантажити файл + server test step + + + Duplicate display name! + Дублююче ім'я користувача! + No comment provided by engineer. + + + Duration + Тривалість + No comment provided by engineer. + + + Edit + Редагувати + chat item action + + + Edit group profile + Редагування профілю групи + No comment provided by engineer. + + + Enable + Увімкнути + No comment provided by engineer. + + + Enable (keep overrides) + Увімкнути (зберегти перевизначення) + No comment provided by engineer. + + + Enable SimpleX Lock + Увімкнути SimpleX Lock + authentication reason + + + Enable TCP keep-alive + Увімкнути TCP keep-alive + No comment provided by engineer. + + + Enable automatic message deletion? + Увімкнути автоматичне видалення повідомлень? + No comment provided by engineer. + + + Enable for all + Увімкнути для всіх + No comment provided by engineer. + + + Enable instant notifications? + Увімкнути миттєві сповіщення? + No comment provided by engineer. + + + Enable lock + Увімкнути блокування + No comment provided by engineer. + + + Enable notifications + Увімкнути сповіщення + No comment provided by engineer. + + + Enable periodic notifications? + Увімкнути періодичні сповіщення? + No comment provided by engineer. + + + Enable self-destruct + Увімкнути самознищення + No comment provided by engineer. + + + Enable self-destruct passcode + Увімкнути пароль самознищення + set passcode view + + + Encrypt + Зашифрувати + No comment provided by engineer. + + + Encrypt database? + Зашифрувати базу даних? + No comment provided by engineer. + + + Encrypt local files + No comment provided by engineer. + + + Encrypt stored files & media + No comment provided by engineer. + + + Encrypted database + Зашифрована база даних + No comment provided by engineer. + + + Encrypted message or another event + Зашифроване повідомлення або інша подія + notification + + + Encrypted message: database error + Зашифроване повідомлення: помилка бази даних + notification + + + Encrypted message: database migration error + Зашифроване повідомлення: помилка міграції бази даних + notification + + + Encrypted message: keychain error + Зашифроване повідомлення: помилка ланцюжка ключів + notification + + + Encrypted message: no passphrase + Зашифроване повідомлення: без ключової фрази + notification + + + Encrypted message: unexpected error + Зашифроване повідомлення: несподівана помилка + notification + + + Enter Passcode + Введіть пароль + No comment provided by engineer. + + + Enter correct passphrase. + Введіть правильну парольну фразу. + No comment provided by engineer. + + + Enter passphrase… + Введіть пароль… + No comment provided by engineer. + + + Enter password above to show! + Введіть пароль вище, щоб показати! + No comment provided by engineer. + + + Enter server manually + Увійдіть на сервер вручну + No comment provided by engineer. + + + Enter welcome message… + Введіть вітальне повідомлення… + placeholder + + + Enter welcome message… (optional) + Введіть вітальне повідомлення... (необов'язково) + placeholder + + + Error + Помилка + No comment provided by engineer. + + + Error aborting address change + Помилка скасування зміни адреси + No comment provided by engineer. + + + Error accepting contact request + Помилка при прийнятті запиту на контакт + No comment provided by engineer. + + + Error accessing database file + Помилка доступу до файлу бази даних + No comment provided by engineer. + + + Error adding member(s) + Помилка додавання користувача(ів) + No comment provided by engineer. + + + Error changing address + Помилка зміни адреси + No comment provided by engineer. + + + Error changing role + Помилка зміни ролі + No comment provided by engineer. + + + Error changing setting + Помилка зміни налаштування + No comment provided by engineer. + + + Error creating address + Помилка створення адреси + No comment provided by engineer. + + + Error creating group + Помилка створення групи + No comment provided by engineer. + + + Error creating group link + Помилка створення посилання на групу + No comment provided by engineer. + + + Error creating member contact + No comment provided by engineer. + + + Error creating profile! + Помилка створення профілю! + No comment provided by engineer. + + + Error decrypting file + No comment provided by engineer. + + + Error deleting chat database + Помилка видалення бази даних чату + No comment provided by engineer. + + + Error deleting chat! + Помилка видалення чату! + No comment provided by engineer. + + + Error deleting connection + Помилка видалення з'єднання + No comment provided by engineer. + + + Error deleting contact + Помилка видалення контакту + No comment provided by engineer. + + + Error deleting database + Помилка видалення бази даних + No comment provided by engineer. + + + Error deleting old database + Помилка видалення старої бази даних + No comment provided by engineer. + + + Error deleting token + Помилка видалення токена + No comment provided by engineer. + + + Error deleting user profile + Помилка видалення профілю користувача + No comment provided by engineer. + + + Error enabling delivery receipts! + Помилка активації підтвердження доставлення! + No comment provided by engineer. + + + Error enabling notifications + Помилка увімкнення сповіщень + No comment provided by engineer. + + + Error encrypting database + Помилка шифрування бази даних + No comment provided by engineer. + + + Error exporting chat database + Помилка експорту бази даних чату + No comment provided by engineer. + + + Error importing chat database + Помилка імпорту бази даних чату + No comment provided by engineer. + + + Error joining group + Помилка приєднання до групи + No comment provided by engineer. + + + Error loading %@ servers + Помилка завантаження %@ серверів + No comment provided by engineer. + + + Error receiving file + Помилка отримання файлу + No comment provided by engineer. + + + Error removing member + Помилка видалення учасника + No comment provided by engineer. + + + Error saving %@ servers + Помилка збереження %@ серверів + No comment provided by engineer. + + + Error saving ICE servers + Помилка збереження серверів ICE + No comment provided by engineer. + + + Error saving group profile + Помилка збереження профілю групи + No comment provided by engineer. + + + Error saving passcode + Помилка збереження пароля + No comment provided by engineer. + + + Error saving passphrase to keychain + Помилка збереження пароля на keychain + No comment provided by engineer. + + + Error saving user password + Помилка збереження пароля користувача + No comment provided by engineer. + + + Error sending email + Помилка надсилання електронного листа + No comment provided by engineer. + + + Error sending member contact invitation + No comment provided by engineer. + + + Error sending message + Помилка надсилання повідомлення + No comment provided by engineer. + + + Error setting delivery receipts! + Помилка встановлення підтвердження доставлення! + No comment provided by engineer. + + + Error starting chat + Помилка запуску чату + No comment provided by engineer. + + + Error stopping chat + Помилка зупинки чату + No comment provided by engineer. + + + Error switching profile! + Помилка перемикання профілю! + No comment provided by engineer. + + + Error synchronizing connection + Помилка синхронізації з'єднання + No comment provided by engineer. + + + Error updating group link + Помилка оновлення посилання на групу + No comment provided by engineer. + + + Error updating message + Повідомлення про помилку оновлення + No comment provided by engineer. + + + Error updating settings + Помилка оновлення налаштувань + No comment provided by engineer. + + + Error updating user privacy + Помилка оновлення конфіденційності користувача + No comment provided by engineer. + + + Error: + Помилка: + No comment provided by engineer. + + + Error: %@ + Помилка: %@ + No comment provided by engineer. + + + Error: URL is invalid + Помилка: URL-адреса невірна + No comment provided by engineer. + + + Error: no database file + Помилка: немає файлу бази даних + No comment provided by engineer. + + + Even when disabled in the conversation. + Навіть коли вимкнений у розмові. + No comment provided by engineer. + + + Exit without saving + Вихід без збереження + No comment provided by engineer. + + + Export database + Експорт бази даних + No comment provided by engineer. + + + Export error: + Помилка експорту: + No comment provided by engineer. + + + Exported database archive. + Експортований архів бази даних. + No comment provided by engineer. + + + Exporting database archive… + Експорт архіву бази даних… + No comment provided by engineer. + + + Failed to remove passphrase + Не вдалося видалити парольну фразу + No comment provided by engineer. + + + Fast and no wait until the sender is online! + Швидко і без очікування, поки відправник буде онлайн! + No comment provided by engineer. + + + Favorite + Улюблений + No comment provided by engineer. + + + File will be deleted from servers. + Файл буде видалено з серверів. + No comment provided by engineer. + + + File will be received when your contact completes uploading it. + Файл буде отримано, коли ваш контакт завершить завантаження. + No comment provided by engineer. + + + File will be received when your contact is online, please wait or check later! + Файл буде отримано, коли ваш контакт буде онлайн, будь ласка, зачекайте або перевірте пізніше! + No comment provided by engineer. + + + File: %@ + Файл: %@ + No comment provided by engineer. + + + Files & media + Файли та медіа + No comment provided by engineer. + + + Files and media + Файли і медіа + chat feature + + + Files and media are prohibited in this group. + Файли та медіа в цій групі заборонені. + No comment provided by engineer. + + + Files and media prohibited! + Файли та медіа заборонені! + No comment provided by engineer. + + + Filter unread and favorite chats. + Фільтруйте непрочитані та улюблені чати. + No comment provided by engineer. + + + Finally, we have them! 🚀 + Нарешті, вони у нас є! 🚀 + No comment provided by engineer. + + + Find chats faster + Швидше знаходьте чати + No comment provided by engineer. + + + Fix + Виправити + No comment provided by engineer. + + + Fix connection + Виправити з'єднання + No comment provided by engineer. + + + Fix connection? + Полагодити зв'язок? + No comment provided by engineer. + + + Fix encryption after restoring backups. + Виправити шифрування після відновлення резервних копій. + No comment provided by engineer. + + + Fix not supported by contact + Виправлення не підтримується контактом + No comment provided by engineer. + + + Fix not supported by group member + Виправлення не підтримується учасником групи + No comment provided by engineer. + + + For console + Для консолі + No comment provided by engineer. + + + French interface + Французький інтерфейс + No comment provided by engineer. + + + Full link + Повне посилання + No comment provided by engineer. + + + Full name (optional) + Повне ім'я (необов'язково) + No comment provided by engineer. + + + Full name: + Повне ім'я: + No comment provided by engineer. + + + Fully re-implemented - work in background! + Повністю перероблено - робота у фоновому режимі! + No comment provided by engineer. + + + Further reduced battery usage + Подальше зменшення використання акумулятора + No comment provided by engineer. + + + GIFs and stickers + GIF-файли та наклейки + No comment provided by engineer. + + + Group + Група + No comment provided by engineer. + + + Group display name + Назва групи для відображення + No comment provided by engineer. + + + Group full name (optional) + Повна назва групи (необов'язково) + No comment provided by engineer. + + + Group image + Зображення групи + No comment provided by engineer. + + + Group invitation + Групове запрошення + No comment provided by engineer. + + + Group invitation expired + Термін дії групового запрошення закінчився + No comment provided by engineer. + + + Group invitation is no longer valid, it was removed by sender. + Групове запрошення більше не дійсне, воно було видалено відправником. + No comment provided by engineer. + + + Group link + Посилання на групу + No comment provided by engineer. + + + Group links + Групові посилання + No comment provided by engineer. + + + Group members can add message reactions. + Учасники групи можуть додавати реакції на повідомлення. + No comment provided by engineer. + + + Group members can irreversibly delete sent messages. + Учасники групи можуть безповоротно видаляти надіслані повідомлення. + No comment provided by engineer. + + + Group members can send direct messages. + Учасники групи можуть надсилати прямі повідомлення. + No comment provided by engineer. + + + Group members can send disappearing messages. + Учасники групи можуть надсилати зникаючі повідомлення. + No comment provided by engineer. + + + Group members can send files and media. + Учасники групи можуть надсилати файли та медіа. + No comment provided by engineer. + + + Group members can send voice messages. + Учасники групи можуть надсилати голосові повідомлення. + No comment provided by engineer. + + + Group message: + Групове повідомлення: + notification + + + Group moderation + Модерація груп + No comment provided by engineer. + + + Group preferences + Параметри груп + No comment provided by engineer. + + + Group profile + Профіль групи + No comment provided by engineer. + + + Group profile is stored on members' devices, not on the servers. + Профіль групи зберігається на пристроях учасників, а не на серверах. + No comment provided by engineer. + + + Group welcome message + Привітальне повідомлення групи + No comment provided by engineer. + + + Group will be deleted for all members - this cannot be undone! + Група буде видалена для всіх учасників - це неможливо скасувати! + No comment provided by engineer. + + + Group will be deleted for you - this cannot be undone! + Група буде видалена для вас - це не може бути скасовано! + No comment provided by engineer. + + + Help + Довідка + No comment provided by engineer. + + + Hidden + Приховано + No comment provided by engineer. + + + Hidden chat profiles + Приховані профілі чату + No comment provided by engineer. + + + Hidden profile password + Прихований пароль до профілю + No comment provided by engineer. + + + Hide + Приховати + chat item action + + + Hide app screen in the recent apps. + Приховати екран програми в останніх програмах. + No comment provided by engineer. + + + Hide profile + Приховати профіль + No comment provided by engineer. + + + Hide: + Приховати: + No comment provided by engineer. + + + History + Історія + No comment provided by engineer. + + + How SimpleX works + Як працює SimpleX + No comment provided by engineer. + + + How it works + Як це працює + No comment provided by engineer. + + + How to + Як зробити + No comment provided by engineer. + + + How to use it + Як ним користуватися + No comment provided by engineer. + + + How to use your servers + Як користуватися вашими серверами + No comment provided by engineer. + + + ICE servers (one per line) + Сервери ICE (по одному на лінію) + No comment provided by engineer. + + + If you can't meet in person, show QR code in a video call, or share the link. + Якщо ви не можете зустрітися особисто, покажіть QR-код у відеодзвінку або поділіться посиланням. + No comment provided by engineer. + + + If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. + Якщо ви не можете зустрітися особисто, ви можете **сканувати QR-код у відеодзвінку**, або ваш контакт може поділитися посиланням на запрошення. + No comment provided by engineer. + + + If you enter this passcode when opening the app, all app data will be irreversibly removed! + Якщо ви введете цей пароль при відкритті програми, всі дані програми будуть безповоротно видалені! + No comment provided by engineer. + + + If you enter your self-destruct passcode while opening the app: + Якщо ви введете пароль самознищення під час відкриття програми: + No comment provided by engineer. + + + If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app). + Якщо вам потрібно скористатися чатом зараз, натисніть **Зробити це пізніше** нижче (вам буде запропоновано перенести базу даних при перезапуску програми). + No comment provided by engineer. + + + Ignore + Ігнорувати + No comment provided by engineer. + + + Image will be received when your contact completes uploading it. + Зображення буде отримано, коли ваш контакт завершить завантаження. + No comment provided by engineer. + + + Image will be received when your contact is online, please wait or check later! + Зображення буде отримано, коли ваш контакт буде онлайн, будь ласка, зачекайте або перевірте пізніше! + No comment provided by engineer. + + + Immediately + Негайно + No comment provided by engineer. + + + Immune to spam and abuse + Імунітет до спаму та зловживань + No comment provided by engineer. + + + Import + Імпорт + No comment provided by engineer. + + + Import chat database? + Імпортувати базу даних чату? + No comment provided by engineer. + + + Import database + Імпорт бази даних + No comment provided by engineer. + + + Improved privacy and security + Покращена конфіденційність та безпека + No comment provided by engineer. + + + Improved server configuration + Покращена конфігурація сервера + No comment provided by engineer. + + + In reply to + У відповідь на + No comment provided by engineer. + + + Incognito + Інкогніто + No comment provided by engineer. + + + Incognito mode + Режим інкогніто + No comment provided by engineer. + + + Incognito mode protects your privacy by using a new random profile for each contact. + Режим інкогніто захищає вашу конфіденційність, використовуючи новий випадковий профіль для кожного контакту. + No comment provided by engineer. + + + Incoming audio call + Вхідний аудіовиклик + notification + + + Incoming call + Вхідний дзвінок + notification + + + Incoming video call + Вхідний відеодзвінок + notification + + + Incompatible database version + Несумісна версія бази даних + No comment provided by engineer. + + + Incorrect passcode + Неправильний пароль + PIN entry + + + Incorrect security code! + Неправильний код безпеки! + No comment provided by engineer. + + + Info + Інформація + chat item action + + + Initial role + Початкова роль + No comment provided by engineer. + + + Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat) + Встановіть [SimpleX Chat для терміналу](https://github.com/simplex-chat/simplex-chat) + No comment provided by engineer. + + + Instant push notifications will be hidden! + + Миттєві пуш-сповіщення будуть приховані! + + No comment provided by engineer. + + + Instantly + Миттєво + No comment provided by engineer. + + + Interface + Інтерфейс + No comment provided by engineer. + + + Invalid connection link + Неправильне посилання для підключення + No comment provided by engineer. + + + Invalid server address! + Неправильна адреса сервера! + No comment provided by engineer. + + + Invalid status + Недійсний статус + item status text + + + Invitation expired! + Термін дії запрошення закінчився! + No comment provided by engineer. + + + Invite friends + Запросити друзів + No comment provided by engineer. + + + Invite members + Запросити учасників + No comment provided by engineer. + + + Invite to group + Запросити до групи + No comment provided by engineer. + + + Irreversible message deletion + Безповоротне видалення повідомлення + No comment provided by engineer. + + + Irreversible message deletion is prohibited in this chat. + У цьому чаті заборонено безповоротне видалення повідомлень. + No comment provided by engineer. + + + Irreversible message deletion is prohibited in this group. + У цій групі заборонено безповоротне видалення повідомлень. + No comment provided by engineer. + + + It allows having many anonymous connections without any shared data between them in a single chat profile. + Це дозволяє мати багато анонімних з'єднань без будь-яких спільних даних між ними в одному профілі чату. + No comment provided by engineer. + + It can happen when you or your connection used the old database backup. - Це може статися, якщо ви або ваше з'єднання використовували стару резервну копію бази даних. + Це може статися, якщо ви або ваше з'єднання використовували стару резервну копію бази даних. No comment provided by engineer. - - Learn more - Дізнайтеся більше - No comment provided by engineer. - - - Lock after - Блокування після - No comment provided by engineer. - - - Let's talk in SimpleX Chat - Поговоримо в чаті SimpleX - email subject - - - Japanese interface - Японський інтерфейс - No comment provided by engineer. - - - Make profile private! - Зробіть профіль приватним! - No comment provided by engineer. - - + It can happen when: 1. The messages expired in the sending client after 2 days or on the server after 30 days. 2. Message decryption failed, because you or your contact used old database backup. 3. The connection was compromised. - Це може статися, коли: + Це може статися, коли: 1. Термін дії повідомлень закінчився в клієнті-відправнику через 2 дні або на сервері через 30 днів. 2. Не вдалося розшифрувати повідомлення, тому що ви або ваш контакт використовували стару резервну копію бази даних. 3. З'єднання було скомпрометовано. 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 (%@). + Схоже, що ви вже підключені за цим посиланням. Якщо це не так, сталася помилка (%@). + No comment provided by engineer. + + + Italian interface + Італійський інтерфейс + No comment provided by engineer. + + + Japanese interface + Японський інтерфейс + No comment provided by engineer. + + + Join + Приєднуйтесь + No comment provided by engineer. + + + Join group + Приєднуйтесь до групи + No comment provided by engineer. + + + Join incognito + Приєднуйтесь інкогніто + No comment provided by engineer. + + + Joining group + Приєднання до групи + No comment provided by engineer. + + + Keep your connections + Зберігайте свої зв'язки + No comment provided by engineer. + + + KeyChain error + помилка KeyChain + No comment provided by engineer. + + + Keychain error + помилка KeyChain + No comment provided by engineer. + + + LIVE + НАЖИВО + No comment provided by engineer. + + + Large file! + Великий файл! + No comment provided by engineer. + + + Learn more + Дізнайтеся більше + No comment provided by engineer. + + + Leave + Залишити + No comment provided by engineer. + + + Leave group + Покинути групу + No comment provided by engineer. + + + Leave group? + Покинути групу? + No comment provided by engineer. + + + Let's talk in SimpleX Chat + Поговоримо в чаті SimpleX + email subject + + + Light + Світлий + No comment provided by engineer. + + + Limitations + Обмеження + No comment provided by engineer. + + + Live message! + Живе повідомлення! + No comment provided by engineer. + + + Live messages + Живі повідомлення + No comment provided by engineer. + + + Local name + Місцева назва + No comment provided by engineer. + + + Local profile data only + Тільки локальні дані профілю + No comment provided by engineer. + + + Lock after + Блокування після + No comment provided by engineer. + + + Lock mode + Режим блокування + No comment provided by engineer. + + + Make a private connection + Створіть приватне з'єднання + No comment provided by engineer. + + + Make one message disappear + Зробити так, щоб одне повідомлення зникло + No comment provided by engineer. + + + Make profile private! + Зробіть профіль приватним! + No comment provided by engineer. + + Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@). - Переконайтеся, що адреси серверів %@ мають правильний формат, розділені рядками і не дублюються (%@). + Переконайтеся, що адреси серверів %@ мають правильний формат, розділені рядками і не дублюються (%@). No comment provided by engineer. - + + Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated. + Переконайтеся, що адреси серверів WebRTC ICE мають правильний формат, розділені рядками і не дублюються. + No comment provided by engineer. + + + Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?* + Багато людей запитували: *якщо SimpleX не має ідентифікаторів користувачів, як він може доставляти повідомлення?* + No comment provided by engineer. + + + Mark deleted for everyone + Позначити видалено для всіх + No comment provided by engineer. + + + Mark read + Позначити прочитано + No comment provided by engineer. + + + Mark verified + Позначити перевірено + No comment provided by engineer. + + + Markdown in messages + Виправлення в повідомленнях + No comment provided by engineer. + + + Max 30 seconds, received instantly. + Максимум 30 секунд, отримується миттєво. + No comment provided by engineer. + + + Member + Учасник + No comment provided by engineer. + + + Member role will be changed to "%@". All group members will be notified. + Роль учасника буде змінено на "%@". Всі учасники групи будуть повідомлені про це. + No comment provided by engineer. + + + Member role will be changed to "%@". The member will receive a new invitation. + Роль учасника буде змінено на "%@". Учасник отримає нове запрошення. + No comment provided by engineer. + + + Member will be removed from group - this cannot be undone! + Учасник буде видалений з групи - це неможливо скасувати! + No comment provided by engineer. + + + Message delivery error + Помилка доставки повідомлення + item status text + + + Message delivery receipts! + Підтвердження доставки повідомлення! + No comment provided by engineer. + + + Message draft + Чернетка повідомлення + No comment provided by engineer. + + + Message reactions + Реакції на повідомлення + chat feature + + Message reactions are prohibited in this chat. - Реакції на повідомлення в цьому чаті заборонені. + Реакції на повідомлення в цьому чаті заборонені. No comment provided by engineer. - + Message reactions are prohibited in this group. - Реакції на повідомлення в цій групі заборонені. + Реакції на повідомлення в цій групі заборонені. No comment provided by engineer. - + + Message text + Текст повідомлення + No comment provided by engineer. + + + Messages + Повідомлення + No comment provided by engineer. + + Messages & files - Повідомлення та файли + Повідомлення та файли No comment provided by engineer. - - Only you can make calls. - Дзвонити можете тільки ви. + + Migrating database archive… + Перенесення архіву бази даних… No comment provided by engineer. - - Only your contact can make calls. - Тільки ваш контакт може здійснювати дзвінки. + + Migration error: + Помилка міграції: No comment provided by engineer. - - Please remember or store it securely - there is no way to recover a lost passcode! - Будь ласка, запам'ятайте або надійно зберігайте його - втрачений пароль неможливо відновити! + + Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat). + Міграція не вдалася. Натисніть **Пропустити** нижче, щоб продовжити використовувати поточну базу даних. Будь ласка, повідомте про проблему розробникам програми через чат або електронну пошту [chat@simplex.chat](mailto:chat@simplex.chat). No comment provided by engineer. - - New Passcode - Новий пароль + + Migration is completed + Міграцію завершено No comment provided by engineer. - - Save welcome message? - Зберегти вітальне повідомлення? + + Migrations: %@ + Міграції: %@ No comment provided by engineer. - - Revoke file - Відкликати файл - cancel file action + + Moderate + Модерується + chat item action - - Save auto-accept settings - Зберегти налаштування автоприйому + + Moderated at + Модерується на No comment provided by engineer. - - Self-destruct - Самознищення - No comment provided by engineer. - - - Self-destruct passcode - Пароль самознищення - No comment provided by engineer. - - + Moderated at: %@ - Модерується за: %@ + Модерується за: %@ copied message info - - Only you can add message reactions. - Тільки ви можете додавати реакції на повідомлення. + + More improvements are coming soon! + Незабаром буде ще більше покращень! No comment provided by engineer. - - Only your contact can add message reactions. - Тільки ваш контакт може додавати реакції на повідомлення. + + Most likely this connection is deleted. + Швидше за все, це з'єднання видалено. + item status description + + + Most likely this contact has deleted the connection with you. + Швидше за все, цей контакт видалив зв'язок з вами. No comment provided by engineer. - - React... - Реагувати... - chat item menu - - - Received message - Отримано повідомлення - message info title - - - Record updated at - Запис оновлено за + + Multiple chat profiles + Кілька профілів чату No comment provided by engineer. - - Record updated at: %@ - Запис оновлено за: %@ - copied message info - - - Revoke - Відкликати + + Mute + Вимкнути звук No comment provided by engineer. - - Revoke file? - Відкликати файл? - No comment provided by engineer. - - - Save profile password - Зберегти пароль профілю - No comment provided by engineer. - - - Select - Виберіть - No comment provided by engineer. - - - Self-destruct passcode enabled! - Пароль самознищення ввімкнено! - No comment provided by engineer. - - - Send disappearing message - Надіслати зникаюче повідомлення - No comment provided by engineer. - - + Muted when inactive! - Вимкнено, коли неактивний! + Вимкнено, коли неактивний! No comment provided by engineer. - + + Name + Ім'я + No comment provided by engineer. + + + Network & servers + Мережа та сервери + No comment provided by engineer. + + + Network settings + Налаштування мережі + No comment provided by engineer. + + + Network status + Стан мережі + No comment provided by engineer. + + + New Passcode + Новий пароль + No comment provided by engineer. + + + New contact request + Новий запит на контакт + notification + + + New contact: + Новий контакт: + notification + + + New database archive + Новий архів бази даних + No comment provided by engineer. + + + New desktop app! + No comment provided by engineer. + + + New display name + Нове ім'я відображення + No comment provided by engineer. + + + New in %@ + Нове в %@ + No comment provided by engineer. + + + New member role + Нова роль учасника + No comment provided by engineer. + + + New message + Нове повідомлення + notification + + + New passphrase… + Новий пароль… + No comment provided by engineer. + + + No + Ні + No comment provided by engineer. + + No app password - Немає пароля програми + Немає пароля програми Authentication unavailable - - Off - Вимкнено + + No contacts selected + Не вибрано жодного контакту No comment provided by engineer. - - Passcode changed! - Пароль змінено! + + No contacts to add + Немає контактів для додавання No comment provided by engineer. - - Passcode - Пароль + + No delivery information + Немає інформації про доставку No comment provided by engineer. - - Passcode entry - Введення пароля + + No device token! + Токен пристрою відсутній! No comment provided by engineer. - - Passcode not changed! - Пароль не змінено! + + No filtered chats + Немає фільтрованих чатів No comment provided by engineer. - - Passcode set! - Пароль встановлено! + + Group not found! + Групу не знайдено! No comment provided by engineer. - - Password to show - Показати пароль + + No history + Немає історії No comment provided by engineer. - - Protect your chat profiles with a password! - Захистіть свої профілі чату паролем! + + No permission to record voice message + Немає дозволу на запис голосового повідомлення No comment provided by engineer. - - Save and update group profile - Збереження та оновлення профілю групи + + No received or sent files + Немає отриманих або відправлених файлів No comment provided by engineer. - - New display name - Нове ім'я відображення + + Notifications + Сповіщення No comment provided by engineer. - - Prohibit message reactions. - Заборонити реакцію на повідомлення. + + Notifications are disabled! + Сповіщення вимкнено! No comment provided by engineer. - - Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). - Читайте більше в [Посібнику користувача](https://simplex.chat/docs/guide/readme.html#connect-to-friends). - No comment provided by engineer. - - - Receiving file will be stopped. - Отримання файлу буде зупинено. - No comment provided by engineer. - - - Save servers? - Зберегти сервери? - No comment provided by engineer. - - - Save settings? - Зберегти налаштування? - No comment provided by engineer. - - - Permanent decryption error - Постійна помилка розшифрування - message decrypt error item - - - Please report it to the developers. - Будь ласка, повідомте про це розробникам. - No comment provided by engineer. - - - Polish interface - Польський інтерфейс - No comment provided by engineer. - - - Preview - Попередній перегляд - No comment provided by engineer. - - - Profile password - Пароль до профілю - No comment provided by engineer. - - - Prohibit audio/video calls. - Заборонити аудіо/відеодзвінки. - No comment provided by engineer. - - - Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). - Читайте більше в [Посібнику користувача](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). - No comment provided by engineer. - - - Moderated at - Модерується на - No comment provided by engineer. - - - Opening database… - Відкриття бази даних… - No comment provided by engineer. - - - Prohibit messages reactions. - Заборонити реакції на повідомлення. - No comment provided by engineer. - - - Received at - Отримано за - No comment provided by engineer. - - - Read more - Читати далі - No comment provided by engineer. - - - Received at: %@ - Отримано за: %@ - copied message info - - - Self-destruct passcode changed! - Пароль самознищення змінено! - No comment provided by engineer. - - - Migrations: %@ - Міграції: %@ - No comment provided by engineer. - - + Now admins can: - delete members' messages. - disable members ("observer" role) - Тепер адміністратори можуть + Тепер адміністратори можуть - видаляти повідомлення користувачів. - відключати користувачів (роль "спостерігач") No comment provided by engineer. - - Profile update will be sent to your contacts. - Оновлення профілю буде надіслано вашим контактам. + + Off + Вимкнено No comment provided by engineer. - - Receiving address will be changed to a different server. Address change will complete after sender comes online. - Адреса отримувача буде змінена на інший сервер. Зміна адреси завершиться після того, як відправник з'явиться в мережі. + + Off (Local) + Вимкнено (локально) No comment provided by engineer. - - Some non-fatal errors occurred during import - you may see Chat console for more details. - Під час імпорту виникли деякі нефатальні помилки – ви можете переглянути консоль чату, щоб дізнатися більше. + + Ok + Гаразд No comment provided by engineer. - - Show: - Показати: + + Old database + Стара база даних No comment provided by engineer. - - SimpleX Address - Адреса SimpleX + + Old database archive + Старий архів бази даних No comment provided by engineer. - - Stop file - Зупинити файл - cancel file action - - - There should be at least one user profile. - Повинен бути принаймні один профіль користувача. + + One-time invitation link + Посилання на одноразове запрошення No comment provided by engineer. - - Unfav. - Нелюб. + + Onion hosts will be required for connection. Requires enabling VPN. + Для підключення будуть потрібні хости onion. Потрібно увімкнути VPN. No comment provided by engineer. - - Server requires authorization to upload, check password - Сервер вимагає авторизації для завантаження, перевірте пароль - server test error - - - SimpleX Lock mode - Режим SimpleX Lock + + Onion hosts will be used when available. Requires enabling VPN. + Onion хости будуть використовуватися, коли вони будуть доступні. Потрібно увімкнути VPN. No comment provided by engineer. - - Submit - Надіслати + + Onion hosts will not be used. + Onion хости не будуть використовуватися. No comment provided by engineer. - - System authentication - Автентифікація системи + + Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**. + Тільки клієнтські пристрої зберігають профілі користувачів, контакти, групи та повідомлення, надіслані за допомогою **2-шарового наскрізного шифрування**. No comment provided by engineer. - - Tap to activate profile. - Натисніть, щоб активувати профіль. + + Only group owners can change group preferences. + Тільки власники груп можуть змінювати налаштування групи. No comment provided by engineer. - - There should be at least one visible user profile. - Повинен бути принаймні один видимий профіль користувача. + + Only group owners can enable files and media. + Тільки власники груп можуть вмикати файли та медіа. No comment provided by engineer. - - Unhide chat profile - Показати профіль чату + + Only group owners can enable voice messages. + Тільки власники груп можуть вмикати голосові повідомлення. No comment provided by engineer. - - Unhide profile - Показати профіль + + Only you can add message reactions. + Тільки ви можете додавати реакції на повідомлення. No comment provided by engineer. - - Unlock app - Розблокувати додаток + + Only you can irreversibly delete messages (your contact can mark them for deletion). + Тільки ви можете безповоротно видалити повідомлення (ваш контакт може позначити їх для видалення). + No comment provided by engineer. + + + Only you can make calls. + Дзвонити можете тільки ви. + No comment provided by engineer. + + + Only you can send disappearing messages. + Тільки ви можете надсилати зникаючі повідомлення. + No comment provided by engineer. + + + Only you can send voice messages. + Тільки ви можете надсилати голосові повідомлення. + No comment provided by engineer. + + + Only your contact can add message reactions. + Тільки ваш контакт може додавати реакції на повідомлення. + No comment provided by engineer. + + + Only your contact can irreversibly delete messages (you can mark them for deletion). + Тільки ваш контакт може безповоротно видалити повідомлення (ви можете позначити їх для видалення). + No comment provided by engineer. + + + Only your contact can make calls. + Тільки ваш контакт може здійснювати дзвінки. + No comment provided by engineer. + + + Only your contact can send disappearing messages. + Тільки ваш контакт може надсилати зникаючі повідомлення. + No comment provided by engineer. + + + Only your contact can send voice messages. + Тільки ваш контакт може надсилати голосові повідомлення. + No comment provided by engineer. + + + Open + No comment provided by engineer. + + + Open Settings + Відкрийте Налаштування + No comment provided by engineer. + + + Open chat + Відкритий чат + No comment provided by engineer. + + + Open chat console + Відкрийте консоль чату authentication reason - - Sent message - Надіслано повідомлення - message info title + + Open user profiles + Відкрити профілі користувачів + authentication reason - - Set it instead of system authentication. - Встановіть його замість аутентифікації системи. + + Open-source protocol and code – anybody can run the servers. + Протокол і код з відкритим вихідним кодом - будь-хто може запускати сервери. No comment provided by engineer. - - Share 1-time link - Поділитися 1-разовим посиланням + + Opening database… + Відкриття бази даних… No comment provided by engineer. - - Share with contacts - Поділіться з контактами + + Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. + Відкриття посилання в браузері може знизити конфіденційність і безпеку з'єднання. Ненадійні посилання SimpleX будуть червоного кольору. No comment provided by engineer. - - SimpleX address - Адреса SimpleX + + PING count + Кількість PING No comment provided by engineer. - - Stop sharing - Припиніть ділитися + + PING interval + Інтервал PING No comment provided by engineer. - - Stop sharing address? - Припинити ділитися адресою? + + Passcode + Пароль No comment provided by engineer. - - The hash of the previous message is different. - Хеш попереднього повідомлення відрізняється. + + Passcode changed! + Пароль змінено! No comment provided by engineer. - - This error is permanent for this connection, please re-connect. - Ця помилка є постійною для цього з'єднання, будь ласка, перепідключіться. + + Passcode entry + Введення пароля No comment provided by engineer. - - Unhide - Показати + + Passcode not changed! + Пароль не змінено! No comment provided by engineer. - - Sent at - Надіслано за + + Passcode set! + Пароль встановлено! No comment provided by engineer. - - Sent at: %@ - Надіслано за: %@ + + Password to show + Показати пароль + No comment provided by engineer. + + + Paste + Вставити + No comment provided by engineer. + + + Paste image + Вставити зображення + No comment provided by engineer. + + + Paste received link + Вставте отримане посилання + No comment provided by engineer. + + + Paste the link you received to connect with your contact. + Вставте отримане посилання для зв'язку з вашим контактом. + placeholder + + + People can connect to you only via the links you share. + Люди можуть зв'язатися з вами лише за посиланнями, якими ви ділитеся. + No comment provided by engineer. + + + Periodically + Періодично + No comment provided by engineer. + + + Permanent decryption error + Постійна помилка розшифрування + message decrypt error item + + + Please ask your contact to enable sending voice messages. + Будь ласка, попросіть вашого контакту увімкнути відправку голосових повідомлень. + No comment provided by engineer. + + + Please check that you used the correct link or ask your contact to send you another one. + Будь ласка, перевірте, чи ви скористалися правильним посиланням, або попросіть контактну особу надіслати вам інше. + No comment provided by engineer. + + + Please check your network connection with %@ and try again. + Будь ласка, перевірте підключення до мережі за допомогою %@ і спробуйте ще раз. + No comment provided by engineer. + + + Please check yours and your contact preferences. + Будь ласка, перевірте свої та контактні налаштування. + No comment provided by engineer. + + + Please contact group admin. + Зверніться до адміністратора групи. + No comment provided by engineer. + + + Please enter correct current passphrase. + Будь ласка, введіть правильний поточний пароль. + No comment provided by engineer. + + + Please enter the previous password after restoring database backup. This action can not be undone. + Будь ласка, введіть попередній пароль після відновлення резервної копії бази даних. Ця дія не може бути скасована. + No comment provided by engineer. + + + Please remember or store it securely - there is no way to recover a lost passcode! + Будь ласка, запам'ятайте або надійно зберігайте його - втрачений пароль неможливо відновити! + No comment provided by engineer. + + + Please report it to the developers. + Будь ласка, повідомте про це розробникам. + No comment provided by engineer. + + + Please restart the app and migrate the database to enable push notifications. + Будь ласка, перезапустіть додаток і перенесіть базу даних, щоб увімкнути push-сповіщення. + No comment provided by engineer. + + + Please store passphrase securely, you will NOT be able to access chat if you lose it. + Будь ласка, зберігайте пароль надійно, ви НЕ зможете отримати доступ до чату, якщо втратите його. + No comment provided by engineer. + + + Please store passphrase securely, you will NOT be able to change it if you lose it. + Будь ласка, зберігайте пароль надійно, ви НЕ зможете змінити його, якщо втратите. + No comment provided by engineer. + + + Polish interface + Польський інтерфейс + No comment provided by engineer. + + + Possibly, certificate fingerprint in server address is incorrect + Можливо, в адресі сервера неправильно вказано відбиток сертифіката + server test error + + + Preserve the last message draft, with attachments. + Зберегти чернетку останнього повідомлення з вкладеннями. + No comment provided by engineer. + + + Preset server + Попередньо встановлений сервер + No comment provided by engineer. + + + Preset server address + Попередньо встановлена адреса сервера + No comment provided by engineer. + + + Preview + Попередній перегляд + No comment provided by engineer. + + + Privacy & security + Конфіденційність і безпека + No comment provided by engineer. + + + Privacy redefined + Конфіденційність переглянута + No comment provided by engineer. + + + Private filenames + Приватні імена файлів + No comment provided by engineer. + + + Profile and server connections + З'єднання профілю та сервера + No comment provided by engineer. + + + Profile image + Зображення профілю + No comment provided by engineer. + + + Profile password + Пароль до профілю + No comment provided by engineer. + + + Profile update will be sent to your contacts. + Оновлення профілю буде надіслано вашим контактам. + No comment provided by engineer. + + + Prohibit audio/video calls. + Заборонити аудіо/відеодзвінки. + No comment provided by engineer. + + + Prohibit irreversible message deletion. + Заборонити незворотне видалення повідомлень. + No comment provided by engineer. + + + Prohibit message reactions. + Заборонити реакцію на повідомлення. + No comment provided by engineer. + + + Prohibit messages reactions. + Заборонити реакції на повідомлення. + No comment provided by engineer. + + + Prohibit sending direct messages to members. + Заборонити надсилати прямі повідомлення учасникам. + No comment provided by engineer. + + + Prohibit sending disappearing messages. + Заборонити надсилання зникаючих повідомлень. + No comment provided by engineer. + + + Prohibit sending files and media. + Заборонити надсилання файлів і медіа. + No comment provided by engineer. + + + Prohibit sending voice messages. + Заборонити надсилання голосових повідомлень. + No comment provided by engineer. + + + Protect app screen + Захистіть екран програми + No comment provided by engineer. + + + Protect your chat profiles with a password! + Захистіть свої профілі чату паролем! + No comment provided by engineer. + + + Protocol timeout + Тайм-аут протоколу + No comment provided by engineer. + + + Protocol timeout per KB + Тайм-аут протоколу на КБ + No comment provided by engineer. + + + Push notifications + Push-повідомлення + No comment provided by engineer. + + + Rate the app + Оцініть додаток + No comment provided by engineer. + + + React… + Реагуй… + chat item menu + + + Read + Читати + No comment provided by engineer. + + + Read more + Читати далі + No comment provided by engineer. + + + Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). + Читайте більше в [Посібнику користувача](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). + No comment provided by engineer. + + + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). + Читайте більше в [Посібнику користувача](https://simplex.chat/docs/guide/readme.html#connect-to-friends). + No comment provided by engineer. + + + Read more in our GitHub repository. + Читайте більше в нашому репозиторії на GitHub. + No comment provided by engineer. + + + Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme). + Читайте більше в нашому [GitHub репозиторії](https://github.com/simplex-chat/simplex-chat#readme). + No comment provided by engineer. + + + Receipts are disabled + Підтвердження виключені + No comment provided by engineer. + + + Received at + Отримано за + No comment provided by engineer. + + + Received at: %@ + Отримано за: %@ copied message info - + + Received file event + Подія отримання файлу + notification + + + Received message + Отримано повідомлення + message info title + + + Receiving address will be changed to a different server. Address change will complete after sender comes online. + Адреса отримувача буде змінена на інший сервер. Зміна адреси завершиться після того, як відправник з'явиться в мережі. + No comment provided by engineer. + + + Receiving file will be stopped. + Отримання файлу буде зупинено. + No comment provided by engineer. + + + Receiving via + Отримання через + No comment provided by engineer. + + + Recipients see updates as you type them. + Одержувачі бачать оновлення, коли ви їх вводите. + No comment provided by engineer. + + + Reconnect all connected servers to force message delivery. It uses additional traffic. + Перепідключіть всі підключені сервери, щоб примусово доставити повідомлення. Це використовує додатковий трафік. + No comment provided by engineer. + + + Reconnect servers? + Перепідключити сервери? + No comment provided by engineer. + + + Record updated at + Запис оновлено за + No comment provided by engineer. + + + Record updated at: %@ + Запис оновлено за: %@ + copied message info + + + Reduced battery usage + Зменшення використання акумулятора + No comment provided by engineer. + + + Reject + Відхилити + reject incoming call via notification + + + Reject (sender NOT notified) + Відхилити (відправника НЕ повідомлено) + No comment provided by engineer. + + + Reject contact request + Відхилити запит на контакт + No comment provided by engineer. + + + Relay server is only used if necessary. Another party can observe your IP address. + Релейний сервер використовується тільки в разі потреби. Інша сторона може бачити вашу IP-адресу. + No comment provided by engineer. + + + Relay server protects your IP address, but it can observe the duration of the call. + Сервер ретрансляції захищає вашу IP-адресу, але він може спостерігати за тривалістю дзвінка. + No comment provided by engineer. + + + Remove + Видалити + No comment provided by engineer. + + + Remove member + Видалити учасника + No comment provided by engineer. + + + Remove member? + Видалити учасника? + No comment provided by engineer. + + + Remove passphrase from keychain? + Видалити парольну фразу з брелока? + No comment provided by engineer. + + + Renegotiate + Переузгодьте + No comment provided by engineer. + + + Renegotiate encryption + Переузгодьте шифрування + No comment provided by engineer. + + + Renegotiate encryption? + Переузгодьте шифрування? + No comment provided by engineer. + + + Reply + Відповісти + chat item action + + + Required + Потрібно + No comment provided by engineer. + + + Reset + Перезавантаження + No comment provided by engineer. + + + Reset colors + Скинути кольори + No comment provided by engineer. + + + Reset to defaults + Відновити налаштування за замовчуванням + No comment provided by engineer. + + + Restart the app to create a new chat profile + Перезапустіть програму, щоб створити новий профіль чату + No comment provided by engineer. + + + Restart the app to use imported chat database + Перезапустіть програму, щоб використовувати імпортовану базу даних чату + No comment provided by engineer. + + + Restore + Відновити + No comment provided by engineer. + + + Restore database backup + Відновлення резервної копії бази даних + No comment provided by engineer. + + + Restore database backup? + Відновити резервну копію бази даних? + No comment provided by engineer. + + + Restore database error + Відновлення помилки бази даних + No comment provided by engineer. + + + Reveal + Показувати + chat item action + + + Revert + Повернутися + No comment provided by engineer. + + + Revoke + Відкликати + No comment provided by engineer. + + + Revoke file + Відкликати файл + cancel file action + + + Revoke file? + Відкликати файл? + No comment provided by engineer. + + + Role + Роль + No comment provided by engineer. + + + Run chat + Запустити чат + No comment provided by engineer. + + + SMP servers + Сервери SMP + No comment provided by engineer. + + + Save + Зберегти + chat item action + + + Save (and notify contacts) + Зберегти (і повідомити контактам) + No comment provided by engineer. + + + Save and notify contact + Зберегти та повідомити контакт + No comment provided by engineer. + + + Save and notify group members + Зберегти та повідомити учасників групи + No comment provided by engineer. + + + Save and update group profile + Збереження та оновлення профілю групи + No comment provided by engineer. + + + Save archive + Зберегти архів + No comment provided by engineer. + + + Save auto-accept settings + Зберегти налаштування автоприйому + No comment provided by engineer. + + + Save group profile + Зберегти профіль групи + No comment provided by engineer. + + + Save passphrase and open chat + Збережіть пароль і відкрийте чат + No comment provided by engineer. + + + Save passphrase in Keychain + Збережіть парольну фразу в Keychain + No comment provided by engineer. + + + Save preferences? + Зберегти налаштування? + No comment provided by engineer. + + + Save profile password + Зберегти пароль профілю + No comment provided by engineer. + + + Save servers + Зберегти сервери + No comment provided by engineer. + + + Save servers? + Зберегти сервери? + No comment provided by engineer. + + + Save settings? + Зберегти налаштування? + No comment provided by engineer. + + + Save welcome message? + Зберегти вітальне повідомлення? + No comment provided by engineer. + + + Saved WebRTC ICE servers will be removed + Збережені сервери WebRTC ICE буде видалено + No comment provided by engineer. + + + Scan QR code + Відскануйте QR-код + No comment provided by engineer. + + + Scan code + Сканувати код + No comment provided by engineer. + + + Scan security code from your contact's app. + Відскануйте код безпеки з додатку вашого контакту. + No comment provided by engineer. + + + Scan server QR code + Відскануйте QR-код сервера + No comment provided by engineer. + + + Search + Пошук + No comment provided by engineer. + + + Secure queue + Безпечна черга + server test step + + + Security assessment + Оцінка безпеки + No comment provided by engineer. + + + Security code + Код безпеки + No comment provided by engineer. + + + Select + Виберіть + No comment provided by engineer. + + + Self-destruct + Самознищення + No comment provided by engineer. + + + Self-destruct passcode + Пароль самознищення + No comment provided by engineer. + + + Self-destruct passcode changed! + Пароль самознищення змінено! + No comment provided by engineer. + + + Self-destruct passcode enabled! + Пароль самознищення ввімкнено! + No comment provided by engineer. + + + Send + Надіслати + No comment provided by engineer. + + + Send a live message - it will update for the recipient(s) as you type it + Надішліть повідомлення в реальному часі - воно буде оновлюватися для одержувача (одержувачів), поки ви його вводите + No comment provided by engineer. + + + Send delivery receipts to + Надсилання звітів про доставку + No comment provided by engineer. + + + Send direct message + Надішліть пряме повідомлення + No comment provided by engineer. + + + Send direct message to connect + No comment provided by engineer. + + + Send disappearing message + Надіслати зникаюче повідомлення + No comment provided by engineer. + + + Send link previews + Надіслати попередній перегляд за посиланням + No comment provided by engineer. + + + Send live message + Надіслати живе повідомлення + No comment provided by engineer. + + + Send notifications + Надсилати сповіщення + No comment provided by engineer. + + + Send notifications: + Надсилати сповіщення: + No comment provided by engineer. + + + Send questions and ideas + Надсилайте запитання та ідеї + No comment provided by engineer. + + + Send receipts + Надіслати підтвердження + No comment provided by engineer. + + + Send them from gallery or custom keyboards. + Надсилайте їх із галереї чи власних клавіатур. + No comment provided by engineer. + + + Sender cancelled file transfer. + Відправник скасував передачу файлу. + No comment provided by engineer. + + + Sender may have deleted the connection request. + Можливо, відправник видалив запит на підключення. + No comment provided by engineer. + + + Sending delivery receipts will be enabled for all contacts in all visible chat profiles. + Надсилання підтверджень доставки буде ввімкнено для всіх контактів у всіх видимих профілях чату. + No comment provided by engineer. + + + Sending delivery receipts will be enabled for all contacts. + Надсилання підтверджень доставки буде ввімкнено для всіх контактів. + No comment provided by engineer. + + + Sending file will be stopped. + Надсилання файлу буде зупинено. + No comment provided by engineer. + + + Sending receipts is disabled for %lld contacts + Надсилання підтвердження вимкнено для контактів %lld + No comment provided by engineer. + + + Sending receipts is disabled for %lld groups + Відправлення підтверджень вимкнено для груп %lld + No comment provided by engineer. + + + Sending receipts is enabled for %lld contacts + Для контактів %lld увімкнено надсилання підтвердження + No comment provided by engineer. + + + Sending receipts is enabled for %lld groups + Для груп %lld увімкнено надсилання підтвердження + No comment provided by engineer. + + + Sending via + Надсилання через + No comment provided by engineer. + + + Sent at + Надіслано за + No comment provided by engineer. + + + Sent at: %@ + Надіслано за: %@ + copied message info + + + Sent file event + Подія надісланого файлу + notification + + + Sent message + Надіслано повідомлення + message info title + + + Sent messages will be deleted after set time. + Надіслані повідомлення будуть видалені через встановлений час. + No comment provided by engineer. + + + Server requires authorization to create queues, check password + Сервер вимагає авторизації для створення черг, перевірте пароль + server test error + + + Server requires authorization to upload, check password + Сервер вимагає авторизації для завантаження, перевірте пароль + server test error + + + Server test failed! + Тест сервера завершився невдало! + No comment provided by engineer. + + + Servers + Сервери + No comment provided by engineer. + + + Set 1 day + Встановити 1 день + No comment provided by engineer. + + + Set contact name… + Встановити ім'я контакту… + No comment provided by engineer. + + + Set group preferences + Встановіть налаштування групи + No comment provided by engineer. + + + Set it instead of system authentication. + Встановіть його замість аутентифікації системи. + No comment provided by engineer. + + + Set passcode + Встановити пароль + No comment provided by engineer. + + + Set passphrase to export + Встановити ключову фразу для експорту + No comment provided by engineer. + + Set the message shown to new members! - Налаштуйте повідомлення, яке показуватиметься новим користувачам! + Налаштуйте повідомлення, яке показуватиметься новим користувачам! No comment provided by engineer. - + + Set timeouts for proxy/VPN + Встановлення таймаутів для проксі/VPN + No comment provided by engineer. + + + Settings + Налаштування + No comment provided by engineer. + + + Share + Поділіться + chat item action + + + Share 1-time link + Поділитися 1-разовим посиланням + No comment provided by engineer. + + + Share address + Поділитися адресою + No comment provided by engineer. + + + Share address with contacts? + Поділіться адресою з контактами? + No comment provided by engineer. + + + Share link + Поділіться посиланням + No comment provided by engineer. + + + Share one-time invitation link + Поділіться посиланням на одноразове запрошення + No comment provided by engineer. + + + Share with contacts + Поділіться з контактами + No comment provided by engineer. + + + Show calls in phone history + Показувати дзвінки в історії дзвінків + No comment provided by engineer. + + Show developer options - Показати опції розробника + Показати опції розробника No comment provided by engineer. - + + Show last messages + Показати останні повідомлення + No comment provided by engineer. + + + Show preview + Показати попередній перегляд + No comment provided by engineer. + + + Show: + Показати: + No comment provided by engineer. + + + SimpleX Address + Адреса SimpleX + No comment provided by engineer. + + + SimpleX Chat security was audited by Trail of Bits. + Безпека SimpleX Chat була перевірена компанією Trail of Bits. + No comment provided by engineer. + + + SimpleX Lock + SimpleX Lock + No comment provided by engineer. + + + SimpleX Lock mode + Режим SimpleX Lock + No comment provided by engineer. + + + SimpleX Lock not enabled! + SimpleX Lock не ввімкнено! + No comment provided by engineer. + + + SimpleX Lock turned on + SimpleX Lock увімкнено + No comment provided by engineer. + + + SimpleX address + Адреса SimpleX + No comment provided by engineer. + + + SimpleX contact address + Контактна адреса SimpleX + simplex link type + + + SimpleX encrypted message or connection event + Зашифроване повідомлення SimpleX або подія підключення + notification + + + SimpleX group link + Посилання на групу SimpleX + simplex link type + + + SimpleX links + Посилання SimpleX + No comment provided by engineer. + + + SimpleX one-time invitation + Одноразове запрошення SimpleX + simplex link type + + + Simplified incognito mode + No comment provided by engineer. + + + Skip + Пропустити + No comment provided by engineer. + + + Skipped messages + Пропущені повідомлення + No comment provided by engineer. + + + Small groups (max 20) + Невеликі групи (максимум 20 осіб) + No comment provided by engineer. + + + Some non-fatal errors occurred during import - you may see Chat console for more details. + Під час імпорту виникли деякі нефатальні помилки – ви можете переглянути консоль чату, щоб дізнатися більше. + No comment provided by engineer. + + + Somebody + Хтось + notification title + + + Start a new chat + Почніть новий чат + No comment provided by engineer. + + + Start chat + Почати чат + No comment provided by engineer. + + + Start migration + Почати міграцію + No comment provided by engineer. + + + Stop + Зупинити + No comment provided by engineer. + + + Stop SimpleX + Зупинити SimpleX + authentication reason + + + Stop chat to enable database actions + Зупиніть чат, щоб увімкнути дії з базою даних + No comment provided by engineer. + + + Stop chat to export, import or delete chat database. You will not be able to receive and send messages while the chat is stopped. + Зупиніть чат, щоб експортувати, імпортувати або видалити базу даних чату. Ви не зможете отримувати та надсилати повідомлення, поки чат зупинено. + No comment provided by engineer. + + + Stop chat? + Зупинити чат? + No comment provided by engineer. + + + Stop file + Зупинити файл + cancel file action + + + Stop receiving file? + Припинити отримання файлу? + No comment provided by engineer. + + + Stop sending file? + Припинити надсилання файлу? + No comment provided by engineer. + + + Stop sharing + Припиніть ділитися + No comment provided by engineer. + + + Stop sharing address? + Припинити ділитися адресою? + No comment provided by engineer. + + + Submit + Надіслати + No comment provided by engineer. + + + Support SimpleX Chat + Підтримка чату SimpleX + No comment provided by engineer. + + + System + Система + No comment provided by engineer. + + + System authentication + Автентифікація системи + No comment provided by engineer. + + + TCP connection timeout + Тайм-аут TCP-з'єднання + No comment provided by engineer. + + + TCP_KEEPCNT + TCP_KEEPCNT + No comment provided by engineer. + + + TCP_KEEPIDLE + TCP_KEEPIDLE + No comment provided by engineer. + + + TCP_KEEPINTVL + TCP_KEEPINTVL + No comment provided by engineer. + + + Take picture + Сфотографуйте + No comment provided by engineer. + + + Tap button + Натисніть кнопку + No comment provided by engineer. + + + Tap to activate profile. + Натисніть, щоб активувати профіль. + No comment provided by engineer. + + + Tap to join + Натисніть, щоб приєднатися + No comment provided by engineer. + + + Tap to join incognito + Натисніть, щоб приєднатися інкогніто + No comment provided by engineer. + + + Tap to start a new chat + Натисніть, щоб почати новий чат + No comment provided by engineer. + + + Test failed at step %@. + Тест завершився невдало на кроці %@. + server test failure + + + Test server + Тестовий сервер + No comment provided by engineer. + + + Test servers + Тестові сервери + No comment provided by engineer. + + + Tests failed! + Тести не пройшли! + No comment provided by engineer. + + + Thank you for installing SimpleX Chat! + Дякуємо, що встановили SimpleX Chat! + No comment provided by engineer. + + + Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + Дякуємо користувачам - [внесок через Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + No comment provided by engineer. + + + Thanks to the users – contribute via Weblate! + Дякуємо користувачам - зробіть свій внесок через Weblate! + No comment provided by engineer. + + + The 1st platform without any user identifiers – private by design. + Перша платформа без жодних ідентифікаторів користувачів – приватна за дизайном. + No comment provided by engineer. + + The ID of the next message is incorrect (less or equal to the previous). It can happen because of some bug or when the connection is compromised. - Ідентифікатор наступного повідомлення неправильний (менше або дорівнює попередньому). + Ідентифікатор наступного повідомлення неправильний (менше або дорівнює попередньому). Це може статися через помилку або коли з'єднання скомпрометовано. No comment provided by engineer. - - Sending file will be stopped. - Надсилання файлу буде зупинено. + + The app can notify you when you receive messages or contact requests - please open settings to enable. + Додаток може сповіщати вас, коли ви отримуєте повідомлення або запити на контакт - будь ласка, відкрийте налаштування, щоб увімкнути цю функцію. No comment provided by engineer. - - Set passcode - Встановити пароль + + The attempt to change database passphrase was not completed. + Спроба змінити пароль до бази даних не була завершена. No comment provided by engineer. - - Share address with contacts? - Поділіться адресою з контактами? + + The connection you accepted will be cancelled! + Прийняте вами з'єднання буде скасовано! No comment provided by engineer. - - Share address - Поділитися адресою + + The contact you shared this link with will NOT be able to connect! + Контакт, з яким ви поділилися цим посиланням, НЕ зможе підключитися! No comment provided by engineer. - - SimpleX Lock not enabled! - SimpleX Lock не ввімкнено! + + The created archive is available via app Settings / Database / Old database archive. + Створений архів доступний через Налаштування програми / База даних / Старий архів бази даних. No comment provided by engineer. - - Stop receiving file? - Припинити отримання файлу? + + The encryption is working and the new encryption agreement is not required. It may result in connection errors! + Шифрування працює і нова угода про шифрування не потрібна. Це може призвести до помилок з'єднання! No comment provided by engineer. - - Stop sending file? - Припинити надсилання файлу? + + The group is fully decentralized – it is visible only to the members. + Група повністю децентралізована - її бачать лише учасники. No comment provided by engineer. - + + The hash of the previous message is different. + Хеш попереднього повідомлення відрізняється. + No comment provided by engineer. + + + The message will be deleted for all members. + Повідомлення буде видалено для всіх учасників. + No comment provided by engineer. + + + The message will be marked as moderated for all members. + Повідомлення буде позначено як модероване для всіх учасників. + No comment provided by engineer. + + + The next generation of private messaging + Наступне покоління приватних повідомлень + No comment provided by engineer. + + + The old database was not removed during the migration, it can be deleted. + Стара база даних не була видалена під час міграції, її можна видалити. + No comment provided by engineer. + + + The profile is only shared with your contacts. + Профіль доступний лише вашим контактам. + No comment provided by engineer. + + + The second tick we missed! ✅ + Другу галочку ми пропустили! ✅ + No comment provided by engineer. + + + The sender will NOT be notified + Відправник НЕ буде повідомлений + No comment provided by engineer. + + + The servers for new connections of your current chat profile **%@**. + Сервери для нових підключень вашого поточного профілю чату **%@**. + No comment provided by engineer. + + + Theme + Тема + No comment provided by engineer. + + + There should be at least one user profile. + Повинен бути принаймні один профіль користувача. + No comment provided by engineer. + + + There should be at least one visible user profile. + Повинен бути принаймні один видимий профіль користувача. + No comment provided by engineer. + + + These settings are for your current profile **%@**. + Ці налаштування стосуються вашого поточного профілю **%@**. + No comment provided by engineer. + + + They can be overridden in contact and group settings. + Їх можна перевизначити в налаштуваннях контактів і груп. + No comment provided by engineer. + + + This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain. + Цю дію неможливо скасувати - всі отримані та надіслані файли і медіа будуть видалені. Зображення з низькою роздільною здатністю залишаться. + No comment provided by engineer. + + + This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes. + Цю дію неможливо скасувати - повідомлення, надіслані та отримані раніше, ніж вибрані, будуть видалені. Це може зайняти кілька хвилин. + No comment provided by engineer. + + + This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost. + Цю дію неможливо скасувати - ваш профіль, контакти, повідомлення та файли будуть безповоротно втрачені. + No comment provided by engineer. + + + This group has over %lld members, delivery receipts are not sent. + У цій групі більше %lld учасників, підтвердження доставки не надсилаються. + No comment provided by engineer. + + + This group no longer exists. + Цієї групи більше не існує. + No comment provided by engineer. + + + This setting applies to messages in your current chat profile **%@**. + Це налаштування застосовується до повідомлень у вашому поточному профілі чату **%@**. + No comment provided by engineer. + + + To ask any questions and to receive updates: + Задати будь-які питання та отримувати новини: + No comment provided by engineer. + + To connect, your contact can scan QR code or use the link in the app. - Щоб підключитися, ваш контакт може відсканувати QR-код або скористатися посиланням у додатку. + Щоб підключитися, ваш контакт може відсканувати QR-код або скористатися посиланням у додатку. No comment provided by engineer. - + + To make a new connection + Щоб створити нове з'єднання + No comment provided by engineer. + + + To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts. + Щоб захистити конфіденційність, замість ідентифікаторів користувачів, які використовуються на всіх інших платформах, SimpleX має ідентифікатори для черг повідомлень, окремі для кожного з ваших контактів. + No comment provided by engineer. + + + To protect timezone, image/voice files use UTC. + Для захисту часового поясу у файлах зображень/голосу використовується UTC. + No comment provided by engineer. + + + To protect your information, turn on SimpleX Lock. +You will be prompted to complete authentication before this feature is enabled. + Щоб захистити вашу інформацію, увімкніть SimpleX Lock. +Перед увімкненням цієї функції вам буде запропоновано пройти автентифікацію. + No comment provided by engineer. + + + To record voice message please grant permission to use Microphone. + Щоб записати голосове повідомлення, будь ласка, надайте дозвіл на використання мікрофону. + No comment provided by engineer. + + To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page. - Щоб відкрити свій прихований профіль, введіть повний пароль у поле пошуку на сторінці **Ваші профілі чату**. + Щоб відкрити свій прихований профіль, введіть повний пароль у поле пошуку на сторінці **Ваші профілі чату**. No comment provided by engineer. - - Unit - Одиниця + + To support instant push notifications the chat database has to be migrated. + Для підтримки миттєвих push-повідомлень необхідно перенести базу даних чату. No comment provided by engineer. - - When people request to connect, you can accept or reject it. - Коли люди звертаються із запитом на підключення, ви можете прийняти або відхилити його. + + To verify end-to-end encryption with your contact compare (or scan) the code on your devices. + Щоб перевірити наскрізне шифрування з вашим контактом, порівняйте (або відскануйте) код на ваших пристроях. No comment provided by engineer. - - minutes - хвилини - time unit - - - Allow to send files and media. - Дозволяє надсилати файли та медіа. + + Toggle incognito when connecting. No comment provided by engineer. - - No filtered chats - Немає фільтрованих чатів + + Transport isolation + Транспортна ізоляція No comment provided by engineer. - - Video will be received when your contact completes uploading it. - Відео буде отримано, коли ваш контакт завершить завантаження. + + Trying to connect to the server used to receive messages from this contact (error: %@). + Спроба з'єднатися з сервером, який використовується для отримання повідомлень від цього контакту (помилка: %@). No comment provided by engineer. - - Your SimpleX address - Ваша адреса SimpleX + + Trying to connect to the server used to receive messages from this contact. + Спроба з'єднатися з сервером, який використовується для отримання повідомлень від цього контакту. No comment provided by engineer. - - Upgrade and open chat - Оновлення та відкритий чат + + Turn off + Вимкнути No comment provided by engineer. - - Warning: you may lose some data! - Попередження: ви можете втратити деякі дані! + + Turn off notifications? + Вимкнути сповіщення? No comment provided by engineer. - - XFTP servers - Сервери XFTP + + Turn on + Ввімкнути No comment provided by engineer. - - Your XFTP servers - Ваші XFTP-сервери + + Unable to record voice message + Не вдається записати голосове повідомлення No comment provided by engineer. - - different migration in the app/database: %@ / %@ - різна міграція в додатку/базі даних: %@ / %@ - No comment provided by engineer. - - - # %@ - # %@ - copied message info title, # <title> - - - ## History - ## Історія - copied message info - - - ## In reply to - ## У відповідь на - copied message info - - - A new random profile will be shared. - Буде створено новий випадковий профіль. - No comment provided by engineer. - - - Accept connection request? - Прийняти запит на підключення? - No comment provided by engineer. - - - Connect directly - Підключіться безпосередньо - No comment provided by engineer. - - - Connect incognito - Підключайтеся інкогніто - No comment provided by engineer. - - - Delivery - Доставка - No comment provided by engineer. - - - Disable (keep overrides) - Вимкнути (зберегти перевизначення) - No comment provided by engineer. - - - Disable for all - Вимкнути для всіх - No comment provided by engineer. - - - Don't enable - Не вмикати - No comment provided by engineer. - - - Enable (keep overrides) - Увімкнути (зберегти перевизначення) - No comment provided by engineer. - - - Group members can send files and media. - Учасники групи можуть надсилати файли та медіа. - No comment provided by engineer. - - - Incognito mode protects your privacy by using a new random profile for each contact. - Режим інкогніто захищає вашу конфіденційність, використовуючи новий випадковий профіль для кожного контакту. - No comment provided by engineer. - - - Invalid status - Недійсний статус - item status text - - - Make one message disappear - Зробити так, щоб одне повідомлення зникло - No comment provided by engineer. - - - Migrating database archive… - Перенесення архіву бази даних… - No comment provided by engineer. - - - Most likely this connection is deleted. - Швидше за все, це з'єднання видалено. + + Unexpected error: %@ + Неочікувана помилка: %@ item status description - - No delivery information - Немає інформації про доставку + + Unexpected migration state + Неочікуваний стан міграції No comment provided by engineer. - - Paste the link you received to connect with your contact. - Вставте отримане посилання для зв'язку з вашим контактом. - placeholder - - - Receipts are disabled - Підтвердження виключені + + Unfav. + Нелюб. No comment provided by engineer. - - Reject (sender NOT notified) - Відхилити (відправника НЕ повідомлено) + + Unhide + Показати No comment provided by engineer. - - Sending receipts is disabled for %lld groups - Відправлення підтверджень вимкнено для груп %lld + + Unhide chat profile + Показати профіль чату No comment provided by engineer. - - Small groups (max 20) - Невеликі групи (максимум 20 осіб) + + Unhide profile + Показати профіль No comment provided by engineer. - - They can be overridden in contact and group settings. - Їх можна перевизначити в налаштуваннях контактів і груп. + + Unit + Одиниця No comment provided by engineer. - - This group has over %lld members, delivery receipts are not sent. - У цій групі більше %lld учасників, підтвердження доставки не надсилаються. + + Unknown caller + Невідомий абонент + callkit banner + + + Unknown database error: %@ + Невідома помилка бази даних: %@ No comment provided by engineer. - + + Unknown error + Невідома помилка + No comment provided by engineer. + + + Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions. + Якщо ви не користуєтеся інтерфейсом виклику iOS, увімкніть режим "Не турбувати", щоб уникнути переривань. + No comment provided by engineer. + + + Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. +To connect, please ask your contact to create another connection link and check that you have a stable network connection. + Якщо ваш контакт не видалив з'єднання або якщо це посилання вже використовувалося, це може бути помилкою - будь ласка, повідомте про це. +Щоб підключитися, попросіть вашого контакта створити інше посилання і перевірте, чи маєте ви стабільне з'єднання з мережею. + No comment provided by engineer. + + + Unlock + Розблокувати + No comment provided by engineer. + + + Unlock app + Розблокувати додаток + authentication reason + + + Unmute + Увімкнути звук + No comment provided by engineer. + + + Unread + Непрочитане + No comment provided by engineer. + + + Update + Оновлення + No comment provided by engineer. + + + Update .onion hosts setting? + Оновити налаштування хостів .onion? + No comment provided by engineer. + + + Update database passphrase + Оновити парольну фразу бази даних + No comment provided by engineer. + + + Update network settings? + Оновити налаштування мережі? + No comment provided by engineer. + + + Update transport isolation mode? + Оновити режим транспортної ізоляції? + No comment provided by engineer. + + + Updating settings will re-connect the client to all servers. + Оновлення налаштувань призведе до перепідключення клієнта до всіх серверів. + No comment provided by engineer. + + + Updating this setting will re-connect the client to all servers. + Оновлення цього параметра призведе до перепідключення клієнта до всіх серверів. + No comment provided by engineer. + + + Upgrade and open chat + Оновлення та відкритий чат + No comment provided by engineer. + + Upload file - Завантажити файл + Завантажити файл server test step - + + Use .onion hosts + Використовуйте хости .onion + No comment provided by engineer. + + + Use SimpleX Chat servers? + Використовувати сервери SimpleX Chat? + No comment provided by engineer. + + + Use chat + Використовуйте чат + No comment provided by engineer. + + Use current profile - Використовувати поточний профіль + Використовувати поточний профіль No comment provided by engineer. - + + Use for new connections + Використовуйте для нових з'єднань + No comment provided by engineer. + + + Use iOS call interface + Використовуйте інтерфейс виклику iOS + No comment provided by engineer. + + Use new incognito profile - Використовуйте новий профіль інкогніто + Використовуйте новий профіль інкогніто No comment provided by engineer. - - You can share your address as a link or QR code - anybody can connect to you. - Ви можете поділитися своєю адресою у вигляді посилання або QR-коду - будь-хто зможе зв'язатися з вами. + + Use server + Використовувати сервер No comment provided by engineer. - - You can turn on SimpleX Lock via Settings. - Увімкнути SimpleX Lock можна в Налаштуваннях. + + User profile + Профіль користувача No comment provided by engineer. - - You invited a contact - Ви запросили контакт + + Using .onion hosts requires compatible VPN provider. + Для використання хостів .onion потрібен сумісний VPN-провайдер. No comment provided by engineer. - - Your %@ servers - Ваші сервери %@ + + Using SimpleX Chat servers. + Використання серверів SimpleX Chat. No comment provided by engineer. - - changing address for %@… - зміна адреси для %@… - chat item text - - - disabled - вимкнено + + Verify connection security + Перевірте безпеку з'єднання No comment provided by engineer. - - encryption ok - шифрування ok - chat item text + + Verify security code + Підтвердіть код безпеки + No comment provided by engineer. - - encryption re-negotiation allowed - переузгодження шифрування дозволено - chat item text + + Via browser + Через браузер + No comment provided by engineer. - - months - місяців - time unit + + Video call + Відеодзвінок + No comment provided by engineer. - - no text - без тексту - copied message info in history + + Video will be received when your contact completes uploading it. + Відео буде отримано, коли ваш контакт завершить завантаження. + No comment provided by engineer. - - days - днів - time unit + + Video will be received when your contact is online, please wait or check later! + Відео буде отримано, коли ваш контакт буде онлайн, будь ласка, зачекайте або перевірте пізніше! + No comment provided by engineer. - - weeks - тижнів - time unit - - + Videos and files up to 1gb - Відео та файли до 1 Гб + Відео та файли до 1 Гб No comment provided by engineer. - - You can share this address with your contacts to let them connect with **%@**. - Ви можете поділитися цією адресою зі своїми контактами, щоб вони могли зв'язатися з **%@**. + + View security code + Переглянути код безпеки No comment provided by engineer. - - You can create it later - Ви можете створити його пізніше - No comment provided by engineer. - - - - more stable message delivery. -- a bit better groups. -- and more! - - стабільніша доставка повідомлень. -- трохи кращі групи. -- і багато іншого! - No comment provided by engineer. - - - A few more things - Ще кілька речей - No comment provided by engineer. - - - Contacts - Контакти - No comment provided by engineer. - - - Enable for all - Увімкнути для всіх - No comment provided by engineer. - - - Error enabling delivery receipts! - Помилка активації підтвердження доставлення! - No comment provided by engineer. - - - Error setting delivery receipts! - Помилка встановлення підтвердження доставлення! - No comment provided by engineer. - - - Error synchronizing connection - Помилка синхронізації з'єднання - No comment provided by engineer. - - - Even when disabled in the conversation. - Навіть коли вимкнений у розмові. - No comment provided by engineer. - - - Exporting database archive… - Експорт архіву бази даних… - No comment provided by engineer. - - - Files and media are prohibited in this group. - Файли та медіа в цій групі заборонені. - No comment provided by engineer. - - - Files and media prohibited! - Файли та медіа заборонені! - No comment provided by engineer. - - - Files and media - Файли і медіа + + Voice messages + Голосові повідомлення chat feature - - Filter unread and favorite chats. - Фільтруйте непрочитані та улюблені чати. + + Voice messages are prohibited in this chat. + Голосові повідомлення в цьому чаті заборонені. No comment provided by engineer. - - Find chats faster - Швидше знаходьте чати + + Voice messages are prohibited in this group. + Голосові повідомлення в цій групі заборонені. No comment provided by engineer. - - Fix - Виправити + + Voice messages prohibited! + Голосові повідомлення заборонені! No comment provided by engineer. - - Fix connection - Виправити з'єднання + + Voice message… + Голосове повідомлення… No comment provided by engineer. - - Fix connection? - Полагодити зв'язок? + + Waiting for file + Очікування файлу No comment provided by engineer. - - Fix encryption after restoring backups. - Виправити шифрування після відновлення резервних копій. + + Waiting for image + Очікування зображення No comment provided by engineer. - - Fix not supported by contact - Виправлення не підтримується контактом + + Waiting for video + Чекаємо на відео No comment provided by engineer. - - Fix not supported by group member - Виправлення не підтримується учасником групи + + Warning: you may lose some data! + Попередження: ви можете втратити деякі дані! No comment provided by engineer. - - In reply to - У відповідь на + + WebRTC ICE servers + Сервери WebRTC ICE No comment provided by engineer. - - Keep your connections - Зберігайте свої зв'язки + + Welcome %@! + Ласкаво просимо %@! No comment provided by engineer. - - No history - Немає історії + + Welcome message + Вітальне повідомлення No comment provided by engineer. - - Only group owners can enable files and media. - Тільки власники груп можуть вмикати файли та медіа. + + What's new + Що нового No comment provided by engineer. - - Renegotiate encryption - Переузгодьте шифрування + + When available + За наявності No comment provided by engineer. - - Renegotiate encryption? - Переузгодьте шифрування? + + When people request to connect, you can accept or reject it. + Коли люди звертаються із запитом на підключення, ви можете прийняти або відхилити його. No comment provided by engineer. - - Sending receipts is enabled for %lld contacts - Для контактів %lld увімкнено надсилання підтвердження + + When you share an incognito profile with somebody, this profile will be used for the groups they invite you to. + Коли ви ділитеся з кимось своїм профілем інкогніто, цей профіль буде використовуватися для груп, до яких вас запрошують. No comment provided by engineer. - - Sending delivery receipts will be enabled for all contacts in all visible chat profiles. - Надсилання підтверджень доставки буде ввімкнено для всіх контактів у всіх видимих профілях чату. + + With optional welcome message. + З необов'язковим вітальним повідомленням. No comment provided by engineer. - - Sending delivery receipts will be enabled for all contacts. - Надсилання підтверджень доставки буде ввімкнено для всіх контактів. + + Wrong database passphrase + Неправильний пароль до бази даних No comment provided by engineer. - - Sending receipts is disabled for %lld contacts - Надсилання підтвердження вимкнено для контактів %lld + + Wrong passphrase! + Неправильний пароль! No comment provided by engineer. - - The second tick we missed! ✅ - Другу галочку ми пропустили! ✅ + + XFTP servers + Сервери XFTP No comment provided by engineer. - - These settings are for your current profile **%@**. - Ці налаштування стосуються вашого поточного профілю **%@**. + + You + Ти No comment provided by engineer. - - Video will be received when your contact is online, please wait or check later! - Відео буде отримано, коли ваш контакт буде онлайн, будь ласка, зачекайте або перевірте пізніше! + + You accepted connection + Ви прийняли підключення No comment provided by engineer. - + + You allow + Ви дозволяєте + No comment provided by engineer. + + + You already have a chat profile with the same display name. Please choose another name. + Ви вже маєте профіль у чаті з таким самим іменем. Будь ласка, виберіть інше ім'я. + No comment provided by engineer. + + + You are already connected to %@. + Ви вже підключені до %@. + No comment provided by engineer. + + + You are connected to the server used to receive messages from this contact. + Ви підключені до сервера, який використовується для отримання повідомлень від цього контакту. + No comment provided by engineer. + + + You are invited to group + Запрошуємо вас до групи + No comment provided by engineer. + + + You can accept calls from lock screen, without device and app authentication. + Ви можете приймати дзвінки з екрана блокування без автентифікації пристрою та програми. + No comment provided by engineer. + + + You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. + Ви також можете підключитися за посиланням. Якщо воно відкриється в браузері, натисніть кнопку **Відкрити в мобільному додатку**. + No comment provided by engineer. + + + You can create it later + Ви можете створити його пізніше + No comment provided by engineer. + + You can enable later via Settings - Ви можете увімкнути пізніше в Налаштуваннях + Ви можете увімкнути пізніше в Налаштуваннях No comment provided by engineer. - + You can enable them later via app Privacy & Security settings. - Ви можете увімкнути їх пізніше в налаштуваннях конфіденційності та безпеки програми. + Ви можете увімкнути їх пізніше в налаштуваннях конфіденційності та безпеки програми. No comment provided by engineer. - + You can hide or mute a user profile - swipe it to the right. - Ви можете приховати або вимкнути звук профілю користувача - проведіть по ньому вправо. + Ви можете приховати або вимкнути звук профілю користувача - проведіть по ньому вправо. No comment provided by engineer. - + + You can now send messages to %@ + Тепер ви можете надсилати повідомлення на адресу %@ + notification body + + + You can set lock screen notification preview via settings. + Ви можете налаштувати попередній перегляд сповіщень на екрані блокування за допомогою налаштувань. + No comment provided by engineer. + + + You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + Ви можете поділитися посиланням або QR-кодом - будь-хто зможе приєднатися до групи. Ви не втратите учасників групи, якщо згодом видалите її. + No comment provided by engineer. + + + You can share this address with your contacts to let them connect with **%@**. + Ви можете поділитися цією адресою зі своїми контактами, щоб вони могли зв'язатися з **%@**. + No comment provided by engineer. + + + You can share your address as a link or QR code - anybody can connect to you. + Ви можете поділитися своєю адресою у вигляді посилання або QR-коду - будь-хто зможе зв'язатися з вами. + No comment provided by engineer. + + + You can start chat via app Settings / Database or by restarting the app + Запустити чат можна через Налаштування програми / База даних або перезапустивши програму + No comment provided by engineer. + + + You can turn on SimpleX Lock via Settings. + Увімкнути SimpleX Lock можна в Налаштуваннях. + No comment provided by engineer. + + + You can use markdown to format messages: + Ви можете використовувати розмітку для форматування повідомлень: + No comment provided by engineer. + + + You can't send messages! + Ви не можете надсилати повідомлення! + No comment provided by engineer. + + + You control through which server(s) **to receive** the messages, your contacts – the servers you use to message them. + Ви контролюєте, через який(і) сервер(и) **отримувати** повідомлення, ваші контакти - сервери, які ви використовуєте для надсилання їм повідомлень. + No comment provided by engineer. + + + You could not be verified; please try again. + Вас не вдалося верифікувати, спробуйте ще раз. + No comment provided by engineer. + + + You have no chats + У вас немає чатів + No comment provided by engineer. + + + You have to enter passphrase every time the app starts - it is not stored on the device. + Вам доведеться вводити парольну фразу щоразу під час запуску програми - вона не зберігається на пристрої. + No comment provided by engineer. + + + You invited a contact + Ви запросили контакт + No comment provided by engineer. + + + You joined this group + Ви приєдналися до цієї групи + No comment provided by engineer. + + + You joined this group. Connecting to inviting group member. + Ви приєдналися до цієї групи. Підключення до запрошеного учасника групи. + 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. + Ви повинні використовувати найновішу версію бази даних чату ТІЛЬКИ на одному пристрої, інакше ви можете перестати отримувати повідомлення від деяких контактів. + No comment provided by engineer. + + + You need to allow your contact to send voice messages to be able to send them. + Щоб мати змогу надсилати голосові повідомлення, вам потрібно дозволити контакту надсилати їх. + No comment provided by engineer. + + + You rejected group invitation + Ви відхилили запрошення до групи + No comment provided by engineer. + + + You sent group invitation + Ви надіслали запрошення до групи + No comment provided by engineer. + + + You will be connected to group when the group host's device is online, please wait or check later! + Ви будете підключені до групи, коли пристрій господаря групи буде в мережі, будь ласка, зачекайте або перевірте пізніше! + No comment provided by engineer. + + + You will be connected when your connection request is accepted, please wait or check later! + Ви будете підключені, коли ваш запит на підключення буде прийнято, будь ласка, зачекайте або перевірте пізніше! + No comment provided by engineer. + + + You will be connected when your contact's device is online, please wait or check later! + Ви будете з'єднані, коли пристрій вашого контакту буде онлайн, будь ласка, зачекайте або перевірте пізніше! + No comment provided by engineer. + + + You will be required to authenticate when you start or resume the app after 30 seconds in background. + Вам потрібно буде пройти автентифікацію при запуску або відновленні програми після 30 секунд роботи у фоновому режимі. + No comment provided by engineer. + + + You will join a group this link refers to and connect to its group members. + Ви приєднаєтеся до групи, на яку посилається це посилання, і з'єднаєтеся з її учасниками. + No comment provided by engineer. + + You will still receive calls and notifications from muted profiles when they are active. - Ви все одно отримуватимете дзвінки та сповіщення від вимкнених профілів, якщо вони активні. + Ви все одно отримуватимете дзвінки та сповіщення від вимкнених профілів, якщо вони активні. No comment provided by engineer. - + + You will stop receiving messages from this group. Chat history will be preserved. + Ви перестанете отримувати повідомлення від цієї групи. Історія чату буде збережена. + No comment provided by engineer. + + You won't lose your contacts if you later delete your address. - Ви не втратите свої контакти, якщо згодом видалите свою адресу. + Ви не втратите свої контакти, якщо згодом видалите свою адресу. No comment provided by engineer. - + + You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile + Ви намагаєтеся запросити контакт, з яким ви поділилися профілем інкогніто, до групи, в якій ви використовуєте свій основний профіль + No comment provided by engineer. + + + You're using an incognito profile for this group - to prevent sharing your main profile inviting contacts is not allowed + Ви використовуєте профіль інкогніто для цієї групи - щоб запобігти поширенню вашого основного профілю, запрошення контактів заборонено + No comment provided by engineer. + + + Your %@ servers + Ваші сервери %@ + No comment provided by engineer. + + + Your ICE servers + Ваші сервери ICE + No comment provided by engineer. + + + Your SMP servers + Ваші SMP-сервери + No comment provided by engineer. + + + Your SimpleX address + Ваша адреса SimpleX + No comment provided by engineer. + + + Your XFTP servers + Ваші XFTP-сервери + No comment provided by engineer. + + + Your calls + Твої дзвінки + No comment provided by engineer. + + + Your chat database + Ваша база даних чату + No comment provided by engineer. + + + Your chat database is not encrypted - set passphrase to encrypt it. + Ваша база даних чату не зашифрована - встановіть ключову фразу, щоб зашифрувати її. + No comment provided by engineer. + + + Your chat profile will be sent to group members + Ваш профіль у чаті буде надіслано учасникам групи + No comment provided by engineer. + + + Your chat profiles + Ваші профілі чату + No comment provided by engineer. + + + Your contact needs to be online for the connection to complete. +You can cancel this connection and remove the contact (and try later with a new link). + Для завершення з'єднання ваш контакт має бути онлайн. +Ви можете скасувати це з'єднання і видалити контакт (і спробувати пізніше з новим посиланням). + No comment provided by engineer. + + + Your contact sent a file that is larger than currently supported maximum size (%@). + Ваш контакт надіслав файл, розмір якого перевищує підтримуваний на цей момент максимальний розмір (%@). + No comment provided by engineer. + + + Your contacts can allow full message deletion. + Ваші контакти можуть дозволити повне видалення повідомлень. + No comment provided by engineer. + + Your contacts in SimpleX will see it. You can change it in Settings. - Ваші контакти в SimpleX побачать це. + Ваші контакти в SimpleX побачать це. Ви можете змінити його в Налаштуваннях. No comment provided by engineer. - + + Your contacts will remain connected. + Ваші контакти залишаться на зв'язку. + No comment provided by engineer. + + + Your current chat database will be DELETED and REPLACED with the imported one. + Ваша поточна база даних чату буде ВИДАЛЕНА і ЗАМІНЕНА імпортованою. + No comment provided by engineer. + + + Your current profile + Ваш поточний профіль + No comment provided by engineer. + + + Your preferences + Ваші уподобання + No comment provided by engineer. + + + Your privacy + Ваша конфіденційність + No comment provided by engineer. + + + Your profile **%@** will be shared. + Ваш профіль **%@** буде опублікований. + No comment provided by engineer. + + + Your profile is stored on your device and shared only with your contacts. +SimpleX servers cannot see your profile. + Ваш профіль зберігається на вашому пристрої і доступний лише вашим контактам. +Сервери SimpleX не бачать ваш профіль. + No comment provided by engineer. + + + Your profile, contacts and delivered messages are stored on your device. + Ваш профіль, контакти та доставлені повідомлення зберігаються на вашому пристрої. + No comment provided by engineer. + + + Your random profile + Ваш випадковий профіль + No comment provided by engineer. + + + Your server + Ваш сервер + No comment provided by engineer. + + + Your server address + Адреса вашого сервера + No comment provided by engineer. + + + Your settings + Ваші налаштування + No comment provided by engineer. + + + [Contribute](https://github.com/simplex-chat/simplex-chat#contribute) + [Внесок](https://github.com/simplex-chat/simplex-chat#contribute) + No comment provided by engineer. + + + [Send us email](mailto:chat@simplex.chat) + [Напишіть нам електронною поштою](mailto:chat@simplex.chat) + No comment provided by engineer. + + + [Star on GitHub](https://github.com/simplex-chat/simplex-chat) + [Зірка на GitHub](https://github.com/simplex-chat/simplex-chat) + No comment provided by engineer. + + + \_italic_ + \_курсив_ + No comment provided by engineer. + + + \`a + b` + \`a + b` + No comment provided by engineer. + + + above, then choose: + вище, а потім обирайте: + No comment provided by engineer. + + + accepted call + прийнято виклик + call status + + + admin + адмін + member role + + agreeing encryption for %@… - узгодження шифрування для %@… + узгодження шифрування для %@… chat item text - + agreeing encryption… - узгодження шифрування… + узгодження шифрування… chat item text - - default (yes) - за замовчуванням (так) + + always + завжди + pref value + + + audio call (not e2e encrypted) + аудіовиклик (без шифрування e2e) No comment provided by engineer. - + + bad message ID + невірний ідентифікатор повідомлення + integrity error chat item + + + bad message hash + невірний хеш повідомлення + integrity error chat item + + + bold + жирний + No comment provided by engineer. + + + call error + помилка дзвінка + call status + + + call in progress + виклик у процесі + call status + + + calling… + дзвоніть… + call status + + + cancelled %@ + скасовано %@ + feature offered item + + + changed address for you + змінили для вас адресу + chat item text + + + changed role of %1$@ to %2$@ + змінено роль %1$@ на %2$@ + rcv group event chat item + + + changed your role to %@ + змінили свою роль на %@ + rcv group event chat item + + + changing address for %@… + зміна адреси для %@… + chat item text + + changing address… - змінює адресу… + змінює адресу… chat item text - - encryption agreed - узгоджено шифрування - chat item text - - - encryption re-negotiation allowed for %@ - переузгодження шифрування дозволено для %@ - chat item text - - - encryption re-negotiation required - потрібне повторне узгодження шифрування - chat item text - - - encryption re-negotiation required for %@ - для %@ потрібне повторне узгодження шифрування - chat item text - - - hours - години - time unit - - - seconds - секунди - time unit - - - security code changed - змінено код безпеки - chat item text - - - Waiting for video - Чекаємо на відео + + colored + кольоровий No comment provided by engineer. - - %1$@ at %2$@: - %1$@ за %2$@: - copied message info, <sender> at <time> - - - Delivery receipts are disabled! - Квитанції про доставку відключені! + + complete + завершено No comment provided by engineer. - - Delivery receipts! - Квитанції про доставку! + + connect to SimpleX Chat developers. + зв'язатися з розробниками SimpleX Chat. No comment provided by engineer. - - Prohibit sending files and media. - Заборонити надсилання файлів і медіа. + + connected + з'єднаний No comment provided by engineer. - - Protocol timeout per KB - Тайм-аут протоколу на КБ + + connected directly + rcv group event chat item + + + connecting + з'єднання No comment provided by engineer. - - React… - Реагуй… - chat item menu - - - Reconnect all connected servers to force message delivery. It uses additional traffic. - Перепідключіть всі підключені сервери, щоб примусово доставити повідомлення. Це використовує додатковий трафік. + + connecting (accepted) + з'єднання (прийнято) No comment provided by engineer. - - Reconnect servers? - Перепідключити сервери? + + connecting (announced) + з'єднання (оголошено) No comment provided by engineer. - - Renegotiate - Переузгодьте + + connecting (introduced) + з'єднання (введено) No comment provided by engineer. - - Send delivery receipts to - Надсилання звітів про доставку + + connecting (introduction invitation) + з'єднання (вступне запрошення) No comment provided by engineer. - - Send receipts - Надіслати підтвердження + + connecting call… + підключення дзвінка… + call status + + + connecting… + з'єднання… + chat list item title + + + connection established + з'єднання встановлене + chat list item title (it should not be shown + + + connection:%@ + з'єднання:%@ + connection information + + + contact has e2e encryption + контакт має шифрування e2e No comment provided by engineer. - - The encryption is working and the new encryption agreement is not required. It may result in connection errors! - Шифрування працює і нова угода про шифрування не потрібна. Це може призвести до помилок з'єднання! + + contact has no e2e encryption + контакт не має шифрування e2e No comment provided by engineer. - + + creator + творець + No comment provided by engineer. + + custom - звичайний + звичайний dropdown time picker choice - + database version is newer than the app, but no down migration for: %@ - версія бази даних новіша, ніж додаток, але без міграції вниз для: %@ + версія бази даних новіша, ніж додаток, але без міграції вниз для: %@ No comment provided by engineer. - + + days + днів + time unit + + + default (%@) + за замовчуванням (%@) + pref value + + default (no) - за замовчуванням (ні) + за замовчуванням (ні) No comment provided by engineer. - - Connect via one-time link - Під'єднатися за одноразовим посиланням + + default (yes) + за замовчуванням (так) No comment provided by engineer. - - Connect via contact link - Підключіться за контактним посиланням + + deleted + видалено + deleted chat item + + + deleted group + видалено групу + rcv group event chat item + + + different migration in the app/database: %@ / %@ + різна міграція в додатку/базі даних: %@ / %@ No comment provided by engineer. - + + direct + прямо + connection level description + + + disabled + вимкнено + No comment provided by engineer. + + + duplicate message + дублююче повідомлення + integrity error chat item + + + e2e encrypted + e2e зашифрований + No comment provided by engineer. + + + enabled + увімкнено + enabled status + + + enabled for contact + увімкнено для контакту + enabled status + + + enabled for you + увімкнено для вас + enabled status + + + encryption agreed + узгоджено шифрування + chat item text + + encryption agreed for %@ - узгоджене шифрування для %@ + узгоджене шифрування для %@ chat item text - + + encryption ok + шифрування ok + chat item text + + encryption ok for %@ - шифрування ok для %@ + шифрування ok для %@ chat item text - - Sending receipts is enabled for %lld groups - Для груп %lld увімкнено надсилання підтвердження + + encryption re-negotiation allowed + переузгодження шифрування дозволено + chat item text + + + encryption re-negotiation allowed for %@ + переузгодження шифрування дозволено для %@ + chat item text + + + encryption re-negotiation required + потрібне повторне узгодження шифрування + chat item text + + + encryption re-negotiation required for %@ + для %@ потрібне повторне узгодження шифрування + chat item text + + + ended + закінчився No comment provided by engineer. - - Message delivery receipts! - Підтвердження доставки повідомлення! + + ended call %@ + закінчився виклик %@ + call status + + + error + помилка No comment provided by engineer. - - Your contacts will remain connected. - Ваші контакти залишаться на зв'язку. - No comment provided by engineer. - - - Your profile **%@** will be shared. - Ваш профіль **%@** буде опублікований. - No comment provided by engineer. - - - %@, %@ and %lld other members connected - %@, %@ та %lld інші підключені учасники - No comment provided by engineer. - - - %@ and %@ connected - %@ і %@ підключено - No comment provided by engineer. - - - Show last messages - Показати останні повідомлення - No comment provided by engineer. - - + event happened - відбулася подія + відбулася подія + No comment provided by engineer. + + + group deleted + групу видалено + No comment provided by engineer. + + + group profile updated + оновлено профіль групи + snd group event chat item + + + hours + години + time unit + + + iOS Keychain is used to securely store passphrase - it allows receiving push notifications. + iOS Keychain використовується для безпечного зберігання пароля - це дає змогу отримувати миттєві повідомлення. + No comment provided by engineer. + + + iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications. + Пароль бази даних буде безпечно збережено в iOS Keychain після запуску чату або зміни пароля - це дасть змогу отримувати миттєві повідомлення. + No comment provided by engineer. + + + incognito via contact address link + інкогніто за посиланням на контактну адресу + chat list item description + + + incognito via group link + інкогніто через групове посилання + chat list item description + + + incognito via one-time link + інкогніто за одноразовим посиланням + chat list item description + + + indirect (%d) + непрямий (%d) + connection level description + + + invalid chat + недійсний чат + invalid chat data + + + invalid chat data + невірні дані чату + No comment provided by engineer. + + + invalid data + невірні дані + invalid chat item + + + invitation to group %@ + запрошення до групи %@ + group name + + + invited + запрошені + No comment provided by engineer. + + + invited %@ + запрошений %@ + rcv group event chat item + + + invited to connect + запрошуємо приєднатися + chat list item title + + + invited via your group link + запрошені за посиланням у вашій групі + rcv group event chat item + + + italic + курсив + No comment provided by engineer. + + + join as %@ + приєднатися як %@ + No comment provided by engineer. + + + left + ліворуч + rcv group event chat item + + + marked deleted + з позначкою видалено + marked deleted chat item preview text + + + member + учасник + member role + + + connected + з'єднаний + rcv group event chat item + + + message received + повідомлення отримано + notification + + + minutes + хвилини + time unit + + + missed call + пропущений дзвінок + call status + + + moderated + модерується + moderated chat item + + + moderated by %@ + модерується %@ + No comment provided by engineer. + + + months + місяців + time unit + + + never + ніколи + No comment provided by engineer. + + + new message + нове повідомлення + notification + + + no + ні + pref value + + + no e2e encryption + без шифрування e2e + No comment provided by engineer. + + + no text + без тексту + copied message info in history + + + observer + спостерігач + member role + + + off + вимкнено + enabled status + group pref value + + + offered %@ + запропоновано %@ + feature offered item + + + offered %1$@: %2$@ + запропонував %1$@: %2$@ + feature offered item + + + on + увімкнено + group pref value + + + or chat with the developers + або поспілкуйтеся з розробниками + No comment provided by engineer. + + + owner + власник + member role + + + peer-to-peer + одноранговий + No comment provided by engineer. + + + received answer… + отримали відповідь… + No comment provided by engineer. + + + received confirmation… + отримали підтвердження… + No comment provided by engineer. + + + rejected call + відхилений виклик + call status + + + removed + видалено + No comment provided by engineer. + + + removed %@ + видалено %@ + rcv group event chat item + + + removed you + прибрали вас + rcv group event chat item + + + sec + сек + network option + + + seconds + секунди + time unit + + + secret + таємниця + No comment provided by engineer. + + + security code changed + змінено код безпеки + chat item text + + + send direct message + No comment provided by engineer. + + + starting… + починаючи… + No comment provided by engineer. + + + strike + закреслено + No comment provided by engineer. + + + this contact + цей контакт + notification title + + + unknown + невідомий + connection info + + + updated group profile + оновлений профіль групи + rcv group event chat item + + + v%@ (%@) + v%@ (%@) + No comment provided by engineer. + + + via contact address link + за посиланням на контактну адресу + chat list item description + + + via group link + за посиланням на групу + chat list item description + + + via one-time link + за одноразовим посиланням + chat list item description + + + via relay + за допомогою ретранслятора + No comment provided by engineer. + + + video call (not e2e encrypted) + відеодзвінок (без шифрування e2e) + No comment provided by engineer. + + + waiting for answer… + в очікуванні відповіді… + No comment provided by engineer. + + + waiting for confirmation… + чекаємо на підтвердження… + No comment provided by engineer. + + + wants to connect to you! + хоче зв'язатися з вами! + No comment provided by engineer. + + + weeks + тижнів + time unit + + + yes + так + pref value + + + you are invited to group + вас запрошують до групи + No comment provided by engineer. + + + you are observer + ви спостерігач + No comment provided by engineer. + + + you changed address + ви змінили адресу + chat item text + + + you changed address for %@ + ви змінили адресу на %@ + chat item text + + + you changed role for yourself to %@ + ви змінили роль для себе на %@ + snd group event chat item + + + you changed role of %1$@ to %2$@ + ви змінили роль %1$@ на %2$@ + snd group event chat item + + + you left + ти пішов + snd group event chat item + + + you removed %@ + ви видалили %@ + snd group event chat item + + + you shared one-time link + ви поділилися одноразовим посиланням + chat list item description + + + you shared one-time link incognito + ви поділилися одноразовим посиланням інкогніто + chat list item description + + + you: + ти: + No comment provided by engineer. + + + \~strike~ + \~закреслити~ No comment provided by engineer.
- +
- + SimpleX - SimpleX + SimpleX Bundle name - + SimpleX needs camera access to scan QR codes to connect to other users and for video calls. - SimpleX потребує доступу до камери, щоб сканувати QR-коди для з'єднання з іншими користувачами та для відеодзвінків. + SimpleX потребує доступу до камери, щоб сканувати QR-коди для з'єднання з іншими користувачами та для відеодзвінків. Privacy - Camera Usage Description - + SimpleX uses Face ID for local authentication - SimpleX використовує Face ID для локальної автентифікації + SimpleX використовує Face ID для локальної автентифікації Privacy - Face ID Usage Description - + SimpleX needs microphone access for audio and video calls, and to record voice messages. - SimpleX потребує доступу до мікрофона для аудіо та відео дзвінків, а також для запису голосових повідомлень. + SimpleX потребує доступу до мікрофона для аудіо та відео дзвінків, а також для запису голосових повідомлень. Privacy - Microphone Usage Description - + SimpleX needs access to Photo Library for saving captured and received media - SimpleX потребує доступу до фототеки для збереження захоплених та отриманих медіафайлів + SimpleX потребує доступу до фототеки для збереження захоплених та отриманих медіафайлів Privacy - Photo Library Additions Usage Description
- +
- + SimpleX NSE - SimpleX NSE + SimpleX NSE Bundle display name - + SimpleX NSE - SimpleX NSE + SimpleX NSE Bundle name - + Copyright © 2022 SimpleX Chat. All rights reserved. - Авторське право © 2022 SimpleX Chat. Всі права захищені. + Авторське право © 2022 SimpleX Chat. Всі права захищені. Copyright (human-readable) diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/contents.json b/apps/ios/SimpleX Localizations/uk.xcloc/contents.json index 6ad42fd109..6c122f11ab 100644 --- a/apps/ios/SimpleX Localizations/uk.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/uk.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "uk", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff index 8fa66159d4..9fcd6d0bf2 100644 --- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff +++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff @@ -2,7 +2,7 @@
- +
@@ -94,7 +94,7 @@ %1$@ at %2$@: - %2$@: + @ %2$@: copied message info, <sender> at <time> @@ -197,6 +197,11 @@ %lld 分钟 No comment provided by engineer. + + %lld new interface languages + %lld 种新的界面语言 + No comment provided by engineer. + %lld second(s) %lld 秒 @@ -327,6 +332,12 @@ , No comment provided by engineer. + + - connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! +- delivery receipts (up to 20 members). +- faster and more stable. + No comment provided by engineer. + - more stable message delivery. - a bit better groups. @@ -414,7 +425,7 @@ A few more things - + 一些杂项 No comment provided by engineer. @@ -424,7 +435,7 @@ A new random profile will be shared. - 创建一个随机的共享文件 + 创建一个随机的共享文件。 No comment provided by engineer. @@ -482,7 +493,7 @@ Accept connection request? - 接受联系人 + 接受联系人? No comment provided by engineer. @@ -700,6 +711,10 @@ 应用程序构建:%@ No comment provided by engineer. + + App encrypts new local files (except videos). + No comment provided by engineer. + App icon 应用程序图标 @@ -835,6 +850,10 @@ 您和您的联系人都可以发送语音消息。 No comment provided by engineer. + + Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)! + 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). 通过聊天资料(默认)或者[通过连接](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)。 @@ -1068,15 +1087,17 @@ Connect directly + 直接连接 No comment provided by engineer. Connect incognito + 在隐身状态下连接 No comment provided by engineer. Connect via contact link - 通过联系人链接进行连接? + 通过联系人链接进行连接 No comment provided by engineer. @@ -1096,7 +1117,7 @@ Connect via one-time link - 通过一次性链接连接? + 通过一次性链接连接 No comment provided by engineer. @@ -1176,6 +1197,7 @@ Contacts + 联系人 No comment provided by engineer. @@ -1228,6 +1250,10 @@ 创建链接 No comment provided by engineer. + + Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 + No comment provided by engineer. + Create one-time invitation link 创建一次性邀请链接 @@ -1573,14 +1599,17 @@ Delivery + 传送 No comment provided by engineer. Delivery receipts are disabled! + 送达回执已禁用! No comment provided by engineer. Delivery receipts! + 送达回执! No comment provided by engineer. @@ -1630,6 +1659,7 @@ Disable (keep overrides) + 禁用(保留覆盖) No comment provided by engineer. @@ -1639,6 +1669,7 @@ Disable for all + 全部禁用 No comment provided by engineer. @@ -1676,6 +1707,10 @@ 断开连接 server test step + + Discover and join groups + No comment provided by engineer. + Display name 显示名称 @@ -1703,6 +1738,7 @@ Don't enable + 不要启用 No comment provided by engineer. @@ -1747,6 +1783,7 @@ Enable (keep overrides) + 启用(保持覆盖) No comment provided by engineer. @@ -1766,6 +1803,7 @@ Enable for all + 全部启用 No comment provided by engineer. @@ -1810,6 +1848,11 @@ Encrypt local files + 加密本地文件 + No comment provided by engineer. + + + Encrypt stored files & media No comment provided by engineer. @@ -1937,6 +1980,10 @@ 创建群组链接错误 No comment provided by engineer. + + Error creating member contact + No comment provided by engineer. + Error creating profile! 创建资料错误! @@ -1944,6 +1991,7 @@ Error decrypting file + 解密文件时出错 No comment provided by engineer. @@ -1988,6 +2036,7 @@ Error enabling delivery receipts! + 启用送达回执出错! No comment provided by engineer. @@ -2065,6 +2114,10 @@ 发送电邮错误 No comment provided by engineer. + + Error sending member contact invitation + No comment provided by engineer. + Error sending message 发送消息错误 @@ -2072,6 +2125,7 @@ Error setting delivery receipts! + 设置送达回执出错! No comment provided by engineer. @@ -2091,6 +2145,7 @@ Error synchronizing connection + 同步连接错误 No comment provided by engineer. @@ -2135,6 +2190,7 @@ Even when disabled in the conversation. + 即使在对话中被禁用。 No comment provided by engineer. @@ -2219,6 +2275,7 @@ Filter unread and favorite chats. + 过滤未读和收藏的聊天记录。 No comment provided by engineer. @@ -2228,30 +2285,37 @@ Find chats faster + 更快地查找聊天记录 No comment provided by engineer. Fix + 修复 No comment provided by engineer. Fix connection + 修复连接 No comment provided by engineer. Fix connection? + 修复连接? No comment provided by engineer. Fix encryption after restoring backups. + 修复还原备份后的加密问题。 No comment provided by engineer. Fix not supported by contact + 修复联系人不支持的问题 No comment provided by engineer. Fix not supported by group member + 修复群组成员不支持的问题 No comment provided by engineer. @@ -2561,6 +2625,7 @@ In reply to + 答复 No comment provided by engineer. @@ -2575,6 +2640,7 @@ Incognito mode protects your privacy by using a new random profile for each contact. + 隐身模式会为每个联系人使用一个新的随机配置文件,从而保护你的隐私。 No comment provided by engineer. @@ -2651,6 +2717,7 @@ Invalid status + 无效状态 item status text @@ -2746,6 +2813,7 @@ Keep your connections + 保持连接 No comment provided by engineer. @@ -2840,6 +2908,7 @@ Make one message disappear + 使一条消息消失 No comment provided by engineer. @@ -2914,6 +2983,7 @@ Message delivery receipts! + 消息送达回执! No comment provided by engineer. @@ -2998,6 +3068,7 @@ Most likely this connection is deleted. + 此连接很可能已被删除。 item status description @@ -3060,6 +3131,10 @@ 新数据库存档 No comment provided by engineer. + + New desktop app! + No comment provided by engineer. + New display name 新显示名 @@ -3107,6 +3182,7 @@ No delivery information + 无送达信息 No comment provided by engineer. @@ -3126,6 +3202,7 @@ No history + 无历史记录 No comment provided by engineer. @@ -3272,6 +3349,10 @@ 只有您的联系人可以发送语音消息。 No comment provided by engineer. + + Open + No comment provided by engineer. + Open Settings 打开设置 @@ -3564,6 +3645,7 @@ Protocol timeout per KB + 每 KB 协议超时 No comment provided by engineer. @@ -3578,6 +3660,7 @@ React… + 回应… chat item menu @@ -3612,6 +3695,7 @@ Receipts are disabled + 回执已禁用 No comment provided by engineer. @@ -3656,10 +3740,12 @@ Reconnect all connected servers to force message delivery. It uses additional traffic. + 重新连接所有已连接的服务器以强制发送信息。这会耗费更多流量。 No comment provided by engineer. Reconnect servers? + 是否重新连接服务器? No comment provided by engineer. @@ -3724,14 +3810,17 @@ Renegotiate + 重新协商 No comment provided by engineer. Renegotiate encryption + 重新协商加密 No comment provided by engineer. Renegotiate encryption? + 重新协商加密? No comment provided by engineer. @@ -3991,6 +4080,7 @@ Send delivery receipts to + 将送达回执发送给 No comment provided by engineer. @@ -3998,6 +4088,10 @@ 发送私信 No comment provided by engineer. + + Send direct message to connect + No comment provided by engineer. + Send disappearing message 发送限时消息中 @@ -4030,6 +4124,7 @@ Send receipts + 发送回执 No comment provided by engineer. @@ -4049,10 +4144,12 @@ Sending delivery receipts will be enabled for all contacts in all visible chat profiles. + 将对所有可见聊天配置文件中的所有联系人启用送达回执功能。 No comment provided by engineer. Sending delivery receipts will be enabled for all contacts. + 将对所有联系人启用送达回执功能。 No comment provided by engineer. @@ -4062,18 +4159,22 @@ Sending receipts is disabled for %lld contacts + 已为 %lld 联系人禁用送达回执功能 No comment provided by engineer. Sending receipts is disabled for %lld groups + 已为 %lld 组禁用送达回执功能 No comment provided by engineer. Sending receipts is enabled for %lld contacts + 已为 %lld 联系人启用送达回执功能 No comment provided by engineer. Sending receipts is enabled for %lld groups + 已为 %lld 组启用送达回执功能 No comment provided by engineer. @@ -4218,6 +4319,7 @@ Show last messages + 显示最近的消息 No comment provided by engineer. @@ -4290,6 +4392,10 @@ SimpleX 一次性邀请 simplex link type + + Simplified incognito mode + No comment provided by engineer. + Skip 跳过 @@ -4302,6 +4408,7 @@ Small groups (max 20) + 小群组(最多 20 人) No comment provided by engineer. @@ -4523,6 +4630,7 @@ It can happen because of some bug or when the connection is compromised. The encryption is working and the new encryption agreement is not required. It may result in connection errors! + 加密正在运行,不需要新的加密协议。这可能会导致连接错误! No comment provided by engineer. @@ -4562,6 +4670,7 @@ It can happen because of some bug or when the connection is compromised. The second tick we missed! ✅ + 我们错过的第二个"√"!✅ No comment provided by engineer. @@ -4591,10 +4700,12 @@ It can happen because of some bug or when the connection is compromised. These settings are for your current profile **%@**. + 这些设置适用于您当前的配置文件 **%@**。 No comment provided by engineer. They can be overridden in contact and group settings. + 可以在联系人和群组设置中覆盖它们。 No comment provided by engineer. @@ -4614,6 +4725,7 @@ It can happen because of some bug or when the connection is compromised. This group has over %lld members, delivery receipts are not sent. + 该组有超过 %lld 个成员,不发送送货单。 No comment provided by engineer. @@ -4678,6 +4790,10 @@ You will be prompted to complete authentication before this feature is enabled.< 要与您的联系人验证端到端加密,请比较(或扫描)您设备上的代码。 No comment provided by engineer. + + Toggle incognito when connecting. + No comment provided by engineer. + Transport isolation 传输隔离 @@ -4857,6 +4973,7 @@ To connect, please ask your contact to create another connection link and check Use current profile + 使用当前配置文件 No comment provided by engineer. @@ -4871,6 +4988,7 @@ To connect, please ask your contact to create another connection link and check Use new incognito profile + 使用新的隐身配置文件 No comment provided by engineer. @@ -5085,10 +5203,12 @@ To connect, please ask your contact to create another connection link and check You can enable later via Settings + 您可以稍后在设置中启用它 No comment provided by engineer. You can enable them later via app Privacy & Security settings. + 您可以稍后通过应用程序的 "隐私与安全 "设置启用它们。 No comment provided by engineer. @@ -5347,6 +5467,7 @@ You can change it in Settings. Your profile **%@** will be shared. + 您的个人资料 **%@** 将被共享。 No comment provided by engineer. @@ -5423,10 +5544,12 @@ SimpleX 服务器无法看到您的资料。 agreeing encryption for %@… + 正在协商将加密应用于 %@… chat item text agreeing encryption… + 同意加密… chat item text @@ -5491,10 +5614,12 @@ SimpleX 服务器无法看到您的资料。 changing address for %@… + 正在将变更的地址应用于 %@… chat item text changing address… + 更改地址… chat item text @@ -5517,6 +5642,10 @@ SimpleX 服务器无法看到您的资料。 已连接 No comment provided by engineer. + + connected directly + rcv group event chat item + connecting 连接中 @@ -5599,10 +5728,12 @@ SimpleX 服务器无法看到您的资料。 default (no) + 默认(否) No comment provided by engineer. default (yes) + 默认 (是) No comment provided by engineer. @@ -5627,6 +5758,7 @@ SimpleX 服务器无法看到您的资料。 disabled + 关闭 No comment provided by engineer. @@ -5656,34 +5788,42 @@ SimpleX 服务器无法看到您的资料。 encryption agreed + 已同意加密 chat item text encryption agreed for %@ + 同意对 %@ 进行加密 chat item text encryption ok + 可以加密 chat item text encryption ok for %@ + 对 %@ 进行加密 chat item text encryption re-negotiation allowed + 允许重新进行加密协商 chat item text encryption re-negotiation allowed for %@ + 允许对 %@ 进行加密重新协商 chat item text encryption re-negotiation required + 需要重新进行加密协商 chat item text encryption re-negotiation required for %@ + 需要为 %@ 重新进行加密协商 chat item text @@ -5703,6 +5843,7 @@ SimpleX 服务器无法看到您的资料。 event happened + 发生的事 No comment provided by engineer. @@ -5963,8 +6104,13 @@ SimpleX 服务器无法看到您的资料。 security code changed + 安全密码已更改 chat item text + + send direct message + No comment provided by engineer. + starting… 启动中…… @@ -6109,7 +6255,7 @@ SimpleX 服务器无法看到您的资料。
- +
@@ -6141,7 +6287,7 @@ SimpleX 服务器无法看到您的资料。
- +
diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json index 2228a43848..807a15f96c 100644 --- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json @@ -3,7 +3,7 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "zh-Hans", "toolInfo" : { - "toolBuildNumber" : "15A5219j", + "toolBuildNumber" : "15A240d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", "toolVersion" : "15.0" diff --git a/apps/ios/SimpleX NSE/NotificationService.swift b/apps/ios/SimpleX NSE/NotificationService.swift index f0a5c2a069..645fdb5952 100644 --- a/apps/ios/SimpleX NSE/NotificationService.swift +++ b/apps/ios/SimpleX NSE/NotificationService.swift @@ -383,7 +383,7 @@ func apiSetFileToReceive(fileId: Int64, encrypted: Bool) { func autoReceiveFile(_ file: CIFile, encrypted: Bool) -> ChatItem? { switch file.fileProtocol { case .smp: - return apiReceiveFile(fileId: file.fileId, encrypted: false)?.chatItem + return apiReceiveFile(fileId: file.fileId, encrypted: encrypted)?.chatItem case .xftp: apiSetFileToReceive(fileId: file.fileId, encrypted: encrypted) return nil diff --git a/apps/ios/SimpleX NSE/bg.lproj/InfoPlist.strings b/apps/ios/SimpleX NSE/bg.lproj/InfoPlist.strings new file mode 100644 index 0000000000..b1c515fbb4 --- /dev/null +++ b/apps/ios/SimpleX NSE/bg.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SimpleX NSE"; + +/* Bundle name */ +"CFBundleName" = "SimpleX NSE"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Авторско право © 2022 SimpleX Chat. Всички права запазени."; + diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index cae3722e81..64ca9c6cb6 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -48,6 +48,11 @@ 5C55A921283CCCB700C4E99E /* IncomingCallView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C55A920283CCCB700C4E99E /* IncomingCallView.swift */; }; 5C55A923283CEDE600C4E99E /* SoundPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C55A922283CEDE600C4E99E /* SoundPlayer.swift */; }; 5C55A92E283D0FDE00C4E99E /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = 5C55A92D283D0FDE00C4E99E /* sounds */; }; + 5C5625062ABCBD3200A21210 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C5625012ABCBD3200A21210 /* libffi.a */; }; + 5C5625072ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C5625022ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo-ghc8.10.7.a */; }; + 5C5625082ABCBD3200A21210 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C5625032ABCBD3200A21210 /* libgmp.a */; }; + 5C5625092ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C5625042ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo.a */; }; + 5C56250A2ABCBD3200A21210 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C5625052ABCBD3200A21210 /* libgmpxx.a */; }; 5C577F7D27C83AA10006112D /* MarkdownHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C577F7C27C83AA10006112D /* MarkdownHelp.swift */; }; 5C58BCD6292BEBE600AF9E4F /* CIChatFeatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C58BCD5292BEBE600AF9E4F /* CIChatFeatureView.swift */; }; 5C5DB70E289ABDD200730FFF /* AppearanceSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5DB70D289ABDD200730FFF /* AppearanceSettings.swift */; }; @@ -78,11 +83,6 @@ 5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9CC7AC28C55D7800BEF955 /* DatabaseEncryptionView.swift */; }; 5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */; }; 5C9D811A2AA8727A001D49FD /* CryptoFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */; }; - 5C9E127E2AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9E12792AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t-ghc8.10.7.a */; }; - 5C9E127F2AAE62A500C9D8FF /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9E127A2AAE62A500C9D8FF /* libgmpxx.a */; }; - 5C9E12802AAE62A500C9D8FF /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9E127B2AAE62A500C9D8FF /* libgmp.a */; }; - 5C9E12812AAE62A500C9D8FF /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9E127C2AAE62A500C9D8FF /* libffi.a */; }; - 5C9E12822AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9E127D2AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t.a */; }; 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */; }; 5CA059DC279559F40002BEB4 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DB279559F40002BEB4 /* Tests_iOS.swift */; }; 5CA059DE279559F40002BEB4 /* Tests_iOSLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DD279559F40002BEB4 /* Tests_iOSLaunchTests.swift */; }; @@ -153,6 +153,8 @@ 5CFE0921282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; }; 5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; }; 6407BA83295DA85D0082BA18 /* CIInvalidJSONView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */; }; + 6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */; }; + 6419EC582AB97507004A607A /* CIMemberCreatedContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */; }; 6432857C2925443C00FBE5C8 /* GroupPreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6432857B2925443C00FBE5C8 /* GroupPreferencesView.swift */; }; 6440CA00288857A10062C672 /* CIEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440C9FF288857A10062C672 /* CIEventView.swift */; }; 6440CA03288AECA70062C672 /* AddGroupMembersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440CA02288AECA70062C672 /* AddGroupMembersView.swift */; }; @@ -291,8 +293,16 @@ 5C55A920283CCCB700C4E99E /* IncomingCallView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncomingCallView.swift; sourceTree = ""; }; 5C55A922283CEDE600C4E99E /* SoundPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundPlayer.swift; sourceTree = ""; }; 5C55A92D283D0FDE00C4E99E /* sounds */ = {isa = PBXFileReference; lastKnownFileType = folder; path = sounds; sourceTree = ""; }; + 5C5625012ABCBD3200A21210 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 5C5625022ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo-ghc8.10.7.a"; sourceTree = ""; }; + 5C5625032ABCBD3200A21210 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + 5C5625042ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo.a"; sourceTree = ""; }; + 5C5625052ABCBD3200A21210 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; 5C577F7C27C83AA10006112D /* MarkdownHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownHelp.swift; sourceTree = ""; }; 5C58BCD5292BEBE600AF9E4F /* CIChatFeatureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIChatFeatureView.swift; sourceTree = ""; }; + 5C5B67912ABAF4B500DA9412 /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Localizable.strings; sourceTree = ""; }; + 5C5B67922ABAF56000DA9412 /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = "bg.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; + 5C5B67932ABAF56000DA9412 /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/InfoPlist.strings; sourceTree = ""; }; 5C5DB70D289ABDD200730FFF /* AppearanceSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceSettings.swift; sourceTree = ""; }; 5C5E5D3A2824468B00B0488A /* ActiveCallView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveCallView.swift; sourceTree = ""; }; 5C5E5D3C282447AB00B0488A /* CallTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallTypes.swift; sourceTree = ""; }; @@ -337,11 +347,6 @@ 5C9CC7AC28C55D7800BEF955 /* DatabaseEncryptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseEncryptionView.swift; sourceTree = ""; }; 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTC.swift; sourceTree = ""; }; 5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoFile.swift; sourceTree = ""; }; - 5C9E12792AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t-ghc8.10.7.a"; sourceTree = ""; }; - 5C9E127A2AAE62A500C9D8FF /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - 5C9E127B2AAE62A500C9D8FF /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - 5C9E127C2AAE62A500C9D8FF /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; - 5C9E127D2AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t.a"; sourceTree = ""; }; 5C9FD96A27A56D4D0075386C /* JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSON.swift; sourceTree = ""; }; 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendMessageView.swift; sourceTree = ""; }; 5CA059C3279559F40002BEB4 /* SimpleXApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXApp.swift; sourceTree = ""; }; @@ -429,6 +434,8 @@ 5CFA59CF286477B400863A68 /* ChatArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatArchiveView.swift; sourceTree = ""; }; 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ZoomableScrollView.swift; path = Shared/Views/ZoomableScrollView.swift; sourceTree = SOURCE_ROOT; }; 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIInvalidJSONView.swift; sourceTree = ""; }; + 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextInvitingContactMemberView.swift; sourceTree = ""; }; + 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMemberCreatedContactView.swift; sourceTree = ""; }; 6432857B2925443C00FBE5C8 /* GroupPreferencesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupPreferencesView.swift; sourceTree = ""; }; 6440C9FF288857A10062C672 /* CIEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIEventView.swift; sourceTree = ""; }; 6440CA02288AECA70062C672 /* AddGroupMembersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupMembersView.swift; sourceTree = ""; }; @@ -500,13 +507,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5C9E127F2AAE62A500C9D8FF /* libgmpxx.a in Frameworks */, - 5C9E12812AAE62A500C9D8FF /* libffi.a in Frameworks */, - 5C9E12802AAE62A500C9D8FF /* libgmp.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, + 5C5625082ABCBD3200A21210 /* libgmp.a in Frameworks */, + 5C5625062ABCBD3200A21210 /* libffi.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, - 5C9E127E2AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t-ghc8.10.7.a in Frameworks */, - 5C9E12822AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t.a in Frameworks */, + 5C5625092ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo.a in Frameworks */, + 5C5625072ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo-ghc8.10.7.a in Frameworks */, + 5C56250A2ABCBD3200A21210 /* libgmpxx.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -567,11 +574,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 5C9E127C2AAE62A500C9D8FF /* libffi.a */, - 5C9E127B2AAE62A500C9D8FF /* libgmp.a */, - 5C9E127A2AAE62A500C9D8FF /* libgmpxx.a */, - 5C9E12792AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t-ghc8.10.7.a */, - 5C9E127D2AAE62A500C9D8FF /* libHSsimplex-chat-5.3.0.7-6JlIR0UqFTrEzd5R0Y6B8t.a */, + 5C5625012ABCBD3200A21210 /* libffi.a */, + 5C5625032ABCBD3200A21210 /* libgmp.a */, + 5C5625052ABCBD3200A21210 /* libgmpxx.a */, + 5C5625022ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo-ghc8.10.7.a */, + 5C5625042ABCBD3200A21210 /* libHSsimplex-chat-5.3.0.9-JpoF1vnleecHyL9iiCdgEo.a */, ); path = Libraries; sourceTree = ""; @@ -822,6 +829,7 @@ 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */, 18415FD2E36F13F596A45BB4 /* CIVideoView.swift */, 5CC868F229EB540C0017BBFD /* CIRcvDecryptionError.swift */, + 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */, ); path = ChatItem; sourceTree = ""; @@ -837,6 +845,7 @@ 3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */, 644EFFDD292BCD9D00525D5B /* ComposeVoiceView.swift */, D72A9087294BD7A70047C86D /* NativeTextEditor.swift */, + 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */, ); path = ComposeMessage; sourceTree = ""; @@ -1014,6 +1023,7 @@ th, fi, uk, + bg, ); mainGroup = 5CA059BD279559F40002BEB4; packageReferences = ( @@ -1094,6 +1104,7 @@ 5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */, 5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */, 5CBD285A295711D700EC2CF4 /* ImageUtils.swift in Sources */, + 6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */, 5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */, 5C3F1D562842B68D00EC8A82 /* IntegrityErrorItemView.swift in Sources */, 5C029EAA283942EA004A9677 /* CallController.swift in Sources */, @@ -1155,6 +1166,7 @@ 5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */, 5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */, 6442E0BA287F169300CEC0F9 /* AddGroupView.swift in Sources */, + 6419EC582AB97507004A607A /* CIMemberCreatedContactView.swift in Sources */, 64D0C2C229FA57AB00B38D5F /* UserAddressLearnMore.swift in Sources */, 64466DCC29FFE3E800E3D48D /* MailView.swift in Sources */, 5C971E2127AEBF8300C8A3CE /* ChatInfoImage.swift in Sources */, @@ -1297,6 +1309,7 @@ 5CA3ED502A9422D1005D71E2 /* th */, 5C136D8F2AAB3D14006DE2FC /* fi */, 5C636F672AAB3D2400751C84 /* uk */, + 5C5B67932ABAF56000DA9412 /* bg */, ); name = InfoPlist.strings; sourceTree = ""; @@ -1318,6 +1331,7 @@ 5CA3ED4D2A942170005D71E2 /* th */, 5CE6C7B32AAB1515007F345C /* fi */, 5CE6C7B42AAB1527007F345C /* uk */, + 5C5B67912ABAF4B500DA9412 /* bg */, ); name = Localizable.strings; sourceTree = ""; @@ -1338,6 +1352,7 @@ 5CA3ED4F2A9422D1005D71E2 /* th */, 5C136D8E2AAB3D14006DE2FC /* fi */, 5C636F662AAB3D2400751C84 /* uk */, + 5C5B67922ABAF56000DA9412 /* bg */, ); name = "SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; @@ -1471,7 +1486,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 170; + CURRENT_PROJECT_VERSION = 171; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_PREVIEWS = YES; @@ -1513,7 +1528,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 170; + CURRENT_PROJECT_VERSION = 171; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_PREVIEWS = YES; @@ -1593,7 +1608,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 170; + CURRENT_PROJECT_VERSION = 171; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GENERATE_INFOPLIST_FILE = YES; @@ -1625,7 +1640,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 170; + CURRENT_PROJECT_VERSION = 171; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GENERATE_INFOPLIST_FILE = YES; @@ -1657,7 +1672,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 170; + CURRENT_PROJECT_VERSION = 171; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1703,7 +1718,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 170; + CURRENT_PROJECT_VERSION = 171; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 635534fea0..b0834f5715 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -61,6 +61,8 @@ public enum ChatCommand { case apiGroupLinkMemberRole(groupId: Int64, memberRole: GroupMemberRole) case apiDeleteGroupLink(groupId: Int64) case apiGetGroupLink(groupId: Int64) + case apiCreateMemberContact(groupId: Int64, groupMemberId: Int64) + case apiSendMemberContactInvitation(contactId: Int64, msg: MsgContent) case apiGetUserProtoServers(userId: Int64, serverProtocol: ServerProtocol) case apiSetUserProtoServers(userId: Int64, serverProtocol: ServerProtocol, servers: [ServerCfg]) case apiTestProtoServer(userId: Int64, server: String) @@ -181,6 +183,8 @@ public enum ChatCommand { case let .apiGroupLinkMemberRole(groupId, memberRole): return "/_set link role #\(groupId) \(memberRole)" case let .apiDeleteGroupLink(groupId): return "/_delete link #\(groupId)" case let .apiGetGroupLink(groupId): return "/_get link #\(groupId)" + case let .apiCreateMemberContact(groupId, groupMemberId): return "/_create member contact #\(groupId) \(groupMemberId)" + case let .apiSendMemberContactInvitation(contactId, mc): return "/_invite member contact @\(contactId) \(mc.cmdString)" case let .apiGetUserProtoServers(userId, serverProtocol): return "/_servers \(userId) \(serverProtocol)" case let .apiSetUserProtoServers(userId, serverProtocol, servers): return "/_servers \(userId) \(serverProtocol) \(protoServersStr(servers))" case let .apiTestProtoServer(userId, server): return "/_server test \(userId) \(server)" @@ -304,6 +308,8 @@ public enum ChatCommand { case .apiGroupLinkMemberRole: return "apiGroupLinkMemberRole" case .apiDeleteGroupLink: return "apiDeleteGroupLink" case .apiGetGroupLink: return "apiGetGroupLink" + case .apiCreateMemberContact: return "apiCreateMemberContact" + case .apiSendMemberContactInvitation: return "apiSendMemberContactInvitation" case .apiGetUserProtoServers: return "apiGetUserProtoServers" case .apiSetUserProtoServers: return "apiSetUserProtoServers" case .apiTestProtoServer: return "apiTestProtoServer" @@ -514,6 +520,9 @@ public enum ChatResponse: Decodable, Error { case groupLinkCreated(user: UserRef, groupInfo: GroupInfo, connReqContact: String, memberRole: GroupMemberRole) case groupLink(user: UserRef, groupInfo: GroupInfo, connReqContact: String, memberRole: GroupMemberRole) case groupLinkDeleted(user: UserRef, groupInfo: GroupInfo) + case newMemberContact(user: UserRef, contact: Contact, groupInfo: GroupInfo, member: GroupMember) + case newMemberContactSentInv(user: UserRef, contact: Contact, groupInfo: GroupInfo, member: GroupMember) + case newMemberContactReceivedInv(user: UserRef, contact: Contact, groupInfo: GroupInfo, member: GroupMember) // receiving file events case rcvFileAccepted(user: UserRef, chatItem: AChatItem) case rcvFileAcceptedSndCancelled(user: UserRef, rcvFileTransfer: RcvFileTransfer) @@ -647,6 +656,9 @@ public enum ChatResponse: Decodable, Error { case .groupLinkCreated: return "groupLinkCreated" case .groupLink: return "groupLink" case .groupLinkDeleted: return "groupLinkDeleted" + case .newMemberContact: return "newMemberContact" + case .newMemberContactSentInv: return "newMemberContactSentInv" + case .newMemberContactReceivedInv: return "newMemberContactReceivedInv" case .rcvFileAccepted: return "rcvFileAccepted" case .rcvFileAcceptedSndCancelled: return "rcvFileAcceptedSndCancelled" case .rcvFileStart: return "rcvFileStart" @@ -780,6 +792,9 @@ public enum ChatResponse: Decodable, Error { case let .groupLinkCreated(u, groupInfo, connReqContact, memberRole): return withUser(u, "groupInfo: \(groupInfo)\nconnReqContact: \(connReqContact)\nmemberRole: \(memberRole)") case let .groupLink(u, groupInfo, connReqContact, memberRole): return withUser(u, "groupInfo: \(groupInfo)\nconnReqContact: \(connReqContact)\nmemberRole: \(memberRole)") case let .groupLinkDeleted(u, groupInfo): return withUser(u, String(describing: groupInfo)) + case let .newMemberContact(u, contact, groupInfo, member): return withUser(u, "contact: \(contact)\ngroupInfo: \(groupInfo)\nmember: \(member)") + case let .newMemberContactSentInv(u, contact, groupInfo, member): return withUser(u, "contact: \(contact)\ngroupInfo: \(groupInfo)\nmember: \(member)") + case let .newMemberContactReceivedInv(u, contact, groupInfo, member): return withUser(u, "contact: \(contact)\ngroupInfo: \(groupInfo)\nmember: \(member)") case let .rcvFileAccepted(u, chatItem): return withUser(u, String(describing: chatItem)) case .rcvFileAcceptedSndCancelled: return noDetails case let .rcvFileStart(u, chatItem): return withUser(u, String(describing: chatItem)) @@ -1077,7 +1092,7 @@ public struct NetCfg: Codable, Equatable { sessionMode: TransportSessionMode.user, tcpConnectTimeout: 15_000_000, tcpTimeout: 10_000_000, - tcpTimeoutPerKb: 20_000, + tcpTimeoutPerKb: 30_000, tcpKeepAlive: KeepAliveOpts.defaults, smpPingInterval: 1200_000_000, smpPingCount: 3, @@ -1089,7 +1104,7 @@ public struct NetCfg: Codable, Equatable { sessionMode: TransportSessionMode.user, tcpConnectTimeout: 30_000_000, tcpTimeout: 20_000_000, - tcpTimeoutPerKb: 40_000, + tcpTimeoutPerKb: 60_000, tcpKeepAlive: KeepAliveOpts.defaults, smpPingInterval: 1200_000_000, smpPingCount: 3, @@ -1454,6 +1469,7 @@ public enum ChatErrorType: Decodable { case agentCommandError(message: String) case invalidFileDescription(message: String) case connectionIncognitoChangeProhibited + case peerChatVRangeIncompatible case internalError(message: String) case exception(message: String) } @@ -1479,6 +1495,7 @@ public enum StoreError: Decodable { case groupMemberNameNotFound(groupId: Int64, groupMemberName: ContactName) case groupMemberNotFound(groupMemberId: Int64) case groupMemberNotFoundByMemberId(memberId: String) + case memberContactGroupMemberNotFound(contactId: Int64) case groupWithoutUser case duplicateGroupMember case groupAlreadyJoined diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index ce8bd426cc..c0ec048572 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -1378,11 +1378,17 @@ public struct Contact: Identifiable, Decodable, NamedChat { public var mergedPreferences: ContactUserPreferences var createdAt: Date var updatedAt: Date + var contactGroupMemberId: Int64? + var contactGrpInvSent: Bool public var id: ChatId { get { "@\(contactId)" } } public var apiId: Int64 { get { contactId } } public var ready: Bool { get { activeConn.connStatus == .ready } } - public var sendMsgEnabled: Bool { get { !(activeConn.connectionStats?.ratchetSyncSendProhibited ?? false) } } + public var sendMsgEnabled: Bool { get { + (ready && !(activeConn.connectionStats?.ratchetSyncSendProhibited ?? false)) + || nextSendGrpInv + } } + public var nextSendGrpInv: Bool { get { contactGroupMemberId != nil && !contactGrpInvSent } } public var displayName: String { localAlias == "" ? profile.displayName : localAlias } public var fullName: String { get { profile.fullName } } public var image: String? { get { profile.image } } @@ -1428,7 +1434,8 @@ public struct Contact: Identifiable, Decodable, NamedChat { userPreferences: Preferences.sampleData, mergedPreferences: ContactUserPreferences.sampleData, createdAt: .now, - updatedAt: .now + updatedAt: .now, + contactGrpInvSent: false ) } @@ -1449,6 +1456,7 @@ public struct ContactSubStatus: Decodable { public struct Connection: Decodable { public var connId: Int64 public var agentConnId: String + public var peerChatVRange: VersionRange var connStatus: ConnStatus public var connLevel: Int public var viaGroupLink: Bool @@ -1458,7 +1466,7 @@ public struct Connection: Decodable { public var connectionStats: ConnectionStats? = nil private enum CodingKeys: String, CodingKey { - case connId, agentConnId, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode + case connId, agentConnId, peerChatVRange, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode } public var id: ChatId { get { ":\(connId)" } } @@ -1466,12 +1474,27 @@ public struct Connection: Decodable { static let sampleData = Connection( connId: 1, agentConnId: "abc", + peerChatVRange: VersionRange(minVersion: 1, maxVersion: 1), connStatus: .ready, connLevel: 0, viaGroupLink: false ) } +public struct VersionRange: Decodable { + public init(minVersion: Int, maxVersion: Int) { + self.minVersion = minVersion + self.maxVersion = maxVersion + } + + public var minVersion: Int + public var maxVersion: Int + + public func isCompatibleRange(_ vRange: VersionRange) -> Bool { + self.minVersion <= vRange.maxVersion && vRange.minVersion <= self.maxVersion + } +} + public struct SecurityCode: Decodable, Equatable { public init(securityCode: String, verifiedAt: Date) { self.securityCode = securityCode @@ -1503,6 +1526,7 @@ public struct UserContact: Decodable { public struct UserContactRequest: Decodable, NamedChat { var contactRequestId: Int64 public var userContactLinkId: Int64 + public var cReqChatVRange: VersionRange var localDisplayName: ContactName var profile: Profile var createdAt: Date @@ -1520,6 +1544,7 @@ public struct UserContactRequest: Decodable, NamedChat { public static let sampleData = UserContactRequest( contactRequestId: 1, userContactLinkId: 1, + cReqChatVRange: VersionRange(minVersion: 1, maxVersion: 1), localDisplayName: "alice", profile: Profile.sampleData, createdAt: .now, @@ -2078,6 +2103,7 @@ public struct ChatItem: Identifiable, Decodable { case .memberLeft: return false case .memberDeleted: return false case .invitedViaGroupLink: return false + case .memberCreatedContact: return false } case .sndGroupEvent: return showNtfDir case .rcvConnEvent: return false @@ -2118,7 +2144,6 @@ public struct ChatItem: Identifiable, Decodable { } public var encryptLocalFile: Bool { - file?.fileProtocol == .xftp && content.msgContent?.isVideo == false && privacyEncryptLocalFilesGroupDefault.get() } @@ -3181,6 +3206,7 @@ public enum RcvGroupEvent: Decodable { case groupDeleted case groupUpdated(groupProfile: GroupProfile) case invitedViaGroupLink + case memberCreatedContact var text: String { switch self { @@ -3198,6 +3224,7 @@ public enum RcvGroupEvent: Decodable { case .groupDeleted: return NSLocalizedString("deleted group", comment: "rcv group event chat item") case .groupUpdated: return NSLocalizedString("updated group profile", comment: "rcv group event chat item") case .invitedViaGroupLink: return NSLocalizedString("invited via your group link", comment: "rcv group event chat item") + case .memberCreatedContact: return NSLocalizedString("connected directly", comment: "rcv group event chat item") } } } diff --git a/apps/ios/bg.lproj/Localizable.strings b/apps/ios/bg.lproj/Localizable.strings new file mode 100644 index 0000000000..c01e3d7e66 --- /dev/null +++ b/apps/ios/bg.lproj/Localizable.strings @@ -0,0 +1,3711 @@ +/* No comment provided by engineer. */ +"\n" = "\n"; + +/* No comment provided by engineer. */ +" " = " "; + +/* No comment provided by engineer. */ +" " = " "; + +/* No comment provided by engineer. */ +" " = " "; + +/* No comment provided by engineer. */ +" (" = " ("; + +/* No comment provided by engineer. */ +" (can be copied)" = " (може да се копира)"; + +/* No comment provided by engineer. */ +"_italic_" = "\\_курсив_"; + +/* No comment provided by engineer. */ +"- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable." = "- свържете се с [директория за услуги](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjd LW3%23%2F%3Fv%3D1-2%26dh %3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (БЕТА)!\n- потвърждениe за доставка (до 20 члена).\n- по-бързо и по-стабилно."; + +/* No comment provided by engineer. */ +"- more stable message delivery.\n- a bit better groups.\n- and more!" = "- по-стабилна доставка на съобщения.\n- малко по-добри групи.\n- и още!"; + +/* No comment provided by engineer. */ +"- voice messages up to 5 minutes.\n- custom time to disappear.\n- editing history." = "- гласови съобщения до 5 минути.\n- персонализирано време за изчезване.\n- история на редактиране."; + +/* No comment provided by engineer. */ +", " = ", "; + +/* No comment provided by engineer. */ +": " = ": "; + +/* No comment provided by engineer. */ +"!1 colored!" = "!1 цветно!"; + +/* No comment provided by engineer. */ +"." = "."; + +/* No comment provided by engineer. */ +"(" = "("; + +/* No comment provided by engineer. */ +")" = ")"; + +/* No comment provided by engineer. */ +"[Contribute](https://github.com/simplex-chat/simplex-chat#contribute)" = "[Допринеси](https://github.com/simplex-chat/simplex-chat#contribute)"; + +/* No comment provided by engineer. */ +"[Send us email](mailto:chat@simplex.chat)" = "[Изпратете ни имейл](mailto:chat@simplex.chat)"; + +/* No comment provided by engineer. */ +"[Star on GitHub](https://github.com/simplex-chat/simplex-chat)" = "[Звезда в GitHub](https://github.com/simplex-chat/simplex-chat)"; + +/* No comment provided by engineer. */ +"**Add new contact**: to create your one-time QR Code for your contact." = "**Добави нов контакт**: за да създадете своя еднократен QR код или линк за вашия контакт."; + +/* No comment provided by engineer. */ +"**Create link / QR code** for your contact to use." = "**Създай линк / QR код**, който вашият контакт да използва."; + +/* No comment provided by engineer. */ +"**e2e encrypted** audio call" = "**e2e криптиран**аудио разговор"; + +/* No comment provided by engineer. */ +"**e2e encrypted** video call" = "**e2e криптирано** видео разговор"; + +/* No comment provided by engineer. */ +"**More private**: check new messages every 20 minutes. Device token is shared with SimpleX Chat server, but not how many contacts or messages you have." = "**По поверително**: проверявайте новите съобщения на всеки 20 минути. Токенът на устройството се споделя със сървъра за чат SimpleX, но не и колко контакти или съобщения имате."; + +/* No comment provided by engineer. */ +"**Most private**: do not use SimpleX Chat notifications server, check messages periodically in the background (depends on how often you use the app)." = "**Най-поверително**: не използвайте сървъра за известия SimpleX Chat, периодично проверявайте съобщенията във фонов режим (зависи от това колко често използвате приложението)."; + +/* No comment provided by engineer. */ +"**Paste received link** or open it in the browser and tap **Open in mobile app**." = "**Поставете получения линк** или го отворете в браузъра и докоснете **Отваряне в мобилно приложение**."; + +/* No comment provided by engineer. */ +"**Please note**: you will NOT be able to recover or change passphrase if you lose it." = "**Моля, обърнете внимание**: НЯМА да можете да възстановите или промените паролата, ако я загубите."; + +/* No comment provided by engineer. */ +"**Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from." = "**Препоръчително**: токенът на устройството и известията се изпращат до сървъра за уведомяване на SimpleX Chat, но не и съдържанието, размерът на съобщението или от кого е."; + +/* No comment provided by engineer. */ +"**Scan QR code**: to connect to your contact in person or via video call." = "**Сканирай QR код**: за да се свържете с вашия контакт лично или чрез видеообаждане."; + +/* No comment provided by engineer. */ +"**Warning**: Instant push notifications require passphrase saved in Keychain." = "**Внимание**: Незабавните push известия изискват парола, запазена в Keychain."; + +/* No comment provided by engineer. */ +"*bold*" = "\\*удебелен*"; + +/* copied message info title, # */ +"# %@" = "# %@"; + +/* copied message info */ +"## History" = "## История"; + +/* copied message info */ +"## In reply to" = "## В отговор на"; + +/* No comment provided by engineer. */ +"#secret#" = "#тайно#"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ (current)" = "%@ (текущ)"; + +/* copied message info */ +"%@ (current):" = "%@ (текущ):"; + +/* No comment provided by engineer. */ +"%@ / %@" = "%@ / %@"; + +/* No comment provided by engineer. */ +"%@ %@" = "%@ %@"; + +/* No comment provided by engineer. */ +"%@ and %@ connected" = "%@ и %@ са свързани"; + +/* copied message info, <sender> at <time> */ +"%@ at %@:" = "%1$@ в %2$@:"; + +/* notification title */ +"%@ is connected!" = "%@ е свързан!"; + +/* No comment provided by engineer. */ +"%@ is not verified" = "%@ не е потвърдено"; + +/* No comment provided by engineer. */ +"%@ is verified" = "%@ е потвърдено"; + +/* No comment provided by engineer. */ +"%@ servers" = "%@ сървъри"; + +/* notification title */ +"%@ wants to connect!" = "%@ иска да се свърже!"; + +/* No comment provided by engineer. */ +"%@, %@ and %lld other members connected" = "%@, %@ и %lld други членове са свързани"; + +/* copied message info */ +"%@:" = "%@:"; + +/* time interval */ +"%d days" = "%d дни"; + +/* time interval */ +"%d hours" = "%d часа"; + +/* time interval */ +"%d min" = "%d мин."; + +/* time interval */ +"%d months" = "%d месеца"; + +/* time interval */ +"%d sec" = "%d сек."; + +/* integrity error chat item */ +"%d skipped message(s)" = "%d пропуснато(и) съобщение(я)"; + +/* time interval */ +"%d weeks" = "%d седмици"; + +/* No comment provided by engineer. */ +"%lld" = "%lld"; + +/* No comment provided by engineer. */ +"%lld %@" = "%lld %@"; + +/* No comment provided by engineer. */ +"%lld contact(s) selected" = "%lld избран(и) контакт(а)"; + +/* No comment provided by engineer. */ +"%lld file(s) with total size of %@" = "%lld файл(а) с общ размер от %@"; + +/* No comment provided by engineer. */ +"%lld members" = "%lld членове"; + +/* No comment provided by engineer. */ +"%lld minutes" = "%lld минути"; + +/* No comment provided by engineer. */ +"%lld new interface languages" = "%lld нови езици на интерфейса"; + +/* No comment provided by engineer. */ +"%lld second(s)" = "%lld секунда(и)"; + +/* No comment provided by engineer. */ +"%lld seconds" = "%lld секунди"; + +/* No comment provided by engineer. */ +"%lldd" = "%lldд"; + +/* No comment provided by engineer. */ +"%lldh" = "%lldч"; + +/* No comment provided by engineer. */ +"%lldk" = "%lldk"; + +/* No comment provided by engineer. */ +"%lldm" = "%lldм"; + +/* No comment provided by engineer. */ +"%lldmth" = "%lldмесц."; + +/* No comment provided by engineer. */ +"%llds" = "%lldс"; + +/* No comment provided by engineer. */ +"%lldw" = "%lldсед."; + +/* No comment provided by engineer. */ +"%u messages failed to decrypt." = "%u съобщения не успяха да се декриптират."; + +/* No comment provided by engineer. */ +"%u messages skipped." = "%u пропуснати съобщения."; + +/* No comment provided by engineer. */ +"`a + b`" = "\\`a + b`"; + +/* email text */ +"<p>Hi!</p>\n<p><a href=\"%@\">Connect to me via SimpleX Chat</a></p>" = "<p>Здравейте!</p>\n<p><a href=\"%@\">Свържете се с мен чрез SimpleX Chat</a></p>"; + +/* No comment provided by engineer. */ +"~strike~" = "\\~зачеркнат~"; + +/* No comment provided by engineer. */ +"0s" = "0s"; + +/* time interval */ +"1 day" = "1 ден"; + +/* time interval */ +"1 hour" = "1 час"; + +/* No comment provided by engineer. */ +"1 minute" = "1 минута"; + +/* time interval */ +"1 month" = "1 месец"; + +/* time interval */ +"1 week" = "1 седмица"; + +/* No comment provided by engineer. */ +"1-time link" = "Еднократен линк"; + +/* No comment provided by engineer. */ +"5 minutes" = "5 минути"; + +/* No comment provided by engineer. */ +"6" = "6"; + +/* No comment provided by engineer. */ +"30 seconds" = "30 секунди"; + +/* No comment provided by engineer. */ +"A few more things" = "Още няколко неща"; + +/* notification title */ +"A new contact" = "Нов контакт"; + +/* No comment provided by engineer. */ +"A new random profile will be shared." = "Нов автоматично генериран профил ще бъде споделен."; + +/* No comment provided by engineer. */ +"A separate TCP connection will be used **for each chat profile you have in the app**." = "Ще се използва отделна TCP връзка **за всеки чатпрофил, който имате в приложението**."; + +/* No comment provided by engineer. */ +"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." = "Ще се използва отделна TCP връзка **за всеки контакт и член на групата**.\n**Моля, обърнете внимание**: ако имате много връзки, консумацията на батерията и трафика може да бъде значително по-висока и някои връзки може да се провалят."; + +/* No comment provided by engineer. */ +"Abort" = "Откажи"; + +/* No comment provided by engineer. */ +"Abort changing address" = "Откажи смяна на адрес"; + +/* No comment provided by engineer. */ +"Abort changing address?" = "Откажи смяна на адрес?"; + +/* No comment provided by engineer. */ +"About SimpleX" = "За SimpleX"; + +/* No comment provided by engineer. */ +"About SimpleX address" = "Повече за SimpleX адреса"; + +/* No comment provided by engineer. */ +"About SimpleX Chat" = "За SimpleX Chat"; + +/* No comment provided by engineer. */ +"above, then choose:" = "по-горе, след това избери:"; + +/* No comment provided by engineer. */ +"Accent color" = "Основен цвят"; + +/* accept contact request via notification + accept incoming call via notification */ +"Accept" = "Приеми"; + +/* No comment provided by engineer. */ +"Accept connection request?" = "Приемане на заявка за връзка?"; + +/* notification body */ +"Accept contact request from %@?" = "Приемане на заявка за контакт от %@?"; + +/* accept contact request via notification */ +"Accept incognito" = "Приеми инкогнито"; + +/* call status */ +"accepted call" = "обаждането прието"; + +/* No comment provided by engineer. */ +"Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." = "Добавете адрес към вашия профил, така че вашите контакти да могат да го споделят с други хора. Актуализацията на профила ще бъде изпратена до вашите контакти."; + +/* No comment provided by engineer. */ +"Add preset servers" = "Добави предварително зададени сървъри"; + +/* No comment provided by engineer. */ +"Add profile" = "Добави профил"; + +/* No comment provided by engineer. */ +"Add server…" = "Добави сървър…"; + +/* No comment provided by engineer. */ +"Add servers by scanning QR codes." = "Добави сървъри чрез сканиране на QR кодове."; + +/* No comment provided by engineer. */ +"Add to another device" = "Добави към друго устройство"; + +/* No comment provided by engineer. */ +"Add welcome message" = "Добави съобщение при посрещане"; + +/* No comment provided by engineer. */ +"Address" = "Адрес"; + +/* No comment provided by engineer. */ +"Address change will be aborted. Old receiving address will be used." = "Промяната на адреса ще бъде прекъсната. Ще се използва старият адрес за получаване."; + +/* member role */ +"admin" = "админ"; + +/* No comment provided by engineer. */ +"Admins can create the links to join groups." = "Админите могат да създадат линкове за присъединяване към групи."; + +/* No comment provided by engineer. */ +"Advanced network settings" = "Разширени мрежови настройки"; + +/* chat item text */ +"agreeing encryption for %@…" = "съгласуване на криптиране за %@…"; + +/* chat item text */ +"agreeing encryption…" = "съгласуване на криптиране…"; + +/* No comment provided by engineer. */ +"All app data is deleted." = "Всички данни от приложението бяха изтрити."; + +/* No comment provided by engineer. */ +"All chats and messages will be deleted - this cannot be undone!" = "Всички чатове и съобщения ще бъдат изтрити - това не може да бъде отменено!"; + +/* No comment provided by engineer. */ +"All data is erased when it is entered." = "Всички данни се изтриват при въвеждане."; + +/* No comment provided by engineer. */ +"All group members will remain connected." = "Всички членове на групата ще останат свързани."; + +/* No comment provided by engineer. */ +"All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Всички съобщения ще бъдат изтрити - това не може да бъде отменено! Съобщенията ще бъдат изтрити САМО за вас."; + +/* No comment provided by engineer. */ +"All your contacts will remain connected." = "Всички ваши контакти ще останат свързани."; + +/* No comment provided by engineer. */ +"All your contacts will remain connected. Profile update will be sent to your contacts." = "Всички ваши контакти ще останат свързани. Актуализацията на профила ще бъде изпратена до вашите контакти."; + +/* No comment provided by engineer. */ +"Allow" = "Позволи"; + +/* No comment provided by engineer. */ +"Allow calls only if your contact allows them." = "Позволи обаждания само ако вашият контакт ги разрешава."; + +/* No comment provided by engineer. */ +"Allow disappearing messages only if your contact allows it to you." = "Позволи изчезващи съобщения само ако вашият контакт ги разрешава."; + +/* No comment provided by engineer. */ +"Allow irreversible message deletion only if your contact allows it to you." = "Позволи необратимо изтриване на съобщение само ако вашият контакт го рарешава."; + +/* No comment provided by engineer. */ +"Allow message reactions only if your contact allows them." = "Позволи реакции на съобщения само ако вашият контакт ги разрешава."; + +/* No comment provided by engineer. */ +"Allow message reactions." = "Позволи реакции на съобщения."; + +/* No comment provided by engineer. */ +"Allow sending direct messages to members." = "Позволи изпращането на лични съобщения до членовете."; + +/* No comment provided by engineer. */ +"Allow sending disappearing messages." = "Разреши изпращането на изчезващи съобщения."; + +/* No comment provided by engineer. */ +"Allow to irreversibly delete sent messages." = "Позволи необратимо изтриване на изпратените съобщения."; + +/* No comment provided by engineer. */ +"Allow to send files and media." = "Позволи изпращане на файлове и медия."; + +/* No comment provided by engineer. */ +"Allow to send voice messages." = "Позволи изпращане на гласови съобщения."; + +/* No comment provided by engineer. */ +"Allow voice messages only if your contact allows them." = "Позволи гласови съобщения само ако вашият контакт ги разрешава."; + +/* No comment provided by engineer. */ +"Allow voice messages?" = "Позволи гласови съобщения?"; + +/* No comment provided by engineer. */ +"Allow your contacts adding message reactions." = "Позволи на вашите контакти да добавят реакции към съобщения."; + +/* No comment provided by engineer. */ +"Allow your contacts to call you." = "Позволи на вашите контакти да ви се обаждат."; + +/* No comment provided by engineer. */ +"Allow your contacts to irreversibly delete sent messages." = "Позволи на вашите контакти да изтриват необратимо изпратените съобщения."; + +/* No comment provided by engineer. */ +"Allow your contacts to send disappearing messages." = "Позволи на вашите контакти да изпращат изчезващи съобщения."; + +/* No comment provided by engineer. */ +"Allow your contacts to send voice messages." = "Позволи на вашите контакти да изпращат гласови съобщения."; + +/* No comment provided by engineer. */ +"Already connected?" = "Вече сте свързани?"; + +/* pref value */ +"always" = "винаги"; + +/* No comment provided by engineer. */ +"Always use relay" = "Винаги използвай реле"; + +/* No comment provided by engineer. */ +"An empty chat profile with the provided name is created, and the app opens as usual." = "Създаен беше празен профил за чат с предоставеното име и приложението се отвари както обикновено."; + +/* No comment provided by engineer. */ +"Answer call" = "Отговор на повикване"; + +/* No comment provided by engineer. */ +"App build: %@" = "Компилация на приложението: %@"; + +/* No comment provided by engineer. */ +"App encrypts new local files (except videos)." = "Приложението криптира нови локални файлове (с изключение на видеоклипове)."; + +/* No comment provided by engineer. */ +"App icon" = "Икона на приложението"; + +/* No comment provided by engineer. */ +"App passcode" = "Код за достъп до приложението"; + +/* No comment provided by engineer. */ +"App passcode is replaced with self-destruct passcode." = "Кода за достъп до приложение се заменя с код за самоунищожение."; + +/* No comment provided by engineer. */ +"App version" = "Версия на приложението"; + +/* No comment provided by engineer. */ +"App version: v%@" = "Версия на приложението: v%@"; + +/* No comment provided by engineer. */ +"Appearance" = "Изглед"; + +/* No comment provided by engineer. */ +"Attach" = "Прикачи"; + +/* No comment provided by engineer. */ +"Audio & video calls" = "Аудио и видео разговори"; + +/* No comment provided by engineer. */ +"Audio and video calls" = "Аудио и видео разговори"; + +/* No comment provided by engineer. */ +"audio call (not e2e encrypted)" = "аудио разговор (не е e2e криптиран)"; + +/* chat feature */ +"Audio/video calls" = "Аудио/видео разговори"; + +/* No comment provided by engineer. */ +"Audio/video calls are prohibited." = "Аудио/видео разговорите са забранени."; + +/* PIN entry */ +"Authentication cancelled" = "Идентификацията е отменена"; + +/* No comment provided by engineer. */ +"Authentication failed" = "Неуспешна идентификация"; + +/* No comment provided by engineer. */ +"Authentication is required before the call is connected, but you may miss calls." = "Изисква се идентификацията, преди да се осъществи обаждането, но може да пропуснете повиквания."; + +/* No comment provided by engineer. */ +"Authentication unavailable" = "Идентификацията е недостъпна"; + +/* No comment provided by engineer. */ +"Auto-accept" = "Автоматично приемане"; + +/* No comment provided by engineer. */ +"Auto-accept contact requests" = "Автоматично приемане на заявки за контакт"; + +/* No comment provided by engineer. */ +"Auto-accept images" = "Автоматично приемане на изображения"; + +/* No comment provided by engineer. */ +"Back" = "Назад"; + +/* integrity error chat item */ +"bad message hash" = "лош хеш на съобщението"; + +/* No comment provided by engineer. */ +"Bad message hash" = "Лош хеш на съобщението"; + +/* integrity error chat item */ +"bad message ID" = "лошо ID на съобщението"; + +/* No comment provided by engineer. */ +"Bad message ID" = "Лошо ID на съобщението"; + +/* No comment provided by engineer. */ +"Better messages" = "По-добри съобщения"; + +/* No comment provided by engineer. */ +"bold" = "удебелен"; + +/* No comment provided by engineer. */ +"Both you and your contact can add message reactions." = "И вие, и вашият контакт можете да добавяте реакции към съобщението."; + +/* No comment provided by engineer. */ +"Both you and your contact can irreversibly delete sent messages." = "И вие, и вашият контакт можете да изтриете необратимо изпратените съобщения."; + +/* No comment provided by engineer. */ +"Both you and your contact can make calls." = "И вие, и вашият контакт можете да осъществявате обаждания."; + +/* No comment provided by engineer. */ +"Both you and your contact can send disappearing messages." = "И вие, и вашият контакт можете да изпращате изчезващи съобщения."; + +/* No comment provided by engineer. */ +"Both you and your contact can send voice messages." = "И вие, и вашият контакт можете да изпращате гласови съобщения."; + +/* No comment provided by engineer. */ +"Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Български, финландски, тайландски и украински - благодарение на потребителите и [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"; + +/* 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)." = "Чрез чат профил (по подразбиране) или [чрез връзка](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (БЕТА)."; + +/* No comment provided by engineer. */ +"Call already ended!" = "Разговорът вече приключи!"; + +/* call status */ +"call error" = "грешка при повикване"; + +/* call status */ +"call in progress" = "в момента тече разговор"; + +/* call status */ +"calling…" = "повикване…"; + +/* No comment provided by engineer. */ +"Calls" = "Обаждания"; + +/* No comment provided by engineer. */ +"Can't delete user profile!" = "Потребителският профил не може да се изтрие!"; + +/* No comment provided by engineer. */ +"Can't invite contact!" = "Не може да покани контакта!"; + +/* No comment provided by engineer. */ +"Can't invite contacts!" = "Не може да поканят контактите!"; + +/* No comment provided by engineer. */ +"Cancel" = "Отказ"; + +/* feature offered item */ +"cancelled %@" = "отменен %@"; + +/* No comment provided by engineer. */ +"Cannot access keychain to save database password" = "Няма достъп до Keychain за запазване на паролата за базата данни"; + +/* No comment provided by engineer. */ +"Cannot receive file" = "Файлът не може да бъде получен"; + +/* No comment provided by engineer. */ +"Change" = "Промени"; + +/* No comment provided by engineer. */ +"Change database passphrase?" = "Промяна на паролата на базата данни?"; + +/* authentication reason */ +"Change lock mode" = "Промяна на режима на заключване"; + +/* No comment provided by engineer. */ +"Change member role?" = "Промяна на ролята на члена?"; + +/* authentication reason */ +"Change passcode" = "Промени kодa за достъп"; + +/* No comment provided by engineer. */ +"Change receiving address" = "Промени адреса за получаване"; + +/* No comment provided by engineer. */ +"Change receiving address?" = "Промени адреса за получаване?"; + +/* No comment provided by engineer. */ +"Change role" = "Промени ролята"; + +/* authentication reason */ +"Change self-destruct mode" = "Промени режима на самоунищожение"; + +/* authentication reason + set passcode view */ +"Change self-destruct passcode" = "Промени кода за достъп за самоунищожение"; + +/* chat item text */ +"changed address for you" = "променен е адреса за вас"; + +/* rcv group event chat item */ +"changed role of %@ to %@" = "променена роля от %1$@ на %2$@"; + +/* rcv group event chat item */ +"changed your role to %@" = "променена е вашата ролята на %@"; + +/* chat item text */ +"changing address for %@…" = "промяна на адреса за %@…"; + +/* chat item text */ +"changing address…" = "промяна на адреса…"; + +/* No comment provided by engineer. */ +"Chat archive" = "Архив на чата"; + +/* No comment provided by engineer. */ +"Chat console" = "Конзола"; + +/* No comment provided by engineer. */ +"Chat database" = "База данни за чата"; + +/* No comment provided by engineer. */ +"Chat database deleted" = "Базата данни на чата е изтрита"; + +/* No comment provided by engineer. */ +"Chat database imported" = "Базата данни на чат е импортирана"; + +/* No comment provided by engineer. */ +"Chat is running" = "Чатът работи"; + +/* No comment provided by engineer. */ +"Chat is stopped" = "Чатът е спрян"; + +/* No comment provided by engineer. */ +"Chat preferences" = "Чат настройки"; + +/* No comment provided by engineer. */ +"Chats" = "Чатове"; + +/* No comment provided by engineer. */ +"Check server address and try again." = "Проверете адреса на сървъра и опитайте отново."; + +/* No comment provided by engineer. */ +"Chinese and Spanish interface" = "Китайски и Испански интерфейс"; + +/* No comment provided by engineer. */ +"Choose file" = "Избери файл"; + +/* No comment provided by engineer. */ +"Choose from library" = "Избери от библиотеката"; + +/* No comment provided by engineer. */ +"Clear" = "Изчисти"; + +/* No comment provided by engineer. */ +"Clear conversation" = "Изчисти разговора"; + +/* No comment provided by engineer. */ +"Clear conversation?" = "Изчисти разговора?"; + +/* No comment provided by engineer. */ +"Clear verification" = "Изчисти проверката"; + +/* No comment provided by engineer. */ +"colored" = "цветен"; + +/* No comment provided by engineer. */ +"Colors" = "Цветове"; + +/* server test step */ +"Compare file" = "Сравни файл"; + +/* No comment provided by engineer. */ +"Compare security codes with your contacts." = "Сравнете кодовете за сигурност с вашите контакти."; + +/* No comment provided by engineer. */ +"complete" = "завършен"; + +/* No comment provided by engineer. */ +"Configure ICE servers" = "Конфигурирай ICE сървъри"; + +/* No comment provided by engineer. */ +"Confirm" = "Потвърди"; + +/* No comment provided by engineer. */ +"Confirm database upgrades" = "Потвърди актуализаациите на базата данни"; + +/* No comment provided by engineer. */ +"Confirm new passphrase…" = "Потвърди новата парола…"; + +/* No comment provided by engineer. */ +"Confirm Passcode" = "Потвърди kодa за достъп"; + +/* No comment provided by engineer. */ +"Confirm password" = "Потвърди парола"; + +/* server test step */ +"Connect" = "Свързване"; + +/* No comment provided by engineer. */ +"Connect directly" = "Свързване директно"; + +/* No comment provided by engineer. */ +"Connect incognito" = "Свързване инкогнито"; + +/* No comment provided by engineer. */ +"connect to SimpleX Chat developers." = "свържете се с разработчиците на SimpleX Chat."; + +/* No comment provided by engineer. */ +"Connect via contact link" = "Свързване чрез линк на контакта"; + +/* No comment provided by engineer. */ +"Connect via group link?" = "Свързване чрез групов линк?"; + +/* No comment provided by engineer. */ +"Connect via link" = "Свърване чрез линк"; + +/* No comment provided by engineer. */ +"Connect via link / QR code" = "Свърване чрез линк/QR код"; + +/* No comment provided by engineer. */ +"Connect via one-time link" = "Свързване чрез еднократен линк за връзка"; + +/* No comment provided by engineer. */ +"connected" = "свързан"; + +/* No comment provided by engineer. */ +"connecting" = "свързване"; + +/* No comment provided by engineer. */ +"connecting (accepted)" = "свързване (прието)"; + +/* No comment provided by engineer. */ +"connecting (announced)" = "свързване (обявено)"; + +/* No comment provided by engineer. */ +"connecting (introduced)" = "свързване (представен)"; + +/* No comment provided by engineer. */ +"connecting (introduction invitation)" = "свързване (покана за представяне)"; + +/* call status */ +"connecting call" = "разговорът се свързва…"; + +/* No comment provided by engineer. */ +"Connecting server…" = "Свързване със сървъра…"; + +/* No comment provided by engineer. */ +"Connecting server… (error: %@)" = "Свързване със сървър…(грешка: %@)"; + +/* chat list item title */ +"connecting…" = "свързване…"; + +/* No comment provided by engineer. */ +"Connection" = "Връзка"; + +/* No comment provided by engineer. */ +"Connection error" = "Грешка при свързване"; + +/* No comment provided by engineer. */ +"Connection error (AUTH)" = "Грешка при свързване (AUTH)"; + +/* chat list item title (it should not be shown */ +"connection established" = "установена е връзка"; + +/* No comment provided by engineer. */ +"Connection request sent!" = "Заявката за връзка е изпратена!"; + +/* No comment provided by engineer. */ +"Connection timeout" = "Времето на изчакване за установяване на връзката изтече"; + +/* connection information */ +"connection:%@" = "връзка:%@"; + +/* No comment provided by engineer. */ +"Contact allows" = "Контактът позволява"; + +/* No comment provided by engineer. */ +"Contact already exists" = "Контактът вече съществува"; + +/* No comment provided by engineer. */ +"Contact and all messages will be deleted - this cannot be undone!" = "Контактът и всички съобщения ще бъдат изтрити - това не може да бъде отменено!"; + +/* No comment provided by engineer. */ +"contact has e2e encryption" = "контактът има e2e криптиране"; + +/* No comment provided by engineer. */ +"contact has no e2e encryption" = "контактът няма e2e криптиране"; + +/* notification */ +"Contact hidden:" = "Контактът е скрит:"; + +/* notification */ +"Contact is connected" = "Контактът е свързан"; + +/* No comment provided by engineer. */ +"Contact is not connected yet!" = "Контактът все още не е свързан!"; + +/* No comment provided by engineer. */ +"Contact name" = "Име на контакт"; + +/* No comment provided by engineer. */ +"Contact preferences" = "Настройки за контакт"; + +/* No comment provided by engineer. */ +"Contacts" = "Контакти"; + +/* No comment provided by engineer. */ +"Contacts can mark messages for deletion; you will be able to view them." = "Контактите могат да маркират съобщения за изтриване; ще можете да ги разглеждате."; + +/* No comment provided by engineer. */ +"Continue" = "Продължи"; + +/* chat item action */ +"Copy" = "Копирай"; + +/* No comment provided by engineer. */ +"Core version: v%@" = "Версия на ядрото: v%@"; + +/* No comment provided by engineer. */ +"Create" = "Създай"; + +/* No comment provided by engineer. */ +"Create an address to let people connect with you." = "Създайте адрес, за да позволите на хората да се свързват с вас."; + +/* server test step */ +"Create file" = "Създай файл"; + +/* No comment provided by engineer. */ +"Create group link" = "Създай групов линк"; + +/* No comment provided by engineer. */ +"Create link" = "Създай линк"; + +/* No comment provided by engineer. */ +"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Създайте нов профил в [настолното приложение](https://simplex.chat/downloads/). 💻"; + +/* No comment provided by engineer. */ +"Create one-time invitation link" = "Създай линк за еднократна покана"; + +/* server test step */ +"Create queue" = "Създай опашка"; + +/* No comment provided by engineer. */ +"Create secret group" = "Създай тайна група"; + +/* No comment provided by engineer. */ +"Create SimpleX address" = "Създай SimpleX адрес"; + +/* No comment provided by engineer. */ +"Create your profile" = "Създай своя профил"; + +/* No comment provided by engineer. */ +"Created on %@" = "Създаден на %@"; + +/* No comment provided by engineer. */ +"creator" = "създател"; + +/* No comment provided by engineer. */ +"Current Passcode" = "Текущ kод за достъп"; + +/* No comment provided by engineer. */ +"Current passphrase…" = "Текуща парола…"; + +/* No comment provided by engineer. */ +"Currently maximum supported file size is %@." = "В момента максималният поддържан размер на файла е %@."; + +/* dropdown time picker choice */ +"custom" = "персонализиран"; + +/* No comment provided by engineer. */ +"Custom time" = "Персонализирано време"; + +/* No comment provided by engineer. */ +"Dark" = "Тъмна"; + +/* No comment provided by engineer. */ +"Database downgrade" = "Понижаване на версията на базата данни"; + +/* No comment provided by engineer. */ +"Database encrypted!" = "Базата данни е криптирана!"; + +/* No comment provided by engineer. */ +"Database encryption passphrase will be updated and stored in the keychain.\n" = "Паролата за криптиране на базата данни ще бъде актуализирана и съхранена в Keychain.\n"; + +/* No comment provided by engineer. */ +"Database encryption passphrase will be updated.\n" = "Паролата за криптиране на базата данни ще бъде актуализирана.\n"; + +/* No comment provided by engineer. */ +"Database error" = "Грешка в базата данни"; + +/* No comment provided by engineer. */ +"Database ID" = "ID в базата данни"; + +/* copied message info */ +"Database ID: %d" = "ID в базата данни: %d"; + +/* No comment provided by engineer. */ +"Database IDs and Transport isolation option." = "Идентификатори в базата данни и опция за изолация на транспорта."; + +/* No comment provided by engineer. */ +"Database is encrypted using a random passphrase, you can change it." = "Базата данни е криптирана с автоматично генерирана парола, можете да я промените."; + +/* No comment provided by engineer. */ +"Database is encrypted using a random passphrase. Please change it before exporting." = "Базата данни е криптирана с автоматично генерирана парола. Моля, променете я преди експортиране."; + +/* No comment provided by engineer. */ +"Database passphrase" = "Парола за базата данни"; + +/* No comment provided by engineer. */ +"Database passphrase & export" = "Парола за базата данни и експортиране"; + +/* No comment provided by engineer. */ +"Database passphrase is different from saved in the keychain." = "Паролата на базата данни е различна от записаната в Keychain."; + +/* No comment provided by engineer. */ +"Database passphrase is required to open chat." = "Изисква се паролата за базата данни, за да се отвори чата."; + +/* No comment provided by engineer. */ +"Database upgrade" = "Актуализация на базата данни"; + +/* No comment provided by engineer. */ +"database version is newer than the app, but no down migration for: %@" = "версията на базата данни е по-нова от приложението, но няма миграция надолу за: %@"; + +/* No comment provided by engineer. */ +"Database will be encrypted and the passphrase stored in the keychain.\n" = "Базата данни ще бъде криптирана и паролата ще бъде съхранена в Keychain.\n"; + +/* No comment provided by engineer. */ +"Database will be encrypted.\n" = "Базата данни ще бъде криптирана.\n"; + +/* No comment provided by engineer. */ +"Database will be migrated when the app restarts" = "Базата данни ще бъде мигрирана, когато приложението се рестартира"; + +/* time unit */ +"days" = "дни"; + +/* No comment provided by engineer. */ +"Decentralized" = "Децентрализиран"; + +/* message decrypt error item */ +"Decryption error" = "Грешка при декриптиране"; + +/* pref value */ +"default (%@)" = "по подразбиране (%@)"; + +/* No comment provided by engineer. */ +"default (no)" = "по подразбиране (не)"; + +/* No comment provided by engineer. */ +"default (yes)" = "по подразбиране (да)"; + +/* chat item action */ +"Delete" = "Изтрий"; + +/* No comment provided by engineer. */ +"Delete address" = "Изтрий адрес"; + +/* No comment provided by engineer. */ +"Delete address?" = "Изтрий адрес?"; + +/* No comment provided by engineer. */ +"Delete after" = "Изтрий след"; + +/* No comment provided by engineer. */ +"Delete all files" = "Изтрий всички файлове"; + +/* No comment provided by engineer. */ +"Delete archive" = "Изтрий архив"; + +/* No comment provided by engineer. */ +"Delete chat archive?" = "Изтриване на архива на чата?"; + +/* No comment provided by engineer. */ +"Delete chat profile" = "Изтрий чат профила"; + +/* No comment provided by engineer. */ +"Delete chat profile?" = "Изтриване на чат профила?"; + +/* No comment provided by engineer. */ +"Delete connection" = "Изтрий връзката"; + +/* No comment provided by engineer. */ +"Delete contact" = "Изтрий контакт"; + +/* No comment provided by engineer. */ +"Delete Contact" = "Изтрий контакт"; + +/* No comment provided by engineer. */ +"Delete contact?" = "Изтрий контакт?"; + +/* No comment provided by engineer. */ +"Delete database" = "Изтрий базата данни"; + +/* server test step */ +"Delete file" = "Изтрий файл"; + +/* No comment provided by engineer. */ +"Delete files and media?" = "Изтрий файлове и медия?"; + +/* No comment provided by engineer. */ +"Delete files for all chat profiles" = "Изтрий файловете за всички чат профили"; + +/* chat feature */ +"Delete for everyone" = "Изтрий за всички"; + +/* No comment provided by engineer. */ +"Delete for me" = "Изтрий за мен"; + +/* No comment provided by engineer. */ +"Delete group" = "Изтрий група"; + +/* No comment provided by engineer. */ +"Delete group?" = "Изтрий група?"; + +/* No comment provided by engineer. */ +"Delete invitation" = "Изтрий поканата"; + +/* No comment provided by engineer. */ +"Delete link" = "Изтрий линк"; + +/* No comment provided by engineer. */ +"Delete link?" = "Изтрий линк?"; + +/* No comment provided by engineer. */ +"Delete member message?" = "Изтрий съобщението на члена?"; + +/* No comment provided by engineer. */ +"Delete message?" = "Изтрий съобщението?"; + +/* No comment provided by engineer. */ +"Delete messages" = "Изтрий съобщенията"; + +/* No comment provided by engineer. */ +"Delete messages after" = "Изтрий съобщенията след"; + +/* No comment provided by engineer. */ +"Delete old database" = "Изтрий старата база данни"; + +/* No comment provided by engineer. */ +"Delete old database?" = "Изтрий старата база данни?"; + +/* No comment provided by engineer. */ +"Delete pending connection" = "Изтрий предстоящата връзка"; + +/* No comment provided by engineer. */ +"Delete pending connection?" = "Изтрий предстоящата връзка?"; + +/* No comment provided by engineer. */ +"Delete profile" = "Изтрий профил"; + +/* server test step */ +"Delete queue" = "Изтрий опашка"; + +/* No comment provided by engineer. */ +"Delete user profile?" = "Изтрий потребителския профил?"; + +/* deleted chat item */ +"deleted" = "изтрит"; + +/* No comment provided by engineer. */ +"Deleted at" = "Изтрито на"; + +/* copied message info */ +"Deleted at: %@" = "Изтрито на: %@"; + +/* rcv group event chat item */ +"deleted group" = "групата изтрита"; + +/* No comment provided by engineer. */ +"Delivery" = "Доставка"; + +/* No comment provided by engineer. */ +"Delivery receipts are disabled!" = "Потвърждениeто за доставка е деактивирано!"; + +/* No comment provided by engineer. */ +"Delivery receipts!" = "Потвърждениe за доставка!"; + +/* No comment provided by engineer. */ +"Description" = "Описание"; + +/* No comment provided by engineer. */ +"Develop" = "Разработване"; + +/* No comment provided by engineer. */ +"Developer tools" = "Инструменти за разработчици"; + +/* No comment provided by engineer. */ +"Device" = "Устройство"; + +/* No comment provided by engineer. */ +"Device authentication is disabled. Turning off SimpleX Lock." = "Идентификацията на устройството е деактивирано. Изключване на SimpleX заключване."; + +/* No comment provided by engineer. */ +"Device authentication is not enabled. You can turn on SimpleX Lock via Settings, once you enable device authentication." = "Идентификацията на устройството не е активирана. Можете да включите SimpleX заключване през Настройки, след като активирате идентификацията на устройството."; + +/* No comment provided by engineer. */ +"different migration in the app/database: %@ / %@" = "различна миграция в приложението/базата данни: %@ / %@"; + +/* No comment provided by engineer. */ +"Different names, avatars and transport isolation." = "Различни имена, аватари и транспортна изолация."; + +/* connection level description */ +"direct" = "директна"; + +/* chat feature */ +"Direct messages" = "Лични съобщения"; + +/* No comment provided by engineer. */ +"Direct messages between members are prohibited in this group." = "Личните съобщения между членовете са забранени в тази група."; + +/* No comment provided by engineer. */ +"Disable (keep overrides)" = "Деактивиране (запазване на промените)"; + +/* No comment provided by engineer. */ +"Disable for all" = "Деактивиране за всички"; + +/* authentication reason */ +"Disable SimpleX Lock" = "Деактивирай SimpleX заключване"; + +/* No comment provided by engineer. */ +"disabled" = "деактивирано"; + +/* No comment provided by engineer. */ +"Disappearing message" = "Изчезващо съобщение"; + +/* chat feature */ +"Disappearing messages" = "Изчезващи съобщения"; + +/* No comment provided by engineer. */ +"Disappearing messages are prohibited in this chat." = "Изчезващите съобщения са забранени в този чат."; + +/* No comment provided by engineer. */ +"Disappearing messages are prohibited in this group." = "Изчезващите съобщения са забранени в тази група."; + +/* No comment provided by engineer. */ +"Disappears at" = "Изчезва в"; + +/* copied message info */ +"Disappears at: %@" = "Изчезва в: %@"; + +/* server test step */ +"Disconnect" = "Прекъсни връзката"; + +/* No comment provided by engineer. */ +"Discover and join groups" = "Открийте и се присъединете към групи"; + +/* No comment provided by engineer. */ +"Display name" = "Показвано Име"; + +/* No comment provided by engineer. */ +"Display name:" = "Показвано име:"; + +/* No comment provided by engineer. */ +"Do it later" = "Отложи"; + +/* No comment provided by engineer. */ +"Do NOT use SimpleX for emergency calls." = "НЕ използвайте SimpleX за спешни повиквания."; + +/* No comment provided by engineer. */ +"Don't create address" = "Не създавай адрес"; + +/* No comment provided by engineer. */ +"Don't enable" = "Не активирай"; + +/* No comment provided by engineer. */ +"Don't show again" = "Не показвай отново"; + +/* No comment provided by engineer. */ +"Downgrade and open chat" = "Понижи версията и отвори чата"; + +/* server test step */ +"Download file" = "Свали файл"; + +/* No comment provided by engineer. */ +"Duplicate display name!" = "Дублирано показвано име!"; + +/* integrity error chat item */ +"duplicate message" = "дублирано съобщение"; + +/* No comment provided by engineer. */ +"Duration" = "Продължителност"; + +/* No comment provided by engineer. */ +"e2e encrypted" = "e2e криптиран"; + +/* chat item action */ +"Edit" = "Редактирай"; + +/* No comment provided by engineer. */ +"Edit group profile" = "Редактирай групов профил"; + +/* No comment provided by engineer. */ +"Enable" = "Активирай"; + +/* No comment provided by engineer. */ +"Enable (keep overrides)" = "Активиране (запазване на промените)"; + +/* No comment provided by engineer. */ +"Enable automatic message deletion?" = "Активиране на автоматично изтриване на съобщения?"; + +/* No comment provided by engineer. */ +"Enable for all" = "Активиране за всички"; + +/* No comment provided by engineer. */ +"Enable instant notifications?" = "Активирай незабавни известия?"; + +/* No comment provided by engineer. */ +"Enable lock" = "Активирай заключване"; + +/* No comment provided by engineer. */ +"Enable notifications" = "Активирай известията"; + +/* No comment provided by engineer. */ +"Enable periodic notifications?" = "Активирай периодични известия?"; + +/* No comment provided by engineer. */ +"Enable self-destruct" = "Активирай самоунищожение"; + +/* set passcode view */ +"Enable self-destruct passcode" = "Активирай kод за достъп за самоунищожение"; + +/* authentication reason */ +"Enable SimpleX Lock" = "Активирай SimpleX заключване"; + +/* No comment provided by engineer. */ +"Enable TCP keep-alive" = "Активирай TCP keep-alive"; + +/* enabled status */ +"enabled" = "активирано"; + +/* enabled status */ +"enabled for contact" = "активирано за контакт"; + +/* enabled status */ +"enabled for you" = "активирано за вас"; + +/* No comment provided by engineer. */ +"Encrypt" = "Криптирай"; + +/* No comment provided by engineer. */ +"Encrypt database?" = "Криптиране на база данни?"; + +/* No comment provided by engineer. */ +"Encrypt local files" = "Криптирай локални файлове"; + +/* No comment provided by engineer. */ +"Encrypt stored files & media" = "Криптиране на съхранените файлове и медия"; + +/* No comment provided by engineer. */ +"Encrypted database" = "Криптирана база данни"; + +/* notification */ +"Encrypted message or another event" = "Криптирано съобщение или друго събитие"; + +/* notification */ +"Encrypted message: database error" = "Криптирано съобщение: грешка в базата данни"; + +/* notification */ +"Encrypted message: database migration error" = "Криптирано съобщение: грешка при мигрирането на база данни"; + +/* notification */ +"Encrypted message: keychain error" = "Криптирано съобщение: грешка в keychain"; + +/* notification */ +"Encrypted message: no passphrase" = "Криптирано съобщение: няма парола"; + +/* notification */ +"Encrypted message: unexpected error" = "Криптирано съобщение: неочаквана грешка"; + +/* chat item text */ +"encryption agreed" = "криптирането е съгласувано"; + +/* chat item text */ +"encryption agreed for %@" = "криптирането е съгласувано за %@"; + +/* chat item text */ +"encryption ok" = "криптирането работи"; + +/* chat item text */ +"encryption ok for %@" = "криптирането работи за %@"; + +/* chat item text */ +"encryption re-negotiation allowed" = "разрешено повторно договаряне на криптиране"; + +/* chat item text */ +"encryption re-negotiation allowed for %@" = "разрешено повторно договаряне на криптиране за %@"; + +/* chat item text */ +"encryption re-negotiation required" = "необходимо е повторно договаряне на криптиране"; + +/* chat item text */ +"encryption re-negotiation required for %@" = "необходимо е повторно договаряне на криптиране за %@"; + +/* No comment provided by engineer. */ +"ended" = "приключен"; + +/* call status */ +"ended call %@" = "приключи разговор %@"; + +/* No comment provided by engineer. */ +"Enter correct passphrase." = "Въведи правилна парола."; + +/* No comment provided by engineer. */ +"Enter Passcode" = "Въведете kодa за достъп"; + +/* No comment provided by engineer. */ +"Enter passphrase…" = "Въведи парола…"; + +/* No comment provided by engineer. */ +"Enter password above to show!" = "Въведете парола по-горе, за да се покаже!"; + +/* No comment provided by engineer. */ +"Enter server manually" = "Въведи сървъра ръчно"; + +/* placeholder */ +"Enter welcome message…" = "Въведи съобщение при посрещане…"; + +/* placeholder */ +"Enter welcome message… (optional)" = "Въведи съобщение при посрещане…(незадължително)"; + +/* No comment provided by engineer. */ +"error" = "грешка"; + +/* No comment provided by engineer. */ +"Error" = "Грешка при свързване със сървъра"; + +/* No comment provided by engineer. */ +"Error aborting address change" = "Грешка при отказване на промяна на адреса"; + +/* No comment provided by engineer. */ +"Error accepting contact request" = "Грешка при приемане на заявка за контакт"; + +/* No comment provided by engineer. */ +"Error accessing database file" = "Грешка при достъпа до файла с базата данни"; + +/* No comment provided by engineer. */ +"Error adding member(s)" = "Грешка при добавяне на член(ове)"; + +/* No comment provided by engineer. */ +"Error changing address" = "Грешка при промяна на адреса"; + +/* No comment provided by engineer. */ +"Error changing role" = "Грешка при промяна на ролята"; + +/* No comment provided by engineer. */ +"Error changing setting" = "Грешка при промяна на настройката"; + +/* No comment provided by engineer. */ +"Error creating address" = "Грешка при създаване на адрес"; + +/* No comment provided by engineer. */ +"Error creating group" = "Грешка при създаване на група"; + +/* No comment provided by engineer. */ +"Error creating group link" = "Грешка при създаване на групов линк"; + +/* No comment provided by engineer. */ +"Error creating profile!" = "Грешка при създаване на профил!"; + +/* No comment provided by engineer. */ +"Error decrypting file" = "Грешка при декриптирането на файла"; + +/* No comment provided by engineer. */ +"Error deleting chat database" = "Грешка при изтриване на чат базата данни"; + +/* No comment provided by engineer. */ +"Error deleting chat!" = "Грешка при изтриването на чата!"; + +/* No comment provided by engineer. */ +"Error deleting connection" = "Грешка при изтриване на връзката"; + +/* No comment provided by engineer. */ +"Error deleting contact" = "Грешка при изтриване на контакт"; + +/* No comment provided by engineer. */ +"Error deleting database" = "Грешка при изтриване на базата данни"; + +/* No comment provided by engineer. */ +"Error deleting old database" = "Грешка при изтриване на старата база данни"; + +/* No comment provided by engineer. */ +"Error deleting token" = "Грешка при изтриването на токена"; + +/* No comment provided by engineer. */ +"Error deleting user profile" = "Грешка при изтриване на потребителския профил"; + +/* No comment provided by engineer. */ +"Error enabling delivery receipts!" = "Грешка при активирането на потвърждениeто за доставка!"; + +/* No comment provided by engineer. */ +"Error enabling notifications" = "Грешка при активирането на известията"; + +/* No comment provided by engineer. */ +"Error encrypting database" = "Грешка при криптиране на базата данни"; + +/* No comment provided by engineer. */ +"Error exporting chat database" = "Грешка при експортиране на чат базата данни"; + +/* No comment provided by engineer. */ +"Error importing chat database" = "Грешка при импортиране на чат базата данни"; + +/* No comment provided by engineer. */ +"Error joining group" = "Грешка при присъединяване към група"; + +/* No comment provided by engineer. */ +"Error loading %@ servers" = "Грешка при зареждане на %@ сървъри"; + +/* No comment provided by engineer. */ +"Error receiving file" = "Грешка при получаване на файл"; + +/* No comment provided by engineer. */ +"Error removing member" = "Грешка при отстраняване на член"; + +/* No comment provided by engineer. */ +"Error saving %@ servers" = "Грешка при запазване на %@ сървъра"; + +/* No comment provided by engineer. */ +"Error saving group profile" = "Грешка при запазване на профила на групата"; + +/* No comment provided by engineer. */ +"Error saving ICE servers" = "Грешка при запазване на ICE сървърите"; + +/* No comment provided by engineer. */ +"Error saving passcode" = "Грешка при запазване на кода за достъп"; + +/* No comment provided by engineer. */ +"Error saving passphrase to keychain" = "Грешка при запазване на парола в Кeychain"; + +/* No comment provided by engineer. */ +"Error saving user password" = "Грешка при запазване на потребителска парола"; + +/* No comment provided by engineer. */ +"Error sending email" = "Грешка при изпращане на имейл"; + +/* No comment provided by engineer. */ +"Error sending message" = "Грешка при изпращане на съобщение"; + +/* No comment provided by engineer. */ +"Error setting delivery receipts!" = "Грешка при настройването на потвърждениeто за доставка!!"; + +/* No comment provided by engineer. */ +"Error starting chat" = "Грешка при стартиране на чата"; + +/* No comment provided by engineer. */ +"Error stopping chat" = "Грешка при спиране на чата"; + +/* No comment provided by engineer. */ +"Error switching profile!" = "Грешка при смяна на профил!"; + +/* No comment provided by engineer. */ +"Error synchronizing connection" = "Грешка при синхронизиране на връзката"; + +/* No comment provided by engineer. */ +"Error updating group link" = "Грешка при актуализиране на груповия линк"; + +/* No comment provided by engineer. */ +"Error updating message" = "Грешка при актуализиране на съобщението"; + +/* No comment provided by engineer. */ +"Error updating settings" = "Грешка при актуализиране на настройките"; + +/* No comment provided by engineer. */ +"Error updating user privacy" = "Грешка при актуализиране на поверителността на потребителя"; + +/* No comment provided by engineer. */ +"Error: " = "Грешка: "; + +/* No comment provided by engineer. */ +"Error: %@" = "Грешка: %@"; + +/* No comment provided by engineer. */ +"Error: no database file" = "Грешка: няма файл с база данни"; + +/* No comment provided by engineer. */ +"Error: URL is invalid" = "Грешка: URL адресът е невалиден"; + +/* No comment provided by engineer. */ +"Even when disabled in the conversation." = "Дори когато е деактивиран в разговора."; + +/* No comment provided by engineer. */ +"event happened" = "събитие се случи"; + +/* No comment provided by engineer. */ +"Exit without saving" = "Изход без запазване"; + +/* No comment provided by engineer. */ +"Export database" = "Експортирай база данни"; + +/* No comment provided by engineer. */ +"Export error:" = "Грешка при експортиране:"; + +/* No comment provided by engineer. */ +"Exported database archive." = "Експортиран архив на базата данни."; + +/* No comment provided by engineer. */ +"Exporting database archive…" = "Експортиране на архив на базата данни…"; + +/* No comment provided by engineer. */ +"Failed to remove passphrase" = "Премахването на паролата е неуспешно"; + +/* No comment provided by engineer. */ +"Fast and no wait until the sender is online!" = "Бързо и без чакане, докато подателят е онлайн!"; + +/* No comment provided by engineer. */ +"Favorite" = "Любим"; + +/* No comment provided by engineer. */ +"File will be deleted from servers." = "Файлът ще бъде изтрит от сървърите."; + +/* No comment provided by engineer. */ +"File will be received when your contact completes uploading it." = "Файлът ще бъде получен, когато вашият контакт завърши качването му."; + +/* No comment provided by engineer. */ +"File will be received when your contact is online, please wait or check later!" = "Файлът ще бъде получен, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно!"; + +/* No comment provided by engineer. */ +"File: %@" = "Файл: %@"; + +/* No comment provided by engineer. */ +"Files & media" = "Файлове и медия"; + +/* chat feature */ +"Files and media" = "Файлове и медия"; + +/* No comment provided by engineer. */ +"Files and media are prohibited in this group." = "Файловете и медията са забранени в тази група."; + +/* No comment provided by engineer. */ +"Files and media prohibited!" = "Файловете и медията са забранени!"; + +/* No comment provided by engineer. */ +"Filter unread and favorite chats." = "Филтрирайте непрочетените и любимите чатове."; + +/* No comment provided by engineer. */ +"Finally, we have them! 🚀" = "Най-накрая ги имаме! 🚀"; + +/* No comment provided by engineer. */ +"Find chats faster" = "Намирайте чатове по-бързо"; + +/* No comment provided by engineer. */ +"Fix" = "Поправи"; + +/* No comment provided by engineer. */ +"Fix connection" = "Поправи връзката"; + +/* No comment provided by engineer. */ +"Fix connection?" = "Поправи връзката?"; + +/* No comment provided by engineer. */ +"Fix encryption after restoring backups." = "Оправяне на криптирането след възстановяване от резервни копия."; + +/* No comment provided by engineer. */ +"Fix not supported by contact" = "Поправката не се поддържа от контакта"; + +/* No comment provided by engineer. */ +"Fix not supported by group member" = "Поправката не се поддържа от члена на групата"; + +/* No comment provided by engineer. */ +"For console" = "За конзолата"; + +/* No comment provided by engineer. */ +"French interface" = "Френски интерфейс"; + +/* No comment provided by engineer. */ +"Full link" = "Цял линк"; + +/* No comment provided by engineer. */ +"Full name (optional)" = "Пълно име (незадължително)"; + +/* No comment provided by engineer. */ +"Full name:" = "Пълно име:"; + +/* No comment provided by engineer. */ +"Fully re-implemented - work in background!" = "Напълно преработено - работи във фонов режим!"; + +/* No comment provided by engineer. */ +"Further reduced battery usage" = "Допълнително намален разход на батерията"; + +/* No comment provided by engineer. */ +"GIFs and stickers" = "GIF файлове и стикери"; + +/* No comment provided by engineer. */ +"Group" = "Група"; + +/* No comment provided by engineer. */ +"group deleted" = "групата е изтрита"; + +/* No comment provided by engineer. */ +"Group display name" = "Показвано име на групата"; + +/* No comment provided by engineer. */ +"Group full name (optional)" = "Пълно име на групата (незадължително)"; + +/* No comment provided by engineer. */ +"Group image" = "Групово изображение"; + +/* No comment provided by engineer. */ +"Group invitation" = "Групова покана"; + +/* No comment provided by engineer. */ +"Group invitation expired" = "Груповата покана е изтекла"; + +/* No comment provided by engineer. */ +"Group invitation is no longer valid, it was removed by sender." = "Груповата покана вече е невалидна, премахната е от подателя."; + +/* No comment provided by engineer. */ +"Group link" = "Групов линк"; + +/* No comment provided by engineer. */ +"Group links" = "Групови линкове"; + +/* No comment provided by engineer. */ +"Group members can add message reactions." = "Членовете на групата могат да добавят реакции към съобщенията."; + +/* No comment provided by engineer. */ +"Group members can irreversibly delete sent messages." = "Членовете на групата могат необратимо да изтриват изпратените съобщения."; + +/* No comment provided by engineer. */ +"Group members can send direct messages." = "Членовете на групата могат да изпращат лични съобщения."; + +/* No comment provided by engineer. */ +"Group members can send disappearing messages." = "Членовете на групата могат да изпращат изчезващи съобщения."; + +/* No comment provided by engineer. */ +"Group members can send files and media." = "Членовете на групата могат да изпращат файлове и медия."; + +/* No comment provided by engineer. */ +"Group members can send voice messages." = "Членовете на групата могат да изпращат гласови съобщения."; + +/* notification */ +"Group message:" = "Групово съобщение:"; + +/* No comment provided by engineer. */ +"Group moderation" = "Групово модериране"; + +/* No comment provided by engineer. */ +"Group preferences" = "Групови настройки"; + +/* No comment provided by engineer. */ +"Group profile" = "Групов профил"; + +/* No comment provided by engineer. */ +"Group profile is stored on members' devices, not on the servers." = "Груповият профил се съхранява на устройствата на членовете, а не на сървърите."; + +/* snd group event chat item */ +"group profile updated" = "профилът на групата е актуализиран"; + +/* No comment provided by engineer. */ +"Group welcome message" = "Съобщение при посрещане в групата"; + +/* No comment provided by engineer. */ +"Group will be deleted for all members - this cannot be undone!" = "Групата ще бъде изтрита за всички членове - това не може да бъде отменено!"; + +/* No comment provided by engineer. */ +"Group will be deleted for you - this cannot be undone!" = "Групата ще бъде изтрита за вас - това не може да бъде отменено!"; + +/* No comment provided by engineer. */ +"Help" = "Помощ"; + +/* No comment provided by engineer. */ +"Hidden" = "Скрит"; + +/* No comment provided by engineer. */ +"Hidden chat profiles" = "Скрити чат профили"; + +/* No comment provided by engineer. */ +"Hidden profile password" = "Парола за скрит профил"; + +/* chat item action */ +"Hide" = "Скрий"; + +/* No comment provided by engineer. */ +"Hide app screen in the recent apps." = "Скриване на екрана на приложението в изгледа на скоро отворнените приложения."; + +/* No comment provided by engineer. */ +"Hide profile" = "Скрий профила"; + +/* No comment provided by engineer. */ +"Hide:" = "Скрий:"; + +/* No comment provided by engineer. */ +"History" = "История"; + +/* time unit */ +"hours" = "часове"; + +/* No comment provided by engineer. */ +"How it works" = "Как работи"; + +/* No comment provided by engineer. */ +"How SimpleX works" = "Как работи SimpleX"; + +/* No comment provided by engineer. */ +"How to" = "Информация"; + +/* No comment provided by engineer. */ +"How to use it" = "Как се използва"; + +/* No comment provided by engineer. */ +"How to use your servers" = "Как да използвате вашите сървъри"; + +/* No comment provided by engineer. */ +"ICE servers (one per line)" = "ICE сървъри (по един на ред)"; + +/* No comment provided by engineer. */ +"If you can't meet in person, show QR code in a video call, or share the link." = "Ако не можете да се срещнете лично, покажете QR код във видеоразговора или споделете линка."; + +/* No comment provided by engineer. */ +"If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link." = "Ако не можете да се срещнете на живо, можете да **сканирате QR код във видеообаждането** или вашият контакт може да сподели линк за покана."; + +/* No comment provided by engineer. */ +"If you enter this passcode when opening the app, all app data will be irreversibly removed!" = "Ако въведете този kод за достъп, когато отваряте приложението, всички данни от приложението ще бъдат необратимо изтрити!"; + +/* No comment provided by engineer. */ +"If you enter your self-destruct passcode while opening the app:" = "Ако въведете kодa за достъп за самоунищожение, докато отваряте приложението:"; + +/* No comment provided by engineer. */ +"If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app)." = "Ако трябва да използвате чата сега, докоснете **Отложи** отдолу (ще ви бъде предложено да мигрирате базата данни, когато рестартирате приложението)."; + +/* No comment provided by engineer. */ +"Ignore" = "Игнорирай"; + +/* No comment provided by engineer. */ +"Image will be received when your contact completes uploading it." = "Изображението ще бъде получено, когато вашият контакт завърши качването му."; + +/* No comment provided by engineer. */ +"Image will be received when your contact is online, please wait or check later!" = "Изображението ще бъде получено, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно!"; + +/* No comment provided by engineer. */ +"Immediately" = "Веднага"; + +/* No comment provided by engineer. */ +"Immune to spam and abuse" = "Защитен от спам и злоупотреби"; + +/* No comment provided by engineer. */ +"Import" = "Импортиране"; + +/* No comment provided by engineer. */ +"Import chat database?" = "Импортиране на чат база данни?"; + +/* No comment provided by engineer. */ +"Import database" = "Импортиране на база данни"; + +/* No comment provided by engineer. */ +"Improved privacy and security" = "Подобрена поверителност и сигурност"; + +/* No comment provided by engineer. */ +"Improved server configuration" = "Подобрена конфигурация на сървъра"; + +/* No comment provided by engineer. */ +"In reply to" = "В отговор на"; + +/* No comment provided by engineer. */ +"Incognito" = "Инкогнито"; + +/* No comment provided by engineer. */ +"Incognito mode" = "Режим инкогнито"; + +/* No comment provided by engineer. */ +"Incognito mode protects your privacy by using a new random profile for each contact." = "Режимът инкогнито защитава вашата поверителност, като използва нов автоматично генериран профил за всеки контакт."; + +/* chat list item description */ +"incognito via contact address link" = "инкогнито чрез линк с адрес за контакт"; + +/* chat list item description */ +"incognito via group link" = "инкогнито чрез групов линк"; + +/* chat list item description */ +"incognito via one-time link" = "инкогнито чрез еднократен линк за връзка"; + +/* notification */ +"Incoming audio call" = "Входящо аудио повикване"; + +/* notification */ +"Incoming call" = "Входящо повикване"; + +/* notification */ +"Incoming video call" = "Входящо видео повикване"; + +/* No comment provided by engineer. */ +"Incompatible database version" = "Несъвместима версия на базата данни"; + +/* PIN entry */ +"Incorrect passcode" = "Неправилен kод за достъп"; + +/* No comment provided by engineer. */ +"Incorrect security code!" = "Неправилен код за сигурност!"; + +/* connection level description */ +"indirect (%d)" = "индиректна (%d)"; + +/* chat item action */ +"Info" = "Информация"; + +/* No comment provided by engineer. */ +"Initial role" = "Първоначална роля"; + +/* No comment provided by engineer. */ +"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Инсталирайте [SimpleX Chat за терминал](https://github.com/simplex-chat/simplex-chat)"; + +/* No comment provided by engineer. */ +"Instant push notifications will be hidden!\n" = "Незабавните push известия ще бъдат скрити!\n"; + +/* No comment provided by engineer. */ +"Instantly" = "Мигновено"; + +/* No comment provided by engineer. */ +"Interface" = "Интерфейс"; + +/* invalid chat data */ +"invalid chat" = "невалиден чат"; + +/* No comment provided by engineer. */ +"invalid chat data" = "невалидни данни за чат"; + +/* No comment provided by engineer. */ +"Invalid connection link" = "Невалиден линк за връзка"; + +/* invalid chat item */ +"invalid data" = "невалидни данни"; + +/* No comment provided by engineer. */ +"Invalid server address!" = "Невалиден адрес на сървъра!"; + +/* item status text */ +"Invalid status" = "Невалиден статус"; + +/* No comment provided by engineer. */ +"Invitation expired!" = "Поканата е изтекла!"; + +/* group name */ +"invitation to group %@" = "покана за група %@"; + +/* No comment provided by engineer. */ +"Invite friends" = "Покани приятели"; + +/* No comment provided by engineer. */ +"Invite members" = "Покани членове"; + +/* No comment provided by engineer. */ +"Invite to group" = "Покани в групата"; + +/* No comment provided by engineer. */ +"invited" = "поканен"; + +/* rcv group event chat item */ +"invited %@" = "поканен %@"; + +/* chat list item title */ +"invited to connect" = "поканен да се свърже"; + +/* rcv group event chat item */ +"invited via your group link" = "поканен чрез вашия групов линк"; + +/* No comment provided by engineer. */ +"iOS Keychain is used to securely store passphrase - it allows receiving push notifications." = "iOS Keychain се използва за сигурно съхраняване на парола - позволява получаване на push известия."; + +/* No comment provided by engineer. */ +"iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications." = "iOS Keychain ще се използва за сигурно съхраняване на паролата, след като рестартирате приложението или промените паролата - това ще позволи получаването на push известия."; + +/* No comment provided by engineer. */ +"Irreversible message deletion" = "Необратимо изтриване на съобщение"; + +/* No comment provided by engineer. */ +"Irreversible message deletion is prohibited in this chat." = "Необратимото изтриване на съобщения е забранено в този чат."; + +/* No comment provided by engineer. */ +"Irreversible message deletion is prohibited in this group." = "Необратимото изтриване на съобщения е забранено в тази група."; + +/* No comment provided by engineer. */ +"It allows having many anonymous connections without any shared data between them in a single chat profile." = "Позволява да имате много анонимни връзки без споделени данни между тях в един чат профил ."; + +/* No comment provided by engineer. */ +"It can happen when you or your connection used the old database backup." = "Това може да се случи, когато вие или вашата връзка използвате старо резервно копие на базата данни."; + +/* 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." = "Това може да се случи, когато:\n1. Времето за пазене на съобщенията е изтекло - в изпращащия клиент е 2 дена а на сървъра е 30.\n2. Декриптирането на съобщението е неуспешно, защото вие или вашият контакт сте използвали старо копие на базата данни.\n3. Връзката е била компрометирана."; + +/* 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 (%@)." = "Изглежда, че вече сте свързани чрез този линк. Ако не е така, има грешка (%@)."; + +/* No comment provided by engineer. */ +"Italian interface" = "Италиански интерфейс"; + +/* No comment provided by engineer. */ +"italic" = "курсив"; + +/* No comment provided by engineer. */ +"Japanese interface" = "Японски интерфейс"; + +/* No comment provided by engineer. */ +"Join" = "Присъединяване"; + +/* No comment provided by engineer. */ +"join as %@" = "присъединяване като %@"; + +/* No comment provided by engineer. */ +"Join group" = "Влез в групата"; + +/* No comment provided by engineer. */ +"Join incognito" = "Влез инкогнито"; + +/* No comment provided by engineer. */ +"Joining group" = "Присъединяване към групата"; + +/* No comment provided by engineer. */ +"Keep your connections" = "Запазете връзките си"; + +/* No comment provided by engineer. */ +"Keychain error" = "Keychain грешка"; + +/* No comment provided by engineer. */ +"KeyChain error" = "KeyChain грешка"; + +/* No comment provided by engineer. */ +"Large file!" = "Голям файл!"; + +/* No comment provided by engineer. */ +"Learn more" = "Научете повече"; + +/* No comment provided by engineer. */ +"Leave" = "Напусни"; + +/* No comment provided by engineer. */ +"Leave group" = "Напусни групата"; + +/* No comment provided by engineer. */ +"Leave group?" = "Напусни групата?"; + +/* rcv group event chat item */ +"left" = "напусна"; + +/* email subject */ +"Let's talk in SimpleX Chat" = "Нека да поговорим в SimpleX Chat"; + +/* No comment provided by engineer. */ +"Light" = "Светла"; + +/* No comment provided by engineer. */ +"Limitations" = "Ограничения"; + +/* No comment provided by engineer. */ +"LIVE" = "НА ЖИВО"; + +/* No comment provided by engineer. */ +"Live message!" = "Съобщение на живо!"; + +/* No comment provided by engineer. */ +"Live messages" = "Съобщения на живо"; + +/* No comment provided by engineer. */ +"Local name" = "Локално име"; + +/* No comment provided by engineer. */ +"Local profile data only" = "Само данни за локален профил"; + +/* No comment provided by engineer. */ +"Lock after" = "Заключване след"; + +/* No comment provided by engineer. */ +"Lock mode" = "Режим на заключване"; + +/* No comment provided by engineer. */ +"Make a private connection" = "Добави поверителна връзка"; + +/* No comment provided by engineer. */ +"Make one message disappear" = "Накарайте едно съобщение да изчезне"; + +/* No comment provided by engineer. */ +"Make profile private!" = "Направи профила поверителен!"; + +/* No comment provided by engineer. */ +"Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@)." = "Уверете се, че %@ сървърните адреси са в правилен формат, разделени на редове и не се дублират (%@)."; + +/* No comment provided by engineer. */ +"Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated." = "Уверете се, че адресите на WebRTC ICE сървъра са в правилен формат, разделени на редове и не са дублирани."; + +/* No comment provided by engineer. */ +"Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" = "Много хора попитаха: *ако SimpleX няма потребителски идентификатори, как може да доставя съобщения?*"; + +/* No comment provided by engineer. */ +"Mark deleted for everyone" = "Маркирай като изтрито за всички"; + +/* No comment provided by engineer. */ +"Mark read" = "Маркирай като прочетено"; + +/* No comment provided by engineer. */ +"Mark verified" = "Маркирай като проверено"; + +/* No comment provided by engineer. */ +"Markdown in messages" = "Форматиране на съобщения"; + +/* marked deleted chat item preview text */ +"marked deleted" = "маркирано като изтрито"; + +/* No comment provided by engineer. */ +"Max 30 seconds, received instantly." = "Макс. 30 секунди, получено незабавно."; + +/* member role */ +"member" = "член"; + +/* No comment provided by engineer. */ +"Member" = "Член"; + +/* rcv group event chat item */ +"member connected" = "свързан"; + +/* No comment provided by engineer. */ +"Member role will be changed to \"%@\". All group members will be notified." = "Ролята на члена ще бъде променена на \"%@\". Всички членове на групата ще бъдат уведомени."; + +/* No comment provided by engineer. */ +"Member role will be changed to \"%@\". The member will receive a new invitation." = "Ролята на члена ще бъде променена на \"%@\". Членът ще получи нова покана."; + +/* No comment provided by engineer. */ +"Member will be removed from group - this cannot be undone!" = "Членът ще бъде премахнат от групата - това не може да бъде отменено!"; + +/* item status text */ +"Message delivery error" = "Грешка при доставката на съобщението"; + +/* No comment provided by engineer. */ +"Message delivery receipts!" = "Потвърждениe за доставка на съобщения!"; + +/* No comment provided by engineer. */ +"Message draft" = "Чернова на съобщение"; + +/* chat feature */ +"Message reactions" = "Реакции на съобщения"; + +/* No comment provided by engineer. */ +"Message reactions are prohibited in this chat." = "Реакциите на съобщения са забранени в този чат."; + +/* No comment provided by engineer. */ +"Message reactions are prohibited in this group." = "Реакциите на съобщения са забранени в тази група."; + +/* notification */ +"message received" = "получено съобщение"; + +/* No comment provided by engineer. */ +"Message text" = "Текст на съобщението"; + +/* No comment provided by engineer. */ +"Messages" = "Съобщения"; + +/* No comment provided by engineer. */ +"Messages & files" = "Съобщения и файлове"; + +/* No comment provided by engineer. */ +"Migrating database archive…" = "Архивът на базата данни се мигрира…"; + +/* No comment provided by engineer. */ +"Migration error:" = "Грешка при мигриране:"; + +/* No comment provided by engineer. */ +"Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat)." = "Мигрирането е неуспешно. Докоснете **Пропускане** по-долу, за да продължите да използвате текущата база данни. Моля, докладвайте проблема на разработчиците на приложението чрез чат или имейл [chat@simplex.chat](mailto:chat@simplex.chat)."; + +/* No comment provided by engineer. */ +"Migration is completed" = "Миграцията е завършена"; + +/* No comment provided by engineer. */ +"Migrations: %@" = "Миграции: %@"; + +/* time unit */ +"minutes" = "минути"; + +/* call status */ +"missed call" = "пропуснато повикване"; + +/* chat item action */ +"Moderate" = "Модерирай"; + +/* moderated chat item */ +"moderated" = "модерирано"; + +/* No comment provided by engineer. */ +"Moderated at" = "Модерирано в"; + +/* copied message info */ +"Moderated at: %@" = "Модерирано в: %@"; + +/* No comment provided by engineer. */ +"moderated by %@" = "модерирано от %@"; + +/* time unit */ +"months" = "месеци"; + +/* No comment provided by engineer. */ +"More improvements are coming soon!" = "Очаквайте скоро още подобрения!"; + +/* item status description */ +"Most likely this connection is deleted." = "Най-вероятно тази връзка е изтрита."; + +/* No comment provided by engineer. */ +"Most likely this contact has deleted the connection with you." = "Най-вероятно този контакт е изтрил връзката с вас."; + +/* No comment provided by engineer. */ +"Multiple chat profiles" = "Множество профили за чат"; + +/* No comment provided by engineer. */ +"Mute" = "Без звук"; + +/* No comment provided by engineer. */ +"Muted when inactive!" = "Без звук при неактивност!"; + +/* No comment provided by engineer. */ +"Name" = "Име"; + +/* No comment provided by engineer. */ +"Network & servers" = "Мрежа и сървъри"; + +/* No comment provided by engineer. */ +"Network settings" = "Мрежови настройки"; + +/* No comment provided by engineer. */ +"Network status" = "Състояние на мрежата"; + +/* No comment provided by engineer. */ +"never" = "никога"; + +/* notification */ +"New contact request" = "Нова заявка за контакт"; + +/* notification */ +"New contact:" = "Нов контакт:"; + +/* No comment provided by engineer. */ +"New database archive" = "Нов архив на база данни"; + +/* No comment provided by engineer. */ +"New desktop app!" = "Ново настолно приложение!"; + +/* No comment provided by engineer. */ +"New display name" = "Ново показвано име"; + +/* No comment provided by engineer. */ +"New in %@" = "Ново в %@"; + +/* No comment provided by engineer. */ +"New member role" = "Нова членска роля"; + +/* notification */ +"new message" = "ново съобщение"; + +/* notification */ +"New message" = "Ново съобщение"; + +/* No comment provided by engineer. */ +"New Passcode" = "Нов kод за достъп"; + +/* No comment provided by engineer. */ +"New passphrase…" = "Нова парола…"; + +/* pref value */ +"no" = "не"; + +/* No comment provided by engineer. */ +"No" = "Не"; + +/* Authentication unavailable */ +"No app password" = "Приложението няма kод за достъп"; + +/* No comment provided by engineer. */ +"No contacts selected" = "Няма избрани контакти"; + +/* No comment provided by engineer. */ +"No contacts to add" = "Няма контакти за добавяне"; + +/* No comment provided by engineer. */ +"No delivery information" = "Няма информация за доставката"; + +/* No comment provided by engineer. */ +"No device token!" = "Няма токен за устройство!"; + +/* No comment provided by engineer. */ +"no e2e encryption" = "липсва e2e криптиране"; + +/* No comment provided by engineer. */ +"No filtered chats" = "Няма филтрирани чатове"; + +/* No comment provided by engineer. */ +"No group!" = "Групата не е намерена!"; + +/* No comment provided by engineer. */ +"No history" = "Няма история"; + +/* No comment provided by engineer. */ +"No permission to record voice message" = "Няма разрешение за запис на гласово съобщение"; + +/* No comment provided by engineer. */ +"No received or sent files" = "Няма получени или изпратени файлове"; + +/* copied message info in history */ +"no text" = "няма текст"; + +/* No comment provided by engineer. */ +"Notifications" = "Известия"; + +/* No comment provided by engineer. */ +"Notifications are disabled!" = "Известията са деактивирани!"; + +/* No comment provided by engineer. */ +"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Сега администраторите могат:\n- да изтриват съобщения на членове.\n- да деактивират членове (роля \"наблюдател\")"; + +/* member role */ +"observer" = "наблюдател"; + +/* enabled status + group pref value */ +"off" = "изключено"; + +/* No comment provided by engineer. */ +"Off" = "Изключено"; + +/* No comment provided by engineer. */ +"Off (Local)" = "Изключено (Локално)"; + +/* feature offered item */ +"offered %@" = "предлага %@"; + +/* feature offered item */ +"offered %@: %@" = "предлага %1$@: %2$@"; + +/* No comment provided by engineer. */ +"Ok" = "Ок"; + +/* No comment provided by engineer. */ +"Old database" = "Стара база данни"; + +/* No comment provided by engineer. */ +"Old database archive" = "Стар архив на база данни"; + +/* group pref value */ +"on" = "включено"; + +/* No comment provided by engineer. */ +"One-time invitation link" = "Линк за еднократна покана"; + +/* No comment provided by engineer. */ +"Onion hosts will be required for connection. Requires enabling VPN." = "За свързване ще са необходими Onion хостове. Изисква се активиране на VPN."; + +/* No comment provided by engineer. */ +"Onion hosts will be used when available. Requires enabling VPN." = "Ще се използват Onion хостове, когато са налични. Изисква се активиране на VPN."; + +/* No comment provided by engineer. */ +"Onion hosts will not be used." = "Няма се използват Onion хостове."; + +/* No comment provided by engineer. */ +"Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Само потребителските устройства съхраняват потребителски профили, контакти, групи и съобщения, изпратени с **двуслойно криптиране от край до край**."; + +/* No comment provided by engineer. */ +"Only group owners can change group preferences." = "Само собствениците на групата могат да променят груповите настройки."; + +/* No comment provided by engineer. */ +"Only group owners can enable files and media." = "Само собствениците на групата могат да активират файлове и медията."; + +/* No comment provided by engineer. */ +"Only group owners can enable voice messages." = "Само собствениците на групата могат да активират гласови съобщения."; + +/* No comment provided by engineer. */ +"Only you can add message reactions." = "Само вие можете да добавяте реакции на съобщенията."; + +/* No comment provided by engineer. */ +"Only you can irreversibly delete messages (your contact can mark them for deletion)." = "Само вие можете необратимо да изтриете съобщения (вашият контакт може да ги маркира за изтриване)."; + +/* No comment provided by engineer. */ +"Only you can make calls." = "Само вие можете да извършвате разговори."; + +/* No comment provided by engineer. */ +"Only you can send disappearing messages." = "Само вие можете да изпращате изчезващи съобщения."; + +/* No comment provided by engineer. */ +"Only you can send voice messages." = "Само вие можете да изпращате гласови съобщения."; + +/* No comment provided by engineer. */ +"Only your contact can add message reactions." = "Само вашият контакт може да добавя реакции на съобщенията."; + +/* No comment provided by engineer. */ +"Only your contact can irreversibly delete messages (you can mark them for deletion)." = "Само вашият контакт може необратимо да изтрие съобщения (можете да ги маркирате за изтриване)."; + +/* No comment provided by engineer. */ +"Only your contact can make calls." = "Само вашият контакт може да извършва разговори."; + +/* No comment provided by engineer. */ +"Only your contact can send disappearing messages." = "Само вашият контакт може да изпраща изчезващи съобщения."; + +/* No comment provided by engineer. */ +"Only your contact can send voice messages." = "Само вашият контакт може да изпраща гласови съобщения."; + +/* No comment provided by engineer. */ +"Open chat" = "Отвори чат"; + +/* authentication reason */ +"Open chat console" = "Отвори конзолата"; + +/* No comment provided by engineer. */ +"Open Settings" = "Отвори настройки"; + +/* authentication reason */ +"Open user profiles" = "Отвори потребителските профили"; + +/* No comment provided by engineer. */ +"Open-source protocol and code – anybody can run the servers." = "Протокол и код с отворен код – всеки може да оперира собствени сървъри."; + +/* No comment provided by engineer. */ +"Opening database…" = "Отваряне на база данни…"; + +/* No comment provided by engineer. */ +"Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red." = "Отварянето на линка в браузъра може да намали поверителността и сигурността на връзката. Несигурните SimpleX линкове ще бъдат червени."; + +/* No comment provided by engineer. */ +"or chat with the developers" = "или пишете на разработчиците"; + +/* member role */ +"owner" = "собственик"; + +/* No comment provided by engineer. */ +"Passcode" = "Код за достъп"; + +/* No comment provided by engineer. */ +"Passcode changed!" = "Кодът за достъп е променен!"; + +/* No comment provided by engineer. */ +"Passcode entry" = "Въвеждане на код за достъп"; + +/* No comment provided by engineer. */ +"Passcode not changed!" = "Кодът за достъп не е променен!"; + +/* No comment provided by engineer. */ +"Passcode set!" = "Кодът за достъп е зададен!"; + +/* No comment provided by engineer. */ +"Password to show" = "Парола за показване"; + +/* No comment provided by engineer. */ +"Paste" = "Постави"; + +/* No comment provided by engineer. */ +"Paste image" = "Постави изображение"; + +/* No comment provided by engineer. */ +"Paste received link" = "Постави получения линк"; + +/* placeholder */ +"Paste the link you received to connect with your contact." = "Поставете линка, който сте получили, за да се свържете с вашия контакт."; + +/* No comment provided by engineer. */ +"peer-to-peer" = "peer-to-peer"; + +/* No comment provided by engineer. */ +"People can connect to you only via the links you share." = "Хората могат да се свържат с вас само чрез ликовете, които споделяте."; + +/* No comment provided by engineer. */ +"Periodically" = "Периодично"; + +/* message decrypt error item */ +"Permanent decryption error" = "Постоянна грешка при декриптиране"; + +/* No comment provided by engineer. */ +"PING count" = "PING бройка"; + +/* No comment provided by engineer. */ +"PING interval" = "PING интервал"; + +/* No comment provided by engineer. */ +"Please ask your contact to enable sending voice messages." = "Моля, попитайте вашия контакт, за да активирате изпращане на гласови съобщения."; + +/* No comment provided by engineer. */ +"Please check that you used the correct link or ask your contact to send you another one." = "Моля, проверете дали сте използвали правилния линк или поискайте вашия контакт, за да ви изпрати друг."; + +/* No comment provided by engineer. */ +"Please check your network connection with %@ and try again." = "Моля, проверете мрежовата си връзка с %@ и опитайте отново."; + +/* No comment provided by engineer. */ +"Please check yours and your contact preferences." = "Моля, проверете вашите настройки и тези вашия за контакт."; + +/* No comment provided by engineer. */ +"Please contact group admin." = "Моля, свържете се с груповия администартор."; + +/* No comment provided by engineer. */ +"Please enter correct current passphrase." = "Моля, въведете правилната текуща парола."; + +/* No comment provided by engineer. */ +"Please enter the previous password after restoring database backup. This action can not be undone." = "Моля, въведете предишната парола след възстановяване на резервното копие на базата данни. Това действие не може да бъде отменено."; + +/* No comment provided by engineer. */ +"Please remember or store it securely - there is no way to recover a lost passcode!" = "Моля, запомнете го или го съхранявайте на сигурно място - няма начин да възстановите изгубен код за достъп!"; + +/* No comment provided by engineer. */ +"Please report it to the developers." = "Моля, докладвайте го на разработчиците."; + +/* No comment provided by engineer. */ +"Please restart the app and migrate the database to enable push notifications." = "Моля, рестартирайте приложението и мигрирайте базата данни, за да активирате push известия."; + +/* No comment provided by engineer. */ +"Please store passphrase securely, you will NOT be able to access chat if you lose it." = "Моля, съхранявайте паролата на сигурно място, НЯМА да имате достъп до чата, ако я загубите."; + +/* No comment provided by engineer. */ +"Please store passphrase securely, you will NOT be able to change it if you lose it." = "Моля, съхранявайте паролата на сигурно място, НЯМА да можете да я промените, ако я загубите."; + +/* No comment provided by engineer. */ +"Polish interface" = "Полски интерфейс"; + +/* server test error */ +"Possibly, certificate fingerprint in server address is incorrect" = "Въжможно е пръстовият отпечатък на сертификата в адреса на сървъра да е неправилен"; + +/* No comment provided by engineer. */ +"Preserve the last message draft, with attachments." = "Запазете последната чернова на съобщението с прикачени файлове."; + +/* No comment provided by engineer. */ +"Preset server" = "Предварително зададен сървър"; + +/* No comment provided by engineer. */ +"Preset server address" = "Предварително зададен адрес на сървъра"; + +/* No comment provided by engineer. */ +"Preview" = "Визуализация"; + +/* No comment provided by engineer. */ +"Privacy & security" = "Поверителност и сигурност"; + +/* No comment provided by engineer. */ +"Privacy redefined" = "Поверителността преосмислена"; + +/* No comment provided by engineer. */ +"Private filenames" = "Поверителни имена на файлове"; + +/* No comment provided by engineer. */ +"Profile and server connections" = "Профилни и сървърни връзки"; + +/* No comment provided by engineer. */ +"Profile image" = "Профилно изображение"; + +/* No comment provided by engineer. */ +"Profile password" = "Профилна парола"; + +/* No comment provided by engineer. */ +"Profile update will be sent to your contacts." = "Актуализацията на профила ще бъде изпратена до вашите контакти."; + +/* No comment provided by engineer. */ +"Prohibit audio/video calls." = "Забрани аудио/видео разговорите."; + +/* No comment provided by engineer. */ +"Prohibit irreversible message deletion." = "Забрани необратимото изтриване на съобщения."; + +/* No comment provided by engineer. */ +"Prohibit message reactions." = "Забрани реакциите на съобщенията."; + +/* No comment provided by engineer. */ +"Prohibit messages reactions." = "Забрани реакциите на съобщенията."; + +/* No comment provided by engineer. */ +"Prohibit sending direct messages to members." = "Забрани изпращането на лични съобщения до членовете."; + +/* No comment provided by engineer. */ +"Prohibit sending disappearing messages." = "Забрани изпращането на изчезващи съобщения."; + +/* No comment provided by engineer. */ +"Prohibit sending files and media." = "Забрани изпращането на файлове и медия."; + +/* No comment provided by engineer. */ +"Prohibit sending voice messages." = "Забрани изпращането на гласови съобщения."; + +/* No comment provided by engineer. */ +"Protect app screen" = "Защити екрана на приложението"; + +/* No comment provided by engineer. */ +"Protect your chat profiles with a password!" = "Защитете чат профилите с парола!"; + +/* No comment provided by engineer. */ +"Protocol timeout" = "Време за изчакване на протокола"; + +/* No comment provided by engineer. */ +"Protocol timeout per KB" = "Време за изчакване на протокола за KB"; + +/* No comment provided by engineer. */ +"Push notifications" = "Push известия"; + +/* No comment provided by engineer. */ +"Rate the app" = "Оценете приложението"; + +/* chat item menu */ +"React…" = "Реагирай…"; + +/* No comment provided by engineer. */ +"Read" = "Прочетено"; + +/* No comment provided by engineer. */ +"Read more" = "Прочетете още"; + +/* No comment provided by engineer. */ +"Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address)." = "Прочетете повече в [Ръководство за потребителя](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address)."; + +/* No comment provided by engineer. */ +"Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends)." = "Прочетете повече в [Ръководство на потребителя](https://simplex.chat/docs/guide/readme.html#connect-to-friends)."; + +/* No comment provided by engineer. */ +"Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme)." = "Прочетете повече в нашето [GitHub хранилище](https://github.com/simplex-chat/simplex-chat#readme)."; + +/* No comment provided by engineer. */ +"Read more in our GitHub repository." = "Прочетете повече в нашето хранилище в GitHub."; + +/* No comment provided by engineer. */ +"Receipts are disabled" = "Потвърждениeто за доставка е деактивирано"; + +/* No comment provided by engineer. */ +"received answer…" = "получен отговор…"; + +/* No comment provided by engineer. */ +"Received at" = "Получено в"; + +/* copied message info */ +"Received at: %@" = "Получено в: %@"; + +/* No comment provided by engineer. */ +"received confirmation…" = "получено потвърждение…"; + +/* notification */ +"Received file event" = "Събитие за получен файл"; + +/* message info title */ +"Received message" = "Получено съобщение"; + +/* No comment provided by engineer. */ +"Receiving address will be changed to a different server. Address change will complete after sender comes online." = "Получаващият адрес ще бъде променен към друг сървър. Промяната на адреса ще завърши, след като подателят е онлайн."; + +/* No comment provided by engineer. */ +"Receiving file will be stopped." = "Получаващият се файл ще бъде спрян."; + +/* No comment provided by engineer. */ +"Receiving via" = "Получаване чрез"; + +/* No comment provided by engineer. */ +"Recipients see updates as you type them." = "Получателите виждат актуализации, докато ги въвеждате."; + +/* No comment provided by engineer. */ +"Reconnect all connected servers to force message delivery. It uses additional traffic." = "Повторно се свържете с всички свързани сървъри, за да принудите доставката на съобщенията. Използва се допълнителен трафик."; + +/* No comment provided by engineer. */ +"Reconnect servers?" = "Повторно свърване със сървърите?"; + +/* No comment provided by engineer. */ +"Record updated at" = "Записът е актуализиран на"; + +/* copied message info */ +"Record updated at: %@" = "Записът е актуализиран на: %@"; + +/* No comment provided by engineer. */ +"Reduced battery usage" = "Намалена консумация на батерията"; + +/* reject incoming call via notification */ +"Reject" = "Отхвърляне"; + +/* No comment provided by engineer. */ +"Reject (sender NOT notified)" = "Отхвърляне (подателят НЕ бива уведомен)"; + +/* No comment provided by engineer. */ +"Reject contact request" = "Отхвърли заявката за контакт"; + +/* call status */ +"rejected call" = "отхвърлено повикване"; + +/* No comment provided by engineer. */ +"Relay server is only used if necessary. Another party can observe your IP address." = "Реле сървър се използва само ако е необходимо. Друга страна може да наблюдава вашия IP адрес."; + +/* No comment provided by engineer. */ +"Relay server protects your IP address, but it can observe the duration of the call." = "Relay сървърът защитава вашия IP адрес, но може да наблюдава продължителността на разговора."; + +/* No comment provided by engineer. */ +"Remove" = "Премахване"; + +/* No comment provided by engineer. */ +"Remove member" = "Острани член"; + +/* No comment provided by engineer. */ +"Remove member?" = "Острани член?"; + +/* No comment provided by engineer. */ +"Remove passphrase from keychain?" = "Премахване на паролата от keychain?"; + +/* No comment provided by engineer. */ +"removed" = "отстранен"; + +/* rcv group event chat item */ +"removed %@" = "отстранен %@"; + +/* rcv group event chat item */ +"removed you" = "ви острани"; + +/* No comment provided by engineer. */ +"Renegotiate" = "Предоговоряне"; + +/* No comment provided by engineer. */ +"Renegotiate encryption" = "Предоговори криптирането"; + +/* No comment provided by engineer. */ +"Renegotiate encryption?" = "Предоговори криптирането?"; + +/* chat item action */ +"Reply" = "Отговори"; + +/* No comment provided by engineer. */ +"Required" = "Задължително"; + +/* No comment provided by engineer. */ +"Reset" = "Нулиране"; + +/* No comment provided by engineer. */ +"Reset colors" = "Нулирай цветовете"; + +/* No comment provided by engineer. */ +"Reset to defaults" = "Възстановяване на настройките по подразбиране"; + +/* No comment provided by engineer. */ +"Restart the app to create a new chat profile" = "Рестартирайте приложението, за да създадете нов чат профил"; + +/* No comment provided by engineer. */ +"Restart the app to use imported chat database" = "Рестартирайте приложението, за да използвате импортирана чат база данни"; + +/* No comment provided by engineer. */ +"Restore" = "Възстанови"; + +/* No comment provided by engineer. */ +"Restore database backup" = "Възстанови резервно копие на база данни"; + +/* No comment provided by engineer. */ +"Restore database backup?" = "Възстанови резервно копие на база данни?"; + +/* No comment provided by engineer. */ +"Restore database error" = "Грешка при възстановяване на базата данни"; + +/* chat item action */ +"Reveal" = "Покажи"; + +/* No comment provided by engineer. */ +"Revert" = "Отмени промените"; + +/* No comment provided by engineer. */ +"Revoke" = "Отзови"; + +/* cancel file action */ +"Revoke file" = "Отзови файл"; + +/* No comment provided by engineer. */ +"Revoke file?" = "Отзови файл?"; + +/* No comment provided by engineer. */ +"Role" = "Роля"; + +/* No comment provided by engineer. */ +"Run chat" = "Стартиране на чат"; + +/* chat item action */ +"Save" = "Запази"; + +/* No comment provided by engineer. */ +"Save (and notify contacts)" = "Запази (и уведоми контактите)"; + +/* No comment provided by engineer. */ +"Save and notify contact" = "Запази и уведоми контакта"; + +/* No comment provided by engineer. */ +"Save and notify group members" = "Запази и уведоми членовете на групата"; + +/* No comment provided by engineer. */ +"Save and update group profile" = "Запази и актуализирай профила на групата"; + +/* No comment provided by engineer. */ +"Save archive" = "Запази архив"; + +/* No comment provided by engineer. */ +"Save auto-accept settings" = "Запази настройките за автоматично приемане"; + +/* No comment provided by engineer. */ +"Save group profile" = "Запази профила на групата"; + +/* No comment provided by engineer. */ +"Save passphrase and open chat" = "Запази паролата и отвори чата"; + +/* No comment provided by engineer. */ +"Save passphrase in Keychain" = "Запази паролата в Keychain"; + +/* No comment provided by engineer. */ +"Save preferences?" = "Запази настройките?"; + +/* No comment provided by engineer. */ +"Save profile password" = "Запази паролата на профила"; + +/* No comment provided by engineer. */ +"Save servers" = "Запази сървърите"; + +/* No comment provided by engineer. */ +"Save servers?" = "Запази сървърите?"; + +/* No comment provided by engineer. */ +"Save settings?" = "Запази настройките?"; + +/* No comment provided by engineer. */ +"Save welcome message?" = "Запази съобщението при посрещане?"; + +/* No comment provided by engineer. */ +"Saved WebRTC ICE servers will be removed" = "Запазените WebRTC ICE сървъри ще бъдат премахнати"; + +/* No comment provided by engineer. */ +"Scan code" = "Сканирай код"; + +/* No comment provided by engineer. */ +"Scan QR code" = "Сканирай QR код"; + +/* No comment provided by engineer. */ +"Scan security code from your contact's app." = "Сканирайте кода за сигурност от приложението на вашия контакт."; + +/* No comment provided by engineer. */ +"Scan server QR code" = "Сканирай QR кода на сървъра"; + +/* No comment provided by engineer. */ +"Search" = "Търсене"; + +/* network option */ +"sec" = "сек."; + +/* time unit */ +"seconds" = "секунди"; + +/* No comment provided by engineer. */ +"secret" = "таен"; + +/* server test step */ +"Secure queue" = "Сигурна опашка"; + +/* No comment provided by engineer. */ +"Security assessment" = "Оценка на сигурността"; + +/* No comment provided by engineer. */ +"Security code" = "Код за сигурност"; + +/* chat item text */ +"security code changed" = "кодът за сигурност е променен"; + +/* No comment provided by engineer. */ +"Select" = "Избери"; + +/* No comment provided by engineer. */ +"Self-destruct" = "Самоунищожение"; + +/* No comment provided by engineer. */ +"Self-destruct passcode" = "Код за достъп за самоунищожение"; + +/* No comment provided by engineer. */ +"Self-destruct passcode changed!" = "Кодът за достъп за самоунищожение е променен!"; + +/* No comment provided by engineer. */ +"Self-destruct passcode enabled!" = "Кодът за достъп за самоунищожение е активиран!"; + +/* No comment provided by engineer. */ +"Send" = "Изпрати"; + +/* No comment provided by engineer. */ +"Send a live message - it will update for the recipient(s) as you type it" = "Изпратете съобщение на живо - то ще се актуализира за получателя(ите), докато го пишете"; + +/* No comment provided by engineer. */ +"Send delivery receipts to" = "Изпращайте потвърждениe за доставка на"; + +/* No comment provided by engineer. */ +"Send direct message" = "Изпрати лично съобщение"; + +/* No comment provided by engineer. */ +"Send disappearing message" = "Изпрати изчезващо съобщение"; + +/* No comment provided by engineer. */ +"Send link previews" = "Изпрати визуализация на линковете"; + +/* No comment provided by engineer. */ +"Send live message" = "Изпрати съобщение на живо"; + +/* No comment provided by engineer. */ +"Send notifications" = "Изпращай известия"; + +/* No comment provided by engineer. */ +"Send notifications:" = "Изпратени известия:"; + +/* No comment provided by engineer. */ +"Send questions and ideas" = "Изпращайте въпроси и идеи"; + +/* No comment provided by engineer. */ +"Send receipts" = "Изпращане на потвърждениe за доставка"; + +/* No comment provided by engineer. */ +"Send them from gallery or custom keyboards." = "Изпрати от галерия или персонализирани клавиатури."; + +/* No comment provided by engineer. */ +"Sender cancelled file transfer." = "Подателят отмени прехвърлянето на файла."; + +/* No comment provided by engineer. */ +"Sender may have deleted the connection request." = "Подателят може да е изтрил заявката за връзка."; + +/* No comment provided by engineer. */ +"Sending delivery receipts will be enabled for all contacts in all visible chat profiles." = "Изпращането на потвърждениe за доставка ще бъде активирано за всички контакти във всички видими чат профили."; + +/* No comment provided by engineer. */ +"Sending delivery receipts will be enabled for all contacts." = "Изпращането на потвърждениe за доставка ще бъде активирано за всички контакти."; + +/* No comment provided by engineer. */ +"Sending file will be stopped." = "Изпращането на файла ще бъде спряно."; + +/* No comment provided by engineer. */ +"Sending receipts is disabled for %lld contacts" = "Изпращането на потвърждениe за доставка е деактивирано за %lld контакта"; + +/* No comment provided by engineer. */ +"Sending receipts is disabled for %lld groups" = "Изпращането на потвърждениe за доставка е деактивирано за %lld групи"; + +/* No comment provided by engineer. */ +"Sending receipts is enabled for %lld contacts" = "Изпращането на потвърждениe за доставка е активирано за %lld контакта"; + +/* No comment provided by engineer. */ +"Sending receipts is enabled for %lld groups" = "Изпращането на потвърждениe за доставка е активирано за %lld групи"; + +/* No comment provided by engineer. */ +"Sending via" = "Изпращане чрез"; + +/* No comment provided by engineer. */ +"Sent at" = "Изпратено на"; + +/* copied message info */ +"Sent at: %@" = "Изпратено на: %@"; + +/* notification */ +"Sent file event" = "Събитие за изпратен файл"; + +/* message info title */ +"Sent message" = "Изпратено съобщение"; + +/* No comment provided by engineer. */ +"Sent messages will be deleted after set time." = "Изпратените съобщения ще бъдат изтрити след зададеното време."; + +/* server test error */ +"Server requires authorization to create queues, check password" = "Сървърът изисква оторизация за създаване на опашки, проверете паролата"; + +/* server test error */ +"Server requires authorization to upload, check password" = "Сървърът изисква оторизация за качване, проверете паролата"; + +/* No comment provided by engineer. */ +"Server test failed!" = "Тестът на сървъра е неуспешен!"; + +/* No comment provided by engineer. */ +"Servers" = "Сървъри"; + +/* No comment provided by engineer. */ +"Set 1 day" = "Задай 1 ден"; + +/* No comment provided by engineer. */ +"Set contact name…" = "Задай име на контакт…"; + +/* No comment provided by engineer. */ +"Set group preferences" = "Задай групови настройки"; + +/* No comment provided by engineer. */ +"Set it instead of system authentication." = "Задайте го вместо системната идентификация."; + +/* No comment provided by engineer. */ +"Set passcode" = "Задай kод за достъп"; + +/* No comment provided by engineer. */ +"Set passphrase to export" = "Задай парола за експортиране"; + +/* No comment provided by engineer. */ +"Set the message shown to new members!" = "Задай съобщението, показано на новите членове!"; + +/* No comment provided by engineer. */ +"Set timeouts for proxy/VPN" = "Задай време за изчакване за прокси/VPN"; + +/* No comment provided by engineer. */ +"Settings" = "Настройки"; + +/* chat item action */ +"Share" = "Сподели"; + +/* No comment provided by engineer. */ +"Share 1-time link" = "Сподели еднократен линк"; + +/* No comment provided by engineer. */ +"Share address" = "Сподели адрес"; + +/* No comment provided by engineer. */ +"Share address with contacts?" = "Сподели адреса с контактите?"; + +/* No comment provided by engineer. */ +"Share link" = "Сподели линк"; + +/* No comment provided by engineer. */ +"Share one-time invitation link" = "Сподели линк за еднократна покана"; + +/* No comment provided by engineer. */ +"Share with contacts" = "Сподели с контактите"; + +/* No comment provided by engineer. */ +"Show calls in phone history" = "Показване на обажданията в хронологията на телефона"; + +/* No comment provided by engineer. */ +"Show developer options" = "Покажи опциите за разработчици"; + +/* No comment provided by engineer. */ +"Show last messages" = "Показване на последните съобщения в листа с чатовете"; + +/* No comment provided by engineer. */ +"Show preview" = "Показване на визуализация"; + +/* No comment provided by engineer. */ +"Show:" = "Покажи:"; + +/* No comment provided by engineer. */ +"SimpleX address" = "SimpleX адрес"; + +/* No comment provided by engineer. */ +"SimpleX Address" = "SimpleX Адрес"; + +/* No comment provided by engineer. */ +"SimpleX Chat security was audited by Trail of Bits." = "Сигурността на SimpleX Chat беше одитирана от Trail of Bits."; + +/* simplex link type */ +"SimpleX contact address" = "SimpleX адрес за контакт"; + +/* notification */ +"SimpleX encrypted message or connection event" = "SimpleX криптирано съобщение или събитие за връзка"; + +/* simplex link type */ +"SimpleX group link" = "SimpleX групов линк"; + +/* No comment provided by engineer. */ +"SimpleX links" = "SimpleX линкове"; + +/* No comment provided by engineer. */ +"SimpleX Lock" = "SimpleX заключване"; + +/* No comment provided by engineer. */ +"SimpleX Lock mode" = "Режим на SimpleX заключване"; + +/* No comment provided by engineer. */ +"SimpleX Lock not enabled!" = "SimpleX заключване не е активирано!"; + +/* No comment provided by engineer. */ +"SimpleX Lock turned on" = "SimpleX заключване е включено"; + +/* simplex link type */ +"SimpleX one-time invitation" = "Еднократна покана за SimpleX"; + +/* No comment provided by engineer. */ +"Simplified incognito mode" = "Опростен режим инкогнито"; + +/* No comment provided by engineer. */ +"Skip" = "Пропускане"; + +/* No comment provided by engineer. */ +"Skipped messages" = "Пропуснати съобщения"; + +/* No comment provided by engineer. */ +"Small groups (max 20)" = "Малки групи (максимум 20)"; + +/* No comment provided by engineer. */ +"SMP servers" = "SMP сървъри"; + +/* No comment provided by engineer. */ +"Some non-fatal errors occurred during import - you may see Chat console for more details." = "Някои не-фатални грешки са възникнали по време на импортиране - може да видите конзолата за повече подробности."; + +/* notification title */ +"Somebody" = "Някой"; + +/* No comment provided by engineer. */ +"Start a new chat" = "Започни нов чат"; + +/* No comment provided by engineer. */ +"Start chat" = "Започни чат"; + +/* No comment provided by engineer. */ +"Start migration" = "Започни миграция"; + +/* No comment provided by engineer. */ +"starting…" = "стартиране…"; + +/* No comment provided by engineer. */ +"Stop" = "Спри"; + +/* No comment provided by engineer. */ +"Stop chat to enable database actions" = "Спрете чата, за да активирате действията с базата данни"; + +/* No comment provided by engineer. */ +"Stop chat to export, import or delete chat database. You will not be able to receive and send messages while the chat is stopped." = "Спрете чата, за да експортирате, импортирате или изтриете чат базата данни. Няма да можете да получавате и изпращате съобщения, докато чатът е спрян."; + +/* No comment provided by engineer. */ +"Stop chat?" = "Спри чата?"; + +/* cancel file action */ +"Stop file" = "Спри файл"; + +/* No comment provided by engineer. */ +"Stop receiving file?" = "Спри получаването на файла?"; + +/* No comment provided by engineer. */ +"Stop sending file?" = "Спри изпращането на файла?"; + +/* No comment provided by engineer. */ +"Stop sharing" = "Спри споделянето"; + +/* No comment provided by engineer. */ +"Stop sharing address?" = "Спри споделянето на адреса?"; + +/* authentication reason */ +"Stop SimpleX" = "Спри SimpleX"; + +/* No comment provided by engineer. */ +"strike" = "зачеркнат"; + +/* No comment provided by engineer. */ +"Submit" = "Изпрати"; + +/* No comment provided by engineer. */ +"Support SimpleX Chat" = "Подкрепете SimpleX Chat"; + +/* No comment provided by engineer. */ +"System" = "Системен"; + +/* No comment provided by engineer. */ +"System authentication" = "Системна идентификация"; + +/* No comment provided by engineer. */ +"Take picture" = "Направи снимка"; + +/* No comment provided by engineer. */ +"Tap button " = "Докосни бутона "; + +/* No comment provided by engineer. */ +"Tap to activate profile." = "Докосни за активиране на профил."; + +/* No comment provided by engineer. */ +"Tap to join" = "Докосни за вход"; + +/* No comment provided by engineer. */ +"Tap to join incognito" = "Докосни за инкогнито вход"; + +/* No comment provided by engineer. */ +"Tap to start a new chat" = "Докосни за започване на нов чат"; + +/* No comment provided by engineer. */ +"TCP connection timeout" = "Времето на изчакване за установяване на TCP връзка"; + +/* No comment provided by engineer. */ +"TCP_KEEPCNT" = "TCP_KEEPCNT"; + +/* No comment provided by engineer. */ +"TCP_KEEPIDLE" = "TCP_KEEPIDLE"; + +/* No comment provided by engineer. */ +"TCP_KEEPINTVL" = "TCP_KEEPINTVL"; + +/* server test failure */ +"Test failed at step %@." = "Тестът е неуспешен на стъпка %@."; + +/* No comment provided by engineer. */ +"Test server" = "Тествай сървър"; + +/* No comment provided by engineer. */ +"Test servers" = "Тествай сървърите"; + +/* No comment provided by engineer. */ +"Tests failed!" = "Тестовете са неуспешни!"; + +/* No comment provided by engineer. */ +"Thank you for installing SimpleX Chat!" = "Благодарим Ви, че инсталирахте SimpleX Chat!"; + +/* No comment provided by engineer. */ +"Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Благодарение на потребителите – [допринесете през Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"; + +/* No comment provided by engineer. */ +"Thanks to the users – contribute via Weblate!" = "Благодарение на потребителите – допринесете през Weblate!"; + +/* No comment provided by engineer. */ +"The 1st platform without any user identifiers – private by design." = "Първата платформа без никакви потребителски идентификатори – поверителна по дизайн."; + +/* No comment provided by engineer. */ +"The app can notify you when you receive messages or contact requests - please open settings to enable." = "Приложението може да ви уведоми, когато получите съобщения или заявки за контакт - моля, отворете настройките, за да активирате."; + +/* No comment provided by engineer. */ +"The attempt to change database passphrase was not completed." = "Опитът за промяна на паролата на базата данни не беше завършен."; + +/* No comment provided by engineer. */ +"The connection you accepted will be cancelled!" = "Връзката, която приехте, ще бъде отказана!"; + +/* No comment provided by engineer. */ +"The contact you shared this link with will NOT be able to connect!" = "Контактът, с когото споделихте този линк, НЯМА да може да се свърже!"; + +/* No comment provided by engineer. */ +"The created archive is available via app Settings / Database / Old database archive." = "Създаденият архив е достъпен чрез Настройки на приложението / База данни / Стар архив на база данни."; + +/* No comment provided by engineer. */ +"The encryption is working and the new encryption agreement is not required. It may result in connection errors!" = "Криптирането работи и новото споразумение за криптиране не е необходимо. Това може да доведе до грешки при свързване!"; + +/* No comment provided by engineer. */ +"The group is fully decentralized – it is visible only to the members." = "Групата е напълно децентрализирана – видима е само за членовете."; + +/* No comment provided by engineer. */ +"The hash of the previous message is different." = "Хешът на предишното съобщение е различен."; + +/* No comment provided by engineer. */ +"The ID of the next message is incorrect (less or equal to the previous).\nIt can happen because of some bug or when the connection is compromised." = "Неправилно ID на следващото съобщение (по-малко или еднакво с предишното).\nТова може да се случи поради някаква грешка или когато връзката е компрометирана."; + +/* No comment provided by engineer. */ +"The message will be deleted for all members." = "Съобщението ще бъде изтрито за всички членове."; + +/* No comment provided by engineer. */ +"The message will be marked as moderated for all members." = "Съобщението ще бъде маркирано като модерирано за всички членове."; + +/* No comment provided by engineer. */ +"The next generation of private messaging" = "Ново поколение поверителни съобщения"; + +/* No comment provided by engineer. */ +"The old database was not removed during the migration, it can be deleted." = "Старата база данни не бе премахната по време на миграцията, тя може да бъде изтрита."; + +/* No comment provided by engineer. */ +"The profile is only shared with your contacts." = "Профилът се споделя само с вашите контакти."; + +/* No comment provided by engineer. */ +"The second tick we missed! ✅" = "Втората отметка, която пропуснахме! ✅"; + +/* No comment provided by engineer. */ +"The sender will NOT be notified" = "Подателят НЯМА да бъде уведомен"; + +/* No comment provided by engineer. */ +"The servers for new connections of your current chat profile **%@**." = "Сървърите за нови връзки на текущия ви чат профил **%@**."; + +/* No comment provided by engineer. */ +"Theme" = "Тема"; + +/* No comment provided by engineer. */ +"There should be at least one user profile." = "Трябва да има поне един потребителски профил."; + +/* No comment provided by engineer. */ +"There should be at least one visible user profile." = "Трябва да има поне един видим потребителски профил."; + +/* No comment provided by engineer. */ +"These settings are for your current profile **%@**." = "Тези настройки са за текущия ви профил **%@**."; + +/* No comment provided by engineer. */ +"They can be overridden in contact and group settings." = "Те могат да бъдат променени в настройките за всеки контакт и група."; + +/* No comment provided by engineer. */ +"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Това действие не може да бъде отменено - всички получени и изпратени файлове и медия ще бъдат изтрити. Снимките с ниска разделителна способност ще бъдат запазени."; + +/* No comment provided by engineer. */ +"This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes." = "Това действие не може да бъде отменено - съобщенията, изпратени и получени по-рано от избраното, ще бъдат изтрити. Може да отнеме няколко минути."; + +/* No comment provided by engineer. */ +"This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost." = "Това действие не може да бъде отменено - вашият профил, контакти, съобщения и файлове ще бъдат безвъзвратно загубени."; + +/* notification title */ +"this contact" = "този контакт"; + +/* No comment provided by engineer. */ +"This group has over %lld members, delivery receipts are not sent." = "Тази група има над %lld членове, потвърждения за доставка не се изпращат."; + +/* No comment provided by engineer. */ +"This group no longer exists." = "Тази група вече не съществува."; + +/* No comment provided by engineer. */ +"This setting applies to messages in your current chat profile **%@**." = "Тази настройка се прилага за съобщения в текущия ви профил **%@**."; + +/* No comment provided by engineer. */ +"To ask any questions and to receive updates:" = "За да задавате въпроси и да получавате актуализации:"; + +/* No comment provided by engineer. */ +"To connect, your contact can scan QR code or use the link in the app." = "За да се свърже, вашият контакт може да сканира QR код или да използва линка в приложението."; + +/* No comment provided by engineer. */ +"To make a new connection" = "За да направите нова връзка"; + +/* No comment provided by engineer. */ +"To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts." = "За да се защити поверителността, вместо потребителски идентификатори, използвани от всички други платформи, SimpleX има идентификатори за опашки от съобщения, отделни за всеки от вашите контакти."; + +/* No comment provided by engineer. */ +"To protect timezone, image/voice files use UTC." = "За да не се разкрива часовата зона, файловете с изображения/глас използват UTC."; + +/* No comment provided by engineer. */ +"To protect your information, turn on SimpleX Lock.\nYou will be prompted to complete authentication before this feature is enabled." = "За да защитите информацията си, включете SimpleX заключване.\nЩе бъдете подканени да извършите идентификация, преди тази функция да бъде активирана."; + +/* No comment provided by engineer. */ +"To record voice message please grant permission to use Microphone." = "За да запишете гласово съобщение, моля, дайте разрешение за използване на микрофон."; + +/* No comment provided by engineer. */ +"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "За да разкриете своя скрит профил, въведете пълна парола в полето за търсене на страницата **Вашите чат профили**."; + +/* No comment provided by engineer. */ +"To support instant push notifications the chat database has to be migrated." = "За поддръжка на незабавни push известия, базата данни за чат трябва да бъде мигрирана."; + +/* No comment provided by engineer. */ +"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "За да проверите криптирането от край до край с вашия контакт, сравнете (или сканирайте) кода на вашите устройства."; + +/* No comment provided by engineer. */ +"Toggle incognito when connecting." = "Избор на инкогнито при свързване."; + +/* No comment provided by engineer. */ +"Transport isolation" = "Транспортна изолация"; + +/* No comment provided by engineer. */ +"Trying to connect to the server used to receive messages from this contact (error: %@)." = "Опит за свързване със сървъра, използван за получаване на съобщения от този контакт (грешка: %@)."; + +/* No comment provided by engineer. */ +"Trying to connect to the server used to receive messages from this contact." = "Опит за свързване със сървъра, използван за получаване на съобщения от този контакт."; + +/* No comment provided by engineer. */ +"Turn off" = "Изключи"; + +/* No comment provided by engineer. */ +"Turn off notifications?" = "Изключи известията?"; + +/* No comment provided by engineer. */ +"Turn on" = "Включи"; + +/* No comment provided by engineer. */ +"Unable to record voice message" = "Не може да се запише гласово съобщение"; + +/* item status description */ +"Unexpected error: %@" = "Неочаквана грешка: %@"; + +/* No comment provided by engineer. */ +"Unexpected migration state" = "Неочаквано състояние на миграция"; + +/* No comment provided by engineer. */ +"Unfav." = "Премахни от любимите"; + +/* No comment provided by engineer. */ +"Unhide" = "Покажи"; + +/* No comment provided by engineer. */ +"Unhide chat profile" = "Покажи чат профила"; + +/* No comment provided by engineer. */ +"Unhide profile" = "Покажи профила"; + +/* No comment provided by engineer. */ +"Unit" = "Мерна единица"; + +/* connection info */ +"unknown" = "неизвестен"; + +/* callkit banner */ +"Unknown caller" = "Неизвестен номер"; + +/* No comment provided by engineer. */ +"Unknown database error: %@" = "Неизвестна грешка в базата данни: %@"; + +/* No comment provided by engineer. */ +"Unknown error" = "Непозната грешка"; + +/* No comment provided by engineer. */ +"Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." = "Освен ако не използвате интерфейса за повикване на iOS, активирайте режима \"Не безпокой\", за да избегнете прекъсвания."; + +/* No comment provided by engineer. */ +"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Освен ако вашият контакт не е изтрил връзката или този линк вече е бил използван, това може да е грешка - моля, докладвайте.\nЗа да се свържете, моля, помолете вашия контакт да създаде друг линк за връзка и проверете дали имате стабилна мрежова връзка."; + +/* No comment provided by engineer. */ +"Unlock" = "Отключи"; + +/* authentication reason */ +"Unlock app" = "Отключи приложението"; + +/* No comment provided by engineer. */ +"Unmute" = "Уведомявай"; + +/* No comment provided by engineer. */ +"Unread" = "Непрочетено"; + +/* No comment provided by engineer. */ +"Update" = "Актуализация"; + +/* No comment provided by engineer. */ +"Update .onion hosts setting?" = "Актуализиране на настройката за .onion хостове?"; + +/* No comment provided by engineer. */ +"Update database passphrase" = "Актуализирай паролата на базата данни"; + +/* No comment provided by engineer. */ +"Update network settings?" = "Актуализиране на мрежовите настройки?"; + +/* No comment provided by engineer. */ +"Update transport isolation mode?" = "Актуализиране на режима на изолация на транспорта?"; + +/* rcv group event chat item */ +"updated group profile" = "актуализиран профил на групата"; + +/* No comment provided by engineer. */ +"Updating settings will re-connect the client to all servers." = "Актуализирането на настройките ще свърже отново клиента към всички сървъри."; + +/* No comment provided by engineer. */ +"Updating this setting will re-connect the client to all servers." = "Актуализирането на тази настройка ще свърже повторно клиента към всички сървъри."; + +/* No comment provided by engineer. */ +"Upgrade and open chat" = "Актуализирай и отвори чата"; + +/* server test step */ +"Upload file" = "Качи файл"; + +/* No comment provided by engineer. */ +"Use .onion hosts" = "Използвай .onion хостове"; + +/* No comment provided by engineer. */ +"Use chat" = "Използвай чата"; + +/* No comment provided by engineer. */ +"Use current profile" = "Използвай текущия профил"; + +/* No comment provided by engineer. */ +"Use for new connections" = "Използвай за нови връзки"; + +/* No comment provided by engineer. */ +"Use iOS call interface" = "Използвай интерфейса за повикване на iOS"; + +/* No comment provided by engineer. */ +"Use new incognito profile" = "Използвай нов инкогнито профил"; + +/* No comment provided by engineer. */ +"Use server" = "Използвай сървър"; + +/* No comment provided by engineer. */ +"Use SimpleX Chat servers?" = "Използвай сървърите на SimpleX Chat?"; + +/* No comment provided by engineer. */ +"User profile" = "Потребителски профил"; + +/* No comment provided by engineer. */ +"Using .onion hosts requires compatible VPN provider." = "Използването на .onion хостове изисква съвместим VPN доставчик."; + +/* No comment provided by engineer. */ +"Using SimpleX Chat servers." = "Използват се сървърите на SimpleX Chat."; + +/* No comment provided by engineer. */ +"v%@ (%@)" = "v%@ (%@)"; + +/* No comment provided by engineer. */ +"Verify connection security" = "Потвръди сигурността на връзката"; + +/* No comment provided by engineer. */ +"Verify security code" = "Потвръди кода за сигурност"; + +/* No comment provided by engineer. */ +"Via browser" = "Чрез браузър"; + +/* chat list item description */ +"via contact address link" = "чрез линк с адрес за контакт"; + +/* chat list item description */ +"via group link" = "чрез групов линк"; + +/* chat list item description */ +"via one-time link" = "чрез еднократен линк за връзка"; + +/* No comment provided by engineer. */ +"via relay" = "чрез реле"; + +/* No comment provided by engineer. */ +"Video call" = "Видео разговор"; + +/* No comment provided by engineer. */ +"video call (not e2e encrypted)" = "видео разговор (не е e2e криптиран)"; + +/* No comment provided by engineer. */ +"Video will be received when your contact completes uploading it." = "Видеото ще бъде получено, когато вашият контакт завърши качването му."; + +/* No comment provided by engineer. */ +"Video will be received when your contact is online, please wait or check later!" = "Видеото ще бъде получено, когато вашият контакт е онлайн, моля, изчакайте или проверете по-късно!"; + +/* No comment provided by engineer. */ +"Videos and files up to 1gb" = "Видео и файлове до 1gb"; + +/* No comment provided by engineer. */ +"View security code" = "Виж кода за сигурност"; + +/* No comment provided by engineer. */ +"Voice message…" = "Гласово съобщение…"; + +/* chat feature */ +"Voice messages" = "Гласови съобщения"; + +/* No comment provided by engineer. */ +"Voice messages are prohibited in this chat." = "Гласовите съобщения са забранени в този чат."; + +/* No comment provided by engineer. */ +"Voice messages are prohibited in this group." = "Гласовите съобщения са забранени в тази група."; + +/* No comment provided by engineer. */ +"Voice messages prohibited!" = "Гласовите съобщения са забранени!"; + +/* No comment provided by engineer. */ +"waiting for answer…" = "чака се отговор…"; + +/* No comment provided by engineer. */ +"waiting for confirmation…" = "чака се за потвърждение…"; + +/* No comment provided by engineer. */ +"Waiting for file" = "Изчаква се получаването на файла"; + +/* No comment provided by engineer. */ +"Waiting for image" = "Изчаква се получаването на изображението"; + +/* No comment provided by engineer. */ +"Waiting for video" = "Изчаква се получаването на видеото"; + +/* No comment provided by engineer. */ +"wants to connect to you!" = "иска да се свърже с вас!"; + +/* No comment provided by engineer. */ +"Warning: you may lose some data!" = "Предупреждение: Може да загубите някои данни!"; + +/* No comment provided by engineer. */ +"WebRTC ICE servers" = "WebRTC ICE сървъри"; + +/* time unit */ +"weeks" = "седмици"; + +/* No comment provided by engineer. */ +"Welcome %@!" = "Добре дошли %@!"; + +/* No comment provided by engineer. */ +"Welcome message" = "Съобщение при посрещане"; + +/* No comment provided by engineer. */ +"What's new" = "Какво е новото"; + +/* No comment provided by engineer. */ +"When available" = "Когато са налични"; + +/* No comment provided by engineer. */ +"When people request to connect, you can accept or reject it." = "Когато хората искат да се свържат с вас, можете да ги приемете или отхвърлите."; + +/* No comment provided by engineer. */ +"When you share an incognito profile with somebody, this profile will be used for the groups they invite you to." = "Когато споделяте инкогнито профил с някого, този профил ще се използва за групите, в които той ви кани."; + +/* No comment provided by engineer. */ +"With optional welcome message." = "С незадължително съобщение при посрещане."; + +/* No comment provided by engineer. */ +"Wrong database passphrase" = "Грешна парола за базата данни"; + +/* No comment provided by engineer. */ +"Wrong passphrase!" = "Грешна парола!"; + +/* No comment provided by engineer. */ +"XFTP servers" = "XFTP сървъри"; + +/* pref value */ +"yes" = "да"; + +/* No comment provided by engineer. */ +"You" = "Вие"; + +/* No comment provided by engineer. */ +"You accepted connection" = "Вие приехте връзката"; + +/* No comment provided by engineer. */ +"You allow" = "Вие позволявате"; + +/* No comment provided by engineer. */ +"You already have a chat profile with the same display name. Please choose another name." = "Вече имате чат профил със същото показвано име. Моля, изберете друго име."; + +/* No comment provided by engineer. */ +"You are already connected to %@." = "Вече сте вече свързани с %@."; + +/* No comment provided by engineer. */ +"You are connected to the server used to receive messages from this contact." = "Вие сте свързани към сървъра, използван за получаване на съобщения от този контакт."; + +/* No comment provided by engineer. */ +"you are invited to group" = "вие сте поканени в групата"; + +/* No comment provided by engineer. */ +"You are invited to group" = "Поканени сте в групата"; + +/* No comment provided by engineer. */ +"you are observer" = "вие сте наблюдател"; + +/* No comment provided by engineer. */ +"You can accept calls from lock screen, without device and app authentication." = "Можете да приемате обаждания от заключен екран, без идентификация на устройство и приложението."; + +/* No comment provided by engineer. */ +"You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button." = "Можете също да се свържете, като натиснете върху линка. Ако се отвори в браузъра, натиснете върху бутона **Отваряне в мобилно приложение**."; + +/* No comment provided by engineer. */ +"You can create it later" = "Можете да го създадете по-късно"; + +/* No comment provided by engineer. */ +"You can enable later via Settings" = "Можете да активирате по-късно през Настройки"; + +/* No comment provided by engineer. */ +"You can enable them later via app Privacy & Security settings." = "Можете да ги активирате по-късно през настройките за \"Поверителност и сигурност\" на приложението."; + +/* No comment provided by engineer. */ +"You can hide or mute a user profile - swipe it to the right." = "Можете да скриете или заглушите известията за потребителски профил - плъзнете надясно."; + +/* notification body */ +"You can now send messages to %@" = "Вече можете да изпращате съобщения до %@"; + +/* No comment provided by engineer. */ +"You can set lock screen notification preview via settings." = "Можете да зададете визуализация на известията на заключен екран през настройките."; + +/* No comment provided by engineer. */ +"You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it." = "Можете да споделите линк или QR код - всеки ще може да се присъедини към групата. Няма да загубите членовете на групата, ако по-късно я изтриете."; + +/* No comment provided by engineer. */ +"You can share this address with your contacts to let them connect with **%@**." = "Можете да споделите този адрес с вашите контакти, за да им позволите да се свържат с **%@**."; + +/* No comment provided by engineer. */ +"You can share your address as a link or QR code - anybody can connect to you." = "Можете да споделите адреса си като линк или QR код - всеки може да се свърже с вас."; + +/* No comment provided by engineer. */ +"You can start chat via app Settings / Database or by restarting the app" = "Можете да започнете чат през Настройки на приложението / База данни или като рестартирате приложението"; + +/* No comment provided by engineer. */ +"You can turn on SimpleX Lock via Settings." = "Можете да включите SimpleX заключване през Настройки."; + +/* No comment provided by engineer. */ +"You can use markdown to format messages:" = "Можете да използвате markdown за форматиране на съобщенията:"; + +/* No comment provided by engineer. */ +"You can't send messages!" = "Не може да изпращате съобщения!"; + +/* chat item text */ +"you changed address" = "променихте адреса"; + +/* chat item text */ +"you changed address for %@" = "променихте адреса за %@"; + +/* snd group event chat item */ +"you changed role for yourself to %@" = "променихте ролята си на %@"; + +/* snd group event chat item */ +"you changed role of %@ to %@" = "променихте ролята на %1$@ на %2$@"; + +/* No comment provided by engineer. */ +"You control through which server(s) **to receive** the messages, your contacts – the servers you use to message them." = "Вие контролирате през кой сървър(и) **да получавате** съобщенията, вашите контакти – сървърите, които използвате, за да им изпращате съобщения."; + +/* No comment provided by engineer. */ +"You could not be verified; please try again." = "Не можахте да бъдете потвърдени; Моля, опитайте отново."; + +/* No comment provided by engineer. */ +"You have no chats" = "Нямате чатове"; + +/* No comment provided by engineer. */ +"You have to enter passphrase every time the app starts - it is not stored on the device." = "Трябва да въвеждате парола при всяко стартиране на приложението - тя не се съхранява на устройството."; + +/* No comment provided by engineer. */ +"You invited a contact" = "Вие поканихте контакта"; + +/* No comment provided by engineer. */ +"You joined this group" = "Вие се присъединихте към тази група"; + +/* No comment provided by engineer. */ +"You joined this group. Connecting to inviting group member." = "Вие се присъединихте към тази група. Свързване с поканващия член на групата."; + +/* snd group event chat item */ +"you left" = "вие напуснахте"; + +/* 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." = "Трябва да използвате най-новата версия на вашата чат база данни САМО на едно устройство, в противен случай може да спрете да получавате съобщения от някои контакти."; + +/* No comment provided by engineer. */ +"You need to allow your contact to send voice messages to be able to send them." = "Трябва да разрешите на вашия контакт да изпраща гласови съобщения, за да можете да ги изпращате."; + +/* No comment provided by engineer. */ +"You rejected group invitation" = "Отхвърлихте поканата за групата"; + +/* snd group event chat item */ +"you removed %@" = "премахнахте %@"; + +/* No comment provided by engineer. */ +"You sent group invitation" = "Изпратихте покана за групата"; + +/* chat list item description */ +"you shared one-time link" = "споделихте еднократен линк за връзка"; + +/* chat list item description */ +"you shared one-time link incognito" = "споделихте еднократен инкогнито линк за връзка"; + +/* No comment provided by engineer. */ +"You will be connected to group when the group host's device is online, please wait or check later!" = "Ще бъдете свързани с групата, когато устройството на домакина на групата е онлайн, моля, изчакайте или проверете по-късно!"; + +/* No comment provided by engineer. */ +"You will be connected when your connection request is accepted, please wait or check later!" = "Ще бъдете свързани, когато заявката ви за връзка бъде приета, моля, изчакайте или проверете по-късно!"; + +/* No comment provided by engineer. */ +"You will be connected when your contact's device is online, please wait or check later!" = "Ще бъдете свързани, когато устройството на вашия контакт е онлайн, моля, изчакайте или проверете по-късно!"; + +/* No comment provided by engineer. */ +"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "Ще трябва да се идентифицирате, когато стартирате или възобновите приложението след 30 секунди във фонов режим."; + +/* No comment provided by engineer. */ +"You will join a group this link refers to and connect to its group members." = "Ще се присъедините към групата, към която този линк препраща, и ще се свържете с нейните членове."; + +/* No comment provided by engineer. */ +"You will still receive calls and notifications from muted profiles when they are active." = "Все още ще получавате обаждания и известия от заглушени профили, когато са активни."; + +/* No comment provided by engineer. */ +"You will stop receiving messages from this group. Chat history will be preserved." = "Ще спрете да получавате съобщения от тази група. Историята на чата ще бъде запазена."; + +/* No comment provided by engineer. */ +"You won't lose your contacts if you later delete your address." = "Няма да загубите контактите си, ако по-късно изтриете адреса си."; + +/* No comment provided by engineer. */ +"you: " = "вие: "; + +/* No comment provided by engineer. */ +"You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile" = "Опитвате се да поканите контакт, с когото сте споделили инкогнито профил, в групата, в която използвате основния си профил"; + +/* No comment provided by engineer. */ +"You're using an incognito profile for this group - to prevent sharing your main profile inviting contacts is not allowed" = "Използвате инкогнито профил за тази група - за да се предотврати споделянето на основния ви профил, поканите на контакти не са разрешени"; + +/* No comment provided by engineer. */ +"Your %@ servers" = "Вашите %@ сървъри"; + +/* No comment provided by engineer. */ +"Your calls" = "Вашите обаждания"; + +/* No comment provided by engineer. */ +"Your chat database" = "Вашата чат база данни"; + +/* No comment provided by engineer. */ +"Your chat database is not encrypted - set passphrase to encrypt it." = "Вашата чат база данни не е криптирана - задайте парола, за да я криптирате."; + +/* No comment provided by engineer. */ +"Your chat profile will be sent to group members" = "Вашият чат профил ще бъде изпратен на членовете на групата"; + +/* No comment provided by engineer. */ +"Your chat profiles" = "Вашите чат профили"; + +/* No comment provided by engineer. */ +"Your contact needs to be online for the connection to complete.\nYou can cancel this connection and remove the contact (and try later with a new link)." = "Вашият контакт трябва да бъде онлайн, за да осъществите връзката.\nМожете да откажете тази връзка и да премахнете контакта (и да опитате по -късно с нов линк)."; + +/* No comment provided by engineer. */ +"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Вашият контакт изпрати файл, който е по-голям от поддържания в момента максимален размер (%@)."; + +/* No comment provided by engineer. */ +"Your contacts can allow full message deletion." = "Вашите контакти могат да позволят пълното изтриване на съобщението."; + +/* No comment provided by engineer. */ +"Your contacts in SimpleX will see it.\nYou can change it in Settings." = "Вашите контакти в SimpleX ще го видят.\nМожете да го промените в Настройки."; + +/* No comment provided by engineer. */ +"Your contacts will remain connected." = "Вашите контакти ще останат свързани."; + +/* No comment provided by engineer. */ +"Your current chat database will be DELETED and REPLACED with the imported one." = "Вашата текуща чат база данни ще бъде ИЗТРИТА и ЗАМЕНЕНА с импортираната."; + +/* No comment provided by engineer. */ +"Your current profile" = "Вашият текущ профил"; + +/* No comment provided by engineer. */ +"Your ICE servers" = "Вашите ICE сървъри"; + +/* No comment provided by engineer. */ +"Your preferences" = "Вашите настройки"; + +/* No comment provided by engineer. */ +"Your privacy" = "Вашата поверителност"; + +/* No comment provided by engineer. */ +"Your profile **%@** will be shared." = "Вашият профил **%@** ще бъде споделен."; + +/* No comment provided by engineer. */ +"Your profile is stored on your device and shared only with your contacts.\nSimpleX servers cannot see your profile." = "Вашият профил се съхранява на вашето устройство и се споделя само с вашите контакти.\nSimpleX сървърите не могат да видят вашия профил."; + +/* No comment provided by engineer. */ +"Your profile, contacts and delivered messages are stored on your device." = "Вашият профил, контакти и доставени съобщения се съхраняват на вашето устройство."; + +/* No comment provided by engineer. */ +"Your random profile" = "Вашият автоматично генериран профил"; + +/* No comment provided by engineer. */ +"Your server" = "Вашият сървър"; + +/* No comment provided by engineer. */ +"Your server address" = "Вашият адрес на сървъра"; + +/* No comment provided by engineer. */ +"Your settings" = "Вашите настройки"; + +/* No comment provided by engineer. */ +"Your SimpleX address" = "Вашият SimpleX адрес"; + +/* No comment provided by engineer. */ +"Your SMP servers" = "Вашите SMP сървъри"; + +/* No comment provided by engineer. */ +"Your XFTP servers" = "Вашите XFTP сървъри"; + diff --git a/apps/ios/bg.lproj/SimpleX--iOS--InfoPlist.strings b/apps/ios/bg.lproj/SimpleX--iOS--InfoPlist.strings new file mode 100644 index 0000000000..d85455d875 --- /dev/null +++ b/apps/ios/bg.lproj/SimpleX--iOS--InfoPlist.strings @@ -0,0 +1,15 @@ +/* Bundle name */ +"CFBundleName" = "SimpleX"; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "SimpleX се нуждае от достъп до камерата, за да сканира QR кодове, за да се свърже с други потребители и за видео разговори."; + +/* Privacy - Face ID Usage Description */ +"NSFaceIDUsageDescription" = "SimpleX използва Face ID за локалнa идентификация"; + +/* Privacy - Microphone Usage Description */ +"NSMicrophoneUsageDescription" = "SimpleX се нуждае от достъп до микрофона за аудио и видео разговори и за запис на гласови съобщения."; + +/* Privacy - Photo Library Additions Usage Description */ +"NSPhotoLibraryAddUsageDescription" = "SimpleX се нуждае от достъп до фотобиблиотека за запазване на заснета и получена медия"; + diff --git a/apps/ios/de.lproj/Localizable.strings b/apps/ios/de.lproj/Localizable.strings index 285990467d..111ce0d916 100644 --- a/apps/ios/de.lproj/Localizable.strings +++ b/apps/ios/de.lproj/Localizable.strings @@ -1245,6 +1245,9 @@ /* No comment provided by engineer. */ "Encrypt database?" = "Datenbank verschlüsseln?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "Lokale Dateien verschlüsseln"; + /* No comment provided by engineer. */ "Encrypted database" = "Verschlüsselte Datenbank"; @@ -1356,6 +1359,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "Fehler beim Erstellen des Profils!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "Fehler beim Entschlüsseln der Datei"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Fehler beim Löschen der Chat-Datenbank"; diff --git a/apps/ios/es.lproj/Localizable.strings b/apps/ios/es.lproj/Localizable.strings index e351114d74..c4180ea153 100644 --- a/apps/ios/es.lproj/Localizable.strings +++ b/apps/ios/es.lproj/Localizable.strings @@ -1117,7 +1117,7 @@ "Direct messages between members are prohibited in this group." = "Los mensajes directos entre miembros del grupo no están permitidos."; /* No comment provided by engineer. */ -"Disable (keep overrides)" = "Desactivar (conservar anulaciones)"; +"Disable (keep overrides)" = "Desactivar (conservando anulaciones)"; /* No comment provided by engineer. */ "Disable for all" = "Desactivar para todos"; @@ -1473,6 +1473,9 @@ /* No comment provided by engineer. */ "Even when disabled in the conversation." = "Incluso si está desactivado para la conversación."; +/* No comment provided by engineer. */ +"event happened" = "evento ocurrido"; + /* No comment provided by engineer. */ "Exit without saving" = "Salir sin guardar"; diff --git a/apps/ios/fi.lproj/Localizable.strings b/apps/ios/fi.lproj/Localizable.strings index 47cce5061d..a917c4a0b4 100644 --- a/apps/ios/fi.lproj/Localizable.strings +++ b/apps/ios/fi.lproj/Localizable.strings @@ -1245,6 +1245,9 @@ /* No comment provided by engineer. */ "Encrypt database?" = "Salaa tietokanta?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "Salaa paikalliset tiedostot"; + /* No comment provided by engineer. */ "Encrypted database" = "Salattu tietokanta"; @@ -1356,6 +1359,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "Virhe profiilin luomisessa!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "Virhe tiedoston salauksen purussa"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Virhe keskustelujen tietokannan poistamisessa"; diff --git a/apps/ios/fr.lproj/Localizable.strings b/apps/ios/fr.lproj/Localizable.strings index 9ce7245cd0..f9f7703382 100644 --- a/apps/ios/fr.lproj/Localizable.strings +++ b/apps/ios/fr.lproj/Localizable.strings @@ -19,6 +19,9 @@ /* No comment provided by engineer. */ "_italic_" = "\\_italique_"; +/* No comment provided by engineer. */ +"- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable." = "- connexion au [service d'annuaire](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA) !\n- les accusés de réception (jusqu'à 20 membres).\n- plus rapide et plus stable."; + /* No comment provided by engineer. */ "- more stable message delivery.\n- a bit better groups.\n- and more!" = "- une diffusion plus stable des messages.\n- des groupes un peu plus performants.\n- et bien d'autres choses encore !"; @@ -181,6 +184,9 @@ /* No comment provided by engineer. */ "%lld minutes" = "%lld minutes"; +/* No comment provided by engineer. */ +"%lld new interface languages" = "%lld nouvelles langues d'interface"; + /* No comment provided by engineer. */ "%lld second(s)" = "%lld seconde·s"; @@ -443,6 +449,9 @@ /* No comment provided by engineer. */ "App build: %@" = "Build de l'app : %@"; +/* No comment provided by engineer. */ +"App encrypts new local files (except videos)." = "L'application chiffre les nouveaux fichiers locaux (sauf les vidéos)."; + /* No comment provided by engineer. */ "App icon" = "Icône de l'app"; @@ -536,6 +545,9 @@ /* No comment provided by engineer. */ "Both you and your contact can send voice messages." = "Vous et votre contact êtes tous deux en mesure d'envoyer des messages vocaux."; +/* No comment provided by engineer. */ +"Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Bulgare, finnois, thaïlandais et ukrainien - grâce aux utilisateurs et à [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat) !"; + /* 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)."; @@ -843,6 +855,9 @@ /* No comment provided by engineer. */ "Create link" = "Créer un lien"; +/* No comment provided by engineer. */ +"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Créer un nouveau profil sur [l'application de bureau](https://simplex.chat/downloads/). 💻"; + /* No comment provided by engineer. */ "Create one-time invitation link" = "Créer un lien d'invitation unique"; @@ -1149,6 +1164,9 @@ /* server test step */ "Disconnect" = "Se déconnecter"; +/* No comment provided by engineer. */ +"Discover and join groups" = "Découvrir et rejoindre des groupes"; + /* No comment provided by engineer. */ "Display name" = "Nom affiché"; @@ -1245,6 +1263,12 @@ /* No comment provided by engineer. */ "Encrypt database?" = "Chiffrer la base de données ?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "Chiffrer les fichiers locaux"; + +/* No comment provided by engineer. */ +"Encrypt stored files & media" = "Chiffrement des fichiers et des médias stockés"; + /* No comment provided by engineer. */ "Encrypted database" = "Base de données chiffrée"; @@ -1356,6 +1380,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "Erreur lors de la création du profil !"; +/* No comment provided by engineer. */ +"Error decrypting file" = "Erreur lors du déchiffrement du fichier"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Erreur lors de la suppression de la base de données du chat"; @@ -2121,6 +2148,9 @@ /* No comment provided by engineer. */ "New database archive" = "Nouvelle archive de base de données"; +/* No comment provided by engineer. */ +"New desktop app!" = "Nouvelle application de bureau !"; + /* No comment provided by engineer. */ "New display name" = "Nouveau nom d'affichage"; @@ -2935,6 +2965,9 @@ /* simplex link type */ "SimpleX one-time invitation" = "Invitation unique SimpleX"; +/* No comment provided by engineer. */ +"Simplified incognito mode" = "Mode incognito simplifié"; + /* No comment provided by engineer. */ "Skip" = "Passer"; @@ -3181,6 +3214,9 @@ /* 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 incognito when connecting." = "Basculer en mode incognito lors de la connexion."; + /* No comment provided by engineer. */ "Transport isolation" = "Transport isolé"; diff --git a/apps/ios/it.lproj/Localizable.strings b/apps/ios/it.lproj/Localizable.strings index 5bfaeefc99..a9a663dfdf 100644 --- a/apps/ios/it.lproj/Localizable.strings +++ b/apps/ios/it.lproj/Localizable.strings @@ -19,6 +19,9 @@ /* No comment provided by engineer. */ "_italic_" = "\\_corsivo_"; +/* No comment provided by engineer. */ +"- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable." = "- connessione al [servizio directory](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- ricevute di consegna (fino a 20 membri).\n- più veloce e più stabile."; + /* No comment provided by engineer. */ "- more stable message delivery.\n- a bit better groups.\n- and more!" = "- recapito dei messaggi più stabile.\n- gruppi un po' migliorati.\n- e altro ancora!"; @@ -181,6 +184,9 @@ /* No comment provided by engineer. */ "%lld minutes" = "%lld minuti"; +/* No comment provided by engineer. */ +"%lld new interface languages" = "%lld nuove lingue dell'interfaccia"; + /* No comment provided by engineer. */ "%lld second(s)" = "%lld secondo/i"; @@ -443,6 +449,9 @@ /* No comment provided by engineer. */ "App build: %@" = "Build dell'app: %@"; +/* No comment provided by engineer. */ +"App encrypts new local files (except videos)." = "L'app cripta i nuovi file locali (eccetto i video)."; + /* No comment provided by engineer. */ "App icon" = "Icona app"; @@ -536,6 +545,9 @@ /* No comment provided by engineer. */ "Both you and your contact can send voice messages." = "Sia tu che il tuo contatto potete inviare messaggi vocali."; +/* No comment provided by engineer. */ +"Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Bulgaro, finlandese, tailandese e ucraino - grazie agli utenti e a [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"; + /* 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)." = "Per profilo di chat (predefinito) o [per connessione](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)."; @@ -843,6 +855,9 @@ /* No comment provided by engineer. */ "Create link" = "Crea link"; +/* No comment provided by engineer. */ +"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Crea un nuovo profilo nell'[app desktop](https://simplex.chat/downloads/). 💻"; + /* No comment provided by engineer. */ "Create one-time invitation link" = "Crea link di invito una tantum"; @@ -1149,6 +1164,9 @@ /* server test step */ "Disconnect" = "Disconnetti"; +/* No comment provided by engineer. */ +"Discover and join groups" = "Scopri ed unisciti ai gruppi"; + /* No comment provided by engineer. */ "Display name" = "Nome da mostrare"; @@ -1245,6 +1263,12 @@ /* No comment provided by engineer. */ "Encrypt database?" = "Crittografare il database?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "Cripta i file locali"; + +/* No comment provided by engineer. */ +"Encrypt stored files & media" = "Crittografia di file e media memorizzati"; + /* No comment provided by engineer. */ "Encrypted database" = "Database crittografato"; @@ -1356,6 +1380,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "Errore nella creazione del profilo!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "Errore decifrando il file"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Errore nell'eliminazione del database della chat"; @@ -2121,6 +2148,9 @@ /* No comment provided by engineer. */ "New database archive" = "Nuovo archivio database"; +/* No comment provided by engineer. */ +"New desktop app!" = "Nuova app desktop!"; + /* No comment provided by engineer. */ "New display name" = "Nuovo nome da mostrare"; @@ -2935,6 +2965,9 @@ /* simplex link type */ "SimpleX one-time invitation" = "Invito SimpleX una tantum"; +/* No comment provided by engineer. */ +"Simplified incognito mode" = "Modalità incognito semplificata"; + /* No comment provided by engineer. */ "Skip" = "Salta"; @@ -3181,6 +3214,9 @@ /* No comment provided by engineer. */ "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 incognito when connecting." = "Attiva/disattiva l'incognito quando ti colleghi."; + /* No comment provided by engineer. */ "Transport isolation" = "Isolamento del trasporto"; diff --git a/apps/ios/ja.lproj/Localizable.strings b/apps/ios/ja.lproj/Localizable.strings index 3d78a9f6e3..6fadf87590 100644 --- a/apps/ios/ja.lproj/Localizable.strings +++ b/apps/ios/ja.lproj/Localizable.strings @@ -1242,6 +1242,9 @@ /* No comment provided by engineer. */ "Encrypt database?" = "データベースを暗号化しますか?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "ローカルファイルを暗号化する"; + /* No comment provided by engineer. */ "Encrypted database" = "暗号化済みデータベース"; @@ -1353,6 +1356,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "プロフィール作成にエラー発生!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "ファイルの復号エラー"; + /* No comment provided by engineer. */ "Error deleting chat database" = "チャットデータベース削除にエラー発生"; diff --git a/apps/ios/nl.lproj/Localizable.strings b/apps/ios/nl.lproj/Localizable.strings index 199afb8422..a218eeeff3 100644 --- a/apps/ios/nl.lproj/Localizable.strings +++ b/apps/ios/nl.lproj/Localizable.strings @@ -19,6 +19,9 @@ /* No comment provided by engineer. */ "_italic_" = "\\_cursief_"; +/* No comment provided by engineer. */ +"- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable." = "- verbinding maken met [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! \n- ontvangst bevestiging(tot 20 leden). \n- sneller en stabieler."; + /* No comment provided by engineer. */ "- more stable message delivery.\n- a bit better groups.\n- and more!" = "- stabielere berichtbezorging.\n- een beetje betere groepen.\n- en meer!"; @@ -56,7 +59,7 @@ "**Add new contact**: to create your one-time QR Code for your contact." = "**Nieuw contact toevoegen**: om uw eenmalige QR-code of link voor uw contact te maken."; /* No comment provided by engineer. */ -"**Create link / QR code** for your contact to use." = "**Maak een link / QR-code aan** die uw contactpersoon kan gebruiken."; +"**Create link / QR code** for your contact to use." = "**Maak een link / QR-code aan** die uw contact kan gebruiken."; /* No comment provided by engineer. */ "**e2e encrypted** audio call" = "**e2e versleuteld** audio gesprek"; @@ -80,7 +83,7 @@ "**Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from." = "**Aanbevolen**: apparaattoken en meldingen worden naar de SimpleX Chat-meldingsserver gestuurd, maar niet de berichtinhoud, -grootte of van wie het afkomstig is."; /* No comment provided by engineer. */ -"**Scan QR code**: to connect to your contact in person or via video call." = "**Scan QR-code**: om persoonlijk of via een video gesprek verbinding te maken met uw contactpersoon."; +"**Scan QR code**: to connect to your contact in person or via video call." = "**Scan QR-code**: om persoonlijk of via een video gesprek verbinding te maken met uw contact."; /* No comment provided by engineer. */ "**Warning**: Instant push notifications require passphrase saved in Keychain." = "**Waarschuwing**: voor directe push meldingen is een wachtwoord vereist dat is opgeslagen in de Keychain."; @@ -181,6 +184,9 @@ /* No comment provided by engineer. */ "%lld minutes" = "%lld minuten"; +/* No comment provided by engineer. */ +"%lld new interface languages" = "%lld nieuwe interface-talen"; + /* No comment provided by engineer. */ "%lld second(s)" = "%lld seconde(n)"; @@ -297,7 +303,7 @@ "Accept" = "Accepteer"; /* No comment provided by engineer. */ -"Accept connection request?" = "Accepteer contactpersoon"; +"Accept connection request?" = "Accepteer contact"; /* notification body */ "Accept contact request from %@?" = "Accepteer contactverzoek van %@?"; @@ -375,16 +381,16 @@ "Allow" = "Toestaan"; /* No comment provided by engineer. */ -"Allow calls only if your contact allows them." = "Sta oproepen alleen toe als uw contact persoon dit toestaat."; +"Allow calls only if your contact allows them." = "Sta oproepen alleen toe als uw contact dit toestaat."; /* No comment provided by engineer. */ -"Allow disappearing messages only if your contact allows it to you." = "Sta verdwijnende berichten alleen toe als uw contactpersoon dit toestaat."; +"Allow disappearing messages only if your contact allows it to you." = "Sta verdwijnende berichten alleen toe als uw contact dit toestaat."; /* No comment provided by engineer. */ -"Allow irreversible message deletion only if your contact allows it to you." = "Sta het onomkeerbaar verwijderen van berichten alleen toe als uw contactpersoon dit toestaat."; +"Allow irreversible message deletion only if your contact allows it to you." = "Sta het onomkeerbaar verwijderen van berichten alleen toe als uw contact dit toestaat."; /* No comment provided by engineer. */ -"Allow message reactions only if your contact allows them." = "Sta berichtreacties alleen toe als uw contactpersoon dit toestaat."; +"Allow message reactions only if your contact allows them." = "Sta berichtreacties alleen toe als uw contact dit toestaat."; /* No comment provided by engineer. */ "Allow message reactions." = "Sta berichtreacties toe."; @@ -405,7 +411,7 @@ "Allow to send voice messages." = "Sta toe om spraak berichten te verzenden."; /* No comment provided by engineer. */ -"Allow voice messages only if your contact allows them." = "Sta spraak berichten alleen toe als uw contactpersoon ze toestaat."; +"Allow voice messages only if your contact allows them." = "Sta spraak berichten alleen toe als uw contact ze toestaat."; /* No comment provided by engineer. */ "Allow voice messages?" = "Spraak berichten toestaan?"; @@ -443,6 +449,9 @@ /* No comment provided by engineer. */ "App build: %@" = "App build: %@"; +/* No comment provided by engineer. */ +"App encrypts new local files (except videos)." = "App versleutelt nieuwe lokale bestanden (behalve video's)."; + /* No comment provided by engineer. */ "App icon" = "App icon"; @@ -522,19 +531,22 @@ "bold" = "vetgedrukt"; /* No comment provided by engineer. */ -"Both you and your contact can add message reactions." = "Zowel u als uw contactpersoon kunnen berichtreacties toevoegen."; +"Both you and your contact can add message reactions." = "Zowel u als uw contact kunnen berichtreacties toevoegen."; /* No comment provided by engineer. */ -"Both you and your contact can irreversibly delete sent messages." = "Zowel jij als je contactpersoon kunnen verzonden berichten onherroepelijk verwijderen."; +"Both you and your contact can irreversibly delete sent messages." = "Zowel jij als je contact kunnen verzonden berichten onherroepelijk verwijderen."; /* No comment provided by engineer. */ -"Both you and your contact can make calls." = "Zowel u als uw contact persoon kunnen bellen."; +"Both you and your contact can make calls." = "Zowel u als uw contact kunnen bellen."; /* No comment provided by engineer. */ -"Both you and your contact can send disappearing messages." = "Zowel jij als je contactpersoon kunnen verdwijnende berichten sturen."; +"Both you and your contact can send disappearing messages." = "Zowel jij als je contact kunnen verdwijnende berichten sturen."; /* No comment provided by engineer. */ -"Both you and your contact can send voice messages." = "Zowel jij als je contactpersoon kunnen spraak berichten verzenden."; +"Both you and your contact can send voice messages." = "Zowel jij als je contact kunnen spraak berichten verzenden."; + +/* No comment provided by engineer. */ +"Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Bulgaars, Fins, Thais en Oekraïens - dankzij de gebruikers en [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"; /* 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)." = "Via chat profiel (standaard) of [via verbinding](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)."; @@ -843,6 +855,9 @@ /* No comment provided by engineer. */ "Create link" = "Maak link"; +/* No comment provided by engineer. */ +"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Maak een nieuw profiel aan in [desktop-app](https://simplex.chat/downloads/). 💻"; + /* No comment provided by engineer. */ "Create one-time invitation link" = "Maak een eenmalige uitnodiging link"; @@ -1149,6 +1164,9 @@ /* server test step */ "Disconnect" = "verbinding verbreken"; +/* No comment provided by engineer. */ +"Discover and join groups" = "Ontdek en sluit je aan bij groepen"; + /* No comment provided by engineer. */ "Display name" = "Weergavenaam"; @@ -1245,6 +1263,12 @@ /* No comment provided by engineer. */ "Encrypt database?" = "Database versleutelen?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "Versleutel lokale bestanden"; + +/* No comment provided by engineer. */ +"Encrypt stored files & media" = "Versleutel opgeslagen bestanden en media"; + /* No comment provided by engineer. */ "Encrypted database" = "Versleutelde database"; @@ -1356,6 +1380,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "Fout bij aanmaken van profiel!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "Fout bij het ontsleutelen van bestand"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Fout bij het verwijderen van de chat database"; @@ -1504,10 +1531,10 @@ "File will be deleted from servers." = "Het bestand wordt van de servers verwijderd."; /* No comment provided by engineer. */ -"File will be received when your contact completes uploading it." = "Het bestand wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid."; +"File will be received when your contact completes uploading it." = "Het bestand wordt gedownload wanneer uw contact het uploaden heeft voltooid."; /* No comment provided by engineer. */ -"File will be received when your contact is online, please wait or check later!" = "Het bestand wordt ontvangen wanneer uw contact persoon online is, even geduld a.u.b. of controleer later!"; +"File will be received when your contact is online, please wait or check later!" = "Het bestand wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of controleer later!"; /* No comment provided by engineer. */ "File: %@" = "Bestand: %@"; @@ -1702,7 +1729,7 @@ "If you can't meet in person, show QR code in a video call, or share the link." = "Als je elkaar niet persoonlijk kunt ontmoeten, laat dan de QR-code zien in een videogesprek of deel de link."; /* No comment provided by engineer. */ -"If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link." = "Als u elkaar niet persoonlijk kunt ontmoeten, kunt u **de QR-code scannen in het video gesprek**, of uw contactpersoon kan een uitnodiging link delen."; +"If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link." = "Als u elkaar niet persoonlijk kunt ontmoeten, kunt u **de QR-code scannen in het video gesprek**, of uw contact kan een uitnodiging link delen."; /* No comment provided by engineer. */ "If you enter this passcode when opening the app, all app data will be irreversibly removed!" = "Als u deze toegangscode invoert bij het openen van de app, worden alle app-gegevens onomkeerbaar verwijderd!"; @@ -1717,7 +1744,7 @@ "Ignore" = "Negeren"; /* No comment provided by engineer. */ -"Image will be received when your contact completes uploading it." = "De afbeelding wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid."; +"Image will be received when your contact completes uploading it." = "De afbeelding wordt gedownload wanneer uw contact het uploaden heeft voltooid."; /* No comment provided by engineer. */ "Image will be received when your contact is online, please wait or check later!" = "De afbeelding wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of kijk later!"; @@ -1756,7 +1783,7 @@ "Incognito mode protects your privacy by using a new random profile for each contact." = "Incognito -modus beschermt uw privacy met behulp van een nieuw willekeurig profiel voor elk contact."; /* chat list item description */ -"incognito via contact address link" = "incognito via contact adres link"; +"incognito via contact address link" = "incognito via contactadres link"; /* chat list item description */ "incognito via group link" = "incognito via groep link"; @@ -1870,7 +1897,7 @@ "It can happen when you or your connection used the old database backup." = "Het kan gebeuren wanneer u of de ander een oude databaseback-up gebruikt."; /* 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." = "Het kan gebeuren wanneer:\n1. De berichten zijn na 2 dagen verlopen bij de verzendende client of na 30 dagen op de server.\n2. Decodering van het bericht is mislukt, omdat u of uw contactpersoon een oude databaseback-up heeft gebruikt.\n3. De verbinding is verbroken."; +"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." = "Het kan gebeuren wanneer:\n1. De berichten zijn na 2 dagen verlopen bij de verzendende client of na 30 dagen op de server.\n2. Decodering van het bericht is mislukt, omdat u of uw contact een oude databaseback-up heeft gebruikt.\n3. De verbinding is verbroken."; /* 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 (%@)." = "Het lijkt erop dat u al bent verbonden via deze link. Als dit niet het geval is, is er een fout opgetreden (%@)."; @@ -2121,6 +2148,9 @@ /* No comment provided by engineer. */ "New database archive" = "Nieuw database archief"; +/* No comment provided by engineer. */ +"New desktop app!" = "Nieuwe desktop app!"; + /* No comment provided by engineer. */ "New display name" = "Nieuwe weergavenaam"; @@ -2252,7 +2282,7 @@ "Only you can add message reactions." = "Alleen jij kunt berichtreacties toevoegen."; /* No comment provided by engineer. */ -"Only you can irreversibly delete messages (your contact can mark them for deletion)." = "Alleen jij kunt berichten onomkeerbaar verwijderen (je contactpersoon kan ze markeren voor verwijdering)."; +"Only you can irreversibly delete messages (your contact can mark them for deletion)." = "Alleen jij kunt berichten onomkeerbaar verwijderen (je contact kan ze markeren voor verwijdering)."; /* No comment provided by engineer. */ "Only you can make calls." = "Alleen jij kunt bellen."; @@ -2264,19 +2294,19 @@ "Only you can send voice messages." = "Alleen jij kunt spraak berichten verzenden."; /* No comment provided by engineer. */ -"Only your contact can add message reactions." = "Alleen uw contactpersoon kan berichtreacties toevoegen."; +"Only your contact can add message reactions." = "Alleen uw contact kan berichtreacties toevoegen."; /* No comment provided by engineer. */ -"Only your contact can irreversibly delete messages (you can mark them for deletion)." = "Alleen uw contactpersoon kan berichten onherroepelijk verwijderen (u kunt ze markeren voor verwijdering)."; +"Only your contact can irreversibly delete messages (you can mark them for deletion)." = "Alleen uw contact kan berichten onherroepelijk verwijderen (u kunt ze markeren voor verwijdering)."; /* No comment provided by engineer. */ "Only your contact can make calls." = "Alleen je contact kan bellen."; /* No comment provided by engineer. */ -"Only your contact can send disappearing messages." = "Alleen uw contactpersoon kan verdwijnende berichten verzenden."; +"Only your contact can send disappearing messages." = "Alleen uw contact kan verdwijnende berichten verzenden."; /* No comment provided by engineer. */ -"Only your contact can send voice messages." = "Alleen uw contactpersoon kan spraak berichten verzenden."; +"Only your contact can send voice messages." = "Alleen uw contact kan spraak berichten verzenden."; /* No comment provided by engineer. */ "Open chat" = "Gesprekken openen"; @@ -2333,7 +2363,7 @@ "Paste received link" = "Plak de ontvangen link"; /* placeholder */ -"Paste the link you received to connect with your contact." = "Plak de link die je hebt ontvangen in het vak hieronder om verbinding te maken met je contactpersoon."; +"Paste the link you received to connect with your contact." = "Plak de link die je hebt ontvangen in het vak hieronder om verbinding te maken met je contact."; /* No comment provided by engineer. */ "peer-to-peer" = "peer-to-peer"; @@ -2354,10 +2384,10 @@ "PING interval" = "PING interval"; /* No comment provided by engineer. */ -"Please ask your contact to enable sending voice messages." = "Vraag uw contactpersoon om het verzenden van spraak berichten in te schakelen."; +"Please ask your contact to enable sending voice messages." = "Vraag uw contact om het verzenden van spraak berichten in te schakelen."; /* No comment provided by engineer. */ -"Please check that you used the correct link or ask your contact to send you another one." = "Controleer of u de juiste link heeft gebruikt of vraag uw contactpersoon om u een andere te sturen."; +"Please check that you used the correct link or ask your contact to send you another one." = "Controleer of u de juiste link heeft gebruikt of vraag uw contact om u een andere te sturen."; /* No comment provided by engineer. */ "Please check your network connection with %@ and try again." = "Controleer uw netwerkverbinding met %@ en probeer het opnieuw."; @@ -2699,7 +2729,7 @@ "Scan QR code" = "Scan QR-code"; /* No comment provided by engineer. */ -"Scan security code from your contact's app." = "Scan de beveiligingscode van de app van uw contactpersoon."; +"Scan security code from your contact's app." = "Scan de beveiligingscode van de app van uw contact."; /* No comment provided by engineer. */ "Scan server QR code" = "Scan server QR-code"; @@ -2935,6 +2965,9 @@ /* simplex link type */ "SimpleX one-time invitation" = "Eenmalige SimpleX uitnodiging"; +/* No comment provided by engineer. */ +"Simplified incognito mode" = "Vereenvoudigde incognitomodus"; + /* No comment provided by engineer. */ "Skip" = "Overslaan"; @@ -3155,7 +3188,7 @@ "To ask any questions and to receive updates:" = "Om vragen te stellen en updates te ontvangen:"; /* No comment provided by engineer. */ -"To connect, your contact can scan QR code or use the link in the app." = "Om verbinding te maken, kan uw contact persoon de QR-code scannen of de link in de app gebruiken."; +"To connect, your contact can scan QR code or use the link in the app." = "Om verbinding te maken, kan uw contact de QR-code scannen of de link in de app gebruiken."; /* No comment provided by engineer. */ "To make a new connection" = "Om een nieuwe verbinding te maken"; @@ -3179,7 +3212,10 @@ "To support instant push notifications the chat database has to be migrated." = "Om directe push meldingen te ondersteunen, moet de chat database worden gemigreerd."; /* No comment provided by engineer. */ -"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Vergelijk (of scan) de code op uw apparaten om end-to-end-codering met uw contactpersoon te verifiëren."; +"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Vergelijk (of scan) de code op uw apparaten om end-to-end-codering met uw contact te verifiëren."; + +/* No comment provided by engineer. */ +"Toggle incognito when connecting." = "Schakel incognito in tijdens het verbinden."; /* No comment provided by engineer. */ "Transport isolation" = "Transport isolation"; @@ -3239,7 +3275,7 @@ "Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." = "Schakel de modus Niet storen in om onderbrekingen te voorkomen, tenzij u de iOS-oproepinterface gebruikt."; /* No comment provided by engineer. */ -"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Tenzij uw contactpersoon de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft.\nOm verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft."; +"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Tenzij uw contact de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft.\nOm verbinding te maken, vraagt u uw contact om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft."; /* No comment provided by engineer. */ "Unlock" = "Ontgrendelen"; @@ -3329,7 +3365,7 @@ "Via browser" = "Via browser"; /* chat list item description */ -"via contact address link" = "via contact adres link"; +"via contact address link" = "via contactadres link"; /* chat list item description */ "via group link" = "via groep link"; @@ -3347,7 +3383,7 @@ "video call (not e2e encrypted)" = "video gesprek (niet e2e versleuteld)"; /* No comment provided by engineer. */ -"Video will be received when your contact completes uploading it." = "De video wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid."; +"Video will be received when your contact completes uploading it." = "De video wordt gedownload wanneer uw contact het uploaden heeft voltooid."; /* No comment provided by engineer. */ "Video will be received when your contact is online, please wait or check later!" = "De video wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of kijk later!"; @@ -3530,7 +3566,7 @@ "You have to enter passphrase every time the app starts - it is not stored on the device." = "U moet elke keer dat de app start het wachtwoord invoeren, deze wordt niet op het apparaat opgeslagen."; /* No comment provided by engineer. */ -"You invited a contact" = "Je hebt je contactpersoon uitgenodigd"; +"You invited a contact" = "Je hebt je contact uitgenodigd"; /* No comment provided by engineer. */ "You joined this group" = "Je bent lid geworden van deze groep"; @@ -3614,10 +3650,10 @@ "Your chat profiles" = "Uw chat profielen"; /* No comment provided by engineer. */ -"Your contact needs to be online for the connection to complete.\nYou can cancel this connection and remove the contact (and try later with a new link)." = "Uw contactpersoon moet online zijn om de verbinding te voltooien.\nU kunt deze verbinding verbreken en het contact verwijderen (en later proberen met een nieuwe link)."; +"Your contact needs to be online for the connection to complete.\nYou can cancel this connection and remove the contact (and try later with a new link)." = "Uw contact moet online zijn om de verbinding te voltooien.\nU kunt deze verbinding verbreken en het contact verwijderen en later proberen met een nieuwe link."; /* No comment provided by engineer. */ -"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Uw contactpersoon heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%@)."; +"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Uw contact heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%@)."; /* No comment provided by engineer. */ "Your contacts can allow full message deletion." = "Uw contacten kunnen volledige verwijdering van berichten toestaan."; diff --git a/apps/ios/pl.lproj/Localizable.strings b/apps/ios/pl.lproj/Localizable.strings index fc20b1c7f2..d80ff67d1f 100644 --- a/apps/ios/pl.lproj/Localizable.strings +++ b/apps/ios/pl.lproj/Localizable.strings @@ -19,6 +19,9 @@ /* No comment provided by engineer. */ "_italic_" = "\\_kursywa_"; +/* No comment provided by engineer. */ +"- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable." = "- połącz do [serwera katalogowego](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- potwierdzenie dostarczenia (do 20 członków).\n- szybszy i bardziej stabilny."; + /* No comment provided by engineer. */ "- more stable message delivery.\n- a bit better groups.\n- and more!" = "- bardziej stabilne dostarczanie wiadomości.\n- nieco lepsze grupy.\n- i więcej!"; @@ -181,6 +184,9 @@ /* No comment provided by engineer. */ "%lld minutes" = "%lld minut"; +/* No comment provided by engineer. */ +"%lld new interface languages" = "%lld nowe języki interfejsu"; + /* No comment provided by engineer. */ "%lld second(s)" = "%lld sekund(y)"; @@ -443,6 +449,9 @@ /* No comment provided by engineer. */ "App build: %@" = "Kompilacja aplikacji: %@"; +/* No comment provided by engineer. */ +"App encrypts new local files (except videos)." = "Aplikacja szyfruje nowe lokalne pliki (bez filmów)."; + /* No comment provided by engineer. */ "App icon" = "Ikona aplikacji"; @@ -536,6 +545,9 @@ /* No comment provided by engineer. */ "Both you and your contact can send voice messages." = "Zarówno Ty, jak i Twój kontakt możecie wysyłać wiadomości głosowe."; +/* No comment provided by engineer. */ +"Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Bułgarski, fiński, tajski i ukraiński – dzięki użytkownikom i [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"; + /* 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)." = "Według profilu czatu (domyślnie) lub [według połączenia](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)."; @@ -843,6 +855,9 @@ /* No comment provided by engineer. */ "Create link" = "Utwórz link"; +/* No comment provided by engineer. */ +"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Utwórz nowy profil w [aplikacji desktopowej](https://simplex.chat/downloads/). 💻"; + /* No comment provided by engineer. */ "Create one-time invitation link" = "Utwórz jednorazowy link do zaproszenia"; @@ -1149,6 +1164,9 @@ /* server test step */ "Disconnect" = "Rozłącz"; +/* No comment provided by engineer. */ +"Discover and join groups" = "Odkrywaj i dołączaj do grup"; + /* No comment provided by engineer. */ "Display name" = "Wyświetlana nazwa"; @@ -1245,6 +1263,12 @@ /* No comment provided by engineer. */ "Encrypt database?" = "Zaszyfrować bazę danych?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "Zaszyfruj lokalne pliki"; + +/* No comment provided by engineer. */ +"Encrypt stored files & media" = "Szyfruj przechowywane pliki i media"; + /* No comment provided by engineer. */ "Encrypted database" = "Zaszyfrowana baza danych"; @@ -1356,6 +1380,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "Błąd tworzenia profilu!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "Błąd odszyfrowania pliku"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Błąd usuwania bazy danych czatu"; @@ -2121,6 +2148,9 @@ /* No comment provided by engineer. */ "New database archive" = "Nowe archiwum bazy danych"; +/* No comment provided by engineer. */ +"New desktop app!" = "Nowa aplikacja desktopowa!"; + /* No comment provided by engineer. */ "New display name" = "Nowa wyświetlana nazwa"; @@ -2935,6 +2965,9 @@ /* simplex link type */ "SimpleX one-time invitation" = "Zaproszenie jednorazowe SimpleX"; +/* No comment provided by engineer. */ +"Simplified incognito mode" = "Uproszczony tryb incognito"; + /* No comment provided by engineer. */ "Skip" = "Pomiń"; @@ -3181,6 +3214,9 @@ /* No comment provided by engineer. */ "To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Aby zweryfikować szyfrowanie end-to-end z Twoim kontaktem porównaj (lub zeskanuj) kod na waszych urządzeniach."; +/* No comment provided by engineer. */ +"Toggle incognito when connecting." = "Przełącz incognito przy połączeniu."; + /* No comment provided by engineer. */ "Transport isolation" = "Izolacja transportu"; diff --git a/apps/ios/ru.lproj/Localizable.strings b/apps/ios/ru.lproj/Localizable.strings index b3b5e83fe1..7857870472 100644 --- a/apps/ios/ru.lproj/Localizable.strings +++ b/apps/ios/ru.lproj/Localizable.strings @@ -19,6 +19,9 @@ /* No comment provided by engineer. */ "_italic_" = "\\_курсив_"; +/* No comment provided by engineer. */ +"- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable." = "- соединиться с [каталогом групп](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- отчеты о доставке (до 20 членов).\n- быстрее и стабильнее."; + /* No comment provided by engineer. */ "- more stable message delivery.\n- a bit better groups.\n- and more!" = "- более стабильная доставка сообщений.\n- немного улучшенные группы.\n- и прочее!"; @@ -181,6 +184,9 @@ /* No comment provided by engineer. */ "%lld minutes" = "%lld минуты"; +/* No comment provided by engineer. */ +"%lld new interface languages" = "%lld новых языков интерфейса"; + /* No comment provided by engineer. */ "%lld second(s)" = "%lld секунд"; @@ -443,6 +449,9 @@ /* No comment provided by engineer. */ "App build: %@" = "Сборка приложения: %@"; +/* No comment provided by engineer. */ +"App encrypts new local files (except videos)." = "Приложение шифрует новые локальные файлы (кроме видео)."; + /* No comment provided by engineer. */ "App icon" = "Иконка"; @@ -536,6 +545,9 @@ /* No comment provided by engineer. */ "Both you and your contact can send voice messages." = "Вы и Ваш контакт можете отправлять голосовые сообщения."; +/* No comment provided by engineer. */ +"Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Болгарский, финский, тайский и украинский - благодаря пользователям и [Weblate] (https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"; + /* 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)." = "По профилю чата или [по соединению](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (БЕТА)."; @@ -843,6 +855,9 @@ /* No comment provided by engineer. */ "Create link" = "Создать ссылку"; +/* No comment provided by engineer. */ +"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Создайте новый профиль в [приложении для компьютера](https://simplex.chat/downloads/). 💻"; + /* No comment provided by engineer. */ "Create one-time invitation link" = "Создать ссылку-приглашение"; @@ -1149,6 +1164,9 @@ /* server test step */ "Disconnect" = "Разрыв соединения"; +/* No comment provided by engineer. */ +"Discover and join groups" = "Найдите и вступите в группы"; + /* No comment provided by engineer. */ "Display name" = "Имя профиля"; @@ -1245,6 +1263,12 @@ /* No comment provided by engineer. */ "Encrypt database?" = "Зашифровать базу данных?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "Шифровать локальные файлы"; + +/* No comment provided by engineer. */ +"Encrypt stored files & media" = "Шифруйте сохраненные файлы и медиа"; + /* No comment provided by engineer. */ "Encrypted database" = "База данных зашифрована"; @@ -1356,6 +1380,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "Ошибка создания профиля!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "Ошибка расшифровки файла"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Ошибка при удалении данных чата"; @@ -2121,6 +2148,9 @@ /* No comment provided by engineer. */ "New database archive" = "Новый архив чата"; +/* No comment provided by engineer. */ +"New desktop app!" = "Приложение для компьютера!"; + /* No comment provided by engineer. */ "New display name" = "Новое имя"; @@ -2935,6 +2965,9 @@ /* simplex link type */ "SimpleX one-time invitation" = "SimpleX одноразовая ссылка"; +/* No comment provided by engineer. */ +"Simplified incognito mode" = "Упрощенный режим Инкогнито"; + /* No comment provided by engineer. */ "Skip" = "Пропустить"; @@ -3181,6 +3214,9 @@ /* No comment provided by engineer. */ "To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Чтобы подтвердить end-to-end шифрование с Вашим контактом сравните (или сканируйте) код безопасности на Ваших устройствах."; +/* No comment provided by engineer. */ +"Toggle incognito when connecting." = "Установите режим Инкогнито при соединении."; + /* No comment provided by engineer. */ "Transport isolation" = "Отдельные сессии для"; diff --git a/apps/ios/zh-Hans.lproj/Localizable.strings b/apps/ios/zh-Hans.lproj/Localizable.strings index a7f42837e3..25eadf44d4 100644 --- a/apps/ios/zh-Hans.lproj/Localizable.strings +++ b/apps/ios/zh-Hans.lproj/Localizable.strings @@ -119,7 +119,7 @@ "%@ and %@ connected" = "%@ 和%@ 以建立连接"; /* copied message info, <sender> at <time> */ -"%@ at %@:" = "%2$@:"; +"%@ at %@:" = "@ %2$@:"; /* notification title */ "%@ is connected!" = "%@ 已连接!"; @@ -181,6 +181,9 @@ /* No comment provided by engineer. */ "%lld minutes" = "%lld 分钟"; +/* No comment provided by engineer. */ +"%lld new interface languages" = "%lld 种新的界面语言"; + /* No comment provided by engineer. */ "%lld second(s)" = "%lld 秒"; @@ -254,13 +257,13 @@ "30 seconds" = "30秒"; /* No comment provided by engineer. */ -"A few more things" = ""; +"A few more things" = "一些杂项"; /* notification title */ "A new contact" = "新联系人"; /* No comment provided by engineer. */ -"A new random profile will be shared." = "创建一个随机的共享文件"; +"A new random profile will be shared." = "创建一个随机的共享文件。"; /* No comment provided by engineer. */ "A separate TCP connection will be used **for each chat profile you have in the app**." = "一个单独的 TCP 连接将被用于**您在应用程序中的每个聊天资料**。"; @@ -297,7 +300,7 @@ "Accept" = "接受"; /* No comment provided by engineer. */ -"Accept connection request?" = "接受联系人"; +"Accept connection request?" = "接受联系人?"; /* notification body */ "Accept contact request from %@?" = "接受来自 %@ 的联系人请求?"; @@ -344,6 +347,12 @@ /* No comment provided by engineer. */ "Advanced network settings" = "高级网络设置"; +/* chat item text */ +"agreeing encryption for %@…" = "正在协商将加密应用于 %@…"; + +/* chat item text */ +"agreeing encryption…" = "同意加密…"; + /* No comment provided by engineer. */ "All app data is deleted." = "已删除所有应用程序数据。"; @@ -609,6 +618,12 @@ /* rcv group event chat item */ "changed your role to %@" = "更改您的角色为 %@"; +/* chat item text */ +"changing address for %@…" = "正在将变更的地址应用于 %@…"; + +/* chat item text */ +"changing address…" = "更改地址…"; + /* No comment provided by engineer. */ "Chat archive" = "聊天档案"; @@ -696,11 +711,17 @@ /* server test step */ "Connect" = "连接"; +/* No comment provided by engineer. */ +"Connect directly" = "直接连接"; + +/* No comment provided by engineer. */ +"Connect incognito" = "在隐身状态下连接"; + /* No comment provided by engineer. */ "connect to SimpleX Chat developers." = "连接到 SimpleX Chat 开发者。"; /* No comment provided by engineer. */ -"Connect via contact link" = "通过联系人链接进行连接?"; +"Connect via contact link" = "通过联系人链接进行连接"; /* No comment provided by engineer. */ "Connect via group link?" = "通过群组链接连接?"; @@ -712,7 +733,7 @@ "Connect via link / QR code" = "通过群组链接/二维码连接"; /* No comment provided by engineer. */ -"Connect via one-time link" = "通过一次性链接连接?"; +"Connect via one-time link" = "通过一次性链接连接"; /* No comment provided by engineer. */ "connected" = "已连接"; @@ -795,6 +816,9 @@ /* No comment provided by engineer. */ "Contact preferences" = "联系人偏好设置"; +/* No comment provided by engineer. */ +"Contacts" = "联系人"; + /* No comment provided by engineer. */ "Contacts can mark messages for deletion; you will be able to view them." = "联系人可以将信息标记为删除;您将可以查看这些信息。"; @@ -930,6 +954,12 @@ /* pref value */ "default (%@)" = "默认 (%@)"; +/* No comment provided by engineer. */ +"default (no)" = "默认(否)"; + +/* No comment provided by engineer. */ +"default (yes)" = "默认 (是)"; + /* chat item action */ "Delete" = "删除"; @@ -1047,6 +1077,15 @@ /* rcv group event chat item */ "deleted group" = "已删除群组"; +/* No comment provided by engineer. */ +"Delivery" = "传送"; + +/* No comment provided by engineer. */ +"Delivery receipts are disabled!" = "送达回执已禁用!"; + +/* No comment provided by engineer. */ +"Delivery receipts!" = "送达回执!"; + /* No comment provided by engineer. */ "Description" = "描述"; @@ -1080,9 +1119,18 @@ /* No comment provided by engineer. */ "Direct messages between members are prohibited in this group." = "此群中禁止成员之间私信。"; +/* No comment provided by engineer. */ +"Disable (keep overrides)" = "禁用(保留覆盖)"; + +/* No comment provided by engineer. */ +"Disable for all" = "全部禁用"; + /* authentication reason */ "Disable SimpleX Lock" = "禁用 SimpleX 锁定"; +/* No comment provided by engineer. */ +"disabled" = "关闭"; + /* No comment provided by engineer. */ "Disappearing message" = "限时消息"; @@ -1119,6 +1167,9 @@ /* No comment provided by engineer. */ "Don't create address" = "不创建地址"; +/* No comment provided by engineer. */ +"Don't enable" = "不要启用"; + /* No comment provided by engineer. */ "Don't show again" = "不再显示"; @@ -1149,9 +1200,15 @@ /* No comment provided by engineer. */ "Enable" = "启用"; +/* No comment provided by engineer. */ +"Enable (keep overrides)" = "启用(保持覆盖)"; + /* No comment provided by engineer. */ "Enable automatic message deletion?" = "启用自动删除消息?"; +/* No comment provided by engineer. */ +"Enable for all" = "全部启用"; + /* No comment provided by engineer. */ "Enable instant notifications?" = "启用即时通知?"; @@ -1191,6 +1248,9 @@ /* No comment provided by engineer. */ "Encrypt database?" = "加密数据库?"; +/* No comment provided by engineer. */ +"Encrypt local files" = "加密本地文件"; + /* No comment provided by engineer. */ "Encrypted database" = "加密数据库"; @@ -1212,6 +1272,30 @@ /* notification */ "Encrypted message: unexpected error" = "加密消息:意外错误"; +/* chat item text */ +"encryption agreed" = "已同意加密"; + +/* chat item text */ +"encryption agreed for %@" = "同意对 %@ 进行加密"; + +/* chat item text */ +"encryption ok" = "可以加密"; + +/* chat item text */ +"encryption ok for %@" = "对 %@ 进行加密"; + +/* chat item text */ +"encryption re-negotiation allowed" = "允许重新进行加密协商"; + +/* chat item text */ +"encryption re-negotiation allowed for %@" = "允许对 %@ 进行加密重新协商"; + +/* chat item text */ +"encryption re-negotiation required" = "需要重新进行加密协商"; + +/* chat item text */ +"encryption re-negotiation required for %@" = "需要为 %@ 重新进行加密协商"; + /* No comment provided by engineer. */ "ended" = "已结束"; @@ -1278,6 +1362,9 @@ /* No comment provided by engineer. */ "Error creating profile!" = "创建资料错误!"; +/* No comment provided by engineer. */ +"Error decrypting file" = "解密文件时出错"; + /* No comment provided by engineer. */ "Error deleting chat database" = "删除聊天数据库错误"; @@ -1302,6 +1389,9 @@ /* No comment provided by engineer. */ "Error deleting user profile" = "删除用户资料错误"; +/* No comment provided by engineer. */ +"Error enabling delivery receipts!" = "启用送达回执出错!"; + /* No comment provided by engineer. */ "Error enabling notifications" = "启用通知错误"; @@ -1350,6 +1440,9 @@ /* No comment provided by engineer. */ "Error sending message" = "发送消息错误"; +/* No comment provided by engineer. */ +"Error setting delivery receipts!" = "设置送达回执出错!"; + /* No comment provided by engineer. */ "Error starting chat" = "启动聊天错误"; @@ -1359,6 +1452,9 @@ /* No comment provided by engineer. */ "Error switching profile!" = "切换资料错误!"; +/* No comment provided by engineer. */ +"Error synchronizing connection" = "同步连接错误"; + /* No comment provided by engineer. */ "Error updating group link" = "更新群组链接错误"; @@ -1383,6 +1479,12 @@ /* No comment provided by engineer. */ "Error: URL is invalid" = "错误:URL 无效"; +/* No comment provided by engineer. */ +"Even when disabled in the conversation." = "即使在对话中被禁用。"; + +/* No comment provided by engineer. */ +"event happened" = "发生的事"; + /* No comment provided by engineer. */ "Exit without saving" = "退出而不保存"; @@ -1431,9 +1533,33 @@ /* No comment provided by engineer. */ "Files and media prohibited!" = "禁止文件和媒体!"; +/* No comment provided by engineer. */ +"Filter unread and favorite chats." = "过滤未读和收藏的聊天记录。"; + /* No comment provided by engineer. */ "Finally, we have them! 🚀" = "终于我们有它们了! 🚀"; +/* No comment provided by engineer. */ +"Find chats faster" = "更快地查找聊天记录"; + +/* No comment provided by engineer. */ +"Fix" = "修复"; + +/* No comment provided by engineer. */ +"Fix connection" = "修复连接"; + +/* No comment provided by engineer. */ +"Fix connection?" = "修复连接?"; + +/* No comment provided by engineer. */ +"Fix encryption after restoring backups." = "修复还原备份后的加密问题。"; + +/* No comment provided by engineer. */ +"Fix not supported by contact" = "修复联系人不支持的问题"; + +/* No comment provided by engineer. */ +"Fix not supported by group member" = "修复群组成员不支持的问题"; + /* No comment provided by engineer. */ "For console" = "用于控制台"; @@ -1626,12 +1752,18 @@ /* No comment provided by engineer. */ "Improved server configuration" = "改进的服务器配置"; +/* No comment provided by engineer. */ +"In reply to" = "答复"; + /* No comment provided by engineer. */ "Incognito" = "隐身聊天"; /* No comment provided by engineer. */ "Incognito mode" = "隐身模式"; +/* No comment provided by engineer. */ +"Incognito mode protects your privacy by using a new random profile for each contact." = "隐身模式会为每个联系人使用一个新的随机配置文件,从而保护你的隐私。"; + /* chat list item description */ "incognito via contact address link" = "通过联系人地址链接隐身聊天"; @@ -1695,6 +1827,9 @@ /* No comment provided by engineer. */ "Invalid server address!" = "无效的服务器地址!"; +/* item status text */ +"Invalid status" = "无效状态"; + /* No comment provided by engineer. */ "Invitation expired!" = "邀请已过期!"; @@ -1773,6 +1908,9 @@ /* No comment provided by engineer. */ "Joining group" = "加入群组中"; +/* No comment provided by engineer. */ +"Keep your connections" = "保持连接"; + /* No comment provided by engineer. */ "Keychain error" = "钥匙串错误"; @@ -1830,6 +1968,9 @@ /* No comment provided by engineer. */ "Make a private connection" = "建立私密连接"; +/* No comment provided by engineer. */ +"Make one message disappear" = "使一条消息消失"; + /* No comment provided by engineer. */ "Make profile private!" = "将个人资料设为私密!"; @@ -1881,6 +2022,9 @@ /* item status text */ "Message delivery error" = "消息传递错误"; +/* No comment provided by engineer. */ +"Message delivery receipts!" = "消息送达回执!"; + /* No comment provided by engineer. */ "Message draft" = "消息草稿"; @@ -1947,6 +2091,9 @@ /* No comment provided by engineer. */ "More improvements are coming soon!" = "更多改进即将推出!"; +/* item status description */ +"Most likely this connection is deleted." = "此连接很可能已被删除。"; + /* No comment provided by engineer. */ "Most likely this contact has deleted the connection with you." = "很可能此联系人已经删除了与您的联系。"; @@ -2019,6 +2166,9 @@ /* No comment provided by engineer. */ "No contacts to add" = "没有联系人可添加"; +/* No comment provided by engineer. */ +"No delivery information" = "无送达信息"; + /* No comment provided by engineer. */ "No device token!" = "无设备令牌!"; @@ -2031,6 +2181,9 @@ /* No comment provided by engineer. */ "No group!" = "未找到群组!"; +/* No comment provided by engineer. */ +"No history" = "无历史记录"; + /* No comment provided by engineer. */ "No permission to record voice message" = "没有录制语音消息的权限"; @@ -2317,12 +2470,18 @@ /* No comment provided by engineer. */ "Protocol timeout" = "协议超时"; +/* No comment provided by engineer. */ +"Protocol timeout per KB" = "每 KB 协议超时"; + /* No comment provided by engineer. */ "Push notifications" = "推送通知"; /* No comment provided by engineer. */ "Rate the app" = "评价此应用程序"; +/* chat item menu */ +"React…" = "回应…"; + /* No comment provided by engineer. */ "Read" = "已读"; @@ -2341,6 +2500,9 @@ /* No comment provided by engineer. */ "Read more in our GitHub repository." = "在我们的 GitHub 仓库中阅读更多内容。"; +/* No comment provided by engineer. */ +"Receipts are disabled" = "回执已禁用"; + /* No comment provided by engineer. */ "received answer…" = "已收到回复……"; @@ -2371,6 +2533,12 @@ /* No comment provided by engineer. */ "Recipients see updates as you type them." = "对方会在您键入时看到更新。"; +/* No comment provided by engineer. */ +"Reconnect all connected servers to force message delivery. It uses additional traffic." = "重新连接所有已连接的服务器以强制发送信息。这会耗费更多流量。"; + +/* No comment provided by engineer. */ +"Reconnect servers?" = "是否重新连接服务器?"; + /* No comment provided by engineer. */ "Record updated at" = "记录更新于"; @@ -2419,6 +2587,15 @@ /* rcv group event chat item */ "removed you" = "已将您移除"; +/* No comment provided by engineer. */ +"Renegotiate" = "重新协商"; + +/* No comment provided by engineer. */ +"Renegotiate encryption" = "重新协商加密"; + +/* No comment provided by engineer. */ +"Renegotiate encryption?" = "重新协商加密?"; + /* chat item action */ "Reply" = "回复"; @@ -2557,6 +2734,9 @@ /* No comment provided by engineer. */ "Security code" = "安全码"; +/* chat item text */ +"security code changed" = "安全密码已更改"; + /* No comment provided by engineer. */ "Select" = "选择"; @@ -2578,6 +2758,9 @@ /* No comment provided by engineer. */ "Send a live message - it will update for the recipient(s) as you type it" = "发送实时消息——它会在您键入时为收件人更新"; +/* No comment provided by engineer. */ +"Send delivery receipts to" = "将送达回执发送给"; + /* No comment provided by engineer. */ "Send direct message" = "发送私信"; @@ -2599,6 +2782,9 @@ /* No comment provided by engineer. */ "Send questions and ideas" = "发送问题和想法"; +/* No comment provided by engineer. */ +"Send receipts" = "发送回执"; + /* No comment provided by engineer. */ "Send them from gallery or custom keyboards." = "发送它们来自图库或自定义键盘。"; @@ -2608,9 +2794,27 @@ /* No comment provided by engineer. */ "Sender may have deleted the connection request." = "发送人可能已删除连接请求。"; +/* No comment provided by engineer. */ +"Sending delivery receipts will be enabled for all contacts in all visible chat profiles." = "将对所有可见聊天配置文件中的所有联系人启用送达回执功能。"; + +/* No comment provided by engineer. */ +"Sending delivery receipts will be enabled for all contacts." = "将对所有联系人启用送达回执功能。"; + /* No comment provided by engineer. */ "Sending file will be stopped." = "即将停止发送文件。"; +/* No comment provided by engineer. */ +"Sending receipts is disabled for %lld contacts" = "已为 %lld 联系人禁用送达回执功能"; + +/* No comment provided by engineer. */ +"Sending receipts is disabled for %lld groups" = "已为 %lld 组禁用送达回执功能"; + +/* No comment provided by engineer. */ +"Sending receipts is enabled for %lld contacts" = "已为 %lld 联系人启用送达回执功能"; + +/* No comment provided by engineer. */ +"Sending receipts is enabled for %lld groups" = "已为 %lld 组启用送达回执功能"; + /* No comment provided by engineer. */ "Sending via" = "发送通过"; @@ -2695,6 +2899,9 @@ /* No comment provided by engineer. */ "Show developer options" = "显示开发者选项"; +/* No comment provided by engineer. */ +"Show last messages" = "显示最近的消息"; + /* No comment provided by engineer. */ "Show preview" = "显示预览"; @@ -2743,6 +2950,9 @@ /* No comment provided by engineer. */ "Skipped messages" = "已跳过消息"; +/* No comment provided by engineer. */ +"Small groups (max 20)" = "小群组(最多 20 人)"; + /* No comment provided by engineer. */ "SMP servers" = "SMP 服务器"; @@ -2878,6 +3088,9 @@ /* No comment provided by engineer. */ "The created archive is available via app Settings / Database / Old database archive." = "创建的归档文件可以通过应用设置/数据库/旧数据库归档访问。"; +/* No comment provided by engineer. */ +"The encryption is working and the new encryption agreement is not required. It may result in connection errors!" = "加密正在运行,不需要新的加密协议。这可能会导致连接错误!"; + /* No comment provided by engineer. */ "The group is fully decentralized – it is visible only to the members." = "该小组是完全分散式的——它只对成员可见。"; @@ -2902,6 +3115,9 @@ /* No comment provided by engineer. */ "The profile is only shared with your contacts." = "该资料仅与您的联系人共享。"; +/* No comment provided by engineer. */ +"The second tick we missed! ✅" = "我们错过的第二个\"√\"!✅"; + /* No comment provided by engineer. */ "The sender will NOT be notified" = "发送者将不会收到通知"; @@ -2917,6 +3133,12 @@ /* No comment provided by engineer. */ "There should be at least one visible user profile." = "应该至少有一个可见的用户资料。"; +/* No comment provided by engineer. */ +"These settings are for your current profile **%@**." = "这些设置适用于您当前的配置文件 **%@**。"; + +/* No comment provided by engineer. */ +"They can be overridden in contact and group settings." = "可以在联系人和群组设置中覆盖它们。"; + /* No comment provided by engineer. */ "This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "此操作无法撤消——所有接收和发送的文件和媒体都将被删除。 低分辨率图片将保留。"; @@ -2929,6 +3151,9 @@ /* notification title */ "this contact" = "这个联系人"; +/* No comment provided by engineer. */ +"This group has over %lld members, delivery receipts are not sent." = "该组有超过 %lld 个成员,不发送送货单。"; + /* No comment provided by engineer. */ "This group no longer exists." = "该群组已不存在。"; @@ -3073,12 +3298,18 @@ /* No comment provided by engineer. */ "Use chat" = "使用聊天"; +/* No comment provided by engineer. */ +"Use current profile" = "使用当前配置文件"; + /* No comment provided by engineer. */ "Use for new connections" = "用于新连接"; /* No comment provided by engineer. */ "Use iOS call interface" = "使用 iOS 通话界面"; +/* No comment provided by engineer. */ +"Use new incognito profile" = "使用新的隐身配置文件"; + /* No comment provided by engineer. */ "Use server" = "使用服务器"; @@ -3247,6 +3478,12 @@ /* No comment provided by engineer. */ "You can create it later" = "您可以以后创建它"; +/* No comment provided by engineer. */ +"You can enable later via Settings" = "您可以稍后在设置中启用它"; + +/* No comment provided by engineer. */ +"You can enable them later via app Privacy & Security settings." = "您可以稍后通过应用程序的 \"隐私与安全 \"设置启用它们。"; + /* No comment provided by engineer. */ "You can hide or mute a user profile - swipe it to the right." = "您可以隐藏或静音用户个人资料——只需向右滑动。"; @@ -3415,6 +3652,9 @@ /* No comment provided by engineer. */ "Your privacy" = "您的隐私设置"; +/* No comment provided by engineer. */ +"Your profile **%@** will be shared." = "您的个人资料 **%@** 将被共享。"; + /* No comment provided by engineer. */ "Your profile is stored on your device and shared only with your contacts.\nSimpleX servers cannot see your profile." = "您的资料存储在您的设备上并仅与您的联系人共享。\nSimpleX 服务器无法看到您的资料。"; diff --git a/apps/multiplatform/android/build.gradle.kts b/apps/multiplatform/android/build.gradle.kts index bd45ee125f..67a8fea87b 100644 --- a/apps/multiplatform/android/build.gradle.kts +++ b/apps/multiplatform/android/build.gradle.kts @@ -139,8 +139,6 @@ dependencies { //implementation("androidx.compose.material:material-icons-extended:$compose_version") //implementation("androidx.compose.ui:ui-util:$compose_version") - implementation("com.google.accompanist:accompanist-pager:0.25.1") - testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.3") androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt index 06def4ce10..512e9efc10 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt @@ -73,7 +73,7 @@ class MainActivity: FragmentActivity() { override fun onStop() { super.onStop() - VideoPlayer.stopAll() + VideoPlayerHolder.stopAll() AppLock.appWasHidden() } diff --git a/apps/multiplatform/common/build.gradle.kts b/apps/multiplatform/common/build.gradle.kts index 5b9560b07e..6a5fd1d0fe 100644 --- a/apps/multiplatform/common/build.gradle.kts +++ b/apps/multiplatform/common/build.gradle.kts @@ -97,6 +97,7 @@ kotlin { implementation("com.github.Dansoftowner:jSystemThemeDetector:3.6") implementation("com.sshtools:two-slices:0.9.0-SNAPSHOT") implementation("org.slf4j:slf4j-simple:2.0.7") + implementation("uk.co.caprica:vlcj:4.7.0") } } val desktopTest by getting diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt index ad07c6a33c..10faa1a82b 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt @@ -44,6 +44,7 @@ import java.net.URI @Composable actual fun PlatformTextField( composeState: MutableState<ComposeState>, + sendMsgEnabled: Boolean, textStyle: MutableState<TextStyle>, showDeleteTextButton: MutableState<Boolean>, userIsObserver: Boolean, @@ -60,6 +61,7 @@ actual fun PlatformTextField( val paddingEnd = with(LocalDensity.current) { 45.dp.roundToPx() } val paddingBottom = with(LocalDensity.current) { 7.dp.roundToPx() } var showKeyboard by remember { mutableStateOf(false) } + var freeFocus by remember { mutableStateOf(false) } LaunchedEffect(cs.contextItem) { if (cs.contextItem is ComposeContextItem.QuotedItem) { delay(100) @@ -70,6 +72,11 @@ actual fun PlatformTextField( showKeyboard = true } } + LaunchedEffect(sendMsgEnabled) { + if (!sendMsgEnabled) { + freeFocus = true + } + } AndroidView(modifier = Modifier, factory = { val editText = @SuppressLint("AppCompatCustomView") object: EditText(it) { @@ -142,6 +149,11 @@ actual fun PlatformTextField( imm.showSoftInput(it, InputMethodManager.SHOW_IMPLICIT) showKeyboard = false } + if (freeFocus) { + it.clearFocus() + hideKeyboard(it) + freeFocus = false + } showDeleteTextButton.value = it.lineCount >= 4 && !cs.inProgress } if (composeState.value.preview is ComposePreview.VoicePreview) { diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/RecAndPlay.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/RecAndPlay.android.kt index 5996193abb..8df99d15f3 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/RecAndPlay.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/RecAndPlay.android.kt @@ -27,7 +27,7 @@ actual class RecorderNative: RecorderInterface { } override fun start(onProgressUpdate: (position: Int?, finished: Boolean) -> Unit): String { - VideoPlayer.stopAll() + VideoPlayerHolder.stopAll() AudioPlayer.stop() val rec: MediaRecorder recorder = initRecorder().also { rec = it } @@ -140,7 +140,7 @@ actual object AudioPlayer: AudioPlayerInterface { return null } - VideoPlayer.stopAll() + VideoPlayerHolder.stopAll() RecorderInterface.stopRecording?.invoke() val current = currentlyPlaying.value if (current == null || current.first != fileSource.filePath) { diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/VideoPlayer.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/VideoPlayer.android.kt index 984f83d455..9d5eadad72 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/VideoPlayer.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/VideoPlayer.android.kt @@ -1,10 +1,13 @@ package chat.simplex.common.platform +import android.media.MediaMetadataRetriever import android.media.session.PlaybackState import android.net.Uri import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.asImageBitmap +import chat.simplex.common.helpers.toUri import chat.simplex.common.views.helpers.* import chat.simplex.res.MR import com.google.android.exoplayer2.* @@ -17,49 +20,15 @@ import kotlinx.coroutines.* import java.io.File import java.net.URI -actual class VideoPlayer private constructor( - private val uri: URI, - private val gallery: Boolean, +actual class VideoPlayer actual constructor( + override val uri: URI, + override val gallery: Boolean, private val defaultPreview: ImageBitmap, defaultDuration: Long, soundEnabled: Boolean ): VideoPlayerInterface { - actual companion object { - private val players: MutableMap<Pair<URI, Boolean>, VideoPlayer> = mutableMapOf() - private val previewsAndDurations: MutableMap<URI, VideoPlayerInterface.PreviewAndDuration> = mutableMapOf() - - actual fun getOrCreate( - uri: URI, - gallery: Boolean, - defaultPreview: ImageBitmap, - defaultDuration: Long, - soundEnabled: Boolean - ): VideoPlayer = - players.getOrPut(uri to gallery) { VideoPlayer(uri, gallery, defaultPreview, defaultDuration, soundEnabled) } - - actual fun enableSound(enable: Boolean, fileName: String?, gallery: Boolean): Boolean = - player(fileName, gallery)?.enableSound(enable) == true - - private fun player(fileName: String?, gallery: Boolean): VideoPlayer? { - fileName ?: return null - return players.values.firstOrNull { player -> player.uri.path?.endsWith(fileName) == true && player.gallery == gallery } - } - - actual fun release(uri: URI, gallery: Boolean, remove: Boolean) = - player(uri.path, gallery)?.release(remove).run { } - - actual fun stopAll() { - players.values.forEach { it.stop() } - } - - actual fun releaseAll() { - players.values.forEach { it.release(false) } - players.clear() - previewsAndDurations.clear() - } - } - private val currentVolume: Float + override val soundEnabled: MutableState<Boolean> = mutableStateOf(soundEnabled) override val brokenVideo: MutableState<Boolean> = mutableStateOf(false) override val videoPlaying: MutableState<Boolean> = mutableStateOf(false) @@ -114,7 +83,7 @@ actual class VideoPlayer private constructor( RecorderInterface.stopRecording?.invoke() } AudioPlayer.stop() - stopAll() + VideoPlayerHolder.stopAll() if (listener.value == null) { runCatching { val dataSourceFactory = DefaultDataSource.Factory(androidAppContext, DefaultHttpDataSource.Factory()) @@ -224,14 +193,14 @@ actual class VideoPlayer private constructor( override fun release(remove: Boolean) { player.release() if (remove) { - players.remove(uri to gallery) + VideoPlayerHolder.players.remove(uri to gallery) } } private fun setPreviewAndDuration() { // It freezes main thread, doing it in IO thread CoroutineScope(Dispatchers.IO).launch { - val previewAndDuration = previewsAndDurations.getOrPut(uri) { getBitmapFromVideo(uri) } + val previewAndDuration = VideoPlayerHolder.previewsAndDurations.getOrPut(uri) { getBitmapFromVideo(uri) } withContext(Dispatchers.Main) { preview.value = previewAndDuration.preview ?: defaultPreview duration.value = (previewAndDuration.duration ?: 0) diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.android.kt index ade538a044..d4efdc3e59 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.android.kt @@ -51,7 +51,7 @@ actual fun FullScreenImageView(modifier: Modifier, data: ByteArray, imageBitmap: } @Composable -actual fun FullScreenVideoView(player: VideoPlayer, modifier: Modifier) { +actual fun FullScreenVideoView(player: VideoPlayer, modifier: Modifier, close: () -> Unit) { AndroidView( factory = { ctx -> StyledPlayerView(ctx).apply { diff --git a/apps/multiplatform/common/src/commonMain/cpp/desktop/CMakeLists.txt b/apps/multiplatform/common/src/commonMain/cpp/desktop/CMakeLists.txt index 7b486e43a6..d41ec9493e 100644 --- a/apps/multiplatform/common/src/commonMain/cpp/desktop/CMakeLists.txt +++ b/apps/multiplatform/common/src/commonMain/cpp/desktop/CMakeLists.txt @@ -72,7 +72,7 @@ if(NOT APPLE) else() # Without direct linking it can't find hs_init in linking step add_library( rts SHARED IMPORTED ) - FILE(GLOB RTSLIB ${CMAKE_SOURCE_DIR}/libs/${OS_LIB_PATH}-${OS_LIB_ARCH}/deps/libHSrts_thr-*.${OS_LIB_EXT}) + FILE(GLOB RTSLIB ${CMAKE_SOURCE_DIR}/libs/${OS_LIB_PATH}-${OS_LIB_ARCH}/deps/libHSrts*_thr-*.${OS_LIB_EXT}) set_target_properties( rts PROPERTIES IMPORTED_LOCATION ${RTSLIB}) target_link_libraries(app-lib rts simplex) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index cdabe71449..887abe756b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -7,13 +7,12 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.font.* import androidx.compose.ui.text.style.TextDecoration import chat.simplex.common.model.* +import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.call.* import chat.simplex.common.views.chat.ComposeState import chat.simplex.common.views.helpers.* import chat.simplex.common.views.onboarding.OnboardingStage -import chat.simplex.common.platform.AudioPlayer -import chat.simplex.common.platform.chatController import chat.simplex.res.MR import dev.icerock.moko.resources.ImageResource import dev.icerock.moko.resources.StringResource @@ -606,10 +605,13 @@ data class Chat ( val userCanSend: Boolean get() = when (chatInfo) { is ChatInfo.Direct -> true - is ChatInfo.Group -> { - val m = chatInfo.groupInfo.membership - m.memberActive && m.memberRole >= GroupMemberRole.Member - } + is ChatInfo.Group -> chatInfo.groupInfo.membership.memberRole >= GroupMemberRole.Member + else -> false + } + + val nextSendGrpInv: Boolean + get() = when (chatInfo) { + is ChatInfo.Direct -> chatInfo.contact.nextSendGrpInv else -> false } @@ -799,13 +801,18 @@ data class Contact( val userPreferences: ChatPreferences, val mergedPreferences: ContactUserPreferences, override val createdAt: Instant, - override val updatedAt: Instant + override val updatedAt: Instant, + val contactGroupMemberId: Long? = null, + val contactGrpInvSent: Boolean ): SomeChat, NamedChat { override val chatType get() = ChatType.Direct override val id get() = "@$contactId" override val apiId get() = contactId override val ready get() = activeConn.connStatus == ConnStatus.Ready - override val sendMsgEnabled get() = !(activeConn.connectionStats?.ratchetSyncSendProhibited ?: false) + override val sendMsgEnabled get() = + (ready && !(activeConn.connectionStats?.ratchetSyncSendProhibited ?: false)) + || nextSendGrpInv + val nextSendGrpInv get() = contactGroupMemberId != null && !contactGrpInvSent override val ntfsEnabled get() = chatSettings.enableNtfs override val incognito get() = contactConnIncognito override fun featureEnabled(feature: ChatFeature) = when (feature) { @@ -856,7 +863,8 @@ data class Contact( userPreferences = ChatPreferences.sampleData, mergedPreferences = ContactUserPreferences.sampleData, createdAt = Clock.System.now(), - updatedAt = Clock.System.now() + updatedAt = Clock.System.now(), + contactGrpInvSent = false ) } } @@ -881,6 +889,7 @@ class ContactSubStatus( data class Connection( val connId: Long, val agentConnId: String, + val peerChatVRange: VersionRange, val connStatus: ConnStatus, val connLevel: Int, val viaGroupLink: Boolean, @@ -890,10 +899,17 @@ data class Connection( ) { val id: ChatId get() = ":$connId" companion object { - val sampleData = Connection(connId = 1, agentConnId = "abc", connStatus = ConnStatus.Ready, connLevel = 0, viaGroupLink = false, customUserProfileId = null) + val sampleData = Connection(connId = 1, agentConnId = "abc", connStatus = ConnStatus.Ready, connLevel = 0, viaGroupLink = false, peerChatVRange = VersionRange(1, 1), customUserProfileId = null) } } +@Serializable +data class VersionRange(val minVersion: Int, val maxVersion: Int) { + + fun isCompatibleRange(vRange: VersionRange): Boolean = + this.minVersion <= vRange.maxVersion && vRange.minVersion <= this.maxVersion +} + @Serializable data class SecurityCode(val securityCode: String, val verifiedAt: Instant) @@ -1224,6 +1240,7 @@ class MemberSubError ( @Serializable class UserContactRequest ( val contactRequestId: Long, + val cReqChatVRange: VersionRange, override val localDisplayName: String, val profile: Profile, override val createdAt: Instant, @@ -1246,6 +1263,7 @@ class UserContactRequest ( companion object { val sampleData = UserContactRequest( contactRequestId = 1, + cReqChatVRange = VersionRange(1, 1), localDisplayName = "alice", profile = Profile.sampleData, createdAt = Clock.System.now(), @@ -1398,8 +1416,7 @@ data class ChatItem ( val encryptedFile: Boolean? = if (file?.fileSource == null) null else file.fileSource.cryptoArgs != null val encryptLocalFile: Boolean - get() = file?.fileProtocol == FileProtocol.XFTP && - content.msgContent !is MsgContent.MCVideo && + get() = content.msgContent !is MsgContent.MCVideo && chatController.appPrefs.privacyEncryptLocalFiles.get() val memberDisplayName: String? get() = @@ -1465,6 +1482,7 @@ data class ChatItem ( is RcvGroupEvent.GroupDeleted -> showNtfDir is RcvGroupEvent.GroupUpdated -> false is RcvGroupEvent.InvitedViaGroupLink -> false + is RcvGroupEvent.MemberCreatedContact -> false } is CIContent.SndGroupEventContent -> showNtfDir is CIContent.RcvConnEventContent -> false @@ -2093,6 +2111,23 @@ data class CryptoFile( val isAbsolutePath: Boolean get() = File(filePath).isAbsolute + @Transient + private var tmpFile: File? = null + + fun createTmpFileIfNeeded(): File { + if (tmpFile == null) { + val tmpFile = File(tmpDir, UUID.randomUUID().toString()) + tmpFile.deleteOnExit() + ChatModel.filesToDelete.add(tmpFile) + this.tmpFile = tmpFile + } + return tmpFile!! + } + + fun deleteTmpFile() { + tmpFile?.delete() + } + companion object { fun plain(f: String): CryptoFile = CryptoFile(f, null) } @@ -2464,6 +2499,7 @@ sealed class RcvGroupEvent() { @Serializable @SerialName("groupDeleted") class GroupDeleted(): RcvGroupEvent() @Serializable @SerialName("groupUpdated") class GroupUpdated(val groupProfile: GroupProfile): RcvGroupEvent() @Serializable @SerialName("invitedViaGroupLink") class InvitedViaGroupLink(): RcvGroupEvent() + @Serializable @SerialName("memberCreatedContact") class MemberCreatedContact(): RcvGroupEvent() val text: String get() = when (this) { is MemberAdded -> String.format(generalGetString(MR.strings.rcv_group_event_member_added), profile.profileViewName) @@ -2476,6 +2512,7 @@ sealed class RcvGroupEvent() { is GroupDeleted -> generalGetString(MR.strings.rcv_group_event_group_deleted) is GroupUpdated -> generalGetString(MR.strings.rcv_group_event_updated_group_profile) is InvitedViaGroupLink -> generalGetString(MR.strings.rcv_group_event_invited_via_your_group_link) + is MemberCreatedContact -> generalGetString(MR.strings.rcv_group_event_member_created_contact) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 3e2c79185f..060738bc18 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -26,6 +26,12 @@ import java.util.Date typealias ChatCtrl = Long +// currentChatVersion in core +const val CURRENT_CHAT_VERSION: Int = 2 + +// version range that supports establishing direct connection with a group member (xGrpDirectInvVRange in core) +val CREATE_MEMBER_CONTACT_VRANGE = VersionRange(minVersion = 2, maxVersion = CURRENT_CHAT_VERSION) + enum class CallOnLockScreen { DISABLE, SHOW, @@ -784,16 +790,18 @@ object ChatController { return null } - suspend fun apiGetContactCode(contactId: Long): Pair<Contact, String> { + suspend fun apiGetContactCode(contactId: Long): Pair<Contact, String>? { val r = sendCmd(CC.APIGetContactCode(contactId)) if (r is CR.ContactCode) return r.contact to r.connectionCode - throw Exception("failed to get contact code: ${r.responseType} ${r.details}") + Log.e(TAG,"failed to get contact code: ${r.responseType} ${r.details}") + return null } - suspend fun apiGetGroupMemberCode(groupId: Long, groupMemberId: Long): Pair<GroupMember, String> { + suspend fun apiGetGroupMemberCode(groupId: Long, groupMemberId: Long): Pair<GroupMember, String>? { val r = sendCmd(CC.APIGetGroupMemberCode(groupId, groupMemberId)) if (r is CR.GroupMemberCode) return r.member to r.connectionCode - throw Exception("failed to get group member code: ${r.responseType} ${r.details}") + Log.e(TAG,"failed to get group member code: ${r.responseType} ${r.details}") + return null } suspend fun apiVerifyContact(contactId: Long, connectionCode: String?): Pair<Boolean, String>? { @@ -1272,6 +1280,30 @@ object ChatController { } } + suspend fun apiCreateMemberContact(groupId: Long, groupMemberId: Long): Contact? { + return when (val r = sendCmd(CC.APICreateMemberContact(groupId, groupMemberId))) { + is CR.NewMemberContact -> r.contact + else -> { + if (!(networkErrorAlert(r))) { + apiErrorAlert("apiCreateMemberContact", generalGetString(MR.strings.error_creating_member_contact), r) + } + null + } + } + } + + suspend fun apiSendMemberContactInvitation(contactId: Long, mc: MsgContent): Contact? { + return when (val r = sendCmd(CC.APISendMemberContactInvitation(contactId, mc))) { + is CR.NewMemberContactSentInv -> r.contact + else -> { + if (!(networkErrorAlert(r))) { + apiErrorAlert("apiSendMemberContactInvitation", generalGetString(MR.strings.error_sending_message_contact_invitation), r) + } + null + } + } + } + suspend fun allowFeatureToContact(contact: Contact, feature: ChatFeature, param: Int? = null) { val prefs = contact.mergedPreferences.toPreferences().setAllowed(feature, param = param) val toContact = apiSetContactPrefs(contact.contactId, prefs) @@ -1527,6 +1559,10 @@ object ChatController { if (active(r.user)) { chatModel.updateGroup(r.toGroup) } + is CR.NewMemberContactReceivedInv -> + if (active(r.user)) { + chatModel.updateContact(r.contact) + } is CR.RcvFileStart -> chatItemSimpleUpdate(r.user, r.chatItem) is CR.RcvFileComplete -> @@ -1822,6 +1858,8 @@ sealed class CC { class APIGroupLinkMemberRole(val groupId: Long, val memberRole: GroupMemberRole): CC() class APIDeleteGroupLink(val groupId: Long): CC() class APIGetGroupLink(val groupId: Long): CC() + class APICreateMemberContact(val groupId: Long, val groupMemberId: Long): CC() + class APISendMemberContactInvitation(val contactId: Long, val mc: MsgContent): CC() class APIGetUserProtoServers(val userId: Long, val serverProtocol: ServerProtocol): CC() class APISetUserProtoServers(val userId: Long, val serverProtocol: ServerProtocol, val servers: List<ServerCfg>): CC() class APITestProtoServer(val userId: Long, val server: String): CC() @@ -1927,6 +1965,8 @@ sealed class CC { is APIGroupLinkMemberRole -> "/_set link role #$groupId ${memberRole.name.lowercase()}" is APIDeleteGroupLink -> "/_delete link #$groupId" is APIGetGroupLink -> "/_get link #$groupId" + is APICreateMemberContact -> "/_create member contact #$groupId $groupMemberId" + is APISendMemberContactInvitation -> "/_invite member contact @$contactId ${mc.cmdString}" is APIGetUserProtoServers -> "/_servers $userId ${serverProtocol.name.lowercase()}" is APISetUserProtoServers -> "/_servers $userId ${serverProtocol.name.lowercase()} ${protoServersStr(servers)}" is APITestProtoServer -> "/_server test $userId $server" @@ -2021,6 +2061,8 @@ sealed class CC { is APIGroupLinkMemberRole -> "apiGroupLinkMemberRole" is APIDeleteGroupLink -> "apiDeleteGroupLink" is APIGetGroupLink -> "apiGetGroupLink" + is APICreateMemberContact -> "apiCreateMemberContact" + is APISendMemberContactInvitation -> "apiSendMemberContactInvitation" is APIGetUserProtoServers -> "apiGetUserProtoServers" is APISetUserProtoServers -> "apiSetUserProtoServers" is APITestProtoServer -> "testProtoServer" @@ -2350,7 +2392,7 @@ data class NetCfg( sessionMode = TransportSessionMode.User, tcpConnectTimeout = 15_000_000, tcpTimeout = 10_000_000, - tcpTimeoutPerKb = 20_000, + tcpTimeoutPerKb = 30_000, tcpKeepAlive = KeepAliveOpts.defaults, smpPingInterval = 1200_000_000, smpPingCount = 3 @@ -2364,7 +2406,7 @@ data class NetCfg( sessionMode = TransportSessionMode.User, tcpConnectTimeout = 30_000_000, tcpTimeout = 20_000_000, - tcpTimeoutPerKb = 40_000, + tcpTimeoutPerKb = 60_000, tcpKeepAlive = KeepAliveOpts.defaults, smpPingInterval = 1200_000_000, smpPingCount = 3 @@ -3311,6 +3353,9 @@ sealed class CR { @Serializable @SerialName("groupLinkCreated") class GroupLinkCreated(val user: UserRef, val groupInfo: GroupInfo, val connReqContact: String, val memberRole: GroupMemberRole): CR() @Serializable @SerialName("groupLink") class GroupLink(val user: UserRef, val groupInfo: GroupInfo, val connReqContact: String, val memberRole: GroupMemberRole): CR() @Serializable @SerialName("groupLinkDeleted") class GroupLinkDeleted(val user: UserRef, val groupInfo: GroupInfo): CR() + @Serializable @SerialName("newMemberContact") class NewMemberContact(val user: UserRef, val contact: Contact, val groupInfo: GroupInfo, val member: GroupMember): CR() + @Serializable @SerialName("newMemberContactSentInv") class NewMemberContactSentInv(val user: UserRef, val contact: Contact, val groupInfo: GroupInfo, val member: GroupMember): CR() + @Serializable @SerialName("newMemberContactReceivedInv") class NewMemberContactReceivedInv(val user: UserRef, val contact: Contact, val groupInfo: GroupInfo, val member: GroupMember): CR() // receiving file events @Serializable @SerialName("rcvFileAccepted") class RcvFileAccepted(val user: UserRef, val chatItem: AChatItem): CR() @Serializable @SerialName("rcvFileAcceptedSndCancelled") class RcvFileAcceptedSndCancelled(val user: UserRef, val rcvFileTransfer: RcvFileTransfer): CR() @@ -3438,6 +3483,9 @@ sealed class CR { is GroupLinkCreated -> "groupLinkCreated" is GroupLink -> "groupLink" is GroupLinkDeleted -> "groupLinkDeleted" + is NewMemberContact -> "newMemberContact" + is NewMemberContactSentInv -> "newMemberContactSentInv" + is NewMemberContactReceivedInv -> "newMemberContactReceivedInv" is RcvFileAcceptedSndCancelled -> "rcvFileAcceptedSndCancelled" is RcvFileAccepted -> "rcvFileAccepted" is RcvFileStart -> "rcvFileStart" @@ -3563,6 +3611,9 @@ sealed class CR { is GroupLinkCreated -> withUser(user, "groupInfo: $groupInfo\nconnReqContact: $connReqContact\nmemberRole: $memberRole") is GroupLink -> withUser(user, "groupInfo: $groupInfo\nconnReqContact: $connReqContact\nmemberRole: $memberRole") is GroupLinkDeleted -> withUser(user, json.encodeToString(groupInfo)) + is NewMemberContact -> withUser(user, "contact: $contact\ngroupInfo: $groupInfo\nmember: $member") + is NewMemberContactSentInv -> withUser(user, "contact: $contact\ngroupInfo: $groupInfo\nmember: $member") + is NewMemberContactReceivedInv -> withUser(user, "contact: $contact\ngroupInfo: $groupInfo\nmember: $member") is RcvFileAcceptedSndCancelled -> withUser(user, noDetails()) is RcvFileAccepted -> withUser(user, json.encodeToString(chatItem)) is RcvFileStart -> withUser(user, json.encodeToString(chatItem)) @@ -3820,6 +3871,7 @@ sealed class ChatErrorType { is AgentCommandError -> "agentCommandError" is InvalidFileDescription -> "invalidFileDescription" is ConnectionIncognitoChangeProhibited -> "connectionIncognitoChangeProhibited" + is PeerChatVRangeIncompatible -> "peerChatVRangeIncompatible" is InternalError -> "internalError" is CEException -> "exception $message" } @@ -3894,6 +3946,7 @@ sealed class ChatErrorType { @Serializable @SerialName("agentCommandError") class AgentCommandError(val message: String): ChatErrorType() @Serializable @SerialName("invalidFileDescription") class InvalidFileDescription(val message: String): ChatErrorType() @Serializable @SerialName("connectionIncognitoChangeProhibited") object ConnectionIncognitoChangeProhibited: ChatErrorType() + @Serializable @SerialName("peerChatVRangeIncompatible") object PeerChatVRangeIncompatible: ChatErrorType() @Serializable @SerialName("internalError") class InternalError(val message: String): ChatErrorType() @Serializable @SerialName("exception") class CEException(val message: String): ChatErrorType() } @@ -3922,6 +3975,7 @@ sealed class StoreError { is GroupMemberNameNotFound -> "groupMemberNameNotFound" is GroupMemberNotFound -> "groupMemberNotFound" is GroupMemberNotFoundByMemberId -> "groupMemberNotFoundByMemberId" + is MemberContactGroupMemberNotFound -> "memberContactGroupMemberNotFound" is GroupWithoutUser -> "groupWithoutUser" is DuplicateGroupMember -> "duplicateGroupMember" is GroupAlreadyJoined -> "groupAlreadyJoined" @@ -3979,6 +4033,7 @@ sealed class StoreError { @Serializable @SerialName("groupMemberNameNotFound") class GroupMemberNameNotFound(val groupId: Long, val groupMemberName: String): StoreError() @Serializable @SerialName("groupMemberNotFound") class GroupMemberNotFound(val groupMemberId: Long): StoreError() @Serializable @SerialName("groupMemberNotFoundByMemberId") class GroupMemberNotFoundByMemberId(val memberId: String): StoreError() + @Serializable @SerialName("memberContactGroupMemberNotFound") class MemberContactGroupMemberNotFound(val contactId: Long): StoreError() @Serializable @SerialName("groupWithoutUser") object GroupWithoutUser: StoreError() @Serializable @SerialName("duplicateGroupMember") object DuplicateGroupMember: StoreError() @Serializable @SerialName("groupAlreadyJoined") object GroupAlreadyJoined: StoreError() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/PlatformTextField.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/PlatformTextField.kt index 4a8a2e204f..95b6a73ca4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/PlatformTextField.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/PlatformTextField.kt @@ -8,6 +8,7 @@ import chat.simplex.common.views.chat.ComposeState @Composable expect fun PlatformTextField( composeState: MutableState<ComposeState>, + sendMsgEnabled: Boolean, textStyle: MutableState<TextStyle>, showDeleteTextButton: MutableState<Boolean>, userIsObserver: Boolean, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/VideoPlayer.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/VideoPlayer.kt index bde9d8a49d..5c3b50bbde 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/VideoPlayer.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/VideoPlayer.kt @@ -7,6 +7,8 @@ import java.net.URI interface VideoPlayerInterface { data class PreviewAndDuration(val preview: ImageBitmap?, val duration: Long?, val timestamp: Long) + val uri: URI + val gallery: Boolean val soundEnabled: MutableState<Boolean> val brokenVideo: MutableState<Boolean> val videoPlaying: MutableState<Boolean> @@ -20,18 +22,45 @@ interface VideoPlayerInterface { fun release(remove: Boolean) } -expect class VideoPlayer: VideoPlayerInterface { - companion object { - fun getOrCreate( - uri: URI, - gallery: Boolean, - defaultPreview: ImageBitmap, - defaultDuration: Long, - soundEnabled: Boolean - ): VideoPlayer - fun enableSound(enable: Boolean, fileName: String?, gallery: Boolean): Boolean - fun release(uri: URI, gallery: Boolean, remove: Boolean) - fun stopAll() - fun releaseAll() +expect class VideoPlayer( + uri: URI, + gallery: Boolean, + defaultPreview: ImageBitmap, + defaultDuration: Long, + soundEnabled: Boolean +): VideoPlayerInterface + +object VideoPlayerHolder { + val players: MutableMap<Pair<URI, Boolean>, VideoPlayer> = mutableMapOf() + val previewsAndDurations: MutableMap<URI, VideoPlayerInterface.PreviewAndDuration> = mutableMapOf() + + fun getOrCreate( + uri: URI, + gallery: Boolean, + defaultPreview: ImageBitmap, + defaultDuration: Long, + soundEnabled: Boolean + ): VideoPlayer = + players.getOrPut(uri to gallery) { VideoPlayer(uri, gallery, defaultPreview, defaultDuration, soundEnabled) } + + fun enableSound(enable: Boolean, fileName: String?, gallery: Boolean): Boolean = + player(fileName, gallery)?.enableSound(enable) == true + + private fun player(fileName: String?, gallery: Boolean): VideoPlayer? { + fileName ?: return null + return players.values.firstOrNull { player -> player.uri.path?.endsWith(fileName) == true && player.gallery == gallery } + } + + fun release(uri: URI, gallery: Boolean, remove: Boolean) = + player(uri.path, gallery)?.release(remove).run { } + + fun stopAll() { + players.values.forEach { it.stop() } + } + + fun releaseAll() { + players.values.forEach { it.release(false) } + players.clear() + previewsAndDurations.clear() } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt index e8af0e71a9..e471341669 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt @@ -85,6 +85,8 @@ fun TerminalLayout( recState = remember { mutableStateOf(RecordingState.NotStarted) }, isDirectChat = false, liveMessageAlertShown = SharedPreference(get = { false }, set = {}), + sendMsgEnabled = true, + nextSendGrpInv = false, needToAllowVoiceToContact = false, allowedVoiceByPrefs = false, userIsObserver = false, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt index 170f870130..5fcb90c1c9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt @@ -291,21 +291,23 @@ fun ChatInfoLayout( SectionDividerSpaced() } - SectionView { - if (connectionCode != null) { - VerifyCodeButton(contact.verified, verifyClicked) + if (contact.ready) { + SectionView { + if (connectionCode != null) { + VerifyCodeButton(contact.verified, verifyClicked) + } + ContactPreferencesButton(openPreferences) + SendReceiptsOption(currentUser, sendReceipts, setSendReceipts) + if (cStats != null && cStats.ratchetSyncAllowed) { + SynchronizeConnectionButton(syncContactConnection) + } + // } else if (developerTools) { + // SynchronizeConnectionButtonForce(syncContactConnectionForce) + // } } - ContactPreferencesButton(openPreferences) - SendReceiptsOption(currentUser, sendReceipts, setSendReceipts) - if (cStats != null && cStats.ratchetSyncAllowed) { - SynchronizeConnectionButton(syncContactConnection) - } -// } else if (developerTools) { -// SynchronizeConnectionButtonForce(syncContactConnectionForce) -// } + SectionDividerSpaced() } - SectionDividerSpaced() if (contact.contactLink != null) { SectionView(stringResource(MR.strings.address_section_title).uppercase()) { QRCode(contact.contactLink, Modifier.padding(horizontal = DEFAULT_PADDING, vertical = DEFAULT_PADDING_HALF).aspectRatio(1f)) @@ -316,36 +318,40 @@ fun ChatInfoLayout( SectionDividerSpaced() } - SectionView(title = stringResource(MR.strings.conn_stats_section_title_servers)) { - SectionItemView({ - AlertManager.shared.showAlertMsg( - generalGetString(MR.strings.network_status), - contactNetworkStatus.statusExplanation - )}) { - NetworkStatusRow(contactNetworkStatus) - } - if (cStats != null) { - SwitchAddressButton( - disabled = cStats.rcvQueuesInfo.any { it.rcvSwitchStatus != null } || cStats.ratchetSyncSendProhibited, - switchAddress = switchContactAddress - ) - if (cStats.rcvQueuesInfo.any { it.rcvSwitchStatus != null }) { - AbortSwitchAddressButton( - disabled = cStats.rcvQueuesInfo.any { it.rcvSwitchStatus != null && !it.canAbortSwitch } || cStats.ratchetSyncSendProhibited, - abortSwitchAddress = abortSwitchContactAddress + if (contact.ready) { + SectionView(title = stringResource(MR.strings.conn_stats_section_title_servers)) { + SectionItemView({ + AlertManager.shared.showAlertMsg( + generalGetString(MR.strings.network_status), + contactNetworkStatus.statusExplanation ) + }) { + NetworkStatusRow(contactNetworkStatus) } - val rcvServers = cStats.rcvQueuesInfo.map { it.rcvServer } - if (rcvServers.isNotEmpty()) { - SimplexServers(stringResource(MR.strings.receiving_via), rcvServers) - } - val sndServers = cStats.sndQueuesInfo.map { it.sndServer } - if (sndServers.isNotEmpty()) { - SimplexServers(stringResource(MR.strings.sending_via), sndServers) + if (cStats != null) { + SwitchAddressButton( + disabled = cStats.rcvQueuesInfo.any { it.rcvSwitchStatus != null } || cStats.ratchetSyncSendProhibited, + switchAddress = switchContactAddress + ) + if (cStats.rcvQueuesInfo.any { it.rcvSwitchStatus != null }) { + AbortSwitchAddressButton( + disabled = cStats.rcvQueuesInfo.any { it.rcvSwitchStatus != null && !it.canAbortSwitch } || cStats.ratchetSyncSendProhibited, + abortSwitchAddress = abortSwitchContactAddress + ) + } + val rcvServers = cStats.rcvQueuesInfo.map { it.rcvServer } + if (rcvServers.isNotEmpty()) { + SimplexServers(stringResource(MR.strings.receiving_via), rcvServers) + } + val sndServers = cStats.sndQueuesInfo.map { it.sndServer } + if (sndServers.isNotEmpty()) { + SimplexServers(stringResource(MR.strings.sending_via), sndServers) + } } } + SectionDividerSpaced() } - SectionDividerSpaced() + SectionView { ClearChatButton(clearChat) DeleteContactButton(deleteContact) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt index c8381cdcb7..3a5e27ed22 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt @@ -114,7 +114,18 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId: unreadCount, composeState, composeView = { - if (chat.chatInfo.sendMsgEnabled) { + Column( + Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + if (chat.chatInfo is ChatInfo.Direct && !chat.chatInfo.contact.ready && !chat.chatInfo.contact.nextSendGrpInv) { + Text( + generalGetString(MR.strings.contact_connection_pending), + Modifier.padding(top = 4.dp), + fontSize = 14.sp, + color = MaterialTheme.colors.secondary + ) + } ComposeView( chatModel, chat, composeState, attachmentOption, showChooseAttachment = { scope.launch { attachmentBottomSheetState.show() } } @@ -145,7 +156,7 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId: var preloadedLink: Pair<String, GroupMemberRole>? = null if (chat.chatInfo is ChatInfo.Direct) { preloadedContactInfo = chatModel.controller.apiContactInfo(chat.chatInfo.apiId) - preloadedCode = chatModel.controller.apiGetContactCode(chat.chatInfo.apiId).second + preloadedCode = chatModel.controller.apiGetContactCode(chat.chatInfo.apiId)?.second } else if (chat.chatInfo is ChatInfo.Group) { setGroupMembers(chat.chatInfo.groupInfo, chatModel) preloadedLink = chatModel.controller.apiGetGroupLink(chat.chatInfo.groupInfo.groupId) @@ -158,7 +169,7 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId: KeyChangeEffect(chat.id, ChatModel.networkStatuses.toMap()) { contactInfo = chatModel.controller.apiContactInfo(chat.chatInfo.apiId) preloadedContactInfo = contactInfo - code = chatModel.controller.apiGetContactCode(chat.chatInfo.apiId).second + code = chatModel.controller.apiGetContactCode(chat.chatInfo.apiId)?.second preloadedCode = code } ChatInfoView(chatModel, (chat.chatInfo as ChatInfo.Direct).contact, contactInfo?.first, contactInfo?.second, chat.chatInfo.localAlias, code, close) @@ -183,12 +194,8 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId: val r = chatModel.controller.apiGroupMemberInfo(groupInfo.groupId, member.groupMemberId) val stats = r?.second val (_, code) = if (member.memberActive) { - try { - chatModel.controller.apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) - } catch (e: Exception) { - Log.e(TAG, e.stackTraceToString()) - member to null - } + val memCode = chatModel.controller.apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) + member to memCode?.second } else { member to null } @@ -280,6 +287,11 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId: chatModel.controller.allowFeatureToContact(contact, feature, param) } }, + openDirectChat = { contactId -> + withApi { + openDirectChat(contactId, chatModel) + } + }, updateContactStats = { contact -> withApi { val r = chatModel.controller.apiContactInfo(chat.chatInfo.apiId) @@ -409,6 +421,7 @@ fun ChatLayout( startCall: (CallMediaType) -> Unit, acceptCall: (Contact) -> Unit, acceptFeature: (Contact, ChatFeature, Int?) -> Unit, + openDirectChat: (Long) -> Unit, updateContactStats: (Contact) -> Unit, updateMemberStats: (GroupInfo, GroupMember) -> Unit, syncContactConnection: (Contact) -> Unit, @@ -485,7 +498,7 @@ fun ChatLayout( ChatItemsList( chat, unreadCount, composeState, chatItems, searchValue, useLinkPreviews, linkMode, showMemberInfo, loadPrevMessages, deleteMessage, - receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, + receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat, updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember, setReaction, showItemDetails, markRead, setFloatingButton, onComposed, ) @@ -534,15 +547,22 @@ fun ChatInfoToolbar( IconButton({ showMenu.value = false startCall(CallMediaType.Audio) - }) { - Icon(painterResource(MR.images.ic_call_500), stringResource(MR.strings.icon_descr_more_button), tint = MaterialTheme.colors.primary) + }, + enabled = chat.chatInfo.contact.ready) { + Icon( + painterResource(MR.images.ic_call_500), + stringResource(MR.strings.icon_descr_more_button), + tint = if (chat.chatInfo.contact.ready) MaterialTheme.colors.primary else MaterialTheme.colors.secondary + ) } } - menuItems.add { - ItemAction(stringResource(MR.strings.icon_descr_video_call).capitalize(Locale.current), painterResource(MR.images.ic_videocam), onClick = { - showMenu.value = false - startCall(CallMediaType.Video) - }) + if (chat.chatInfo.contact.ready) { + menuItems.add { + ItemAction(stringResource(MR.strings.icon_descr_video_call).capitalize(Locale.current), painterResource(MR.images.ic_videocam), onClick = { + showMenu.value = false + startCall(CallMediaType.Video) + }) + } } } else if (chat.chatInfo is ChatInfo.Group && chat.chatInfo.groupInfo.canAddMembers && !chat.chatInfo.incognito) { barButtons.add { @@ -554,20 +574,22 @@ fun ChatInfoToolbar( } } } - val ntfsEnabled = remember { mutableStateOf(chat.chatInfo.ntfsEnabled) } - menuItems.add { - ItemAction( - if (ntfsEnabled.value) stringResource(MR.strings.mute_chat) else stringResource(MR.strings.unmute_chat), - if (ntfsEnabled.value) painterResource(MR.images.ic_notifications_off) else painterResource(MR.images.ic_notifications), - onClick = { - showMenu.value = false - // Just to make a delay before changing state of ntfsEnabled, otherwise it will redraw menu item with new value before closing the menu - scope.launch { - delay(200) - changeNtfsState(!ntfsEnabled.value, ntfsEnabled) + if ((chat.chatInfo is ChatInfo.Direct && chat.chatInfo.contact.ready) || chat.chatInfo is ChatInfo.Group) { + val ntfsEnabled = remember { mutableStateOf(chat.chatInfo.ntfsEnabled) } + menuItems.add { + ItemAction( + if (ntfsEnabled.value) stringResource(MR.strings.mute_chat) else stringResource(MR.strings.unmute_chat), + if (ntfsEnabled.value) painterResource(MR.images.ic_notifications_off) else painterResource(MR.images.ic_notifications), + onClick = { + showMenu.value = false + // Just to make a delay before changing state of ntfsEnabled, otherwise it will redraw menu item with new value before closing the menu + scope.launch { + delay(200) + changeNtfsState(!ntfsEnabled.value, ntfsEnabled) + } } - } - ) + ) + } } barButtons.add { @@ -661,6 +683,7 @@ fun BoxWithConstraintsScope.ChatItemsList( joinGroup: (Long) -> Unit, acceptCall: (Contact) -> Unit, acceptFeature: (Contact, ChatFeature, Int?) -> Unit, + openDirectChat: (Long) -> Unit, updateContactStats: (Contact) -> Unit, updateMemberStats: (GroupInfo, GroupMember) -> Unit, syncContactConnection: (Contact) -> Unit, @@ -714,7 +737,7 @@ fun BoxWithConstraintsScope.ChatItemsList( } DisposableEffectOnGone( whenGone = { - VideoPlayer.releaseAll() + VideoPlayerHolder.releaseAll() } ) LazyColumn(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) { @@ -808,7 +831,7 @@ fun BoxWithConstraintsScope.ChatItemsList( ) { MemberImage(member) } - ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = {}, acceptCall = acceptCall, acceptFeature = acceptFeature, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, getConnectedMemberNames = ::getConnectedMemberNames) + ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = {}, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, getConnectedMemberNames = ::getConnectedMemberNames) } } } else { @@ -817,7 +840,7 @@ fun BoxWithConstraintsScope.ChatItemsList( .padding(start = 8.dp + MEMBER_IMAGE_SIZE + 4.dp, end = if (voiceWithTransparentBack) 12.dp else 66.dp) .then(swipeableModifier) ) { - ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = {}, acceptCall = acceptCall, acceptFeature = acceptFeature, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, getConnectedMemberNames = ::getConnectedMemberNames) + ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = {}, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, getConnectedMemberNames = ::getConnectedMemberNames) } } } @@ -827,7 +850,7 @@ fun BoxWithConstraintsScope.ChatItemsList( .padding(start = if (voiceWithTransparentBack) 12.dp else 104.dp, end = 12.dp) .then(swipeableModifier) ) { - ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = {}, acceptCall = acceptCall, acceptFeature = acceptFeature, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails) + ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = {}, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails) } } } else { // direct message @@ -838,7 +861,7 @@ fun BoxWithConstraintsScope.ChatItemsList( end = if (sent || voiceWithTransparentBack) 12.dp else 76.dp, ).then(swipeableModifier) ) { - ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails) + ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, deleteMessage = deleteMessage, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails) } } @@ -1263,6 +1286,7 @@ fun PreviewChatLayout() { startCall = {}, acceptCall = { _ -> }, acceptFeature = { _, _, _ -> }, + openDirectChat = { _ -> }, updateContactStats = { }, updateMemberStats = { _, _ -> }, syncContactConnection = { }, @@ -1330,6 +1354,7 @@ fun PreviewGroupChatLayout() { startCall = {}, acceptCall = { _ -> }, acceptFeature = { _, _, _ -> }, + openDirectChat = { _ -> }, updateContactStats = { }, updateMemberStats = { _, _ -> }, syncContactConnection = { }, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextInvitingContactMemberView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextInvitingContactMemberView.kt new file mode 100644 index 0000000000..20316dd524 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextInvitingContactMemberView.kt @@ -0,0 +1,39 @@ +package chat.simplex.common.views.chat + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import chat.simplex.common.ui.theme.* +import chat.simplex.common.views.helpers.generalGetString +import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource +import dev.icerock.moko.resources.compose.stringResource + +@Composable +fun ComposeContextInvitingContactMemberView() { + val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage + Row( + Modifier + .height(60.dp) + .fillMaxWidth() + .padding(top = 8.dp) + .background(sentColor), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + painterResource(MR.images.ic_chat), + stringResource(MR.strings.button_send_direct_message), + modifier = Modifier + .padding(start = 12.dp, end = 8.dp) + .height(20.dp) + .width(20.dp), + tint = MaterialTheme.colors.secondary + ) + Text(generalGetString(MR.strings.compose_send_direct_message_to_connect)) + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt index 4d6bc297f0..f26ce0a7a4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt @@ -335,8 +335,6 @@ fun ComposeView( return null } - - suspend fun sendMessageAsync(text: String?, live: Boolean, ttl: Int?): ChatItem? { val cInfo = chat.chatInfo val cs = composeState.value @@ -358,6 +356,7 @@ fun ComposeView( MsgContent.MCText(msgText) } } + else -> MsgContent.MCText(msgText) } } @@ -374,6 +373,14 @@ fun ComposeView( } } + suspend fun sendMemberContactInvitation() { + val mc = checkLinkPreview() + val contact = chatModel.controller.apiSendMemberContactInvitation(chat.chatInfo.apiId, mc) + if (contact != null) { + chatModel.updateContact(contact) + } + } + suspend fun updateMessage(ei: ChatItem, cInfo: ChatInfo, live: Boolean): ChatItem? { val oldMsgContent = ei.content.msgContent if (oldMsgContent != null) { @@ -397,7 +404,10 @@ fun ComposeView( } clearCurrentDraft() - if (cs.contextItem is ComposeContextItem.EditingItem) { + if (chat.nextSendGrpInv) { + sendMemberContactInvitation() + sent = null + } else if (cs.contextItem is ComposeContextItem.EditingItem) { val ei = cs.contextItem.chatItem sent = updateMessage(ei, cInfo, live) } else if (liveMessage != null && liveMessage.sent) { @@ -655,9 +665,14 @@ fun ComposeView( } val userCanSend = rememberUpdatedState(chat.userCanSend) + val sendMsgEnabled = rememberUpdatedState(chat.chatInfo.sendMsgEnabled) val userIsObserver = rememberUpdatedState(chat.userIsObserver) + val nextSendGrpInv = rememberUpdatedState(chat.nextSendGrpInv) Column { + if (nextSendGrpInv.value) { + ComposeContextInvitingContactMemberView() + } if (composeState.value.preview !is ComposePreview.VoicePreview || composeState.value.editing) { contextItemView() when { @@ -690,15 +705,21 @@ fun ComposeView( } else { showChooseAttachment } + val attachmentEnabled = + !composeState.value.attachmentDisabled + && sendMsgEnabled.value + && userCanSend.value + && !isGroupAndProhibitedFiles + && !nextSendGrpInv.value IconButton( attachmentClicked, Modifier.padding(bottom = if (appPlatform.isAndroid) 0.dp else 7.dp), - enabled = !composeState.value.attachmentDisabled && rememberUpdatedState(chat.userCanSend).value + enabled = attachmentEnabled ) { Icon( painterResource(MR.images.ic_attach_file_filled_500), contentDescription = stringResource(MR.strings.attach), - tint = if (!composeState.value.attachmentDisabled && userCanSend.value && !isGroupAndProhibitedFiles) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, + tint = if (attachmentEnabled) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, modifier = Modifier .size(28.dp) .clip(CircleShape) @@ -774,6 +795,8 @@ fun ComposeView( recState, chat.chatInfo is ChatInfo.Direct, liveMessageAlertShown = chatModel.controller.appPrefs.liveMessageAlertShown, + sendMsgEnabled = sendMsgEnabled.value, + nextSendGrpInv = nextSendGrpInv.value, needToAllowVoiceToContact, allowedVoiceByPrefs, allowVoiceToContact = ::allowVoiceToContact, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt index 205f18c46a..2d696b7781 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt @@ -37,6 +37,8 @@ fun SendMsgView( recState: MutableState<RecordingState>, isDirectChat: Boolean, liveMessageAlertShown: SharedPreference<Boolean>, + sendMsgEnabled: Boolean, + nextSendGrpInv: Boolean, needToAllowVoiceToContact: Boolean, allowedVoiceByPrefs: Boolean, userIsObserver: Boolean, @@ -74,16 +76,16 @@ fun SendMsgView( false } } - val showVoiceButton = cs.message.isEmpty() && showVoiceRecordIcon && !composeState.value.editing && + val showVoiceButton = !nextSendGrpInv && cs.message.isEmpty() && showVoiceRecordIcon && !composeState.value.editing && cs.liveMessage == null && (cs.preview is ComposePreview.NoPreview || recState.value is RecordingState.Started) val showDeleteTextButton = rememberSaveable { mutableStateOf(false) } - PlatformTextField(composeState, textStyle, showDeleteTextButton, userIsObserver, onMessageChange, editPrevMessage) { + PlatformTextField(composeState, sendMsgEnabled, textStyle, showDeleteTextButton, userIsObserver, onMessageChange, editPrevMessage) { if (!cs.inProgress) { sendMessage(null) } } // Disable clicks on text field - if (cs.preview is ComposePreview.VoicePreview || !userCanSend || cs.inProgress) { + if (!sendMsgEnabled || cs.preview is ComposePreview.VoicePreview || !userCanSend || cs.inProgress) { Box( Modifier .matchParentSize() @@ -110,7 +112,7 @@ fun SendMsgView( } when { progressByTimeout -> ProgressIndicator() - showVoiceButton -> { + showVoiceButton && sendMsgEnabled -> { Row(verticalAlignment = Alignment.CenterVertically) { val stopRecOnNextClick = remember { mutableStateOf(false) } when { @@ -150,7 +152,7 @@ fun SendMsgView( else -> { val cs = composeState.value val icon = if (cs.editing || cs.liveMessage != null) painterResource(MR.images.ic_check_filled) else painterResource(MR.images.ic_arrow_upward) - val disabled = !cs.sendEnabled() || + val disabled = !sendMsgEnabled || !cs.sendEnabled() || (!allowedVoiceByPrefs && cs.preview is ComposePreview.VoicePreview) || cs.endLiveDisabled val showDropdown = rememberSaveable { mutableStateOf(false) } @@ -159,7 +161,7 @@ fun SendMsgView( fun MenuItems(): List<@Composable () -> Unit> { val menuItems = mutableListOf<@Composable () -> Unit>() - if (cs.liveMessage == null && !cs.editing) { + if (cs.liveMessage == null && !cs.editing && !nextSendGrpInv || sendMsgEnabled) { if ( cs.preview !is ComposePreview.VoicePreview && cs.contextItem is ComposeContextItem.NoContextItem && @@ -599,6 +601,8 @@ fun PreviewSendMsgView() { recState = remember { mutableStateOf(RecordingState.NotStarted) }, isDirectChat = true, liveMessageAlertShown = SharedPreference(get = { true }, set = { }), + sendMsgEnabled = true, + nextSendGrpInv = false, needToAllowVoiceToContact = false, allowedVoiceByPrefs = true, userIsObserver = false, @@ -630,6 +634,8 @@ fun PreviewSendMsgViewEditing() { recState = remember { mutableStateOf(RecordingState.NotStarted) }, isDirectChat = true, liveMessageAlertShown = SharedPreference(get = { true }, set = { }), + sendMsgEnabled = true, + nextSendGrpInv = false, needToAllowVoiceToContact = false, allowedVoiceByPrefs = true, userIsObserver = false, @@ -661,6 +667,8 @@ fun PreviewSendMsgViewInProgress() { recState = remember { mutableStateOf(RecordingState.NotStarted) }, isDirectChat = true, liveMessageAlertShown = SharedPreference(get = { true }, set = { }), + sendMsgEnabled = true, + nextSendGrpInv = false, needToAllowVoiceToContact = false, allowedVoiceByPrefs = true, userIsObserver = false, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt index 40291b8fe0..f475d045cf 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt @@ -76,12 +76,8 @@ fun GroupChatInfoView(chatModel: ChatModel, groupLink: String?, groupLinkMemberR val r = chatModel.controller.apiGroupMemberInfo(groupInfo.groupId, member.groupMemberId) val stats = r?.second val (_, code) = if (member.memberActive) { - try { - chatModel.controller.apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) - } catch (e: Exception) { - Log.e(TAG, e.stackTraceToString()) - member to null - } + val memCode = chatModel.controller.apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) + member to memCode?.second } else { member to null } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt index a3e5d5af18..e14089ec52 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt @@ -35,6 +35,7 @@ import chat.simplex.common.views.newchat.* import chat.simplex.common.views.usersettings.SettingsActionItem import chat.simplex.common.model.GroupInfo import chat.simplex.common.platform.* +import chat.simplex.common.views.chatlist.openChat import chat.simplex.res.MR import kotlinx.datetime.Clock @@ -52,6 +53,8 @@ fun GroupMemberInfoView( val chat = chatModel.chats.firstOrNull { it.id == chatModel.chatId.value } val connStats = remember { mutableStateOf(connectionStats) } val developerTools = chatModel.controller.appPrefs.developerTools.get() + var progressIndicator by remember { mutableStateOf(false) } + if (chat != null) { val newRole = remember { mutableStateOf(member.memberRole) } GroupMemberInfoLayout( @@ -76,6 +79,20 @@ fun GroupMemberInfoView( } } }, + createMemberContact = { + withApi { + progressIndicator = true + val memberContact = chatModel.controller.apiCreateMemberContact(groupInfo.apiId, member.groupMemberId) + if (memberContact != null) { + val memberChat = Chat(ChatInfo.Direct(memberContact), chatItems = arrayListOf()) + chatModel.addChat(memberChat) + openChat(memberChat, chatModel) + closeAll() + chatModel.setContactNetworkStatus(memberContact, NetworkStatus.Connected()) + } + progressIndicator = false + } + }, connectViaAddress = { connReqUri -> connectViaMemberAddressAlert(connReqUri) }, @@ -170,6 +187,10 @@ fun GroupMemberInfoView( } } ) + + if (progressIndicator) { + ProgressIndicator() + } } } @@ -201,6 +222,7 @@ fun GroupMemberInfoLayout( connectionCode: String?, getContactChat: (Long) -> Chat?, openDirectChat: (Long) -> Unit, + createMemberContact: () -> Unit, connectViaAddress: (String) -> Unit, removeMember: () -> Unit, onRoleSelected: (GroupMemberRole) -> Unit, @@ -237,9 +259,13 @@ fun GroupMemberInfoLayout( if (member.memberActive) { SectionView { - if (contactId != null) { - if (knownDirectChat(contactId) != null || groupInfo.fullGroupPreferences.directMessages.on) { + if (contactId != null && knownDirectChat(contactId) != null) { + OpenChatButton(onClick = { openDirectChat(contactId) }) + } else if (groupInfo.fullGroupPreferences.directMessages.on) { + if (contactId != null) { OpenChatButton(onClick = { openDirectChat(contactId) }) + } else if (member.activeConn?.peerChatVRange?.isCompatibleRange(CREATE_MEMBER_CONTACT_VRANGE) == true) { + OpenChatButton(onClick = { createMemberContact() }) } } if (connectionCode != null) { @@ -498,6 +524,7 @@ fun PreviewGroupMemberInfoLayout() { connectionCode = "123", getContactChat = { Chat.sampleData }, openDirectChat = {}, + createMemberContact = {}, connectViaAddress = {}, removeMember = {}, onRoleSelected = {}, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt index 8de805ba54..87f4aa4f31 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt @@ -71,7 +71,7 @@ fun CIFileView( when (file.fileStatus) { is CIFileStatus.RcvInvitation -> { if (fileSizeValid()) { - val encrypted = file.fileProtocol == FileProtocol.XFTP && chatController.appPrefs.privacyEncryptLocalFiles.get() + val encrypted = chatController.appPrefs.privacyEncryptLocalFiles.get() receiveFile(file.fileId, encrypted) } else { AlertManager.shared.showAlertMsg( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMemberCreatedContactView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMemberCreatedContactView.kt new file mode 100644 index 0000000000..2ade49b3fc --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMemberCreatedContactView.kt @@ -0,0 +1,70 @@ +package chat.simplex.common.views.chat.item + +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.* +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import chat.simplex.common.views.helpers.generalGetString +import chat.simplex.common.model.* +import chat.simplex.res.MR + +@Composable +fun CIMemberCreatedContactView( + chatItem: ChatItem, + openDirectChat: (Long) -> Unit +) { + fun eventText(): AnnotatedString { + val memberDisplayName = chatItem.memberDisplayName + return if (memberDisplayName != null) { + buildAnnotatedString { + withStyle(chatEventStyle) { append(memberDisplayName) } + append(" ") + withStyle(chatEventStyle) { append(chatItem.content.text) } + } + } else { + buildAnnotatedString { + withStyle(chatEventStyle) { append(chatItem.content.text) } + } + } + } + + Row( + Modifier.padding(horizontal = 6.dp, vertical = 6.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp) + ) { + if (chatItem.chatDir is CIDirection.GroupRcv && chatItem.chatDir.groupMember.memberContactId != null) { + val openChatStyle = SpanStyle(color = MaterialTheme.colors.primary, fontSize = 12.sp) + val annotatedText = buildAnnotatedString { + append(eventText()) + append(" ") + withAnnotation(tag = "Open", annotation = "Open") { + withStyle(openChatStyle) { append(generalGetString(MR.strings.rcv_group_event_open_chat) + " ") } + } + withStyle(chatEventStyle) { append(chatItem.timestampText) } + } + + fun open(offset: Int): Boolean = annotatedText.getStringAnnotations(tag = "Open", start = offset, end = offset).isNotEmpty() + ClickableText( + annotatedText, + onClick = { + if (open(it)) { + openDirectChat(chatItem.chatDir.groupMember.memberContactId) + } + }, + shouldConsumeEvent = ::open + ) + } else { + val annotatedText = buildAnnotatedString { + append(eventText()) + append(" ") + withStyle(chatEventStyle) { append(chatItem.timestampText) } + } + Text(annotatedText) + } + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt index aad1e8a8f5..78bdf53d14 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt @@ -50,7 +50,7 @@ fun CIVideoView( }) } else { Box { - ImageView(preview, showMenu, onClick = { + VideoPreviewImageView(preview, onClick = { if (file != null) { when (file.fileStatus) { CIFileStatus.RcvInvitation -> @@ -75,7 +75,10 @@ fun CIVideoView( else -> {} } } - }) + }, + onLongClick = { + showMenu.value = true + }) if (file != null) { DurationProgress(file, remember { mutableStateOf(false) }, remember { mutableStateOf(duration * 1000L) }, remember { mutableStateOf(0L) }/*, soundEnabled*/) } @@ -90,7 +93,7 @@ fun CIVideoView( @Composable private fun VideoView(uri: URI, file: CIFile, defaultPreview: ImageBitmap, defaultDuration: Long, showMenu: MutableState<Boolean>, onClick: () -> Unit) { - val player = remember(uri) { VideoPlayer.getOrCreate(uri, false, defaultPreview, defaultDuration, true) } + val player = remember(uri) { VideoPlayerHolder.getOrCreate(uri, false, defaultPreview, defaultDuration, true) } val videoPlaying = remember(uri.path) { player.videoPlaying } val progress = remember(uri.path) { player.progress } val duration = remember(uri.path) { player.duration } @@ -111,6 +114,7 @@ private fun VideoView(uri: URI, file: CIFile, defaultPreview: ImageBitmap, defau stop() } } + val onLongClick = { showMenu.value = true } Box { val windowWidth = LocalWindowWidth() val width = remember(preview) { if (preview.width * 0.97 <= preview.height) videoViewFullWidth(windowWidth) * 0.75f else DEFAULT_MAX_IMAGE_WIDTH } @@ -118,12 +122,12 @@ private fun VideoView(uri: URI, file: CIFile, defaultPreview: ImageBitmap, defau player, width, onClick = onClick, - onLongClick = { showMenu.value = true }, + onLongClick = onLongClick, stop ) if (showPreview.value) { - ImageView(preview, showMenu, onClick) - PlayButton(brokenVideo, onLongClick = { showMenu.value = true }, play) + VideoPreviewImageView(preview, onClick, onLongClick) + PlayButton(brokenVideo, onLongClick = onLongClick, if (appPlatform.isAndroid) play else onClick) } DurationProgress(file, videoPlaying, duration, progress/*, soundEnabled*/) } @@ -201,7 +205,7 @@ private fun DurationProgress(file: CIFile, playing: MutableState<Boolean>, durat } @Composable -private fun ImageView(preview: ImageBitmap, showMenu: MutableState<Boolean>, onClick: () -> Unit) { +fun VideoPreviewImageView(preview: ImageBitmap, onClick: () -> Unit, onLongClick: () -> Unit) { val windowWidth = LocalWindowWidth() val width = remember(preview) { if (preview.width * 0.97 <= preview.height) videoViewFullWidth(windowWidth) * 0.75f else DEFAULT_MAX_IMAGE_WIDTH } Image( @@ -210,10 +214,10 @@ private fun ImageView(preview: ImageBitmap, showMenu: MutableState<Boolean>, onC modifier = Modifier .width(width) .combinedClickable( - onLongClick = { showMenu.value = true }, + onLongClick = onLongClick, onClick = onClick ) - .onRightClick { showMenu.value = true }, + .onRightClick(onLongClick), contentScale = ContentScale.FillWidth, ) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt index 60ef7e8cfe..98811260d9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt @@ -54,6 +54,7 @@ fun ChatItemView( acceptCall: (Contact) -> Unit, scrollToItem: (Long) -> Unit, acceptFeature: (Contact, ChatFeature, Int?) -> Unit, + openDirectChat: (Long) -> Unit, updateContactStats: (Contact) -> Unit, updateMemberStats: (GroupInfo, GroupMember) -> Unit, syncContactConnection: (Contact) -> Unit, @@ -348,6 +349,7 @@ fun ChatItemView( is CIContent.SndGroupInvitation -> CIGroupInvitationView(cItem, c.groupInvitation, c.memberRole, joinGroup = joinGroup, chatIncognito = cInfo.incognito) is CIContent.RcvGroupEventContent -> when (c.rcvGroupEvent) { is RcvGroupEvent.MemberConnected -> CIEventView(membersConnectedItemText()) + is RcvGroupEvent.MemberCreatedContact -> CIMemberCreatedContactView(cItem, openDirectChat) else -> EventItemView() } is CIContent.SndGroupEventContent -> EventItemView() @@ -572,6 +574,7 @@ fun PreviewChatItemView() { acceptCall = { _ -> }, scrollToItem = {}, acceptFeature = { _, _, _ -> }, + openDirectChat = { _ -> }, updateContactStats = { }, updateMemberStats = { _, _ -> }, syncContactConnection = { }, @@ -601,6 +604,7 @@ fun PreviewChatItemViewDeletedContent() { acceptCall = { _ -> }, scrollToItem = {}, acceptFeature = { _, _, _ -> }, + openDirectChat = { _ -> }, updateContactStats = { }, updateMemberStats = { _, _ -> }, syncContactConnection = { }, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.kt index 9664cabc41..05d11208fb 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.kt @@ -46,9 +46,11 @@ fun ImageFullScreenView(imageProvider: () -> ImageGalleryProvider, close: () -> val scope = rememberCoroutineScope() val playersToRelease = rememberSaveable { mutableSetOf<URI>() } DisposableEffectOnGone( - whenGone = { playersToRelease.forEach { VideoPlayer.release(it, true, true) } } + whenGone = { playersToRelease.forEach { VideoPlayerHolder.release(it, true, true) } } ) - HorizontalPager(pageCount = remember { provider.totalMediaSize }.value, state = pagerState) { index -> + + @Composable + fun Content(index: Int) { Column( Modifier .fillMaxSize() @@ -127,7 +129,7 @@ fun ImageFullScreenView(imageProvider: () -> ImageGalleryProvider, close: () -> FullScreenImageView(modifier, data, imageBitmap) } else if (media is ProviderMedia.Video) { val preview = remember(media.uri.path) { base64ToBitmap(media.preview) } - VideoView(modifier, media.uri, preview, index == settledCurrentPage) + VideoView(modifier, media.uri, preview, index == settledCurrentPage, close) DisposableEffect(Unit) { onDispose { playersToRelease.add(media.uri) } } @@ -135,14 +137,19 @@ fun ImageFullScreenView(imageProvider: () -> ImageGalleryProvider, close: () -> } } } + if (appPlatform.isAndroid) { + HorizontalPager(pageCount = remember { provider.totalMediaSize }.value, state = pagerState) { index -> Content(index) } + } else { + Content(pagerState.currentPage) + } } @Composable expect fun FullScreenImageView(modifier: Modifier, data: ByteArray, imageBitmap: ImageBitmap) @Composable -private fun VideoView(modifier: Modifier, uri: URI, defaultPreview: ImageBitmap, currentPage: Boolean) { - val player = remember(uri) { VideoPlayer.getOrCreate(uri, true, defaultPreview, 0L, true) } +private fun VideoView(modifier: Modifier, uri: URI, defaultPreview: ImageBitmap, currentPage: Boolean, close: () -> Unit) { + val player = remember(uri) { VideoPlayerHolder.getOrCreate(uri, true, defaultPreview, 0L, true) } val isCurrentPage = rememberUpdatedState(currentPage) val play = { player.play(true) @@ -154,13 +161,16 @@ private fun VideoView(modifier: Modifier, uri: URI, defaultPreview: ImageBitmap, player.enableSound(true) snapshotFlow { isCurrentPage.value } .distinctUntilChanged() - .collect { if (it) play() else stop() } + .collect { + // Do not autoplay on desktop because it needs workaround + if (it && appPlatform.isAndroid) play() else if (!it) stop() + } } Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - FullScreenVideoView(player, modifier) + FullScreenVideoView(player, modifier, close) } } @Composable -expect fun FullScreenVideoView(player: VideoPlayer, modifier: Modifier) +expect fun FullScreenVideoView(player: VideoPlayer, modifier: Modifier, close: () -> Unit) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt index 3886fc8c29..57575a1e75 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt @@ -103,11 +103,7 @@ fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) { } fun directChatAction(chatInfo: ChatInfo, chatModel: ChatModel) { - if (chatInfo.ready) { - withBGApi { openChat(chatInfo, chatModel) } - } else { - pendingContactAlertDialog(chatInfo, chatModel) - } + withBGApi { openChat(chatInfo, chatModel) } } fun groupChatAction(groupInfo: GroupInfo, chatModel: ChatModel) { @@ -118,15 +114,28 @@ fun groupChatAction(groupInfo: GroupInfo, chatModel: ChatModel) { } } -suspend fun openChat(chatInfo: ChatInfo, chatModel: ChatModel) { - val chat = chatModel.controller.apiGetChat(chatInfo.chatType, chatInfo.apiId) +suspend fun openDirectChat(contactId: Long, chatModel: ChatModel) { + val chat = chatModel.controller.apiGetChat(ChatType.Direct, contactId) if (chat != null) { chatModel.chatItems.clear() chatModel.chatItems.addAll(chat.chatItems) - chatModel.chatId.value = chatInfo.id + chatModel.chatId.value = "@$contactId" } } +suspend fun openChat(chatInfo: ChatInfo, chatModel: ChatModel) { + val chat = chatModel.controller.apiGetChat(chatInfo.chatType, chatInfo.apiId) + if (chat != null) { + openChat(chat, chatModel) + } +} + +suspend fun openChat(chat: Chat, chatModel: ChatModel) { + chatModel.chatItems.clear() + chatModel.chatItems.addAll(chat.chatItems) + chatModel.chatId.value = chat.chatInfo.id +} + suspend fun apiLoadPrevMessages(chatInfo: ChatInfo, chatModel: ChatModel, beforeChatItemId: Long, search: String) { val pagination = ChatPagination.Before(beforeChatItemId, ChatPagination.PRELOAD_COUNT) val chat = chatModel.controller.apiGetChat(chatInfo.chatType, chatInfo.apiId, pagination, search) ?: return diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt index f71ec865f7..6d7450a213 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt @@ -66,6 +66,8 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf if (chatModel.chatId.value != null) { ModalManager.end.closeModalsExceptFirst() } + AudioPlayer.stop() + VideoPlayerHolder.stopAll() } } val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp @@ -76,6 +78,7 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf scaffoldState = scaffoldState, drawerContent = { SettingsView(chatModel, setPerformLA, scaffoldState.drawerState) }, drawerScrimColor = MaterialTheme.colors.onSurface.copy(alpha = if (isInDarkTheme()) 0.16f else 0.32f), + drawerGesturesEnabled = appPlatform.isAndroid, floatingActionButton = { if (searchInList.isEmpty()) { FloatingActionButton( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt index 95467111e5..780e3515df 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt @@ -172,7 +172,9 @@ fun ChatPreviewView( } else { when (cInfo) { is ChatInfo.Direct -> - if (!cInfo.ready) { + if (cInfo.contact.nextSendGrpInv) { + Text(stringResource(MR.strings.member_contact_send_direct_message), color = MaterialTheme.colors.secondary) + } else if (!cInfo.ready) { Text(stringResource(MR.strings.contact_connection_pending), color = MaterialTheme.colors.secondary) } is ChatInfo.Group -> diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt index 074dd0656a..390fd0f14f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt @@ -334,12 +334,6 @@ private val versionDescriptions: List<VersionDescription> = listOf( ) ) ), - // Also in v5.1 - // preference to disable calls per contact - // configurable SOCKS proxy port - // access welcome message via a group profile - // improve calls on lock screen - // better formatting of times and dates VersionDescription( version = "v5.1", post = "https://simplex.chat/blog/20230523-simplex-chat-v5-1-message-reactions-self-destruct-passcode.html", @@ -370,7 +364,7 @@ private val versionDescriptions: List<VersionDescription> = listOf( descrId = MR.strings.whats_new_thanks_to_users_contribute_weblate, link = "https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat" ) - ), + ) ), VersionDescription( version = "v5.2", @@ -401,8 +395,42 @@ private val versionDescriptions: List<VersionDescription> = listOf( titleId = MR.strings.v5_2_more_things, descrId = MR.strings.v5_2_more_things_descr ) - ), - ) + ) + ), + VersionDescription( + version = "v5.3", + post = "https://simplex.chat/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.html", + features = listOf( + FeatureDescription( + icon = MR.images.ic_desktop, + titleId = MR.strings.v5_3_new_desktop_app, + descrId = MR.strings.v5_3_new_desktop_app_descr, + link = "https://simplex.chat/downloads/" + ), + FeatureDescription( + icon = MR.images.ic_lock, + titleId = MR.strings.v5_3_encrypt_local_files, + descrId = MR.strings.v5_3_encrypt_local_files_descr + ), + FeatureDescription( + icon = MR.images.ic_search, + titleId = MR.strings.v5_3_discover_join_groups, + descrId = MR.strings.v5_3_discover_join_groups_descr, + link = "simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion" + ), + FeatureDescription( + icon = MR.images.ic_theater_comedy, + titleId = MR.strings.v5_3_simpler_incognito_mode, + descrId = MR.strings.v5_3_simpler_incognito_mode_descr + ), + FeatureDescription( + icon = MR.images.ic_translate, + titleId = MR.strings.v5_3_new_interface_languages, + descrId = MR.strings.v5_3_new_interface_languages_descr, + link = "https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat" + ) + ) + ), ) private val lastVersion = versionDescriptions.last().version diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt index ce09ee661c..eedf604a7f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt @@ -164,9 +164,10 @@ fun AdvancedNetworkSettingsView(chatModel: ChatModel) { ) } SectionItemView { + // can't be higher than 130ms to avoid overflow on 32bit systems TimeoutSettingRow( stringResource(MR.strings.network_option_protocol_timeout_per_kb), networkTCPTimeoutPerKb, - listOf(10_000, 20_000, 40_000, 75_000, 100_000), secondsLabel + listOf(15_000, 30_000, 60_000, 90_000, 120_000), secondsLabel ) } SectionItemView { diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml index 3c39d8f803..65767087be 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <string name="accept_contact_button">اقبل</string> - <string name="about_simplex_chat">عن ٍSimpleX </string> + <string name="about_simplex_chat">عن SimpleX Chat</string> <string name="a_plus_b">a + b</string> <string name="accept">اقبل</string> <string name="chat_item_ttl_week">اسبوع 1</string> @@ -10,7 +10,7 @@ <string name="chat_item_ttl_day">يوم 1</string> <string name="accept_feature">اقبل</string> <string name="about_simplex">عن SimpleX</string> - <string name="above_then_preposition_continuation">أعلاه ، ثم:</string> + <string name="above_then_preposition_continuation">أعلاه، ثم:</string> <string name="accept_call_on_lock_screen">اقبل</string> <string name="delete_chat_profile_action_cannot_be_undone_warning">لا يمكن التراجع عن هذا الإجراء - سيتم فقد ملف التعريف وجهات الاتصال والرسائل والملفات الخاصة بك بشكل نهائي.</string> <string name="alert_message_no_group">هذه المجموعة لم تعد موجودة.</string> @@ -114,7 +114,7 @@ <string name="v4_5_transport_isolation_descr">عن طريق ملف تعريف الدردشة (افتراضي) أو عن طريق الاتصال (تجريبي).</string> <string name="it_can_disabled_via_settings_notifications_still_shown"><![CDATA[<b> يمكن تعطيله عبر الإعدادات</b> - سيستمر عرض الإشعارات أثناء تشغيل التطبيق.]]></string> <string name="settings_audio_video_calls">مكالمات الصوت والفيديو</string> - <string name="impossible_to_recover_passphrase"><![CDATA[<b> الرجاء ملاحظة </b>: لن تتمكن من استعادة عبارة المرور أو تغييرها في حالة فقدها.]]></string> + <string name="impossible_to_recover_passphrase"><![CDATA[<b>يُرجى الملاحظة</b>: لن تتمكن من استعادة عبارة المرور أو تغييرها في حالة فقدها.]]></string> <string name="both_you_and_your_contacts_can_delete">يمكنك أنت وجهة اتصالك حذف الرسائل المرسلة بشكل لا رجعة فيه.</string> <string name="v4_2_auto_accept_contact_requests">قبول طلبات الاتصال تلقائيًا</string> <string name="la_auth_failed">فشلت المصادقة</string> @@ -584,7 +584,7 @@ <string name="large_file">الملف كبير!</string> <string name="learn_more">معرفة المزيد</string> <string name="v4_3_irreversible_message_deletion">حذف رسالة لا رجعة فيه</string> - <string name="v4_4_live_messages">رسائل مباشرة</string> + <string name="v4_4_live_messages">رسائل حيّة</string> <string name="smp_servers_invalid_address">عنوان الخادم غير صالح!</string> <string name="invalid_migration_confirmation">تأكيد الترحيل غير صالح</string> <string name="group_member_status_invited">مدعو</string> @@ -794,7 +794,8 @@ <string name="videos_limit_desc">يمكن إرسال 10 فيديوهات فقط في نفس الوقت</string> <string name="add_contact">رابط دعوة لمرة واحدة</string> <string name="network_use_onion_hosts_no">لا</string> - <string name="network_use_onion_hosts_required_desc">سوف تكون مضيفات البصل مطلوبة للاتصال.</string> + <string name="network_use_onion_hosts_required_desc">سوف تكون مضيفات البصل مطلوبة للاتصال. +\nيُرجى ملاحظة: أنك لن تتمكن من الاتصال بالخوادم بدون عنوان onion.</string> <string name="network_use_onion_hosts_prefer_desc_in_alert">سيتم استخدام مضيفات البصل عند توفرها.</string> <string name="network_use_onion_hosts_no_desc_in_alert">لن يتم استخدام مضيفات البصل.</string> <string name="self_destruct_new_display_name">اسم عرض جديد:</string> @@ -881,7 +882,7 @@ <string name="restore_database_alert_title">استعادة النسخة الاحتياطية لقاعدة البيانات؟</string> <string name="network_options_save">حفظ</string> <string name="users_delete_with_connections">اتصالات الملف الشخصي والخادم</string> - <string name="prohibit_message_reactions">منع ردود فعل الرسائل.</string> + <string name="prohibit_message_reactions">منع ردود فعل الرسالة.</string> <string name="prohibit_sending_voice">منع إرسال الرسائل الصوتية.</string> <string name="prohibit_message_reactions_group">منع ردود فعل الرسائل.</string> <string name="whats_new_read_more">قراءة المزيد</string> @@ -1084,7 +1085,7 @@ <string name="notifications_mode_periodic">يبدأ بشكل دوري</string> <string name="stop_file__confirm">إيقاف</string> <string name="stop_file__action">إيقاف الملف</string> - <string name="stop_snd_file__title">التوقف عن استلام الملف؟</string> + <string name="stop_snd_file__title">التوقف عن إرسال الملف؟</string> <string name="icon_descr_address">عنوان SimpleX</string> <string name="disable_onion_hosts_when_not_supported"><![CDATA[اضبط <i>استخدم مضيفي .onion</i> إلى \"لا\" إذا كان وكيل SOCKS لا يدعمها.]]></string> <string name="share_with_contacts">مشاركة مع جهات الاتصال</string> @@ -1374,4 +1375,28 @@ <string name="privacy_show_last_messages">إظهار الرسائل الأخيرة</string> <string name="rcv_group_event_n_members_connected">%s، %s و %d أعضاء آخرين متصلون</string> <string name="rcv_group_event_3_members_connected">%s، %s و %s متصل</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">سيتم تشفير قاعدة البيانات وتخزين عبارة المرور في الإعدادات.</string> + <string name="you_can_change_it_later">يُخزين عبارة المرور العشوائية في الإعدادات كنص عادي. +\nيمكنك تغييره لاحقا.</string> + <string name="database_encryption_will_be_updated_in_settings">سيتم تحديث عبارة مرور تشفير قاعدة البيانات وتخزينها في الإعدادات.</string> + <string name="remove_passphrase_from_settings">هل تريد إزالة عبارة المرور من الإعدادات؟</string> + <string name="use_random_passphrase">استخدم عبارة مرور عشوائية</string> + <string name="save_passphrase_in_settings">حفظ عبارة المرور في الإعدادات</string> + <string name="setup_database_passphrase">إعداد كلمة المرور لقاعدة البيانات</string> + <string name="set_database_passphrase">تعيين عبارة مرور قاعدة البيانات</string> + <string name="open_database_folder">افتح مجلد قاعدة البيانات</string> + <string name="passphrase_will_be_saved_in_settings">سيتم تخزين عبارة المرور في الإعدادات كنص عادي بعد تغييرها أو إعادة تشغيل التطبيق.</string> + <string name="settings_is_storing_in_clear_text">يُخزين عبارة المرور في الإعدادات كنص عادي.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>يُرجى الملاحظة</b>: يتم توصيل مرحلات الرسائل والملفات عبر وكيل SOCKS. تستخدم المكالمات وإرسال معاينات الارتباط الاتصال المباشر.]]></string> + <string name="encrypt_local_files">تشفير الملفات المحلية</string> + <string name="v5_3_encrypt_local_files">تشفير الملفات والوسائط المخزنة</string> + <string name="v5_3_new_desktop_app">تطبيق سطح المكتب الجديد!</string> + <string name="v5_3_new_interface_languages">6 لغات واجهة جديدة</string> + <string name="v5_3_encrypt_local_files_descr">يقوم التطبيق بتشفير الملفات المحلية الجديدة (باستثناء مقاطع الفيديو).</string> + <string name="v5_3_discover_join_groups">اكتشاف والانضمام إلى المجموعات</string> + <string name="v5_3_new_interface_languages_descr">العربية والبلغارية والفنلندية والعبرية والتايلاندية والأوكرانية - شكرًا للمستخدمين و Weblate.</string> + <string name="v5_3_new_desktop_app_descr">إنشاء ملف تعريف جديد في تطبيق سطح المكتب. 💻</string> + <string name="v5_3_discover_join_groups_descr">- الاتصال بخدمة الدليل (تجريبي)! +\n- إيصالات التسليم (ما يصل إلى 20 عضوا). +\n- أسرع وأكثر استقرارًا.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 8e035420d5..ab0d943f33 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -272,6 +272,7 @@ <string name="this_text_is_available_in_settings">This text is available in settings</string> <string name="your_chats">Chats</string> <string name="contact_connection_pending">connecting…</string> + <string name="member_contact_send_direct_message">send direct message</string> <string name="group_preview_you_are_invited">you are invited to group</string> <string name="group_preview_join_as">join as %s</string> <string name="group_connection_pending">connecting…</string> @@ -304,6 +305,7 @@ <string name="observer_cant_send_message_desc">Please contact group admin.</string> <string name="files_and_media_prohibited">Files and media prohibited!</string> <string name="only_owners_can_enable_files_and_media">Only group owners can enable files and media.</string> + <string name="compose_send_direct_message_to_connect">Send direct message to connect</string> <!-- Images - chat.simplex.app.views.chat.item.CIImageView.kt --> <string name="image_descr">Image</string> @@ -1114,6 +1116,7 @@ <string name="rcv_group_event_group_deleted">deleted group</string> <string name="rcv_group_event_updated_group_profile">updated group profile</string> <string name="rcv_group_event_invited_via_your_group_link">invited via your group link</string> + <string name="rcv_group_event_member_created_contact">connected directly</string> <string name="snd_group_event_changed_member_role">you changed role of %s to %s</string> <string name="snd_group_event_changed_role_for_yourself">you changed role for yourself to %s</string> <string name="snd_group_event_member_deleted">you removed %1$s</string> @@ -1124,6 +1127,8 @@ <string name="rcv_group_event_3_members_connected">%s, %s and %s connected</string> <string name="rcv_group_event_n_members_connected">%s, %s and %d other members connected</string> + <string name="rcv_group_event_open_chat">Open</string> + <!-- Conn event chat items --> <string name="rcv_conn_event_switch_queue_phase_completed">changed address for you</string> <string name="rcv_conn_event_switch_queue_phase_changing">changing address…</string> @@ -1201,6 +1206,8 @@ <string name="error_creating_link_for_group">Error creating group link</string> <string name="error_updating_link_for_group">Error updating group link</string> <string name="error_deleting_link_for_group">Error deleting group link</string> + <string name="error_creating_member_contact">Error creating member contact</string> + <string name="error_sending_message_contact_invitation">Sending message contact invitation</string> <string name="only_group_owners_can_change_prefs">Only group owners can change group preferences.</string> <string name="address_section_title">Address</string> <string name="share_address">Share address</string> @@ -1552,6 +1559,16 @@ <string name="v5_2_disappear_one_message_descr">Even when disabled in the conversation.</string> <string name="v5_2_more_things">A few more things</string> <string name="v5_2_more_things_descr">- more stable message delivery.\n- a bit better groups.\n- and more!</string> + <string name="v5_3_new_desktop_app">New desktop app!</string> + <string name="v5_3_new_desktop_app_descr">Create new profile in desktop app. 💻</string> + <string name="v5_3_encrypt_local_files">Encrypt stored files & media</string> + <string name="v5_3_encrypt_local_files_descr">App encrypts new local files (except videos).</string> + <string name="v5_3_discover_join_groups">Discover and join groups</string> + <string name="v5_3_discover_join_groups_descr">- connect to directory service (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable.</string> + <string name="v5_3_simpler_incognito_mode">Simplified incognito mode</string> + <string name="v5_3_simpler_incognito_mode_descr">Toggle incognito when connecting.</string> + <string name="v5_3_new_interface_languages">6 new interface languages</string> + <string name="v5_3_new_interface_languages_descr">Arabic, Bulgarian, Finnish, Hebrew, Thai and Ukrainian - thanks to the users and Weblate.</string> <!-- CustomTimePicker --> <string name="custom_time_unit_seconds">seconds</string> diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml index 692e729c38..39b7bceee7 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml @@ -19,7 +19,7 @@ <string name="add_address_to_your_profile">Добавете адрес към вашия профил, така че вашите контакти да могат да го споделят с други хора. Актуализацията на профила ще бъде изпратена до вашите контакти.</string> <string name="color_secondary_variant">Допълнителен вторичен</string> <string name="users_add">Добави профил</string> - <string name="one_time_link_short">1-кратен линк</string> + <string name="one_time_link_short">Еднократен линк</string> <string name="chat_item_ttl_week">1 седмица</string> <string name="send_disappearing_message_5_minutes">5 минути</string> <string name="integrity_msg_skipped">%1$d пропуснато(и) съобщение(я)</string> @@ -62,7 +62,7 @@ <string name="cannot_access_keychain">Не може да се осъществи достъп до Keystore, за да се запази паролата на базата данни</string> <string name="cannot_receive_file">Файлът не може да бъде получен</string> <string name="alert_title_cant_invite_contacts">Не може да поканят контактите!</string> - <string name="settings_notification_preview_title">Визуализация на известието</string> + <string name="settings_notification_preview_title">Визуализация на известията</string> <string name="notification_preview_mode_message">Текст на съобщението</string> <string name="notification_preview_new_message">ново съобщение</string> <string name="group_welcome_preview">Визуализация</string> @@ -177,7 +177,7 @@ <string name="app_passcode_replaced_with_self_destruct">Кода за достъп до приложение се заменя с код за самоунищожение.</string> <string name="auto_accept_images">Автоматично приемане на изображения</string> <string name="authentication_cancelled">Идентификацията е отменена</string> - <string name="send_link_previews">Изпрати визуализация на линка</string> + <string name="send_link_previews">Изпрати визуализация на линковете</string> <string name="settings_section_title_calls">ОБАЖДАНИЯ</string> <string name="keychain_allows_to_receive_ntfs">Android Keystore ще се използва за сигурно съхраняване на паролата, след като рестартирате приложението или промените паролата - това ще позволи получаването на известия.</string> <string name="change_database_passphrase_question">Промяна на паролата на базата данни\?</string> @@ -327,14 +327,14 @@ <string name="share_text_database_id">ID в базата данни: %d</string> <string name="receipts_section_contacts">Контакти</string> <string name="settings_section_title_themes">ТЕМИ</string> - <string name="set_password_to_export_desc">Базата данни е криптирана с произволна парола. Моля, променете я преди експортиране.</string> + <string name="set_password_to_export_desc">Базата данни е криптирана с автоматично генерирана парола. Моля, променете я преди експортиране.</string> <string name="database_passphrase">Парола за базата данни</string> <string name="delete_database">Изтрий базата данни</string> <string name="delete_chat_profile_question">Изтриване на чат профила\?</string> <string name="delete_files_and_media_question">Изтрий файлове и медия\?</string> <string name="current_passphrase">Текуща парола…</string> <string name="database_encrypted">Базата данни е криптирана!</string> - <string name="encrypted_with_random_passphrase">Базата данни е криптирана с произволна парола, можете да я промените.</string> + <string name="encrypted_with_random_passphrase">Базата данни е криптирана с автоматично генерирана парола, можете да я промените.</string> <string name="database_encryption_will_be_updated">Паролата за крптиране на базата данни ще бъде актуализирана и съхранена в Keystore.</string> <string name="database_will_be_encrypted_and_passphrase_stored">Базата данни ще бъде криптирана и паролата ще бъде съхранена в Keystore.</string> <string name="database_passphrase_will_be_updated">Паролата за криптиране на базата данни ще бъде актуализирана.</string> @@ -752,7 +752,7 @@ <string name="user_unhide">Покажи</string> <string name="you_can_hide_or_mute_user_profile">Можете да скриете или заглушите потребителски профил - задръжте върху него за менюто.</string> <string name="incognito">Инкогнито</string> - <string name="incognito_info_protects">Режимът инкогнито защитава вашата поверителност, като използва нов произволен профил за всеки контакт.</string> + <string name="incognito_info_protects">Режимът инкогнито защитава вашата поверителност, като използва нов автоматично генериран профил за всеки контакт.</string> <string name="incognito_info_allows">Позволява да имате много анонимни връзки без споделени данни между тях в един чат профил .</string> <string name="v4_5_italian_interface">Италиански интерфейс</string> <string name="description_via_contact_address_link_incognito">инкогнито чрез линк с адрес за контакт</string> @@ -808,7 +808,8 @@ <string name="network_use_onion_hosts_no_desc_in_alert">Няма се използват Onion хостове.</string> <string name="network_use_onion_hosts_required">Задължително</string> <string name="network_use_onion_hosts_no">Не</string> - <string name="network_use_onion_hosts_required_desc">За свързване ще са необходими Onion хостове.</string> + <string name="network_use_onion_hosts_required_desc">За свързване ще са необходими Onion хостове. +\nМоля, обърнете внимание: няма да можете да се свържете със сървърите без .onion адрес.</string> <string name="network_use_onion_hosts_prefer_desc">Ще се използват Onion хостове, когато са налични.</string> <string name="network_use_onion_hosts_prefer_desc_in_alert">Ще се използват Onion хостове, когато са налични.</string> <string name="network_use_onion_hosts_no_desc">Няма се използват Onion хостове.</string> @@ -928,7 +929,7 @@ <string name="button_remove_member">Острани член</string> <string name="member_role_will_be_changed_with_notification">Ролята ще бъде променена на \"%s\". Всички в групата ще бъдат уведомени.</string> <string name="users_delete_data_only">Само данни за локален профил</string> - <string name="users_delete_with_connections">Profile and server connections</string> + <string name="users_delete_with_connections">Профилни и сървърни връзки</string> <string name="user_mute">Без звук</string> <string name="make_profile_private">Направи профила поверителен!</string> <string name="muted_when_inactive">Без звук при неактивност!</string> @@ -1032,7 +1033,7 @@ <string name="save_auto_accept_settings">Запази настройките за автоматично приемане</string> <string name="save_settings_question">Запази настройките\?</string> <string name="save_profile_password">Запази паролата на профила</string> - <string name="stop_chat_question">Спри чат\?</string> + <string name="stop_chat_question">Спри чата\?</string> <string name="set_password_to_export">Задай парола за експортиране</string> <string name="stop_chat_confirmation">Спри</string> <string name="stop_chat_to_export_import_or_delete_chat_database">Спрете чата, за да експортирате, импортирате или изтриете чат базата данни. Няма да можете да получавате и изпращате съобщения, докато чатът е спрян.</string> @@ -1057,7 +1058,7 @@ <string name="smp_servers">SMP сървъри</string> <string name="share_address_with_contacts_question">Сподели адреса с контактите\?</string> <string name="share_link">Сподели линк</string> - <string name="share_with_contacts">Сподели с контакти</string> + <string name="share_with_contacts">Сподели с контактите</string> <string name="stop_sharing">Спри споделянето</string> <string name="stop_sharing_address">Спри споделянето на адреса\?</string> <string name="settings_section_title_settings">НАСТРОЙКИ</string> @@ -1137,7 +1138,7 @@ <string name="search_verb">Търсене</string> <string name="sent_message">Изпратено съобщение</string> <string name="share_verb">Сподели</string> - <string name="auth_stop_chat">Спри чат</string> + <string name="auth_stop_chat">Спри чата</string> <string name="reveal_verb">Покажи</string> <string name="stop_file__action">Спри файл</string> <string name="icon_descr_settings">Настройки</string> @@ -1146,7 +1147,7 @@ <string name="show_dev_options">Покажи:</string> <string name="core_simplexmq_version">simplexmq: v%s (%2s)</string> <string name="save_and_notify_contact">Запази и уведоми контакта</string> - <string name="save_and_notify_group_members">Запази и уведоми контактите</string> + <string name="save_and_notify_group_members">Запази и уведоми членовете на групата</string> <string name="save_preferences_question">Запази настройките\?</string> <string name="icon_descr_speaker_on">Високоговорителят е включен</string> <string name="icon_descr_speaker_off">Високоговорителят е изключен</string> @@ -1287,14 +1288,14 @@ <string name="wrong_passphrase_title">Грешна парола!</string> <string name="voice_messages">Гласови съобщения</string> <string name="your_preferences">Вашите настройки</string> - <string name="whats_new">Какво е ново</string> + <string name="whats_new">Какво е новото</string> <string name="v4_3_irreversible_message_deletion_desc">Вашите контакти могат да позволят пълното изтриване на съобщението.</string> <string name="update_database_passphrase">Актуализирай паролата на базата данни</string> <string name="snd_group_event_changed_role_for_yourself">променихте ролята си на %s</string> <string name="snd_group_event_user_left">вие напуснахте</string> <string name="snd_group_event_changed_member_role">променихте ролята на %s на %s</string> <string name="snd_group_event_member_deleted">премахнахте %1$s</string> - <string name="incognito_random_profile">Вашият случаен профил</string> + <string name="incognito_random_profile">Вашият автоматично генериран профил</string> <string name="user_unmute">Уведомявай</string> <string name="you_can_share_your_address">Можете да споделите адреса си като линк или QR код - всеки може да се свърже с вас.</string> <string name="snd_conn_event_switch_queue_phase_completed_for_member">променихте адреса за %s</string> @@ -1354,7 +1355,7 @@ <string name="connect_via_link_incognito">Свързване инкогнито</string> <string name="turn_off_system_restriction_button">Отвори настройките на приложението</string> <string name="turn_off_battery_optimization_button">Позволи</string> - <string name="connect__a_new_random_profile_will_be_shared">Нов произволен профил ще бъде споделен.</string> + <string name="connect__a_new_random_profile_will_be_shared">Нов автоматично генериран профил ще бъде споделен.</string> <string name="disable_notifications_button">Деактивирай известията</string> <string name="system_restricted_background_in_call_title">Без фонови разговори</string> <string name="connect_via_member_address_alert_title">Свързване директно\?</string> @@ -1372,5 +1373,31 @@ <string name="rcv_group_event_n_members_connected">%s, %s и %d други членове са свързани</string> <string name="rcv_group_event_3_members_connected">%s, %s и %s са свързани</string> <string name="privacy_message_draft">Чернова на съобщение</string> - <string name="privacy_show_last_messages">Показване на последните съобщения</string> + <string name="privacy_show_last_messages">Показване на последните съобщения в листа с чатовете</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Базата данни ще бъде криптирана и паролата ще бъде съхранена в настройките.</string> + <string name="you_can_change_it_later">Автоматично генерирана парола се съхранява в настройките като обикновен текст. +\nМожете да я промените по-късно.</string> + <string name="database_encryption_will_be_updated_in_settings">Паролата за криптиране на базата данни ще бъде актуализирана и съхранена в настройките.</string> + <string name="remove_passphrase_from_settings">Премахване на паролата от настройките\?</string> + <string name="use_random_passphrase">Използвай автоматично генерирана парола</string> + <string name="save_passphrase_in_settings">Запази паролата в настройките</string> + <string name="setup_database_passphrase">Задай парола за базата данни</string> + <string name="set_database_passphrase">Задай парола за базата данни</string> + <string name="open_database_folder">Отвори папката за база данни</string> + <string name="passphrase_will_be_saved_in_settings">Паролата ще бъде съхранена в настройките като обикновен текст, след като я промените или рестартирате приложението.</string> + <string name="settings_is_storing_in_clear_text">Паролата се съхранява в настройките като обикновен текст.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Моля, обърнете внимание</b>: релетата за съобщения и файлове са свързани чрез SOCKS прокси. Обажданията и изпращането на визуализации на линкове използват директна връзка.]]></string> + <string name="encrypt_local_files">Криптиране на локални файлове</string> + <string name="v5_3_encrypt_local_files">Криптиране на съхранените файлове и медия</string> + <string name="v5_3_new_desktop_app">Ново настолно приложение!</string> + <string name="v5_3_new_interface_languages">6 нови езика на интерфейса</string> + <string name="v5_3_encrypt_local_files_descr">Приложението криптира нови локални файлове (с изключение на видеоклипове).</string> + <string name="v5_3_discover_join_groups">Открийте и се присъединете към групи</string> + <string name="v5_3_simpler_incognito_mode">Опростен режим инкогнито</string> + <string name="v5_3_new_interface_languages_descr">Арабски, български, финландски, иврит, тайландски и украински - благодарение на потребителите и Weblate.</string> + <string name="v5_3_new_desktop_app_descr">Създайте нов профил в настолното приложение. 💻</string> + <string name="v5_3_simpler_incognito_mode_descr">Избор на инкогнито при свързване.</string> + <string name="v5_3_discover_join_groups_descr">- свържете се с директория за услуги (БЕТА)! +\n- потвърждениe за доставка (до 20 члена). +\n- по-бързо и по-стабилно.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml index 4b4bac96de..2afdb7a690 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml @@ -1072,14 +1072,14 @@ <string name="enable_lock">Povolit zámek</string> <string name="lock_after">Zamknout po</string> <string name="lock_mode">Režim zámku</string> - <string name="authentication_cancelled">Ověření zrušeno</string> + <string name="authentication_cancelled">Autentizace zrušena</string> <string name="confirm_passcode">Potvrdit heslo</string> <string name="incorrect_passcode">Nesprávné heslo</string> <string name="new_passcode">Nové heslo</string> <string name="submit_passcode">Odeslat</string> <string name="la_mode_system">Systém</string> <string name="change_lock_mode">Změnit zamykání</string> - <string name="la_mode_passcode">Heslo</string> + <string name="la_mode_passcode">Přístupový kód</string> <string name="passcode_changed">Heslo změněno!</string> <string name="passcode_not_changed">Heslo nezměněno!</string> <string name="passcode_set">Heslo nastaveno!</string> @@ -1376,4 +1376,18 @@ <string name="privacy_show_last_messages">Zobrazit poslední zprávy</string> <string name="send_receipts_disabled_alert_msg">Tato skupina má více než %1$d členů, doručenky nejsou odeslány.</string> <string name="in_developing_desc">Tato funkce zatím není podporována. Vyzkoušejte další vydání.</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Databáze bude zašifrována a heslo bude uloženo v klíčence.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Všimněte si prosím</b>: zprávy a relé souborů jsou spojeny prostřednictvím proxy SOCKS. Volání a odesílání náhledů odkazů pomocí přímého připojení.]]></string> + <string name="encrypt_local_files">Šifrovat místní soubory</string> + <string name="you_can_change_it_later">Náhodné heslo je uloženo v nastavení jako prostý text. +\nMůžete jej změnit později.</string> + <string name="database_encryption_will_be_updated_in_settings">Heslo pro šifrování databáze bude aktualizováno a uloženo v klíčence.</string> + <string name="remove_passphrase_from_settings">Odebrat heslo z nastavení\?</string> + <string name="use_random_passphrase">Použít náhodné heslo</string> + <string name="save_passphrase_in_settings">Uložit heslo v nastavení</string> + <string name="setup_database_passphrase">Nastavení hesla databáze</string> + <string name="set_database_passphrase">Nastavit heslo databáze</string> + <string name="open_database_folder">Otevřete složku databáze</string> + <string name="passphrase_will_be_saved_in_settings">Heslo bude uloženo v nastavení jako prostý text až jej změníte nebo po restartu aplikace.</string> + <string name="settings_is_storing_in_clear_text">Heslo je uloženo v nastavení jako prostý text.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml index 6c3f7d0644..6fad3dc0ac 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml @@ -405,7 +405,8 @@ <string name="network_use_onion_hosts_required">Erforderlich</string> <string name="network_use_onion_hosts_prefer_desc">Onion-Hosts werden verwendet, wenn sie verfügbar sind.</string> <string name="network_use_onion_hosts_no_desc">Onion-Hosts werden nicht verwendet.</string> - <string name="network_use_onion_hosts_required_desc">Für die Verbindung werden Onion-Hosts benötigt.</string> + <string name="network_use_onion_hosts_required_desc">Für die Verbindung werden Onion-Hosts benötigt. +\nBitte beachten Sie: Ohne .onion-Adresse können Sie keine Verbindung mit den Servern herstellen.</string> <string name="network_use_onion_hosts_prefer_desc_in_alert">Onion-Hosts werden verwendet, wenn sie verfügbar sind.</string> <string name="network_use_onion_hosts_no_desc_in_alert">Onion-Hosts werden nicht verwendet.</string> <string name="network_use_onion_hosts_required_desc_in_alert">Für die Verbindung werden Onion-Hosts benötigt.</string> @@ -1457,4 +1458,18 @@ <string name="rcv_group_event_3_members_connected">%s, %s und %s wurden verbunden</string> <string name="privacy_message_draft">Nachrichtenentwurf</string> <string name="privacy_show_last_messages">Letzte Nachrichten anzeigen</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Die Datenbank wird verschlüsselt und das Passwort in den Einstellungen gespeichert.</string> + <string name="you_can_change_it_later">Das zufällige Passwort wird in Klartext in den Einstellungen gespeichert. +\nSie können es später ändern.</string> + <string name="database_encryption_will_be_updated_in_settings">Das Passwort für die Datenbankverschlüsselung wird aktualisiert und in den Einstellungen gespeichert.</string> + <string name="remove_passphrase_from_settings">Passwort aus den Einstellungen entfernen\?</string> + <string name="use_random_passphrase">Zufälliges Passwort verwenden</string> + <string name="save_passphrase_in_settings">Passwort in den Einstellungen sichern</string> + <string name="setup_database_passphrase">Datenbank-Passwort einrichten</string> + <string name="set_database_passphrase">Datenbank-Passwort festlegen</string> + <string name="open_database_folder">Datenbank-Ordner öffnen</string> + <string name="passphrase_will_be_saved_in_settings">Das Passwort wird in Klartext in den Einstellungen gespeichert, nachdem Sie es geändert oder die App neu gestartet haben.</string> + <string name="settings_is_storing_in_clear_text">Das Passwort wurde in Klartext in den Einstellungen gespeichert.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Bitte beachten Sie</b>: Die Nachrichten- und Dateirelais sind per SOCKS Proxy verbunden. Anrufe und gesendete Link-Vorschaubilder nutzen eine direkte Verbindung.]]></string> + <string name="encrypt_local_files">Lokale Dateien verschlüsseln</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml index dffad174fc..7b2aa4e685 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml @@ -1306,7 +1306,7 @@ <string name="sending_delivery_receipts_will_be_enabled_all_profiles">El envío de confirmaciones de entrega se activará para todos los contactos en todos los perfiles visibles.</string> <string name="receipts_section_contacts">Contactos</string> <string name="delivery_receipts_title">¡Confirmación de entrega!</string> - <string name="receipts_contacts_disable_keep_overrides">Desactivar (conservar anulaciones)</string> + <string name="receipts_contacts_disable_keep_overrides">Desactivar (conservando anulaciones)</string> <string name="v5_2_favourites_filter">Encontrar chats mas rápido</string> <string name="v5_2_disappear_one_message">Escribir un mensaje temporal</string> <string name="receipts_contacts_override_disabled">El envío de confirmaciones está desactivado para %d contactos</string> @@ -1351,7 +1351,7 @@ <string name="recipient_colon_delivery_status">%s: %s</string> <string name="send_receipts_disabled">desactivado</string> <string name="receipts_groups_disable_for_all">Desactivado para todos los grupos</string> - <string name="receipts_groups_disable_keep_overrides">Desactivar (conservar anulaciones de grupo)</string> + <string name="receipts_groups_disable_keep_overrides">Desactivar (conservando anulaciones de grupo)</string> <string name="receipts_groups_title_disable">¿Desactivar confirmaciones para grupos\?</string> <string name="receipts_groups_enable_keep_overrides">Activar (conservar anulaciones de grupo)</string> <string name="send_receipts_disabled_alert_title">Confirmaciones desactivadas</string> @@ -1377,4 +1377,16 @@ <string name="rcv_group_event_3_members_connected">%s, %s y %s conectados</string> <string name="rcv_group_event_2_members_connected">%s y %s conectados</string> <string name="privacy_message_draft">Borrador de mensaje</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">La base de datos será cifrada y la contraseña se guardará en Configuración</string> + <string name="you_can_change_it_later">La contraseña aleatoria se almacenará en Configuración como texto plano. +\nPuedes cambiarlo más tarde.</string> + <string name="database_encryption_will_be_updated_in_settings">La contraseña para el cifrado de la base de datos se actualizará y almacenará en Configuración</string> + <string name="remove_passphrase_from_settings">Eliminar contraseña de configuración\?</string> + <string name="use_random_passphrase">Usar contraseña aleatoria</string> + <string name="save_passphrase_in_settings">Guardar contraseña en configuración</string> + <string name="setup_database_passphrase">Configuración contraseña base de datos</string> + <string name="set_database_passphrase">Escribe una contraseña para la base de datos</string> + <string name="open_database_folder">Abrir carpeta base de datos</string> + <string name="passphrase_will_be_saved_in_settings">La contraseña se almacenará en configuración como texto plano después de cambiarla o reiniciar la aplicación.</string> + <string name="settings_is_storing_in_clear_text">La contraseña está almacenada en configuración como texto plano.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml index cee4837a75..b0280d84ae 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml @@ -872,7 +872,8 @@ <string name="network_use_onion_hosts_prefer_desc">Onion-isäntiä käytetään, kun niitä on saatavilla.</string> <string name="network_use_onion_hosts_no_desc">Onion-isäntiä ei käytetä.</string> <string name="network_use_onion_hosts_required">Pakollinen</string> - <string name="network_use_onion_hosts_required_desc">Yhteyden muodostamiseen tarvitaan Onion-isäntiä.</string> + <string name="network_use_onion_hosts_required_desc">Yhteyden muodostamiseen tarvitaan Onion-isäntiä. +\nHuomioi: et voi muodostaa yhteyttä palvelimiin ilman .onion-osoitetta.</string> <string name="callstate_received_answer">vastaus saatu…</string> <string name="icon_descr_call_rejected">Hylätty puhelu</string> <string name="v4_6_chinese_spanish_interface_descr">Kiitos käyttäjille – osallistu Weblaten kautta!</string> @@ -1374,4 +1375,18 @@ <string name="v5_2_message_delivery_receipts_descr">Toinen kuittaus, joka uupui! ✅</string> <string name="error_synchronizing_connection">Virhe yhteyden synkronoinnissa</string> <string name="no_history">Ei historiaa</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Tietokanta salataan ja tunnuslause tallennetaan asetuksiin.</string> + <string name="you_can_change_it_later">Satunnainen tunnuslause on tallennettu asetuksiin selkokielisenä. +\nVoit muuttaa sen myöhemmin.</string> + <string name="database_encryption_will_be_updated_in_settings">Tietokannan salaustunnuslause päivitetään ja tallennetaan asetuksiin.</string> + <string name="remove_passphrase_from_settings">Poista tunnuslause asetuksista\?</string> + <string name="use_random_passphrase">Käytä satunnaista tunnuslausetta</string> + <string name="save_passphrase_in_settings">Tallenna tunnuslause asetuksiin</string> + <string name="setup_database_passphrase">Aseta tietokannan tunnuslause</string> + <string name="set_database_passphrase">Aseta tietokannan tunnuslause</string> + <string name="open_database_folder">Avaa tietokantakansio</string> + <string name="passphrase_will_be_saved_in_settings">Tunnuslause tallennetaan asetuksiin selkokielisenä sen jälkeen, kun olet vaihtanut sen tai käynnistänyt sovelluksen uudelleen.</string> + <string name="settings_is_storing_in_clear_text">Tunnuslause on tallennettu asetuksiin selkokielisenä.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b> Huomioi </b>: Viesti- ja tiedostovälittimet yhdistetään SOCKS-proxyn kautta. Puhelut ja linkin esikatselut käyttävät suoraa yhteyttä.]]></string> + <string name="encrypt_local_files">Salaa paikalliset tiedostot</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml index 1611b413f0..9ac692cf70 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml @@ -253,7 +253,7 @@ <string name="icon_descr_server_status_pending">En attente</string> <string name="accept_connection_request__question">Accepter la demande de connexion \?</string> <string name="clear_verb">Effacer</string> - <string name="clear_chat_button">Effacer la conversation</string> + <string name="clear_chat_button">Effacer le chat</string> <string name="connect_via_link">Se connecter via un lien</string> <string name="clear_verification">Retirer la vérification</string> <string name="one_time_link">Lien d\'invitation unique</string> @@ -421,7 +421,8 @@ <string name="update_onion_hosts_settings_question">Mettre à jour le paramètre des hôtes .onion \?</string> <string name="network_use_onion_hosts_prefer">Quand disponible</string> <string name="network_use_onion_hosts_no_desc">Les hôtes .onion ne seront pas utilisés.</string> - <string name="network_use_onion_hosts_required_desc">Les hôtes .onion seront nécessaires pour la connexion.</string> + <string name="network_use_onion_hosts_required_desc">Les hôtes .onion seront nécessaires pour la connexion. +\nAttention : vous ne pourrez pas vous connecter aux serveurs sans adresse .onion.</string> <string name="network_use_onion_hosts_no_desc_in_alert">Les hôtes .onion ne seront pas utilisés.</string> <string name="delete_address__question">Supprimer l\'adresse \?</string> <string name="all_your_contacts_will_remain_connected">Tous vos contacts resteront connectés.</string> @@ -1376,4 +1377,30 @@ <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> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">La base de données sera chiffrée et la phrase de passe sera stockée dans les paramètres.</string> + <string name="you_can_change_it_later">La phrase secrète aléatoire est stockée en clair dans les paramètres. +\nVous pouvez la modifier ultérieurement.</string> + <string name="database_encryption_will_be_updated_in_settings">La phrase de chiffrement de la base de données sera mise à jour et stockée dans les paramètres.</string> + <string name="remove_passphrase_from_settings">Supprimer la phrase secrète des paramètres \?</string> + <string name="use_random_passphrase">Utiliser une phrase secrète aléatoire</string> + <string name="save_passphrase_in_settings">Enregistrer la phrase secrète dans les paramètres</string> + <string name="setup_database_passphrase">Configurer la phrase secrète de la base de données</string> + <string name="set_database_passphrase">Définir la phrase secrète de la base de données</string> + <string name="open_database_folder">Ouvrir le dossier de la base de données</string> + <string name="passphrase_will_be_saved_in_settings">La phrase secrète sera stockée en clair dans les paramètres après que vous la modifiez ou que vous redémarrez l\'application.</string> + <string name="settings_is_storing_in_clear_text">La phrase secrète est stockée en clair dans les paramètres.</string> + <string name="v5_3_encrypt_local_files">Chiffrement des fichiers et des médias stockés</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Remarque</b> : Les relais de messages et de fichiers sont connectés par le biais d\'un proxy SOCKS. Les appels et l\'envoi d\'aperçus de liens utilisent une connexion directe.]]></string> + <string name="encrypt_local_files">Chiffrer les fichiers locaux</string> + <string name="v5_3_new_desktop_app">Nouvelle application de bureau !</string> + <string name="v5_3_new_interface_languages">6 nouvelles langues d\'interface</string> + <string name="v5_3_encrypt_local_files_descr">L\'application chiffre les nouveaux fichiers locaux (sauf les vidéos).</string> + <string name="v5_3_discover_join_groups">Découvrir et rejoindre des groupes</string> + <string name="v5_3_simpler_incognito_mode">Mode incognito simplifié</string> + <string name="v5_3_new_interface_languages_descr">Arabe, bulgare, finnois, hébreu, thaï et ukrainien - grâce aux utilisateurs et à Weblate.</string> + <string name="v5_3_new_desktop_app_descr">Créer un nouveau profil sur l\'application de bureau. 💻</string> + <string name="v5_3_simpler_incognito_mode_descr">Basculer en mode incognito lors de la connexion.</string> + <string name="v5_3_discover_join_groups_descr">- connexion au service d\'annuaire (BETA) ! +\n- accusés de réception (jusqu\'à 20 membres). +\n- plus rapide et plus stable.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_desktop.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_desktop.svg new file mode 100644 index 0000000000..e9c30f5199 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_desktop.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M422.5-182v-99.5h-280q-22.969 0-40.234-17.266Q85-316.031 85-339v-439q0-22.969 17.266-40.234Q119.531-835.5 142.5-835.5h675q22.969 0 40.234 17.266Q875-800.969 875-778v439q0 22.969-17.266 40.234Q840.469-281.5 817.5-281.5h-280v99.5h57q11.675 0 20.088 8.463Q623-165.074 623-153.325q0 12.325-8.412 20.575-8.413 8.25-20.088 8.25H366q-12.25 0-20.625-8.425-8.375-8.426-8.375-20.5 0-12.075 8.375-20.325T366-182h56.5Zm-280-157h675v-439h-675v439Zm0 0v-439 439Z"/></svg> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml index 4822f235bb..846cd931a2 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml @@ -612,7 +612,8 @@ <string name="network_and_servers">Rete e server</string> <string name="network_settings_title">Impostazioni di rete</string> <string name="network_use_onion_hosts_no">No</string> - <string name="network_use_onion_hosts_required_desc">Gli host Onion saranno necessari per la connessione.</string> + <string name="network_use_onion_hosts_required_desc">Gli host Onion saranno necessari per la connessione. +\nNota bene: non potrai connetterti ai server senza indirizzo .onion .</string> <string name="network_use_onion_hosts_required_desc_in_alert">Gli host Onion saranno necessari per la connessione.</string> <string name="network_use_onion_hosts_prefer_desc">Gli host Onion verranno usati quando disponibili.</string> <string name="network_use_onion_hosts_prefer_desc_in_alert">Gli host Onion verranno usati quando disponibili.</string> @@ -1376,4 +1377,30 @@ <string name="rcv_group_event_3_members_connected">%s, %s e %s sono connessi/e</string> <string name="privacy_message_draft">Bozza</string> <string name="privacy_show_last_messages">Mostra gli ultimi messaggi</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Il database verrà crittografato e la password conservata nelle impostazioni.</string> + <string name="you_can_change_it_later">La password casuale viene conservata nelle impostazioni come testo normale. +\nPuoi cambiarla dopo.</string> + <string name="database_encryption_will_be_updated_in_settings">La password di crittografia del database verrà aggiornata e conservata nelle impostazioni.</string> + <string name="remove_passphrase_from_settings">Rimuovere la password dalle impostazioni\?</string> + <string name="use_random_passphrase">Usa password casuale</string> + <string name="save_passphrase_in_settings">Salva password nelle impostazioni</string> + <string name="setup_database_passphrase">Configura password del database</string> + <string name="set_database_passphrase">Imposta password del database</string> + <string name="open_database_folder">Apri cartella del database</string> + <string name="passphrase_will_be_saved_in_settings">La password verrà conservata nelle impostazioni come testo normale dopo averla cambiata o il riavvio dell\'app.</string> + <string name="settings_is_storing_in_clear_text">La password viene conservata nelle impostazioni come testo normale.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Nota bene</b>: i relay di messaggi e file sono connessi via proxy SOCKS. Le chiamate e l\'invio di anteprime dei link usano una connessione diretta.]]></string> + <string name="encrypt_local_files">Cripta i file locali</string> + <string name="v5_3_encrypt_local_files">Crittografia di file e media memorizzati</string> + <string name="v5_3_new_desktop_app">Nuova app desktop!</string> + <string name="v5_3_new_interface_languages">6 nuove lingue dell\'interfaccia</string> + <string name="v5_3_encrypt_local_files_descr">L\'app cripta i nuovi file locali (eccetto i video).</string> + <string name="v5_3_discover_join_groups">Scopri ed unisciti ai gruppi</string> + <string name="v5_3_simpler_incognito_mode">Modalità incognito semplificata</string> + <string name="v5_3_new_interface_languages_descr">Arabo, bulgaro, finlandese, ebraico, tailandese e ucraino - grazie agli utenti e a Weblate.</string> + <string name="v5_3_new_desktop_app_descr">Crea un nuovo profilo nell\'app desktop. 💻</string> + <string name="v5_3_simpler_incognito_mode_descr">Attiva/disattiva l\'incognito quando ti colleghi.</string> + <string name="v5_3_discover_join_groups_descr">- connessione al servizio directory (BETA)! +\n- ricevute di consegna (fino a 20 membri). +\n- più veloce e più stabile.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml index b82f10b255..8b955ceb8f 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml @@ -530,7 +530,8 @@ <string name="how_to_use_simplex_chat">使い方</string> <string name="markdown_help">マークダウン (書式編集) ガイド</string> <string name="smp_servers_enter_manually">サーバを手動で入力</string> - <string name="network_use_onion_hosts_required_desc">接続にオニオンのホストが必要となります。</string> + <string name="network_use_onion_hosts_required_desc">接続にオニオンのホストが必要となります。 +\n注意: .onion アドレスがないとサーバーに接続できません。</string> <string name="create_address">アドレスを作成</string> <string name="delete_address__question">アドレスを削除しますか?</string> <string name="display_name__field">表示の名前:</string> @@ -1376,4 +1377,18 @@ <string name="send_receipts_disabled_alert_msg">This group has over %1$d members, delivery receipts are not sent.</string> <string name="error_enabling_delivery_receipts">Error enabling delivery receipts!</string> <string name="delivery_receipts_are_disabled">Delivery receipts are disabled!</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">データベースは暗号化され、パスフレーズは設定に保存されます。</string> + <string name="you_can_change_it_later">ランダムなパスフレーズは設定に平文として保存されます。 +\n後で変更できます。</string> + <string name="database_encryption_will_be_updated_in_settings">データベースの暗号化パスフレーズが更新され、設定に保存されます。</string> + <string name="remove_passphrase_from_settings">設定からパスフレーズを削除しますか?</string> + <string name="use_random_passphrase">ランダムなパスフレーズを使用する</string> + <string name="save_passphrase_in_settings">パスフレーズを設定に保存します</string> + <string name="setup_database_passphrase">データベースのパスフレーズを設定する</string> + <string name="set_database_passphrase">データベースのパスフレーズを設定する</string> + <string name="open_database_folder">データベースフォルダを開く</string> + <string name="passphrase_will_be_saved_in_settings">パスフレーズを変更するかアプリを再起動すると、平文として設定に保存されます。</string> + <string name="settings_is_storing_in_clear_text">パスフレーズは平文として設定に保存されます。</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>注意</b>: メッセージとファイルのリレーは SOCKS プロキシ経由で接続されます。 通話とリンク プレビューの送信には直接接続が使用されます。]]></string> + <string name="encrypt_local_files">ローカルファイルを暗号化する</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml index e69ad19fb0..aaa79b9a71 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml @@ -59,14 +59,14 @@ <string name="v4_2_auto_accept_contact_requests">Contact verzoeken automatisch accepteren</string> <string name="bold_text">vetgedrukt</string> <string name="attach">Bijvoegen</string> - <string name="allow_irreversible_message_deletion_only_if">Sta het onomkeerbaar verwijderen van berichten alleen toe als uw contactpersoon dit toestaat.</string> + <string name="allow_irreversible_message_deletion_only_if">Sta het onomkeerbaar verwijderen van berichten alleen toe als uw contact dit toestaat.</string> <string name="allow_to_send_disappearing">Sta toe om verdwijnende berichten te verzenden.</string> <string name="allow_your_contacts_to_send_voice_messages">Sta toe dat uw contacten spraak berichten verzenden.</string> <string name="all_your_contacts_will_remain_connected">Al uw contacten blijven verbonden.</string> <string name="allow_voice_messages_question">Spraak berichten toestaan\?</string> <string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Goed voor de batterij</b>. Achtergrondservice controleert berichten elke 10 minuten. Mogelijk mist u oproepen of dringende berichten.]]></string> <string name="integrity_msg_bad_hash">Onjuiste bericht hash</string> - <string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><![CDATA[<b>Scan QR-code</b>: om verbinding te maken met uw contactpersoon die u de QR-code laat zien.]]></string> + <string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><![CDATA[<b>Scan QR-code</b>: om verbinding te maken met uw contact die u de QR-code laat zien.]]></string> <string name="integrity_msg_bad_id">Onjuiste bericht-ID</string> <string name="call_already_ended">Oproep al beëindigd!</string> <string name="chat_item_ttl_month">1 maand</string> @@ -75,8 +75,8 @@ <string name="above_then_preposition_continuation">hier boven, dan:</string> <string name="users_delete_all_chats_deleted">Alle gesprekken en berichten worden verwijderd, dit kan niet ongedaan worden gemaakt!</string> <string name="clear_chat_warning">Alle berichten worden verwijderd, dit kan niet ongedaan worden gemaakt! De berichten worden ALLEEN voor jou verwijderd.</string> - <string name="allow_disappearing_messages_only_if">Sta verdwijnende berichten alleen toe als uw contactpersoon dit toestaat.</string> - <string name="allow_voice_messages_only_if">Sta spraak berichten alleen toe als uw contactpersoon ze toestaat.</string> + <string name="allow_disappearing_messages_only_if">Sta verdwijnende berichten alleen toe als uw contact dit toestaat.</string> + <string name="allow_voice_messages_only_if">Sta spraak berichten alleen toe als uw contact ze toestaat.</string> <string name="allow_your_contacts_irreversibly_delete">Laat uw contacten verzonden berichten onomkeerbaar verwijderen.</string> <string name="allow_your_contacts_to_send_disappearing_messages">Sta toe dat uw contacten verdwijnende berichten verzenden.</string> <string name="chat_preferences_always">altijd</string> @@ -99,9 +99,9 @@ <string name="turning_off_service_and_periodic">Batterijoptimalisatie is actief, waardoor achtergrondservice en periodieke verzoeken om nieuwe berichten worden uitgeschakeld. Je kunt ze weer inschakelen via instellingen.</string> <string name="onboarding_notifications_mode_off_desc"><![CDATA[<b>Het beste voor de batterij</b>. U ontvangt alleen meldingen wanneer de app wordt uitgevoerd (GEEN achtergrondservice).]]></string> <string name="it_can_disabled_via_settings_notifications_still_shown"><![CDATA[<b>Het kan worden uitgeschakeld via instellingen</b>, meldingen worden nog steeds weergegeven terwijl de app actief is.]]></string> - <string name="both_you_and_your_contacts_can_delete">Zowel jij als je contactpersoon kunnen verzonden berichten onherroepelijk verwijderen.</string> - <string name="both_you_and_your_contact_can_send_disappearing">Zowel jij als je contactpersoon kunnen verdwijnende berichten sturen.</string> - <string name="both_you_and_your_contact_can_send_voice">Zowel jij als je contactpersoon kunnen spraak berichten verzenden.</string> + <string name="both_you_and_your_contacts_can_delete">Zowel jij als je contact kunnen verzonden berichten onherroepelijk verwijderen.</string> + <string name="both_you_and_your_contact_can_send_disappearing">Zowel jij als je contact kunnen verdwijnende berichten sturen.</string> + <string name="both_you_and_your_contact_can_send_voice">Zowel jij als je contact kunnen spraak berichten verzenden.</string> <string name="impossible_to_recover_passphrase"><![CDATA[<b>Let op</b>: u kunt het wachtwoord NIET herstellen of wijzigen als u het kwijt raakt.]]></string> <string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Gebruikt meer batterij</b>! Achtergrondservice wordt altijd uitgevoerd - meldingen worden weergegeven zodra berichten beschikbaar zijn.]]></string> <string name="icon_descr_cancel_link_preview">link voorbeeld annuleren</string> @@ -374,7 +374,7 @@ <string name="delete_group_for_self_cannot_undo_warning">De groep wordt voor u verwijderd, dit kan niet ongedaan worden gemaakt!</string> <string name="hide_notification">Verbergen</string> <string name="server_error">fout</string> - <string name="file_will_be_received_when_contact_is_online">Het bestand wordt ontvangen wanneer uw contact persoon online is, even geduld a.u.b. of controleer later!</string> + <string name="file_will_be_received_when_contact_is_online">Het bestand wordt ontvangen wanneer uw contact online is, even geduld a.u.b. of controleer later!</string> <string name="error_saving_file">Fout bij opslaan van bestand</string> <string name="file_not_found">Bestand niet gevonden</string> <string name="file_saved">Bestand opgeslagen</string> @@ -420,7 +420,7 @@ <string name="mark_read">Markeer gelezen</string> <string name="mark_unread">Markeer als ongelezen</string> <string name="mute_chat">Dempen</string> - <string name="if_you_cannot_meet_in_person_scan_QR_in_video_call_or_ask_for_invitation_link"><![CDATA[Als u elkaar niet persoonlijk kunt ontmoeten, kunt u <b> de QR-code scannen in het video gesprek </b>, of uw contactpersoon kan een uitnodiging link delen.]]></string> + <string name="if_you_cannot_meet_in_person_scan_QR_in_video_call_or_ask_for_invitation_link"><![CDATA[Als u elkaar niet persoonlijk kunt ontmoeten, kunt u <b> de QR-code scannen in het video gesprek </b>, of uw contact kan een uitnodiging link delen.]]></string> <string name="if_you_cannot_meet_in_person_show_QR_in_video_call_or_via_another_channel"><![CDATA[Als je elkaar niet persoonlijk kunt ontmoeten, <b>toon je de QR-code in het video gesprek</b> of deel je de link.]]></string> <string name="invalid_QR_code">Ongeldige QR-code</string> <string name="icon_descr_more_button">Meer</string> @@ -479,7 +479,7 @@ <string name="group_preview_join_as">lid worden als %s</string> <string name="alert_text_skipped_messages_it_can_happen_when">Het kan gebeuren wanneer: \n1. De berichten zijn na 2 dagen verlopen bij de verzendende client of na 30 dagen op de server. -\n2. Decodering van het bericht is mislukt, omdat u of uw contactpersoon een oude databaseback-up heeft gebruikt. +\n2. Decodering van het bericht is mislukt, omdat u of uw contact een oude databaseback-up heeft gebruikt. \n3. De verbinding is verbroken.</string> <string name="joining_group">Deel nemen aan groep</string> <string name="leave_group_button">Verlaten</string> @@ -527,7 +527,7 @@ <string name="rcv_group_event_invited_via_your_group_link">uitgenodigd via je groep link</string> <string name="incognito">Incognito</string> <string name="icon_descr_call_missed">Gemiste oproep</string> - <string name="description_via_contact_address_link_incognito">incognito via contact adres link</string> + <string name="description_via_contact_address_link_incognito">incognito via contactadres link</string> <string name="description_via_group_link_incognito">incognito via groep link</string> <string name="description_via_one_time_link_incognito">incognito via eenmalige link</string> <string name="invalid_chat">ongeldige gesprek</string> @@ -537,7 +537,7 @@ <string name="live">LIVE</string> <string name="ensure_smp_server_address_are_correct_format_and_unique">Zorg ervoor dat SMP server adressen de juiste indeling hebben, regel gescheiden zijn en niet gedupliceerd zijn.</string> <string name="marked_deleted_description">gemarkeerd als verwijderd</string> - <string name="please_check_correct_link_and_maybe_ask_for_a_new_one">Controleer of u de juiste link heeft gebruikt of vraag uw contactpersoon om u een andere te sturen.</string> + <string name="please_check_correct_link_and_maybe_ask_for_a_new_one">Controleer of u de juiste link heeft gebruikt of vraag uw contact om u een andere te sturen.</string> <string name="image_descr_profile_image">profielfoto</string> <string name="privacy_redefined">Privacy opnieuw gedefinieerd</string> <string name="privacy_and_security">Privacy en beveiliging</string> @@ -563,8 +563,8 @@ <string name="chat_preferences_off">uit</string> <string name="chat_preferences_on">aan</string> <string name="only_you_can_send_disappearing">Alleen jij kunt verdwijnende berichten verzenden.</string> - <string name="only_your_contact_can_send_disappearing">Alleen uw contactpersoon kan verdwijnende berichten verzenden.</string> - <string name="only_you_can_delete_messages">Alleen jij kunt berichten onomkeerbaar verwijderen (je contactpersoon kan ze markeren voor verwijdering).</string> + <string name="only_your_contact_can_send_disappearing">Alleen uw contact kan verdwijnende berichten verzenden.</string> + <string name="only_you_can_delete_messages">Alleen jij kunt berichten onomkeerbaar verwijderen (je contact kan ze markeren voor verwijdering).</string> <string name="feature_offered_item_with_param">voorgesteld %s: %2s</string> <string name="old_database_archive">Oud database archief</string> <string name="enter_correct_current_passphrase">Voer het juiste huidige wachtwoord in.</string> @@ -584,7 +584,7 @@ <string name="periodic_notifications_disabled">Periodieke meldingen zijn uitgeschakeld!</string> <string name="icon_descr_server_status_pending">In behandeling</string> <string name="only_group_owners_can_enable_voice">Alleen groep eigenaren kunnen spraak berichten inschakelen.</string> - <string name="ask_your_contact_to_enable_voice">Vraag uw contactpersoon om het verzenden van spraak berichten in te schakelen.</string> + <string name="ask_your_contact_to_enable_voice">Vraag uw contact om het verzenden van spraak berichten in te schakelen.</string> <string name="ok">OK</string> <string name="network_use_onion_hosts_required_desc">Onion hosts zijn vereist voor verbinding.</string> <string name="network_use_onion_hosts_prefer_desc">Onion hosts worden gebruikt indien beschikbaar.</string> @@ -592,9 +592,9 @@ <string name="network_use_onion_hosts_no_desc">Onion hosts worden niet gebruikt.</string> <string name="opensource_protocol_and_code_anybody_can_run_servers">Open-source protocol en code. Iedereen kan de servers draaien.</string> <string name="people_can_connect_only_via_links_you_share">Mensen kunnen alleen verbinding met u maken via de links die u deelt.</string> - <string name="only_your_contact_can_delete">Alleen uw contactpersoon kan berichten onherroepelijk verwijderen (u kunt ze markeren voor verwijdering).</string> + <string name="only_your_contact_can_delete">Alleen uw contact kan berichten onherroepelijk verwijderen (u kunt ze markeren voor verwijdering).</string> <string name="only_you_can_send_voice">Alleen jij kunt spraak berichten verzenden.</string> - <string name="only_your_contact_can_send_voice">Alleen uw contactpersoon kan spraak berichten verzenden.</string> + <string name="only_your_contact_can_send_voice">Alleen uw contact kan spraak berichten verzenden.</string> <string name="prohibit_message_deletion">Verbied het onomkeerbaar verwijderen van berichten.</string> <string name="feature_offered_item">voorgesteld %s</string> <string name="store_passphrase_securely_without_recover">Sla het wachtwoord veilig op. Als u deze kwijtraakt, heeft u GEEN toegang tot de gesprekken.</string> @@ -641,7 +641,7 @@ <string name="simplex_service_notification_title">SimpleX Chat service</string> <string name="simplex_service_notification_text">Berichten ontvangen…</string> <string name="notification_preview_mode_message_desc">Toon contact en bericht</string> - <string name="notification_preview_mode_contact_desc">Toon alleen contactpersoon</string> + <string name="notification_preview_mode_contact_desc">Toon alleen contact</string> <string name="ntf_channel_messages">SimpleX Chat berichten</string> <string name="auth_simplex_lock_turned_on">SimpleX Vergrendelen ingeschakeld</string> <string name="auth_stop_chat">Stop chat</string> @@ -674,28 +674,28 @@ <string name="connect_via_link_or_qr_from_clipboard_or_in_person">(scannen of plakken vanaf klembord)</string> <string name="to_connect_via_link_title">Om verbinding te maken via een link</string> <string name="reject_contact_button">Afwijzen</string> - <string name="set_contact_name">Naam contactpersoon instellen</string> + <string name="set_contact_name">Naam contact instellen</string> <string name="connection_you_accepted_will_be_cancelled">De door u geaccepteerde verbinding wordt geannuleerd!</string> <string name="contact_you_shared_link_with_wont_be_able_to_connect">Het contact met wie je deze link hebt gedeeld kan GEEN verbinding maken!</string> <string name="you_accepted_connection">Je hebt de verbinding geaccepteerd</string> - <string name="you_invited_a_contact">Je hebt je contactpersoon uitgenodigd</string> - <string name="alert_text_connection_pending_they_need_to_be_online_can_delete_and_retry">Uw contactpersoon moet online zijn om de verbinding te voltooien. -\nU kunt deze verbinding verbreken en het contact verwijderen (en later proberen met een nieuwe link).</string> + <string name="you_invited_a_contact">Je hebt je contact uitgenodigd</string> + <string name="alert_text_connection_pending_they_need_to_be_online_can_delete_and_retry">Uw contact moet online zijn om de verbinding te voltooien. +\nU kunt deze verbinding verbreken en het contact verwijderen en later proberen met een nieuwe link.</string> <string name="image_descr_qr_code">QR code</string> <string name="icon_descr_settings">Instellingen</string> <string name="contact_wants_to_connect_with_you">wil met je in contact komen!</string> <string name="icon_descr_address">SimpleX Adres</string> <string name="show_QR_code">Toon QR-code</string> <string name="image_descr_simplex_logo">SimpleX-Logo</string> - <string name="your_chat_profile_will_be_sent_to_your_contact">Je chat profiel wordt verzonden naar uw contactpersoon</string> + <string name="your_chat_profile_will_be_sent_to_your_contact">Je chat profiel wordt verzonden naar uw contact</string> <string name="you_will_be_connected_when_group_host_device_is_online">Je wordt verbonden met de groep wanneer het apparaat van de groep host online is, even geduld a.u.b. of controleer het later!</string> <string name="you_will_be_connected_when_your_connection_request_is_accepted">U wordt verbonden wanneer uw verbindingsverzoek wordt geaccepteerd, even geduld a.u.b. of controleer later!</string> <string name="you_will_be_connected_when_your_contacts_device_is_online">Je wordt verbonden wanneer het apparaat van je contact online is, even geduld a.u.b. of controleer het later!</string> - <string name="scan_code_from_contacts_app">Scan de beveiligingscode van de app van uw contactpersoon.</string> + <string name="scan_code_from_contacts_app">Scan de beveiligingscode van de app van uw contact.</string> <string name="security_code">Beveiligingscode</string> <string name="is_not_verified">%s is niet geverifieerd</string> <string name="is_verified">%s is geverifieerd</string> - <string name="to_verify_compare">Vergelijk (of scan) de code op uw apparaten om end-to-end codering met uw contactpersoon te verifiëren.</string> + <string name="to_verify_compare">Vergelijk (of scan) de code op uw apparaten om end-to-end codering met uw contact te verifiëren.</string> <string name="you_can_also_connect_by_clicking_the_link"><![CDATA[U kunt ook verbinding maken door op de link te klikken. Als het in de browser wordt geopend, klikt u op de knop <b> Openen in mobiele app </b>.]]></string> <string name="your_chat_profiles">Uw chat profielen</string> <string name="your_simplex_contact_address">Uw SimpleX adres</string> @@ -907,8 +907,8 @@ <string name="chat_preferences_you_allow">Jij staat toe</string> <string name="you_are_invited_to_group">Je bent uitgenodigd voor de groep</string> <string name="you_can_connect_to_simplex_chat_founder"><![CDATA[U kunt <font color="#0088ff">verbinding maken met SimpleX Chat ontwikkelaars om vragen te stellen en updates te ontvangen</font>.]]></string> - <string name="connection_error_auth_desc">Tenzij uw contactpersoon de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft. -\nOm verbinding te maken, vraagt u uw contactpersoon om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft.</string> + <string name="connection_error_auth_desc">Tenzij uw contact de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft. +\nOm verbinding te maken, vraagt u uw contact om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft.</string> <string name="update_onion_hosts_settings_question">.onion hosts-instelling updaten\?</string> <string name="use_simplex_chat_servers__question">SimpleX Chat servers gebruiken\?</string> <string name="voice_messages_are_prohibited">Spraak berichten zijn verboden in deze groep.</string> @@ -916,7 +916,7 @@ <string name="you_can_start_chat_via_setting_or_by_restarting_the_app">U kunt de chat starten via app Instellingen / Database of door de app opnieuw op te starten.</string> <string name="snd_conn_event_switch_queue_phase_completed_for_member">je hebt het adres gewijzigd voor %s</string> <string name="snd_group_event_member_deleted">je hebt %1$s verwijderd</string> - <string name="contact_sent_large_file">Je contactpersoon heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%1$s).</string> + <string name="contact_sent_large_file">Je contact heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%1$s).</string> <string name="your_current_chat_database_will_be_deleted_and_replaced_with_the_imported_one">Uw huidige chatdatabase wordt VERWIJDERD en VERVANGEN door de geïmporteerde. \nDeze actie kan niet ongedaan worden gemaakt. Uw profiel, contacten, berichten en bestanden gaan onomkeerbaar verloren.</string> <string name="invite_prohibited_description">Je probeert een contact met wie je een incognito profiel hebt gedeeld uit te nodigen voor de groep waarin je je hoofdprofiel gebruikt</string> @@ -937,7 +937,7 @@ <string name="trying_to_connect_to_server_to_receive_messages_with_error">Er wordt geprobeerd verbinding te maken met de server die wordt gebruikt om berichten van dit contact te ontvangen (fout: %1$s).</string> <string name="unknown_message_format">onbekend berichtformaat</string> <string name="simplex_link_mode_browser">Via browser</string> - <string name="description_via_contact_address_link">via contact adres link</string> + <string name="description_via_contact_address_link">via contactadres link</string> <string name="description_via_group_link">via groep link</string> <string name="description_via_one_time_link">via een eenmalige link</string> <string name="simplex_link_connection">via %1$s</string> @@ -1014,8 +1014,8 @@ <string name="confirm_database_upgrades">Bevestig database upgrades</string> <string name="mtr_error_no_down_migration">database versie is nieuwer dan de app, maar geen down migratie voor: %s</string> <string name="incompatible_database_version">Incompatibele database versie</string> - <string name="file_will_be_received_when_contact_completes_uploading">Het bestand wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid.</string> - <string name="image_will_be_received_when_contact_completes_uploading">De afbeelding wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid.</string> + <string name="file_will_be_received_when_contact_completes_uploading">Het bestand wordt gedownload wanneer uw contact het uploaden heeft voltooid.</string> + <string name="image_will_be_received_when_contact_completes_uploading">De afbeelding wordt gedownload wanneer uw contact het uploaden heeft voltooid.</string> <string name="show_dev_options">Toon:</string> <string name="developer_options">Database-ID\'s en Transport isolatie optie.</string> <string name="hide_dev_options">Verbergen:</string> @@ -1034,7 +1034,7 @@ <string name="icon_descr_waiting_for_video">Wachten op video</string> <string name="waiting_for_video">Wachten op video</string> <string name="video_descr">Video</string> - <string name="video_will_be_received_when_contact_completes_uploading">De video wordt gedownload wanneer uw contactpersoon het uploaden heeft voltooid.</string> + <string name="video_will_be_received_when_contact_completes_uploading">De video wordt gedownload wanneer uw contact het uploaden heeft voltooid.</string> <string name="error_saving_xftp_servers">Fout bij opslaan van XFTP-servers</string> <string name="error_loading_xftp_servers">Fout bij het laden van XFTP servers</string> <string name="error_xftp_test_server_auth">Server vereist autorisatie om te uploaden, wachtwoord controleren</string> @@ -1104,10 +1104,10 @@ <string name="stop_snd_file__title">Bestand verzenden stoppen\?</string> <string name="only_your_contact_can_make_calls">Alleen je contact kan bellen.</string> <string name="revoke_file__message">Het bestand wordt van de servers verwijderd.</string> - <string name="both_you_and_your_contact_can_make_calls">Zowel u als uw contact persoon kunnen bellen.</string> + <string name="both_you_and_your_contact_can_make_calls">Zowel u als uw contact kunnen bellen.</string> <string name="only_you_can_make_calls">Alleen jij kunt bellen.</string> <string name="stop_snd_file__message">Het verzenden van het bestand wordt gestopt.</string> - <string name="allow_calls_only_if">Sta oproepen alleen toe als uw contact persoon dit toestaat.</string> + <string name="allow_calls_only_if">Sta oproepen alleen toe als uw contact dit toestaat.</string> <string name="allow_your_contacts_to_call">Sta toe dat uw contacten u bellen.</string> <string name="audio_video_calls">Audio/video oproepen</string> <string name="available_in_v51">" @@ -1123,7 +1123,7 @@ <string name="auth_open_chat_profiles">Chat profielen openen</string> <string name="learn_more_about_address">Over SimpleX adres</string> <string name="learn_more">Kom meer te weten</string> - <string name="scan_qr_to_connect_to_contact">Om verbinding te maken, kan uw contact persoon de QR-code scannen of de link in de app gebruiken.</string> + <string name="scan_qr_to_connect_to_contact">Om verbinding te maken, kan uw contact de QR-code scannen of de link in de app gebruiken.</string> <string name="customize_theme_title">Thema aanpassen</string> <string name="group_welcome_preview">Voorbeeld</string> <string name="you_can_share_this_address_with_your_contacts">U kunt dit adres delen met uw contacten om ze verbinding te laten maken met %s.</string> @@ -1196,14 +1196,14 @@ <string name="only_you_can_add_message_reactions">Alleen jij kunt berichtreacties toevoegen.</string> <string name="message_reactions_are_prohibited">Reacties op berichten zijn verboden in deze groep.</string> <string name="prohibit_message_reactions_group">Berichten reacties verbieden.</string> - <string name="allow_message_reactions_only_if">Sta berichtreacties alleen toe als uw contactpersoon dit toestaat.</string> + <string name="allow_message_reactions_only_if">Sta berichtreacties alleen toe als uw contact dit toestaat.</string> <string name="allow_your_contacts_adding_message_reactions">Sta uw contactpersonen toe om berichtreacties toe te voegen.</string> <string name="allow_message_reactions">Sta berichtreacties toe.</string> <string name="group_members_can_add_message_reactions">Groepsleden kunnen berichtreacties toevoegen.</string> - <string name="both_you_and_your_contact_can_add_message_reactions">Zowel u als uw contactpersoon kunnen berichtreacties toevoegen.</string> + <string name="both_you_and_your_contact_can_add_message_reactions">Zowel u als uw contact kunnen berichtreacties toevoegen.</string> <string name="message_reactions">Reacties op berichten</string> <string name="message_reactions_prohibited_in_this_chat">Reacties op berichten zijn verboden in deze chat.</string> - <string name="only_your_contact_can_add_message_reactions">Alleen uw contactpersoon kan berichtreacties toevoegen.</string> + <string name="only_your_contact_can_add_message_reactions">Alleen uw contact kan berichtreacties toevoegen.</string> <string name="custom_time_unit_days">dagen</string> <string name="custom_time_unit_hours">uren</string> <string name="custom_time_unit_minutes">minuten</string> @@ -1375,4 +1375,30 @@ <string name="privacy_show_last_messages">Laat laatste berichten zien</string> <string name="rcv_group_event_3_members_connected">%s, %s en %s verbonden</string> <string name="rcv_group_event_2_members_connected">%s en %s verbonden</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">De database wordt versleuteld en het wachtwoord wordt opgeslagen in de instellingen.</string> + <string name="you_can_change_it_later">Willekeurig wachtwoord wordt in de instellingen opgeslagen als platte tekst. +\nJe kunt het later wijzigen.</string> + <string name="database_encryption_will_be_updated_in_settings">Het wachtwoord voor database versleuteling wordt bijgewerkt en opgeslagen in de instellingen.</string> + <string name="remove_passphrase_from_settings">Wachtwoord uit instellingen verwijderen\?</string> + <string name="use_random_passphrase">Gebruik een willekeurig wachtwoord</string> + <string name="save_passphrase_in_settings">Bewaar het wachtwoord in de instellingen</string> + <string name="setup_database_passphrase">Database wachtwoord instellen</string> + <string name="set_database_passphrase">Database wachtwoord instellen</string> + <string name="open_database_folder">Database map openen</string> + <string name="passphrase_will_be_saved_in_settings">Het wachtwoord wordt als platte tekst in de instellingen opgeslagen nadat u deze hebt gewijzigd of de app opnieuw hebt opgestart.</string> + <string name="settings_is_storing_in_clear_text">Het wachtwoord wordt als leesbare tekst in de instellingen opgeslagen.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Let op</b>: bericht en bestands relais zijn verbonden via SOCKS-proxy. Voor oproepen en het verzenden van link voorbeelden wordt gebruik gemaakt van een directe verbinding.]]></string> + <string name="encrypt_local_files">Versleutel lokale bestanden</string> + <string name="v5_3_encrypt_local_files">Versleutel opgeslagen bestanden en media</string> + <string name="v5_3_new_desktop_app">Nieuwe desktop app!</string> + <string name="v5_3_new_interface_languages">6 nieuwe interfacetalen</string> + <string name="v5_3_encrypt_local_files_descr">App versleutelt nieuwe lokale bestanden (behalve video\'s)</string> + <string name="v5_3_discover_join_groups">Ontdek en sluit je aan bij groepen</string> + <string name="v5_3_simpler_incognito_mode">Vereenvoudigde incognitomodus</string> + <string name="v5_3_new_interface_languages_descr">Arabisch, Bulgaars, Fins, Hebreeuws, Thais en Oekraïens - dankzij de gebruikers en Weblate.</string> + <string name="v5_3_new_desktop_app_descr">Maak een nieuw profiel in de desktop-app. 💻</string> + <string name="v5_3_simpler_incognito_mode_descr">Schakel incognito in tijdens het verbinden.</string> + <string name="v5_3_discover_join_groups_descr">- maak verbinding met de directoryservice (BETA)! +\n- ontvangst bevestiging (tot 20 leden). +\n- sneller en stabieler.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml index 641dd9b43c..35630919e6 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml @@ -347,7 +347,8 @@ <string name="network_and_servers">Sieć i serwery</string> <string name="network_settings_title">Ustawienia sieci</string> <string name="network_use_onion_hosts_no">Nie</string> - <string name="network_use_onion_hosts_required_desc">Hosty onion będą wymagane do połączenia.</string> + <string name="network_use_onion_hosts_required_desc">Hosty onion będą wymagane do połączenia. +\nUwaga: nie będziesz mógł połączyć się z serwerami bez adresu .onion.</string> <string name="network_use_onion_hosts_required_desc_in_alert">Hosty onion będą wymagane do połączenia.</string> <string name="network_use_onion_hosts_prefer_desc">Hosty onion będą używane, gdy będą dostępne.</string> <string name="network_use_onion_hosts_prefer_desc_in_alert">Hosty onion będą używane, gdy będą dostępne.</string> @@ -1376,4 +1377,30 @@ <string name="rcv_group_event_2_members_connected">%s i %s połączeni</string> <string name="rcv_group_event_n_members_connected">%s, %s i %d innych członków połączeni</string> <string name="rcv_group_event_3_members_connected">%s, %s i %s połączeni</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Baza danych zostanie zaszyfrowana, a hasło zapisane w ustawieniach.</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Uwaga</b>: przekaźniki wiadomości i plików są połączone za pośrednictwem serwera proxy SOCKS. Połączenia i wysyłanie podglądów linków korzystają z połączenia bezpośredniego.]]></string> + <string name="encrypt_local_files">Zaszyfruj lokalne pliki</string> + <string name="you_can_change_it_later">Losowe hasło jest trzymane w ustawieniach w czystym tekście. +\nMożesz zmienić je później.</string> + <string name="database_encryption_will_be_updated_in_settings">Hasło szyfrowania bazy danych zostanie zaktualizowane i zapisane w ustawieniach.</string> + <string name="remove_passphrase_from_settings">Usunąć hasło z ustawień\?</string> + <string name="use_random_passphrase">Użyj losowego hasła</string> + <string name="save_passphrase_in_settings">Zapisz hasło w ustawieniach</string> + <string name="setup_database_passphrase">Ustaw hasło bazy danych</string> + <string name="set_database_passphrase">Ustaw hasło bazy danych</string> + <string name="open_database_folder">Otwórz folder bazy danych</string> + <string name="passphrase_will_be_saved_in_settings">Hasło będzie trzymane w ustawieniach jako czysty tekst po tym jak je zmienisz lub zrestartujesz aplikację.</string> + <string name="settings_is_storing_in_clear_text">Hasło jest trzymane w ustawieniach w czystym tekście.</string> + <string name="v5_3_encrypt_local_files">Szyfruj przechowywane pliki i media</string> + <string name="v5_3_new_desktop_app">Nowa aplikacja desktopowa!</string> + <string name="v5_3_new_interface_languages">6 nowych języków interfejsu</string> + <string name="v5_3_encrypt_local_files_descr">Aplikacja szyfruje nowe lokalne pliki (bez filmów).</string> + <string name="v5_3_discover_join_groups">Odkrywaj i dołączaj do grup</string> + <string name="v5_3_simpler_incognito_mode">Uproszczony tryb incognito</string> + <string name="v5_3_new_interface_languages_descr">Arabski, bułgarski, fiński, hebrajski, tajski i ukraiński - dzięki użytkownikom i Weblate.</string> + <string name="v5_3_new_desktop_app_descr">Utwórz nowy profil w aplikacji desktopowej. 💻</string> + <string name="v5_3_simpler_incognito_mode_descr">Przełącz incognito przy połączeniu.</string> + <string name="v5_3_discover_join_groups_descr">- połącz się z usługą katalogową (BETA)! +\n- potwierdzenia dostaw (do 20 członków). +\n- szybszy i stabilniejszy.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml index 53f17c44a0..d2b4465ec4 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml @@ -343,14 +343,14 @@ <string name="one_time_link">Одноразовая ссылка</string> <!-- settings - SettingsView.kt --> <string name="your_settings">Настройки</string> - <string name="your_simplex_contact_address">Ваш адрес SimpleX</string> - <string name="database_passphrase_and_export">Пароль и экспорт базы</string> + <string name="your_simplex_contact_address">Ваш SimpleX адрес</string> + <string name="database_passphrase_and_export">База данных</string> <string name="about_simplex_chat">Информация о SimpleX Chat</string> <string name="how_to_use_simplex_chat">Как использовать</string> <string name="markdown_help">Форматирование сообщений</string> <string name="markdown_in_messages">Форматирование сообщений</string> - <string name="chat_with_the_founder">Отправьте вопросы и идеи</string> - <string name="send_us_an_email">Отправить email</string> + <string name="chat_with_the_founder">Вопросы и предложения</string> + <string name="send_us_an_email">Написать нам письмо</string> <string name="chat_lock">Блокировка SimpleX</string> <string name="chat_console">Консоль</string> <string name="smp_servers">SMP серверы</string> @@ -403,7 +403,8 @@ <string name="network_use_onion_hosts_required">Обязательно</string> <string name="network_use_onion_hosts_prefer_desc">Onion хосты используются, если возможно.</string> <string name="network_use_onion_hosts_no_desc">Onion хосты не используются.</string> - <string name="network_use_onion_hosts_required_desc">Подключаться только к onion хостам.</string> + <string name="network_use_onion_hosts_required_desc">Подключаться только к onion хостам. +\nОбратите внимание: Вы не сможете соединиться с серверами, у которых нет .onion адреса.</string> <string name="network_use_onion_hosts_prefer_desc_in_alert">Onion хосты используются, если возможно.</string> <string name="network_use_onion_hosts_no_desc_in_alert">Onion хосты не используются.</string> <string name="network_use_onion_hosts_required_desc_in_alert">Подключаться только к onion хостам.</string> @@ -862,11 +863,11 @@ <string name="chat_preferences_always">всегда</string> <string name="chat_preferences_on">да</string> <string name="chat_preferences_off">нет</string> - <string name="chat_preferences">Предпочтения</string> + <string name="chat_preferences">Настройки чатов</string> <string name="contact_preferences">Предпочтения контакта</string> <string name="group_preferences">Предпочтения группы</string> <string name="set_group_preferences">Предпочтения группы</string> - <string name="your_preferences">Ваши предпочтения</string> + <string name="your_preferences">Настройки чатов</string> <string name="direct_messages">Прямые сообщения</string> <string name="full_deletion">Удаление для всех</string> <string name="voice_messages">Голосовые сообщения</string> @@ -958,7 +959,7 @@ <string name="allow_disappearing_messages_only_if">Разрешить исчезающие сообщения, только если Ваш контакт разрешает их Вам.</string> <string name="prohibit_sending_disappearing">Запретить посылать исчезающие сообщения.</string> <string name="group_members_can_send_disappearing">Члены группы могут посылать исчезающие сообщения.</string> - <string name="whats_new">Новые функции</string> + <string name="whats_new">Что нового</string> <string name="new_in_version">Новое в %s</string> <string name="v4_2_security_assessment">Аудит безопасности</string> <string name="v4_2_security_assessment_desc">Безопасность SimpleX Chat была проверена Trail of Bits.</string> @@ -1000,7 +1001,7 @@ <string name="users_delete_data_only">Только локальные данные профиля</string> <string name="messages_section_title">Сообщения</string> <string name="smp_servers_per_user">Серверы для новых соединений Вашего текущего профиля чата</string> - <string name="your_chat_profiles">Ваши профили чата</string> + <string name="your_chat_profiles">Ваши профили</string> <string name="users_delete_all_chats_deleted">Все чаты и сообщения будут удалены - это нельзя отменить!</string> <string name="app_version_code">Сборка приложения: %s</string> <string name="app_version_name">Версия приложения: v%s</string> @@ -1049,7 +1050,7 @@ <string name="smp_save_servers_question">Сохранить серверы\?</string> <string name="should_be_at_least_one_profile">Должен быть хотя бы один профиль пользователя.</string> <string name="should_be_at_least_one_visible_profile">Должен быть хотя бы один открытый профиль пользователя.</string> - <string name="to_reveal_profile_enter_password">Чтобы показать Ваш скрытый профиль, введите пароль в поле поиска на странице Ваши профили чата.</string> + <string name="to_reveal_profile_enter_password">Чтобы показать Ваш скрытый профиль, введите пароль в поле поиска на странице Ваши профили.</string> <string name="user_unmute">Уведомлять</string> <string name="group_welcome_title">Приветственное сообщение</string> <string name="confirm_password">Подтвердить пароль</string> @@ -1082,10 +1083,10 @@ <string name="v4_6_audio_video_calls_descr">Поддержка bluetooth и другие улучшения.</string> <string name="save_welcome_message_question">Сохранить приветственное сообщение\?</string> <string name="v4_6_group_welcome_message_descr">Установить сообщение для новых членов группы!</string> - <string name="tap_to_activate_profile">Нажмите, чтобы сделать профиль активным.</string> - <string name="v4_6_chinese_spanish_interface_descr">Благодаря пользователям – добавьте переводы через Weblate!</string> + <string name="tap_to_activate_profile">Нажмите на профиль, чтобы переключиться на него.</string> + <string name="v4_6_chinese_spanish_interface_descr">Благодаря пользователям - добавьте переводы через Weblate!</string> <string name="you_will_still_receive_calls_and_ntfs">Вы все равно получите звонки и уведомления в профилях без звука, когда они активные.</string> - <string name="you_can_hide_or_mute_user_profile">Вы можете скрыть профиль или выключить уведомления - подержите, чтобы увидеть меню.</string> + <string name="you_can_hide_or_mute_user_profile">Вы можете скрыть или отключить уведомления профиля - нажмите и удерживайте профиль, чтобы открыть меню.</string> <string name="image_will_be_received_when_contact_completes_uploading">Изображение будет принято когда Ваш контакт его загрузит.</string> <string name="file_will_be_received_when_contact_completes_uploading">Файл будет принят когда Ваш контакт загрузит его.</string> <string name="database_upgrade">Обновление базы данных</string> @@ -1362,7 +1363,7 @@ <string name="receipts_section_description">Установки для Вашего активного профиля</string> <string name="receipts_contacts_override_disabled">Отправка отчётов о доставке выключена для %d контактов.</string> <string name="sync_connection_force_desc">Шифрование работает, и новое соглашение не требуется. Это может привести к ошибкам соединения!</string> - <string name="v5_2_message_delivery_receipts_descr">Вторая галочка - знать, что доставлено! ✅</string> + <string name="v5_2_message_delivery_receipts_descr">Вторая галочка, когда сообщение доставлено! ✅</string> <string name="you_can_enable_delivery_receipts_later_alert">Вы можете включить их позже в настройках Конфиденциальности.</string> <string name="error_aborting_address_change">Ошибка при прекращении изменения адреса</string> <string name="abort_switch_receiving_address_confirm">Прекратить</string> @@ -1396,7 +1397,7 @@ <string name="fix_connection_not_supported_by_contact">Починка не поддерживается контактом.</string> <string name="fix_connection_not_supported_by_group_member">Починка не поддерживается членом группы.</string> <string name="renegotiate_encryption">Пересогласовать шифрование</string> - <string name="v5_2_favourites_filter">Быстро найти чаты</string> + <string name="v5_2_favourites_filter">Быстрый поиск чатов</string> <string name="v5_2_message_delivery_receipts">Отчеты о доставке сообщений!</string> <string name="v5_2_more_things">Еще несколько изменений</string> <string name="delivery_receipts_title">Отчёты о доставке!</string> @@ -1458,4 +1459,30 @@ <string name="connect_use_current_profile">Использовать активный профиль</string> <string name="connect_use_new_incognito_profile">Использовать новый Инкогнито профиль</string> <string name="system_restricted_background_in_call_warn"><![CDATA[Чтобы совершать звонки в фоне, выберите <b>Расход батареи приложением</b> / <b>Без ограничений</b> в настройках приложения.]]></string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">База данных будет зашифрована, и пароль сохранен в настройках.</string> + <string name="v5_3_encrypt_local_files">Шифруйте сохраненные файлы и медиа</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>Обратите внимание</b>: соединение с серверами файлов и сообщений устанавливаются через SOCKS прокси. Звонки и картинки ссылок используют прямое соединение.]]></string> + <string name="encrypt_local_files">Шифровать локальные файлы</string> + <string name="v5_3_new_desktop_app">Приложение для компьютера!</string> + <string name="v5_3_new_interface_languages">6 новых языков интерфейса</string> + <string name="v5_3_encrypt_local_files_descr">Приложение шифрует новые локальные файлы (кроме видео).</string> + <string name="you_can_change_it_later">Случайный пароль хранится в настройках как открытый текст. +\nВы можете изменить его позже.</string> + <string name="v5_3_discover_join_groups">Найдите и вступите в группы</string> + <string name="database_encryption_will_be_updated_in_settings">Пароль шифрования базы данных будет обновлён и сохранён в настройках.</string> + <string name="remove_passphrase_from_settings">Удалить пароль из настроек\?</string> + <string name="use_random_passphrase">Использовать случайный пароль</string> + <string name="save_passphrase_in_settings">Сохранить пароль в настройках</string> + <string name="v5_3_simpler_incognito_mode">Упрощенный режим Инкогнито</string> + <string name="setup_database_passphrase">Установить пароль базы данных</string> + <string name="set_database_passphrase">Установить пароль базы данных</string> + <string name="open_database_folder">Открыть директорию базы данных</string> + <string name="v5_3_new_interface_languages_descr">Арабский, болгарский, финский, иврит, тайский и украинский - благодаря пользователям и Weblate.</string> + <string name="v5_3_new_desktop_app_descr">Создайте новый профиль в приложении для компьютера. 💻</string> + <string name="passphrase_will_be_saved_in_settings">Пароль будет сохранён в настройках как простой текст после того, как вы его измените или перезапустите приложение.</string> + <string name="v5_3_simpler_incognito_mode_descr">Установите режим Инкогнито при соединении.</string> + <string name="v5_3_discover_join_groups_descr">- соединиться с каталогом групп (BETA)! +\n- отчеты о доставке (до 20 членов). +\n- быстрее и стабильнее.</string> + <string name="settings_is_storing_in_clear_text">Пароль хранится в настройках, как открытый текст.</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml index 4263633369..bf0fe570cc 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml @@ -67,7 +67,7 @@ <string name="connect_via_group_link">通过群组链接连接?</string> <string name="connect_via_link_or_qr">通过群组链接/二维码连接</string> <string name="always_use_relay">总是通过中继连接</string> - <string name="allow_your_contacts_irreversibly_delete">允许您的联系人不可撤回地删除已发送消息。</string> + <string name="allow_your_contacts_irreversibly_delete">允许您的联系人永久删除已发送消息。</string> <string name="chat_preferences_contact_allows">联系人允许</string> <string name="allow_voice_messages_only_if">仅有您的联系人许可后才允许语音消息。</string> <string name="group_info_member_you">您: %1$s</string> @@ -98,7 +98,7 @@ <string name="app_version_title">应用程序版本</string> <string name="full_backup">应用程序数据备份</string> <string name="settings_section_title_icon">应用程序图标</string> - <string name="app_version_name">应用程序版本:v%s</string> + <string name="app_version_name">应用版本:v%s</string> <string name="notifications_mode_off_desc">应用程序仅在运行时可以接受通知,没有后台服务会被启动</string> <string name="auth_unavailable">身份验证不可用</string> <string name="auto_accept_images">自动接受图像</string> @@ -106,7 +106,7 @@ <string name="icon_descr_audio_call">语音通话</string> <string name="audio_call_no_encryption">语音通话(非端到端加密)</string> <string name="v4_2_auto_accept_contact_requests">自动接受联系人请求</string> - <string name="integrity_msg_bad_hash">错误消息散列</string> + <string name="integrity_msg_bad_hash">消息散列值错误</string> <string name="integrity_msg_bad_id">错误消息 ID</string> <string name="settings_audio_video_calls">语音和视频通话</string> <string name="turning_off_service_and_periodic">启用电池优化,关闭了后台服务和对新消息的定期请求。您可以在设置里重新启用它们。</string> @@ -122,7 +122,7 @@ <string name="onboarding_notifications_mode_off_desc"><![CDATA[<b> 最长续航 </b>。您只会在应用程序运行时收到通知(无后台服务)。]]></string> <string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b> 较长续航 </b>。后台服务每 10 分钟检查一次消息。您可能会错过来电或者紧急信息。]]></string> <string name="bold_text">加粗</string> - <string name="both_you_and_your_contacts_can_delete">您和您的联系人都可以不可逆转地删除已发送的消息。</string> + <string name="both_you_and_your_contacts_can_delete">您和您的联系人都可以永久删除已发送的消息。</string> <string name="both_you_and_your_contact_can_send_disappearing">您和您的联系人都可以发送限时消息。</string> <string name="both_you_and_your_contact_can_send_voice">您和您的联系人都可以发送语音消息。</string> <string name="it_can_disabled_via_settings_notifications_still_shown"><![CDATA[<b> 可以在设置里禁用它 </b> - 应用程序运行时仍会显示通知。]]></string> @@ -190,7 +190,7 @@ <string name="group_invitation_tap_to_join_incognito">点击以加入隐身聊天</string> <string name="group_main_profile_sent">您的聊天资料将被发送给群组成员</string> <string name="invite_prohibited_description">您正在尝试邀请与您共享隐身个人资料的联系人加入您使用主要个人资料的群组</string> - <string name="incognito_info_protects">隐身模式可以保护你的主要个人资料名称和图像的隐私——对于每个新的联系人,都会创建一个新的随机个人资料。</string> + <string name="incognito_info_protects">隐身模式通过为每个联系人使用新的随机配置文件来保护您的隐私。</string> <string name="alert_title_cant_invite_contacts_descr">您正在为该群组使用隐身个人资料——为防止共享您的主要个人资料,不允许邀请联系人</string> <string name="description_via_one_time_link_incognito">通过一次性链接隐身</string> <string name="only_group_owners_can_enable_voice">只有群主可以启用语音信息。</string> @@ -285,7 +285,7 @@ <string name="incoming_video_call">视频通话来电</string> <string name="no_call_on_lock_screen">禁用</string> <string name="status_e2e_encrypted">端到端加密</string> - <string name="status_contact_has_e2e_encryption">联系人具有端到端加密</string> + <string name="status_contact_has_e2e_encryption">联系人已开启端到端加密</string> <string name="allow_accepting_calls_from_lock_screen">通过设置启用在锁定屏幕上通话。</string> <string name="icon_descr_call_connecting">连接通话中</string> <string name="status_contact_has_no_e2e_encryption">联系人没有端到端加密</string> @@ -531,7 +531,7 @@ <string name="enter_passphrase_notification_desc">要接收通知,请输入数据库密码</string> <string name="to_preserve_privacy_simplex_has_background_service_instead_of_push_notifications_it_uses_a_few_pc_battery"><![CDATA[为了保护您的隐私,该应用程序没有推送通知,而是具有 <b>SimpleX 后台服务 </b>——它每天使用百分之几的电池。]]></string> <string name="your_settings">您的设置</string> - <string name="turn_off_battery_optimization"><![CDATA[为了使用它,请 <b>禁用电池优化</b>为SimpleX在下一个对话框。否则通知将被禁用。]]></string> + <string name="turn_off_battery_optimization"><![CDATA[要使用它,请在下一个对话框中<b>允许 SimpleX 在后台运行</b>。 否则,通知将被禁用。]]></string> <string name="settings_notification_preview_title">通知预览</string> <string name="enter_passphrase_notification_title">需要密码</string> <string name="periodic_notifications_disabled">定期通知被禁用!</string> @@ -669,7 +669,8 @@ <string name="no_contacts_selected">未选择联系人</string> <string name="one_time_link">一次性邀请链接</string> <string name="feature_off">关闭</string> - <string name="network_use_onion_hosts_required_desc">连接需要 Onion 主机。</string> + <string name="network_use_onion_hosts_required_desc">连接需要 Onion 主机。 +\n请注意:如果没有 .onion 地址,您将无法连接到服务器。</string> <string name="network_use_onion_hosts_prefer_desc_in_alert">Onion 主机将在可用时使用。</string> <string name="chat_item_ttl_none">从不</string> <string name="feature_offered_item">已提供 %s</string> @@ -1107,7 +1108,7 @@ <string name="revoke_file__confirm">撤销</string> <string name="audio_video_calls">音频/视频通话</string> <string name="available_in_v51">" -\n在 v5.1 中可用"</string> +\n在 v5.1 版本中可用"</string> <string name="v5_0_app_passcode">应用程序密码</string> <string name="v5_0_polish_interface">波兰语界面</string> <string name="v5_0_polish_interface_descr">感谢用户——通过 Weblate 做出贡献!</string> @@ -1119,7 +1120,7 @@ <string name="only_you_can_make_calls">只有您可以拨打电话。</string> <string name="only_your_contact_can_make_calls">只有您的联系人可以拨打电话。</string> <string name="allow_your_contacts_to_call">允许您的联系人与您进行语音通话。</string> - <string name="allow_calls_only_if">仅当您的联系人许可时才允许呼叫。</string> + <string name="allow_calls_only_if">仅当您的联系人允许时才允许呼叫。</string> <string name="calls_prohibited_with_this_contact">禁止音频/视频通话。</string> <string name="send_disappearing_message_1_minute">1分钟</string> <string name="one_time_link_short">一次性链接</string> @@ -1292,10 +1293,114 @@ <string name="connect__a_new_random_profile_will_be_shared">一个新的随机个人档案将被分享。</string> <string name="snd_conn_event_ratchet_sync_started">与 %s 协调加密中…</string> <string name="in_developing_desc">该功能还没支持。请尝试下一个版本。</string> - <string name="turn_off_battery_optimization_button">确认</string> + <string name="turn_off_battery_optimization_button">允许</string> <string name="connect_via_link_incognito">隐身连接</string> <string name="connect_via_member_address_alert_title">确认发起私聊?</string> <string name="delivery">发送</string> <string name="recipient_colon_delivery_status">%s: %s</string> <string name="in_developing_title">敬请期待!</string> + <string name="database_will_be_encrypted_and_passphrase_stored_in_settings">数据库将被加密,密码将存储在设置中。</string> + <string name="you_can_enable_delivery_receipts_later">您可以稍后在“设置”中启用它</string> + <string name="receipts_groups_disable_for_all">对所有群组关闭</string> + <string name="no_info_on_delivery">无送货信息</string> + <string name="connect__your_profile_will_be_shared">您的个人资料 %1$s 将被共享。</string> + <string name="sending_delivery_receipts_will_be_enabled">将为所有联系人启用送达回执功能。</string> + <string name="turn_off_system_restriction_button">打开应用程序设置</string> + <string name="receipts_groups_enable_for_all">为所有组启用</string> + <string name="rcv_group_event_n_members_connected">%s、%s 和 %d 其他成员已连接</string> + <string name="receipts_contacts_override_enabled">已为 %d 联系人启用送达回执功能</string> + <string name="snd_conn_event_ratchet_sync_agreed">已同意 %s 的加密</string> + <string name="conn_event_ratchet_sync_allowed">允许重新协商加密</string> + <string name="delivery_receipts_title">送达回执!</string> + <string name="connect_use_new_incognito_profile">使用新的隐身个人资料</string> + <string name="v5_2_favourites_filter_descr">过滤未读和收藏的聊天记录。</string> + <string name="rcv_conn_event_verification_code_reset">已更改安全密码</string> + <string name="sending_delivery_receipts_will_be_enabled_all_profiles">将为所有可见聊天配置文件中的所有联系人启用送达回执功能。</string> + <string name="system_restricted_background_in_call_warn"><![CDATA[要在后台拨打电话,请在应用设置中选择<b>应用电池使用情况</b> / <b>无限制</b>。]]></string> + <string name="sender_at_ts">%s 在 %s</string> + <string name="receipts_contacts_title_disable">禁用回执?</string> + <string name="sync_connection_force_question">重新协商加密?</string> + <string name="receipts_section_description_1">可以在联系人和群组设置中覆盖它们。</string> + <string name="receipts_contacts_disable_for_all">对所有联系人关闭</string> + <string name="you_can_change_it_later">随机密码以明文形式存储在设置中。 +\n您可以稍后更改。</string> + <string name="receipts_groups_override_disabled">已禁用 %d 组的送达回执功能</string> + <string name="snd_conn_event_ratchet_sync_required">需要为 %s 重新协商加密</string> + <string name="system_restricted_background_desc">SimpleX 无法在后台运行。只有在应用程序运行时,您才会收到通知。</string> + <string name="receipts_contacts_enable_keep_overrides">启用(保留覆盖)</string> + <string name="database_encryption_will_be_updated_in_settings">即将更新数据库加密密码并将其存储在设置中。</string> + <string name="connect_use_current_profile">使用当前配置文件</string> + <string name="remove_passphrase_from_settings">从设置中删除密码?</string> + <string name="conn_event_ratchet_sync_agreed">同意加密</string> + <string name="receipts_contacts_title_enable">启用回执?</string> + <string name="system_restricted_background_in_call_desc">程序在后台运行 1 分钟后可能会关闭。</string> + <string name="privacy_message_draft">留言草稿</string> + <string name="v5_2_disappear_one_message_descr">即使在对话中禁用。</string> + <string name="use_random_passphrase">使用随机密码</string> + <string name="system_restricted_background_in_call_title">无后台通话</string> + <string name="you_can_enable_delivery_receipts_later_alert">您可以稍后通过应用程序隐私和安全设置启用它们。</string> + <string name="save_passphrase_in_settings">在设置中保存密码</string> + <string name="enable_receipts_all">启用</string> + <string name="send_receipts_disabled_alert_msg">该群组成员超过 %1$d ,未发送送达回执。</string> + <string name="fix_connection_question">修复连接?</string> + <string name="v5_2_message_delivery_receipts_descr">我们错过的第二个\"√\"!✅</string> + <string name="setup_database_passphrase">设定数据库密码</string> + <string name="receipts_groups_title_disable">为群组禁用回执吗?</string> + <string name="rcv_group_event_3_members_connected">%s、%s 和 %d 已连接</string> + <string name="fix_connection_not_supported_by_group_member">修复群组成员不支持的问题</string> + <string name="receipts_groups_override_enabled">已为 %d 组启用送达回执功能</string> + <string name="sync_connection_force_confirm">重新协商</string> + <string name="receipts_contacts_disable_keep_overrides">禁用(保留覆盖)</string> + <string name="set_database_passphrase">设置数据库密码</string> + <string name="receipts_contacts_override_disabled">已禁用 %d 联系人的送达回执功能</string> + <string name="receipts_groups_enable_keep_overrides">启用(保留组覆盖)</string> + <string name="system_restricted_background_warn"><![CDATA[要启用通知,请在应用设置中选择<b>应用电池使用情况</b> / <b>无限制</b>。]]></string> + <string name="send_receipts_disabled_alert_title">送达回执已禁用</string> + <string name="open_database_folder">打开数据库文件夹</string> + <string name="no_history">无历史记录</string> + <string name="fix_connection_confirm">修复</string> + <string name="fix_connection">修复连接</string> + <string name="rcv_group_event_2_members_connected">%s 和 %s 已连接</string> + <string name="send_receipts_disabled">关闭</string> + <string name="receipts_section_groups">小群组(最多 20 人)</string> + <string name="privacy_show_last_messages">显示最近的消息</string> + <string name="settings_section_title_delivery_receipts">将送达回执发送给</string> + <string name="error_enabling_delivery_receipts">启用已读回执时出错!</string> + <string name="passphrase_will_be_saved_in_settings">更改密码或重启应用后,密码将以明文形式保存在设置中。</string> + <string name="paste_the_link_you_received_to_connect_with_your_contact">粘贴您收到的链接以与您的联系人联系…</string> + <string name="send_receipts">送达回执</string> + <string name="no_selected_chat">没有选择聊天</string> + <string name="conn_event_ratchet_sync_ok">可以加密</string> + <string name="renegotiate_encryption">重新协商加密</string> + <string name="receipts_groups_disable_keep_overrides">禁用(保留组覆盖)</string> + <string name="receipts_groups_title_enable">为群组启用回执吗?</string> + <string name="fix_connection_not_supported_by_contact">修复联系人不支持的问题</string> + <string name="snd_conn_event_ratchet_sync_ok">对 %s 加密正常</string> + <string name="v5_2_fix_encryption_descr">修复还原备份后的加密问题。</string> + <string name="sync_connection_force_desc">加密正在运行,不需要新的加密协议。此操作可能会导致连接错误!</string> + <string name="disable_notifications_button">禁用通知</string> + <string name="in_reply_to">回复</string> + <string name="dont_enable_receipts">不启用</string> + <string name="connect_via_member_address_alert_desc">连接请求将发送给该组成员。</string> + <string name="settings_is_storing_in_clear_text">密码以明文形式存储在设置中。</string> + <string name="error_synchronizing_connection">同步连接时出错</string> + <string name="receipts_section_description">这些设置适用于您当前的配置文件</string> + <string name="snd_conn_event_ratchet_sync_allowed">允许为 %s 重新协商加密</string> + <string name="receipts_contacts_enable_for_all">为所有人启用</string> + <string name="conn_event_ratchet_sync_required">需要重新协商加密</string> + <string name="delivery_receipts_are_disabled">已关闭送达回执!</string> + <string name="socks_proxy_setting_limitations"><![CDATA[<b>请注意</b>:消息和文件中继通过 SOCKS 代理连接。呼叫和发送链接预览使用直接连接。]]></string> + <string name="encrypt_local_files">加密本地文件</string> + <string name="v5_3_encrypt_local_files">为存储的文件和媒体加密</string> + <string name="v5_3_new_desktop_app">全新桌面应用!</string> + <string name="v5_3_new_interface_languages">6种全新的界面语言</string> + <string name="v5_3_encrypt_local_files_descr">应用程序为新的本地文件(视频除外)加密。</string> + <string name="v5_3_discover_join_groups">发现和加入群组</string> + <string name="v5_3_simpler_incognito_mode">简化的隐身模式</string> + <string name="v5_3_new_interface_languages_descr">阿拉伯语、保加利亚语、芬兰语、希伯莱语、泰国语和乌克兰语——得益于用户和Weblate。</string> + <string name="v5_3_new_desktop_app_descr">在桌面应用里创建新的账号。💻</string> + <string name="v5_3_simpler_incognito_mode_descr">在连接时切换隐身模式。</string> + <string name="v5_3_discover_join_groups_descr">- 连接到目录服务(BETA)! +\n- 发送回执(至多20名成员)。 +\n- 更快,更稳定。</string> </resources> \ No newline at end of file diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt index 612217925b..7193fbe2be 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt @@ -29,6 +29,10 @@ fun initApp() { //testCrypto() } +fun discoverVlcLibs(path: String) { + uk.co.caprica.vlcj.binding.LibC.INSTANCE.setenv("VLC_PLUGIN_PATH", path, 1) +} + private fun applyAppLocale() { val lang = ChatController.appPrefs.appLanguage.get() if (lang == null || lang == Locale.getDefault().language) return diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt index 9042a62830..46124a44fa 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt @@ -21,6 +21,8 @@ actual val agentDatabaseFileName: String = "simplex_v1_agent.db" actual val databaseExportDir: File = tmpDir +val vlcDir: File = File(System.getProperty("java.io.tmpdir") + File.separator + "simplex-vlc").also { it.deleteOnExit() } + actual fun desktopOpenDatabaseDir() { if (Desktop.isDesktopSupported()) { try { diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/PlatformTextField.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/PlatformTextField.desktop.kt index 36feb1abdf..3b7ba84863 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/PlatformTextField.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/PlatformTextField.desktop.kt @@ -33,6 +33,7 @@ import kotlin.text.substring @Composable actual fun PlatformTextField( composeState: MutableState<ComposeState>, + sendMsgEnabled: Boolean, textStyle: MutableState<TextStyle>, showDeleteTextButton: MutableState<Boolean>, userIsObserver: Boolean, @@ -42,6 +43,7 @@ actual fun PlatformTextField( ) { val cs = composeState.value val focusRequester = remember { FocusRequester() } + val focusManager = LocalFocusManager.current val keyboard = LocalSoftwareKeyboardController.current val padding = PaddingValues(12.dp, 12.dp, 45.dp, 0.dp) LaunchedEffect(cs.contextItem) { @@ -51,6 +53,13 @@ actual fun PlatformTextField( delay(50) keyboard?.show() } + LaunchedEffect(sendMsgEnabled) { + if (!sendMsgEnabled) { + focusManager.clearFocus() + delay(50) + keyboard?.hide() + } + } val isRtl = remember(cs.message) { isRtl(cs.message.subSequence(0, min(50, cs.message.length))) } var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = cs.message)) } val textFieldValue = textFieldValueState.copy(text = cs.message) @@ -113,7 +122,8 @@ actual fun PlatformTextField( } } } - } + }, + ) showDeleteTextButton.value = cs.message.split("\n").size >= 4 && !cs.inProgress if (composeState.value.preview is ComposePreview.VoicePreview) { diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/RecAndPlay.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/RecAndPlay.desktop.kt index 8e6a7d7ef9..ed8efcd57f 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/RecAndPlay.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/RecAndPlay.desktop.kt @@ -1,9 +1,17 @@ package chat.simplex.common.platform import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf import chat.simplex.common.model.* -import chat.simplex.common.views.usersettings.showInDevelopingAlert -import kotlinx.coroutines.CoroutineScope +import chat.simplex.common.views.helpers.AlertManager +import chat.simplex.common.views.helpers.generalGetString +import chat.simplex.res.MR +import kotlinx.coroutines.* +import uk.co.caprica.vlcj.player.base.MediaPlayer +import uk.co.caprica.vlcj.player.base.State +import uk.co.caprica.vlcj.player.component.AudioPlayerComponent +import java.io.File +import kotlin.math.max actual class RecorderNative: RecorderInterface { override fun start(onProgressUpdate: (position: Int?, finished: Boolean) -> Unit): String { @@ -18,36 +26,187 @@ actual class RecorderNative: RecorderInterface { } actual object AudioPlayer: AudioPlayerInterface { - override fun play(fileSource: CryptoFile, audioPlaying: MutableState<Boolean>, progress: MutableState<Int>, duration: MutableState<Int>, resetOnEnd: Boolean) { - showInDevelopingAlert() + val player by lazy { AudioPlayerComponent().mediaPlayer() } + + // Filepath: String, onProgressUpdate + private val currentlyPlaying: MutableState<Pair<CryptoFile, (position: Int?, state: TrackState) -> Unit>?> = mutableStateOf(null) + private var progressJob: Job? = null + + enum class TrackState { + PLAYING, PAUSED, REPLACED + } + + // Returns real duration of the track + private fun start(fileSource: CryptoFile, seek: Int? = null, onProgressUpdate: (position: Int?, state: TrackState) -> Unit): Int? { + val absoluteFilePath = getAppFilePath(fileSource.filePath) + if (!File(absoluteFilePath).exists()) { + Log.e(TAG, "No such file: ${fileSource.filePath}") + return null + } + + VideoPlayerHolder.stopAll() + RecorderInterface.stopRecording?.invoke() + val current = currentlyPlaying.value + if (current == null || current.first != fileSource) { + stopListener() + player.stop() + runCatching { + if (fileSource.cryptoArgs != null) { + val tmpFile = fileSource.createTmpFileIfNeeded() + decryptCryptoFile(absoluteFilePath, fileSource.cryptoArgs, tmpFile.absolutePath) + player.media().prepare("file://${tmpFile.absolutePath}") + } else { + player.media().prepare("file://$absoluteFilePath") + } + }.onFailure { + Log.e(TAG, it.stackTraceToString()) + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.unknown_error), it.message) + return null + } + } + if (seek != null) player.seekTo(seek) + player.start() + currentlyPlaying.value = fileSource to onProgressUpdate + progressJob = CoroutineScope(Dispatchers.Default).launch { + onProgressUpdate(player.currentPosition, TrackState.PLAYING) + while(isActive && (player.isPlaying || player.status().state() == State.OPENING)) { + // Even when current position is equal to duration, the player has isPlaying == true for some time, + // so help to make the playback stopped in UI immediately + if (player.currentPosition == player.duration) { + onProgressUpdate(player.currentPosition, TrackState.PLAYING) + break + } + delay(50) + onProgressUpdate(player.currentPosition, TrackState.PLAYING) + } + onProgressUpdate(null, TrackState.PAUSED) + currentlyPlaying.value?.first?.deleteTmpFile() + } + return player.duration + } + + private fun pause(): Int { + progressJob?.cancel() + progressJob = null + val position = player.currentPosition + player.pause() + return position } override fun stop() { - /*LALAL*/ + if (currentlyPlaying.value == null) return + player.stop() + stopListener() } - override fun stop(item: ChatItem) { - /*LALAL*/ - } + override fun stop(item: ChatItem) = stop(item.file?.fileName) + // FileName or filePath are ok override fun stop(fileName: String?) { - TODO("Not yet implemented") + if (fileName != null && currentlyPlaying.value?.first?.filePath?.endsWith(fileName) == true) { + stop() + } + } + + private fun stopListener() { + val afterCoroutineCancel: CompletionHandler = { + // Notify prev audio listener about stop + currentlyPlaying.value?.second?.invoke(null, TrackState.REPLACED) + currentlyPlaying.value?.first?.deleteTmpFile() + currentlyPlaying.value = null + } + /** Preventing race by calling a code AFTER coroutine ends, so [TrackState] will be: + * [TrackState.PLAYING] -> [TrackState.PAUSED] -> [TrackState.REPLACED] (in this order) + * */ + if (progressJob != null) { + progressJob?.invokeOnCompletion(afterCoroutineCancel) + } else { + afterCoroutineCancel(null) + } + progressJob?.cancel() + progressJob = null + } + + override fun play( + fileSource: CryptoFile, + audioPlaying: MutableState<Boolean>, + progress: MutableState<Int>, + duration: MutableState<Int>, + resetOnEnd: Boolean, + ) { + if (progress.value == duration.value) { + progress.value = 0 + } + val realDuration = start(fileSource, progress.value) { pro, state -> + if (pro != null) { + progress.value = pro + } + if (pro == null || pro == duration.value) { + audioPlaying.value = false + if (pro == duration.value) { + progress.value = if (resetOnEnd) 0 else duration.value + } else if (state == TrackState.REPLACED) { + progress.value = 0 + } + } + } + audioPlaying.value = realDuration != null + // Update to real duration instead of what was received in ChatInfo + realDuration?.let { duration.value = it } } override fun pause(audioPlaying: MutableState<Boolean>, pro: MutableState<Int>) { - TODO("Not yet implemented") + pro.value = pause() + audioPlaying.value = false } override fun seekTo(ms: Int, pro: MutableState<Int>, filePath: String?) { - /*LALAL*/ + pro.value = ms + if (currentlyPlaying.value?.first?.filePath == filePath) { + player.seekTo(ms) + } } override fun duration(unencryptedFilePath: String): Int? { - /*LALAL*/ - return null + var res: Int? = null + try { + val helperPlayer = AudioPlayerComponent().mediaPlayer() + helperPlayer.media().startPaused("file://$unencryptedFilePath") + res = helperPlayer.duration + helperPlayer.stop() + helperPlayer.release() + } catch (e: Exception) { + Log.e(TAG, e.stackTraceToString()) + } + return res } } +val MediaPlayer.isPlaying: Boolean + get() = status().isPlaying + +fun MediaPlayer.seekTo(time: Int) { + controls().setTime(time.toLong()) +} + +fun MediaPlayer.start() { + controls().start() +} + +fun MediaPlayer.pause() { + controls().pause() +} + +fun MediaPlayer.stop() { + controls().stop() +} + +private val MediaPlayer.currentPosition: Int + get() = max(0, status().time().toInt()) + +val MediaPlayer.duration: Int + get() = media().info().duration().toInt() + actual object SoundPlayer: SoundPlayerInterface { override fun start(scope: CoroutineScope, sound: Boolean) { /*LALAL*/ } override fun stop() { /*LALAL*/ } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/VideoPlayer.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/VideoPlayer.desktop.kt index 90f6a593f5..1d98c6497d 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/VideoPlayer.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/VideoPlayer.desktop.kt @@ -3,51 +3,213 @@ package chat.simplex.common.platform import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.graphics.ImageBitmap -import chat.simplex.common.views.usersettings.showInDevelopingAlert +import androidx.compose.ui.graphics.toComposeImageBitmap +import chat.simplex.common.views.helpers.* +import chat.simplex.res.MR +import kotlinx.coroutines.* +import uk.co.caprica.vlcj.player.base.MediaPlayer +import uk.co.caprica.vlcj.player.component.CallbackMediaPlayerComponent +import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent +import java.awt.Component +import java.io.File import java.net.URI +import kotlin.math.max -actual class VideoPlayer: VideoPlayerInterface { - actual companion object { - actual fun getOrCreate( - uri: URI, - gallery: Boolean, - defaultPreview: ImageBitmap, - defaultDuration: Long, - soundEnabled: Boolean - ): VideoPlayer = VideoPlayer().also { - it.preview.value = defaultPreview - it.duration.value = defaultDuration - it.soundEnabled.value = soundEnabled - } - actual fun enableSound(enable: Boolean, fileName: String?, gallery: Boolean): Boolean { /*TODO*/ return false } - actual fun release(uri: URI, gallery: Boolean, remove: Boolean) { /*TODO*/ } - actual fun stopAll() { /*LALAL*/ } - actual fun releaseAll() { /*LALAL*/ } - } - +actual class VideoPlayer actual constructor( + override val uri: URI, + override val gallery: Boolean, + private val defaultPreview: ImageBitmap, + defaultDuration: Long, + soundEnabled: Boolean +): VideoPlayerInterface { override val soundEnabled: MutableState<Boolean> = mutableStateOf(false) override val brokenVideo: MutableState<Boolean> = mutableStateOf(false) override val videoPlaying: MutableState<Boolean> = mutableStateOf(false) override val progress: MutableState<Long> = mutableStateOf(0L) override val duration: MutableState<Long> = mutableStateOf(0L) - override val preview: MutableState<ImageBitmap> = mutableStateOf(ImageBitmap(0, 0)) + override val preview: MutableState<ImageBitmap> = mutableStateOf(defaultPreview) + + val mediaPlayerComponent = initializeMediaPlayerComponent() + val player by lazy { mediaPlayerComponent.mediaPlayer() } + + init { + withBGApi { + setPreviewAndDuration() + } + } + + private val currentVolume: Int by lazy { player.audio().volume() } + private var isReleased: Boolean = false + + private val listener: MutableState<((position: Long?, state: TrackState) -> Unit)?> = mutableStateOf(null) + private var progressJob: Job? = null + + enum class TrackState { + PLAYING, PAUSED, STOPPED + } + + private fun start(seek: Long? = null, onProgressUpdate: (position: Long?, state: TrackState) -> Unit): Boolean { + val filepath = getAppFilePath(uri) + if (filepath == null || !File(filepath).exists()) { + Log.e(TAG, "No such file: $uri") + brokenVideo.value = true + return false + } + + if (soundEnabled.value) { + RecorderInterface.stopRecording?.invoke() + } + AudioPlayer.stop() + VideoPlayerHolder.stopAll() + val playerFilePath = uri.toString().replaceFirst("file:", "file://") + if (listener.value == null) { + runCatching { + player.media().prepare(playerFilePath) + if (seek != null) { + player.seekTo(seek.toInt()) + } + }.onFailure { + Log.e(TAG, it.stackTraceToString()) + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.unknown_error), it.message) + brokenVideo.value = true + return false + } + } + player.start() + if (seek != null) player.seekTo(seek.toInt()) + if (!player.isPlaying) { + // Can happen when video file is broken + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.unknown_error)) + brokenVideo.value = true + return false + } + listener.value = onProgressUpdate + // Player can only be accessed in one specific thread + progressJob = CoroutineScope(Dispatchers.Main).launch { + onProgressUpdate(player.currentPosition.toLong(), TrackState.PLAYING) + while (isActive && !isReleased && player.isPlaying) { + // Even when current position is equal to duration, the player has isPlaying == true for some time, + // so help to make the playback stopped in UI immediately + if (player.currentPosition == player.duration) { + onProgressUpdate(player.currentPosition.toLong(), TrackState.PLAYING) + break + } + delay(50) + onProgressUpdate(player.currentPosition.toLong(), TrackState.PLAYING) + } + if (isActive && !isReleased) { + onProgressUpdate(player.currentPosition.toLong(), TrackState.PAUSED) + } + onProgressUpdate(null, TrackState.PAUSED) + } + + return true + } override fun stop() { - /*TODO*/ + if (isReleased || !videoPlaying.value) return + player.controls().stop() + stopListener() + } + + private fun stopListener() { + val afterCoroutineCancel: CompletionHandler = { + // Notify prev video listener about stop + listener.value?.invoke(null, TrackState.STOPPED) + } + /** Preventing race by calling a code AFTER coroutine ends, so [TrackState] will be: + * [TrackState.PLAYING] -> [TrackState.PAUSED] -> [TrackState.STOPPED] (in this order) + * */ + if (progressJob != null) { + progressJob?.invokeOnCompletion(afterCoroutineCancel) + } else { + afterCoroutineCancel(null) + } + progressJob?.cancel() + progressJob = null } override fun play(resetOnEnd: Boolean) { - if (appPlatform.isDesktop) { - showInDevelopingAlert() + if (progress.value == duration.value) { + progress.value = 0 + } + videoPlaying.value = start(progress.value) { pro, _ -> + if (pro != null) { + progress.value = pro + } + if ((pro == null || pro == duration.value) && duration.value != 0L) { + videoPlaying.value = false + if (pro == duration.value) { + progress.value = if (resetOnEnd) 0 else duration.value + }/* else if (state == TrackState.STOPPED) { + progress.value = 0 // + }*/ + } } } override fun enableSound(enable: Boolean): Boolean { - /*TODO*/ - return false + if (isReleased) return false + if (soundEnabled.value == enable) return false + soundEnabled.value = enable + player.audio().setVolume(if (enable) currentVolume else 0) + return true } - override fun release(remove: Boolean) { - /*TODO*/ + override fun release(remove: Boolean) { withApi { + if (isReleased) return@withApi + isReleased = true + // TODO + /** [player.release] freezes thread for some reason. It happens periodically. So doing this we don't see the freeze, but it's still there */ + if (player.isPlaying) player.stop() + CoroutineScope(Dispatchers.IO).launch { player.release() } + if (remove) { + VideoPlayerHolder.players.remove(uri to gallery) + } + }} + + private val MediaPlayer.currentPosition: Int + get() = if (isReleased) 0 else max(0, player.status().time().toInt()) + + private suspend fun setPreviewAndDuration() { + // It freezes main thread, doing it in IO thread + CoroutineScope(Dispatchers.IO).launch { + val previewAndDuration = VideoPlayerHolder.previewsAndDurations.getOrPut(uri) { getBitmapFromVideo() } + withContext(Dispatchers.Main) { + preview.value = previewAndDuration.preview ?: defaultPreview + duration.value = (previewAndDuration.duration ?: 0) + } + } + } + + private suspend fun getBitmapFromVideo(): VideoPlayerInterface.PreviewAndDuration { + val player = CallbackMediaPlayerComponent().mediaPlayer() + val filepath = getAppFilePath(uri) + if (filepath == null || !File(filepath).exists()) { + return VideoPlayerInterface.PreviewAndDuration(preview = defaultPreview, timestamp = 0L, duration = 0L) + } + player.media().startPaused(filepath) + val start = System.currentTimeMillis() + while (player.snapshots()?.get() == null && start + 5000 > System.currentTimeMillis()) { + delay(10) + } + val preview = player.snapshots()?.get()?.toComposeImageBitmap() + val duration = player.duration.toLong() + CoroutineScope(Dispatchers.IO).launch { player.release() } + return VideoPlayerInterface.PreviewAndDuration(preview = preview, timestamp = 0L, duration = duration) + } + + private fun initializeMediaPlayerComponent(): Component { + return if (desktopPlatform.isMac()) { + CallbackMediaPlayerComponent() + } else { + EmbeddedMediaPlayerComponent() + } + } + + private fun Component.mediaPlayer() = when (this) { + is CallbackMediaPlayerComponent -> mediaPlayer() + is EmbeddedMediaPlayerComponent -> mediaPlayer() + else -> error("mediaPlayer() can only be called on vlcj player components") } } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/CIVideoView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/CIVideoView.desktop.kt index aac995e480..c85057b47e 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/CIVideoView.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/CIVideoView.desktop.kt @@ -6,9 +6,7 @@ import androidx.compose.ui.unit.Dp import chat.simplex.common.platform.VideoPlayer @Composable -actual fun PlayerView(player: VideoPlayer, width: Dp, onClick: () -> Unit, onLongClick: () -> Unit, stop: () -> Unit) { - /* LALAL */ -} +actual fun PlayerView(player: VideoPlayer, width: Dp, onClick: () -> Unit, onLongClick: () -> Unit, stop: () -> Unit) {} @Composable actual fun LocalWindowWidth(): Dp { diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.desktop.kt index a73c2784ed..9aafc83d23 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/ImageFullScreenView.desktop.kt @@ -1,14 +1,23 @@ package chat.simplex.common.views.chat.item -import androidx.compose.foundation.Image -import androidx.compose.runtime.Composable +import androidx.compose.foundation.* +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.awt.SwingPanel import androidx.compose.ui.graphics.* import androidx.compose.ui.layout.ContentScale -import chat.simplex.common.platform.VideoPlayer +import androidx.compose.ui.unit.dp +import chat.simplex.common.platform.* +import chat.simplex.common.simplexWindowState import chat.simplex.common.views.helpers.getBitmapFromByteArray import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource +import kotlinx.coroutines.delay +import kotlin.math.max @Composable actual fun FullScreenImageView(modifier: Modifier, data: ByteArray, imageBitmap: ImageBitmap) { @@ -20,6 +29,43 @@ actual fun FullScreenImageView(modifier: Modifier, data: ByteArray, imageBitmap: ) } @Composable -actual fun FullScreenVideoView(player: VideoPlayer, modifier: Modifier) { - +actual fun FullScreenVideoView(player: VideoPlayer, modifier: Modifier, close: () -> Unit) { + // Workaround. Without changing size of the window the screen flashes a lot even if it's not being recomposed + LaunchedEffect(Unit) { + simplexWindowState.windowState.size = simplexWindowState.windowState.size.copy(width = simplexWindowState.windowState.size.width + 1.dp) + delay(50) + player.play(true) + simplexWindowState.windowState.size = simplexWindowState.windowState.size.copy(width = simplexWindowState.windowState.size.width - 1.dp) + } + Box { + Box(Modifier.fillMaxSize().padding(bottom = 50.dp)) { + val factory = remember { { player.mediaPlayerComponent } } + SwingPanel( + background = Color.Transparent, + modifier = Modifier, + factory = factory + ) + } + Controls(player, close) + } +} + +@Composable +private fun BoxScope.Controls(player: VideoPlayer, close: () -> Unit) { + val playing = remember(player) { player.videoPlaying } + val progress = remember(player) { player.progress } + val duration = remember(player) { player.duration } + Row(Modifier.fillMaxWidth().align(Alignment.BottomCenter).height(50.dp)) { + IconButton(onClick = { if (playing.value) player.player.pause() else player.play(true) },) { + Icon(painterResource(if (playing.value) MR.images.ic_pause_filled else MR.images.ic_play_arrow_filled), null, Modifier.size(30.dp), tint = MaterialTheme.colors.primary) + } + Slider( + value = progress.value.toFloat() / max(0.0001f, duration.value.toFloat()), + onValueChange = { player.player.seekTo((it * duration.value).toInt()) }, + modifier = Modifier.fillMaxWidth().weight(1f) + ) + IconButton(onClick = close,) { + Icon(painterResource(MR.images.ic_close), null, Modifier.size(30.dp), tint = MaterialTheme.colors.primary) + } + } } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/helpers/Utils.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/helpers/Utils.desktop.kt index 4fa768a5d3..cc84e9ac0b 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/helpers/Utils.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/helpers/Utils.desktop.kt @@ -133,7 +133,6 @@ actual suspend fun saveTempImageUncompressed(image: ImageBitmap, asPng: Boolean) } actual fun getBitmapFromVideo(uri: URI, timestamp: Long?, random: Boolean): VideoPlayerInterface.PreviewAndDuration { - // LALAL return VideoPlayerInterface.PreviewAndDuration(preview = null, timestamp = 0L, duration = 0L) } diff --git a/apps/multiplatform/desktop/build.gradle.kts b/apps/multiplatform/desktop/build.gradle.kts index af9ea986cb..3062d25f2d 100644 --- a/apps/multiplatform/desktop/build.gradle.kts +++ b/apps/multiplatform/desktop/build.gradle.kts @@ -1,6 +1,5 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly -import java.util.* plugins { kotlin("multiplatform") @@ -22,6 +21,7 @@ kotlin { dependencies { implementation(project(":common")) implementation(compose.desktop.currentOs) + implementation("net.java.dev.jna:jna:5.13.0") } } val jvmTest by getting @@ -33,16 +33,23 @@ compose { desktop { application { // For debugging via VisualVM - /*jvmArgs += listOf( - "-Dcom.sun.management.jmxremote.port=8080", - "-Dcom.sun.management.jmxremote.ssl=false", - "-Dcom.sun.management.jmxremote.authenticate=false" - )*/ + val debugJava = false + if (debugJava) { + jvmArgs += listOf( + "-Dcom.sun.management.jmxremote.port=8080", + "-Dcom.sun.management.jmxremote.ssl=false", + "-Dcom.sun.management.jmxremote.authenticate=false" + ) + } mainClass = "chat.simplex.desktop.MainKt" nativeDistributions { // For debugging via VisualVM - //modules("jdk.zipfs", "jdk.management.agent") - modules("jdk.zipfs") + if (debugJava) { + modules("jdk.zipfs", "jdk.unsupported", "jdk.management.agent") + } else { + // 'jdk.unsupported' is for vlcj + modules("jdk.zipfs", "jdk.unsupported") + } //includeAllModules = true outputBaseDir.set(project.file("../release")) targetFormats( @@ -148,57 +155,119 @@ tasks.named("compileJava") { afterEvaluate { tasks.create("cmakeBuildAndCopy") { dependsOn("cmakeBuild") + val copyDetails = mutableMapOf<String, ArrayList<FileCopyDetails>>() + copy { + from("${project(":desktop").buildDir}/cmake/main/linux-amd64", "$cppPath/desktop/libs/linux-x86_64", "$cppPath/desktop/libs/linux-x86_64/deps") + into("src/jvmMain/resources/libs/linux-x86_64") + include("*.so*") + eachFile { + path = name + } + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + copy { + val destinationDir = "src/jvmMain/resources/libs/linux-x86_64/vlc" + from("$cppPath/desktop/libs/linux-x86_64/deps/vlc") + into(destinationDir) + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + copyIfNeeded(destinationDir, copyDetails) + } + copy { + from("${project(":desktop").buildDir}/cmake/main/linux-aarch64", "$cppPath/desktop/libs/linux-aarch64", "$cppPath/desktop/libs/linux-aarch64/deps") + into("src/jvmMain/resources/libs/linux-aarch64") + include("*.so*") + eachFile { + path = name + } + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + copy { + val destinationDir = "src/jvmMain/resources/libs/linux-aarch64/vlc" + from("$cppPath/desktop/libs/linux-aarch64/deps/vlc") + into(destinationDir) + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + copyIfNeeded(destinationDir, copyDetails) + } + copy { + from("${project(":desktop").buildDir}/cmake/main/win-amd64", "$cppPath/desktop/libs/windows-x86_64", "$cppPath/desktop/libs/windows-x86_64/deps") + into("src/jvmMain/resources/libs/windows-x86_64") + include("*.dll") + eachFile { + path = name + } + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + copy { + val destinationDir = "src/jvmMain/resources/libs/windows-x86_64/vlc" + from("$cppPath/desktop/libs/windows-x86_64/deps/vlc") + into(destinationDir) + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + copyIfNeeded(destinationDir, copyDetails) + } + copy { + from("${project(":desktop").buildDir}/cmake/main/mac-x86_64", "$cppPath/desktop/libs/mac-x86_64", "$cppPath/desktop/libs/mac-x86_64/deps") + into("src/jvmMain/resources/libs/mac-x86_64") + include("*.dylib") + eachFile { + path = name + } + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + copy { + val destinationDir = "src/jvmMain/resources/libs/mac-x86_64/vlc" + from("$cppPath/desktop/libs/mac-x86_64/deps/vlc") + into(destinationDir) + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + copyIfNeeded(destinationDir, copyDetails) + } + copy { + from("${project(":desktop").buildDir}/cmake/main/mac-aarch64", "$cppPath/desktop/libs/mac-aarch64", "$cppPath/desktop/libs/mac-aarch64/deps") + into("src/jvmMain/resources/libs/mac-aarch64") + include("*.dylib") + eachFile { + path = name + } + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + copy { + val destinationDir = "src/jvmMain/resources/libs/mac-aarch64/vlc" + from("$cppPath/desktop/libs/mac-aarch64/deps/vlc") + into(destinationDir) + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + copyIfNeeded(destinationDir, copyDetails) + } doLast { - copy { - from("${project(":desktop").buildDir}/cmake/main/linux-amd64", "$cppPath/desktop/libs/linux-x86_64", "$cppPath/desktop/libs/linux-x86_64/deps") - into("src/jvmMain/resources/libs/linux-x86_64") - include("*.so*") - eachFile { - path = name + copyDetails.forEach { (destinationDir, details) -> + details.forEach { detail -> + val target = File(projectDir.absolutePath + File.separator + destinationDir + File.separator + detail.path) + if (target.exists()) { + target.setLastModified(detail.lastModified) + } } - includeEmptyDirs = false - duplicatesStrategy = DuplicatesStrategy.INCLUDE - } - copy { - from("${project(":desktop").buildDir}/cmake/main/linux-aarch64", "$cppPath/desktop/libs/linux-aarch64", "$cppPath/desktop/libs/linux-aarch64/deps") - into("src/jvmMain/resources/libs/linux-aarch64") - include("*.so*") - eachFile { - path = name - } - includeEmptyDirs = false - duplicatesStrategy = DuplicatesStrategy.INCLUDE - } - copy { - from("${project(":desktop").buildDir}/cmake/main/win-amd64", "$cppPath/desktop/libs/windows-x86_64", "$cppPath/desktop/libs/windows-x86_64/deps") - into("src/jvmMain/resources/libs/windows-x86_64") - include("*.dll") - eachFile { - path = name - } - includeEmptyDirs = false - duplicatesStrategy = DuplicatesStrategy.INCLUDE - } - copy { - from("${project(":desktop").buildDir}/cmake/main/mac-x86_64", "$cppPath/desktop/libs/mac-x86_64", "$cppPath/desktop/libs/mac-x86_64/deps") - into("src/jvmMain/resources/libs/mac-x86_64") - include("*.dylib") - eachFile { - path = name - } - includeEmptyDirs = false - duplicatesStrategy = DuplicatesStrategy.INCLUDE - } - copy { - from("${project(":desktop").buildDir}/cmake/main/mac-aarch64", "$cppPath/desktop/libs/mac-aarch64", "$cppPath/desktop/libs/mac-aarch64/deps") - into("src/jvmMain/resources/libs/mac-aarch64") - include("*.dylib") - eachFile { - path = name - } - includeEmptyDirs = false - duplicatesStrategy = DuplicatesStrategy.INCLUDE } } } } + +fun CopySpec.copyIfNeeded(destinationDir: String, into: MutableMap<String, ArrayList<FileCopyDetails>>) { + val details = arrayListOf<FileCopyDetails>() + eachFile { + val targetFile = File(destinationDir, path) + if (file.lastModified() == targetFile.lastModified() && file.length() == targetFile.length()) { + exclude() + } else { + details.add(this) + } + } + into[destinationDir] = details +} diff --git a/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt b/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt index 494b37f0e2..3879af9dbc 100644 --- a/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt +++ b/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt @@ -5,6 +5,8 @@ import chat.simplex.common.showApp import java.io.File import java.nio.file.* import java.nio.file.attribute.BasicFileAttributes +import java.nio.file.attribute.FileTime +import kotlin.io.path.setLastModifiedTime fun main() { initHaskell() @@ -25,6 +27,15 @@ private fun initHaskell() { System.load(File(libsTmpDir, libSimplex).absolutePath) } System.load(File(libsTmpDir, libApp).absolutePath) + + vlcDir.deleteRecursively() + Files.move(File(libsTmpDir, "vlc").toPath(), vlcDir.toPath(), StandardCopyOption.REPLACE_EXISTING) + // No picture without preloading it, only sound. However, with libs from AppImage it works without preloading + //val libXcb = "libvlc_xcb_events.so.0.0.0" + //System.load(File(File(vlcDir, "vlc"), libXcb).absolutePath) + System.setProperty("jna.library.path", vlcDir.absolutePath) + //discoverVlcLibs(File(File(vlcDir, "vlc"), "plugins").absolutePath) + libsTmpDir.deleteRecursively() initHS() } @@ -39,7 +50,12 @@ private fun copyResources(from: String, to: Path) { return FileVisitResult.CONTINUE } override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult { - Files.copy(file, to.resolve(resPath.relativize(file).toString()), StandardCopyOption.REPLACE_EXISTING) + val dest = to.resolve(resPath.relativize(file).toString()) + Files.copy(file, dest, StandardCopyOption.REPLACE_EXISTING) + // Setting the same time on file as the time set in script that generates VLC libs + if (dest.toString().contains("." + desktopPlatform.libExtension)) { + dest.setLastModifiedTime(FileTime.fromMillis(0)) + } return FileVisitResult.CONTINUE } }) diff --git a/apps/multiplatform/desktop/src/jvmMain/resources/distribute/SimpleX.desktop b/apps/multiplatform/desktop/src/jvmMain/resources/distribute/SimpleX.desktop index 225a7812ba..79281a4dc8 100644 --- a/apps/multiplatform/desktop/src/jvmMain/resources/distribute/SimpleX.desktop +++ b/apps/multiplatform/desktop/src/jvmMain/resources/distribute/SimpleX.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=Application Name=SimpleX Chat -Comment=Private and secure open-source messenger - no user IDs (not even random numbers). +Comment=Private and secure open-source messenger - no user IDs (not even random numbers) Exec=/opt/simplex/bin/simplex Icon=/opt/simplex/lib/simplex Categories=Network;Chat; diff --git a/apps/multiplatform/desktop/src/jvmMain/resources/distribute/chat.simplex.app.appdata.xml b/apps/multiplatform/desktop/src/jvmMain/resources/distribute/chat.simplex.app.appdata.xml new file mode 100644 index 0000000000..9f9b2d6d20 --- /dev/null +++ b/apps/multiplatform/desktop/src/jvmMain/resources/distribute/chat.simplex.app.appdata.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component type="desktop-application"> + <id>chat.simplex.app</id> + <launchable type="desktop-id">chat.simplex.app.desktop</launchable> + <metadata_license>FSFAP</metadata_license> + <project_license>AGPL-3.0</project_license> + <name>SimpleX</name> + <summary>Private and secure open-source messenger - no user IDs (not even random numbers)</summary> + + <description> + <p>Security assessment was done by Trail of Bits in November 2022.</p> + <p>SimpleX Chat features:</p> + <ul> + <li>end-to-end encrypted messages, with editing, replies and deletion of messages.</li> + <li>sending end-to-end encrypted images and files.</li> + <li>single-use and long-term user addresses.</li> + <li>secret chat groups - only group members know it exists and who is the member.</li> + <li>end-to-end encrypted audio and video calls.</li> + <li>private instant notifications.</li> + <li>portable chat profile - you can transfer your chat contacts and history to another device (terminal or mobile).</li> + <li>encrypted app database and files in the app storage (except videos).</li> + <li>18 interface languages.</li> + </ul> + <p>SimpleX Chat advantages:</p> + <ul> + <li><em>Full privacy of your identity, profile, contacts and metadata</em>: unlike any other existing messaging platform, SimpleX uses no phone numbers or any other identifiers assigned to the users - not even random numbers. This protects the privacy of who you are communicating with, hiding it from SimpleX platform servers and from any observers.</li> + <li><em>Complete protection against spam and abuse</em>: as you have no identifier on SimpleX platform, you cannot be contacted unless you share a one-time invitation link or an optional temporary user address.</li> + <li><em>Full ownership, control and security of your data</em>: SimpleX stores all user data on client devices, the messages are only held temporarily on SimpleX relay servers until they are received.</li> + <li><em>Decentralized network</em>: you can use SimpleX with your own servers and still communicate with people using the servers that are pre-configured in the apps or any other SimpleX servers.</li> + </ul> + <p>You can connect to anybody you know via link or scan QR code (in the video call or in person) and start sending messages instantly - no emails, phone numbers or passwords needed.</p> + <p>Your profile and contacts are only stored in the app on your device - our servers do not have access to this information.</p> + <p>All messages are end-to-end encrypted using open-source double-ratchet protocol; the messages are routed via our servers using open-source SimpleX Messaging Protocol.</p> + <p>Please send us any questions via the app or submit an issue on GitHub.</p> + <p>Follow us on Mastodon, Twitter and Reddit for the latest updates.</p> + <p>Once you install SimpleX Chat, "connect to developers" for any questions, to share feedback, and to discover the groups (the link for directory service will be in response).</p> + </description> + + <screenshots> + <screenshot type="default"> + <image>https://simplex.chat/img/simplex-desktop-linux-light.png</image> + </screenshot> + <screenshot> + <image>https://simplex.chat/img/simplex-desktop-linux-dark-1.png</image> + </screenshot> + <screenshot> + <image>https://simplex.chat/img/simplex-desktop-linux-dark-2.png</image> + </screenshot> + </screenshots> + + <url type="homepage">https://simplex.chat</url> + <url type="bugtracker">https://github.com/simplex-chat/simplex-chat/issues</url> + <url type="translate">https://github.com/simplex-chat/simplex-chat#help-translating-simplex-chat</url> + <url type="contact">https://simplex.chat/connect-team</url> + <url type="donation">https://github.com/simplex-chat/simplex-chat#help-us-with-donations</url> + + <content_rating type="oars-1.1"/> + + <releases> + <release version="5.3" date="2023-09-19"> + <description> + <p>- the first release of the desktop app!</p> + <p>- encrypted local files</p> + <p>- message delivery receipts in small groups</p> + <p>- 6 new interface languages: Arabic, Bulgarian, Finnish, Hebrew, Thai and Ukrainian</p> + </description> + </release> + </releases> +</component> diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index 4352b8eb81..e8ca8faa21 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -25,11 +25,11 @@ android.nonTransitiveRClass=true android.enableJetifier=true kotlin.mpp.androidSourceSetLayoutVersion=2 -android.version_name=5.3-beta.7 -android.version_code=149 +android.version_name=5.3-beta.8 +android.version_code=150 -desktop.version_name=1.5.0 -desktop.version_code=7 +desktop.version_name=1.6.0 +desktop.version_code=8 kotlin.version=1.8.20 gradle.plugin.version=7.4.2 diff --git a/apps/simplex-bot-advanced/Main.hs b/apps/simplex-bot-advanced/Main.hs index f30438c384..04d8e4ffa1 100644 --- a/apps/simplex-bot-advanced/Main.hs +++ b/apps/simplex-bot-advanced/Main.hs @@ -8,7 +8,7 @@ module Main where import Control.Concurrent.Async import Control.Concurrent.STM -import Control.Monad.Reader +import Control.Monad import qualified Data.Text as T import Simplex.Chat.Bot import Simplex.Chat.Controller diff --git a/apps/simplex-broadcast-bot/src/Broadcast/Bot.hs b/apps/simplex-broadcast-bot/src/Broadcast/Bot.hs index 3a1be2ae08..04b6627f38 100644 --- a/apps/simplex-broadcast-bot/src/Broadcast/Bot.hs +++ b/apps/simplex-broadcast-bot/src/Broadcast/Bot.hs @@ -9,7 +9,7 @@ module Broadcast.Bot where import Control.Concurrent (forkIO) import Control.Concurrent.Async import Control.Concurrent.STM -import Control.Monad.Reader +import Control.Monad import qualified Data.Text as T import Broadcast.Options import Simplex.Chat.Bot diff --git a/apps/simplex-chat/Server.hs b/apps/simplex-chat/Server.hs index d59adc04e7..6f198340f8 100644 --- a/apps/simplex-chat/Server.hs +++ b/apps/simplex-chat/Server.hs @@ -8,6 +8,7 @@ module Server where +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Data.Aeson (FromJSON, ToJSON) diff --git a/apps/simplex-directory-service/src/Directory/Service.hs b/apps/simplex-directory-service/src/Directory/Service.hs index 09ab424cf0..46abc4652d 100644 --- a/apps/simplex-directory-service/src/Directory/Service.hs +++ b/apps/simplex-directory-service/src/Directory/Service.hs @@ -15,7 +15,7 @@ where import Control.Concurrent (forkIO) import Control.Concurrent.Async import Control.Concurrent.STM -import Control.Monad.Reader +import Control.Monad import qualified Data.ByteString.Char8 as B import Data.List (sortOn) import Data.Maybe (fromMaybe, maybeToList) diff --git a/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.md b/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.md new file mode 100644 index 0000000000..ba076295c0 --- /dev/null +++ b/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.md @@ -0,0 +1,15 @@ +--- +layout: layouts/article.html +title: "SimpleX Chat v5.3 released: desktop app, local file encryption and improved groups with directory service" +date: 2023-09-25 +# image: images/20230925-desktop-app.png +# previewBody: blog_previews/20230722.html +permalink: "/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.html" +draft: true +--- + +# SimpleX Chat v5.3 released: desktop app, local file encryption and improved groups + +**Published:** September 25, 2023 + +This is a placeholder for the release announcement diff --git a/cabal.project b/cabal.project index 983468726a..b4024f088c 100644 --- a/cabal.project +++ b/cabal.project @@ -2,14 +2,14 @@ packages: . -- packages: . ../simplexmq -- packages: . ../simplexmq ../direct-sqlcipher ../sqlcipher-simple -with-compiler: ghc-8.10.7 +with-compiler: ghc-9.6.2 constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 0cabe0690beee90f460ad7bada72294222e7e109 + tag: 8d47f690838371bc848e4b31a4b09ef6bf67ccc5 source-repository-package type: git @@ -24,17 +24,17 @@ source-repository-package source-repository-package type: git location: https://github.com/simplex-chat/direct-sqlcipher.git - tag: 34309410eb2069b029b8fc1872deb1e0db123294 + tag: f814ee68b16a9447fbb467ccc8f29bdd3546bfd9 source-repository-package type: git location: https://github.com/simplex-chat/sqlcipher-simple.git - tag: 5e154a2aeccc33ead6c243ec07195ab673137221 + tag: a46bd361a19376c5211f1058908fc0ae6bf42446 source-repository-package type: git location: https://github.com/simplex-chat/aeson.git - tag: 3eb66f9a68f103b5f1489382aad89f5712a64db7 + tag: 68330dce8208173c6acf5f62b23acb500ab5d873 source-repository-package type: git @@ -43,5 +43,10 @@ source-repository-package source-repository-package type: git - location: https://github.com/zw3rk/android-support.git - tag: 3c3a5ab0b8b137a072c98d3d0937cbdc96918ddb + location: https://github.com/simplex-chat/android-support.git + tag: 9aa09f148089d6752ce563b14c2df1895718d806 + +source-repository-package + type: git + location: https://github.com/simplex-chat/network-transport.git + tag: 0013798272a683e35ca38d2fdaf480942311fba8 diff --git a/docs/CLI.md b/docs/CLI.md index 65de29e601..7966627c4a 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -16,7 +16,7 @@ revision: 31.01.2023 - [Windows](#windows) - [Build from source](#build-from-source) - [Using Docker](#using-docker) - - [Using Haskell stack](#using-haskell-stack) + - [Using Haskell in any OS](#in-any-os) - [Usage](#usage) - [Running the chat client](#running-the-chat-client) - [Access messaging servers via Tor](#access-messaging-servers-via-tor-beta) @@ -102,27 +102,49 @@ DOCKER_BUILDKIT=1 docker build --output ~/.local/bin . #### In any OS -1. Install [Haskell GHCup](https://www.haskell.org/ghcup/), GHC 8.10.7 and cabal: +1. Install [Haskell GHCup](https://www.haskell.org/ghcup/), GHC 9.6.2 and cabal 3.10.1.0: ```shell curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh ``` -2. Build the project: +You can use `ghcup tui` to check or add GHC and cabal versions. + +2. Clone the source code: ```shell git clone git@github.com:simplex-chat/simplex-chat.git cd simplex-chat git checkout stable -# on Linux +# or to build a specific version: +# git checkout v5.3.0-beta.8 +``` + +`master` is a development branch, it may containt unstable code. + +3. Prepare the system: + +On Linux: + +```shell apt-get update && apt-get install -y build-essential libgmp3-dev zlib1g-dev cp scripts/cabal.project.local.linux cabal.project.local -# or on MacOS: -# brew install openssl@1.1 -# cp scripts/cabal.project.local.mac cabal.project.local -# you may need to amend cabal.project.local to point to the actual openssl location +``` + +On Mac: + +``` +brew install openssl@1.1 +cp scripts/cabal.project.local.mac cabal.project.local +``` + +You may need to amend cabal.project.local to point to the actual openssl location. + +4. Build the app: + +```shell cabal update -cabal install +cabal install simplex-chat ``` ## Usage diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index ef58bfec04..dc18bebb02 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -24,3 +24,88 @@ MacOS comes with LibreSSL as default, OpenSSL must be installed to compile Simpl OpenSSL can be installed with `brew install openssl@1.1` You will have to add `/opt/homebrew/opt/openssl@1.1/bin` to your PATH in order to have things working properly + + +## Project branches + +**In simplex-chat repo** + +- `stable` - stable release of the apps, can be used for updates to the previous stable release (GHC 9.6.2). + +- `stable-android` - used to build stable Android core library with Nix (GHC 8.10.7). + +- `stable-ios` - used to build stable iOS core library with Nix (GHC 8.10.7) – this branch should be the same as `stable-android` except Nix configuration files. + +- `master` - branch for beta version releases (GHC 9.6.2). + +- `master-android` - used to build beta Android core library with Nix (GHC 8.10.7). + +- `master-ios` - used to build beta iOS core library with Nix (GHC 8.10.7) – this branch should be the same as `master-android` except Nix configuration files. + +**In simplexmq repo** + +- `master` - uses GHC 9.6.2 its commit should be used in `master` branch of simplex-chat repo. + +- `master-ghc8107` - its commit should be used in `master-android` (and `master-ios`) branch of simplex-chat repo. + +## Development & release process + +1. Make PRs to `master` branch _only_ for both simplex-chat and simplexmq repos. + +2. If simplexmq repo was changed, to build mobile core libraries you need to merge its `master` branch into `master-ghc8107` branch. + +3. To build Android core library: +- merge `master` branch to `master-android` branch. +- update code to be compatible with GHC 8.10.7 (see below). +- update `simplexmq` commit in `master-android` branch to the commit in `master-ghc8107` branch. +- push to GitHub. + +4. To build iOS core library, merge `master-android` branch to `master-ios` branch, and push to GitHub. + +5. To build Desktop and CLI apps, make tag in `master` branch, APK files should be attached to the release. + +6. After the public release to App Store and Play Store, merge: +- `master` to `stable` +- `master` to `master-android` (and compile/update code) +- `master-android` to `master-ios` +- `master-android` to `stable-android` +- `master-ios` to `stable-ios` + +7. Independently, `master` branch of simplexmq repo should be merged to `stable` branch on stable releases. + + +## Differences between GHC 8.10.7 and GHC 9.6.2 + +1. The main difference is related to `DuplicateRecordFields` extension. + +It is no longer possible in GHC 9.6.2 to specify type when using selectors, instead OverloadedRecordDot extension and syntax are used that need to be removed in GHC 8.10.7: + +```haskell +{-# LANGUAGE DuplicateRecordFields #-} +-- use this in GHC 9.6.2 when needed +{-# LANGUAGE OverloadedRecordDot #-} + +-- GHC 9.6.2 syntax +let x = record.field + +-- GHC 8.10.7 syntax removed in GHC 9.6.2 +let x = field (record :: Record) +``` + +It is still possible to specify type when using record update syntax, use this pragma to suppress compiler warning: + +```haskell +-- use this in GHC 9.6.2 when needed +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + +let r' = (record :: Record) {field = value} +``` + +2. Most monad functions now have to be imported from `Control.Monad`, and not from specific monad modules (e.g. `Control.Monad.Except`). + +```haskell +-- use this in GHC 9.6.2 when needed +import Control.Monad +``` + +[This PR](https://github.com/simplex-chat/simplex-chat/pull/2975/files) has all the differences. diff --git a/docs/DOWNLOADS.md b/docs/DOWNLOADS.md new file mode 100644 index 0000000000..948fecfc2e --- /dev/null +++ b/docs/DOWNLOADS.md @@ -0,0 +1,42 @@ +--- +title: Download SimpleX apps +permalink: /downloads/index.html +revision: 20.09.2023 +--- + +| Updated 20.09.2023 | Languages: EN | +# Download SimpleX apps + +- [desktop](#desktop-app) +- [mobile](#mobile-apps) +- [terminal](#terminal-console-app) (console) + +## Desktop app + +<img src="/docs/images/simplex-desktop-light.png" alt="desktop app" width=500> + +The latest version of desktop app is v5.3-beta.8 (1.6.0 in the app). + +Using the same profile as on mobile device is not yet supported – you need to create a separate profile to use desktop apps. + +**Linux**: [AppImage](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-desktop-x86_64.AppImage) (most Linux distros), [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-desktop-ubuntu-20_04-x86_64.deb) (and Debian-based distros), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-desktop-ubuntu-22_04-x86_64.deb). + +**Mac**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-desktop-macos-x86_64.dmg) (Intel), [aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-desktop-macos-aarch64.dmg) (Apple Silicon). + +**Windows**: coming soon. + +## Mobile apps + +**iOS**: [App store](https://apps.apple.com/us/app/simplex-chat/id1605771084) (v5.2.3), [TestFlight](https://testflight.apple.com/join/DWuT2LQu) (v5.3-beta.8). + +**Android**: [Play store](https://play.google.com/store/apps/details?id=chat.simplex.app), [F-Droid](https://simplex.chat/fdroid/), [APK aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex.apk), [APK armv7](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-armv7a.apk). + +## Terminal (console) app + +See [Using terminal app](/docs/CLI.md). + +**Linux**: [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-chat-ubuntu-20_04-x86-64), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-chat-ubuntu-22_04-x86-64). + +**Mac** [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-chat-macos-x86-64), aarch64 - [compile from source](./CLI.md#). + +**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.3.0-beta.8/simplex-chat-windows-x86-64). diff --git a/docs/JOIN_TEAM.md b/docs/JOIN_TEAM.md index c1f9e6c014..5a31b3e058 100644 --- a/docs/JOIN_TEAM.md +++ b/docs/JOIN_TEAM.md @@ -1,3 +1,9 @@ +--- +title: Join SimpleX Chat team +permalink: /jobs/index.html +layout: layouts/jobs.html +--- + # Join SimpleX Chat team SimpleX Chat Ltd is a seed stage startup with a lot of user growth in 2022-2023, and a lot of exciting technical and product problems to solve to grow faster. @@ -7,35 +13,6 @@ We currently have 4 full-time people in the team - all engineers, including the We want to add up to 3 people to the team. -**You**: - -- **Passionate about joining SimpleX Chat team**: - - already use SimpleX Chat to communicate with friends/family or participate in public SimpleX Chat groups. - - passionate about privacy, security and communications. - - interested to make contributions to SimpleX Chat open-source project in your free time before we hire you, as an extended test. - -- **Exceptionally pragmatic, very fast and customer-focussed**: - - care about the customers (aka users) and about the product we build much more than about the code quality, technology stack, etc. - - believe that the simplest solution is the best. - - 2-3x faster than the most competent people you worked with. - - focus on solving only today's problems and resist engineering for the future (aka over-engineering) – see [The Duct Tape Programmer](https://www.joelonsoftware.com/2009/09/23/the-duct-tape-programmer/) and [Why I Hate Frameworks](https://medium.com/@johnfliu/why-i-hate-frameworks-6af8cbadba42). - - do not suffer from "not invented here" syndrome, at the same time interested to design and implement protocols and systems from the ground up when appropriate. - -- **Love software engineering**: - - have 5y+ of software engineering experience in complex projects, - - great understanding of the common principles: - - data structures, bits and byte manipulation - - text encoding and manipulation - - software design and algorithms - - concurrency - - networking - -- **Want to join a very early stage startup**: - - high pace and intensity, longer hours. - - a substantial part of the compensation is stock options. - - full transparency – we believe that too much [autonomy](https://twitter.com/KentBeck/status/851459129830850561) hurts learning and slows down progress. - - ## Who we are looking for ### Systems Haskell engineer @@ -63,6 +40,35 @@ You are a product UX expert who designs great user experiences directly in iOS c Knowledge of Android and Kotlin Multiplatform would be a bonus - we use Kotlin Jetpack Compose for our Android and desktop apps. +## About you + +- **Passionate about joining SimpleX Chat team**: + - already use SimpleX Chat to communicate with friends/family or participate in public SimpleX Chat groups. + - passionate about privacy, security and communications. + - interested to make contributions to SimpleX Chat open-source project in your free time before we hire you, as an extended test. + +- **Exceptionally pragmatic, very fast and customer-focussed**: + - care about the customers (aka users) and about the product we build much more than about the code quality, technology stack, etc. + - believe that the simplest solution is the best. + - 2-3x faster than the most competent people you worked with. + - focus on solving only today's problems and resist engineering for the future (aka over-engineering) – see [The Duct Tape Programmer](https://www.joelonsoftware.com/2009/09/23/the-duct-tape-programmer/) and [Why I Hate Frameworks](https://medium.com/@johnfliu/why-i-hate-frameworks-6af8cbadba42). + - do not suffer from "not invented here" syndrome, at the same time interested to design and implement protocols and systems from the ground up when appropriate. + +- **Love software engineering**: + - have 5y+ of software engineering experience in complex projects, + - great understanding of the common principles: + - data structures, bits and byte manipulation + - text encoding and manipulation + - software design and algorithms + - concurrency + - networking + +- **Want to join a very early stage startup**: + - high pace and intensity, longer hours. + - a substantial part of the compensation is stock options. + - full transparency – we believe that too much [autonomy](https://twitter.com/KentBeck/status/851459129830850561) hurts learning and slows down progress. + + ## How to join the team 1. [Install the app](../README.md#install-the-app), try using it with the friends and [join some user groups](https://github.com/simplex-chat/simplex-chat#join-user-groups) – you will discover a lot of things that need improvements. diff --git a/website/src/img/simplex-desktop-dark-1.png b/docs/images/simplex-desktop-dark-1.png similarity index 100% rename from website/src/img/simplex-desktop-dark-1.png rename to docs/images/simplex-desktop-dark-1.png diff --git a/website/src/img/simplex-desktop-dark-2.png b/docs/images/simplex-desktop-dark-2.png similarity index 100% rename from website/src/img/simplex-desktop-dark-2.png rename to docs/images/simplex-desktop-dark-2.png diff --git a/website/src/img/simplex-desktop-light.png b/docs/images/simplex-desktop-light.png similarity index 100% rename from website/src/img/simplex-desktop-light.png rename to docs/images/simplex-desktop-light.png diff --git a/package.yaml b/package.yaml index 811a6cd8a6..58f84b3e92 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.3.0.7 +version: 5.3.0.9 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme @@ -13,25 +13,25 @@ extra-source-files: - cabal.project dependencies: - - aeson == 2.0.* + - aeson == 2.2.* - ansi-terminal >= 0.10 && < 0.12 - async == 2.2.* - attoparsec == 0.14.* - base >= 4.7 && < 5 - base64-bytestring >= 1.0 && < 1.3 - - bytestring == 0.10.* + - bytestring == 0.11.* - composition == 1.0.* - constraints >= 0.12 && < 0.14 - containers == 0.6.* - - cryptonite >= 0.27 && < 0.30 + - cryptonite == 0.30.* - directory == 1.3.* - direct-sqlcipher == 2.3.* - email-validate == 2.3.* - exceptions == 0.10.* - filepath == 1.4.* - http-types == 0.12.* - - memory == 0.15.* - - mtl == 2.2.* + - memory == 0.18.* + - mtl == 2.3.* - network >= 3.1.2.7 && < 3.2 - optparse-applicative >= 0.15 && < 0.17 - process == 1.6.* @@ -42,13 +42,13 @@ dependencies: - socks == 0.6.* - sqlcipher-simple == 0.4.* - stm == 2.5.* - - template-haskell == 2.16.* + - template-haskell == 2.20.* - terminal == 0.2.* - - text == 1.2.* + - text == 2.0.* - time == 1.9.* - unliftio == 0.2.* - unliftio-core == 0.2.* - - zip == 1.7.* + - zip == 2.0.* flags: swift: @@ -118,7 +118,7 @@ tests: - simplex-chat - async == 2.2.* - deepseq == 1.4.* - - hspec == 2.7.* + - hspec == 2.11.* - network == 3.1.* - silently == 1.2.* - stm == 2.5.* diff --git a/scripts/desktop/build-desktop-mac-ci.sh b/scripts/ci/build-desktop-mac.sh similarity index 63% rename from scripts/desktop/build-desktop-mac-ci.sh rename to scripts/ci/build-desktop-mac.sh index 07a3db9c8e..259b946228 100755 --- a/scripts/desktop/build-desktop-mac-ci.sh +++ b/scripts/ci/build-desktop-mac.sh @@ -2,7 +2,7 @@ set -e -trap "rm apps/multiplatform/local.properties || true; rm local.properties || true; rm /tmp/simplex.keychain || true" EXIT +trap "rm apps/multiplatform/local.properties 2> /dev/null || true; rm local.properties 2> /dev/null || true; rm /tmp/simplex.keychain" EXIT echo "desktop.mac.signing.identity=Developer ID Application: SimpleX Chat Ltd (5NN7GUYB6T)" >> apps/multiplatform/local.properties echo "desktop.mac.signing.keychain=/tmp/simplex.keychain" >> apps/multiplatform/local.properties echo "desktop.mac.notarization.apple_id=$APPLE_SIMPLEX_NOTARIZATION_APPLE_ID" >> apps/multiplatform/local.properties @@ -10,6 +10,10 @@ echo "desktop.mac.notarization.password=$APPLE_SIMPLEX_NOTARIZATION_PASSWORD" >> echo "desktop.mac.notarization.team_id=5NN7GUYB6T" >> apps/multiplatform/local.properties echo "$APPLE_SIMPLEX_SIGNING_KEYCHAIN" | base64 --decode - > /tmp/simplex.keychain +security unlock-keychain -p "" /tmp/simplex.keychain +# Adding keychain to the list of keychains. +# Otherwise, it can find cert but exits while signing with "error: The specified item could not be found in the keychain." +security list-keychains -s `security list-keychains | xargs` /tmp/simplex.keychain scripts/desktop/build-lib-mac.sh cd apps/multiplatform ./gradlew packageDmg diff --git a/scripts/ci/prepare-keychain-mac.sh b/scripts/ci/prepare-keychain-mac.sh new file mode 100644 index 0000000000..912e6285af --- /dev/null +++ b/scripts/ci/prepare-keychain-mac.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +security create-keychain -p "" simplex.keychain +security set-keychain-settings -u simplex.keychain +security add-certificates -k simplex.keychain "Developer ID Application: SimpleX Chat Ltd (5NN7GUYB6T).cer" +security add-certificates -k simplex.keychain "Developer ID Certification Authority.cer" +# Private key with access from any app +security import "SimpleX Chat.p12" -P "" -k simplex.keychain -A +# Public key +security import "SimpleX Chat.pem" -k simplex.keychain diff --git a/scripts/desktop/build-lib-linux.sh b/scripts/desktop/build-lib-linux.sh index 41ca8a64f7..2d9681fc6f 100755 --- a/scripts/desktop/build-lib-linux.sh +++ b/scripts/desktop/build-lib-linux.sh @@ -2,12 +2,12 @@ OS=linux ARCH=${1:-`uname -a | rev | cut -d' ' -f2 | rev`} -GHC_VERSION=8.10.7 +GHC_VERSION=9.6.2 BUILD_DIR=dist-newstyle/build/$ARCH-$OS/ghc-${GHC_VERSION}/simplex-chat-* rm -rf $BUILD_DIR -cabal build lib:simplex-chat --ghc-options='-optl-Wl,-rpath,$ORIGIN' --ghc-options="-optl-L$(ghc --print-libdir)/rts -optl-Wl,--as-needed,-lHSrts_thr-ghc$GHC_VERSION" +cabal build lib:simplex-chat --ghc-options='-optl-Wl,-rpath,$ORIGIN -flink-rts -threaded' cd $BUILD_DIR/build #patchelf --add-needed libHSrts_thr-ghc${GHC_VERSION}.so libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so #patchelf --add-rpath '$ORIGIN' libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so @@ -23,3 +23,4 @@ rm -rf apps/multiplatform/desktop/build/cmake mkdir -p apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp -r $BUILD_DIR/build/deps apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp $BUILD_DIR/build/libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ +scripts/desktop/prepare-vlc-linux.sh diff --git a/scripts/desktop/build-lib-mac.sh b/scripts/desktop/build-lib-mac.sh index 5a8ac3d3fb..50bc09df57 100755 --- a/scripts/desktop/build-lib-mac.sh +++ b/scripts/desktop/build-lib-mac.sh @@ -2,9 +2,12 @@ OS=mac ARCH="${1:-`uname -a | rev | cut -d' ' -f1 | rev`}" +GHC_VERSION=9.6.2 + if [ "$ARCH" == "arm64" ]; then ARCH=aarch64 fi + LIB_EXT=dylib LIB=libHSsimplex-chat-*-inplace-ghc*.$LIB_EXT GHC_LIBS_DIR=$(ghc --print-libdir) @@ -12,13 +15,26 @@ GHC_LIBS_DIR=$(ghc --print-libdir) BUILD_DIR=dist-newstyle/build/$ARCH-*/ghc-*/simplex-chat-* rm -rf $BUILD_DIR -cabal build lib:simplex-chat lib:simplex-chat --ghc-options="-optl-Wl,-rpath,@loader_path -optl-Wl,-L$GHC_LIBS_DIR/rts -optl-lHSrts_thr-ghc8.10.7 -optl-lffi" +cabal build lib:simplex-chat lib:simplex-chat --ghc-options="-optl-Wl,-rpath,@loader_path -optl-Wl,-L$GHC_LIBS_DIR/$ARCH-osx-ghc-$GHC_VERSION -optl-lHSrts_thr-ghc$GHC_VERSION -optl-lffi" cd $BUILD_DIR/build mkdir deps 2> /dev/null # It's not included by default for some reason. Compiled lib tries to find system one but it's not always available -cp $GHC_LIBS_DIR/rts/libffi.dylib ./deps +#cp $GHC_LIBS_DIR/libffi.dylib ./deps +( + BUILD=$PWD + cp /tmp/libffi-3.4.4/*-apple-darwin*/.libs/libffi.dylib $BUILD/deps || \ + ( \ + cd /tmp && \ + curl "https://gitlab.haskell.org/ghc/libffi-tarballs/-/raw/libffi-3.4.4/libffi-3.4.4.tar.gz?inline=false" -o libffi.tar.gz && \ + tar -xzvf libffi.tar.gz && \ + cd "libffi-3.4.4" && \ + ./configure && \ + make && \ + cp *-apple-darwin*/.libs/libffi.dylib $BUILD/deps \ + ) +) DYLIBS=`otool -L $LIB | grep @rpath | tail -n +2 | cut -d' ' -f 1 | cut -d'/' -f2` RPATHS=`otool -l $LIB | grep "path "| cut -d' ' -f11` @@ -59,11 +75,13 @@ function copy_deps() { } copy_deps $LIB +# Special case +cp $(ghc --print-libdir)/$ARCH-osx-ghc-$GHC_VERSION/libHSghc-boot-th-$GHC_VERSION-ghc$GHC_VERSION.dylib deps rm deps/`basename $LIB` if [ -e deps/libHSdrct-*.$LIB_EXT ]; then LIBCRYPTO_PATH=$(otool -l deps/libHSdrct-*.$LIB_EXT | grep libcrypto | cut -d' ' -f11) - install_name_tool -change $LIBCRYPTO_PATH @rpath/libcrypto.1.1.$LIB_EXT deps/libHSdrct*.$LIB_EXT + install_name_tool -change $LIBCRYPTO_PATH @rpath/libcrypto.1.1.$LIB_EXT deps/libHSdrct-*.$LIB_EXT cp $LIBCRYPTO_PATH deps/libcrypto.1.1.$LIB_EXT chmod 755 deps/libcrypto.1.1.$LIB_EXT fi @@ -77,3 +95,4 @@ rm -rf apps/multiplatform/desktop/build/cmake mkdir -p apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp -r $BUILD_DIR/build/deps apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp $BUILD_DIR/build/libHSsimplex-chat-*-inplace-ghc*.$LIB_EXT apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ +scripts/desktop/prepare-vlc-mac.sh diff --git a/scripts/desktop/make-appimage-linux.sh b/scripts/desktop/make-appimage-linux.sh index bf00df439d..e71b097c7d 100755 --- a/scripts/desktop/make-appimage-linux.sh +++ b/scripts/desktop/make-appimage-linux.sh @@ -12,7 +12,7 @@ release_app_dir=$root_dir/apps/multiplatform/release/main/app cd $multiplatform_dir libcrypto_path=$(ldd common/src/commonMain/cpp/desktop/libs/*/deps/libHSdirect-sqlcipher-*.so | grep libcrypto | cut -d'=' -f 2 | cut -d ' ' -f 2) - +trap "rm common/src/commonMain/cpp/desktop/libs/*/deps/`basename $libcrypto_path` 2> /dev/null" EXIT cp $libcrypto_path common/src/commonMain/cpp/desktop/libs/*/deps ./gradlew createDistributable @@ -27,13 +27,15 @@ cp -r ../*imple*/{bin,lib} usr cp usr/lib/simplex.png . # For https://github.com/TheAssassin/AppImageLauncher to be able to show the icon -mkdir -p usr/share/icons +mkdir -p usr/share/{icons,metainfo,applications} cp usr/lib/simplex.png usr/share/icons ln -s usr/bin/*imple* AppRun -cp $multiplatform_dir/desktop/src/jvmMain/resources/distribute/*imple*.desktop . +cp $multiplatform_dir/desktop/src/jvmMain/resources/distribute/*imple*.desktop chat.simplex.app.desktop sed -i 's|Exec=.*|Exec=simplex|g' *imple*.desktop sed -i 's|Icon=.*|Icon=simplex|g' *imple*.desktop +cp *imple*.desktop usr/share/applications/ +cp $multiplatform_dir/desktop/src/jvmMain/resources/distribute/*.appdata.xml usr/share/metainfo if [ ! -f ../appimagetool-x86_64.AppImage ]; then wget https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage -O ../appimagetool-x86_64.AppImage diff --git a/scripts/desktop/prepare-vlc-linux.sh b/scripts/desktop/prepare-vlc-linux.sh new file mode 100755 index 0000000000..e1cfa7e9fc --- /dev/null +++ b/scripts/desktop/prepare-vlc-linux.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +set -e + +function readlink() { + echo "$(cd "$(dirname "$1")"; pwd -P)" +} +root_dir="$(dirname "$(dirname "$(readlink "$0")")")" +vlc_dir=$root_dir/apps/multiplatform/common/src/commonMain/cpp/desktop/libs/linux-x86_64/deps/vlc + +mkdir $vlc_dir || exit 0 + + +cd /tmp +mkdir tmp 2>/dev/null || true +cd tmp +curl https://github.com/cmatomic/VLCplayer-AppImage/releases/download/3.0.11.1/VLC_media_player-3.0.11.1-x86_64.AppImage -L -o appimage +chmod +x appimage +./appimage --appimage-extract +cp -r squashfs-root/usr/lib/* $vlc_dir +cd ../ +rm -rf tmp +exit 0 + + +# This is currently unneeded +cd /tmp +( +mkdir tmp +cd tmp +curl http://archive.ubuntu.com/ubuntu/pool/universe/v/vlc/libvlc5_3.0.9.2-1_amd64.deb -o libvlc +ar p libvlc data.tar.xz > data.tar.xz +tar -xvf data.tar.xz +mv usr/lib/x86_64-linux-gnu/libvlc.so{.5,} +cp usr/lib/x86_64-linux-gnu/libvlc.so* $vlc_dir +cd ../ +rm -rf tmp +) + +( +mkdir tmp +cd tmp +curl http://archive.ubuntu.com/ubuntu/pool/universe/v/vlc/libvlccore9_3.0.9.2-1_amd64.deb -o libvlccore +ar p libvlccore data.tar.xz > data.tar.xz +tar -xvf data.tar.xz +cp usr/lib/x86_64-linux-gnu/libvlccore.so* $vlc_dir +cd ../ +rm -rf tmp +) + +( +mkdir tmp +cd tmp +curl http://mirrors.edge.kernel.org/ubuntu/pool/universe/v/vlc/vlc-plugin-base_3.0.9.2-1_amd64.deb -o plugins +ar p plugins data.tar.xz > data.tar.xz +tar -xvf data.tar.xz +find usr/lib/x86_64-linux-gnu/vlc/plugins/ -name "lib*.so*" -exec patchelf --set-rpath '$ORIGIN/../../' {} \; +cp -r usr/lib/x86_64-linux-gnu/vlc/{libvlc*,plugins} $vlc_dir +cd ../ +rm -rf tmp +) + +( +mkdir tmp +cd tmp +curl http://archive.ubuntu.com/ubuntu/pool/main/libi/libidn/libidn11_1.33-2.2ubuntu2_amd64.deb -o idn +ar p idn data.tar.xz > data.tar.xz +tar -xvf data.tar.xz +cp lib/x86_64-linux-gnu/lib* $vlc_dir +cd ../ +rm -rf tmp +) + +find $vlc_dir -maxdepth 1 -name "lib*.so*" -exec patchelf --set-rpath '$ORIGIN' {} \; diff --git a/scripts/desktop/prepare-vlc-mac.sh b/scripts/desktop/prepare-vlc-mac.sh new file mode 100755 index 0000000000..69644bcc16 --- /dev/null +++ b/scripts/desktop/prepare-vlc-mac.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +set -e + +ARCH="${1:-`uname -a | rev | cut -d' ' -f1 | rev`}" +if [ "$ARCH" == "arm64" ]; then + ARCH=aarch64 + vlc_arch=arm64 +else + vlc_arch=intel64 +fi +vlc_version=3.0.19 + +function readlink() { + echo "$(cd "$(dirname "$1")"; pwd -P)" +} + +root_dir="$(dirname "$(dirname "$(readlink "$0")")")" +vlc_dir=$root_dir/apps/multiplatform/common/src/commonMain/cpp/desktop/libs/mac-$ARCH/deps/vlc +#rm -rf $vlc_dir +mkdir -p $vlc_dir/vlc || exit 0 + +cd /tmp +mkdir tmp 2>/dev/null || true +cd tmp +curl https://github.com/simplex-chat/vlc/releases/download/v$vlc_version/vlc-macos-$ARCH.zip -L -o vlc +unzip -oqq vlc +install_name_tool -add_rpath "@loader_path/VLC.app/Contents/MacOS/lib" vlc-cache-gen +cd VLC.app/Contents/MacOS/lib +for lib in $(ls *.dylib); do install_name_tool -add_rpath "@loader_path" $lib 2> /dev/null || true; done +cd ../plugins +for lib in $(ls *.dylib); do + install_name_tool -add_rpath "@loader_path/../../" $lib 2> /dev/null || true +done +cd .. +../../../vlc-cache-gen plugins +cp lib/* $vlc_dir/ +cp -r -p plugins/ $vlc_dir/vlc/plugins +cd ../../../../ +rm -rf tmp diff --git a/scripts/ios/export-localizations.sh b/scripts/ios/export-localizations.sh index df880e2694..cc6eed25a9 100755 --- a/scripts/ios/export-localizations.sh +++ b/scripts/ios/export-localizations.sh @@ -2,7 +2,7 @@ set -e -langs=( en cs de es fi fr it ja nl pl ru uk zh-Hans ) +langs=( en bg cs de es fi fr it ja nl pl ru uk zh-Hans ) for lang in "${langs[@]}"; do echo "***" diff --git a/scripts/ios/import-localizations.sh b/scripts/ios/import-localizations.sh index 542c3a7f61..c699966d79 100755 --- a/scripts/ios/import-localizations.sh +++ b/scripts/ios/import-localizations.sh @@ -2,7 +2,7 @@ set -e -langs=( en cs de es fi fr it ja nl pl ru th uk zh-Hans ) +langs=( en bg cs de es fi fr it ja nl pl ru th uk zh-Hans ) for lang in "${langs[@]}"; do echo "***" diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 493985085a..26f4ea1122 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,10 +1,11 @@ { - "https://github.com/simplex-chat/simplexmq.git"."0cabe0690beee90f460ad7bada72294222e7e109" = "1yfcrifb2l59wgl14q56ywlil2g2zs57ic62s617whh3w2mnh0kz"; + "https://github.com/simplex-chat/simplexmq.git"."8d47f690838371bc848e4b31a4b09ef6bf67ccc5" = "1pwasv22ii3wy4xchaknlwczmy5ws7adx7gg2g58lxzrgdjm3650"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/kazu-yamamoto/http2.git"."b5a1b7200cf5bc7044af34ba325284271f6dff25" = "0dqb50j57an64nf4qcf5vcz4xkd1vzvghvf8bk529c1k30r9nfzb"; - "https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd"; - "https://github.com/simplex-chat/sqlcipher-simple.git"."5e154a2aeccc33ead6c243ec07195ab673137221" = "1d1gc5wax4vqg0801ajsmx1sbwvd9y7p7b8mmskvqsmpbwgbh0m0"; - "https://github.com/simplex-chat/aeson.git"."3eb66f9a68f103b5f1489382aad89f5712a64db7" = "0kilkx59fl6c3qy3kjczqvm8c3f4n3p0bdk9biyflf51ljnzp4yp"; + "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "0kiwhvml42g9anw4d2v0zd1fpc790pj9syg5x3ik4l97fnkbbwpp"; + "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; + "https://github.com/simplex-chat/aeson.git"."68330dce8208173c6acf5f62b23acb500ab5d873" = "1l51p1v54c88c1jmxcvbz4gy0cns7l46ihzzfjwxxrvcrrrxgcjp"; "https://github.com/simplex-chat/haskell-terminal.git"."f708b00009b54890172068f168bf98508ffcd495" = "0zmq7lmfsk8m340g47g5963yba7i88n4afa6z93sg9px5jv1mijj"; - "https://github.com/zw3rk/android-support.git"."3c3a5ab0b8b137a072c98d3d0937cbdc96918ddb" = "1r6jyxbim3dsvrmakqfyxbd6ms6miaghpbwyl0sr6dzwpgaprz97"; + "https://github.com/simplex-chat/android-support.git"."9aa09f148089d6752ce563b14c2df1895718d806" = "0pbf2pf13v2kjzi397nr13f1h3jv0imvsq8rpiyy2qyx5vd50pqn"; + "https://github.com/simplex-chat/network-transport.git"."0013798272a683e35ca38d2fdaf480942311fba8" = "0dnn62apgvc248df0m8ib7phrzn63wm0xs71xvlypv52j6cgwzkb"; } diff --git a/simplex-chat.cabal b/simplex-chat.cabal index ebd3d1d646..33c09d15cb 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.3.0.7 +version: 5.3.0.9 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat @@ -111,6 +111,8 @@ library Simplex.Chat.Migrations.M20230827_file_encryption Simplex.Chat.Migrations.M20230829_connections_chat_vrange Simplex.Chat.Migrations.M20230903_connections_to_subscribe + Simplex.Chat.Migrations.M20230913_member_contacts + Simplex.Chat.Migrations.M20230914_member_probes Simplex.Chat.Mobile Simplex.Chat.Mobile.File Simplex.Chat.Mobile.Shared @@ -143,25 +145,25 @@ library src ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns build-depends: - aeson ==2.0.* + aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 , async ==2.2.* , attoparsec ==0.14.* , base >=4.7 && <5 , base64-bytestring >=1.0 && <1.3 - , bytestring ==0.10.* + , bytestring ==0.11.* , composition ==1.0.* , constraints >=0.12 && <0.14 , containers ==0.6.* - , cryptonite >=0.27 && <0.30 + , cryptonite ==0.30.* , direct-sqlcipher ==2.3.* , directory ==1.3.* , email-validate ==2.3.* , exceptions ==0.10.* , filepath ==1.4.* , http-types ==0.12.* - , memory ==0.15.* - , mtl ==2.2.* + , memory ==0.18.* + , mtl ==2.3.* , network >=3.1.2.7 && <3.2 , optparse-applicative >=0.15 && <0.17 , process ==1.6.* @@ -172,13 +174,13 @@ library , socks ==0.6.* , sqlcipher-simple ==0.4.* , stm ==2.5.* - , template-haskell ==2.16.* + , template-haskell ==2.20.* , terminal ==0.2.* - , text ==1.2.* + , text ==2.0.* , time ==1.9.* , unliftio ==0.2.* , unliftio-core ==0.2.* - , zip ==1.7.* + , zip ==2.0.* default-language: Haskell2010 if flag(swift) cpp-options: -DswiftJSON @@ -191,25 +193,25 @@ executable simplex-bot apps/simplex-bot ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded build-depends: - aeson ==2.0.* + aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 , async ==2.2.* , attoparsec ==0.14.* , base >=4.7 && <5 , base64-bytestring >=1.0 && <1.3 - , bytestring ==0.10.* + , bytestring ==0.11.* , composition ==1.0.* , constraints >=0.12 && <0.14 , containers ==0.6.* - , cryptonite >=0.27 && <0.30 + , cryptonite ==0.30.* , direct-sqlcipher ==2.3.* , directory ==1.3.* , email-validate ==2.3.* , exceptions ==0.10.* , filepath ==1.4.* , http-types ==0.12.* - , memory ==0.15.* - , mtl ==2.2.* + , memory ==0.18.* + , mtl ==2.3.* , network >=3.1.2.7 && <3.2 , optparse-applicative >=0.15 && <0.17 , process ==1.6.* @@ -221,13 +223,13 @@ executable simplex-bot , socks ==0.6.* , sqlcipher-simple ==0.4.* , stm ==2.5.* - , template-haskell ==2.16.* + , template-haskell ==2.20.* , terminal ==0.2.* - , text ==1.2.* + , text ==2.0.* , time ==1.9.* , unliftio ==0.2.* , unliftio-core ==0.2.* - , zip ==1.7.* + , zip ==2.0.* default-language: Haskell2010 if flag(swift) cpp-options: -DswiftJSON @@ -240,25 +242,25 @@ executable simplex-bot-advanced apps/simplex-bot-advanced ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded build-depends: - aeson ==2.0.* + aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 , async ==2.2.* , attoparsec ==0.14.* , base >=4.7 && <5 , base64-bytestring >=1.0 && <1.3 - , bytestring ==0.10.* + , bytestring ==0.11.* , composition ==1.0.* , constraints >=0.12 && <0.14 , containers ==0.6.* - , cryptonite >=0.27 && <0.30 + , cryptonite ==0.30.* , direct-sqlcipher ==2.3.* , directory ==1.3.* , email-validate ==2.3.* , exceptions ==0.10.* , filepath ==1.4.* , http-types ==0.12.* - , memory ==0.15.* - , mtl ==2.2.* + , memory ==0.18.* + , mtl ==2.3.* , network >=3.1.2.7 && <3.2 , optparse-applicative >=0.15 && <0.17 , process ==1.6.* @@ -270,13 +272,13 @@ executable simplex-bot-advanced , socks ==0.6.* , sqlcipher-simple ==0.4.* , stm ==2.5.* - , template-haskell ==2.16.* + , template-haskell ==2.20.* , terminal ==0.2.* - , text ==1.2.* + , text ==2.0.* , time ==1.9.* , unliftio ==0.2.* , unliftio-core ==0.2.* - , zip ==1.7.* + , zip ==2.0.* default-language: Haskell2010 if flag(swift) cpp-options: -DswiftJSON @@ -291,25 +293,25 @@ executable simplex-broadcast-bot apps/simplex-broadcast-bot/src ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded build-depends: - aeson ==2.0.* + aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 , async ==2.2.* , attoparsec ==0.14.* , base >=4.7 && <5 , base64-bytestring >=1.0 && <1.3 - , bytestring ==0.10.* + , bytestring ==0.11.* , composition ==1.0.* , constraints >=0.12 && <0.14 , containers ==0.6.* - , cryptonite >=0.27 && <0.30 + , cryptonite ==0.30.* , direct-sqlcipher ==2.3.* , directory ==1.3.* , email-validate ==2.3.* , exceptions ==0.10.* , filepath ==1.4.* , http-types ==0.12.* - , memory ==0.15.* - , mtl ==2.2.* + , memory ==0.18.* + , mtl ==2.3.* , network >=3.1.2.7 && <3.2 , optparse-applicative >=0.15 && <0.17 , process ==1.6.* @@ -321,13 +323,13 @@ executable simplex-broadcast-bot , socks ==0.6.* , sqlcipher-simple ==0.4.* , stm ==2.5.* - , template-haskell ==2.16.* + , template-haskell ==2.20.* , terminal ==0.2.* - , text ==1.2.* + , text ==2.0.* , time ==1.9.* , unliftio ==0.2.* , unliftio-core ==0.2.* - , zip ==1.7.* + , zip ==2.0.* default-language: Haskell2010 if flag(swift) cpp-options: -DswiftJSON @@ -341,25 +343,25 @@ executable simplex-chat apps/simplex-chat ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded build-depends: - aeson ==2.0.* + aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 , async ==2.2.* , attoparsec ==0.14.* , base >=4.7 && <5 , base64-bytestring >=1.0 && <1.3 - , bytestring ==0.10.* + , bytestring ==0.11.* , composition ==1.0.* , constraints >=0.12 && <0.14 , containers ==0.6.* - , cryptonite >=0.27 && <0.30 + , cryptonite ==0.30.* , direct-sqlcipher ==2.3.* , directory ==1.3.* , email-validate ==2.3.* , exceptions ==0.10.* , filepath ==1.4.* , http-types ==0.12.* - , memory ==0.15.* - , mtl ==2.2.* + , memory ==0.18.* + , mtl ==2.3.* , network ==3.1.* , optparse-applicative >=0.15 && <0.17 , process ==1.6.* @@ -371,14 +373,14 @@ executable simplex-chat , socks ==0.6.* , sqlcipher-simple ==0.4.* , stm ==2.5.* - , template-haskell ==2.16.* + , template-haskell ==2.20.* , terminal ==0.2.* - , text ==1.2.* + , text ==2.0.* , time ==1.9.* , unliftio ==0.2.* , unliftio-core ==0.2.* , websockets ==0.12.* - , zip ==1.7.* + , zip ==2.0.* default-language: Haskell2010 if flag(swift) cpp-options: -DswiftJSON @@ -395,25 +397,25 @@ executable simplex-directory-service apps/simplex-directory-service/src ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded build-depends: - aeson ==2.0.* + aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 , async ==2.2.* , attoparsec ==0.14.* , base >=4.7 && <5 , base64-bytestring >=1.0 && <1.3 - , bytestring ==0.10.* + , bytestring ==0.11.* , composition ==1.0.* , constraints >=0.12 && <0.14 , containers ==0.6.* - , cryptonite >=0.27 && <0.30 + , cryptonite ==0.30.* , direct-sqlcipher ==2.3.* , directory ==1.3.* , email-validate ==2.3.* , exceptions ==0.10.* , filepath ==1.4.* , http-types ==0.12.* - , memory ==0.15.* - , mtl ==2.2.* + , memory ==0.18.* + , mtl ==2.3.* , network >=3.1.2.7 && <3.2 , optparse-applicative >=0.15 && <0.17 , process ==1.6.* @@ -425,13 +427,13 @@ executable simplex-directory-service , socks ==0.6.* , sqlcipher-simple ==0.4.* , stm ==2.5.* - , template-haskell ==2.16.* + , template-haskell ==2.20.* , terminal ==0.2.* - , text ==1.2.* + , text ==2.0.* , time ==1.9.* , unliftio ==0.2.* , unliftio-core ==0.2.* - , zip ==1.7.* + , zip ==2.0.* default-language: Haskell2010 if flag(swift) cpp-options: -DswiftJSON @@ -468,27 +470,27 @@ test-suite simplex-chat-test apps/simplex-directory-service/src ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded build-depends: - aeson ==2.0.* + aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 , async ==2.2.* , attoparsec ==0.14.* , base >=4.7 && <5 , base64-bytestring >=1.0 && <1.3 - , bytestring ==0.10.* + , bytestring ==0.11.* , composition ==1.0.* , constraints >=0.12 && <0.14 , containers ==0.6.* - , cryptonite >=0.27 && <0.30 + , cryptonite ==0.30.* , deepseq ==1.4.* , direct-sqlcipher ==2.3.* , directory ==1.3.* , email-validate ==2.3.* , exceptions ==0.10.* , filepath ==1.4.* - , hspec ==2.7.* + , hspec ==2.11.* , http-types ==0.12.* - , memory ==0.15.* - , mtl ==2.2.* + , memory ==0.18.* + , mtl ==2.3.* , network ==3.1.* , optparse-applicative >=0.15 && <0.17 , process ==1.6.* @@ -501,13 +503,13 @@ test-suite simplex-chat-test , socks ==0.6.* , sqlcipher-simple ==0.4.* , stm ==2.5.* - , template-haskell ==2.16.* + , template-haskell ==2.20.* , terminal ==0.2.* - , text ==1.2.* + , text ==2.0.* , time ==1.9.* , unliftio ==0.2.* , unliftio-core ==0.2.* - , zip ==1.7.* + , zip ==2.0.* default-language: Haskell2010 if flag(swift) cpp-options: -DswiftJSON diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index d96baba18c..e74eaa0f5c 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -5,6 +5,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -12,12 +13,15 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module Simplex.Chat where import Control.Applicative (optional, (<|>)) -import Control.Concurrent.STM (retry, stateTVar) +import Control.Concurrent.STM (retry) import qualified Control.Exception as E import Control.Logger.Simple +import Control.Monad import Control.Monad.Except import Control.Monad.IO.Unlift import Control.Monad.Reader @@ -69,6 +73,7 @@ import Simplex.Chat.Store.Shared import Simplex.Chat.Types import Simplex.Chat.Types.Preferences import Simplex.Chat.Types.Util +import Simplex.Chat.Util (encryptFile) import Simplex.FileTransfer.Client.Main (maxFileSize) import Simplex.FileTransfer.Client.Presets (defaultXFTPServers) import Simplex.FileTransfer.Description (ValidFileDescription, gb, kb, mb) @@ -212,8 +217,8 @@ newChatController ChatDatabase {chatStore, agentStore} user cfg@ChatConfig {agen where configServers :: DefaultAgentServers configServers = - let smp' = fromMaybe (smp (defaultServers :: DefaultAgentServers)) (nonEmpty smpServers) - xftp' = fromMaybe (xftp (defaultServers :: DefaultAgentServers)) (nonEmpty xftpServers) + let smp' = fromMaybe (defaultServers.smp) (nonEmpty smpServers) + xftp' = fromMaybe (defaultServers.xftp) (nonEmpty xftpServers) in defaultServers {smp = smp', xftp = xftp', netCfg = networkConfig} agentServers :: ChatConfig -> IO InitialAgentServers agentServers config@ChatConfig {defaultServers = defServers@DefaultAgentServers {ntf, netCfg}} = do @@ -240,9 +245,9 @@ activeAgentServers ChatConfig {defaultServers} p = . filter (\ServerCfg {enabled} -> enabled) cfgServers :: UserProtocol p => SProtocolType p -> (DefaultAgentServers -> NonEmpty (ProtoServerWithAuth p)) -cfgServers = \case - SPSMP -> smp - SPXFTP -> xftp +cfgServers p s = case p of + SPSMP -> s.smp + SPXFTP -> s.xftp startChatController :: forall m. ChatMonad' m => Bool -> Bool -> Bool -> m (Async ()) startChatController subConns enableExpireCIs startXFTPWorkers = do @@ -698,7 +703,9 @@ processChatCommand = \case MCVoice {} -> False MCUnknown {} -> True qText = msgContentText qmc - qFileName = maybe qText (T.pack . (fileName :: CIFile d -> String)) ciFile_ + getFileName :: CIFile d -> String + getFileName CIFile{fileName} = fileName + qFileName = maybe qText (T.pack . getFileName) ciFile_ qTextOrFile = if T.null qText then qFileName else qText xftpSndFileTransfer :: User -> CryptoFile -> Integer -> Int -> ContactOrGroup -> m (FileInvitation, CIFile 'MDSnd, FileTransferMeta) xftpSndFileTransfer user file@(CryptoFile filePath cfArgs) fileSize n contactOrGroup = do @@ -911,7 +918,7 @@ processChatCommand = \case pure $ CRContactConnectionDeleted user conn CTGroup -> do Group gInfo@GroupInfo {membership} members <- withStore $ \db -> getGroup db user chatId - let isOwner = memberRole (membership :: GroupMember) == GROwner + let isOwner = membership.memberRole == GROwner canDelete = isOwner || not (memberCurrent membership) unless canDelete $ throwChatError $ CEGroupUserRole gInfo GROwner filesInfo <- withStore' $ \db -> getGroupFileInfo db user gInfo @@ -1088,7 +1095,9 @@ processChatCommand = \case APIGetNtfMessage nonce encNtfInfo -> withUser $ \_ -> do (NotificationInfo {ntfConnId, ntfMsgMeta}, msgs) <- withAgent $ \a -> getNotificationMessage a nonce encNtfInfo let ntfMessages = map (\SMP.SMPMsgMeta {msgTs, msgFlags} -> NtfMsgInfo {msgTs = systemToUTCTime msgTs, msgFlags}) msgs - msgTs' = systemToUTCTime . (SMP.msgTs :: SMP.NMsgMeta -> SystemTime) <$> ntfMsgMeta + getMsgTs :: SMP.NMsgMeta -> SystemTime + getMsgTs SMP.NMsgMeta{msgTs} = msgTs + msgTs' = systemToUTCTime . getMsgTs <$> ntfMsgMeta agentConnId = AgentConnId ntfConnId user_ <- withStore' (`getUserByAConnId` agentConnId) connEntity <- @@ -1368,8 +1377,49 @@ processChatCommand = \case RejectContact cName -> withUser $ \User {userId} -> do connReqId <- withStore $ \db -> getContactRequestIdByName db userId cName processChatCommand $ APIRejectContact connReqId - SendMessage chatName msg -> sendTextMessage chatName msg False - SendLiveMessage chatName msg -> sendTextMessage chatName msg True + SendMessage (ChatName cType name) msg -> withUser $ \user -> do + let mc = MCText msg + case cType of + CTDirect -> + withStore' (\db -> runExceptT $ getContactIdByName db user name) >>= \case + Right ctId -> do + let chatRef = ChatRef CTDirect ctId + processChatCommand . APISendMessage chatRef False Nothing $ ComposedMessage Nothing Nothing mc + Left _ -> + withStore' (\db -> runExceptT $ getActiveMembersByName db user name) >>= \case + Right [(gInfo, member)] -> do + let GroupInfo {localDisplayName = gName} = gInfo + GroupMember {localDisplayName = mName} = member + processChatCommand $ SendMemberContactMessage gName mName msg + Right (suspectedMember : _) -> + throwChatError $ CEContactNotFound name (Just suspectedMember) + _ -> + throwChatError $ CEContactNotFound name Nothing + CTGroup -> do + gId <- withStore $ \db -> getGroupIdByName db user name + let chatRef = ChatRef CTGroup gId + processChatCommand . APISendMessage chatRef False Nothing $ ComposedMessage Nothing Nothing mc + _ -> throwChatError $ CECommandError "not supported" + SendMemberContactMessage gName mName msg -> withUser $ \user -> do + (gId, mId) <- getGroupAndMemberId user gName mName + m <- withStore $ \db -> getGroupMember db user gId mId + let mc = MCText msg + case memberContactId m of + Nothing -> do + gInfo <- withStore $ \db -> getGroupInfo db user gId + toView $ CRNoMemberContactCreating user gInfo m + processChatCommand (APICreateMemberContact gId mId) >>= \case + cr@(CRNewMemberContact _ Contact {contactId} _ _) -> do + toView cr + processChatCommand $ APISendMemberContactInvitation contactId (Just mc) + cr -> pure cr + Just ctId -> do + let chatRef = ChatRef CTDirect ctId + processChatCommand . APISendMessage chatRef False Nothing $ ComposedMessage Nothing Nothing mc + SendLiveMessage chatName msg -> withUser $ \user -> do + chatRef <- getChatRef user chatName + let mc = MCText msg + processChatCommand . APISendMessage chatRef True Nothing $ ComposedMessage Nothing Nothing mc SendMessageBroadcast msg -> withUser $ \user -> do contacts <- withStore' (`getUserContacts` user) let cts = filter (\ct -> isReady ct && directOrUsed ct) contacts @@ -1421,13 +1471,13 @@ processChatCommand = \case -- TODO for large groups: no need to load all members to determine if contact is a member (group, contact) <- withStore $ \db -> (,) <$> getGroup db user groupId <*> getContact db user contactId assertDirectAllowed user MDSnd contact XGrpInv_ - let Group gInfo@GroupInfo {membership} members = group + let Group gInfo members = group Contact {localDisplayName = cName} = contact assertUserGroupRole gInfo $ max GRAdmin memRole -- [incognito] forbid to invite contact to whom user is connected incognito when (contactConnIncognito contact) $ throwChatError CEContactIncognitoCantInvite -- [incognito] forbid to invite contacts if user joined the group using an incognito profile - when (memberIncognito membership) $ throwChatError CEGroupIncognitoCantInvite + when (incognitoMembership gInfo) $ throwChatError CEGroupIncognitoCantInvite let sendInvitation = sendGrpInvitation user contact gInfo case contactMember contact members of Nothing -> do @@ -1454,7 +1504,7 @@ processChatCommand = \case Contact {activeConn = Connection {peerChatVRange}} = ct withChatLock "joinGroup" . procCmd $ do subMode <- chatReadVar subscriptionMode - dm <- directMessage $ XGrpAcpt (memberId (membership :: GroupMember)) + dm <- directMessage $ XGrpAcpt membership.memberId agentConnId <- withAgent $ \a -> joinConnection a (aUserId user) True connRequest dm subMode withStore' $ \db -> do createMemberConnection db userId fromMember agentConnId (fromJVersionRange peerChatVRange) subMode @@ -1588,6 +1638,34 @@ processChatCommand = \case gInfo <- withStore $ \db -> getGroupInfo db user groupId (_, groupLink, mRole) <- withStore $ \db -> getGroupLink db user gInfo pure $ CRGroupLink user gInfo groupLink mRole + APICreateMemberContact gId gMemberId -> withUser $ \user -> do + (g, m) <- withStore $ \db -> (,) <$> getGroupInfo db user gId <*> getGroupMember db user gId gMemberId + assertUserGroupRole g GRAuthor + unless (groupFeatureAllowed SGFDirectMessages g) $ throwChatError $ CECommandError "direct messages not allowed" + case memberConn m of + Just mConn@Connection {peerChatVRange} -> do + unless (isCompatibleRange (fromJVersionRange peerChatVRange) xGrpDirectInvVRange) $ throwChatError CEPeerChatVRangeIncompatible + when (isJust $ memberContactId m) $ throwChatError $ CECommandError "member contact already exists" + subMode <- chatReadVar subscriptionMode + (connId, cReq) <- withAgent $ \a -> createConnection a (aUserId user) True SCMInvitation Nothing subMode + -- [incognito] reuse membership incognito profile + ct <- withStore' $ \db -> createMemberContact db user connId cReq g m mConn subMode + pure $ CRNewMemberContact user ct g m + _ -> throwChatError CEGroupMemberNotActive + APISendMemberContactInvitation contactId msgContent_ -> withUser $ \user -> do + (g, m, ct, cReq) <- withStore $ \db -> getMemberContact db user contactId + when (contactGrpInvSent ct) $ throwChatError $ CECommandError "x.grp.direct.inv already sent" + case memberConn m of + Just mConn -> do + let msg = XGrpDirectInv cReq msgContent_ + (sndMsg, _) <- sendDirectMessage mConn msg (GroupId $ g.groupId) + withStore' $ \db -> setContactGrpInvSent db ct True + let ct' = ct {contactGrpInvSent = True} + forM_ msgContent_ $ \mc -> do + ci <- saveSndChatItem user (CDDirectSnd ct') sndMsg (CISndMsgContent mc) + toView $ CRNewChatItem user (AChatItem SCTDirect SMDSnd (DirectChat ct') ci) + pure $ CRNewMemberContactSentInv user ct' g m + _ -> throwChatError CEGroupMemberNotActive CreateGroupLink gName mRole -> withUser $ \user -> do groupId <- withStore $ \db -> getGroupIdByName db user gName processChatCommand $ APICreateGroupLink groupId mRole @@ -1657,22 +1735,15 @@ processChatCommand = \case ft' <- if encrypted then encryptLocalFile ft else pure ft receiveFile' user ft' rcvInline_ filePath_ where - encryptLocalFile ft@RcvFileTransfer {xftpRcvFile} = case xftpRcvFile of - Nothing -> throwChatError $ CEFileInternal "locally encrypted files can't be received via SMP" - Just f -> do - cfArgs <- liftIO $ CF.randomArgs - withStore' $ \db -> setFileCryptoArgs db fileId cfArgs - pure ft {xftpRcvFile = Just ((f :: XFTPRcvFile) {cryptoArgs = Just cfArgs})} + encryptLocalFile ft = do + cfArgs <- liftIO $ CF.randomArgs + withStore' $ \db -> setFileCryptoArgs db fileId cfArgs + pure (ft :: RcvFileTransfer) {cryptoArgs = Just cfArgs} SetFileToReceive fileId encrypted -> withUser $ \_ -> do withChatLock "setFileToReceive" . procCmd $ do - cfArgs <- if encrypted then fileCryptoArgs else pure Nothing + cfArgs <- if encrypted then Just <$> liftIO CF.randomArgs else pure Nothing withStore' $ \db -> setRcvFileToReceive db fileId cfArgs ok_ - where - fileCryptoArgs = do - (_, RcvFileTransfer {xftpRcvFile = f}) <- withStore (`getRcvFileTransferById` fileId) - unless (isJust f) $ throwChatError $ CEFileInternal "locally encrypted files can't be received via SMP" - liftIO $ Just <$> CF.randomArgs CancelFile fileId -> withUser $ \user@User {userId} -> withChatLock "cancelFile" . procCmd $ withStore (\db -> getFileTransfer db user fileId) >>= \case @@ -1951,7 +2022,7 @@ processChatCommand = \case pure $ CRGroupUpdated user g g' Nothing assertUserGroupRole :: GroupInfo -> GroupMemberRole -> m () assertUserGroupRole g@GroupInfo {membership} requiredRole = do - when (memberRole (membership :: GroupMember) < requiredRole) $ throwChatError $ CEGroupUserRole g requiredRole + when (membership.memberRole < requiredRole) $ throwChatError $ CEGroupUserRole g requiredRole when (memberStatus membership == GSMemInvited) $ throwChatError (CEGroupNotJoined g) when (memberRemoved membership) $ throwChatError CEGroupMemberUserRemoved unless (memberActive membership) $ throwChatError CEGroupMemberNotActive @@ -1969,7 +2040,7 @@ processChatCommand = \case runUpdateGroupProfile user g $ update p isReady :: Contact -> Bool isReady ct = - let s = connStatus $ activeConn (ct :: Contact) + let s = connStatus $ ct.activeConn in s == ConnReady || s == ConnSndReady withCurrentCall :: ContactId -> (User -> Contact -> Call -> m (Maybe Call)) -> m ChatResponse withCurrentCall ctId action = do @@ -2019,10 +2090,6 @@ processChatCommand = \case ci <- saveSndChatItem user (CDDirectSnd ct) msg content toView $ CRNewChatItem user (AChatItem SCTDirect SMDSnd (DirectChat ct) ci) setActive $ ActiveG localDisplayName - sendTextMessage chatName msg live = withUser $ \user -> do - chatRef <- getChatRef user chatName - let mc = MCText msg - processChatCommand . APISendMessage chatRef live Nothing $ ComposedMessage Nothing Nothing mc sndContactCITimed :: Bool -> Contact -> Maybe Int -> m (Maybe CITimed) sndContactCITimed live = sndCITimed_ live . contactTimedTTL sndGroupCITimed :: Bool -> GroupInfo -> Maybe Int -> m (Maybe CITimed) @@ -2246,7 +2313,7 @@ receiveFile' user ft rcvInline_ filePath_ = do e -> throwError e acceptFileReceive :: forall m. ChatMonad m => User -> RcvFileTransfer -> Maybe Bool -> Maybe FilePath -> m AChatItem -acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = FileInvitation {fileName = fName, fileConnReq, fileInline, fileSize}, fileStatus, grpMemberId} rcvInline_ filePath_ = do +acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = FileInvitation {fileName = fName, fileConnReq, fileInline, fileSize}, fileStatus, grpMemberId, cryptoArgs} rcvInline_ filePath_ = do unless (fileStatus == RFSNew) $ case fileStatus of RFSCancelled _ -> throwChatError $ CEFileCancelled fName _ -> throwChatError $ CEFileAlreadyReceiving fName @@ -2259,7 +2326,7 @@ acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileI filePath <- getRcvFilePath fileId filePath_ fName True withStoreCtx (Just "acceptFileReceive, acceptRcvFileTransfer") $ \db -> acceptRcvFileTransfer db user fileId connIds ConnJoined filePath subMode -- XFTP - (Just XFTPRcvFile {cryptoArgs}, _) -> do + (Just XFTPRcvFile {}, _) -> do filePath <- getRcvFilePath fileId filePath_ fName False (ci, rfd) <- withStoreCtx (Just "acceptFileReceive, xftpAcceptRcvFT ...") $ \db -> do -- marking file as accepted and reading description in the same transaction @@ -2333,7 +2400,7 @@ getRcvFilePath fileId fPath_ fn keepHandle = case fPath_ of asks filesFolder >>= readTVarIO >>= \case Nothing -> do dir <- (`combine` "Downloads") <$> getHomeDirectory - ifM (doesDirectoryExist dir) (pure dir) getTemporaryDirectory + ifM (doesDirectoryExist dir) (pure dir) getChatTempDirectory >>= (`uniqueCombine` fn) >>= createEmptyFile Just filesFolder -> @@ -2361,14 +2428,18 @@ getRcvFilePath fileId fPath_ fn keepHandle = case fPath_ of pure fPath getTmpHandle :: FilePath -> m Handle getTmpHandle fPath = openFile fPath AppendMode `catchThrow` (ChatError . CEFileInternal . show) - uniqueCombine :: FilePath -> String -> m FilePath - uniqueCombine filePath fileName = tryCombine (0 :: Int) - where - tryCombine n = - let (name, ext) = splitExtensions fileName - suffix = if n == 0 then "" else "_" <> show n - f = filePath `combine` (name <> suffix <> ext) - in ifM (doesFileExist f) (tryCombine $ n + 1) (pure f) + +uniqueCombine :: MonadIO m => FilePath -> String -> m FilePath +uniqueCombine filePath fileName = tryCombine (0 :: Int) + where + tryCombine n = + let (name, ext) = splitExtensions fileName + suffix = if n == 0 then "" else "_" <> show n + f = filePath `combine` (name <> suffix <> ext) + in ifM (doesFileExist f) (tryCombine $ n + 1) (pure f) + +getChatTempDirectory :: ChatMonad m => m FilePath +getChatTempDirectory = chatReadVar tempDirectory >>= maybe getTemporaryDirectory pure acceptContactRequest :: ChatMonad m => User -> UserContactRequest -> Maybe IncognitoProfile -> m Contact acceptContactRequest user UserContactRequest {agentInvitationId = AgentInvId invId, cReqChatVRange, localDisplayName = cName, profileId, profile = cp, userContactLinkId, xContactId} incognitoProfile = do @@ -2964,7 +3035,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do XFileAcptInv sharedMsgId fileConnReq_ fName -> xFileAcptInv ct' sharedMsgId fileConnReq_ fName msgMeta XInfo p -> xInfo ct' p XGrpInv gInv -> processGroupInvitation ct' gInv msg msgMeta - XInfoProbe probe -> xInfoProbe ct' probe + XInfoProbe probe -> xInfoProbe (CGMContact ct') probe XInfoProbeCheck probeHash -> xInfoProbeCheck ct' probeHash XInfoProbeOk probe -> xInfoProbeOk ct' probe XCallInv callId invitation -> xCallInv ct' callId invitation msg msgMeta @@ -2980,16 +3051,23 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do withAckMessage' agentConnId conn msgMeta $ directMsgReceived ct conn msgMeta msgRcpt CONF confId _ connInfo -> do - -- confirming direct connection with a member ChatMessage {chatVRange, chatMsgEvent} <- parseChatMessage conn connInfo conn' <- updatePeerChatVRange conn chatVRange case chatMsgEvent of + -- confirming direct connection with a member XGrpMemInfo _memId _memProfile -> do -- TODO check member ID -- TODO update member profile -- [async agent commands] no continuation needed, but command should be asynchronous for stability allowAgentConnectionAsync user conn' confId XOk - _ -> messageError "CONF from member must have x.grp.mem.info" + XInfo profile -> do + ct' <- processContactProfileUpdate ct profile False `catchChatError` const (pure ct) + -- [incognito] send incognito profile + incognitoProfile <- forM customUserProfileId $ \profileId -> withStore $ \db -> getProfileById db userId profileId + let p = userProfileToSend user (fromLocalProfile <$> incognitoProfile) (Just ct') + allowAgentConnectionAsync user conn' confId $ XInfo p + void $ withStore' $ \db -> resetMemberContactFields db ct' + _ -> messageError "CONF for existing contact must have x.grp.mem.info or x.info" INFO connInfo -> do ChatMessage {chatVRange, chatMsgEvent} <- parseChatMessage conn connInfo _conn' <- updatePeerChatVRange conn chatVRange @@ -2998,9 +3076,8 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do -- TODO check member ID -- TODO update member profile pure () - XInfo _profile -> do - -- TODO update contact profile - pure () + XInfo profile -> + void $ processContactProfileUpdate ct profile False XOk -> pure () _ -> messageError "INFO for existing contact must have x.grp.mem.info, x.info or x.ok" CON -> @@ -3027,10 +3104,10 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do groupConnIds <- createAgentConnectionAsync user CFCreateConnGrpInv True SCMInvitation subMode withStore $ \db -> createNewContactMemberAsync db gVar user groupId ct gLinkMemRole groupConnIds (fromJVersionRange peerChatVRange) subMode _ -> pure () - Just (gInfo@GroupInfo {membership}, m@GroupMember {activeConn}) -> + Just (gInfo, m@GroupMember {activeConn}) -> when (maybe False ((== ConnReady) . connStatus) activeConn) $ do notifyMemberConnected gInfo m $ Just ct - let connectedIncognito = contactConnIncognito ct || memberIncognito membership + let connectedIncognito = contactConnIncognito ct || incognitoMembership gInfo when (memberCategory m == GCPreMember) $ probeMatchingContacts ct connectedIncognito SENT msgId -> do sentMsgDeliveryEvent conn msgId @@ -3093,7 +3170,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do groupConnReq@(CRInvitationUri _ _) -> case cmdFunction of -- [async agent commands] XGrpMemIntro continuation on receiving INV CFCreateConnGrpMemInv - | isCompatibleRange (fromJVersionRange $ peerChatVRange conn) groupNoDirectVRange -> sendWithDirectCReq -- sendWithoutDirectCReq + | isCompatibleRange (fromJVersionRange $ peerChatVRange conn) groupNoDirectVRange -> sendWithoutDirectCReq | otherwise -> sendWithDirectCReq where sendWithoutDirectCReq = do @@ -3145,7 +3222,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do | sameMemberId memId m -> do -- TODO update member profile -- [async agent commands] no continuation needed, but command should be asynchronous for stability - allowAgentConnectionAsync user conn' confId $ XGrpMemInfo (memberId (membership :: GroupMember)) (fromLocalProfile $ memberProfile membership) + allowAgentConnectionAsync user conn' confId $ XGrpMemInfo membership.memberId (fromLocalProfile $ memberProfile membership) | otherwise -> messageError "x.grp.mem.info: memberId is different from expected" _ -> messageError "CONF from member must have x.grp.mem.info" INFO connInfo -> do @@ -3184,7 +3261,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do toView $ CRJoinedGroupMember user gInfo m {memberStatus = GSMemConnected} whenGroupNtfs user gInfo $ do setActive $ ActiveG gName - showToast ("#" <> gName) $ "member " <> localDisplayName (m :: GroupMember) <> " is connected" + showToast ("#" <> gName) $ "member " <> m.localDisplayName <> " is connected" intros <- withStore' $ \db -> createIntroductions db members m void . sendGroupMessage user gInfo members . XGrpMemNew $ memberInfo m forM_ intros $ \intro -> @@ -3194,16 +3271,16 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do void $ sendDirectMessage conn (XGrpMemIntro $ memberInfo (reMember intro)) (GroupId groupId) withStore' $ \db -> updateIntroStatus db introId GMIntroSent _ -> do - -- TODO send probe and decide whether to use existing contact connection or the new contact connection -- TODO notify member who forwarded introduction - question - where it is stored? There is via_contact but probably there should be via_member in group_members table withStore' (\db -> getViaGroupContact db user m) >>= \case Nothing -> do notifyMemberConnected gInfo m Nothing - messageWarning "connected member does not have contact" + let connectedIncognito = memberIncognito membership + when (memberCategory m == GCPreMember) $ probeMatchingMemberContact gInfo m connectedIncognito Just ct@Contact {activeConn = Connection {connStatus}} -> when (connStatus == ConnReady) $ do notifyMemberConnected gInfo m $ Just ct - let connectedIncognito = contactConnIncognito ct || memberIncognito membership + let connectedIncognito = contactConnIncognito ct || incognitoMembership gInfo when (memberCategory m == GCPreMember) $ probeMatchingContacts ct connectedIncognito MSG msgMeta _msgFlags msgBody -> do cmdId <- createAckCmd conn @@ -3231,6 +3308,10 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do XGrpLeave -> xGrpLeave gInfo m' msg msgMeta XGrpDel -> xGrpDel gInfo m' msg msgMeta XGrpInfo p' -> xGrpInfo gInfo m' p' msg msgMeta + XGrpDirectInv connReq mContent_ -> canSend m' $ xGrpDirectInv gInfo m' conn' connReq mContent_ msg msgMeta + XInfoProbe probe -> xInfoProbe (CGMGroupMember gInfo m') probe + -- XInfoProbeCheck -- TODO merge members? + -- XInfoProbeOk -- TODO merge members? BFileChunk sharedMsgId chunk -> bFileChunkGroup gInfo sharedMsgId chunk msgMeta _ -> messageError $ "unsupported message: " <> T.pack (show event) currentMemCount <- withStore' $ \db -> getGroupCurrentMembersCount db user gInfo @@ -3240,8 +3321,9 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do && hasDeliveryReceipt (toCMEventTag event) && currentMemCount <= smallGroupsRcptsMemLimit where + canSend :: GroupMember -> m () -> m () canSend mem a - | memberRole (mem :: GroupMember) <= GRObserver = messageError "member is not allowed to send messages" + | mem.memberRole <= GRObserver = messageError "member is not allowed to send messages" | otherwise = a RCVD msgMeta msgRcpt -> withAckMessage' agentConnId conn msgMeta $ @@ -3432,12 +3514,12 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do RcvChunkOk -> if B.length chunk /= fromInteger chunkSize then badRcvFileChunk ft "incorrect chunk size" - else ack $ appendFileChunk ft chunkNo chunk + else ack $ appendFileChunk ft chunkNo chunk False RcvChunkFinal -> if B.length chunk > fromInteger chunkSize then badRcvFileChunk ft "incorrect chunk size" else do - appendFileChunk ft chunkNo chunk + appendFileChunk ft chunkNo chunk True ci <- withStore $ \db -> do liftIO $ do updateRcvFileStatus db fileId FSComplete @@ -3445,7 +3527,6 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do deleteRcvFileChunks db ft getChatItemByFileId db user fileId toView $ CRRcvFileComplete user ci - closeFileHandle fileId rcvFiles forM_ conn_ $ \conn -> deleteAgentConnectionAsync user (aConnId conn) RcvChunkDuplicate -> ack $ pure () RcvChunkError -> badRcvFileChunk ft $ "incorrect chunk number " <> show chunkNo @@ -3487,8 +3568,8 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do ct <- acceptContactRequestAsync user cReq incognitoProfile toView $ CRAcceptingContactRequest user ct Just groupId -> do - gInfo@GroupInfo {membership = membership@GroupMember {memberProfile}} <- withStore $ \db -> getGroupInfo db user groupId - let profileMode = if memberIncognito membership then Just $ ExistingIncognito memberProfile else Nothing + gInfo <- withStore $ \db -> getGroupInfo db user groupId + let profileMode = ExistingIncognito <$> incognitoMembershipProfile gInfo ct <- acceptContactRequestAsync user cReq profileMode toView $ CRAcceptingGroupJoinRequest user gInfo ct _ -> do @@ -3596,19 +3677,42 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do probeMatchingContacts :: Contact -> IncognitoEnabled -> m () probeMatchingContacts ct connectedIncognito = do gVar <- asks idsDrg - (probe, probeId) <- withStore $ \db -> createSentProbe db gVar userId ct - void . sendDirectContactMessage ct $ XInfoProbe probe if connectedIncognito - then withStore' $ \db -> deleteSentProbe db userId probeId + then sendProbe . Probe =<< liftIO (encodedRandomBytes gVar 32) else do + (probe, probeId) <- withStore $ \db -> createSentProbe db gVar userId (CGMContact ct) + sendProbe probe cs <- withStore' $ \db -> getMatchingContacts db user ct - let probeHash = ProbeHash $ C.sha256Hash (unProbe probe) - forM_ cs $ \c -> sendProbeHash c probeHash probeId `catchChatError` \_ -> pure () + sendProbeHashes cs probe probeId where - sendProbeHash :: Contact -> ProbeHash -> Int64 -> m () - sendProbeHash c probeHash probeId = do + sendProbe :: Probe -> m () + sendProbe probe = void . sendDirectContactMessage ct $ XInfoProbe probe + + probeMatchingMemberContact :: GroupInfo -> GroupMember -> IncognitoEnabled -> m () + probeMatchingMemberContact _ GroupMember {activeConn = Nothing} _ = pure () + probeMatchingMemberContact g m@GroupMember {groupId, activeConn = Just conn} connectedIncognito = do + gVar <- asks idsDrg + if connectedIncognito + then sendProbe . Probe =<< liftIO (encodedRandomBytes gVar 32) + else do + (probe, probeId) <- withStore $ \db -> createSentProbe db gVar userId $ CGMGroupMember g m + sendProbe probe + cs <- withStore' $ \db -> getMatchingMemberContacts db user m + sendProbeHashes cs probe probeId + where + sendProbe :: Probe -> m () + sendProbe probe = void $ sendDirectMessage conn (XInfoProbe probe) (GroupId groupId) + + -- TODO currently we only send probe hashes to contacts + sendProbeHashes :: [Contact] -> Probe -> Int64 -> m () + sendProbeHashes cs probe probeId = + forM_ cs $ \c -> sendProbeHash c `catchChatError` \_ -> pure () + where + probeHash = ProbeHash $ C.sha256Hash (unProbe probe) + sendProbeHash :: Contact -> m () + sendProbeHash c = do void . sendDirectContactMessage c $ XInfoProbeCheck probeHash - withStore' $ \db -> createSentProbeHash db userId probeId c + withStore' $ \db -> createSentProbeHash db userId probeId $ CGMContact c messageWarning :: Text -> m () messageWarning = toView . CRMessageError user "warning" @@ -3668,14 +3772,14 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do processFDMessage fileId fileDescr = do ft <- withStore $ \db -> getRcvFileTransfer db user fileId unless (rcvFileCompleteOrCancelled ft) $ do - (rfd, RcvFileTransfer {fileStatus, xftpRcvFile}) <- withStore $ \db -> do + (rfd, RcvFileTransfer {fileStatus, xftpRcvFile, cryptoArgs}) <- withStore $ \db -> do rfd <- appendRcvFD db userId fileId fileDescr -- reading second time in the same transaction as appending description -- to prevent race condition with accept ft' <- getRcvFileTransfer db user fileId pure (rfd, ft') case (fileStatus, xftpRcvFile) of - (RFSAccepted _, Just XFTPRcvFile {cryptoArgs}) -> receiveViaCompleteFD user fileId rfd cryptoArgs + (RFSAccepted _, Just XFTPRcvFile {}) -> receiveViaCompleteFD user fileId rfd cryptoArgs _ -> pure () cancelMessageFile :: Contact -> SharedMsgId -> MsgMeta -> m () @@ -4132,15 +4236,22 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do MsgError e -> createInternalChatItem user cd (CIRcvIntegrityError e) (Just brokerTs) xInfo :: Contact -> Profile -> m () - xInfo c@Contact {profile = p} p' = unless (fromLocalProfile p == p') $ do - c' <- withStore $ \db -> - if userTTL == rcvTTL - then updateContactProfile db user c p' - else do - c' <- liftIO $ updateContactUserPreferences db user c ctUserPrefs' - updateContactProfile db user c' p' - when (directOrUsed c') $ createRcvFeatureItems user c c' - toView $ CRContactUpdated user c c' + xInfo c p' = void $ processContactProfileUpdate c p' True + + processContactProfileUpdate :: Contact -> Profile -> Bool -> m Contact + processContactProfileUpdate c@Contact {profile = p} p' createItems + | fromLocalProfile p /= p' = do + c' <- withStore $ \db -> + if userTTL == rcvTTL + then updateContactProfile db user c p' + else do + c' <- liftIO $ updateContactUserPreferences db user c ctUserPrefs' + updateContactProfile db user c' p' + when (directOrUsed c' && createItems) $ createRcvFeatureItems user c c' + toView $ CRContactUpdated user c c' + pure c' + | otherwise = + pure c where Contact {userPreferences = ctUserPrefs@Preferences {timedMessages = ctUserTMPref}} = c userTTL = prefParam $ getPreference SCFTimedMessages ctUserPrefs @@ -4169,35 +4280,48 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do (_, param) = groupFeatureState p createInternalChatItem user (CDGroupRcv g m) (CIRcvGroupFeature (toGroupFeature f) (toGroupPreference p) param) Nothing - xInfoProbe :: Contact -> Probe -> m () - xInfoProbe c2 probe = + xInfoProbe :: ContactOrGroupMember -> Probe -> m () + xInfoProbe cgm2 probe = -- [incognito] unless connected incognito - unless (contactConnIncognito c2) $ do - r <- withStore' $ \db -> matchReceivedProbe db user c2 probe - forM_ r $ \c1 -> probeMatch c1 c2 probe + unless (contactOrGroupMemberIncognito cgm2) $ do + r <- withStore' $ \db -> matchReceivedProbe db user cgm2 probe + forM_ r $ \case + CGMContact c1 -> probeMatch c1 cgm2 probe + CGMGroupMember _ _ -> messageWarning "xInfoProbe ignored: matched member (no probe hashes sent to members)" + -- TODO currently we send probe hashes only to contacts xInfoProbeCheck :: Contact -> ProbeHash -> m () xInfoProbeCheck c1 probeHash = -- [incognito] unless connected incognito unless (contactConnIncognito c1) $ do - r <- withStore' $ \db -> matchReceivedProbeHash db user c1 probeHash + r <- withStore' $ \db -> matchReceivedProbeHash db user (CGMContact c1) probeHash forM_ r . uncurry $ probeMatch c1 - probeMatch :: Contact -> Contact -> Probe -> m () - probeMatch c1@Contact {contactId = cId1, profile = p1} c2@Contact {contactId = cId2, profile = p2} probe = - if profilesMatch (fromLocalProfile p1) (fromLocalProfile p2) && cId1 /= cId2 - then do - void . sendDirectContactMessage c1 $ XInfoProbeOk probe - mergeContacts c1 c2 - else messageWarning "probeMatch ignored: profiles don't match or same contact id" + probeMatch :: Contact -> ContactOrGroupMember -> Probe -> m () + probeMatch c1@Contact {contactId = cId1, profile = p1} cgm2 probe = + case cgm2 of + CGMContact c2@Contact {contactId = cId2, profile = p2} + | cId1 /= cId2 && profilesMatch p1 p2 -> do + void . sendDirectContactMessage c1 $ XInfoProbeOk probe + mergeContacts c1 c2 + | otherwise -> messageWarning "probeMatch ignored: profiles don't match or same contact id" + CGMGroupMember g m2@GroupMember {memberProfile = p2, memberContactId} + | isNothing memberContactId && profilesMatch p1 p2 -> do + void . sendDirectContactMessage c1 $ XInfoProbeOk probe + connectContactToMember c1 g m2 + | otherwise -> messageWarning "probeMatch ignored: profiles don't match or member already has contact" + -- TODO currently we send probe hashes only to contacts xInfoProbeOk :: Contact -> Probe -> m () - xInfoProbeOk c1@Contact {contactId = cId1} probe = do - r <- withStore' $ \db -> matchSentProbe db user c1 probe - forM_ r $ \c2@Contact {contactId = cId2} -> - if cId1 /= cId2 - then mergeContacts c1 c2 - else messageWarning "xInfoProbeOk ignored: same contact id" + xInfoProbeOk c1@Contact {contactId = cId1} probe = + withStore' (\db -> matchSentProbe db user (CGMContact c1) probe) >>= \case + Just (CGMContact c2@Contact {contactId = cId2}) + | cId1 /= cId2 -> mergeContacts c1 c2 + | otherwise -> messageWarning "xInfoProbeOk ignored: same contact id" + Just (CGMGroupMember g m2@GroupMember {memberContactId}) + | isNothing memberContactId -> connectContactToMember c1 g m2 + | otherwise -> messageWarning "xInfoProbeOk ignored: member already has contact" + _ -> pure () -- to party accepting call xCallInv :: Contact -> CallId -> CallInvitation -> RcvMessage -> MsgMeta -> m () @@ -4309,6 +4433,11 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do withStore' $ \db -> mergeContactRecords db userId c1 c2 toView $ CRContactsMerged user c1 c2 + connectContactToMember :: Contact -> GroupInfo -> GroupMember -> m () + connectContactToMember c1 g m2 = do + withStore' $ \db -> updateMemberContact db user c1 m2 + toView $ CRMemberContactConnected user c1 g m2 + saveConnInfo :: Connection -> ConnInfo -> m Connection saveConnInfo activeConn connInfo = do ChatMessage {chatVRange, chatMsgEvent} <- parseChatMessage activeConn connInfo @@ -4335,7 +4464,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do toView $ CRJoinedGroupMemberConnecting user gInfo m newMember xGrpMemIntro :: GroupInfo -> GroupMember -> MemberInfo -> m () - xGrpMemIntro gInfo@GroupInfo {membership, chatSettings = ChatSettings {enableNtfs}} m@GroupMember {memberRole, localDisplayName = c} memInfo@(MemberInfo memId _ memberChatVRange _) = do + xGrpMemIntro gInfo@GroupInfo {chatSettings = ChatSettings {enableNtfs}} m@GroupMember {memberRole, localDisplayName = c} memInfo@(MemberInfo memId _ memberChatVRange _) = do case memberCategory m of GCHostMember -> do members <- withStore' $ \db -> getGroupMembers db user gInfo @@ -4349,9 +4478,9 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do directConnIds <- case memberChatVRange of Nothing -> Just <$> createConn subMode Just mcvr - | isCompatibleRange (fromChatVRange mcvr) groupNoDirectVRange -> Just <$> createConn subMode -- pure Nothing + | isCompatibleRange (fromChatVRange mcvr) groupNoDirectVRange -> pure Nothing | otherwise -> Just <$> createConn subMode - let customUserProfileId = if memberIncognito membership then Just (localProfileId $ memberProfile membership) else Nothing + let customUserProfileId = localProfileId <$> incognitoMembershipProfile gInfo void $ withStore $ \db -> createIntroReMember db user gInfo m memInfo groupConnIds directConnIds customUserProfileId subMode _ -> messageError "x.grp.mem.intro can be only sent by host member" where @@ -4391,17 +4520,17 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do withStore' $ \db -> saveMemberInvitation db toMember introInv subMode <- chatReadVar subscriptionMode -- [incognito] send membership incognito profile, create direct connection as incognito - dm <- directMessage $ XGrpMemInfo (memberId (membership :: GroupMember)) (fromLocalProfile $ memberProfile membership) + dm <- directMessage $ XGrpMemInfo membership.memberId (fromLocalProfile $ memberProfile membership) -- [async agent commands] no continuation needed, but commands should be asynchronous for stability groupConnIds <- joinAgentConnectionAsync user enableNtfs groupConnReq dm subMode directConnIds <- forM directConnReq $ \dcr -> joinAgentConnectionAsync user enableNtfs dcr dm subMode - let customUserProfileId = if memberIncognito membership then Just (localProfileId $ memberProfile membership) else Nothing + let customUserProfileId = localProfileId <$> incognitoMembershipProfile gInfo mcvr = maybe chatInitialVRange fromChatVRange memberChatVRange withStore' $ \db -> createIntroToMemberContact db user m toMember mcvr groupConnIds directConnIds customUserProfileId subMode xGrpMemRole :: GroupInfo -> GroupMember -> MemberId -> GroupMemberRole -> RcvMessage -> MsgMeta -> m () xGrpMemRole gInfo@GroupInfo {membership} m@GroupMember {memberRole = senderRole} memId memRole msg msgMeta - | memberId (membership :: GroupMember) == memId = + | membership.memberId == memId = let gInfo' = gInfo {membership = membership {memberRole = memRole}} in changeMemberRole gInfo' membership $ RGEUserRole memRole | otherwise = do @@ -4425,7 +4554,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do xGrpMemDel :: GroupInfo -> GroupMember -> MemberId -> RcvMessage -> MsgMeta -> m () xGrpMemDel gInfo@GroupInfo {membership} m@GroupMember {memberRole = senderRole} memId msg msgMeta = do members <- withStore' $ \db -> getGroupMembers db user gInfo - if memberId (membership :: GroupMember) == memId + if membership.memberId == memId then checkRole membership $ do deleteGroupLinkIfExists user gInfo -- member records are not deleted to keep history @@ -4489,6 +4618,52 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do groupMsgToView g' m ci msgMeta createGroupFeatureChangedItems user cd CIRcvGroupFeature g g' + xGrpDirectInv :: GroupInfo -> GroupMember -> Connection -> ConnReqInvitation -> Maybe MsgContent -> RcvMessage -> MsgMeta -> m () + xGrpDirectInv g m mConn connReq mContent_ msg msgMeta = do + unless (groupFeatureAllowed SGFDirectMessages g) $ messageError "x.grp.direct.inv: direct messages not allowed" + let GroupMember {memberContactId} = m + subMode <- chatReadVar subscriptionMode + case memberContactId of + Nothing -> createNewContact subMode + Just mContactId -> do + mCt <- withStore $ \db -> getContact db user mContactId + let Contact {activeConn = Connection {connId}, contactGrpInvSent} = mCt + if contactGrpInvSent + then do + ownConnReq <- withStore $ \db -> getConnReqInv db connId + -- in case both members sent x.grp.direct.inv before receiving other's for processing, + -- only the one who received greater connReq joins, the other creates items and waits for confirmation + if strEncode connReq > strEncode ownConnReq + then joinExistingContact subMode mCt + else createItems mCt m + else joinExistingContact subMode mCt + where + joinExistingContact subMode mCt = do + connIds <- joinConn subMode + mCt' <- withStore' $ \db -> updateMemberContactInvited db user connIds g mConn mCt subMode + createItems mCt' m + securityCodeChanged mCt' + createNewContact subMode = do + connIds <- joinConn subMode + -- [incognito] reuse membership incognito profile + (mCt', m') <- withStore' $ \db -> createMemberContactInvited db user connIds g m mConn subMode + createItems mCt' m' + joinConn subMode = do + -- [incognito] send membership incognito profile + let p = userProfileToSend user (fromLocalProfile <$> incognitoMembershipProfile g) Nothing + dm <- directMessage $ XInfo p + joinAgentConnectionAsync user True connReq dm subMode + createItems mCt' m' = do + checkIntegrityCreateItem (CDGroupRcv g m') msgMeta + createInternalChatItem user (CDGroupRcv g m') (CIRcvGroupEvent RGEMemberCreatedContact) Nothing + toView $ CRNewMemberContactReceivedInv user mCt' g m' + forM_ mContent_ $ \mc -> do + ci <- saveRcvChatItem user (CDDirectRcv mCt') msg msgMeta (CIRcvMsgContent mc) + toView $ CRNewChatItem user (AChatItem SCTDirect SMDRcv (DirectChat mCt') ci) + securityCodeChanged ct = do + toView $ CRContactVerificationReset user ct + createInternalChatItem user (CDDirectRcv ct) (CIRcvConnEvent RCEVerificationCodeReset) Nothing + directMsgReceived :: Contact -> Connection -> MsgMeta -> NonEmpty MsgReceipt -> m () directMsgReceived ct conn@Connection {connId} msgMeta msgRcpts = do checkIntegrityCreateItem (CDDirectRcv ct) msgMeta @@ -4620,8 +4795,8 @@ readFileChunk SndFileTransfer {fileId, filePath, chunkSize} chunkNo = do parseFileChunk :: ChatMonad m => ByteString -> m FileChunk parseFileChunk = liftEither . first (ChatError . CEFileRcvChunk) . smpDecode -appendFileChunk :: ChatMonad m => RcvFileTransfer -> Integer -> ByteString -> m () -appendFileChunk ft@RcvFileTransfer {fileId, fileStatus} chunkNo chunk = +appendFileChunk :: forall m. ChatMonad m => RcvFileTransfer -> Integer -> ByteString -> Bool -> m () +appendFileChunk ft@RcvFileTransfer {fileId, fileStatus, cryptoArgs} chunkNo chunk final = case fileStatus of RFSConnected RcvFileInfo {filePath} -> append_ filePath -- sometimes update of file transfer status to FSConnected @@ -4630,11 +4805,27 @@ appendFileChunk ft@RcvFileTransfer {fileId, fileStatus} chunkNo chunk = RFSCancelled _ -> pure () _ -> throwChatError $ CEFileInternal "receiving file transfer not in progress" where + append_ :: FilePath -> m () append_ filePath = do fsFilePath <- toFSFilePath filePath h <- getFileHandle fileId fsFilePath rcvFiles AppendMode - liftIO (B.hPut h chunk >> hFlush h) `catchThrow` (ChatError . CEFileWrite filePath . show) + liftIO (B.hPut h chunk >> hFlush h) `catchThrow` (fileErr . show) withStore' $ \db -> updatedRcvFileChunkStored db ft chunkNo + when final $ do + closeFileHandle fileId rcvFiles + forM_ cryptoArgs $ \cfArgs -> do + tmpFile <- getChatTempDirectory >>= (`uniqueCombine` ft.fileInvitation.fileName) + tryChatError (liftError encryptErr $ encryptFile fsFilePath tmpFile cfArgs) >>= \case + Right () -> do + removeFile fsFilePath `catchChatError` \_ -> pure () + renameFile tmpFile fsFilePath + Left e -> do + toView $ CRChatError Nothing e + removeFile tmpFile `catchChatError` \_ -> pure () + withStore' (`removeFileCryptoArgs` fileId) + where + encryptErr e = fileErr $ e <> ", received file not encrypted" + fileErr = ChatError . CEFileWrite filePath getFileHandle :: ChatMonad m => Int64 -> FilePath -> (ChatController -> TVar (Map Int64 Handle)) -> IOMode -> m Handle getFileHandle fileId filePath files ioMode = do @@ -4962,7 +5153,7 @@ createSndFeatureItems :: forall m. ChatMonad m => User -> Contact -> Contact -> createSndFeatureItems user ct ct' = createFeatureItems user ct ct' CDDirectSnd CISndChatFeature CISndChatPreference getPref where - getPref = (preference :: ContactUserPref (FeaturePreference f) -> FeaturePreference f) . userPreference + getPref u = (userPreference u).preference type FeatureContent a d = ChatFeature -> a -> Maybe Int -> CIContent d @@ -5047,7 +5238,7 @@ getCreateActiveUser st testView = do Right user -> pure user selectUser :: [User] -> IO User selectUser [user] = do - withTransaction st (`setActiveUser` userId (user :: User)) + withTransaction st (`setActiveUser` user.userId) pure user selectUser users = do putStrLn "Select user profile:" @@ -5062,7 +5253,7 @@ getCreateActiveUser st testView = do | n <= 0 || n > length users -> putStrLn "invalid user number" >> loop | otherwise -> do let user = users !! (n - 1) - withTransaction st (`setActiveUser` userId (user :: User)) + withTransaction st (`setActiveUser` user.userId) pure user userStr :: User -> String userStr User {localDisplayName, profile = LocalProfile {fullName}} = @@ -5337,6 +5528,8 @@ chatCommandP = "/set link role #" *> (GroupLinkMemberRole <$> displayName <*> memberRole), "/delete link #" *> (DeleteGroupLink <$> displayName), "/show link #" *> (ShowGroupLink <$> displayName), + "/_create member contact #" *> (APICreateMemberContact <$> A.decimal <* A.space <*> A.decimal), + "/_invite member contact @" *> (APISendMemberContactInvitation <$> A.decimal <*> optional (A.space *> msgContentP)), (">#" <|> "> #") *> (SendGroupMessageQuote <$> displayName <* A.space <*> pure Nothing <*> quotedMsg <*> msgTextP), (">#" <|> "> #") *> (SendGroupMessageQuote <$> displayName <* A.space <* char_ '@' <*> (Just <$> displayName) <* A.space <*> quotedMsg <*> msgTextP), "/_contacts " *> (APIListContacts <$> A.decimal), @@ -5347,6 +5540,7 @@ chatCommandP = ("/connect" <|> "/c") *> (Connect <$> incognitoP <* A.space <*> ((Just <$> strP) <|> A.takeByteString $> Nothing)), ("/connect" <|> "/c") *> (AddContact <$> incognitoP), SendMessage <$> chatNameP <* A.space <*> msgTextP, + "@#" *> (SendMemberContactMessage <$> displayName <* A.space <* char_ '@' <*> displayName <* A.space <*> msgTextP), "/live " *> (SendLiveMessage <$> chatNameP <*> (A.space *> msgTextP <|> pure "")), (">@" <|> "> @") *> sendMsgQuote (AMsgDirection SMDRcv), (">>@" <|> ">> @") *> sendMsgQuote (AMsgDirection SMDSnd), diff --git a/src/Simplex/Chat/Archive.hs b/src/Simplex/Chat/Archive.hs index 2444785501..f8fa0d152a 100644 --- a/src/Simplex/Chat/Archive.hs +++ b/src/Simplex/Chat/Archive.hs @@ -13,6 +13,7 @@ module Simplex.Chat.Archive where import qualified Codec.Archive.Zip as Z +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Data.Functor (($>)) diff --git a/src/Simplex/Chat/Bot.hs b/src/Simplex/Chat/Bot.hs index df9c66ceee..ecd1659bca 100644 --- a/src/Simplex/Chat/Bot.hs +++ b/src/Simplex/Chat/Bot.hs @@ -8,7 +8,7 @@ module Simplex.Chat.Bot where import Control.Concurrent.Async import Control.Concurrent.STM -import Control.Monad.Reader +import Control.Monad import qualified Data.ByteString.Char8 as B import qualified Data.Text as T import Simplex.Chat.Controller diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index b2403e8587..2c829e4a95 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -282,6 +282,8 @@ data ChatCommand | APIGroupLinkMemberRole GroupId GroupMemberRole | APIDeleteGroupLink GroupId | APIGetGroupLink GroupId + | APICreateMemberContact GroupId GroupMemberId + | APISendMemberContactInvitation {contactId :: ContactId, msgContent_ :: Maybe MsgContent} | APIGetUserProtoServers UserId AProtocolType | GetUserProtoServers AProtocolType | APISetUserProtoServers UserId AProtoServersConfig @@ -353,6 +355,7 @@ data ChatCommand | AcceptContact IncognitoEnabled ContactName | RejectContact ContactName | SendMessage ChatName Text + | SendMemberContactMessage GroupName ContactName Text | SendLiveMessage ChatName Text | SendMessageQuote {contactName :: ContactName, msgDir :: AMsgDirection, quotedMsg :: Text, message :: Text} | SendMessageBroadcast Text -- UserId (not used in UI) @@ -553,6 +556,11 @@ data ChatResponse | CRGroupLink {user :: User, groupInfo :: GroupInfo, connReqContact :: ConnReqContact, memberRole :: GroupMemberRole} | CRGroupLinkDeleted {user :: User, groupInfo :: GroupInfo} | CRAcceptingGroupJoinRequest {user :: User, groupInfo :: GroupInfo, contact :: Contact} + | CRNoMemberContactCreating {user :: User, groupInfo :: GroupInfo, member :: GroupMember} -- only used in CLI + | CRNewMemberContact {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} + | CRNewMemberContactSentInv {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} + | CRNewMemberContactReceivedInv {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} + | CRMemberContactConnected {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} | CRMemberSubError {user :: User, groupInfo :: GroupInfo, member :: GroupMember, chatError :: ChatError} | CRMemberSubSummary {user :: User, memberSubscriptions :: [MemberSubStatus]} | CRGroupSubscribed {user :: User, groupInfo :: GroupInfo} @@ -877,6 +885,7 @@ data ChatErrorType | CEChatStoreChanged | CEInvalidConnReq | CEInvalidChatMessage {connection :: Connection, msgMeta :: Maybe MsgMetaJSON, messageData :: Text, message :: String} + | CEContactNotFound {contactName :: ContactName, suspectedMember :: Maybe (GroupInfo, GroupMember)} | CEContactNotReady {contact :: Contact} | CEContactDisabled {contact :: Contact} | CEConnectionDisabled {connection :: Connection} @@ -927,6 +936,7 @@ data ChatErrorType | CEAgentCommandError {message :: String} | CEInvalidFileDescription {message :: String} | CEConnectionIncognitoChangeProhibited + | CEPeerChatVRangeIncompatible | CEInternalError {message :: String} | CEException {message :: String} deriving (Show, Exception, Generic) diff --git a/src/Simplex/Chat/Messages.hs b/src/Simplex/Chat/Messages.hs index 45e5f9ff74..79463d2107 100644 --- a/src/Simplex/Chat/Messages.hs +++ b/src/Simplex/Chat/Messages.hs @@ -6,11 +6,14 @@ {-# LANGUAGE KindSignatures #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeApplications #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module Simplex.Chat.Messages where import Control.Applicative ((<|>)) @@ -373,7 +376,7 @@ contactTimedTTL Contact {mergedPreferences = ContactUserPreferences {timedMessag | forUser enabled && forContact enabled = Just ttl | otherwise = Nothing where - TimedMessagesPreference {ttl} = preference (userPreference :: ContactUserPref TimedMessagesPreference) + TimedMessagesPreference {ttl} = userPreference.preference groupTimedTTL :: GroupInfo -> Maybe (Maybe Int) groupTimedTTL GroupInfo {fullGroupPreferences = FullGroupPreferences {timedMessages = TimedMessagesGroupPreference {enable, ttl}}} diff --git a/src/Simplex/Chat/Messages/CIContent.hs b/src/Simplex/Chat/Messages/CIContent.hs index 95c490a901..df22c2684c 100644 --- a/src/Simplex/Chat/Messages/CIContent.hs +++ b/src/Simplex/Chat/Messages/CIContent.hs @@ -190,6 +190,7 @@ ciRequiresAttention content = case msgDirection @d of RGEGroupDeleted -> True RGEGroupUpdated _ -> False RGEInvitedViaGroupLink -> False + RGEMemberCreatedContact -> False CIRcvConnEvent _ -> True CIRcvChatFeature {} -> False CIRcvChatPreference {} -> False @@ -213,6 +214,7 @@ data RcvGroupEvent -- but being RcvGroupEvent allows them to be assigned to the respective member (and so enable "send direct message") -- and be created as unread without adding / working around new status for sent items | RGEInvitedViaGroupLink -- CRSentGroupInvitationViaLink + | RGEMemberCreatedContact -- CRNewMemberContactReceivedInv deriving (Show, Generic) instance FromJSON RcvGroupEvent where @@ -378,6 +380,7 @@ rcvGroupEventToText = \case RGEGroupDeleted -> "deleted group" RGEGroupUpdated _ -> "group profile updated" RGEInvitedViaGroupLink -> "invited via your group link" + RGEMemberCreatedContact -> "started direct connection with you" sndGroupEventToText :: SndGroupEvent -> Text sndGroupEventToText = \case diff --git a/src/Simplex/Chat/Migrations/M20230913_member_contacts.hs b/src/Simplex/Chat/Migrations/M20230913_member_contacts.hs new file mode 100644 index 0000000000..b116373518 --- /dev/null +++ b/src/Simplex/Chat/Migrations/M20230913_member_contacts.hs @@ -0,0 +1,27 @@ +{-# LANGUAGE QuasiQuotes #-} + +module Simplex.Chat.Migrations.M20230913_member_contacts where + +import Database.SQLite.Simple (Query) +import Database.SQLite.Simple.QQ (sql) + +m20230913_member_contacts :: Query +m20230913_member_contacts = + [sql| +ALTER TABLE contacts ADD COLUMN contact_group_member_id INTEGER + REFERENCES group_members(group_member_id) ON DELETE SET NULL; + +CREATE INDEX idx_contacts_contact_group_member_id ON contacts(contact_group_member_id); + +ALTER TABLE contacts ADD COLUMN contact_grp_inv_sent INTEGER NOT NULL DEFAULT 0; +|] + +down_m20230913_member_contacts :: Query +down_m20230913_member_contacts = + [sql| +ALTER TABLE contacts DROP COLUMN contact_grp_inv_sent; + +DROP INDEX idx_contacts_contact_group_member_id; + +ALTER TABLE contacts DROP COLUMN contact_group_member_id; +|] diff --git a/src/Simplex/Chat/Migrations/M20230914_member_probes.hs b/src/Simplex/Chat/Migrations/M20230914_member_probes.hs new file mode 100644 index 0000000000..8772b6cdad --- /dev/null +++ b/src/Simplex/Chat/Migrations/M20230914_member_probes.hs @@ -0,0 +1,169 @@ +{-# LANGUAGE QuasiQuotes #-} + +module Simplex.Chat.Migrations.M20230914_member_probes where + +import Database.SQLite.Simple (Query) +import Database.SQLite.Simple.QQ (sql) + +m20230914_member_probes :: Query +m20230914_member_probes = + [sql| +CREATE TABLE new__sent_probes( + sent_probe_id INTEGER PRIMARY KEY, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, + probe BLOB NOT NULL, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL), + UNIQUE(user_id, probe) +); + +CREATE TABLE new__sent_probe_hashes( + sent_probe_hash_id INTEGER PRIMARY KEY, + sent_probe_id INTEGER NOT NULL REFERENCES new__sent_probes ON DELETE CASCADE, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL) +); + +CREATE TABLE new__received_probes( + received_probe_id INTEGER PRIMARY KEY, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, + probe BLOB, + probe_hash BLOB NOT NULL, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL) +); + +INSERT INTO new__sent_probes + (sent_probe_id, contact_id, probe, user_id, created_at, updated_at) +SELECT + sent_probe_id, contact_id, probe, user_id, created_at, updated_at + FROM sent_probes; + +INSERT INTO new__sent_probe_hashes + (sent_probe_hash_id, sent_probe_id, contact_id, user_id, created_at, updated_at) +SELECT + sent_probe_hash_id, sent_probe_id, contact_id, user_id, created_at, updated_at + FROM sent_probe_hashes; + +INSERT INTO new__received_probes + (received_probe_id, contact_id, probe, probe_hash, user_id, created_at, updated_at) +SELECT + received_probe_id, contact_id, probe, probe_hash, user_id, created_at, updated_at + FROM received_probes; + +DROP INDEX idx_sent_probe_hashes_user_id; +DROP INDEX idx_sent_probe_hashes_contact_id; +DROP INDEX idx_received_probes_user_id; +DROP INDEX idx_received_probes_contact_id; + +DROP TABLE sent_probes; +DROP TABLE sent_probe_hashes; +DROP TABLE received_probes; + +ALTER TABLE new__sent_probes RENAME TO sent_probes; +ALTER TABLE new__sent_probe_hashes RENAME TO sent_probe_hashes; +ALTER TABLE new__received_probes RENAME TO received_probes; + +CREATE INDEX idx_sent_probes_user_id ON sent_probes(user_id); +CREATE INDEX idx_sent_probes_contact_id ON sent_probes(contact_id); +CREATE INDEX idx_sent_probes_group_member_id ON sent_probes(group_member_id); + +CREATE INDEX idx_sent_probe_hashes_user_id ON sent_probe_hashes(user_id); +CREATE INDEX idx_sent_probe_hashes_sent_probe_id ON sent_probe_hashes(sent_probe_id); +CREATE INDEX idx_sent_probe_hashes_contact_id ON sent_probe_hashes(contact_id); +CREATE INDEX idx_sent_probe_hashes_group_member_id ON sent_probe_hashes(group_member_id); + +CREATE INDEX idx_received_probes_user_id ON received_probes(user_id); +CREATE INDEX idx_received_probes_contact_id ON received_probes(contact_id); +CREATE INDEX idx_received_probes_probe ON received_probes(probe); +CREATE INDEX idx_received_probes_probe_hash ON received_probes(probe_hash); +|] + +down_m20230914_member_probes :: Query +down_m20230914_member_probes = + [sql| +CREATE TABLE old__sent_probes( + sent_probe_id INTEGER PRIMARY KEY, + contact_id INTEGER NOT NULL REFERENCES contacts ON DELETE CASCADE, + probe BLOB NOT NULL, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL), + UNIQUE(user_id, probe) +); + +CREATE TABLE old__sent_probe_hashes( + sent_probe_hash_id INTEGER PRIMARY KEY, + sent_probe_id INTEGER NOT NULL REFERENCES old__sent_probes ON DELETE CASCADE, + contact_id INTEGER NOT NULL REFERENCES contacts ON DELETE CASCADE, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL) +); + +CREATE TABLE old__received_probes( + received_probe_id INTEGER PRIMARY KEY, + contact_id INTEGER NOT NULL REFERENCES contacts ON DELETE CASCADE, + probe BLOB, + probe_hash BLOB NOT NULL, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL) +); + +DELETE FROM sent_probes WHERE contact_id IS NULL; +DELETE FROM sent_probe_hashes WHERE contact_id IS NULL; +DELETE FROM received_probes WHERE contact_id IS NULL; + +INSERT INTO old__sent_probes + (sent_probe_id, contact_id, probe, user_id, created_at, updated_at) +SELECT + sent_probe_id, contact_id, probe, user_id, created_at, updated_at + FROM sent_probes; + +INSERT INTO old__sent_probe_hashes + (sent_probe_hash_id, sent_probe_id, contact_id, user_id, created_at, updated_at) +SELECT + sent_probe_hash_id, sent_probe_id, contact_id, user_id, created_at, updated_at + FROM sent_probe_hashes; + +INSERT INTO old__received_probes + (received_probe_id, contact_id, probe, probe_hash, user_id, created_at, updated_at) +SELECT + received_probe_id, contact_id, probe, probe_hash, user_id, created_at, updated_at + FROM received_probes; + +DROP INDEX idx_sent_probes_user_id; +DROP INDEX idx_sent_probes_contact_id; +DROP INDEX idx_sent_probes_group_member_id; + +DROP INDEX idx_sent_probe_hashes_user_id; +DROP INDEX idx_sent_probe_hashes_sent_probe_id; +DROP INDEX idx_sent_probe_hashes_contact_id; +DROP INDEX idx_sent_probe_hashes_group_member_id; + +DROP INDEX idx_received_probes_user_id; +DROP INDEX idx_received_probes_contact_id; +DROP INDEX idx_received_probes_probe; +DROP INDEX idx_received_probes_probe_hash; + +DROP TABLE sent_probes; +DROP TABLE sent_probe_hashes; +DROP TABLE received_probes; + +ALTER TABLE old__sent_probes RENAME TO sent_probes; +ALTER TABLE old__sent_probe_hashes RENAME TO sent_probe_hashes; +ALTER TABLE old__received_probes RENAME TO received_probes; + +CREATE INDEX idx_received_probes_user_id ON received_probes(user_id); +CREATE INDEX idx_received_probes_contact_id ON received_probes(contact_id); +CREATE INDEX idx_sent_probe_hashes_user_id ON sent_probe_hashes(user_id); +CREATE INDEX idx_sent_probe_hashes_contact_id ON sent_probe_hashes(contact_id); +|] diff --git a/src/Simplex/Chat/Migrations/chat_schema.sql b/src/Simplex/Chat/Migrations/chat_schema.sql index c71cc9aa90..141247e590 100644 --- a/src/Simplex/Chat/Migrations/chat_schema.sql +++ b/src/Simplex/Chat/Migrations/chat_schema.sql @@ -68,6 +68,9 @@ CREATE TABLE contacts( deleted INTEGER NOT NULL DEFAULT 0, favorite INTEGER NOT NULL DEFAULT 0, send_rcpts INTEGER, + contact_group_member_id INTEGER + REFERENCES group_members(group_member_id) ON DELETE SET NULL, + contact_grp_inv_sent INTEGER NOT NULL DEFAULT 0, FOREIGN KEY(user_id, local_display_name) REFERENCES display_names(user_id, local_display_name) ON DELETE CASCADE @@ -75,34 +78,6 @@ CREATE TABLE contacts( UNIQUE(user_id, local_display_name), UNIQUE(user_id, contact_profile_id) ); -CREATE TABLE sent_probes( - sent_probe_id INTEGER PRIMARY KEY, - contact_id INTEGER NOT NULL UNIQUE REFERENCES contacts ON DELETE CASCADE, - probe BLOB NOT NULL, - user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, - created_at TEXT CHECK(created_at NOT NULL), - updated_at TEXT CHECK(updated_at NOT NULL), - UNIQUE(user_id, probe) -); -CREATE TABLE sent_probe_hashes( - sent_probe_hash_id INTEGER PRIMARY KEY, - sent_probe_id INTEGER NOT NULL REFERENCES sent_probes ON DELETE CASCADE, - contact_id INTEGER NOT NULL REFERENCES contacts ON DELETE CASCADE, - user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, - created_at TEXT CHECK(created_at NOT NULL), - updated_at TEXT CHECK(updated_at NOT NULL), - UNIQUE(sent_probe_id, contact_id) -); -CREATE TABLE received_probes( - received_probe_id INTEGER PRIMARY KEY, - contact_id INTEGER NOT NULL REFERENCES contacts ON DELETE CASCADE, - probe BLOB, - probe_hash BLOB NOT NULL, - user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE - , - created_at TEXT CHECK(created_at NOT NULL), - updated_at TEXT CHECK(updated_at NOT NULL) -); CREATE TABLE known_servers( server_id INTEGER PRIMARY KEY, host TEXT NOT NULL, @@ -511,6 +486,35 @@ CREATE TABLE group_snd_item_statuses( created_at TEXT NOT NULL DEFAULT(datetime('now')), updated_at TEXT NOT NULL DEFAULT(datetime('now')) ); +CREATE TABLE IF NOT EXISTS "sent_probes"( + sent_probe_id INTEGER PRIMARY KEY, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, + probe BLOB NOT NULL, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL), + UNIQUE(user_id, probe) +); +CREATE TABLE IF NOT EXISTS "sent_probe_hashes"( + sent_probe_hash_id INTEGER PRIMARY KEY, + sent_probe_id INTEGER NOT NULL REFERENCES "sent_probes" ON DELETE CASCADE, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL) +); +CREATE TABLE IF NOT EXISTS "received_probes"( + received_probe_id INTEGER PRIMARY KEY, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, + probe BLOB, + probe_hash BLOB NOT NULL, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, + created_at TEXT CHECK(created_at NOT NULL), + updated_at TEXT CHECK(updated_at NOT NULL) +); CREATE INDEX contact_profiles_index ON contact_profiles( display_name, full_name @@ -624,10 +628,6 @@ CREATE INDEX idx_pending_group_messages_group_member_id ON pending_group_message ); CREATE INDEX idx_rcv_file_chunks_file_id ON rcv_file_chunks(file_id); CREATE INDEX idx_rcv_files_group_member_id ON rcv_files(group_member_id); -CREATE INDEX idx_received_probes_user_id ON received_probes(user_id); -CREATE INDEX idx_received_probes_contact_id ON received_probes(contact_id); -CREATE INDEX idx_sent_probe_hashes_user_id ON sent_probe_hashes(user_id); -CREATE INDEX idx_sent_probe_hashes_contact_id ON sent_probe_hashes(contact_id); CREATE INDEX idx_settings_user_id ON settings(user_id); CREATE INDEX idx_snd_file_chunks_file_id_connection_id ON snd_file_chunks( file_id, @@ -713,3 +713,21 @@ CREATE INDEX idx_chat_items_user_id_item_status ON chat_items( item_status ); CREATE INDEX idx_connections_to_subscribe ON connections(to_subscribe); +CREATE INDEX idx_contacts_contact_group_member_id ON contacts( + contact_group_member_id +); +CREATE INDEX idx_sent_probes_user_id ON sent_probes(user_id); +CREATE INDEX idx_sent_probes_contact_id ON sent_probes(contact_id); +CREATE INDEX idx_sent_probes_group_member_id ON sent_probes(group_member_id); +CREATE INDEX idx_sent_probe_hashes_user_id ON sent_probe_hashes(user_id); +CREATE INDEX idx_sent_probe_hashes_sent_probe_id ON sent_probe_hashes( + sent_probe_id +); +CREATE INDEX idx_sent_probe_hashes_contact_id ON sent_probe_hashes(contact_id); +CREATE INDEX idx_sent_probe_hashes_group_member_id ON sent_probe_hashes( + group_member_id +); +CREATE INDEX idx_received_probes_user_id ON received_probes(user_id); +CREATE INDEX idx_received_probes_contact_id ON received_probes(contact_id); +CREATE INDEX idx_received_probes_probe ON received_probes(probe); +CREATE INDEX idx_received_probes_probe_hash ON received_probes(probe_hash); diff --git a/src/Simplex/Chat/Mobile/File.hs b/src/Simplex/Chat/Mobile/File.hs index 4aabbcd12a..e30b899f12 100644 --- a/src/Simplex/Chat/Mobile/File.hs +++ b/src/Simplex/Chat/Mobile/File.hs @@ -16,7 +16,9 @@ module Simplex.Chat.Mobile.File ) where +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import Data.Aeson (ToJSON) import qualified Data.Aeson as J import Data.ByteString (ByteString) @@ -32,6 +34,7 @@ import Foreign.Ptr import Foreign.Storable (poke) import GHC.Generics (Generic) import Simplex.Chat.Mobile.Shared +import Simplex.Chat.Util (chunkSize, encryptFile) import Simplex.Messaging.Crypto.File (CryptoFile (..), CryptoFileArgs (..), CryptoFileHandle, FTCryptoError (..)) import qualified Simplex.Messaging.Crypto.File as CF import Simplex.Messaging.Encoding.String @@ -103,16 +106,8 @@ chatEncryptFile fromPath toPath = where encrypt = do cfArgs <- liftIO $ CF.randomArgs - let toFile = CryptoFile toPath $ Just cfArgs - withExceptT show $ - withFile fromPath ReadMode $ \r -> CF.withFile toFile WriteMode $ \w -> do - encryptChunks r w - liftIO $ CF.hPutTag w + encryptFile fromPath toPath cfArgs pure cfArgs - encryptChunks r w = do - ch <- liftIO $ LB.hGet r chunkSize - unless (LB.null ch) $ liftIO $ CF.hPut w ch - unless (LB.length ch < chunkSize) $ encryptChunks r w cChatDecryptFile :: CString -> CString -> CString -> CString -> IO CString cChatDecryptFile cFromPath cKey cNonce cToPath = do @@ -147,7 +142,3 @@ chatDecryptFile fromPath keyStr nonceStr toPath = fromLeft "" <$> runCatchExcept runCatchExceptT :: ExceptT String IO a -> IO (Either String a) runCatchExceptT action = runExceptT action `catchAll` (pure . Left . show) - -chunkSize :: Num a => a -chunkSize = 65536 -{-# INLINE chunkSize #-} diff --git a/src/Simplex/Chat/Mobile/WebRTC.hs b/src/Simplex/Chat/Mobile/WebRTC.hs index 19ba2b751b..7840a069fa 100644 --- a/src/Simplex/Chat/Mobile/WebRTC.hs +++ b/src/Simplex/Chat/Mobile/WebRTC.hs @@ -8,7 +8,9 @@ module Simplex.Chat.Mobile.WebRTC ( reservedSize, ) where +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import qualified Crypto.Cipher.Types as AES import Data.Bifunctor (bimap) import qualified Data.ByteArray as BA diff --git a/src/Simplex/Chat/Protocol.hs b/src/Simplex/Chat/Protocol.hs index 13692b57cc..6e725e6c26 100644 --- a/src/Simplex/Chat/Protocol.hs +++ b/src/Simplex/Chat/Protocol.hs @@ -13,6 +13,8 @@ {-# LANGUAGE StrictData #-} {-# LANGUAGE TypeApplications #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module Simplex.Chat.Protocol where import Control.Applicative ((<|>)) @@ -58,6 +60,10 @@ supportedChatVRange = mkVersionRange 1 currentChatVersion groupNoDirectVRange :: VersionRange groupNoDirectVRange = mkVersionRange 2 currentChatVersion +-- version range that supports establishing direct connection via x.grp.direct.inv with a group member +xGrpDirectInvVRange :: VersionRange +xGrpDirectInvVRange = mkVersionRange 2 currentChatVersion + data ConnectionEntity = RcvDirectMsgConnection {entityConnection :: Connection, contact :: Maybe Contact} | RcvGroupMsgConnection {entityConnection :: Connection, groupInfo :: GroupInfo, groupMember :: GroupMember} @@ -223,6 +229,7 @@ data ChatMsgEvent (e :: MsgEncoding) where XGrpLeave :: ChatMsgEvent 'Json XGrpDel :: ChatMsgEvent 'Json XGrpInfo :: GroupProfile -> ChatMsgEvent 'Json + XGrpDirectInv :: ConnReqInvitation -> Maybe MsgContent -> ChatMsgEvent 'Json XInfoProbe :: Probe -> ChatMsgEvent 'Json XInfoProbeCheck :: ProbeHash -> ChatMsgEvent 'Json XInfoProbeOk :: Probe -> ChatMsgEvent 'Json @@ -557,6 +564,7 @@ data CMEventTag (e :: MsgEncoding) where XGrpLeave_ :: CMEventTag 'Json XGrpDel_ :: CMEventTag 'Json XGrpInfo_ :: CMEventTag 'Json + XGrpDirectInv_ :: CMEventTag 'Json XInfoProbe_ :: CMEventTag 'Json XInfoProbeCheck_ :: CMEventTag 'Json XInfoProbeOk_ :: CMEventTag 'Json @@ -602,6 +610,7 @@ instance MsgEncodingI e => StrEncoding (CMEventTag e) where XGrpLeave_ -> "x.grp.leave" XGrpDel_ -> "x.grp.del" XGrpInfo_ -> "x.grp.info" + XGrpDirectInv_ -> "x.grp.direct.inv" XInfoProbe_ -> "x.info.probe" XInfoProbeCheck_ -> "x.info.probe.check" XInfoProbeOk_ -> "x.info.probe.ok" @@ -648,6 +657,7 @@ instance StrEncoding ACMEventTag where "x.grp.leave" -> XGrpLeave_ "x.grp.del" -> XGrpDel_ "x.grp.info" -> XGrpInfo_ + "x.grp.direct.inv" -> XGrpDirectInv_ "x.info.probe" -> XInfoProbe_ "x.info.probe.check" -> XInfoProbeCheck_ "x.info.probe.ok" -> XInfoProbeOk_ @@ -690,6 +700,7 @@ toCMEventTag msg = case msg of XGrpLeave -> XGrpLeave_ XGrpDel -> XGrpDel_ XGrpInfo _ -> XGrpInfo_ + XGrpDirectInv _ _ -> XGrpDirectInv_ XInfoProbe _ -> XInfoProbe_ XInfoProbeCheck _ -> XInfoProbeCheck_ XInfoProbeOk _ -> XInfoProbeOk_ @@ -785,6 +796,7 @@ appJsonToCM AppMessageJson {v, msgId, event, params} = do XGrpLeave_ -> pure XGrpLeave XGrpDel_ -> pure XGrpDel XGrpInfo_ -> XGrpInfo <$> p "groupProfile" + XGrpDirectInv_ -> XGrpDirectInv <$> p "connReq" <*> opt "content" XInfoProbe_ -> XInfoProbe <$> p "probe" XInfoProbeCheck_ -> XInfoProbeCheck <$> p "probeHash" XInfoProbeOk_ -> XInfoProbeOk <$> p "probe" @@ -841,6 +853,7 @@ chatToAppMessage ChatMessage {chatVRange, msgId, chatMsgEvent} = case encoding @ XGrpLeave -> JM.empty XGrpDel -> JM.empty XGrpInfo p -> o ["groupProfile" .= p] + XGrpDirectInv connReq content -> o $ ("content" .=? content) ["connReq" .= connReq] XInfoProbe probe -> o ["probe" .= probe] XInfoProbeCheck probeHash -> o ["probeHash" .= probeHash] XInfoProbeOk probe -> o ["probe" .= probe] diff --git a/src/Simplex/Chat/Store/Connections.hs b/src/Simplex/Chat/Store/Connections.hs index 025755c924..7da0d1ca85 100644 --- a/src/Simplex/Chat/Store/Connections.hs +++ b/src/Simplex/Chat/Store/Connections.hs @@ -5,6 +5,8 @@ {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TypeOperators #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module Simplex.Chat.Store.Connections ( getConnectionEntity, getConnectionsToSubscribe, @@ -13,6 +15,7 @@ module Simplex.Chat.Store.Connections where import Control.Applicative ((<|>)) +import Control.Monad import Control.Monad.Except import Data.Int (Int64) import Data.Maybe (catMaybes, fromMaybe) @@ -69,18 +72,18 @@ getConnectionEntity db user@User {userId, userContactId} agentConnId = do [sql| SELECT c.contact_profile_id, c.local_display_name, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, c.via_group, c.contact_used, c.enable_ntfs, c.send_rcpts, c.favorite, - p.preferences, c.user_preferences, c.created_at, c.updated_at, c.chat_ts + p.preferences, c.user_preferences, c.created_at, c.updated_at, c.chat_ts, c.contact_group_member_id, c.contact_grp_inv_sent FROM contacts c JOIN contact_profiles p ON c.contact_profile_id = p.contact_profile_id WHERE c.user_id = ? AND c.contact_id = ? AND c.deleted = 0 |] (userId, contactId) - toContact' :: Int64 -> Connection -> [(ProfileId, ContactName, Text, Text, Maybe ImageData, Maybe ConnReqContact, LocalAlias, Maybe Int64, Bool) :. (Maybe Bool, Maybe Bool, Bool, Maybe Preferences, Preferences, UTCTime, UTCTime, Maybe UTCTime)] -> Either StoreError Contact - toContact' contactId activeConn [(profileId, localDisplayName, displayName, fullName, image, contactLink, localAlias, viaGroup, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs)] = + toContact' :: Int64 -> Connection -> [(ProfileId, ContactName, Text, Text, Maybe ImageData, Maybe ConnReqContact, LocalAlias, Maybe Int64, Bool) :. (Maybe Bool, Maybe Bool, Bool, Maybe Preferences, Preferences, UTCTime, UTCTime, Maybe UTCTime, Maybe GroupMemberId, Bool)] -> Either StoreError Contact + toContact' contactId activeConn [(profileId, localDisplayName, displayName, fullName, image, contactLink, localAlias, viaGroup, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent)] = let profile = LocalProfile {profileId, displayName, fullName, image, contactLink, preferences, localAlias} chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_, sendRcpts, favorite} mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito activeConn - in Right Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs} + in Right Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent} toContact' _ _ _ = Left $ SEInternalError "referenced contact not found" getGroupAndMember_ :: Int64 -> Connection -> ExceptT StoreError IO (GroupInfo, GroupMember) getGroupAndMember_ groupMemberId c = ExceptT $ do diff --git a/src/Simplex/Chat/Store/Direct.hs b/src/Simplex/Chat/Store/Direct.hs index 609da128a7..7e8cee0e74 100644 --- a/src/Simplex/Chat/Store/Direct.hs +++ b/src/Simplex/Chat/Store/Direct.hs @@ -1,4 +1,5 @@ {-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} @@ -7,11 +8,14 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module Simplex.Chat.Store.Direct ( updateContact_, updateContactProfile_, updateContactProfile_', deleteContactProfile_, + deleteUnusedProfile_, -- * Contacts and connections functions getPendingContactConnection, @@ -60,7 +64,9 @@ module Simplex.Chat.Store.Direct ) where +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import Data.Either (rights) import Data.Functor (($>)) import Data.Int (Int64) @@ -142,7 +148,7 @@ getConnReqContactXContactId db user@User {userId} cReqHash = do SELECT -- Contact ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.send_rcpts, ct.favorite, - cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, + cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.contact_group_member_id, ct.contact_grp_inv_sent, -- Connection c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.auth_err_counter, @@ -200,7 +206,7 @@ createDirectContact db user@User {userId} activeConn@Connection {connId, localAl let profile = toLocalProfile profileId p localAlias userPreferences = emptyChatPrefs mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito activeConn - pure $ Contact {contactId, localDisplayName, profile, activeConn, viaGroup = Nothing, contactUsed = False, chatSettings = defaultChatSettings, userPreferences, mergedPreferences, createdAt, updatedAt = createdAt, chatTs = Just createdAt} + pure $ Contact {contactId, localDisplayName, profile, activeConn, viaGroup = Nothing, contactUsed = False, chatSettings = defaultChatSettings, userPreferences, mergedPreferences, createdAt, updatedAt = createdAt, chatTs = Just createdAt, contactGroupMemberId = Nothing, contactGrpInvSent = False} deleteContactConnectionsAndFiles :: DB.Connection -> UserId -> Contact -> IO () deleteContactConnectionsAndFiles db userId Contact {contactId} = do @@ -267,6 +273,34 @@ deleteContactProfile_ db userId contactId = |] (userId, contactId) +deleteUnusedProfile_ :: DB.Connection -> UserId -> ProfileId -> IO () +deleteUnusedProfile_ db userId profileId = + DB.executeNamed + db + [sql| + DELETE FROM contact_profiles + WHERE user_id = :user_id AND contact_profile_id = :profile_id + AND 1 NOT IN ( + SELECT 1 FROM connections + WHERE user_id = :user_id AND custom_user_profile_id = :profile_id LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM contacts + WHERE user_id = :user_id AND contact_profile_id = :profile_id LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM contact_requests + WHERE user_id = :user_id AND contact_profile_id = :profile_id LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM group_members + WHERE user_id = :user_id + AND (member_profile_id = :profile_id OR contact_profile_id = :profile_id) + LIMIT 1 + ) + |] + [":user_id" := userId, ":profile_id" := profileId] + updateContactProfile :: DB.Connection -> User -> Contact -> Profile -> ExceptT StoreError IO Contact updateContactProfile db user@User {userId} c p' | displayName == newName = do @@ -427,7 +461,7 @@ createOrUpdateContactRequest db user@User {userId} userContactLinkId invId (Vers ExceptT $ maybeM getContactRequestByXContactId xContactId_ >>= \case Nothing -> createContactRequest - Just cr -> updateContactRequest cr $> Right (contactRequestId (cr :: UserContactRequest)) + Just cr -> updateContactRequest cr $> Right cr.contactRequestId getContactRequest db user cReqId createContactRequest :: IO (Either StoreError Int64) createContactRequest = do @@ -458,7 +492,7 @@ createOrUpdateContactRequest db user@User {userId} userContactLinkId invId (Vers SELECT -- Contact ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.send_rcpts, ct.favorite, - cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, + cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.contact_group_member_id, ct.contact_grp_inv_sent, -- Connection c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.auth_err_counter, @@ -603,7 +637,7 @@ createAcceptedContact db user@User {userId, profile = LocalProfile {preferences} contactId <- insertedRowId db activeConn <- createConnection_ db userId ConnContact (Just contactId) agentConnId cReqChatVRange Nothing (Just userContactLinkId) customUserProfileId 0 createdAt subMode let mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito activeConn - pure $ Contact {contactId, localDisplayName, profile = toLocalProfile profileId profile "", activeConn, viaGroup = Nothing, contactUsed = False, chatSettings = defaultChatSettings, userPreferences, mergedPreferences, createdAt = createdAt, updatedAt = createdAt, chatTs = Just createdAt} + pure $ Contact {contactId, localDisplayName, profile = toLocalProfile profileId profile "", activeConn, viaGroup = Nothing, contactUsed = False, chatSettings = defaultChatSettings, userPreferences, mergedPreferences, createdAt = createdAt, updatedAt = createdAt, chatTs = Just createdAt, contactGroupMemberId = Nothing, contactGrpInvSent = False} getContactIdByName :: DB.Connection -> User -> ContactName -> ExceptT StoreError IO Int64 getContactIdByName db User {userId} cName = @@ -622,7 +656,7 @@ getContact_ db user@User {userId} contactId deleted = SELECT -- Contact ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.send_rcpts, ct.favorite, - cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, + cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.contact_group_member_id, ct.contact_grp_inv_sent, -- Connection c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.auth_err_counter, diff --git a/src/Simplex/Chat/Store/Files.hs b/src/Simplex/Chat/Store/Files.hs index 685d67e4de..a710696dad 100644 --- a/src/Simplex/Chat/Store/Files.hs +++ b/src/Simplex/Chat/Store/Files.hs @@ -57,6 +57,7 @@ module Simplex.Chat.Store.Files xftpAcceptRcvFT, setRcvFileToReceive, setFileCryptoArgs, + removeFileCryptoArgs, getRcvFilesToReceive, setRcvFTAgentDeleted, updateRcvFileStatus, @@ -75,7 +76,9 @@ module Simplex.Chat.Store.Files where import Control.Applicative ((<|>)) +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import Data.Either (rights) import Data.Int (Int64) import Data.Maybe (fromMaybe, isJust, listToMaybe) @@ -483,9 +486,9 @@ createRcvFileTransfer :: DB.Connection -> UserId -> Contact -> FileInvitation -> createRcvFileTransfer db userId Contact {contactId, localDisplayName = c} f@FileInvitation {fileName, fileSize, fileConnReq, fileInline, fileDescr} rcvFileInline chunkSize = do currentTs <- liftIO getCurrentTime rfd_ <- mapM (createRcvFD_ db userId currentTs) fileDescr - let rfdId = (fileDescrId :: RcvFileDescr -> Int64) <$> rfd_ + let rfdId = (\RcvFileDescr {fileDescrId} -> fileDescrId) <$> rfd_ -- cryptoArgs = Nothing here, the decision to encrypt is made when receiving it - xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False, cryptoArgs = Nothing}) <$> rfd_ + xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False}) <$> rfd_ fileProtocol = if isJust rfd_ then FPXFTP else FPSMP fileId <- liftIO $ do DB.execute @@ -498,15 +501,15 @@ createRcvFileTransfer db userId Contact {contactId, localDisplayName = c} f@File db "INSERT INTO rcv_files (file_id, file_status, file_queue_info, file_inline, rcv_file_inline, file_descr_id, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)" (fileId, FSNew, fileConnReq, fileInline, rcvFileInline, rfdId, currentTs, currentTs) - pure RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = f, fileStatus = RFSNew, rcvFileInline, senderDisplayName = c, chunkSize, cancelled = False, grpMemberId = Nothing} + pure RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = f, fileStatus = RFSNew, rcvFileInline, senderDisplayName = c, chunkSize, cancelled = False, grpMemberId = Nothing, cryptoArgs = Nothing} createRcvGroupFileTransfer :: DB.Connection -> UserId -> GroupMember -> FileInvitation -> Maybe InlineFileMode -> Integer -> ExceptT StoreError IO RcvFileTransfer createRcvGroupFileTransfer db userId GroupMember {groupId, groupMemberId, localDisplayName = c} f@FileInvitation {fileName, fileSize, fileConnReq, fileInline, fileDescr} rcvFileInline chunkSize = do currentTs <- liftIO getCurrentTime rfd_ <- mapM (createRcvFD_ db userId currentTs) fileDescr - let rfdId = (fileDescrId :: RcvFileDescr -> Int64) <$> rfd_ + let rfdId = (\RcvFileDescr {fileDescrId} -> fileDescrId) <$> rfd_ -- cryptoArgs = Nothing here, the decision to encrypt is made when receiving it - xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False, cryptoArgs = Nothing}) <$> rfd_ + xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False}) <$> rfd_ fileProtocol = if isJust rfd_ then FPXFTP else FPSMP fileId <- liftIO $ do DB.execute @@ -519,7 +522,7 @@ createRcvGroupFileTransfer db userId GroupMember {groupId, groupMemberId, localD db "INSERT INTO rcv_files (file_id, file_status, file_queue_info, file_inline, rcv_file_inline, group_member_id, file_descr_id, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)" (fileId, FSNew, fileConnReq, fileInline, rcvFileInline, groupMemberId, rfdId, currentTs, currentTs) - pure RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = f, fileStatus = RFSNew, rcvFileInline, senderDisplayName = c, chunkSize, cancelled = False, grpMemberId = Just groupMemberId} + pure RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = f, fileStatus = RFSNew, rcvFileInline, senderDisplayName = c, chunkSize, cancelled = False, grpMemberId = Just groupMemberId, cryptoArgs = Nothing} createRcvFD_ :: DB.Connection -> UserId -> UTCTime -> FileDescr -> ExceptT StoreError IO RcvFileDescr createRcvFD_ db userId currentTs FileDescr {fileDescrText, fileDescrPartNo, fileDescrComplete} = do @@ -637,8 +640,8 @@ getRcvFileTransfer db User {userId} fileId = do ft senderDisplayName fileStatus = let fileInvitation = FileInvitation {fileName, fileSize, fileDigest = Nothing, fileConnReq, fileInline, fileDescr = Nothing} cryptoArgs = CFArgs <$> fileKey <*> fileNonce - xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId, agentRcvFileDeleted, cryptoArgs}) <$> rfd_ - in RcvFileTransfer {fileId, xftpRcvFile, fileInvitation, fileStatus, rcvFileInline, senderDisplayName, chunkSize, cancelled, grpMemberId} + xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId, agentRcvFileDeleted}) <$> rfd_ + in RcvFileTransfer {fileId, xftpRcvFile, fileInvitation, fileStatus, rcvFileInline, senderDisplayName, chunkSize, cancelled, grpMemberId, cryptoArgs} rfi = maybe (throwError $ SERcvFileInvalid fileId) pure =<< rfi_ rfi_ = case (filePath_, connId_, agentConnId_) of (Just filePath, connId, agentConnId) -> pure $ Just RcvFileInfo {filePath, connId, agentConnId} @@ -707,6 +710,11 @@ setFileCryptoArgs_ db fileId (CFArgs key nonce) currentTs = "UPDATE files SET file_crypto_key = ?, file_crypto_nonce = ?, updated_at = ? WHERE file_id = ?" (key, nonce, currentTs, fileId) +removeFileCryptoArgs :: DB.Connection -> FileTransferId -> IO () +removeFileCryptoArgs db fileId = do + currentTs <- getCurrentTime + DB.execute db "UPDATE files SET file_crypto_key = NULL, file_crypto_nonce = NULL, updated_at = ? WHERE file_id = ?" (currentTs, fileId) + getRcvFilesToReceive :: DB.Connection -> User -> IO [RcvFileTransfer] getRcvFilesToReceive db user@User {userId} = do cutoffTs <- addUTCTime (- (2 * nominalDay)) <$> getCurrentTime diff --git a/src/Simplex/Chat/Store/Groups.hs b/src/Simplex/Chat/Store/Groups.hs index 89499e4486..6656208aba 100644 --- a/src/Simplex/Chat/Store/Groups.hs +++ b/src/Simplex/Chat/Store/Groups.hs @@ -8,6 +8,9 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeOperators #-} +{-# LANGUAGE OverloadedRecordDot #-} + +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} module Simplex.Chat.Store.Groups ( -- * Util methods @@ -34,6 +37,7 @@ module Simplex.Chat.Store.Groups updateGroupProfile, getGroupIdByName, getGroupMemberIdByName, + getActiveMembersByName, getGroupInfoByName, getGroupMember, getGroupMemberById, @@ -73,25 +77,36 @@ module Simplex.Chat.Store.Groups getViaGroupMember, getViaGroupContact, getMatchingContacts, + getMatchingMemberContacts, createSentProbe, createSentProbeHash, - deleteSentProbe, matchReceivedProbe, matchReceivedProbeHash, matchSentProbe, mergeContactRecords, + updateMemberContact, updateGroupSettings, getXGrpMemIntroContDirect, getXGrpMemIntroContGroup, getHostConnId, + createMemberContact, + getMemberContact, + setContactGrpInvSent, + createMemberContactInvited, + updateMemberContactInvited, + resetMemberContactFields, ) where +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import Crypto.Random (ChaChaDRG) import Data.Either (rights) import Data.Int (Int64) +import Data.List (sortOn) import Data.Maybe (fromMaybe, isNothing) +import Data.Ord (Down (..)) import Data.Text (Text) import Data.Time.Clock (UTCTime (..), getCurrentTime) import Database.SQLite.Simple (NamedParam (..), Only (..), Query (..), (:.) (..)) @@ -105,8 +120,8 @@ import Simplex.Messaging.Agent.Protocol (ConnId, UserId) import Simplex.Messaging.Agent.Store.SQLite (firstRow, maybeFirstRow) import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB import qualified Simplex.Messaging.Crypto as C -import Simplex.Messaging.Protocol (SubscriptionMode) -import Simplex.Messaging.Util (eitherToMaybe) +import Simplex.Messaging.Protocol (SubscriptionMode (..)) +import Simplex.Messaging.Util (eitherToMaybe, ($>>=), (<$$>)) import Simplex.Messaging.Version import UnliftIO.STM @@ -406,13 +421,12 @@ deleteGroupConnectionsAndFiles db User {userId} GroupInfo {groupId} members = do DB.execute db "DELETE FROM files WHERE user_id = ? AND group_id = ?" (userId, groupId) deleteGroupItemsAndMembers :: DB.Connection -> User -> GroupInfo -> [GroupMember] -> IO () -deleteGroupItemsAndMembers db user@User {userId} GroupInfo {groupId} members = do +deleteGroupItemsAndMembers db user@User {userId} g@GroupInfo {groupId} members = do DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ?" (userId, groupId) void $ runExceptT cleanupHostGroupLinkConn_ -- to allow repeat connection via the same group link if one was used DB.execute db "DELETE FROM group_members WHERE user_id = ? AND group_id = ?" (userId, groupId) - forM_ members $ \m@GroupMember {memberProfile = LocalProfile {profileId}} -> do - cleanupMemberProfileAndName_ db user m - when (memberIncognito m) $ deleteUnusedIncognitoProfileById_ db user profileId + forM_ members $ cleanupMemberProfileAndName_ db user + forM_ (incognitoMembershipProfile g) $ deleteUnusedIncognitoProfileById_ db user . localProfileId where cleanupHostGroupLinkConn_ = do hostId <- getHostMemberId_ db user groupId @@ -430,11 +444,11 @@ deleteGroupItemsAndMembers db user@User {userId} GroupInfo {groupId} members = d (userId, userId, hostId) deleteGroup :: DB.Connection -> User -> GroupInfo -> IO () -deleteGroup db user@User {userId} GroupInfo {groupId, localDisplayName, membership = membership@GroupMember {memberProfile = LocalProfile {profileId}}} = do +deleteGroup db user@User {userId} g@GroupInfo {groupId, localDisplayName} = do deleteGroupProfile_ db userId groupId DB.execute db "DELETE FROM groups WHERE user_id = ? AND group_id = ?" (userId, groupId) DB.execute db "DELETE FROM display_names WHERE user_id = ? AND local_display_name = ?" (userId, localDisplayName) - when (memberIncognito membership) $ deleteUnusedIncognitoProfileById_ db user profileId + forM_ (incognitoMembershipProfile g) $ deleteUnusedIncognitoProfileById_ db user . localProfileId deleteGroupProfile_ :: DB.Connection -> UserId -> GroupId -> IO () deleteGroupProfile_ db userId groupId = @@ -687,7 +701,7 @@ getContactViaMember db user@User {userId} GroupMember {groupMemberId} = SELECT -- Contact ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.send_rcpts, ct.favorite, - cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, + cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.contact_group_member_id, ct.contact_grp_inv_sent, -- Connection c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.auth_err_counter, @@ -801,12 +815,12 @@ checkGroupMemberHasItems db User {userId} GroupMember {groupMemberId, groupId} = maybeFirstRow fromOnly $ DB.query db "SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ? AND group_member_id = ? LIMIT 1" (userId, groupId, groupMemberId) deleteGroupMember :: DB.Connection -> User -> GroupMember -> IO () -deleteGroupMember db user@User {userId} m@GroupMember {groupMemberId, groupId, memberProfile = LocalProfile {profileId}} = do +deleteGroupMember db user@User {userId} m@GroupMember {groupMemberId, groupId, memberProfile} = do deleteGroupMemberConnection db user m DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ? AND group_member_id = ?" (userId, groupId, groupMemberId) DB.execute db "DELETE FROM group_members WHERE user_id = ? AND group_member_id = ?" (userId, groupMemberId) cleanupMemberProfileAndName_ db user m - when (memberIncognito m) $ deleteUnusedIncognitoProfileById_ db user profileId + when (memberIncognito m) $ deleteUnusedIncognitoProfileById_ db user $ localProfileId memberProfile cleanupMemberProfileAndName_ :: DB.Connection -> User -> GroupMember -> IO () cleanupMemberProfileAndName_ db User {userId} GroupMember {groupMemberId, memberContactId, memberContactProfileId, localDisplayName} = @@ -876,7 +890,7 @@ saveIntroInvitation db reMember toMember introInv = do WHERE group_member_intro_id = :intro_id |] [ ":intro_status" := GMIntroInvReceived, - ":group_queue_info" := groupConnReq (introInv :: IntroInvitation), + ":group_queue_info" := introInv.groupConnReq, ":direct_queue_info" := directConnReq introInv, ":updated_at" := currentTs, ":intro_id" := introId intro @@ -924,7 +938,7 @@ getIntroduction_ db reMember toMember = ExceptT $ do createIntroReMember :: DB.Connection -> User -> GroupInfo -> GroupMember -> MemberInfo -> (CommandId, ConnId) -> Maybe (CommandId, ConnId) -> Maybe ProfileId -> SubscriptionMode -> ExceptT StoreError IO GroupMember createIntroReMember db user@User {userId} gInfo@GroupInfo {groupId} _host@GroupMember {memberContactId, activeConn} memInfo@(MemberInfo _ _ memberChatVRange memberProfile) (groupCmdId, groupAgentConnId) directConnIds customUserProfileId subMode = do let mcvr = maybe chatInitialVRange fromChatVRange memberChatVRange - cLevel = 1 + maybe 0 (connLevel :: Connection -> Int) activeConn + cLevel = 1 + maybe 0 (\Connection {connLevel} -> connLevel) activeConn currentTs <- liftIO getCurrentTime newMember <- case directConnIds of Just (directCmdId, directAgentConnId) -> do @@ -943,7 +957,7 @@ createIntroReMember db user@User {userId} gInfo@GroupInfo {groupId} _host@GroupM createIntroToMemberContact :: DB.Connection -> User -> GroupMember -> GroupMember -> VersionRange -> (CommandId, ConnId) -> Maybe (CommandId, ConnId) -> Maybe ProfileId -> SubscriptionMode -> IO () createIntroToMemberContact db user@User {userId} GroupMember {memberContactId = viaContactId, activeConn} _to@GroupMember {groupMemberId, localDisplayName} mcvr (groupCmdId, groupAgentConnId) directConnIds customUserProfileId subMode = do - let cLevel = 1 + maybe 0 (connLevel :: Connection -> Int) activeConn + let cLevel = 1 + maybe 0 (\Connection {connLevel} -> connLevel) activeConn currentTs <- getCurrentTime Connection {connId = groupConnId} <- createMemberConnection_ db userId groupMemberId groupAgentConnId mcvr viaContactId cLevel currentTs subMode setCommandConnId db user groupCmdId groupConnId @@ -1031,7 +1045,7 @@ getViaGroupContact db user@User {userId} GroupMember {groupMemberId} = [sql| SELECT ct.contact_id, ct.contact_profile_id, ct.local_display_name, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, ct.via_group, ct.contact_used, ct.enable_ntfs, ct.send_rcpts, ct.favorite, - p.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, + p.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.contact_group_member_id, ct.contact_grp_inv_sent, c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.auth_err_counter, c.peer_chat_min_version, c.peer_chat_max_version @@ -1048,13 +1062,13 @@ getViaGroupContact db user@User {userId} GroupMember {groupMemberId} = |] (userId, groupMemberId) where - toContact' :: ((ContactId, ProfileId, ContactName, Text, Text, Maybe ImageData, Maybe ConnReqContact, LocalAlias, Maybe Int64, Bool) :. (Maybe Bool, Maybe Bool, Bool, Maybe Preferences, Preferences, UTCTime, UTCTime, Maybe UTCTime)) :. ConnectionRow -> Contact - toContact' (((contactId, profileId, localDisplayName, displayName, fullName, image, contactLink, localAlias, viaGroup, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs)) :. connRow) = + toContact' :: ((ContactId, ProfileId, ContactName, Text, Text, Maybe ImageData, Maybe ConnReqContact, LocalAlias, Maybe Int64, Bool) :. (Maybe Bool, Maybe Bool, Bool, Maybe Preferences, Preferences, UTCTime, UTCTime, Maybe UTCTime, Maybe GroupMemberId, Bool)) :. ConnectionRow -> Contact + toContact' (((contactId, profileId, localDisplayName, displayName, fullName, image, contactLink, localAlias, viaGroup, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent)) :. connRow) = let profile = LocalProfile {profileId, displayName, fullName, image, contactLink, preferences, localAlias} chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_, sendRcpts, favorite} activeConn = toConnection connRow mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito activeConn - in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs} + in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent} updateGroupProfile :: DB.Connection -> User -> GroupInfo -> GroupProfile -> ExceptT StoreError IO GroupInfo updateGroupProfile db User {userId} g@GroupInfo {groupId, localDisplayName, groupProfile = GroupProfile {displayName}} p'@GroupProfile {displayName = newName, fullName, description, image, groupPreferences} @@ -1121,112 +1135,160 @@ getGroupMemberIdByName db User {userId} groupId groupMemberName = ExceptT . firstRow fromOnly (SEGroupMemberNameNotFound groupId groupMemberName) $ DB.query db "SELECT group_member_id FROM group_members WHERE user_id = ? AND group_id = ? AND local_display_name = ?" (userId, groupId, groupMemberName) +getActiveMembersByName :: DB.Connection -> User -> ContactName -> ExceptT StoreError IO [(GroupInfo, GroupMember)] +getActiveMembersByName db user@User {userId} groupMemberName = do + groupMemberIds :: [(GroupId, GroupMemberId)] <- + liftIO $ + DB.query + db + [sql| + SELECT group_id, group_member_id + FROM group_members + WHERE user_id = ? AND local_display_name = ? + AND member_status IN (?,?) AND member_category != ? + |] + (userId, groupMemberName, GSMemConnected, GSMemComplete, GCUserMember) + possibleMembers <- forM groupMemberIds $ \(groupId, groupMemberId) -> do + groupInfo <- getGroupInfo db user groupId + groupMember <- getGroupMember db user groupId groupMemberId + pure (groupInfo, groupMember) + pure $ sortOn (Down . ts . fst) possibleMembers + where + ts GroupInfo {chatTs, updatedAt} = fromMaybe updatedAt chatTs + getMatchingContacts :: DB.Connection -> User -> Contact -> IO [Contact] getMatchingContacts db user@User {userId} Contact {contactId, profile = LocalProfile {displayName, fullName, image}} = do contactIds <- - map fromOnly - <$> DB.query - db - [sql| - SELECT ct.contact_id - FROM contacts ct - JOIN contact_profiles p ON ct.contact_profile_id = p.contact_profile_id - WHERE ct.user_id = ? AND ct.contact_id != ? - AND ct.deleted = 0 - AND p.display_name = ? AND p.full_name = ? - AND ((p.image IS NULL AND ? IS NULL) OR p.image = ?) - |] - (userId, contactId, displayName, fullName, image, image) + map fromOnly <$> case image of + Just img -> DB.query db (q <> " AND p.image = ?") (userId, contactId, displayName, fullName, img) + Nothing -> DB.query db (q <> " AND p.image is NULL") (userId, contactId, displayName, fullName) rights <$> mapM (runExceptT . getContact db user) contactIds + where + -- this query is different from one in getMatchingMemberContacts + -- it checks that it's not the same contact + q = + [sql| + SELECT ct.contact_id + FROM contacts ct + JOIN contact_profiles p ON ct.contact_profile_id = p.contact_profile_id + WHERE ct.user_id = ? AND ct.contact_id != ? + AND ct.deleted = 0 + AND p.display_name = ? AND p.full_name = ? + |] -createSentProbe :: DB.Connection -> TVar ChaChaDRG -> UserId -> Contact -> ExceptT StoreError IO (Probe, Int64) -createSentProbe db gVar userId _to@Contact {contactId} = +getMatchingMemberContacts :: DB.Connection -> User -> GroupMember -> IO [Contact] +getMatchingMemberContacts _ _ GroupMember {memberContactId = Just _} = pure [] +getMatchingMemberContacts db user@User {userId} GroupMember {memberProfile = LocalProfile {displayName, fullName, image}} = do + contactIds <- + map fromOnly <$> case image of + Just img -> DB.query db (q <> " AND p.image = ?") (userId, displayName, fullName, img) + Nothing -> DB.query db (q <> " AND p.image is NULL") (userId, displayName, fullName) + rights <$> mapM (runExceptT . getContact db user) contactIds + where + q = + [sql| + SELECT ct.contact_id + FROM contacts ct + JOIN contact_profiles p ON ct.contact_profile_id = p.contact_profile_id + WHERE ct.user_id = ? + AND ct.deleted = 0 + AND p.display_name = ? AND p.full_name = ? + |] + +createSentProbe :: DB.Connection -> TVar ChaChaDRG -> UserId -> ContactOrGroupMember -> ExceptT StoreError IO (Probe, Int64) +createSentProbe db gVar userId to = createWithRandomBytes 32 gVar $ \probe -> do currentTs <- getCurrentTime + let (ctId, gmId) = contactOrGroupMemberIds to DB.execute db - "INSERT INTO sent_probes (contact_id, probe, user_id, created_at, updated_at) VALUES (?,?,?,?,?)" - (contactId, probe, userId, currentTs, currentTs) - (Probe probe,) <$> insertedRowId db + "INSERT INTO sent_probes (contact_id, group_member_id, probe, user_id, created_at, updated_at) VALUES (?,?,?,?,?,?)" + (ctId, gmId, probe, userId, currentTs, currentTs) + (Probe probe,) <$> insertedRowId db -createSentProbeHash :: DB.Connection -> UserId -> Int64 -> Contact -> IO () -createSentProbeHash db userId probeId _to@Contact {contactId} = do +createSentProbeHash :: DB.Connection -> UserId -> Int64 -> ContactOrGroupMember -> IO () +createSentProbeHash db userId probeId to = do currentTs <- getCurrentTime + let (ctId, gmId) = contactOrGroupMemberIds to DB.execute db - "INSERT INTO sent_probe_hashes (sent_probe_id, contact_id, user_id, created_at, updated_at) VALUES (?,?,?,?,?)" - (probeId, contactId, userId, currentTs, currentTs) + "INSERT INTO sent_probe_hashes (sent_probe_id, contact_id, group_member_id, user_id, created_at, updated_at) VALUES (?,?,?,?,?,?)" + (probeId, ctId, gmId, userId, currentTs, currentTs) -deleteSentProbe :: DB.Connection -> UserId -> Int64 -> IO () -deleteSentProbe db userId probeId = - DB.execute - db - "DELETE FROM sent_probes WHERE user_id = ? AND sent_probe_id = ?" - (userId, probeId) - -matchReceivedProbe :: DB.Connection -> User -> Contact -> Probe -> IO (Maybe Contact) -matchReceivedProbe db user@User {userId} _from@Contact {contactId} (Probe probe) = do +matchReceivedProbe :: DB.Connection -> User -> ContactOrGroupMember -> Probe -> IO (Maybe ContactOrGroupMember) +matchReceivedProbe db user@User {userId} from (Probe probe) = do let probeHash = C.sha256Hash probe - contactIds <- - map fromOnly - <$> DB.query + cgmIds <- + maybeFirstRow id $ + DB.query db [sql| - SELECT c.contact_id - FROM contacts c - JOIN received_probes r ON r.contact_id = c.contact_id - WHERE c.user_id = ? AND c.deleted = 0 AND r.probe_hash = ? AND r.probe IS NULL + SELECT r.contact_id, g.group_id, r.group_member_id + FROM received_probes r + LEFT JOIN contacts c ON r.contact_id = c.contact_id AND c.deleted = 0 + LEFT JOIN group_members m ON r.group_member_id = m.group_member_id + LEFT JOIN groups g ON g.group_id = m.group_id + WHERE r.user_id = ? AND r.probe_hash = ? AND r.probe IS NULL |] (userId, probeHash) currentTs <- getCurrentTime + let (ctId, gmId) = contactOrGroupMemberIds from DB.execute db - "INSERT INTO received_probes (contact_id, probe, probe_hash, user_id, created_at, updated_at) VALUES (?,?,?,?,?,?)" - (contactId, probe, probeHash, userId, currentTs, currentTs) - case contactIds of - [] -> pure Nothing - cId : _ -> eitherToMaybe <$> runExceptT (getContact db user cId) + "INSERT INTO received_probes (contact_id, group_member_id, probe, probe_hash, user_id, created_at, updated_at) VALUES (?,?,?,?,?,?,?)" + (ctId, gmId, probe, probeHash, userId, currentTs, currentTs) + pure cgmIds $>>= getContactOrGroupMember_ db user -matchReceivedProbeHash :: DB.Connection -> User -> Contact -> ProbeHash -> IO (Maybe (Contact, Probe)) -matchReceivedProbeHash db user@User {userId} _from@Contact {contactId} (ProbeHash probeHash) = do - namesAndProbes <- - DB.query - db - [sql| - SELECT c.contact_id, r.probe - FROM contacts c - JOIN received_probes r ON r.contact_id = c.contact_id - WHERE c.user_id = ? AND c.deleted = 0 AND r.probe_hash = ? AND r.probe IS NOT NULL - |] - (userId, probeHash) - currentTs <- getCurrentTime - DB.execute - db - "INSERT INTO received_probes (contact_id, probe_hash, user_id, created_at, updated_at) VALUES (?,?,?,?,?)" - (contactId, probeHash, userId, currentTs, currentTs) - case namesAndProbes of - [] -> pure Nothing - (cId, probe) : _ -> - either (const Nothing) (Just . (,Probe probe)) - <$> runExceptT (getContact db user cId) - -matchSentProbe :: DB.Connection -> User -> Contact -> Probe -> IO (Maybe Contact) -matchSentProbe db user@User {userId} _from@Contact {contactId} (Probe probe) = do - contactIds <- - map fromOnly - <$> DB.query +matchReceivedProbeHash :: DB.Connection -> User -> ContactOrGroupMember -> ProbeHash -> IO (Maybe (ContactOrGroupMember, Probe)) +matchReceivedProbeHash db user@User {userId} from (ProbeHash probeHash) = do + probeIds <- + maybeFirstRow id $ + DB.query db [sql| - SELECT c.contact_id - FROM contacts c - JOIN sent_probes s ON s.contact_id = c.contact_id - JOIN sent_probe_hashes h ON h.sent_probe_id = s.sent_probe_id - WHERE c.user_id = ? AND c.deleted = 0 AND s.probe = ? AND h.contact_id = ? + SELECT r.probe, r.contact_id, g.group_id, r.group_member_id + FROM received_probes r + LEFT JOIN contacts c ON r.contact_id = c.contact_id AND c.deleted = 0 + LEFT JOIN group_members m ON r.group_member_id = m.group_member_id + LEFT JOIN groups g ON g.group_id = m.group_id + WHERE r.user_id = ? AND r.probe_hash = ? AND r.probe IS NOT NULL |] - (userId, probe, contactId) - case contactIds of - [] -> pure Nothing - cId : _ -> eitherToMaybe <$> runExceptT (getContact db user cId) + (userId, probeHash) + currentTs <- getCurrentTime + let (ctId, gmId) = contactOrGroupMemberIds from + DB.execute + db + "INSERT INTO received_probes (contact_id, group_member_id, probe_hash, user_id, created_at, updated_at) VALUES (?,?,?,?,?,?)" + (ctId, gmId, probeHash, userId, currentTs, currentTs) + pure probeIds $>>= \(Only probe :. cgmIds) -> (,Probe probe) <$$> getContactOrGroupMember_ db user cgmIds + +matchSentProbe :: DB.Connection -> User -> ContactOrGroupMember -> Probe -> IO (Maybe ContactOrGroupMember) +matchSentProbe db user@User {userId} _from (Probe probe) = + cgmIds $>>= getContactOrGroupMember_ db user + where + (ctId, gmId) = contactOrGroupMemberIds _from + cgmIds = + maybeFirstRow id $ + DB.query + db + [sql| + SELECT s.contact_id, g.group_id, s.group_member_id + FROM sent_probes s + LEFT JOIN contacts c ON s.contact_id = c.contact_id AND c.deleted = 0 + LEFT JOIN group_members m ON s.group_member_id = m.group_member_id + LEFT JOIN groups g ON g.group_id = m.group_id + JOIN sent_probe_hashes h ON h.sent_probe_id = s.sent_probe_id + WHERE s.user_id = ? AND s.probe = ? + AND (h.contact_id = ? OR h.group_member_id = ?) + |] + (userId, probe, ctId, gmId) + +getContactOrGroupMember_ :: DB.Connection -> User -> (Maybe ContactId, Maybe GroupId, Maybe GroupMemberId) -> IO (Maybe ContactOrGroupMember) +getContactOrGroupMember_ db user ids = + fmap eitherToMaybe . runExceptT $ case ids of + (Just ctId, _, _) -> CGMContact <$> getContact db user ctId + (_, Just gId, Just gmId) -> CGMGroupMember <$> getGroupInfo db user gId <*> getGroupMember db user gId gmId + _ -> throwError $ SEInternalError "" mergeContactRecords :: DB.Connection -> UserId -> Contact -> Contact -> IO () mergeContactRecords db userId ct1 ct2 = do @@ -1274,7 +1336,7 @@ mergeContactRecords db userId ct1 ct2 = do ] deleteContactProfile_ db userId fromContactId DB.execute db "DELETE FROM contacts WHERE contact_id = ? AND user_id = ?" (fromContactId, userId) - DB.execute db "DELETE FROM display_names WHERE local_display_name = ? AND user_id = ?" (localDisplayName, userId) + deleteUnusedDisplayName_ db userId localDisplayName where toFromContacts :: Contact -> Contact -> (Contact, Contact) toFromContacts c1 c2 @@ -1287,6 +1349,64 @@ mergeContactRecords db userId ct1 ct2 = do d2 = directOrUsed c2 ctCreatedAt Contact {createdAt} = createdAt +updateMemberContact :: DB.Connection -> User -> Contact -> GroupMember -> IO () +updateMemberContact + db + User {userId} + Contact {contactId, localDisplayName, profile = LocalProfile {profileId}} + GroupMember {groupId, groupMemberId, localDisplayName = memLDN, memberProfile = LocalProfile {profileId = memProfileId}} = do + -- TODO possibly, we should update profiles and local_display_names of all members linked to the same remote user, + -- once we decide on how we identify it, either based on shared contact_profile_id or on local_display_name + currentTs <- getCurrentTime + DB.execute + db + [sql| + UPDATE group_members + SET contact_id = ?, local_display_name = ?, contact_profile_id = ?, updated_at = ? + WHERE user_id = ? AND group_id = ? AND group_member_id = ? + |] + (contactId, localDisplayName, profileId, currentTs, userId, groupId, groupMemberId) + when (memProfileId /= profileId) $ deleteUnusedProfile_ db userId memProfileId + when (memLDN /= localDisplayName) $ deleteUnusedDisplayName_ db userId memLDN + +deleteUnusedDisplayName_ :: DB.Connection -> UserId -> ContactName -> IO () +deleteUnusedDisplayName_ db userId localDisplayName = + DB.executeNamed + db + [sql| + DELETE FROM display_names + WHERE user_id = :user_id AND local_display_name = :local_display_name + AND 1 NOT IN ( + SELECT 1 FROM users + WHERE local_display_name = :local_display_name LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM contacts + WHERE user_id = :user_id AND local_display_name = :local_display_name LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM groups + WHERE user_id = :user_id AND local_display_name = :local_display_name LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM group_members + WHERE user_id = :user_id AND local_display_name = :local_display_name LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM user_contact_links + WHERE user_id = :user_id AND local_display_name = :local_display_name LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM contact_requests + WHERE user_id = :user_id AND local_display_name = :local_display_name LIMIT 1 + ) + AND 1 NOT IN ( + SELECT 1 FROM contact_requests + WHERE user_id = :user_id AND local_display_name = :local_display_name LIMIT 1 + ) + |] + [":user_id" := userId, ":local_display_name" := localDisplayName] + updateGroupSettings :: DB.Connection -> User -> Int64 -> ChatSettings -> IO () updateGroupSettings db User {userId} groupId ChatSettings {enableNtfs, sendRcpts, favorite} = DB.execute db "UPDATE groups SET enable_ntfs = ?, send_rcpts = ?, favorite = ? WHERE user_id = ? AND group_id = ?" (enableNtfs, sendRcpts, favorite, userId, groupId) @@ -1356,3 +1476,154 @@ getHostConnId db user@User {userId} groupId = do hostMemberId <- getHostMemberId_ db user groupId ExceptT . firstRow fromOnly (SEConnectionNotFoundByMemberId hostMemberId) $ DB.query db "SELECT connection_id FROM connections WHERE user_id = ? AND group_member_id = ?" (userId, hostMemberId) + +createMemberContact :: DB.Connection -> User -> ConnId -> ConnReqInvitation -> GroupInfo -> GroupMember -> Connection -> SubscriptionMode -> IO Contact +createMemberContact + db + user@User {userId, profile = LocalProfile {preferences}} + acId + cReq + gInfo + GroupMember {groupMemberId, localDisplayName, memberProfile, memberContactProfileId} + Connection {connLevel, peerChatVRange = peerChatVRange@(JVersionRange (VersionRange minV maxV))} + subMode = do + currentTs <- getCurrentTime + let incognitoProfile = incognitoMembershipProfile gInfo + customUserProfileId = localProfileId <$> incognitoProfile + userPreferences = fromMaybe emptyChatPrefs $ incognitoProfile >> preferences + DB.execute + db + [sql| + INSERT INTO contacts ( + user_id, local_display_name, contact_profile_id, enable_ntfs, user_preferences, contact_used, + contact_group_member_id, contact_grp_inv_sent, created_at, updated_at, chat_ts + ) VALUES (?,?,?,?,?,?,?,?,?,?,?) + |] + ( (userId, localDisplayName, memberContactProfileId, True, userPreferences, True) + :. (groupMemberId, False, currentTs, currentTs, currentTs) + ) + contactId <- insertedRowId db + DB.execute + db + "UPDATE group_members SET contact_id = ?, updated_at = ? WHERE group_member_id = ?" + (contactId, currentTs, groupMemberId) + DB.execute + db + [sql| + INSERT INTO connections ( + user_id, agent_conn_id, conn_req_inv, conn_level, conn_status, conn_type, contact_id, custom_user_profile_id, + peer_chat_min_version, peer_chat_max_version, created_at, updated_at, to_subscribe + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?) + |] + ( (userId, acId, cReq, connLevel, ConnNew, ConnContact, contactId, customUserProfileId) + :. (minV, maxV, currentTs, currentTs, subMode == SMOnlyCreate) + ) + connId <- insertedRowId db + let ctConn = Connection {connId, agentConnId = AgentConnId acId, peerChatVRange, connType = ConnContact, entityId = Just contactId, viaContact = Nothing, viaUserContactLink = Nothing, viaGroupLink = False, groupLinkId = Nothing, customUserProfileId, connLevel, connStatus = ConnNew, localAlias = "", createdAt = currentTs, connectionCode = Nothing, authErrCounter = 0} + mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito ctConn + pure Contact {contactId, localDisplayName, profile = memberProfile, activeConn = ctConn, viaGroup = Nothing, contactUsed = True, chatSettings = defaultChatSettings, userPreferences, mergedPreferences, createdAt = currentTs, updatedAt = currentTs, chatTs = Just currentTs, contactGroupMemberId = Just groupMemberId, contactGrpInvSent = False} + +getMemberContact :: DB.Connection -> User -> ContactId -> ExceptT StoreError IO (GroupInfo, GroupMember, Contact, ConnReqInvitation) +getMemberContact db user contactId = do + ct <- getContact db user contactId + let Contact {contactGroupMemberId, activeConn = Connection {connId}} = ct + cReq <- getConnReqInv db connId + case contactGroupMemberId of + Just groupMemberId -> do + m@GroupMember {groupId} <- getGroupMemberById db user groupMemberId + g <- getGroupInfo db user groupId + pure (g, m, ct, cReq) + _ -> + throwError $ SEMemberContactGroupMemberNotFound contactId + +setContactGrpInvSent :: DB.Connection -> Contact -> Bool -> IO () +setContactGrpInvSent db Contact {contactId} xGrpDirectInvSent = do + currentTs <- getCurrentTime + DB.execute + db + "UPDATE contacts SET contact_grp_inv_sent = ?, updated_at = ? WHERE contact_id = ?" + (xGrpDirectInvSent, currentTs, contactId) + +createMemberContactInvited :: DB.Connection -> User -> (CommandId, ConnId) -> GroupInfo -> GroupMember -> Connection -> SubscriptionMode -> IO (Contact, GroupMember) +createMemberContactInvited + db + user@User {userId, profile = LocalProfile {preferences}} + connIds + gInfo + m@GroupMember {groupMemberId, localDisplayName = memberLDN, memberProfile, memberContactProfileId} + mConn + subMode = do + currentTs <- liftIO getCurrentTime + let userPreferences = fromMaybe emptyChatPrefs $ incognitoMembershipProfile gInfo >> preferences + contactId <- createContactUpdateMember currentTs userPreferences + ctConn <- createMemberContactConn_ db user connIds gInfo mConn contactId subMode + let mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito ctConn + mCt' = Contact {contactId, localDisplayName = memberLDN, profile = memberProfile, activeConn = ctConn, viaGroup = Nothing, contactUsed = True, chatSettings = defaultChatSettings, userPreferences, mergedPreferences, createdAt = currentTs, updatedAt = currentTs, chatTs = Just currentTs, contactGroupMemberId = Just groupMemberId, contactGrpInvSent = False} + m' = m {memberContactId = Just contactId} + pure (mCt', m') + where + createContactUpdateMember :: UTCTime -> Preferences -> IO ContactId + createContactUpdateMember currentTs userPreferences = do + DB.execute + db + [sql| + INSERT INTO contacts ( + user_id, local_display_name, contact_profile_id, enable_ntfs, user_preferences, contact_used, + created_at, updated_at, chat_ts + ) VALUES (?,?,?,?,?,?,?,?,?) + |] + ( (userId, memberLDN, memberContactProfileId, True, userPreferences, True) + :. (currentTs, currentTs, currentTs) + ) + contactId <- insertedRowId db + DB.execute + db + "UPDATE group_members SET contact_id = ?, updated_at = ? WHERE group_member_id = ?" + (contactId, currentTs, groupMemberId) + pure contactId + +updateMemberContactInvited :: DB.Connection -> User -> (CommandId, ConnId) -> GroupInfo -> Connection -> Contact -> SubscriptionMode -> IO Contact +updateMemberContactInvited db user connIds gInfo mConn ct@Contact {contactId, activeConn = oldContactConn} subMode = do + updateConnectionStatus db oldContactConn ConnDeleted + activeConn <- createMemberContactConn_ db user connIds gInfo mConn contactId subMode + ct' <- resetMemberContactFields db ct + pure (ct' :: Contact) {activeConn} + +resetMemberContactFields :: DB.Connection -> Contact -> IO Contact +resetMemberContactFields db ct@Contact {contactId} = do + currentTs <- liftIO getCurrentTime + DB.execute + db + [sql| + UPDATE contacts + SET contact_group_member_id = NULL, contact_grp_inv_sent = 0, updated_at = ? + WHERE contact_id = ? + |] + (currentTs, contactId) + pure ct {contactGroupMemberId = Nothing, contactGrpInvSent = False, updatedAt = currentTs} + +createMemberContactConn_ :: DB.Connection -> User -> (CommandId, ConnId) -> GroupInfo -> Connection -> ContactId -> SubscriptionMode -> IO Connection +createMemberContactConn_ + db + user@User {userId} + (cmdId, acId) + gInfo + _memberConn@Connection {connLevel, peerChatVRange = peerChatVRange@(JVersionRange (VersionRange minV maxV))} + contactId + subMode = do + currentTs <- liftIO getCurrentTime + let customUserProfileId = localProfileId <$> incognitoMembershipProfile gInfo + DB.execute + db + [sql| + INSERT INTO connections ( + user_id, agent_conn_id, conn_level, conn_status, conn_type, contact_id, custom_user_profile_id, + peer_chat_min_version, peer_chat_max_version, created_at, updated_at, to_subscribe + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?) + |] + ( (userId, acId, connLevel, ConnNew, ConnContact, contactId, customUserProfileId) + :. (minV, maxV, currentTs, currentTs, subMode == SMOnlyCreate) + ) + connId <- insertedRowId db + setCommandConnId db user cmdId connId + pure Connection {connId, agentConnId = AgentConnId acId, peerChatVRange, connType = ConnContact, entityId = Just contactId, viaContact = Nothing, viaUserContactLink = Nothing, viaGroupLink = False, groupLinkId = Nothing, customUserProfileId, connLevel, connStatus = ConnNew, localAlias = "", createdAt = currentTs, connectionCode = Nothing, authErrCounter = 0} diff --git a/src/Simplex/Chat/Store/Messages.hs b/src/Simplex/Chat/Store/Messages.hs index ddd59319d5..c08e6b11d3 100644 --- a/src/Simplex/Chat/Store/Messages.hs +++ b/src/Simplex/Chat/Store/Messages.hs @@ -10,6 +10,8 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module Simplex.Chat.Store.Messages ( getContactConnIds_, getDirectChatReactions_, @@ -96,7 +98,9 @@ module Simplex.Chat.Store.Messages ) where +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import Crypto.Random (ChaChaDRG) import Data.Bifunctor (first) import Data.ByteString.Char8 (ByteString) @@ -475,7 +479,7 @@ getDirectChatPreviews_ db user@User {userId} = do SELECT -- Contact ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.send_rcpts, ct.favorite, - cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, + cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.contact_group_member_id, ct.contact_grp_inv_sent, -- Connection c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.auth_err_counter, diff --git a/src/Simplex/Chat/Store/Migrations.hs b/src/Simplex/Chat/Store/Migrations.hs index cbcc4ddd28..d8bab817e3 100644 --- a/src/Simplex/Chat/Store/Migrations.hs +++ b/src/Simplex/Chat/Store/Migrations.hs @@ -79,6 +79,8 @@ import Simplex.Chat.Migrations.M20230814_indexes import Simplex.Chat.Migrations.M20230827_file_encryption import Simplex.Chat.Migrations.M20230829_connections_chat_vrange import Simplex.Chat.Migrations.M20230903_connections_to_subscribe +import Simplex.Chat.Migrations.M20230913_member_contacts +import Simplex.Chat.Migrations.M20230914_member_probes import Simplex.Messaging.Agent.Store.SQLite.Migrations (Migration (..)) schemaMigrations :: [(String, Query, Maybe Query)] @@ -157,7 +159,9 @@ schemaMigrations = ("20230814_indexes", m20230814_indexes, Just down_m20230814_indexes), ("20230827_file_encryption", m20230827_file_encryption, Just down_m20230827_file_encryption), ("20230829_connections_chat_vrange", m20230829_connections_chat_vrange, Just down_m20230829_connections_chat_vrange), - ("20230903_connections_to_subscribe", m20230903_connections_to_subscribe, Just down_m20230903_connections_to_subscribe) + ("20230903_connections_to_subscribe", m20230903_connections_to_subscribe, Just down_m20230903_connections_to_subscribe), + ("20230913_member_contacts", m20230913_member_contacts, Just down_m20230913_member_contacts), + ("20230914_member_probes", m20230914_member_probes, Just down_m20230914_member_probes) ] -- | The list of migrations in ascending order by date diff --git a/src/Simplex/Chat/Store/Profiles.hs b/src/Simplex/Chat/Store/Profiles.hs index 7f3c9841c0..e521cb43cf 100644 --- a/src/Simplex/Chat/Store/Profiles.hs +++ b/src/Simplex/Chat/Store/Profiles.hs @@ -7,6 +7,8 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module Simplex.Chat.Store.Profiles ( AutoAccept (..), UserMsgReceiptSettings (..), @@ -54,7 +56,9 @@ module Simplex.Chat.Store.Profiles ) where +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import Data.Aeson (ToJSON) import qualified Data.Aeson as J import Data.Functor (($>)) @@ -290,7 +294,7 @@ getUserContactProfiles db User {userId} = |] (Only userId) where - toContactProfile :: (ContactName, Text, Maybe ImageData, Maybe ConnReqContact, Maybe Preferences) -> (Profile) + toContactProfile :: (ContactName, Text, Maybe ImageData, Maybe ConnReqContact, Maybe Preferences) -> Profile toContactProfile (displayName, fullName, image, contactLink, preferences) = Profile {displayName, fullName, image, contactLink, preferences} createUserContactLink :: DB.Connection -> User -> ConnId -> ConnReqContact -> SubscriptionMode -> ExceptT StoreError IO () diff --git a/src/Simplex/Chat/Store/Shared.hs b/src/Simplex/Chat/Store/Shared.hs index 0906159bb9..e979c90067 100644 --- a/src/Simplex/Chat/Store/Shared.hs +++ b/src/Simplex/Chat/Store/Shared.hs @@ -10,10 +10,11 @@ module Simplex.Chat.Store.Shared where -import Control.Concurrent.STM (stateTVar) import Control.Exception (Exception) import qualified Control.Exception as E +import Control.Monad import Control.Monad.Except +import Control.Monad.IO.Class import Crypto.Random (ChaChaDRG, randomBytesGenerate) import Data.Aeson (ToJSON) import qualified Data.Aeson as J @@ -63,6 +64,7 @@ data StoreError | SEGroupMemberNameNotFound {groupId :: GroupId, groupMemberName :: ContactName} | SEGroupMemberNotFound {groupMemberId :: GroupMemberId} | SEGroupMemberNotFoundByMemberId {memberId :: MemberId} + | SEMemberContactGroupMemberNotFound {contactId :: ContactId} | SEGroupWithoutUser | SEDuplicateGroupMember | SEGroupAlreadyJoined @@ -239,24 +241,24 @@ deleteUnusedIncognitoProfileById_ db User {userId} profileId = |] [":user_id" := userId, ":profile_id" := profileId] -type ContactRow = (ContactId, ProfileId, ContactName, Maybe Int64, ContactName, Text, Maybe ImageData, Maybe ConnReqContact, LocalAlias, Bool) :. (Maybe Bool, Maybe Bool, Bool, Maybe Preferences, Preferences, UTCTime, UTCTime, Maybe UTCTime) +type ContactRow = (ContactId, ProfileId, ContactName, Maybe Int64, ContactName, Text, Maybe ImageData, Maybe ConnReqContact, LocalAlias, Bool) :. (Maybe Bool, Maybe Bool, Bool, Maybe Preferences, Preferences, UTCTime, UTCTime, Maybe UTCTime, Maybe GroupMemberId, Bool) toContact :: User -> ContactRow :. ConnectionRow -> Contact -toContact user (((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, contactLink, localAlias, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs)) :. connRow) = +toContact user (((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, contactLink, localAlias, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent)) :. connRow) = let profile = LocalProfile {profileId, displayName, fullName, image, contactLink, preferences, localAlias} activeConn = toConnection connRow chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_, sendRcpts, favorite} mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito activeConn - in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs} + in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent} toContactOrError :: User -> ContactRow :. MaybeConnectionRow -> Either StoreError Contact -toContactOrError user (((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, contactLink, localAlias, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs)) :. connRow) = +toContactOrError user (((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, contactLink, localAlias, contactUsed) :. (enableNtfs_, sendRcpts, favorite, preferences, userPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent)) :. connRow) = let profile = LocalProfile {profileId, displayName, fullName, image, contactLink, preferences, localAlias} chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_, sendRcpts, favorite} in case toMaybeConnection connRow of Just activeConn -> let mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito activeConn - in Right Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs} + in Right Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, userPreferences, mergedPreferences, createdAt, updatedAt, chatTs, contactGroupMemberId, contactGrpInvSent} _ -> Left $ SEContactNotReady localDisplayName getProfileById :: DB.Connection -> UserId -> Int64 -> ExceptT StoreError IO LocalProfile @@ -304,6 +306,14 @@ toPendingContactConnection :: (Int64, ConnId, ConnStatus, Maybe ByteString, Mayb toPendingContactConnection (pccConnId, acId, pccConnStatus, connReqHash, viaUserContactLink, groupLinkId, customUserProfileId, connReqInv, localAlias, createdAt, updatedAt) = PendingContactConnection {pccConnId, pccAgentConnId = AgentConnId acId, pccConnStatus, viaContactUri = isJust connReqHash, viaUserContactLink, groupLinkId, customUserProfileId, connReqInv, localAlias, createdAt, updatedAt} +getConnReqInv :: DB.Connection -> Int64 -> ExceptT StoreError IO ConnReqInvitation +getConnReqInv db connId = + ExceptT . firstRow fromOnly (SEConnectionNotFoundById connId) $ + DB.query + db + "SELECT conn_req_inv FROM connections WHERE connection_id = ?" + (Only connId) + -- | Saves unique local display name based on passed displayName, suffixed with _N if required. -- This function should be called inside transaction. withLocalDisplayName :: forall a. DB.Connection -> UserId -> Text -> (Text -> IO (Either StoreError a)) -> IO (Either StoreError a) diff --git a/src/Simplex/Chat/Terminal.hs b/src/Simplex/Chat/Terminal.hs index 6a148e8778..0ef3d3bace 100644 --- a/src/Simplex/Chat/Terminal.hs +++ b/src/Simplex/Chat/Terminal.hs @@ -5,7 +5,7 @@ module Simplex.Chat.Terminal where import Control.Exception (handle, throwIO) -import Control.Monad.Except +import Control.Monad import qualified Data.List.NonEmpty as L import Database.SQLite.Simple (SQLError (..)) import qualified Database.SQLite.Simple as DB diff --git a/src/Simplex/Chat/Terminal/Input.hs b/src/Simplex/Chat/Terminal/Input.hs index 36cec49d7c..8841f15ffd 100644 --- a/src/Simplex/Chat/Terminal/Input.hs +++ b/src/Simplex/Chat/Terminal/Input.hs @@ -12,6 +12,7 @@ module Simplex.Chat.Terminal.Input where import Control.Applicative (optional, (<|>)) import Control.Concurrent (forkFinally, forkIO, killThread, mkWeakThreadId, threadDelay) +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import qualified Data.Attoparsec.ByteString.Char8 as A diff --git a/src/Simplex/Chat/Terminal/Output.hs b/src/Simplex/Chat/Terminal/Output.hs index ce68d715fe..db6f16f3ca 100644 --- a/src/Simplex/Chat/Terminal/Output.hs +++ b/src/Simplex/Chat/Terminal/Output.hs @@ -9,6 +9,7 @@ module Simplex.Chat.Terminal.Output where import Control.Concurrent (ThreadId) +import Control.Monad import Control.Monad.Catch (MonadMask) import Control.Monad.Except import Control.Monad.Reader diff --git a/src/Simplex/Chat/Types.hs b/src/Simplex/Chat/Types.hs index 319142c08c..ecae9eb09b 100644 --- a/src/Simplex/Chat/Types.hs +++ b/src/Simplex/Chat/Types.hs @@ -16,6 +16,8 @@ {-# LANGUAGE StrictData #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE OverloadedRecordDot #-} + {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Use newtype instead of data" #-} @@ -56,21 +58,21 @@ class IsContact a where preferences' :: a -> Maybe Preferences instance IsContact User where - contactId' = userContactId + contactId' u = u.userContactId {-# INLINE contactId' #-} - profile' = profile + profile' u = u.profile {-# INLINE profile' #-} - localDisplayName' = localDisplayName + localDisplayName' u = u.localDisplayName {-# INLINE localDisplayName' #-} preferences' User {profile = LocalProfile {preferences}} = preferences {-# INLINE preferences' #-} instance IsContact Contact where - contactId' = contactId + contactId' c = c.contactId {-# INLINE contactId' #-} - profile' = profile + profile' c = c.profile {-# INLINE profile' #-} - localDisplayName' = localDisplayName + localDisplayName' c = c.localDisplayName {-# INLINE localDisplayName' #-} preferences' Contact {profile = LocalProfile {preferences}} = preferences {-# INLINE preferences' #-} @@ -172,7 +174,9 @@ data Contact = Contact mergedPreferences :: ContactUserPreferences, createdAt :: UTCTime, updatedAt :: UTCTime, - chatTs :: Maybe UTCTime + chatTs :: Maybe UTCTime, + contactGroupMemberId :: Maybe GroupMemberId, + contactGrpInvSent :: Bool } deriving (Eq, Show, Generic) @@ -181,7 +185,7 @@ instance ToJSON Contact where toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True} contactConn :: Contact -> Connection -contactConn = activeConn +contactConn Contact{activeConn} = activeConn contactConnId :: Contact -> ConnId contactConnId = aConnId . contactConn @@ -214,6 +218,19 @@ data ContactRef = ContactRef instance ToJSON ContactRef where toEncoding = J.genericToEncoding J.defaultOptions +data ContactOrGroupMember = CGMContact Contact | CGMGroupMember GroupInfo GroupMember + deriving (Show) + +contactOrGroupMemberIds :: ContactOrGroupMember -> (Maybe ContactId, Maybe GroupMemberId) +contactOrGroupMemberIds = \case + CGMContact Contact {contactId} -> (Just contactId, Nothing) + CGMGroupMember _ GroupMember {groupMemberId} -> (Nothing, Just groupMemberId) + +contactOrGroupMemberIncognito :: ContactOrGroupMember -> IncognitoEnabled +contactOrGroupMemberIncognito = \case + CGMContact ct -> contactConnIncognito ct + CGMGroupMember _ m -> memberIncognito m + data UserContact = UserContact { userContactLinkId :: Int64, connReqContact :: ConnReqContact, @@ -425,10 +442,10 @@ instance ToJSON Profile where toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True} -- check if profiles match ignoring preferences -profilesMatch :: Profile -> Profile -> Bool +profilesMatch :: LocalProfile -> LocalProfile -> Bool profilesMatch - Profile {displayName = n1, fullName = fn1, image = i1} - Profile {displayName = n2, fullName = fn2, image = i2} = + LocalProfile {displayName = n1, fullName = fn1, image = i1} + LocalProfile {displayName = n2, fullName = fn2, image = i2} = n1 == n2 && fn1 == fn2 && i1 == i2 data IncognitoProfile = NewIncognito Profile | ExistingIncognito LocalProfile @@ -451,7 +468,7 @@ instance ToJSON LocalProfile where toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True} localProfileId :: LocalProfile -> ProfileId -localProfileId = profileId +localProfileId LocalProfile{profileId} = profileId toLocalProfile :: ProfileId -> Profile -> LocalAlias -> LocalProfile toLocalProfile profileId Profile {displayName, fullName, image, contactLink, preferences} localAlias = @@ -586,8 +603,13 @@ data GroupMember = GroupMember memberStatus :: GroupMemberStatus, invitedBy :: InvitedBy, localDisplayName :: ContactName, + -- for membership, memberProfile can be either user's profile or incognito profile, based on memberIncognito test. + -- for other members it's whatever profile the local user can see (there is no info about whether it's main or incognito profile for remote users). memberProfile :: LocalProfile, + -- this is the ID of the associated contact (it will be used to send direct messages to the member) memberContactId :: Maybe ContactId, + -- for membership it would always point to user's contact + -- it is used to test for incognito status by comparing with ID in memberProfile memberContactProfileId :: ProfileId, activeConn :: Maybe Connection } @@ -607,7 +629,7 @@ groupMemberRef GroupMember {groupMemberId, memberProfile = p} = GroupMemberRef {groupMemberId, profile = fromLocalProfile p} memberConn :: GroupMember -> Maybe Connection -memberConn = activeConn +memberConn GroupMember{activeConn} = activeConn memberConnId :: GroupMember -> Maybe ConnId memberConnId GroupMember {activeConn} = aConnId <$> activeConn @@ -618,6 +640,15 @@ groupMemberId' GroupMember {groupMemberId} = groupMemberId memberIncognito :: GroupMember -> IncognitoEnabled memberIncognito GroupMember {memberProfile, memberContactProfileId} = localProfileId memberProfile /= memberContactProfileId +incognitoMembership :: GroupInfo -> IncognitoEnabled +incognitoMembership GroupInfo {membership} = memberIncognito membership + +-- returns profile when membership is incognito, otherwise Nothing +incognitoMembershipProfile :: GroupInfo -> Maybe LocalProfile +incognitoMembershipProfile GroupInfo {membership = m@GroupMember {memberProfile}} + | memberIncognito m = Just memberProfile + | otherwise = Nothing + memberSecurityCode :: GroupMember -> Maybe SecurityCode memberSecurityCode GroupMember {activeConn} = connectionCode =<< activeConn @@ -955,7 +986,10 @@ data RcvFileTransfer = RcvFileTransfer senderDisplayName :: ContactName, chunkSize :: Integer, cancelled :: Bool, - grpMemberId :: Maybe Int64 + grpMemberId :: Maybe Int64, + -- XFTP files are encrypted as they are received, they are never stored unecrypted + -- SMP files are encrypted after all chunks are received + cryptoArgs :: Maybe CryptoFileArgs } deriving (Eq, Show, Generic) @@ -964,8 +998,7 @@ instance ToJSON RcvFileTransfer where toEncoding = J.genericToEncoding J.default data XFTPRcvFile = XFTPRcvFile { rcvFileDescription :: RcvFileDescr, agentRcvFileId :: Maybe AgentRcvFileId, - agentRcvFileDeleted :: Bool, - cryptoArgs :: Maybe CryptoFileArgs + agentRcvFileDeleted :: Bool } deriving (Eq, Show, Generic) diff --git a/src/Simplex/Chat/Types/Preferences.hs b/src/Simplex/Chat/Types/Preferences.hs index a89e383242..c53e4476f4 100644 --- a/src/Simplex/Chat/Types/Preferences.hs +++ b/src/Simplex/Chat/Types/Preferences.hs @@ -8,12 +8,15 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilyDependencies #-} + {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} {-# HLINT ignore "Use newtype instead of data" #-} @@ -85,12 +88,12 @@ allChatFeatures = ] chatPrefSel :: SChatFeature f -> Preferences -> Maybe (FeaturePreference f) -chatPrefSel = \case - SCFTimedMessages -> timedMessages - SCFFullDelete -> fullDelete - SCFReactions -> reactions - SCFVoice -> voice - SCFCalls -> calls +chatPrefSel f ps = case f of + SCFTimedMessages -> ps.timedMessages + SCFFullDelete -> ps.fullDelete + SCFReactions -> ps.reactions + SCFVoice -> ps.voice + SCFCalls -> ps.calls chatFeature :: SChatFeature f -> ChatFeature chatFeature = \case @@ -110,12 +113,12 @@ instance PreferenceI (Maybe Preferences) where getPreference f prefs = fromMaybe (getPreference f defaultChatPrefs) (chatPrefSel f =<< prefs) instance PreferenceI FullPreferences where - getPreference = \case - SCFTimedMessages -> timedMessages - SCFFullDelete -> fullDelete - SCFReactions -> reactions - SCFVoice -> voice - SCFCalls -> calls + getPreference f ps = case f of + SCFTimedMessages -> ps.timedMessages + SCFFullDelete -> ps.fullDelete + SCFReactions -> ps.reactions + SCFVoice -> ps.voice + SCFCalls -> ps.calls {-# INLINE getPreference #-} setPreference :: forall f. FeatureI f => SChatFeature f -> Maybe FeatureAllowed -> Maybe Preferences -> Preferences @@ -215,13 +218,13 @@ allGroupFeatures = ] groupPrefSel :: SGroupFeature f -> GroupPreferences -> Maybe (GroupFeaturePreference f) -groupPrefSel = \case - SGFTimedMessages -> timedMessages - SGFDirectMessages -> directMessages - SGFFullDelete -> fullDelete - SGFReactions -> reactions - SGFVoice -> voice - SGFFiles -> files +groupPrefSel f ps = case f of + SGFTimedMessages -> ps.timedMessages + SGFDirectMessages -> ps.directMessages + SGFFullDelete -> ps.fullDelete + SGFReactions -> ps.reactions + SGFVoice -> ps.voice + SGFFiles -> ps.files toGroupFeature :: SGroupFeature f -> GroupFeature toGroupFeature = \case @@ -242,13 +245,13 @@ instance GroupPreferenceI (Maybe GroupPreferences) where getGroupPreference pt prefs = fromMaybe (getGroupPreference pt defaultGroupPrefs) (groupPrefSel pt =<< prefs) instance GroupPreferenceI FullGroupPreferences where - getGroupPreference = \case - SGFTimedMessages -> timedMessages - SGFDirectMessages -> directMessages - SGFFullDelete -> fullDelete - SGFReactions -> reactions - SGFVoice -> voice - SGFFiles -> files + getGroupPreference f ps = case f of + SGFTimedMessages -> ps.timedMessages + SGFDirectMessages -> ps.directMessages + SGFFullDelete -> ps.fullDelete + SGFReactions -> ps.reactions + SGFVoice -> ps.voice + SGFFiles -> ps.files {-# INLINE getGroupPreference #-} -- collection of optional group preferences @@ -428,19 +431,19 @@ class (Eq (FeaturePreference f), HasField "allow" (FeaturePreference f) FeatureA prefParam :: FeaturePreference f -> Maybe Int instance HasField "allow" TimedMessagesPreference FeatureAllowed where - hasField p = (\allow -> p {allow}, allow (p :: TimedMessagesPreference)) + hasField p = (\allow -> p {allow}, p.allow) instance HasField "allow" FullDeletePreference FeatureAllowed where - hasField p = (\allow -> p {allow}, allow (p :: FullDeletePreference)) + hasField p = (\allow -> p {allow}, p.allow) instance HasField "allow" ReactionsPreference FeatureAllowed where - hasField p = (\allow -> p {allow}, allow (p :: ReactionsPreference)) + hasField p = (\allow -> p {allow}, p.allow) instance HasField "allow" VoicePreference FeatureAllowed where - hasField p = (\allow -> p {allow}, allow (p :: VoicePreference)) + hasField p = (\allow -> p {allow}, p.allow) instance HasField "allow" CallsPreference FeatureAllowed where - hasField p = (\allow -> p {allow}, allow (p :: CallsPreference)) + hasField p = (\allow -> p {allow}, p.allow) instance FeatureI 'CFTimedMessages where type FeaturePreference 'CFTimedMessages = TimedMessagesPreference @@ -517,25 +520,25 @@ class (Eq (GroupFeaturePreference f), HasField "enable" (GroupFeaturePreference groupPrefParam :: GroupFeaturePreference f -> Maybe Int instance HasField "enable" GroupPreference GroupFeatureEnabled where - hasField p = (\enable -> p {enable}, enable (p :: GroupPreference)) + hasField p = (\enable -> p {enable}, p.enable) instance HasField "enable" TimedMessagesGroupPreference GroupFeatureEnabled where - hasField p = (\enable -> p {enable}, enable (p :: TimedMessagesGroupPreference)) + hasField p = (\enable -> p {enable}, p.enable) instance HasField "enable" DirectMessagesGroupPreference GroupFeatureEnabled where - hasField p = (\enable -> p {enable}, enable (p :: DirectMessagesGroupPreference)) + hasField p = (\enable -> p {enable}, p.enable) instance HasField "enable" ReactionsGroupPreference GroupFeatureEnabled where - hasField p = (\enable -> p {enable}, enable (p :: ReactionsGroupPreference)) + hasField p = (\enable -> p {enable}, p.enable) instance HasField "enable" FullDeleteGroupPreference GroupFeatureEnabled where - hasField p = (\enable -> p {enable}, enable (p :: FullDeleteGroupPreference)) + hasField p = (\enable -> p {enable}, p.enable) instance HasField "enable" VoiceGroupPreference GroupFeatureEnabled where - hasField p = (\enable -> p {enable}, enable (p :: VoiceGroupPreference)) + hasField p = (\enable -> p {enable}, p.enable) instance HasField "enable" FilesGroupPreference GroupFeatureEnabled where - hasField p = (\enable -> p {enable}, enable (p :: FilesGroupPreference)) + hasField p = (\enable -> p {enable}, p.enable) instance GroupFeatureI 'GFTimedMessages where type GroupFeaturePreference 'GFTimedMessages = TimedMessagesGroupPreference @@ -770,9 +773,9 @@ preferenceState pref = in (allow, param) getContactUserPreference :: SChatFeature f -> ContactUserPreferences -> ContactUserPreference (FeaturePreference f) -getContactUserPreference = \case - SCFTimedMessages -> timedMessages - SCFFullDelete -> fullDelete - SCFReactions -> reactions - SCFVoice -> voice - SCFCalls -> calls +getContactUserPreference f ps = case f of + SCFTimedMessages -> ps.timedMessages + SCFFullDelete -> ps.fullDelete + SCFReactions -> ps.reactions + SCFVoice -> ps.voice + SCFCalls -> ps.calls diff --git a/src/Simplex/Chat/Util.hs b/src/Simplex/Chat/Util.hs index 7a350705f1..46b5be28b3 100644 --- a/src/Simplex/Chat/Util.hs +++ b/src/Simplex/Chat/Util.hs @@ -1,6 +1,32 @@ -module Simplex.Chat.Util (week) where +module Simplex.Chat.Util (week, encryptFile, chunkSize) where +import Control.Monad +import Control.Monad.Except +import Control.Monad.IO.Class +import qualified Data.ByteString.Lazy as LB import Data.Time (NominalDiffTime) +import Simplex.Messaging.Crypto.File (CryptoFile (..), CryptoFileArgs (..)) +import qualified Simplex.Messaging.Crypto.File as CF +import UnliftIO.IO (IOMode (..), withFile) week :: NominalDiffTime week = 7 * 86400 + +encryptFile :: FilePath -> FilePath -> CryptoFileArgs -> ExceptT String IO () +encryptFile fromPath toPath cfArgs = do + let toFile = CryptoFile toPath $ Just cfArgs + -- uncomment to test encryption error in runTestFileTransferEncrypted + -- throwError "test error" + withExceptT show $ + withFile fromPath ReadMode $ \r -> CF.withFile toFile WriteMode $ \w -> do + encryptChunks r w + liftIO $ CF.hPutTag w + where + encryptChunks r w = do + ch <- liftIO $ LB.hGet r chunkSize + unless (LB.null ch) $ liftIO $ CF.hPut w ch + unless (LB.length ch < chunkSize) $ encryptChunks r w + +chunkSize :: Num a => a +chunkSize = 65536 +{-# INLINE chunkSize #-} diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 65e90c096b..5db0c317e8 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -7,6 +7,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE OverloadedRecordDot #-} module Simplex.Chat.View where @@ -191,7 +192,7 @@ responseToView user_ ChatConfig {logLevel, showReactions, showReceipts, testView CRContactConnecting u _ -> ttyUser u [] CRContactConnected u ct userCustomProfile -> ttyUser u $ viewContactConnected ct userCustomProfile testView CRContactAnotherClient u c -> ttyUser u [ttyContact' c <> ": contact is connected to another client"] - CRSubscriptionEnd u acEntity -> ttyUser u [sShow (connId (entityConnection acEntity :: Connection)) <> ": END"] + CRSubscriptionEnd u acEntity -> ttyUser u [sShow ((entityConnection acEntity).connId) <> ": END"] CRContactsDisconnected srv cs -> [plain $ "server disconnected " <> showSMPServer srv <> " (" <> contactList cs <> ")"] CRContactsSubscribed srv cs -> [plain $ "server connected " <> showSMPServer srv <> " (" <> contactList cs <> ")"] CRContactSubError u c e -> ttyUser u [ttyContact' c <> ": contact error " <> sShow e] @@ -230,6 +231,11 @@ responseToView user_ ChatConfig {logLevel, showReactions, showReceipts, testView CRGroupLink u g cReq mRole -> ttyUser u $ groupLink_ "Group link:" g cReq mRole CRGroupLinkDeleted u g -> ttyUser u $ viewGroupLinkDeleted g CRAcceptingGroupJoinRequest _ g c -> [ttyFullContact c <> ": accepting request to join group " <> ttyGroup' g <> "..."] + CRNoMemberContactCreating u g m -> ttyUser u ["member " <> ttyGroup' g <> " " <> ttyMember m <> " does not have direct connection, creating"] + CRNewMemberContact u _ g m -> ttyUser u ["contact for member " <> ttyGroup' g <> " " <> ttyMember m <> " is created"] + CRNewMemberContactSentInv u _ct g m -> ttyUser u ["sent invitation to connect directly to member " <> ttyGroup' g <> " " <> ttyMember m] + CRNewMemberContactReceivedInv u ct g m -> ttyUser u [ttyGroup' g <> " " <> ttyMember m <> " is creating direct contact " <> ttyContact' ct <> " with you"] + CRMemberContactConnected u ct g m -> ttyUser u ["member " <> ttyGroup' g <> " " <> ttyMember m <> " is merged into " <> ttyContact' ct] CRMemberSubError u g m e -> ttyUser u [ttyGroup' g <> " member " <> ttyMember m <> " error: " <> sShow e] CRMemberSubSummary u summary -> ttyUser u $ viewErrorsSummary (filter (isJust . memberError) summary) " group member errors" CRGroupSubscribed u g -> ttyUser u $ viewGroupSubscribed g @@ -662,6 +668,17 @@ viewConnReqInvitation cReq = "and ask them to connect: " <> highlight' "/c <invitation_link_above>" ] +viewContactNotFound :: ContactName -> Maybe (GroupInfo, GroupMember) -> [StyledString] +viewContactNotFound cName suspectedMember = + ["no contact " <> ttyContact cName <> useMessageMember] + where + useMessageMember = case suspectedMember of + Just (g, m) -> do + let GroupInfo {localDisplayName = gName} = g + GroupMember {localDisplayName = mName} = m + ", use " <> highlight' ("@#" <> T.unpack gName <> " " <> T.unpack mName <> " <your message>") + _ -> "" + viewChatCleared :: AChatInfo -> [StyledString] viewChatCleared (AChatInfo _ chatInfo) = case chatInfo of DirectChat ct -> [ttyContact' ct <> ": all messages are removed locally ONLY"] @@ -670,7 +687,9 @@ viewChatCleared (AChatInfo _ chatInfo) = case chatInfo of viewContactsList :: [Contact] -> [StyledString] viewContactsList = - let ldn = T.toLower . (localDisplayName :: Contact -> ContactName) + let getLDN :: Contact -> ContactName + getLDN Contact{localDisplayName} = localDisplayName + ldn = T.toLower . getLDN in map (\ct -> ctIncognito ct <> ttyFullContact ct <> muted' ct <> alias ct) . sortOn ldn where muted' Contact {chatSettings, localDisplayName = ldn} @@ -757,21 +776,21 @@ viewDirectMessagesProhibited MDSnd c = ["direct messages to indirect contact " < viewDirectMessagesProhibited MDRcv c = ["received prohibited direct message from indirect contact " <> ttyContact' c <> " (discarded)"] viewUserJoinedGroup :: GroupInfo -> [StyledString] -viewUserJoinedGroup g@GroupInfo {membership = membership@GroupMember {memberProfile}} = - if memberIncognito membership - then [ttyGroup' g <> ": you joined the group incognito as " <> incognitoProfile' (fromLocalProfile memberProfile)] - else [ttyGroup' g <> ": you joined the group"] +viewUserJoinedGroup g = + case incognitoMembershipProfile g of + Just mp -> [ttyGroup' g <> ": you joined the group incognito as " <> incognitoProfile' (fromLocalProfile mp)] + Nothing -> [ttyGroup' g <> ": you joined the group"] viewJoinedGroupMember :: GroupInfo -> GroupMember -> [StyledString] viewJoinedGroupMember g m = [ttyGroup' g <> ": " <> ttyMember m <> " joined the group "] viewReceivedGroupInvitation :: GroupInfo -> Contact -> GroupMemberRole -> [StyledString] -viewReceivedGroupInvitation g@GroupInfo {membership = membership@GroupMember {memberProfile}} c role = +viewReceivedGroupInvitation g c role = ttyFullGroup g <> ": " <> ttyContact' c <> " invites you to join the group as " <> plain (strEncode role) : - if memberIncognito membership - then ["use " <> highlight ("/j " <> groupName' g) <> " to join incognito as " <> incognitoProfile' (fromLocalProfile memberProfile)] - else ["use " <> highlight ("/j " <> groupName' g) <> " to accept"] + case incognitoMembershipProfile g of + Just mp -> ["use " <> highlight ("/j " <> groupName' g) <> " to join incognito as " <> incognitoProfile' (fromLocalProfile mp)] + Nothing -> ["use " <> highlight ("/j " <> groupName' g) <> " to accept"] groupPreserved :: GroupInfo -> [StyledString] groupPreserved g = ["use " <> highlight ("/d #" <> groupName' g) <> " to delete the group"] @@ -808,7 +827,8 @@ viewGroupMembers (Group GroupInfo {membership} members) = map groupMember . filt where removedOrLeft m = let s = memberStatus m in s == GSMemRemoved || s == GSMemLeft groupMember m = memIncognito m <> ttyFullMember m <> ": " <> role m <> ", " <> category m <> status m - role m = plain . strEncode $ memberRole (m :: GroupMember) + role :: GroupMember -> StyledString + role m = plain . strEncode $ m.memberRole category m = case memberCategory m of GCUserMember -> "you, " GCInviteeMember -> "invited, " @@ -840,9 +860,10 @@ viewContactConnected ct@Contact {localDisplayName} userIncognitoProfile testView viewGroupsList :: [(GroupInfo, GroupSummary)] -> [StyledString] viewGroupsList [] = ["you have no groups!", "to create: " <> highlight' "/g <name>"] -viewGroupsList gs = map groupSS $ sortOn ldn_ gs +viewGroupsList gs = map groupSS $ sortOn (ldn_ . fst) gs where - ldn_ = T.toLower . (localDisplayName :: GroupInfo -> GroupName) . fst + ldn_ :: GroupInfo -> Text + ldn_ g = T.toLower g.localDisplayName groupSS (g@GroupInfo {localDisplayName = ldn, groupProfile = GroupProfile {fullName}, membership, chatSettings}, GroupSummary {currentMembers}) = case memberStatus membership of GSMemInvited -> groupInvitation' g @@ -859,7 +880,7 @@ viewGroupsList gs = map groupSS $ sortOn ldn_ gs memberCount = sShow currentMembers <> " member" <> if currentMembers == 1 then "" else "s" groupInvitation' :: GroupInfo -> StyledString -groupInvitation' GroupInfo {localDisplayName = ldn, groupProfile = GroupProfile {fullName}, membership = membership@GroupMember {memberProfile}} = +groupInvitation' g@GroupInfo {localDisplayName = ldn, groupProfile = GroupProfile {fullName}} = highlight ("#" <> ldn) <> optFullName ldn fullName <> " - you are invited (" @@ -868,10 +889,9 @@ groupInvitation' GroupInfo {localDisplayName = ldn, groupProfile = GroupProfile <> highlight ("/d #" <> ldn) <> " to delete invitation)" where - joinText = - if memberIncognito membership - then " to join as " <> incognitoProfile' (fromLocalProfile memberProfile) <> ", " - else " to join, " + joinText = case incognitoMembershipProfile g of + Just mp -> " to join as " <> incognitoProfile' (fromLocalProfile mp) <> ", " + Nothing -> " to join, " viewContactsMerged :: Contact -> Contact -> [StyledString] viewContactsMerged _into@Contact {localDisplayName = c1} _merged@Contact {localDisplayName = c2} = @@ -1391,7 +1411,8 @@ viewFileTransferStatus (FTSnd FileTransferMeta {cancelled} fts@(ft : _), chunksN case concatMap recipientsTransferStatus $ groupBy ((==) `on` fs) $ sortOn fs fts of [recipientsStatus] -> ["sending " <> sndFile ft <> " " <> recipientsStatus] recipientsStatuses -> ("sending " <> sndFile ft <> ": ") : map (" " <>) recipientsStatuses - fs = fileStatus :: SndFileTransfer -> FileStatus + fs :: SndFileTransfer -> FileStatus + fs SndFileTransfer{fileStatus} = fileStatus recipientsTransferStatus [] = [] recipientsTransferStatus ts@(SndFileTransfer {fileStatus, fileSize, chunkSize} : _) = [sndStatus <> ": " <> listRecipients ts] where @@ -1544,6 +1565,7 @@ viewChatError logLevel = \case <> (", connection id: " <> show connId) <> maybe "" (\MsgMetaJSON {rcvId} -> ", agent msg rcv id: " <> show rcvId) msgMeta_ ] + CEContactNotFound cName m_ -> viewContactNotFound cName m_ CEContactNotReady c -> [ttyContact' c <> ": not ready"] CEContactDisabled Contact {localDisplayName = c} -> [ttyContact c <> ": disabled, to enable: " <> highlight ("/enable " <> c) <> ", to delete: " <> highlight ("/d " <> c)] CEConnectionDisabled Connection {connId, connType} -> [plain $ "connection " <> textEncode connType <> " (" <> tshow connId <> ") is disabled" | logLevel <= CLLWarning] @@ -1570,8 +1592,8 @@ viewChatError logLevel = \case CEFileCancelled f -> ["file cancelled: " <> plain f] CEFileCancel fileId e -> ["error cancelling file " <> sShow fileId <> ": " <> sShow e] CEFileAlreadyExists f -> ["file already exists: " <> plain f] - CEFileRead f e -> ["cannot read file " <> plain f, sShow e] - CEFileWrite f e -> ["cannot write file " <> plain f, sShow e] + CEFileRead f e -> ["cannot read file " <> plain f <> ": " <> plain e] + CEFileWrite f e -> ["cannot write file " <> plain f <> ": " <> plain e] CEFileSend fileId e -> ["error sending file " <> sShow fileId <> ": " <> sShow e] CEFileRcvChunk e -> ["error receiving file: " <> plain e] CEFileInternal e -> ["file error: " <> plain e] @@ -1597,6 +1619,7 @@ viewChatError logLevel = \case CEAgentCommandError e -> ["agent command error: " <> plain e] CEInvalidFileDescription e -> ["invalid file description: " <> plain e] CEConnectionIncognitoChangeProhibited -> ["incognito mode change prohibited"] + CEPeerChatVRangeIncompatible -> ["peer chat protocol version range incompatible"] CEInternalError e -> ["internal chat error: " <> plain e] CEException e -> ["exception: " <> plain e] -- e -> ["chat error: " <> sShow e] @@ -1652,7 +1675,8 @@ viewChatError logLevel = \case Just entity@(UserContactConnection conn UserContact {userContactLinkId}) -> "[" <> connEntityLabel entity <> ", userContactLinkId: " <> sShow userContactLinkId <> ", connId: " <> cId conn <> "] " Nothing -> "" - cId conn = sShow (connId (conn :: Connection)) + cId :: Connection -> StyledString + cId conn = sShow conn.connId where fileNotFound fileId = ["file " <> sShow fileId <> " not found"] sqliteError' = \case diff --git a/stack.yaml b/stack.yaml index 18d5afe8b9..0840970e49 100644 --- a/stack.yaml +++ b/stack.yaml @@ -49,20 +49,24 @@ extra-deps: # - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561 # - ../simplexmq - github: simplex-chat/simplexmq - commit: 0cabe0690beee90f460ad7bada72294222e7e109 + commit: 8d47f690838371bc848e4b31a4b09ef6bf67ccc5 - github: kazu-yamamoto/http2 commit: b5a1b7200cf5bc7044af34ba325284271f6dff25 # - ../direct-sqlcipher - github: simplex-chat/direct-sqlcipher - commit: 34309410eb2069b029b8fc1872deb1e0db123294 + commit: f814ee68b16a9447fbb467ccc8f29bdd3546bfd9 # - ../sqlcipher-simple - github: simplex-chat/sqlcipher-simple - commit: 5e154a2aeccc33ead6c243ec07195ab673137221 + commit: a46bd361a19376c5211f1058908fc0ae6bf42446 # - terminal-0.2.0.0@sha256:de6770ecaae3197c66ac1f0db5a80cf5a5b1d3b64a66a05b50f442de5ad39570,2977 - github: simplex-chat/aeson - commit: 3eb66f9a68f103b5f1489382aad89f5712a64db7 + commit: 68330dce8208173c6acf5f62b23acb500ab5d873 - github: simplex-chat/haskell-terminal commit: f708b00009b54890172068f168bf98508ffcd495 + - github: simplex-chat/android-support + commit: 9aa09f148089d6752ce563b14c2df1895718d806 + - github: simplex-chat/network-transport + commit: 0013798272a683e35ca38d2fdaf480942311fba8 # # extra-deps: [] diff --git a/tests/Bots/BroadcastTests.hs b/tests/Bots/BroadcastTests.hs index 69ec10a7ab..ae2d67c7f0 100644 --- a/tests/Bots/BroadcastTests.hs +++ b/tests/Bots/BroadcastTests.hs @@ -1,5 +1,6 @@ {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE OverloadedStrings #-} module Bots.BroadcastTests where @@ -33,7 +34,7 @@ broadcastBotProfile = Profile {displayName = "broadcast_bot", fullName = "Broadc mkBotOpts :: FilePath -> [KnownContact] -> BroadcastBotOpts mkBotOpts tmp publishers = BroadcastBotOpts - { coreOptions = (coreOptions (testOpts :: ChatOpts)) {dbFilePrefix = tmp </> botDbPrefix}, + { coreOptions = testOpts.coreOptions {dbFilePrefix = tmp </> botDbPrefix}, publishers, welcomeMessage = defaultWelcomeMessage publishers, prohibitedMessage = defaultWelcomeMessage publishers diff --git a/tests/Bots/DirectoryTests.hs b/tests/Bots/DirectoryTests.hs index f34ab042e8..0e315190c5 100644 --- a/tests/Bots/DirectoryTests.hs +++ b/tests/Bots/DirectoryTests.hs @@ -1,5 +1,6 @@ {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PostfixOperators #-} @@ -60,7 +61,7 @@ directoryProfile = Profile {displayName = "SimpleX-Directory", fullName = "", im mkDirectoryOpts :: FilePath -> [KnownContact] -> DirectoryOpts mkDirectoryOpts tmp superUsers = DirectoryOpts - { coreOptions = (coreOptions (testOpts :: ChatOpts)) {dbFilePrefix = tmp </> serviceDbPrefix}, + { coreOptions = testOpts.coreOptions {dbFilePrefix = tmp </> serviceDbPrefix}, superUsers, directoryLog = Just $ tmp </> "directory_service.log", serviceName = "SimpleX-Directory", diff --git a/tests/ChatClient.hs b/tests/ChatClient.hs index 9e5d4fe1c0..7da5263253 100644 --- a/tests/ChatClient.hs +++ b/tests/ChatClient.hs @@ -6,12 +6,15 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeApplications #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module ChatClient where import Control.Concurrent (forkIOWithUnmask, killThread, threadDelay) import Control.Concurrent.Async import Control.Concurrent.STM import Control.Exception (bracket, bracket_) +import Control.Monad import Control.Monad.Except import Data.Functor (($>)) import Data.List (dropWhileEnd, find) @@ -259,7 +262,7 @@ getTermLine cc = Just s -> do -- remove condition to always echo virtual terminal when (printOutput cc) $ do - -- when True $ do + -- when True $ do name <- userName cc putStrLn $ name <> ": " <> s pure s diff --git a/tests/ChatTests.hs b/tests/ChatTests.hs index ed81853ac8..eeb96503e3 100644 --- a/tests/ChatTests.hs +++ b/tests/ChatTests.hs @@ -8,7 +8,7 @@ import Test.Hspec chatTests :: SpecWith FilePath chatTests = do - chatDirectTests - chatGroupTests - chatFileTests - chatProfileTests + describe "direct tests" chatDirectTests + describe "group tests" chatGroupTests + describe "file tests" chatFileTests + describe "profile tests" chatProfileTests diff --git a/tests/ChatTests/Files.hs b/tests/ChatTests/Files.hs index 9b4c466726..f84d4dcb40 100644 --- a/tests/ChatTests/Files.hs +++ b/tests/ChatTests/Files.hs @@ -2,6 +2,8 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PostfixOperators #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + module ChatTests.Files where import ChatClient @@ -29,6 +31,7 @@ chatFileTests :: SpecWith FilePath chatFileTests = do describe "sending and receiving files" $ do describe "send and receive file" $ fileTestMatrix2 runTestFileTransfer + describe "send file, receive and locally encrypt file" $ fileTestMatrix2 runTestFileTransferEncrypted it "send and receive file inline (without accepting)" testInlineFileTransfer xit'' "accept inline file transfer, sender cancels during transfer" testAcceptInlineFileSndCancelDuringTransfer it "send and receive small file inline (default config)" testSmallInlineFileTransfer @@ -95,6 +98,37 @@ runTestFileTransfer alice bob = do dest <- B.readFile "./tests/tmp/test.pdf" dest `shouldBe` src +runTestFileTransferEncrypted :: HasCallStack => TestCC -> TestCC -> IO () +runTestFileTransferEncrypted alice bob = do + connectUsers alice bob + alice #> "/f @bob ./tests/fixtures/test.pdf" + alice <## "use /fc 1 to cancel sending" + bob <# "alice> sends file test.pdf (266.0 KiB / 272376 bytes)" + bob <## "use /fr 1 [<dir>/ | <path>] to receive it" + bob ##> "/fr 1 encrypt=on ./tests/tmp" + bob <## "saving file 1 from alice to ./tests/tmp/test.pdf" + Just (CFArgs key nonce) <- J.decode . LB.pack <$> getTermLine bob + concurrently_ + (bob <## "started receiving file 1 (test.pdf) from alice") + (alice <## "started sending file 1 (test.pdf) to bob") + + concurrentlyN_ + [ do + bob #> "@alice receiving here..." + -- uncomment this and below to test encryption error in encryptFile + -- bob <## "cannot write file ./tests/tmp/test.pdf: test error, received file not encrypted" + bob <## "completed receiving file 1 (test.pdf) from alice", + alice + <### [ WithTime "bob> receiving here...", + "completed sending file 1 (test.pdf) to bob" + ] + ] + src <- B.readFile "./tests/fixtures/test.pdf" + -- dest <- B.readFile "./tests/tmp/test.pdf" + -- dest `shouldBe` src + Right dest <- chatReadFile "./tests/tmp/test.pdf" (strEncode key) (strEncode nonce) + LB.toStrict dest `shouldBe` src + testInlineFileTransfer :: HasCallStack => FilePath -> IO () testInlineFileTransfer = testChatCfg2 cfg aliceProfile bobProfile $ \alice bob -> do diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index d476285fcd..bf740a960f 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -68,19 +68,20 @@ chatGroupTests = do it "should send delivery receipts in group depending on configuration" testConfigureGroupDeliveryReceipts describe "direct connections in group are not established based on chat protocol version" $ do describe "3 members group" $ do - testNoDirect _0 _0 False -- True - testNoDirect _0 _1 False -- True + testNoDirect _0 _0 True + testNoDirect _0 _1 True testNoDirect _1 _0 False testNoDirect _1 _1 False - describe "4 members group" $ do - testNoDirect4 _0 _0 _0 False False False -- True True True - testNoDirect4 _0 _0 _1 False False False -- True True True - testNoDirect4 _0 _1 _0 False False False -- True True False - testNoDirect4 _0 _1 _1 False False False -- True True False - testNoDirect4 _1 _0 _0 False False False -- False False True - testNoDirect4 _1 _0 _1 False False False -- False False True - testNoDirect4 _1 _1 _0 False False False - testNoDirect4 _1 _1 _1 False False False + it "members have different local display names in different groups" testNoDirectDifferentLDNs + it "member should connect to contact when profile match" testConnectMemberToContact + describe "create member contact" $ do + it "create contact with group member with invitation message" testMemberContactMessage + it "create contact with group member without invitation message" testMemberContactNoMessage + it "prohibited to create contact with group member if it already exists" testMemberContactProhibitedContactExists + it "prohibited to repeat sending x.grp.direct.inv" testMemberContactProhibitedRepeatInv + it "invited member replaces member contact reference if it already exists" testMemberContactInvitedConnectionReplaced + it "share incognito profile" testMemberContactIncognito + it "sends and updates profile when creating contact" testMemberContactProfileUpdate where _0 = supportedChatVRange -- don't create direct connections _1 = groupCreateDirectVRange @@ -94,17 +95,6 @@ chatGroupTests = do <> (if noConns then " : 2 <!!> 3" else " : 2 <##> 3") ) $ testNoGroupDirectConns supportedChatVRange vrMem2 vrMem3 noConns - testNoDirect4 vrMem2 vrMem3 vrMem4 noConns23 noConns24 noConns34 = - it - ( "host " <> vRangeStr supportedChatVRange - <> (", 2nd mem " <> vRangeStr vrMem2) - <> (", 3rd mem " <> vRangeStr vrMem3) - <> (", 4th mem " <> vRangeStr vrMem4) - <> (if noConns23 then " : 2 <!!> 3" else " : 2 <##> 3") - <> (if noConns24 then " : 2 <!!> 4" else " : 2 <##> 4") - <> (if noConns34 then " : 3 <!!> 4" else " : 3 <##> 4") - ) - $ testNoGroupDirectConns4Members supportedChatVRange vrMem2 vrMem3 vrMem4 noConns23 noConns24 noConns34 testGroup :: HasCallStack => FilePath -> IO () testGroup = @@ -230,8 +220,12 @@ testGroupShared alice bob cath checkMessages = do -- delete contact alice ##> "/d bob" alice <## "bob: contact is deleted" - alice ##> "@bob hey" - alice <## "no contact bob" + alice `send` "@bob hey" + alice + <### [ "@bob hey", + "member #team bob does not have direct connection, creating", + "peer chat protocol version range incompatible" + ] when checkMessages $ threadDelay 1000000 alice #> "#team checking connection" bob <# "#team alice> checking connection" @@ -643,11 +637,22 @@ testGroupDeleteInvitedContact = bob <# "#team alice> hello" bob #> "#team hi there" alice <# "#team bob> hi there" - alice ##> "@bob hey" - alice <## "no contact bob" - bob #> "@alice hey" - bob <## "[alice, contactId: 2, connId: 1] error: connection authorization failed - this could happen if connection was deleted, secured with different credentials, or due to a bug - please re-create the connection" - (alice </) + alice `send` "@bob hey" + alice + <### [ WithTime "@bob hey", + "member #team bob does not have direct connection, creating", + "contact for member #team bob is created", + "sent invitation to connect directly to member #team bob" + ] + bob + <### [ "#team alice is creating direct contact alice with you", + WithTime "alice> hey", + "alice: security code changed" + ] + concurrently_ + (alice <## "bob (Bob): contact is connected") + (bob <## "alice (Alice): contact is connected") + alice <##> bob testDeleteGroupMemberProfileKept :: HasCallStack => FilePath -> IO () testDeleteGroupMemberProfileKept = @@ -696,7 +701,7 @@ testDeleteGroupMemberProfileKept = alice ##> "/d bob" alice <## "bob: contact is deleted" alice ##> "@bob hey" - alice <## "no contact bob" + alice <## "no contact bob, use @#club bob <your message>" bob #> "@alice hey" bob <## "[alice, contactId: 2, connId: 1] error: connection authorization failed - this could happen if connection was deleted, secured with different credentials, or due to a bug - please re-create the connection" (alice </) @@ -2636,53 +2641,482 @@ testNoGroupDirectConns hostVRange mem2VRange mem3VRange noDirectConns tmp = createGroup3 "team" alice bob cath if noDirectConns then contactsDontExist bob cath - else bob <##> cath + else contactsExist bob cath where contactsDontExist bob cath = do - bob ##> "@cath hi" - bob <## "no contact cath" - cath ##> "@bob hi" - cath <## "no contact bob" + bob ##> "/contacts" + bob <## "alice (Alice)" + cath ##> "/contacts" + cath <## "alice (Alice)" + contactsExist bob cath = do + bob ##> "/contacts" + bob + <### [ "alice (Alice)", + "cath (Catherine)" + ] + cath ##> "/contacts" + cath + <### [ "alice (Alice)", + "bob (Bob)" + ] + bob <##> cath -testNoGroupDirectConns4Members :: HasCallStack => VersionRange -> VersionRange -> VersionRange -> VersionRange -> Bool -> Bool -> Bool -> FilePath -> IO () -testNoGroupDirectConns4Members hostVRange mem2VRange mem3VRange mem4VRange noConns23 noConns24 noConns34 tmp = - withNewTestChatCfg tmp testCfg {chatVRange = hostVRange} "alice" aliceProfile $ \alice -> do - withNewTestChatCfg tmp testCfg {chatVRange = mem2VRange} "bob" bobProfile $ \bob -> do - withNewTestChatCfg tmp testCfg {chatVRange = mem3VRange} "cath" cathProfile $ \cath -> do - withNewTestChatCfg tmp testCfg {chatVRange = mem4VRange} "dan" danProfile $ \dan -> do - createGroup3 "team" alice bob cath - connectUsers alice dan - addMember "team" alice dan GRMember - dan ##> "/j team" - concurrentlyN_ - [ alice <## "#team: dan joined the group", - do - dan <## "#team: you joined the group" - dan - <### [ "#team: member bob (Bob) is connected", - "#team: member cath (Catherine) is connected" - ], - aliceAddedDan bob, - aliceAddedDan cath - ] - if noConns23 - then contactsDontExist bob cath - else bob <##> cath - if noConns24 - then contactsDontExist bob dan - else bob <##> dan - if noConns34 - then contactsDontExist cath dan - else cath <##> dan +testNoDirectDifferentLDNs :: HasCallStack => FilePath -> IO () +testNoDirectDifferentLDNs = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + createGroup3 "team" alice bob cath + alice ##> "/g club" + alice <## "group #club is created" + alice <## "to add members use /a club <name> or /create link #club" + addMember "club" alice bob GRAdmin + bob ##> "/j club" + concurrently_ + (alice <## "#club: bob joined the group") + (bob <## "#club: you joined the group") + addMember "club" alice cath GRAdmin + cath ##> "/j club" + concurrentlyN_ + [ alice <## "#club: cath joined the group", + do + cath <## "#club: you joined the group" + cath <## "#club: member bob_1 (Bob) is connected", + do + bob <## "#club: alice added cath_1 (Catherine) to the group (connecting...)" + bob <## "#club: new member cath_1 is connected" + ] + + testGroupLDNs alice bob cath "team" "bob" "cath" + testGroupLDNs alice bob cath "club" "bob_1" "cath_1" + + alice `hasContactProfiles` ["alice", "bob", "cath"] + bob `hasContactProfiles` ["bob", "alice", "cath", "cath"] + cath `hasContactProfiles` ["cath", "alice", "bob", "bob"] where - aliceAddedDan :: HasCallStack => TestCC -> IO () - aliceAddedDan cc = do - cc <## "#team: alice added dan (Daniel) to the group (connecting...)" - cc <## "#team: new member dan is connected" - contactsDontExist cc1 cc2 = do - name1 <- userName cc1 - name2 <- userName cc2 - cc1 ##> ("@" <> name2 <> " hi") - cc1 <## ("no contact " <> name2) - cc2 ##> ("@" <> name1 <> " hi") - cc2 <## ("no contact " <> name1) + testGroupLDNs alice bob cath gName bobLDN cathLDN = do + alice ##> ("/ms " <> gName) + alice + <### [ "alice (Alice): owner, you, created group", + "bob (Bob): admin, invited, connected", + "cath (Catherine): admin, invited, connected" + ] + + bob ##> ("/ms " <> gName) + bob + <### [ "alice (Alice): owner, host, connected", + "bob (Bob): admin, you, connected", + ConsoleString (cathLDN <> " (Catherine): admin, connected") + ] + + cath ##> ("/ms " <> gName) + cath + <### [ "alice (Alice): owner, host, connected", + ConsoleString (bobLDN <> " (Bob): admin, connected"), + "cath (Catherine): admin, you, connected" + ] + + alice #> ("#" <> gName <> " hello") + concurrentlyN_ + [ bob <# ("#" <> gName <> " alice> hello"), + cath <# ("#" <> gName <> " alice> hello") + ] + bob #> ("#" <> gName <> " hi there") + concurrentlyN_ + [ alice <# ("#" <> gName <> " bob> hi there"), + cath <# ("#" <> gName <> " " <> bobLDN <> "> hi there") + ] + cath #> ("#" <> gName <> " hey") + concurrentlyN_ + [ alice <# ("#" <> gName <> " cath> hey"), + bob <# ("#" <> gName <> " " <> cathLDN <> "> hey") + ] + +testConnectMemberToContact :: HasCallStack => FilePath -> IO () +testConnectMemberToContact = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + connectUsers alice bob + connectUsers alice cath + createGroup2 "team" bob cath + bob ##> "/a #team alice" + bob <## "invitation to join the group #team sent to alice" + alice <## "#team: bob invites you to join the group as member" + alice <## "use /j team to accept" + alice ##> "/j team" + concurrentlyN_ + [ do + alice <## "#team: you joined the group" + alice <## "#team: member cath_1 (Catherine) is connected" + alice <## "member #team cath_1 is merged into cath", + do + bob <## "#team: alice joined the group", + do + cath <## "#team: bob added alice_1 (Alice) to the group (connecting...)" + cath <## "#team: new member alice_1 is connected" + cath <## "member #team alice_1 is merged into alice" + ] + alice <##> cath + alice #> "#team hello" + bob <# "#team alice> hello" + cath <# "#team alice> hello" + cath #> "#team hello too" + bob <# "#team cath> hello too" + alice <# "#team cath> hello too" + + alice ##> "/contacts" + alice + <### [ "bob (Bob)", + "cath (Catherine)" + ] + cath ##> "/contacts" + cath + <### [ "alice (Alice)", + "bob (Bob)" + ] + alice `hasContactProfiles` ["alice", "bob", "cath"] + cath `hasContactProfiles` ["cath", "alice", "bob"] + +testMemberContactMessage :: HasCallStack => FilePath -> IO () +testMemberContactMessage = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + createGroup3 "team" alice bob cath + + -- alice and bob delete contacts, connect + alice ##> "/d bob" + alice <## "bob: contact is deleted" + bob ##> "/d alice" + bob <## "alice: contact is deleted" + + alice ##> "@#team bob hi" + alice + <### [ "member #team bob does not have direct connection, creating", + "contact for member #team bob is created", + "sent invitation to connect directly to member #team bob", + WithTime "@bob hi" + ] + bob + <### [ "#team alice is creating direct contact alice with you", + WithTime "alice> hi" + ] + concurrently_ + (alice <## "bob (Bob): contact is connected") + (bob <## "alice (Alice): contact is connected") + + bob #$> ("/_get chat #1 count=1", chat, [(0, "started direct connection with you")]) + alice <##> bob + + -- bob and cath connect + bob ##> "@#team cath hi" + bob + <### [ "member #team cath does not have direct connection, creating", + "contact for member #team cath is created", + "sent invitation to connect directly to member #team cath", + WithTime "@cath hi" + ] + cath + <### [ "#team bob is creating direct contact bob with you", + WithTime "bob> hi" + ] + concurrently_ + (bob <## "cath (Catherine): contact is connected") + (cath <## "bob (Bob): contact is connected") + + cath #$> ("/_get chat #1 count=1", chat, [(0, "started direct connection with you")]) + bob <##> cath + +testMemberContactNoMessage :: HasCallStack => FilePath -> IO () +testMemberContactNoMessage = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + createGroup3 "team" alice bob cath + + -- bob and cath connect + bob ##> "/_create member contact #1 3" + bob <## "contact for member #team cath is created" + + bob ##> "/_invite member contact @3" + bob <## "sent invitation to connect directly to member #team cath" + cath <## "#team bob is creating direct contact bob with you" + concurrently_ + (bob <## "cath (Catherine): contact is connected") + (cath <## "bob (Bob): contact is connected") + + cath #$> ("/_get chat #1 count=1", chat, [(0, "started direct connection with you")]) + bob <##> cath + +testMemberContactProhibitedContactExists :: HasCallStack => FilePath -> IO () +testMemberContactProhibitedContactExists = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + createGroup3 "team" alice bob cath + + alice ##> "/_create member contact #1 2" + alice <## "bad chat command: member contact already exists" + + alice ##> "@#team bob hi" + alice <# "@bob hi" + bob <# "alice> hi" + +testMemberContactProhibitedRepeatInv :: HasCallStack => FilePath -> IO () +testMemberContactProhibitedRepeatInv = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + createGroup3 "team" alice bob cath + + bob ##> "/_create member contact #1 3" + bob <## "contact for member #team cath is created" + + bob ##> "/_invite member contact @3 text hi" + bob + <### [ "sent invitation to connect directly to member #team cath", + WithTime "@cath hi" + ] + bob ##> "/_invite member contact @3 text hey" + bob <## "bad chat command: x.grp.direct.inv already sent" + cath + <### [ "#team bob is creating direct contact bob with you", + WithTime "bob> hi" + ] + concurrently_ + (bob <## "cath (Catherine): contact is connected") + (cath <## "bob (Bob): contact is connected") + + bob <##> cath + +testMemberContactInvitedConnectionReplaced :: HasCallStack => FilePath -> IO () +testMemberContactInvitedConnectionReplaced tmp = do + withNewTestChat tmp "alice" aliceProfile $ \alice -> do + withNewTestChat tmp "bob" bobProfile $ \bob -> do + withNewTestChat tmp "cath" cathProfile $ \cath -> do + createGroup3 "team" alice bob cath + + alice ##> "/d bob" + alice <## "bob: contact is deleted" + + alice ##> "@#team bob hi" + alice + <### [ "member #team bob does not have direct connection, creating", + "contact for member #team bob is created", + "sent invitation to connect directly to member #team bob", + WithTime "@bob hi" + ] + bob + <### [ "#team alice is creating direct contact alice with you", + WithTime "alice> hi", + "alice: security code changed" + ] + concurrently_ + (alice <## "bob (Bob): contact is connected") + (bob <## "alice (Alice): contact is connected") + + bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "received invitation to join group team as admin"), (0, "hi"), (0, "security code changed")] <> chatFeatures) + + withTestChat tmp "bob" $ \bob -> do + subscriptions bob 1 + + checkConnectionsWork alice bob + + withTestChat tmp "alice" $ \alice -> do + subscriptions alice 2 + + withTestChat tmp "bob" $ \bob -> do + subscriptions bob 1 + + checkConnectionsWork alice bob + + withTestChat tmp "cath" $ \cath -> do + subscriptions cath 1 + + -- group messages work + alice #> "#team hello" + concurrently_ + (bob <# "#team alice> hello") + (cath <# "#team alice> hello") + bob #> "#team hi there" + concurrently_ + (alice <# "#team bob> hi there") + (cath <# "#team bob> hi there") + cath #> "#team hey team" + concurrently_ + (alice <# "#team cath> hey team") + (bob <# "#team cath> hey team") + where + subscriptions :: TestCC -> Int -> IO () + subscriptions cc n = do + cc <## (show n <> " contacts connected (use /cs for the list)") + cc <## "#team: connected to server(s)" + checkConnectionsWork alice bob = do + alice <##> bob + alice @@@ [("@bob", "hey"), ("@cath", "sent invitation to join group team as admin"), ("#team", "connected")] + bob @@@ [("@alice", "hey"), ("#team", "started direct connection with you")] + +testMemberContactIncognito :: HasCallStack => FilePath -> IO () +testMemberContactIncognito = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + -- create group, bob joins incognito + alice ##> "/g team" + alice <## "group #team is created" + alice <## "to add members use /a team <name> or /create link #team" + alice ##> "/create link #team" + gLink <- getGroupLink alice "team" GRMember True + bob ##> ("/c i " <> gLink) + bobIncognito <- getTermLine bob + bob <## "connection request sent incognito!" + alice <## (bobIncognito <> ": accepting request to join group #team...") + _ <- getTermLine bob + concurrentlyN_ + [ do + alice <## (bobIncognito <> ": contact is connected") + alice <## (bobIncognito <> " invited to group #team via your group link") + alice <## ("#team: " <> bobIncognito <> " joined the group"), + do + bob <## ("alice (Alice): contact is connected, your incognito profile for this contact is " <> bobIncognito) + bob <## "use /i alice to print out this incognito profile again" + bob <## ("#team: you joined the group incognito as " <> bobIncognito) + ] + -- cath joins incognito + cath ##> ("/c i " <> gLink) + cathIncognito <- getTermLine cath + cath <## "connection request sent incognito!" + alice <## (cathIncognito <> ": accepting request to join group #team...") + _ <- getTermLine cath + concurrentlyN_ + [ do + alice <## (cathIncognito <> ": contact is connected") + alice <## (cathIncognito <> " invited to group #team via your group link") + alice <## ("#team: " <> cathIncognito <> " joined the group"), + do + cath <## ("alice (Alice): contact is connected, your incognito profile for this contact is " <> cathIncognito) + cath <## "use /i alice to print out this incognito profile again" + cath <## ("#team: you joined the group incognito as " <> cathIncognito) + cath <## ("#team: member " <> bobIncognito <> " is connected"), + do + bob <## ("#team: alice added " <> cathIncognito <> " to the group (connecting...)") + bob <## ("#team: new member " <> cathIncognito <> " is connected") + ] + + alice `hasContactProfiles` ["alice", T.pack bobIncognito, T.pack cathIncognito] + bob `hasContactProfiles` ["bob", "alice", T.pack bobIncognito, T.pack cathIncognito] + cath `hasContactProfiles` ["cath", "alice", T.pack bobIncognito, T.pack cathIncognito] + + -- bob creates member contact with cath - both share incognito profile + bob ##> ("@#team " <> cathIncognito <> " hi") + bob + <### [ ConsoleString ("member #team " <> cathIncognito <> " does not have direct connection, creating"), + ConsoleString ("contact for member #team " <> cathIncognito <> " is created"), + ConsoleString ("sent invitation to connect directly to member #team " <> cathIncognito), + WithTime ("i @" <> cathIncognito <> " hi") + ] + cath + <### [ ConsoleString ("#team " <> bobIncognito <> " is creating direct contact " <> bobIncognito <> " with you"), + WithTime ("i " <> bobIncognito <> "> hi") + ] + _ <- getTermLine bob + _ <- getTermLine cath + concurrentlyN_ + [ do + bob <## (cathIncognito <> ": contact is connected, your incognito profile for this contact is " <> bobIncognito) + bob <## ("use /i " <> cathIncognito <> " to print out this incognito profile again"), + do + cath <## (bobIncognito <> ": contact is connected, your incognito profile for this contact is " <> cathIncognito) + cath <## ("use /i " <> bobIncognito <> " to print out this incognito profile again") + ] + + bob `hasContactProfiles` ["bob", "alice", T.pack bobIncognito, T.pack cathIncognito] + cath `hasContactProfiles` ["cath", "alice", T.pack bobIncognito, T.pack cathIncognito] + + bob ?#> ("@" <> cathIncognito <> " hi, I'm incognito") + cath ?<# (bobIncognito <> "> hi, I'm incognito") + cath ?#> ("@" <> bobIncognito <> " hey, me too") + bob ?<# (cathIncognito <> "> hey, me too") + + -- members still use incognito profile for group + alice #> "#team hello" + concurrentlyN_ + [ bob ?<# "#team alice> hello", + cath ?<# "#team alice> hello" + ] + bob ?#> "#team hi there" + concurrentlyN_ + [ alice <# ("#team " <> bobIncognito <> "> hi there"), + cath ?<# ("#team " <> bobIncognito <> "> hi there") + ] + cath ?#> "#team hey" + concurrentlyN_ + [ alice <# ("#team " <> cathIncognito <> "> hey"), + bob ?<# ("#team " <> cathIncognito <> "> hey") + ] + +testMemberContactProfileUpdate :: HasCallStack => FilePath -> IO () +testMemberContactProfileUpdate = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + createGroup3 "team" alice bob cath + + bob ##> "/p rob Rob" + bob <## "user profile is changed to rob (Rob) (your 1 contacts are notified)" + alice <## "contact bob changed to rob (Rob)" + alice <## "use @rob <message> to send messages" + + cath ##> "/p kate Kate" + cath <## "user profile is changed to kate (Kate) (your 1 contacts are notified)" + alice <## "contact cath changed to kate (Kate)" + alice <## "use @kate <message> to send messages" + + alice #> "#team hello" + bob <# "#team alice> hello" + cath <# "#team alice> hello" + + bob #> "#team hello too" + alice <# "#team rob> hello too" + cath <# "#team bob> hello too" -- not updated profile + + cath #> "#team hello there" + alice <# "#team kate> hello there" + bob <# "#team cath> hello there" -- not updated profile + + bob `send` "@cath hi" + bob + <### [ "member #team cath does not have direct connection, creating", + "contact for member #team cath is created", + "sent invitation to connect directly to member #team cath", + WithTime "@cath hi" + ] + cath + <### [ "#team bob is creating direct contact bob with you", + WithTime "bob> hi" + ] + concurrentlyN_ + [ do + bob <## "contact cath changed to kate (Kate)" + bob <## "use @kate <message> to send messages" + bob <## "kate (Kate): contact is connected", + do + cath <## "contact bob changed to rob (Rob)" + cath <## "use @rob <message> to send messages" + cath <## "rob (Rob): contact is connected" + ] + + bob ##> "/contacts" + bob + <### [ "alice (Alice)", + "kate (Kate)" + ] + cath ##> "/contacts" + cath + <### [ "alice (Alice)", + "rob (Rob)" + ] + alice `hasContactProfiles` ["alice", "rob", "kate"] + bob `hasContactProfiles` ["rob", "alice", "kate"] + cath `hasContactProfiles` ["kate", "alice", "rob"] + + bob #> "#team hello too" + alice <# "#team rob> hello too" + cath <# "#team rob> hello too" -- updated profile + + cath #> "#team hello there" + alice <# "#team kate> hello there" + bob <# "#team kate> hello there" -- updated profile diff --git a/tests/ProtocolTests.hs b/tests/ProtocolTests.hs index 3acc78e7d8..d62d7a470a 100644 --- a/tests/ProtocolTests.hs +++ b/tests/ProtocolTests.hs @@ -270,6 +270,12 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do it "x.grp.del" $ "{\"v\":\"1\",\"event\":\"x.grp.del\",\"params\":{}}" ==# XGrpDel + it "x.grp.direct.inv" $ + "{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"https://simplex.chat/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D1-2%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\", \"content\":{\"text\":\"hello\",\"type\":\"text\"}}}" + #==# XGrpDirectInv testConnReq (Just $ MCText "hello") + it "x.grp.direct.inv without content" $ + "{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"https://simplex.chat/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D1-2%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}" + #==# XGrpDirectInv testConnReq Nothing it "x.info.probe" $ "{\"v\":\"1\",\"event\":\"x.info.probe\",\"params\":{\"probe\":\"AQIDBA==\"}}" #==# XInfoProbe (Probe "\1\2\3\4") diff --git a/tests/SchemaDump.hs b/tests/SchemaDump.hs index cd493ab34e..f4538e4b3b 100644 --- a/tests/SchemaDump.hs +++ b/tests/SchemaDump.hs @@ -69,7 +69,9 @@ skipComparisonForDownMigrations = [ -- on down migration msg_delivery_events table moves down to the end of the file "20230504_recreate_msg_delivery_events_cleanup_messages", -- on down migration idx_chat_items_timed_delete_at index moves down to the end of the file - "20230529_indexes" + "20230529_indexes", + -- table and index definitions move down the file, so fields are re-created as not unique + "20230914_member_probes" ] getSchema :: FilePath -> FilePath -> IO String diff --git a/website/.eleventy.js b/website/.eleventy.js index fb9fe108f2..09fc7c2c44 100644 --- a/website/.eleventy.js +++ b/website/.eleventy.js @@ -188,6 +188,50 @@ module.exports = function (ty) { return dom.serialize() }) + ty.addFilter('wrapH3s', function (content, page) { + if (!page.url.includes("/jobs/")) { + return content + } + + const dom = new JSDOM(content) + const document = dom.window.document + + const makeBlock = (block) => { + const jobTab = document.createElement('div') + jobTab.className = "job-tab" + + const flexDiv = document.createElement('div') + flexDiv.className = "flex items-center justify-between job-tab-btn cursor-pointer" + flexDiv.innerHTML = ` + <${block.tagName}>${block.innerHTML}</${block.tagName}> + <svg class="fill-grey-black dark:fill-white" width="10" height="5" viewBox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M8.40813 4.79332C8.69689 5.06889 9.16507 5.06889 9.45384 4.79332C9.7426 4.51775 9.7426 4.07097 9.45384 3.7954L5.69327 0.206676C5.65717 0.17223 5.61827 0.142089 5.57727 0.116255C5.29026 -0.064587 4.90023 -0.0344467 4.64756 0.206676L0.886983 3.7954C0.598219 4.07097 0.598219 4.51775 0.886983 4.79332C1.17575 5.06889 1.64393 5.06889 1.93269 4.79332L5.17041 1.70356L8.40813 4.79332Z"></path> + </svg> + ` + jobTab.appendChild(flexDiv) + + const jobContent = document.createElement('div') + jobContent.className = "job-tab-content" + jobTab.appendChild(jobContent) + + block.parentNode.insertBefore(jobTab, block) + block.remove() + + let sibling = jobTab.nextElementSibling + const siblingsToMove = [] + while (sibling && !['H3', 'H2'].includes(sibling.tagName)) { + siblingsToMove.push(sibling) + sibling = sibling.nextElementSibling + } + + siblingsToMove.forEach(el => jobContent.appendChild(el)) + } + + Array.from(document.querySelectorAll("h3")).forEach(makeBlock) + + return dom.serialize() + }) + ty.addShortcode("completeRoute", (obj) => { const urlParts = obj.url.split("/") @@ -271,7 +315,8 @@ module.exports = function (ty) { referenceMenu.data.forEach(referenceSubmenu => { docs.forEach(doc => { const url = doc.url.replace("/docs/", "") - const urlParts = url.split("/") + let urlParts = url.split("/") + urlParts = urlParts.filter((ele) => ele !== "") if (doc.inputPath.split('/').includes(referenceSubmenu)) { if (urlParts.length === 1 && urlParts[0] !== "") { diff --git a/website/customize_docs_frontmatter.js b/website/customize_docs_frontmatter.js index 8f2546e168..10031b5436 100644 --- a/website/customize_docs_frontmatter.js +++ b/website/customize_docs_frontmatter.js @@ -54,13 +54,17 @@ Object.entries(fileLanguageMapping).forEach(([fileName, languages]) => { // Calculate the permalink based on the file's location const linkPath = path.relative(directoryPath, fullPath).replace(/\.md$/, '.html'); const permalink = `/docs/${linkPath}`.toLowerCase(); - parsedMatter.data.permalink = permalink; + + if (fileName === 'JOIN_TEAM') { + parsedMatter.data.active_jobs = true; + } + if (!parsedMatter.data.permalink) parsedMatter.data.permalink = permalink; // Update the frontmatter with the new languages list parsedMatter.data.supportedLangsForDoc = languages; // Add the layout value - parsedMatter.data.layout = 'layouts/doc.html'; + if (!parsedMatter.data.layout) parsedMatter.data.layout = 'layouts/doc.html'; if (fullPath.startsWith(path.join(directoryPath, langFolder))) { // Non-English files diff --git a/website/langs/ar.json b/website/langs/ar.json index bf44575f28..3fe698a3fe 100644 --- a/website/langs/ar.json +++ b/website/langs/ar.json @@ -132,7 +132,7 @@ "donate-here-to-help-us": "تبرّع هنا لمساعدتنا", "sign-up-to-receive-our-updates": "اشترك للحصول على آخر مستجداتنا", "enter-your-email-address": "أدخل عنوان بريدك الإلكتروني", - "get-simplex": "احصل على SimpleX", + "get-simplex": "احصل على SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "لماذا SimpleX", "unique": "فريد من نوعه", "learn-more": "اقرأ أكثر", diff --git a/website/langs/bg.json b/website/langs/bg.json index 0967ef424b..8ab6d958ed 100644 --- a/website/langs/bg.json +++ b/website/langs/bg.json @@ -1 +1,3 @@ -{} +{ + "developers": "Разработчици" +} diff --git a/website/langs/cs.json b/website/langs/cs.json index 99febbeacd..93aed0c9b2 100644 --- a/website/langs/cs.json +++ b/website/langs/cs.json @@ -114,7 +114,7 @@ "donate-here-to-help-us": "Přispějte zde a pomozte nám", "sign-up-to-receive-our-updates": "Přihlaste se k odběru novinek", "enter-your-email-address": "vložte svou e-mailovou adresu", - "get-simplex": "Získat SimpleX", + "get-simplex": "Získat SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Proč je SimpleX", "unique": "jedinečný", "learn-more": "Další informace", diff --git a/website/langs/de.json b/website/langs/de.json index 6cb3f1d3f6..052b73235a 100644 --- a/website/langs/de.json +++ b/website/langs/de.json @@ -127,7 +127,7 @@ "donate-here-to-help-us": "Spenden Sie, um uns zu unterstützen", "sign-up-to-receive-our-updates": "Melden Sie sich an, um Updates von uns zu erhalten", "enter-your-email-address": "Geben Sie Ihre Mail-Adresse ein", - "get-simplex": "Laden Sie sich SimpleX herunter", + "get-simplex": "Laden Sie sich SimpleX herunter <a href=\"/downloads\">desktop app</a>", "learn-more": "Erfahren Sie mehr darüber", "more-info": "Weitere Informationen", "hide-info": "Informationen verbergen", diff --git a/website/langs/en.json b/website/langs/en.json index d9ff80f3e4..434aed8343 100644 --- a/website/langs/en.json +++ b/website/langs/en.json @@ -30,10 +30,12 @@ "hero-p-1": "Other apps have user IDs: Signal, Matrix, Session, Briar, Jami, Cwtch, etc.<br> SimpleX does not, <strong>not even random numbers</strong>.<br> This radically improves your privacy.", "hero-overlay-1-textlink": "Why user IDs are bad for privacy?", "hero-overlay-2-textlink": "How does SimpleX work?", + "hero-overlay-3-textlink": "Security assessment", "hero-2-header": "Make a private connection", "hero-2-header-desc": "The video shows how you connect to your friend via their 1-time QR-code, in person or via a video link. You can also connect by sharing an invitation link.", "hero-overlay-1-title": "How does SimpleX work?", "hero-overlay-2-title": "Why user IDs are bad for privacy?", + "hero-overlay-3-title": "Security assessment", "feature-1-title": "E2E-encrypted messages with markdown and editing", "feature-2-title": "E2E-encrypted<br>images and files", "feature-3-title": "Decentralized secret groups —<br>only users know they exist", @@ -99,6 +101,9 @@ "hero-overlay-card-2-p-2": "They could then correlate this information with the existing public social networks, and determine some real identities.", "hero-overlay-card-2-p-3": "Even with the most private apps that use Tor v3 services, if you talk to two different contacts via the same profile they can prove that they are connected to the same person.", "hero-overlay-card-2-p-4": "SimpleX protects against these attacks by not having any user IDs in its design. And, if you use Incognito mode, you will have a different display name for each contact, avoiding any shared data between them.", + "hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> is a leading security and technology consultancy whose clients include big tech, governmental agencies and major blockchain projects.", + "hero-overlay-card-3-p-2": "Trail of Bits reviewed SimpleX platform cryptography and networking components in November 2022.", + "hero-overlay-card-3-p-3": "Read more in <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">the announcement</a>.", "simplex-network-overlay-card-1-p-1": "<a href='https://en.wikipedia.org/wiki/Peer-to-peer'>P2P</a> messaging protocols and apps have various problems that make them less reliable than SimpleX, more complex to analyse, and vulnerable to several types of attack.", "simplex-network-overlay-card-1-li-1": "P2P networks rely on some variant of <a href='https://en.wikipedia.org/wiki/Distributed_hash_table'>DHT</a> to route messages. DHT designs have to balance delivery guarantee and latency. SimpleX has both better delivery guarantee and lower latency than P2P, because the message can be redundantly passed via several servers in parallel, using the servers chosen by the recipient. In P2P networks the message is passed through <em>O(log N)</em> nodes sequentially, using nodes chosen by the algorithm.", "simplex-network-overlay-card-1-li-2": "SimpleX design, unlike most P2P networks, has no global user identifiers of any kind, even temporary, and only uses temporary pairwise identifiers, providing better anonymity and metadata protection.", @@ -143,7 +148,7 @@ "donate-here-to-help-us": "Donate here to help us", "sign-up-to-receive-our-updates": "Sign up to receive our updates", "enter-your-email-address": "Enter your email address", - "get-simplex": "Get SimpleX", + "get-simplex": "Get SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Why SimpleX is", "unique": "unique", "learn-more": "Learn more", @@ -229,6 +234,7 @@ "docs-dropdown-6": "WebRTC servers", "docs-dropdown-7": "Translate SimpleX Chat", "docs-dropdown-8": "SimpleX Directory Service", + "docs-dropdown-9": "Downloads", "newer-version-of-eng-msg": "There is a newer version of this page in English.", "click-to-see": "Click to see", "menu": "Menu", @@ -243,5 +249,6 @@ "f-droid-org-repo": "F-Droid.org repo", "stable-versions-built-by-f-droid-org": "Stable versions built by F-Droid.org", "releases-to-this-repo-are-done-1-2-days-later": "The releases to this repo are done 1-2 days later", - "f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat and F-Droid.org repositories sign builds with the different keys. To switch, please <a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>export</a> the chat database and re-install the app." + "f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat and F-Droid.org repositories sign builds with the different keys. To switch, please <a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>export</a> the chat database and re-install the app.", + "jobs": "Join team" } diff --git a/website/langs/es.json b/website/langs/es.json index 3f317ae4e6..dfbb95d725 100644 --- a/website/langs/es.json +++ b/website/langs/es.json @@ -137,7 +137,7 @@ "sign-up-to-receive-our-updates": "Suscríbase para recibir nuestras actualizaciones", "donate-here-to-help-us": "Para ayudarnos haga una donación aquí", "enter-your-email-address": "Escriba su dirección de correo electrónico", - "get-simplex": "Obtenga SimpleX", + "get-simplex": "Obtenga SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Por qué SimpleX es", "unique": "único", "learn-more": "Descubra más", diff --git a/website/langs/fi.json b/website/langs/fi.json index eaa774aa9d..963ed42c87 100644 --- a/website/langs/fi.json +++ b/website/langs/fi.json @@ -186,7 +186,7 @@ "donate-here-to-help-us": "Tue meitä täällä lahjoituksilla", "sign-up-to-receive-our-updates": "Tilaa päivityksemme", "enter-your-email-address": "Syötä sähköpostiosoitteesi", - "get-simplex": "Hanki SimpleX", + "get-simplex": "Hanki SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Miksi SimpleX on", "unique": "ainutlaatuinen", "learn-more": "Lue lisää", diff --git a/website/langs/fr.json b/website/langs/fr.json index 5d261d69ab..37dc6d5a14 100644 --- a/website/langs/fr.json +++ b/website/langs/fr.json @@ -143,7 +143,7 @@ "donate-here-to-help-us": "Faites un don ici pour nous aider", "sign-up-to-receive-our-updates": "Inscrivez-vous pour recevoir nos mises à jour", "enter-your-email-address": "Entrez votre adresse e-mail", - "get-simplex": "Obtenir SimpleX", + "get-simplex": "Obtenir SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Pourquoi SimpleX est", "unique": "unique", "learn-more": "En savoir plus", diff --git a/website/langs/it.json b/website/langs/it.json index d7ca0d9a34..fa254e66ef 100644 --- a/website/langs/it.json +++ b/website/langs/it.json @@ -81,7 +81,7 @@ "join": "Unisciti a", "we-invite-you-to-join-the-conversation": "Ti invitiamo a unirti alla conversazione", "enter-your-email-address": "Inserisci il tuo indirizzo email", - "get-simplex": "Ottieni SimpleX", + "get-simplex": "Ottieni SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Perché SimpleX è", "unique": "unico", "learn-more": "Maggiori informazioni", diff --git a/website/langs/ja.json b/website/langs/ja.json index f77f0619ce..b2ac7ecbc0 100644 --- a/website/langs/ja.json +++ b/website/langs/ja.json @@ -53,5 +53,195 @@ "chat-bot-example": "チャットボットの例", "donate": "寄付", "copyright-label": "© 2020-2023 SimpleX | Open-Source Project", - "hero-p-1": "他のアプリにはユーザー ID があります: Signal、Matrix、Session、Briar、Jami、Cwtch など。<br> SimpleX にはありません。<strong>乱数さえもありません</strong>。<br> これにより、プライバシーが大幅に向上します。" + "hero-p-1": "他のアプリにはユーザー ID があります: Signal、Matrix、Session、Briar、Jami、Cwtch など。<br> SimpleX にはありません。<strong>乱数さえもありません</strong>。<br> これにより、プライバシーが大幅に向上します。", + "copy-the-command-below-text": "以下のコマンドをコピーしてチャットで使用します:", + "simplex-private-card-9-point-1": "各メッセージ キューは、異なる送信アドレスと受信アドレスを使用してメッセージを一方向に渡します。", + "simplex-private-card-1-point-2": "各キューのNaCL cryptoboxは、TLSが侵害された場合にメッセージキュー間のトラフィック相関を防止します。", + "contact-hero-p-1": "このページを表示したときに、このリンク内の公開キーとメッセージ キュー アドレスはネットワーク経由で送信されません。 それらはリンク URL のハッシュ フラグメントに含まれています。", + "scan-the-qr-code-with-the-simplex-chat-app": "SimpleX Chat アプリで QR コードをスキャン", + "simplex-private-card-9-point-2": "従来のメッセージ ブローカーと比較して、攻撃ベクトルが減少し、利用可能なメタデータが減少します。", + "feature-7-title": "ポータブルな暗号化データベース — プロファイルを別のデバイスに移動する", + "no-federated": "いいえ - 連合型", + "simplex-unique-overlay-card-3-p-3": "電子メール、XMPP、Matrixなどの連携ネットワークサーバーとは異なり、SimpleXサーバーはユーザーアカウントを保存せず、メッセージの中継のみを行い、双方のプライバシーを保護します。", + "privacy-matters-overlay-card-3-p-2": "最も衝撃的な話の 1 つは、<a href='https://en.wikipedia.org/wiki/Mohamedou_Ould_Slahi' target='_blank'>Mohamedou Ould Salahi</a>の経験であり、彼の回顧録に記述され、『モーリタニア映画』で紹介されました。 彼は裁判も受けずにグアンタナモ収容所に入れられ、それまで10年間ドイツに住んでいたにも関わらず、9/11攻撃への関与の疑いでアフガニスタンの親戚に電話をかけた後、そこで15年間拷問を受けました。", + "signing-key-fingerprint": "署名キーのフィンガープリント (SHA-256)", + "simplex-network-2-desc": "SimpleX リレー サーバーは、ユーザー プロファイル、連絡先、配信されたメッセージを保存せず、相互に接続せず、サーバー ディレクトリもありません。", + "docs-dropdown-5": "ホストXFTPサーバー", + "simplex-private-card-3-point-2": "サーバーのフィンガープリントとチャネル バインディングにより、MITM 攻撃やリプレイ攻撃を防止します。", + "docs-dropdown-3": "チャットのデータベースへのアクセス", + "installing-simplex-chat-to-terminal": "SimpleX チャットをターミナルにインストールする", + "use-this-command": "次のコマンドを使用してください:", + "to-make-a-connection": "接続するには:", + "comparison-section-list-point-6": "P2P は分散されていますが、統合されておらず、単一のネットワークとして動作します", + "simplex-chat-via-f-droid": "F-Droid 経由の SimpleX チャット", + "privacy-matters-overlay-card-1-p-1": "多くの大企業は、あなたの収入を見積もり、本当に必要のない製品を販売し、価格を決定するために、あなたのつながりに関する情報を使用します。", + "privacy-matters-1-overlay-1-title": "プライバシーの保護はコストを削減します", + "simplex-private-card-5-point-1": "SimpleX は、各暗号化レイヤーにコンテンツ パディングを使用して、メッセージ サイズ攻撃を阻止します。", + "privacy-matters-2-overlay-1-linkText": "プライバシーはあなたに力を与えます", + "enter-your-email-address": "Eメールアドレスを入力してください", + "tap-to-close": "タップして閉じる", + "feature-1-title": "マークダウンと編集を使用可能なE2E 暗号化メッセージ", + "comparison-point-4-text": "単一または集中型ネットワーク", + "guide-dropdown-9": "コネクションを作る", + "simplex-unique-1-overlay-1-title": "ID、プロフィール、連絡先、メタデータの完全なプライバシー", + "hero-overlay-card-2-p-4": "SimpleX は、その設計にユーザー ID を持たないことで、これらの攻撃から保護します。 また、シークレット モードを使用すると、連絡先ごとに異なる表示名が付けられ、連絡先間でデータが共有されることがなくなります。", + "privacy-matters-overlay-card-2-p-2": "客観的であり、独立した意思決定を行うには、情報空間を制御する必要があります。 これは、ソーシャル グラフにアクセスできないプライベート コミュニケーション プラットフォームを使用している場合にのみ可能です。", + "hero-overlay-card-2-p-1": "ユーザーが永続的な ID を持っている場合、それがセッション ID などの単なる乱数であっても、プロバイダーや攻撃者がユーザーの接続方法や送信するメッセージの数を監視できるリスクがあります。", + "feature-3-title": "分散型シークレットグループ —<br>ユーザーのみがその存在を知っています", + "simplex-network-overlay-1-title": "P2Pメッセージングプロトコルとの比較", + "comparison-section-list-point-7": "P2Pネットワークには中央当局が存在するか、ネットワーク全体が侵害される可能性がある", + "docs-dropdown-1": "SimpleXプラットフォーム", + "hero-overlay-card-1-p-5": "クライアント デバイスのみがユーザー プロファイル、連絡先、およびグループを保存します。 メッセージは 2 レイヤーのエンドツーエンド暗号化を使用して送信されます。", + "simplex-chat-for-the-terminal": "ターミナル用 SimpleX チャット", + "simplex-network-overlay-card-1-li-3": "P2P は <a href='https://en.wikipedia.org/wiki/Man-in-the-middle_ Attack'>MITM 攻撃</a> 問題を解決せず、既存の実装のほとんどは最初の鍵交換に帯域外メッセージを使用していません 。 SimpleX は、最初のキー交換に帯域外メッセージを使用するか、場合によっては既存の安全で信頼できる接続を使用します。", + "the-instructions--source-code": "ソース コードからダウンロードまたはコンパイルする方法を説明します。", + "simplex-network-section-desc": "Simplex Chat は、P2P とフェデレーション ネットワークの利点を組み合わせて最高のプライバシーを提供します。", + "privacy-matters-section-subheader": "メタデータのプライバシーを保護する — <span class='text-active-blue'>話す相手</span> — 以下のことからあなたを守ります:", + "if-you-already-installed": "すでにインストールしている場合", + "join": "参加", + "privacy-matters-section-header": "プライバシーが<span class='gradient-text'>重要である理由</span>", + "on-this-page": "このページでは", + "privacy-matters-overlay-card-1-p-2": "オンライン小売業者は、収入が低い人ほど急ぎの買い物をする可能性が高いことを知っているため、より高い価格を請求したり、割引を廃止したりすることがあります。", + "simplex-unique-3-overlay-1-title": "データの所有権、管理、セキュリティ", + "protocol-3-text": "P2Pプロトコル", + "simplex-private-card-6-point-2": "これを防ぐために、SimpleX アプリは、アドレスをリンクまたは QR コードとして共有するときに、ワンタイム キーを帯域外で渡します。", + "no": "いいえ", + "contact-hero-header": "SimpleX Chatで接続するためのアドレスを受信しました", + "feature-8-title": "シークレット モード — <br>SimpleX Chat に固有の", + "simplex-private-card-4-point-2": "Tor経由でSimpleXを使用するには、<a href=\"https://guardianproject.info/apps/org.torproject.android/\" target=\"_blank\">Orbotアプリ</a>をインストールし、SOCKS5プロキシを有効にしてください(iOSの場合は<a href=\"https://apps.apple.com/us/app/orbot/id1609461599?platform=iphone\" target=\"_blank\">VPN</a>)。", + "contact-hero-subheader": "スマホ・タブレットのSimpleX ChatアプリでQRコードを読み取ってください。", + "simplex-unique-2-overlay-1-title": "スパムと悪用からの最高の保護", + "simplex-private-6-title": "帯域外の<br>鍵交換", + "join-us-on-GitHub": "GitHubで参加する", + "comparison-section-header": "他のプロトコルとの比較", + "invitation-hero-header": "SimpleX Chatで接続するための使い捨てのリンクを受信しました", + "no-secure": "いいえ - 安全", + "hero-overlay-card-1-p-2": "メッセージを配信するために、SimpleX は、他のすべてのプラットフォームで使用されるユーザー ID の代わりに、接続ごとに個別のメッセージ キューの一時的な匿名ペア識別子を使用します — 長期的な識別子はありません。", + "simplex-network-1-header": "P2Pネットワークとは異なります", + "simplex-private-card-7-point-2": "メッセージが追加、削除、または変更されると、受信者に警告が表示されます。", + "simplex-unique-3-title": "データを管理するのはあなたです", + "no-resilient": "いいえ - 弾力性", + "hide-info": "情報を隠す", + "privacy-matters-overlay-card-3-p-4": "エンドツーエンドで暗号化されたメッセンジャーを使用するだけでは十分ではありません。私たちは皆、個人ネットワークのプライバシーを保護するメッセンジャーを使用する必要があります — 私たちがつながっているのは誰なのか。", + "releases-to-this-repo-are-done-1-2-days-later": "このリポジトリへのリリースは 1 ~ 2 日後に行われます", + "comparison-point-1-text": "グローバル ID が必要", + "comparison-section-list-point-5": "ユーザーのメタデータのプライバシーを保護しない", + "hero-overlay-card-2-p-2": "その後、この情報を既存の公開ソーシャル ネットワークと関連付けて、本当の身元を特定することができます。", + "privacy-matters-overlay-card-1-p-3": "一部の金融会社や保険会社は、ソーシャル グラフを使用して金利や保険料を決定しています。 多くの場合、収入の低い人にはより多くの料金を支払わなければなりません。 —これは、<a href='https://fairbydesign.com/povertypremium/' target='_blank'>「貧困プレミアム」</a> として知られています。", + "comparison-point-3-text": "DNS への依存", + "yes": "はい", + "docs-dropdown-6": "WebRTC サーバー", + "newer-version-of-eng-msg": "このページには英語版の新しいバージョンがあります。", + "install-simplex-app": "SimpleX アプリをインストールする", + "comparison-point-2-text": "MITMの可能性", + "scan-the-qr-code-with-the-simplex-chat-app-description": "このリンクの公開キーとメッセージ キュー アドレスは、このページを表示するときにネットワーク経由で送信されません。<br> これらはリンク URL のハッシュ フラグメントに含まれています。", + "open-simplex-app": "SimpleXアプリを開く", + "see-simplex-chat": "SimpleX チャットを見る", + "comparison-section-list-point-1": "通常は電話番号に基づいていますが、場合によってはユーザー名に基づいています", + "github-repository": "GitHub リポジトリ", + "feature-5-title": "消えるメッセージ", + "connect-in-app": "アプリで接続する", + "simplex-private-card-4-point-1": "IP アドレスを保護するために、Tor またはその他のトランスポート オーバーレイ ネットワーク経由でサーバーにアクセスできます。", + "privacy-matters-3-title": "無実の交際による起訴", + "comparison-point-5-text": "中央コンポーネントまたはその他のネットワーク全体の攻撃", + "click-to-see": "クリックして見る", + "donate-here-to-help-us": "寄付はこちらから", + "simplex-private-1-title": "2レイヤーの<br>エンドツーエンド暗号化", + "privacy-matters-2-overlay-1-title": "プライバシーはあなたに力を与えます", + "simplex-unique-overlay-card-2-p-2": "オプションのユーザー アドレスを使用しても、スパムの連絡先リクエストの送信に使用される可能性がありますが、接続を失うことなく変更または完全に削除できます。", + "simplex-unique-4-overlay-1-title": "完全に分散化されています — ユーザーは SimpleX ネットワークを所有します", + "simplex-network-overlay-card-1-li-5": "すべての既知の P2P ネットワークは、各ノードが検出可能であり、ネットワーク全体が動作するため、<a href='https://en.wikipedia.org/wiki/Sybil_question'>Sybil 攻撃</a>に対して脆弱である可能性があります。 この問題を軽減する既知の対策には、一元化されたコンポーネントか、高価な<a href='https://en.wikipedia.org/wiki/Proof_of_work'>作業証明</a>が必要です。 SimpleX ネットワークにはサーバーの検出機能がなく、断片化されており、複数の分離されたサブネットワークとして動作するため、ネットワーク全体への攻撃は不可能です。", + "simplex-private-2-title": "追加レイヤーの<br>サーバー暗号化", + "hero-overlay-card-1-p-4": "この設計により、ユーザーの情報の漏洩が防止されます' アプリケーションレベルのメタデータ。 プライバシーをさらに向上させ、IP アドレスを保護するために、Tor 経由でメッセージング サーバーに接続できます。", + "f-droid-org-repo": "F-Droid.org リポジトリ", + "simplex-network-2-header": "連合型ネットワークとは異なります", + "simplex-private-3-title": "セキュアな認証付き<br>TLSトランスポート", + "comparison-section-list-point-3": "公開キーまたはその他のグローバルに一意な ID", + "hero-overlay-card-2-p-3": "Tor v3 サービスを使用する最もプライベートなアプリであっても、同じプロファイルを介して 2 人の異なる連絡先と会話すると、それらが同じ人物に接続していることが証明される可能性があります。", + "simplex-private-4-title": "オプション<br>Tor経由のアクセス", + "privacy-matters-1-title": "広告と価格差別", + "hero-overlay-1-title": "SimpleXの仕組みは?", + "stable-versions-built-by-f-droid-org": "F-Droid.org によって構築された安定バージョン", + "contact-hero-p-3": "以下のリンクを使用してアプリをダウンロードしてください。", + "privacy-matters-3-overlay-1-title": "プライバシーはあなたの自由を守ります", + "docs-dropdown-7": "SimpleX チャットを翻訳する", + "simplex-network-1-desc": "すべてのメッセージはサーバー経由で送信され、メタデータのプライバシーが向上し、信頼性の高い非同期メッセージ配信が提供されると同時に、多くが回避されます", + "simplex-chat-repo": "SimpleX チャット リポジトリ", + "simplex-private-card-6-point-1": "多くの通信プラットフォームは、サーバーやネットワーク プロバイダーによる MITM 攻撃に対して脆弱です。", + "privacy-matters-3-overlay-1-linkText": "プライバシーはあなたの自由を守ります", + "simplex-unique-overlay-card-1-p-2": "メッセージを配信するために、SimpleX は一方向メッセージ キューの<a href='https://csrc.nist.gov/glossary/term/Pairwise_Pseudonymous_Identifier'>ペアワイズ匿名アドレス</a>を使用し、受信メッセージと送信メッセージに分けて、通常は異なるサーバーを経由します。 SimpleX を使用することは、<strong>別の「バーナー」 を使用するようなものです。 連絡先ごとにメールまたは電話</strong>を使用できるため、管理に手間がかかりません。", + "simplex-unique-overlay-card-3-p-4": "送受信されるサーバー トラフィックの間に共通の識別子や暗号文はありません。 — 誰かがそれを観察している場合、たとえ TLS が侵害されたとしても、誰が誰と通信しているのかを簡単に判断することはできません。", + "docs-dropdown-2": "Android ファイルへのアクセス", + "get-simplex": "SimpleXを入手する <a href=\"/downloads\">desktop app</a>", + "privacy-matters-overlay-card-3-p-1": "誰もが通信のプライバシーとセキュリティに気を配る必要があります。 たとえ何も隠すものがなかったとしても、無害な会話はあなたを危険にさらす可能性があります。", + "simplex-unique-2-title": "スパムや悪用から<br>保護されています", + "comparison-section-list-point-2": "DNSベースのアドレス", + "stable-and-beta-versions-built-by-developers": "開発者によって構築された安定版とベータ版", + "simplex-network-3-header": "SimpleX ネットワーク", + "comparison-section-list-point-4": "オペレーターのサーバーが侵害された場合。 Signal およびその他の一部のアプリでセキュリティ コードを検証して緩和する", + "simplex-private-card-2-point-1": "TLSが侵害された場合、受信したサーバー・トラフィックと送信したサーバー・トラフィックの相関を防ぐため、受信者に配信するサーバー暗号化レイヤーを追加します。", + "f-droid-page-simplex-chat-repo-section-text": "F-Droid クライアントに追加するには、<span class='hide-on-mobile'>QR コードをスキャンするか</span>、次の URL を使用します:", + "join-the-REDDIT-community": "REDDITコミュニティに参加する", + "simplex-private-card-10-point-2": "ユーザー プロファイル識別子なしでメッセージを配信できるため、他の方法よりも優れたメタデータ プライバシーが提供されます。", + "privacy-matters-2-title": "選挙操作", + "simplex-private-card-5-point-2": "これにより、異なるサイズのメッセージがサーバーやネットワーク オブザーバーには同じように見えます。", + "hero-overlay-card-1-p-1": "多くのユーザーは、<em>SimpleX にユーザー識別子がない場合、メッセージの配信先をどのようにして知ることができるのでしょうか?</em> と質問しました", + "feature-6-title": "E2E暗号化された<br>音声通話とビデオ通話", + "simplex-network-overlay-card-1-li-2": "SimpleX 設計は、ほとんどの P2P ネットワークとは異なり、一時的であってもいかなる種類のグローバル ユーザー識別子も持たず、一時的なペアごとの識別子のみを使用するため、より優れた匿名性とメタデータ保護が提供されます。", + "simplex-unique-4-title": "SimpleX ネットワークを所有", + "privacy-matters-overlay-card-3-p-3": "一般の人が、たとえ「匿名」アカウント経由であっても、オンラインで共有した内容で逮捕されます。<a href='https://www.dailymail.co.uk/news/article-11282263/Moment-police-swoop-house-devout -catholic-mother-malicious-online-posts.html' target='_blank'>たとえ民主主義国家であったとしても</a>。", + "simplex-unique-overlay-card-3-p-2": "エンドツーエンドで暗号化されたメッセージは、SimpleXのリレーサーバーで受信するまで一時的に保持され、その後永久に削除されます。", + "simplex-private-card-7-point-1": "整合性を保証するために、メッセージには連続した番号が付けられ、前のメッセージのハッシュが含まれます。", + "contact-hero-p-2": "SimpleX Chat をまだダウンロードしていませんか?", + "why-simplex-is": "なぜSimpleXなのか", + "simplex-network-section-header": "SimpleX <span class='gradient-text'>ネットワーク</span>", + "simplex-private-10-title": "一時的な匿名のペア識別子", + "privacy-matters-1-overlay-1-linkText": "プライバシーの保護はコストを削減します", + "tap-the-connect-button-in-the-app": "アプリの <span class='text-active-blue'>「接続」</span> ボタンをタップします", + "comparison-section-list-point-4a": "SimpleX リレーは e2e 暗号化を侵害できません。 セキュリティ コードを検証して帯域外チャネルへの攻撃を軽減します", + "unique": "唯一", + "simplex-network-1-overlay-linktext": "P2Pネットワークの問題点", + "no-private": "いいえ - プライベート", + "simplex-unique-1-title": "プライバシーが完全に守られます", + "protocol-2-text": "XMPP、Matrix", + "guide": "ガイド", + "simplex-network-overlay-card-1-li-4": "P2P の実装は、一部のインターネット プロバイダー (<a href='https://en.wikipedia.org/wiki/BitTorrent'>BitTorrent</a> など) によってブロックされる場合があります。 SimpleX はトランスポートに依存しません- WebSocketのような標準的な Web プロトコル上で動作します。", + "hero-overlay-2-title": "ユーザー ID がプライバシーに悪影響を与えるのはなぜですか?", + "docs-dropdown-4": "ホストSMPサーバー", + "feature-4-title": "E2E暗号化された音声メッセージ", + "privacy-matters-overlay-card-2-p-1": "つい最近まで、私たちは主要な選挙が <a href='https://en.wikipedia.org/wiki/Facebook–Cambridge_Analytica_data_scandal' target='_blank'>評判の高いコンサルティング会社</a>によって操作されているのを観察しました。 ソーシャルグラフは私たちの現実世界の見方を歪め、私たちの投票を操作します。", + "privacy-matters-overlay-card-2-p-3": "SimpleX は、設計上ユーザー識別子を持たない最初のプラットフォームであり、この方法で既知の代替手段よりも接続グラフを保護します。", + "learn-more": "さらに詳しく", + "simplex-private-8-title": "メッセージのミキシング<br>相関性を減らす", + "scan-qr-code-from-mobile-app": "モバイルアプリからQRコードをスキャン", + "simplex-private-card-3-point-3": "セッション攻撃を防ぐために、接続の再開は無効になっています。", + "simplex-private-card-10-point-1": "SimpleX は、ユーザー連絡先またはグループ メンバーごとに、一時的な匿名のペアごとのアドレスと資格情報を使用します。", + "more-info": "詳細情報", + "no-decentralized": "いいえ - 分散型", + "protocol-1-text": "Signal、大きなプラットフォーム", + "simplex-network-overlay-card-1-li-6": "P2P ネットワークは、<a href='https://www.usenix.org/conference/woot15/workshop-program/presentation/p2p-file-sharing-hell-exploiting-bittorrent'>DRDoS 攻撃</a>に対して脆弱になる可能性があります。 クライアントがトラフィックを再ブロードキャストして増幅する可能性があり、その結果、ネットワーク全体のサービス拒否が発生する可能性があります。 SimpleX クライアントは既知の接続からのトラフィックのみを中継するため、攻撃者がネットワーク全体のトラフィックを増幅するために使用することはできません。", + "if-you-already-installed-simplex-chat-for-the-terminal": "すでにターミナルに SimpleX Chat をインストールしている場合", + "docs-dropdown-8": "SimpleX ディレクトリ サービス", + "simplex-private-card-1-point-1": "ダブルラチェットプロトコル —<br>完全な前方秘匿性と侵入回復機能を備えたOTRメッセージング。", + "simplex-private-card-8-point-1": "SimpleX サーバーは、低遅延の混合ノードとして機能します — 受信メッセージと送信メッセージの順序が異なります。", + "simplex-unique-overlay-card-2-p-1": "SimpleX プラットフォームには識別子がないため、ワンタイムまたは一時的なユーザー アドレスを QR コードまたはリンクとして共有しない限り、誰もあなたに連絡することはできません。", + "sign-up-to-receive-our-updates": "最新情報を受け取る", + "simplex-private-section-header": "SimpleX を<span class='gradient-text'>プライベート</span>にするもの", + "we-invite-you-to-join-the-conversation": "ぜひ会話にご参加ください", + "feature-2-title": "E2E暗号化された<br>画像とファイル", + "simplex-private-9-title": "単方向<br>メッセージキュー", + "simplex-unique-overlay-card-1-p-3": "この設計により、通信相手のプライバシーが保護され、SimpleX プラットフォーム サーバーや監視者からプライバシーが隠されます。 IP アドレスをサーバーから隠すには、<strong>Tor 経由で SimpleX サーバーに接続</strong>します。", + "simplex-private-7-title": "メッセージの整合性<br>検証", + "privacy-matters-overlay-card-1-p-4": "SimpleX プラットフォームは、他のどのプラットフォームよりも接続のプライバシーを保護し、ソーシャル グラフが企業や組織に利用されることを完全に防ぎます。 SimpleX Chat が提供するサーバーを使用している場合でも、ユーザーの数や接続数はわかりません。", + "hero-overlay-card-1-p-6": "詳細については、<a href='https://github.com/simplex-chat/simplexmq/blob/stable/protocol/overview-tjr.md' target='_blank'>SimpleX ホワイトペーパー</a>をご覧ください。", + "simplex-network-overlay-card-1-p-1": "<a href='https://en.wikipedia.org/wiki/Peer-to-peer'>P2P</a> メッセージング プロトコルとアプリには、SimpleX よりも信頼性が低く、分析がより複雑になるさまざまな問題があり、 いくつかの種類の攻撃に対して脆弱です。", + "simplex-network-overlay-card-1-li-1": "P2P ネットワークは、メッセージをルーティングするために <a href='https://en.wikipedia.org/wiki/Distributed_hash_table'>DHT</a> の一部の変種に依存します。 DHT の設計では、配信保証と遅延のバランスを取る必要があります。 SimpleX は、受信者が選択したサーバーを使用して、メッセージを複数のサーバーを介して並行して冗長的に渡すことができるため、P2P よりも優れた配信保証と低い遅延の両方を備えています。 P2P ネットワークでは、メッセージはアルゴリズムによって選択されたノードを使用して、<em>O(log N)</em> 個のノードを順番に通過します。", + "privacy-matters-section-label": "メッセンジャーがあなたのデータにアクセスできないようにしてください!", + "simplex-unique-overlay-card-3-p-1": "SimpleX Chat は、サポートされているデバイスにエクスポートして転送できる<strong>ポータブル暗号化データベース形式</strong>を使用して、すべてのユーザー データをクライアント デバイスにのみ保存します。", + "simplex-network-3-desc": "サーバーはユーザーを接続するための<span class='text-active-blue'>一方向キュー</span>を提供しますが、ネットワーク接続グラフは表示されません— ユーザーだけがそうします。", + "simplex-private-card-3-point-1": "クライアント/サーバー接続には、強力なアルゴリズムを備えた TLS 1.2/1.3 のみが使用されます。", + "hero-overlay-card-1-p-3": "メッセージの受信に使用するサーバー、連絡先を定義します —メッセージを送信するために使用するサーバー。 すべての会話では 2 つの異なるサーバーが使用される可能性があります。", + "simplex-unique-overlay-card-1-p-1": "他のメッセージング プラットフォームとは異なり、SimpleX には<strong>ユーザーに割り当てられる識別子がありません</strong>。 ユーザーを識別するために、電話番号、ドメインベースのアドレス (電子メールや XMPP など)、ユーザー名、公開キー、さらには乱数にも依存しません。 —我々もSimpleX サーバーを何人が使用しているかはわかりません。", + "f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat と F-Droid.org リポジトリは、異なるキーを使用してビルドに署名します。 切り替えるには、チャット データベースを<a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>エクスポート</a>し、アプリを再インストールしてください。", + "simplex-private-5-title": "何レイヤーもの<br>コンテンツパディング" } diff --git a/website/langs/nl.json b/website/langs/nl.json index 980d16c0ff..02bf471d3b 100644 --- a/website/langs/nl.json +++ b/website/langs/nl.json @@ -58,7 +58,7 @@ "simplex-explained-tab-2-p-1": "Voor elke verbinding gebruikt u twee afzonderlijke berichten wachtrijen om berichten via verschillende servers te verzenden en te ontvangen.", "simplex-explained-tab-2-p-2": "Servers geven berichten slechts in één richting door, zonder een volledig beeld te hebben van het gesprek of de connecties van de gebruiker.", "hero-p-1": "Andere apps hebben gebruikers-ID's: Signal, Matrix, Session, Briar, Jami, Cwtch, enz.<br> SimpleX niet, <strong>zelfs geen willekeurige getallen</strong>.<br> Dit verbetert uw privacy.", - "hero-2-header-desc": "De video laat zien hoe je verbinding maakt met een vriend via een eenmalige QR-code, persoonlijk of via een videolink. U kunt ook verbinding maken door een uitnodigingslink te delen.", + "hero-2-header-desc": "De video laat zien hoe je verbinding maakt met een vriend via een persoonlijk of videolink gedeelde eenmalige QR-code. U kunt ook verbinding maken door een uitnodigingslink te delen.", "hero-header": "Privacy opnieuw gedefinieerd", "feature-7-title": "Portable versleutelde database — verplaats je profiel naar een ander apparaat", "simplex-private-card-1-point-1": "Protocol met double-ratchet -<br>OTR-berichten met perfecte voorwaartse geheimhouding en inbraak herstel.", @@ -194,7 +194,7 @@ "simplex-unique-overlay-card-4-p-3": "Als u overweegt om voor het SimpleX platform te ontwikkelen, bijvoorbeeld de chatbot voor gebruikers van de SimpleX app, of de integratie van de SimpleX Chat bibliotheek in uw mobiele apps, <a href='https://simplex.chat/contact# /?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23MCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%3D' target='_blank'>get in touch</a> for any advice en ondersteuning.", "simplex-unique-card-1-p-1": "SimpleX beschermt de privacy van uw profiel, contacten en metadata en verbergt deze voor SimpleX platformservers en eventuele waarnemers.", "enter-your-email-address": "Voer uw e-mail adres in", - "get-simplex": "Verkrijg SimpleX", + "get-simplex": "Verkrijg SimpleX <a href=\"/downloads\">desktop app</a>", "tap-to-close": "Tik om te sluiten", "contact-hero-header": "Je hebt een adres ontvangen om verbinding te maken met SimpleX Chat", "invitation-hero-header": "Je hebt een eenmalige link ontvangen om verbinding te maken met SimpleX Chat", @@ -204,8 +204,8 @@ "simplex-unique-card-1-p-2": "In tegenstelling tot elk ander bestaand berichten platform, heeft SimpleX geen identificatiecodes toegewezen aan de gebruikers — <strong>zelfs geen willekeurige nummers </strong>.", "comparison-section-list-point-1": "Meestal op basis van een telefoonnummer, in sommige gevallen op gebruikersnamen", "comparison-section-list-point-2": "Op DNS gebaseerde adressen", - "comparison-section-list-point-4": "Als de servers van de operator zijn aangetast", - "comparison-section-list-point-5": "Beschermt de metadata van gebruikers niet", + "comparison-section-list-point-4": "Als de servers van de operator zijn gecompromitteerd. Controleer de beveiligingscode in Signal en enkele andere apps om dit te beperken", + "comparison-section-list-point-5": "Beschermt de privacy van metagegevens van gebruikers niet", "comparison-section-list-point-6": "Hoewel P2P wordt gedistribueerd, zijn ze niet federatief - ze werken als een enkel netwerk", "see-here": "kijk hier", "comparison-section-list-point-7": "P2P netwerken hebben een centrale autoriteit of het hele netwerk kan worden aangetast", @@ -242,5 +242,6 @@ "stable-versions-built-by-f-droid-org": "Stabiele versies gebouwd door F-Droid.org", "releases-to-this-repo-are-done-1-2-days-later": "De releases voor deze repository vinden 1-2 dagen later plaats", "f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat- en F-Droid.org-repository's ondertekenen builds met de verschillende sleutels. Om over te stappen, alstublieft <a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>exporteer</a> de chatdatabase en installeer de app opnieuw.", - "docs-dropdown-8": "SimpleX Directory Service" -} \ No newline at end of file + "docs-dropdown-8": "SimpleX Directory Service", + "comparison-section-list-point-4a": "SimpleX relais kunnen de e2e-versleuteling niet in gevaar brengen. Controleer de beveiligingscode om aanvallen op out-of-band kanalen te beperken" +} diff --git a/website/langs/pl.json b/website/langs/pl.json index 0ca0363aeb..f9b9936848 100644 --- a/website/langs/pl.json +++ b/website/langs/pl.json @@ -98,7 +98,7 @@ "no-federated": "Nie - sfederowany", "comparison-section-list-point-1": "Zazwyczaj na podstawie numeru telefonu, w niektórych przypadkach na podstawie nazwy użytkownika", "comparison-section-list-point-2": "Adresy oparte na DNS", - "comparison-section-list-point-5": "Nie chroni metadanych użytkowników", + "comparison-section-list-point-5": "Nie chroni prywatności metadanych użytkowników", "see-here": "zobacz tutaj", "simplex-unique-1-title": "Masz pełną prywatność", "hero-overlay-card-1-p-3": "Ty określasz, którego serwera (serwerów) użyć do odbierania wiadomości, Twoje kontakty — serwery, których używasz do wysyłania do nich wiadomości. Każda rozmowa prawdopodobnie będzie korzystać z dwóch różnych serwerów.", @@ -159,7 +159,7 @@ "simplex-unique-card-4-p-2": "Możesz <strong>używać SimpleX z własnymi serwerami</strong> lub z serwerami dostarczonymi przez nas — i nadal łączyć się z dowolnym użytkownikiem.", "we-invite-you-to-join-the-conversation": "Zapraszamy do udziału w rozmowie", "enter-your-email-address": "Wpisz swój adres e-mail", - "get-simplex": "Pobierz SimpleX", + "get-simplex": "Pobierz SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Dlaczego SimpleX jest", "join": "Dołącz do", "join-us-on-GitHub": "Dołącz do nas na GitHubie", @@ -208,7 +208,7 @@ "protocol-2-text": "XMPP, Matrix", "protocol-3-text": "Protokoły sieci P2P", "comparison-section-list-point-6": "Podczas gdy sieci P2P są rozproszone, nie są sfederowane - działają jako jedna sieć", - "comparison-section-list-point-4": "Jeśli bezpieczeństwo serwerów operatora zostało naruszone", + "comparison-section-list-point-4": "Jeśli bezpieczeństwo serwerów operatora zostało naruszone. Zweryfikuj kody bezpieczeństwa w Signalu lub innej aplikacji aby to złagodzić", "comparison-section-list-point-7": "Sieci P2P albo mają centralny organ, albo cała sieć może zostać skompromitowana", "guide-dropdown-1": "Szybki start", "guide-dropdown-2": "Wysyłanie wiadomości", @@ -242,5 +242,6 @@ "signing-key-fingerprint": "Odcisk klucza podpisu (SHA-256)", "f-droid-org-repo": "Repo F-Droid.org", "stable-versions-built-by-f-droid-org": "Wersje stabilne zbudowane przez F-Droid.org", - "releases-to-this-repo-are-done-1-2-days-later": "Wydania na tym repo są 1-2 dni później" + "releases-to-this-repo-are-done-1-2-days-later": "Wydania na tym repo są 1-2 dni później", + "comparison-section-list-point-4a": "Przekaźniki SimpleX nie mogą skompromitować szyfrowania e2e. Zweryfikuj kody bezpieczeństwa aby złagodzić atak na kanał pozapasmowy" } diff --git a/website/langs/pt_BR.json b/website/langs/pt_BR.json index 083f4942ec..278d54c43a 100644 --- a/website/langs/pt_BR.json +++ b/website/langs/pt_BR.json @@ -146,7 +146,7 @@ "donate-here-to-help-us": "Doe aqui para nos ajudar", "sign-up-to-receive-our-updates": "Inscreva-se para receber nossas atualizações", "enter-your-email-address": "Digite seu endereço de e-mail", - "get-simplex": "Obtenha o SimpleX", + "get-simplex": "Obtenha o SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Por que o SimpleX é", "unique": "único", "learn-more": "Saiba mais", diff --git a/website/langs/uk.json b/website/langs/uk.json index eae508ed47..6a48cc5640 100644 --- a/website/langs/uk.json +++ b/website/langs/uk.json @@ -173,7 +173,7 @@ "donate-here-to-help-us": "Пожертвуйте тут, щоб допомогти нам", "sign-up-to-receive-our-updates": "Підпишіться на наші оновлення", "enter-your-email-address": "Введіть адресу вашої електронної пошти", - "get-simplex": "Отримати SimpleX", + "get-simplex": "Отримати SimpleX <a href=\"/downloads\">desktop app</a>", "why-simplex-is": "Чому SimpleX це", "unique": "унікальний", "learn-more": "Дізнайтеся більше", diff --git a/website/langs/zh_Hans.json b/website/langs/zh_Hans.json index 4a1bbcf2d3..c327e160be 100644 --- a/website/langs/zh_Hans.json +++ b/website/langs/zh_Hans.json @@ -26,7 +26,7 @@ "simplex-unique-overlay-card-3-p-4": "发送和接收的服务器流量之间没有共同的标识符或密文—— 如果有人在观察它,他们也无法轻易确定谁与谁通信,即使 TLS 受到威胁。", "simplex-unique-card-4-p-1": "SimpleX 网络是完全去中心化的,并且独立于任何加密货币或除互联网以外的任何其他平台。", "join": "加入", - "get-simplex": "获取 SimpleX", + "get-simplex": "获取 SimpleX <a href=\"/downloads\">desktop app</a>", "hide-info": "隐藏信息", "contact-hero-header": "您收到了一个用于连接 SimpleX Chat 的地址", "contact-hero-p-2": "还没有下载 SimpleX Chat 吗?", @@ -194,7 +194,7 @@ "no-resilient": "不需要 - 有抗御力", "no-decentralized": "不需要 - 去中心化的", "comparison-section-list-point-3": "公钥或其他一些全球唯一的 ID", - "comparison-section-list-point-4": "如果运营商的服务器受到威胁", + "comparison-section-list-point-4": "如果运营商的服务器受到威胁。 验证 Signal 和其他一些应用程序中的安全代码以缓解该问题", "comparison-section-list-point-1": "通常基于电话号码,在某些情况下基于用户名", "comparison-section-list-point-2": "基于 DNS 的地址", "comparison-section-list-point-6": "P2P 是分布式的,而非联邦式的 - 它们作为单个网络运行", @@ -232,5 +232,16 @@ "guide-dropdown-9": "建立连接", "back-to-top": "回到页首", "on-this-page": "在此页面上", - "glossary": "术语表" + "glossary": "术语表", + "signing-key-fingerprint": "签名密钥指纹 (SHA-256)", + "simplex-chat-via-f-droid": "通过 F-Droid 下载 SimpleX", + "releases-to-this-repo-are-done-1-2-days-later": "此存储库的版本将延迟 1-2 天发布", + "f-droid-org-repo": "F-Droid.org 存储库", + "stable-versions-built-by-f-droid-org": "由 F-Droid.org 构建的稳定版本", + "simplex-chat-repo": "SimpleX 存储库", + "stable-and-beta-versions-built-by-developers": "开发人员构建的稳定版和测试版", + "f-droid-page-simplex-chat-repo-section-text": "要将其添加到您的 F-Droid 客户端,请<span class='hide-on-mobile'>扫描二维码或</span>使用以下 URL:", + "comparison-section-list-point-4a": "SimpleX 中继无法破坏 e2e 加密。 验证安全代码以减轻对带外通道的攻击", + "docs-dropdown-8": "SimpleX 目录服务", + "f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat 和 F-Droid.org 存储库使用不同的密钥对构建进行签名。 如需切换,请<a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>导出</a>聊天数据库并重新安装应用。" } diff --git a/website/src/_data/docs_dropdown.json b/website/src/_data/docs_dropdown.json index cdcb595086..a8c6e634b2 100644 --- a/website/src/_data/docs_dropdown.json +++ b/website/src/_data/docs_dropdown.json @@ -31,6 +31,10 @@ { "title": "docs-dropdown-7", "url": "/docs/translations.html" + }, + { + "title": "docs-dropdown-9", + "url": "/downloads/" } ] } \ No newline at end of file diff --git a/website/src/_data/docs_sidebar.json b/website/src/_data/docs_sidebar.json index a45f69fb06..fcd980121d 100644 --- a/website/src/_data/docs_sidebar.json +++ b/website/src/_data/docs_sidebar.json @@ -26,7 +26,8 @@ "SERVER.md", "TRANSLATIONS.md", "WEBRTC.md", - "XFTP-SERVER.md" + "XFTP-SERVER.md", + "DOWNLOADS.md" ] }, { diff --git a/website/src/_data/hero_overlays.json b/website/src/_data/hero_overlays.json index d50ba0db68..7388994459 100644 --- a/website/src/_data/hero_overlays.json +++ b/website/src/_data/hero_overlays.json @@ -23,6 +23,18 @@ "showImage": true, "contentBody": "overlay_content/hero/card_2.html" } + }, + { + "id": 3, + "imgLight": "/img/trail-of-bits-light.png", + "imgDark": "/img/trail-of-bits-dark.png", + "overlayContent": { + "overlayId": "security-assessment", + "overlayScrollTo": "", + "title": "hero-overlay-3-title", + "showImage": true, + "contentBody": "overlay_content/hero/card_3.html" + } } ] } \ No newline at end of file diff --git a/website/src/_data/languages.json b/website/src/_data/languages.json index 3629172642..0ac05063cc 100644 --- a/website/src/_data/languages.json +++ b/website/src/_data/languages.json @@ -45,6 +45,12 @@ "flag": "/img/flags/it.svg", "enabled": true }, + { + "label": "ja", + "name": "日本語", + "flag": "/img/flags/jp.svg", + "enabled": true + }, { "label": "nl", "name": "Nederlands", diff --git a/website/src/_includes/hero.html b/website/src/_includes/hero.html index 161e0da4a8..c0e2b3f30b 100644 --- a/website/src/_includes/hero.html +++ b/website/src/_includes/hero.html @@ -17,6 +17,8 @@ {{ overlay(hero_overlays.sections[1], lang) }} <a href="javascript:void(0)" data-show-overlay="{{ hero_overlays.sections[0].overlayContent.overlayId }}" class="open-overlay-btn underline text-primary-light dark:text-primary-dark block text-center xl:text-left xl:rtl:text-right text-[14px] xl:text-[16px] leading-[34px] underline-offset-2">{{ "hero-overlay-2-textlink" | i18n({}, lang ) | safe }}</a> {{ overlay(hero_overlays.sections[0], lang) }} + <a href="javascript:void(0)" data-show-overlay="{{ hero_overlays.sections[2].overlayContent.overlayId }}" class="open-overlay-btn underline text-primary-light dark:text-primary-dark block text-center xl:text-left xl:rtl:text-right text-[14px] xl:text-[16px] leading-[34px] underline-offset-2">{{ "hero-overlay-3-textlink" | i18n({}, lang ) | safe }}</a> + {{ overlay(hero_overlays.sections[2], lang) }} </article> <article class="w-full xl:max-w-[600px]"> diff --git a/website/src/_includes/layouts/jobs.html b/website/src/_includes/layouts/jobs.html new file mode 100644 index 0000000000..6a68c0795f --- /dev/null +++ b/website/src/_includes/layouts/jobs.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html lang="{{ page.url | getlang }}" + {% for language in languages.languages %} + {% if language.label == page.url | getlang %} + dir="{{ "rtl" if language.rtl else "ltr" }}" + {% endif %} + {% endfor %}> + + <head> + <meta charset="UTF-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>{{ title }} + + + + + + + + + + + +
+ {% include "navbar.html" %} +
+ +
+
+
{{ content | wrapH3s(page) | safe }}
+
+
+ + {% include "footer.html" %} + + + + \ No newline at end of file diff --git a/website/src/_includes/navbar.html b/website/src/_includes/navbar.html index beb3139c2b..55836bd576 100644 --- a/website/src/_includes/navbar.html +++ b/website/src/_includes/navbar.html @@ -100,6 +100,14 @@
+ + +
+