mobile: onboarding (#618)

* mobile: onboarding

* ios onboarding: create profile and make connection

* how SimpleX works

* connect via link

* remove separate view for connecting via link, fix bugs

* remove unused files

* fix help on small screens, update how it works page

* layout

* add About to settings, tidy up

* rename function

* update layout

* translations

* translation corrections

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>

* correction

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>

* corrections

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>

* fix translations/layout

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny Poberezkin
2022-05-09 09:52:09 +01:00
committed by GitHub
parent 3d2315a117
commit dcaefd6566
23 changed files with 1170 additions and 407 deletions

View File

@@ -13,27 +13,22 @@ struct ContentView: View {
@State private var showNotificationAlert = false
var body: some View {
if let user = chatModel.currentUser {
ChatListView(user: user)
.onAppear {
do {
try apiStartChat()
try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path)
chatModel.userAddress = try apiGetUserAddress()
chatModel.userSMPServers = try getUserSMPServers()
chatModel.chats = try apiGetChats()
} catch {
fatalError("Failed to start or load chats: \(error)")
ZStack {
if let step = chatModel.onboardingStage {
if case .onboardingComplete = step,
let user = chatModel.currentUser {
ChatListView(user: user)
.onAppear {
NtfManager.shared.requestAuthorization(onDeny: {
alertManager.showAlert(notificationAlert())
})
}
ChatReceiver.shared.start()
NtfManager.shared.requestAuthorization(onDeny: {
alertManager.showAlert(notificationAlert())
})
} else {
OnboardingView(onboarding: step)
}
.alert(isPresented: $alertManager.presentAlert) { alertManager.alertView! }
} else {
WelcomeView()
}
}
.alert(isPresented: $alertManager.presentAlert) { alertManager.alertView! }
}
func notificationAlert() -> Alert {
@@ -50,6 +45,37 @@ struct ContentView: View {
}
}
func connectViaUrl() {
let m = ChatModel.shared
if let url = m.appOpenUrl {
m.appOpenUrl = nil
AlertManager.shared.showAlert(connectViaUrlAlert(url))
}
}
func connectViaUrlAlert(_ url: URL) -> Alert {
var path = url.path
logger.debug("ChatListView.connectViaUrlAlert 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)")
let title: LocalizedStringKey
if case .contact = action { title = "Connect via contact link?" }
else { title = "Connect via one-time link?" }
return Alert(
title: Text(title),
message: Text("Your profile will be sent to the contact that you received this link from"),
primaryButton: .default(Text("Connect")) {
connectViaLink(link)
},
secondaryButton: .cancel()
)
} else {
return Alert(title: Text("Error: URL is invalid"))
}
}
final class AlertManager: ObservableObject {
static let shared = AlertManager()
@Published var presentAlert = false

View File

@@ -11,6 +11,7 @@ import Combine
import SwiftUI
final class ChatModel: ObservableObject {
@Published var onboardingStage: OnboardingStage?
@Published var currentUser: User?
// list of chat "previews"
@Published var chats: [Chat] = []

View File

@@ -10,6 +10,7 @@ import Foundation
import UIKit
import Dispatch
import BackgroundTasks
import SwiftUI
private var chatController: chat_ctrl?
@@ -261,6 +262,16 @@ func apiConnect(connReq: String) async throws -> ConnReqType? {
message: "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."
)
return nil
case let .chatCmdError(.errorAgent(.INTERNAL(internalErr))):
if internalErr == "SEUniqueID" {
am.showAlertMsg(
title: "Already connected?",
message: "It seems like you are already connected via this link. If it is not the case, there was an error (\(responseError(r)))."
)
return nil
} else {
throw r
}
default: throw r
}
}
@@ -424,13 +435,40 @@ private func sendCommandOkResp(_ cmd: ChatCommand) async throws {
}
func initializeChat() {
logger.debug("initializeChat")
do {
ChatModel.shared.currentUser = try apiGetActiveUser()
let m = ChatModel.shared
m.currentUser = try apiGetActiveUser()
if m.currentUser == nil {
m.onboardingStage = .step1_SimpleXInfo
} else {
startChat()
}
} catch {
fatalError("Failed to initialize chat controller or database: \(error)")
}
}
func startChat() {
logger.debug("startChat")
do {
let m = ChatModel.shared
try apiStartChat()
try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path)
m.userAddress = try apiGetUserAddress()
m.userSMPServers = try getUserSMPServers()
m.chats = try apiGetChats()
withAnimation {
m.onboardingStage = m.chats.isEmpty
? .step3_MakeConnection
: .onboardingComplete
}
ChatReceiver.shared.start()
} catch {
fatalError("Failed to start or load chats: \(error)")
}
}
class ChatReceiver {
private var receiveLoop: Task<Void, Never>?
private var receiveMessages = true

View File

@@ -28,30 +28,19 @@ struct ChatHelp: View {
}
VStack(alignment: .leading, spacing: 10) {
Text("To start a new chat")
Text("To make a new connection")
.font(.title2)
.fontWeight(.bold)
HStack(spacing: 8) {
Text("Tap button ")
NewChatButton()
Text("above, then:")
Text("above, then choose:")
}
Text("**Add new contact**: to create your one-time QR Code for your contact.")
Text("**Scan QR code**: to connect to your contact who shows QR code to you.")
}
.padding(.top, 24)
VStack(alignment: .leading, spacing: 10) {
Text("To connect via link")
.font(.title2)
.fontWeight(.bold)
Text("If you received SimpleX Chat invitation link you can open it in your browser:")
Text("💻 desktop: scan displayed QR code from the app, via **Scan QR code**.")
Text("📱 mobile: tap **Open in mobile app**, then tap **Connect** in the app.")
Text("**Create link / QR code** for your contact to use.")
Text("**Paste received link** or open it in the browser and tap **Open in mobile app**.")
Text("**Scan QR code**: to connect to your contact in person or via video call.")
}
.padding(.top, 24)
}

View File

@@ -21,13 +21,9 @@ struct ChatListView: View {
var body: some View {
let v = NavigationView {
List {
if chatModel.chats.isEmpty {
ChatHelp(showSettings: $showSettings)
} else {
ForEach(filteredChats()) { chat in
ChatListNavLink(chat: chat, showCallView: $showCallView)
.padding(.trailing, -16)
}
ForEach(filteredChats()) { chat in
ChatListNavLink(chat: chat, showCallView: $showCallView)
.padding(.trailing, -16)
}
}
.onChange(of: chatModel.chatId) { _ in
@@ -36,15 +32,15 @@ struct ChatListView: View {
chatModel.popChat(chatId)
}
}
.onChange(of: chatModel.appOpenUrl) { _ in
if let url = chatModel.appOpenUrl {
chatModel.appOpenUrl = nil
AlertManager.shared.showAlert(connectViaUrlAlert(url))
}
.onChange(of: chatModel.chats.isEmpty) { empty in
if !empty { return }
withAnimation { chatModel.onboardingStage = .step3_MakeConnection }
}
.onChange(of: chatModel.appOpenUrl) { _ in connectViaUrl() }
.onAppear() { connectViaUrl() }
.offset(x: -8)
.listStyle(.plain)
.navigationTitle(chatModel.chats.isEmpty ? "Welcome \(user.displayName)!" : "Your chats")
.navigationTitle("Your chats")
.navigationBarTitleDisplayMode(chatModel.chats.count > 8 ? .inline : .large)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
@@ -101,29 +97,6 @@ struct ChatListView: View {
}
}
private func connectViaUrlAlert(_ url: URL) -> Alert {
var path = url.path
logger.debug("ChatListView.connectViaUrlAlert 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)")
let title: LocalizedStringKey
if case .contact = action { title = "Connect via contact link?" }
else { title = "Connect via one-time link?" }
return Alert(
title: Text(title),
message: Text("Your profile will be sent to the contact that you received this link from"),
primaryButton: .default(Text("Connect")) {
connectViaLink(link)
},
secondaryButton: .cancel()
)
} else {
return Alert(title: Text("Error: URL is invalid"))
}
}
private func answerCallAlert(_ contact: Contact, _ invitation: CallInvitation) {
AlertManager.shared.showAlert(Alert(
title: Text("Incoming call"),

View File

@@ -12,26 +12,25 @@ import CoreImage.CIFilterBuiltins
struct AddContactView: View {
var connReqInvitation: String
var body: some View {
VStack {
Text("Add contact")
VStack(alignment: .leading) {
Text("One-time invitation link")
.font(.title)
.padding(.vertical)
Text("Your contact can scan it from the app")
.padding(.bottom)
Text("Show QR code to your contact\nto scan from the app")
.font(.title2)
.multilineTextAlignment(.center)
QRCode(uri: connReqInvitation)
.padding()
Text("If you cannot meet in person, you can **show QR code in the video call**, or you can share the invitation link via any other channel.")
.font(.subheadline)
.multilineTextAlignment(.center)
.padding(.horizontal)
.padding(.bottom)
Text("If you can't meet in person, **show QR code in the video call**, or share the link.")
.padding(.bottom)
Button {
showShareSheet(items: [connReqInvitation])
} label: {
Label("Share invitation link", systemImage: "square.and.arrow.up")
}
.padding()
.frame(maxWidth: .infinity, alignment: .center)
}
.padding()
.frame(maxHeight: .infinity, alignment: .top)
}
}

View File

@@ -8,12 +8,18 @@
import SwiftUI
enum NewChatAction: Identifiable {
case createLink
case pasteLink
case scanQRCode
var id: NewChatAction { get { self } }
}
struct NewChatButton: View {
@State private var showAddChat = false
@State private var addContact = false
@State private var connReqInvitation: String = ""
@State private var scanToConnect = false
@State private var pasteToConnect = false
@State private var connReq: String = ""
@State private var actionSheet: NewChatAction?
var body: some View {
Button { showAddChat = true } label: {
@@ -21,24 +27,22 @@ struct NewChatButton: View {
}
.confirmationDialog("Add contact to start a new chat", isPresented: $showAddChat, titleVisibility: .visible) {
Button("Create link / QR code") { addContactAction() }
Button("Paste received link") { pasteToConnect = true }
Button("Scan QR code") { scanToConnect = true }
Button("Paste received link") { actionSheet = .pasteLink }
Button("Scan QR code") { actionSheet = .scanQRCode }
}
.sheet(item: $actionSheet) { sheet in
switch sheet {
case .createLink: AddContactView(connReqInvitation: connReq)
case .pasteLink: PasteToConnectView(openedSheet: $actionSheet)
case .scanQRCode: ScanToConnectView(openedSheet: $actionSheet)
}
}
.sheet(isPresented: $addContact, content: {
AddContactView(connReqInvitation: connReqInvitation)
})
.sheet(isPresented: $scanToConnect, content: {
ScanToConnectView(openedSheet: $scanToConnect)
})
.sheet(isPresented: $pasteToConnect, content: {
PasteToConnectView(openedSheet: $pasteToConnect)
})
}
func addContactAction() {
do {
connReqInvitation = try apiAddContact()
addContact = true
connReq = try apiAddContact()
actionSheet = .createLink
} catch {
DispatchQueue.global().async {
connectionErrorAlert(error)
@@ -53,12 +57,12 @@ enum ConnReqType: Equatable {
case invitation
}
func connectViaLink(_ connectionLink: String, _ openedSheet: Binding<Bool>? = nil) {
func connectViaLink(_ connectionLink: String, _ openedSheet: Binding<NewChatAction?>? = nil) {
Task {
do {
let res = try await apiConnect(connReq: connectionLink)
DispatchQueue.main.async {
openedSheet?.wrappedValue = false
openedSheet?.wrappedValue = nil
if let connReqType = res {
connectionReqSentAlert(connReqType)
}
@@ -66,7 +70,7 @@ func connectViaLink(_ connectionLink: String, _ openedSheet: Binding<Bool>? = ni
} catch {
logger.error("connectViaLink apiConnect error: \(responseError(error))")
DispatchQueue.main.async {
openedSheet?.wrappedValue = false
openedSheet?.wrappedValue = nil
connectionErrorAlert(error)
}
}
@@ -74,7 +78,7 @@ func connectViaLink(_ connectionLink: String, _ openedSheet: Binding<Bool>? = ni
}
func connectionErrorAlert(_ error: Error) {
AlertManager.shared.showAlertMsg(title: "Connection error", message: "Error: \(error.localizedDescription)")
AlertManager.shared.showAlertMsg(title: "Connection error", message: "Error: \(responseError(error))")
}
func connectionReqSentAlert(_ type: ConnReqType) {

View File

@@ -9,23 +9,19 @@
import SwiftUI
struct PasteToConnectView: View {
@Binding var openedSheet: Bool
@Binding var openedSheet: NewChatAction?
@State private var connectionLink: String = ""
var body: some View {
VStack(alignment: .leading) {
Text("Connect via link")
.font(.title)
.padding([.bottom])
.frame(maxWidth: .infinity, alignment: .center)
.padding(.vertical)
Text("Paste the link you received into the box below to connect with your contact.")
.multilineTextAlignment(.leading)
Text("Your profile will be sent to the contact that you received this link from")
.multilineTextAlignment(.leading)
.padding(.bottom)
TextEditor(text: $connectionLink)
.onSubmit(connect)
.font(.body)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.allowsTightening(false)
@@ -60,9 +56,9 @@ struct PasteToConnectView: View {
.padding(.bottom)
Text("You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button")
.multilineTextAlignment(.leading)
}
.padding()
.frame(maxHeight: .infinity, alignment: .top)
}
private func connect() {
@@ -72,7 +68,7 @@ struct PasteToConnectView: View {
struct PasteToConnectView_Previews: PreviewProvider {
static var previews: some View {
@State var openedSheet: Bool = true
@State var openedSheet: NewChatAction? = nil
return PasteToConnectView(openedSheet: $openedSheet)
}
}

View File

@@ -10,28 +10,26 @@ import SwiftUI
import CodeScanner
struct ScanToConnectView: View {
@Binding var openedSheet: Bool
@Binding var openedSheet: NewChatAction?
var body: some View {
VStack {
VStack(alignment: .leading) {
Text("Scan QR code")
.font(.title)
.padding(.bottom)
.padding(.vertical)
Text("Your chat profile will be sent to your contact")
.font(.title2)
.multilineTextAlignment(.center)
.padding()
.padding(.bottom)
ZStack {
CodeScannerView(codeTypes: [.qr], completion: processQRCode)
.aspectRatio(1, contentMode: .fit)
.border(.gray)
}
.padding(12)
.padding(.bottom)
Text("If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link.")
.font(.subheadline)
.multilineTextAlignment(.center)
.padding(.horizontal)
.padding(.bottom)
}
.padding()
.frame(maxHeight: .infinity, alignment: .top)
}
func processQRCode(_ resp: Result<ScanResult, ScanError>) {
@@ -40,14 +38,14 @@ struct ScanToConnectView: View {
Task { connectViaLink(r.string, $openedSheet) }
case let .failure(e):
logger.error("ConnectContactView.processQRCode QR code error: \(e.localizedDescription)")
openedSheet = false
openedSheet = nil
}
}
}
struct ConnectContactView_Previews: PreviewProvider {
static var previews: some View {
@State var openedSheet: Bool = true
@State var openedSheet: NewChatAction? = nil
return ScanToConnectView(openedSheet: $openedSheet)
}
}

View File

@@ -0,0 +1,124 @@
//
// CreateProfile.swift
// SimpleX (iOS)
//
// Created by Evgeny on 07/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct CreateProfile: View {
@EnvironmentObject var m: ChatModel
@State private var displayName: String = ""
@State private var fullName: String = ""
@FocusState private var focusDisplayName
@FocusState private var focusFullName
var body: some View {
GeometryReader { g in
VStack(alignment: .leading) {
Text("Create your profile")
.font(.largeTitle)
.padding(.bottom, 4)
Text("Your profile, contacts and delivered messages are stored on your device.")
.padding(.bottom, 4)
Text("The profile is only shared with your contacts.")
.padding(.bottom)
ZStack(alignment: .topLeading) {
if !validDisplayName(displayName) {
Image(systemName: "exclamationmark.circle")
.foregroundColor(.red)
.padding(.top, 4)
}
textField("Display name", text: $displayName)
.focused($focusDisplayName)
.submitLabel(.next)
.onSubmit {
if canCreateProfile() { focusFullName = true }
else { focusDisplayName = true }
}
}
textField("Full name (optional)", text: $fullName)
.focused($focusFullName)
.submitLabel(.go)
.onSubmit {
if canCreateProfile() { createProfile() }
else { focusFullName = true }
}
Spacer()
HStack {
Button {
hideKeyboard()
withAnimation { m.onboardingStage = .step1_SimpleXInfo }
} label: {
HStack {
Image(systemName: "lessthan")
Text("About SimpleX")
}
}
Spacer()
HStack {
Button {
createProfile()
} label: {
Text("Create")
Image(systemName: "greaterthan")
}
.disabled(!canCreateProfile())
}
}
}
.onAppear() {
focusDisplayName = true
}
}
.padding()
}
func textField(_ placeholder: LocalizedStringKey, text: Binding<String>) -> some View {
TextField(placeholder, text: text)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.padding(.leading, 28)
.padding(.bottom)
}
func createProfile() {
hideKeyboard()
let profile = Profile(
displayName: displayName,
fullName: fullName
)
do {
m.currentUser = try apiCreateActiveUser(profile)
startChat()
withAnimation { m.onboardingStage = .step3_MakeConnection }
} catch {
fatalError("Failed to create user: \(error)")
}
}
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
func validDisplayName(_ name: String) -> Bool {
name.firstIndex(of: " ") == nil
}
func canCreateProfile() -> Bool {
displayName != "" && validDisplayName(displayName)
}
}
struct CreateProfile_Previews: PreviewProvider {
static var previews: some View {
CreateProfile()
}
}

View File

@@ -0,0 +1,54 @@
//
// HowItWorks.swift
// SimpleX (iOS)
//
// Created by Evgeny on 08/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct HowItWorks: View {
@EnvironmentObject var m: ChatModel
var onboarding: Bool
var body: some View {
VStack(alignment: .leading) {
Text("How SimpleX works")
.font(.largeTitle)
.padding(.vertical)
ScrollView {
VStack(alignment: .leading) {
Group {
Text("Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*")
Text("To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts.")
Text("You control through which server(s) **to receive** the messages, your contacts the servers you use to message them.")
Text("Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**.")
if onboarding {
Text("Read more in our GitHub repository.")
} else {
Text("Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme).")
}
}
.padding(.bottom)
}
}
Spacer()
if onboarding {
OnboardingActionButton()
.padding(.bottom, 8)
}
}
.lineLimit(10)
.padding()
.frame(maxHeight: .infinity, alignment: .top)
}
}
struct HowItWorks_Previews: PreviewProvider {
static var previews: some View {
HowItWorks(onboarding: true)
}
}

View File

@@ -0,0 +1,146 @@
//
// MakeConnection.swift
// SimpleX (iOS)
//
// Created by Evgeny on 07/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct MakeConnection: View {
@EnvironmentObject var m: ChatModel
@State private var connReq: String = ""
@State private var actionSheet: NewChatAction?
var body: some View {
VStack(alignment: .leading) {
SettingsButton().padding(.bottom, 1)
if let user = m.currentUser {
Text("Welcome \(user.displayName)!")
.font(.largeTitle)
.multilineTextAlignment(.leading)
.padding(.bottom, 8)
} else {
Text("Make a private connection")
.font(.largeTitle)
.padding(.bottom)
}
ScrollView {
VStack(alignment: .leading) {
Text("To make your first private connection, choose **one of the following**:")
.padding(.bottom)
actionRow(
icon: "qrcode",
title: "Create 1-time link / QR code",
text: "It's secure to share - only one contact can use it."
) { addContactAction() }
actionRow(
icon: "link",
title: "Paste the link you received",
text: "Or open the link in the browser and tap **Open in mobile**."
) { actionSheet = .pasteLink }
actionRow(
icon: "qrcode.viewfinder",
title: "Scan contact's QR code",
text: "In person or via a video call the most secure way to connect."
) { actionSheet = .scanQRCode }
Text("or")
.padding(.bottom)
.frame(maxWidth: .infinity)
actionRow(
icon: "number",
title: "Connect with the developers",
text: "To ask any questions and to receive SimpleX Chat updates."
) {
DispatchQueue.main.async {
UIApplication.shared.open(simplexTeamURL)
}
}
}
}
Spacer()
Button {
withAnimation { m.onboardingStage = .step1_SimpleXInfo }
} label: {
HStack {
Image(systemName: "lessthan")
Text("About SimpleX")
}
}
.padding(.bottom, 8)
.padding(.bottom)
}
.sheet(item: $actionSheet) { sheet in
switch sheet {
case .createLink: AddContactView(connReqInvitation: connReq)
case .pasteLink: PasteToConnectView(openedSheet: $actionSheet)
case .scanQRCode: ScanToConnectView(openedSheet: $actionSheet)
}
}
.onChange(of: actionSheet) { _ in checkOnboarding() }
.onChange(of: m.chats.isEmpty) { _ in checkOnboarding() }
.onChange(of: m.appOpenUrl) { _ in connectViaUrl() }
.onAppear() { connectViaUrl() }
.padding(.horizontal)
.frame(maxHeight: .infinity, alignment: .top)
}
private func checkOnboarding() {
if actionSheet == nil && !m.chats.isEmpty {
withAnimation { m.onboardingStage = .onboardingComplete }
}
}
private func addContactAction() {
do {
connReq = try apiAddContact()
actionSheet = .createLink
} catch {
DispatchQueue.global().async {
connectionErrorAlert(error)
}
logger.error("NewChatButton.addContactAction apiAddContact error: \(error.localizedDescription)")
}
}
private func actionRow(icon: String, title: LocalizedStringKey, text: LocalizedStringKey, action: @escaping () -> Void) -> some View {
HStack(alignment: .top, spacing: 20) {
Button(action: action, label: {
Image(systemName: icon)
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
.padding(.leading, 6)
.padding(.top, 6)
})
VStack(alignment: .leading) {
Button(action: action, label: {
Text(title)
.font(.headline)
.multilineTextAlignment(.leading)
})
Text(text)
}
}
.padding(.bottom)
}
}
struct MakeConnection_Previews: PreviewProvider {
static var previews: some View {
let chatModel = ChatModel()
chatModel.currentUser = User.sampleData
return MakeConnection()
.environmentObject(chatModel)
}
}

View File

@@ -0,0 +1,35 @@
//
// OnboardingStepsView.swift
// SimpleX (iOS)
//
// Created by Evgeny on 07/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct OnboardingView: View {
var onboarding: OnboardingStage
var body: some View {
switch onboarding {
case .step1_SimpleXInfo: SimpleXInfo(onboarding: true)
case .step2_CreateProfile: CreateProfile()
case .step3_MakeConnection: MakeConnection()
case .onboardingComplete: EmptyView()
}
}
}
enum OnboardingStage {
case step1_SimpleXInfo
case step2_CreateProfile
case step3_MakeConnection
case onboardingComplete
}
struct OnboardingStepsView_Previews: PreviewProvider {
static var previews: some View {
OnboardingView(onboarding: .step1_SimpleXInfo)
}
}

View File

@@ -0,0 +1,102 @@
//
// SimpleXInfo.swift
// SimpleX (iOS)
//
// Created by Evgeny on 07/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct SimpleXInfo: View {
@EnvironmentObject var m: ChatModel
@State private var showHowItWorks = false
var onboarding: Bool
var body: some View {
GeometryReader { g in
VStack(alignment: .leading) {
Image("logo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: g.size.width * 0.7)
.padding(.bottom)
Text("The next generation of private messaging")
.font(.title)
.padding(.bottom)
infoRow("🎭", "Privacy redefined",
"The 1st platform without any user identifiers private by design.")
infoRow("📭", "Immune to spam and abuse",
"People can connect to you only via the links you share.")
infoRow("🤝", "Decentralized",
"Open-source protocol and code anybody can run the servers.")
Spacer()
if onboarding {
OnboardingActionButton()
Spacer()
}
Button {
showHowItWorks = true
} label: {
Label("How it works", systemImage: "info.circle")
.font(.subheadline)
}
.padding(.bottom, 8)
.frame(maxWidth: .infinity)
}
.sheet(isPresented: $showHowItWorks) {
HowItWorks(onboarding: onboarding)
}
}
.padding()
}
private func infoRow(_ emoji: String, _ title: LocalizedStringKey, _ text: LocalizedStringKey) -> some View {
HStack(alignment: .top) {
Text(emoji)
.font(mediumEmojiFont)
.frame(width: 40)
VStack(alignment: .leading) {
Text(title).font(.headline)
Text(text)
}
}
.padding(.bottom)
}
}
struct OnboardingActionButton: View {
@EnvironmentObject var m: ChatModel
var body: some View {
if m.currentUser == nil {
actionButton("Create your profile", onboarding: .step2_CreateProfile)
} else {
actionButton("Make a private connection", onboarding: .step3_MakeConnection)
}
}
private func actionButton(_ label: LocalizedStringKey, onboarding: OnboardingStage) -> some View {
Button {
withAnimation {
m.onboardingStage = onboarding
}
} label: {
HStack {
Text(label).font(.title2)
Image(systemName: "greaterthan")
}
}
.frame(maxWidth: .infinity)
}
}
struct SimpleXInfo_Previews: PreviewProvider {
static var previews: some View {
SimpleXInfo(onboarding: true)
}
}

View File

@@ -17,6 +17,8 @@ let appBuild = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as?
let DEFAULT_USE_NOTIFICATIONS = "useNotifications"
let DEFAULT_PENDING_CONNECTIONS = "pendingConnections"
private var indent: CGFloat = 36
struct SettingsView: View {
@Environment(\.colorScheme) var colorScheme
@EnvironmentObject var chatModel: ChatModel
@@ -54,29 +56,19 @@ struct SettingsView: View {
UserAddress()
.navigationTitle("Your chat address")
} label: {
HStack {
Image(systemName: "qrcode")
.padding(.trailing, 8)
Text("Your SimpleX contact address")
}
settingsRow("qrcode") { Text("Your SimpleX contact address") }
}
}
Section("Settings") {
HStack {
Image(systemName: "link")
.padding(.trailing, 8)
settingsRow("link") {
Toggle("Show pending connections", isOn: $pendingConnections)
}
NavigationLink {
SMPServers()
.navigationTitle("Your SMP servers")
} label: {
HStack {
Image(systemName: "server.rack")
.padding(.trailing, 4)
Text("SMP servers")
}
settingsRow("server.rack") { Text("SMP servers") }
}
}
@@ -86,26 +78,23 @@ struct SettingsView: View {
.navigationTitle("Welcome \(user.displayName)!")
.frame(maxHeight: .infinity, alignment: .top)
} label: {
HStack {
Image(systemName: "questionmark.circle")
.padding(.trailing, 8)
Text("How to use SimpleX Chat")
}
settingsRow("questionmark") { Text("How to use it") }
}
NavigationLink {
SimpleXInfo(onboarding: false)
.navigationBarTitle("", displayMode: .inline)
.frame(maxHeight: .infinity, alignment: .top)
} label: {
settingsRow("info") { Text("About SimpleX Chat") }
}
NavigationLink {
MarkdownHelp()
.navigationTitle("How to use markdown")
.frame(maxHeight: .infinity, alignment: .top)
} label: {
HStack {
Image(systemName: "textformat")
.padding(.trailing, 4)
Text("Markdown in messages")
}
settingsRow("textformat") { Text("Markdown in messages") }
}
HStack {
Image(systemName: "number")
.padding(.trailing, 8)
settingsRow("number") {
Button {
showSettings = false
DispatchQueue.main.async {
@@ -115,30 +104,21 @@ struct SettingsView: View {
Text("Chat with the developers")
}
}
HStack {
Image(systemName: "envelope")
.padding(.trailing, 4)
Text("[Send us email](mailto:chat@simplex.chat)")
}
settingsRow("envelope") { Text("[Send us email](mailto:chat@simplex.chat)") }
}
Section("Develop") {
NavigationLink {
TerminalView()
} label: {
HStack {
Image(systemName: "terminal")
.frame(maxWidth: 24)
.padding(.trailing, 8)
Text("Chat console")
}
settingsRow("terminal") { Text("Chat console") }
}
HStack {
ZStack(alignment: .leading) {
Image(colorScheme == .dark ? "github_light" : "github")
.resizable()
.frame(width: 24, height: 24)
.padding(.trailing, 8)
Text("Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)")
.padding(.leading, indent)
}
// if let token = chatModel.deviceToken {
// HStack {
@@ -158,6 +138,13 @@ struct SettingsView: View {
}
}
private func settingsRow<Content : View>(_ icon: String, content: @escaping () -> Content) -> some View {
ZStack(alignment: .leading) {
Image(systemName: icon).frame(maxWidth: 24, maxHeight: 24, alignment: .center)
content().padding(.leading, indent)
}
}
enum NotificationAlert {
case enable
case error(LocalizedStringKey, String)

View File

@@ -1,80 +0,0 @@
//
// WelcomeView.swift
// SimpleX
//
// Created by Evgeny Poberezkin on 18/01/2022.
//
import SwiftUI
struct WelcomeView: View {
@EnvironmentObject var chatModel: ChatModel
@State var displayName: String = ""
@State var fullName: String = ""
var body: some View {
GeometryReader { g in
VStack(alignment: .leading) {
Image("logo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: g.size.width * 0.7)
.padding(.vertical)
Text("You control your chat!")
.font(.title)
.padding(.bottom)
Text("The messaging and application platform 100% private by design!")
.padding(.bottom, 8)
Text("Your profile, contacts and messages (once delivered) are only stored locally on your device.")
.padding(.bottom, 8)
Text("Create profile")
.font(.largeTitle)
.padding(.bottom, 4)
Text("(shared only with your contacts)")
.padding(.bottom)
ZStack(alignment: .topLeading) {
if !validDisplayName(displayName) {
Image(systemName: "exclamationmark.circle")
.foregroundColor(.red)
.padding(.top, 4)
}
TextField("Display name", text: $displayName)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.padding(.leading, 28)
.padding(.bottom, 2)
}
.padding(.bottom)
TextField("Full name (optional)", text: $fullName)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.padding(.leading, 28)
.padding(.bottom)
Button("Create") {
let profile = Profile(
displayName: displayName,
fullName: fullName
)
do {
let user = try apiCreateActiveUser(profile)
chatModel.currentUser = user
} catch {
fatalError("Failed to create user: \(error)")
}
}
.disabled(!validDisplayName(displayName) || displayName == "")
}
}
.padding()
}
func validDisplayName(_ name: String) -> Bool {
name.firstIndex(of: " ") == nil
}
}
struct WelcomeView_Previews: PreviewProvider {
static var previews: some View {
WelcomeView()
}
}

View File

@@ -50,24 +50,29 @@
<target>%lldk</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(shared only with your contacts)" xml:space="preserve">
<source>(shared only with your contacts)</source>
<target>(shared only with your contacts)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Add new contact**: to create your one-time QR Code for your contact." xml:space="preserve">
<source>**Add new contact**: to create your one-time QR Code for your contact.</source>
<target>**Add new contact**: to create your one-time QR Code for your contact.</target>
<source>**Add new contact**: to create your one-time QR Code or link for your contact.</source>
<target>**Add new contact**: to create your one-time QR Code or link for your contact.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Scan QR code**: to connect to your contact who shows QR code to you." xml:space="preserve">
<source>**Scan QR code**: to connect to your contact who shows QR code to you.</source>
<target>**Scan QR code**: to connect to your contact who shows QR code to you.</target>
<trans-unit id="**Create link / QR code** for your contact to use." xml:space="preserve">
<source>**Create link / QR code** for your contact to use.</source>
<target>**Create link / QR code** for your contact to use.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Paste received link** or open it in the browser and tap **Open in mobile app**." xml:space="preserve">
<source>**Paste received link** or open it in the browser and tap **Open in mobile app**.</source>
<target>**Paste received link** or open it in the browser and tap **Open in mobile app**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Scan QR code**: to connect to your contact in person or via video call." xml:space="preserve">
<source>**Scan QR code**: to connect to your contact in person or via video call.</source>
<target>**Scan QR code**: to connect to your contact in person or via video call.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="*bold*" xml:space="preserve">
@@ -95,6 +100,16 @@
<target>: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="About SimpleX" xml:space="preserve">
<source>About SimpleX</source>
<target>About SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="About SimpleX Chat" xml:space="preserve">
<source>About SimpleX Chat</source>
<target>About SimpleX Chat</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Accept" xml:space="preserve">
<source>Accept</source>
<target>Accept</target>
@@ -110,11 +125,6 @@
<target>Accept contact request from %@?</target>
<note>notification body</note>
</trans-unit>
<trans-unit id="Add contact" xml:space="preserve">
<source>Add contact</source>
<target>Add contact</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Add contact to start a new chat" xml:space="preserve">
<source>Add contact to start a new chat</source>
<target>Add contact to start a new chat</target>
@@ -125,6 +135,11 @@
<target>All your contacts will remain connected</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already connected?" xml:space="preserve">
<source>Already connected?</source>
<target>Already connected?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Answer" xml:space="preserve">
<source>Answer</source>
<target>Answer</target>
@@ -171,7 +186,7 @@
<note>notification</note>
</trans-unit>
<trans-unit id="Choose file" xml:space="preserve">
<source>Choose file</source>
<source>Choose file (new in v2.0)</source>
<target>Choose file (new in v2.0)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
@@ -215,6 +230,11 @@
<target>Connect via one-time link?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect with the developers" xml:space="preserve">
<source>Connect with the developers</source>
<target>Connect with the developers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Connecting to server…</target>
@@ -285,6 +305,11 @@
<target>Create</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create 1-time link / QR code" xml:space="preserve">
<source>Create 1-time link / QR code</source>
<target>Create 1-time link / QR code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create address" xml:space="preserve">
<source>Create address</source>
<target>Create address</target>
@@ -295,9 +320,9 @@
<target>Create link / QR code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Create profile</target>
<trans-unit id="Create your profile" xml:space="preserve">
<source>Create your profile</source>
<target>Create your profile</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
@@ -305,6 +330,11 @@
<target>Currently maximum supported file size is %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Decentralized" xml:space="preserve">
<source>Decentralized</source>
<target>Decentralized</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete" xml:space="preserve">
<source>Delete</source>
<target>Delete</target>
@@ -435,14 +465,24 @@
<target>Help</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve">
<source>How SimpleX works</source>
<target>How SimpleX works</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How it works" xml:space="preserve">
<source>How it works</source>
<target>How it works</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How to" xml:space="preserve">
<source>How to</source>
<target>How to</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How to use SimpleX Chat" xml:space="preserve">
<source>How to use SimpleX Chat</source>
<target>How to use SimpleX Chat</target>
<trans-unit id="How to use it" xml:space="preserve">
<source>How to use it</source>
<target>How to use it</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How to use markdown" xml:space="preserve">
@@ -450,21 +490,16 @@
<target>How to use markdown</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, **show QR code in the video call**, or share the link." xml:space="preserve">
<source>If you can't meet in person, **show QR code in the video call**, or share the link.</source>
<target>If you can't meet in person, **show QR code in the video call**, or share the link.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link." xml:space="preserve">
<source>If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link.</source>
<target>If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you cannot meet in person, you can **show QR code in the video call**, or you can share the invitation link via any other channel." xml:space="preserve">
<source>If you cannot meet in person, you can **show QR code in the video call**, or you can share the invitation link via any other channel.</source>
<target>If you cannot meet in person, you can **show QR code in the video call**, or you can share the invitation link via any other channel.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you received SimpleX Chat invitation link you can open it in your browser:" xml:space="preserve">
<source>If you received SimpleX Chat invitation link you can open it in your browser:</source>
<target>If you received SimpleX Chat invitation link you can open it in your browser:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Ignore" xml:space="preserve">
<source>Ignore</source>
<target>Ignore</target>
@@ -475,6 +510,16 @@
<target>Image will be received when your contact is online, please wait or check later!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Immune to spam and abuse" xml:space="preserve">
<source>Immune to spam and abuse</source>
<target>Immune to spam and abuse</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="In person or via a video call the most secure way to connect." xml:space="preserve">
<source>In person or via a video call the most secure way to connect.</source>
<target>In person or via a video call the most secure way to connect.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incoming %@ call" xml:space="preserve">
<source>Incoming %@ call</source>
<target>Incoming %@ call</target>
@@ -495,16 +540,36 @@
<target>Invalid connection link</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="It seems like you are already connected via this link. If it is not the case, there was an error (%@)." xml:space="preserve">
<source>It seems like you are already connected via this link. If it is not the case, there was an error (%@).</source>
<target>It seems like you are already connected via this link. If it is not the case, there was an error (%@).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="It's secure to share - only one contact can use it." xml:space="preserve">
<source>It's secure to share - only one contact can use it.</source>
<target>It's secure to share - only one contact can use it.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Large file!" xml:space="preserve">
<source>Large file!</source>
<target>Large file!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make a private connection" xml:space="preserve">
<source>Make a private connection</source>
<target>Make a private connection</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated." xml:space="preserve">
<source>Make sure SMP server addresses are in correct format, line separated and are not duplicated.</source>
<target>Make sure SMP server addresses are in correct format, line separated and are not duplicated.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" xml:space="preserve">
<source>Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*</source>
<target>Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Markdown in messages" xml:space="preserve">
<source>Markdown in messages</source>
<target>Markdown in messages</target>
@@ -535,11 +600,31 @@
<target>Notifications are disabled!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="One-time invitation link" xml:space="preserve">
<source>One-time invitation link</source>
<target>One-time invitation link</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." xml:space="preserve">
<source>Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**.</source>
<target>Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open Settings" xml:space="preserve">
<source>Open Settings</source>
<target>Open Settings</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open-source protocol anybody can run the servers." xml:space="preserve">
<source>Open-source protocol anybody can run the servers.</source>
<target>Open-source protocol anybody can run the servers.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Or open the link in the browser and tap **Open in mobile**." xml:space="preserve">
<source>Or open the link in the browser and tap **Open in mobile**.</source>
<target>Or open the link in the browser and tap **Open in mobile**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste" xml:space="preserve">
<source>Paste</source>
<target>Paste</target>
@@ -550,11 +635,21 @@
<target>Paste received link</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste the link you received" xml:space="preserve">
<source>Paste the link you received</source>
<target>Paste the link you received</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste the link you received into the box below to connect with your contact." xml:space="preserve">
<source>Paste the link you received into the box below to connect with your contact.</source>
<target>Paste the link you received into the box below to connect with your contact.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="People can connect to you only via the links you share." xml:space="preserve">
<source>People can connect to you only via the links you share.</source>
<target>People can connect to you only via the links you share.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please check that you used the correct link or ask your contact to send you another one." xml:space="preserve">
<source>Please check that you used the correct link or ask your contact to send you another one.</source>
<target>Please check that you used the correct link or ask your contact to send you another one.</target>
@@ -565,6 +660,11 @@
<target>Please check your network connection and try again.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Privacy redefined" xml:space="preserve">
<source>Privacy redefined</source>
<target>Privacy redefined</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile image" xml:space="preserve">
<source>Profile image</source>
<target>Profile image</target>
@@ -575,6 +675,16 @@
<target>Read</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Read more in our GitHub repository." xml:space="preserve">
<source>Read more in our GitHub repository.</source>
<target>Read more in our GitHub repository.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme)." xml:space="preserve">
<source>Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme).</source>
<target>Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reject" xml:space="preserve">
<source>Reject</source>
<target>Reject</target>
@@ -620,6 +730,11 @@
<target>Scan QR code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan contact's QR code" xml:space="preserve">
<source>Scan contact's QR code</source>
<target>Scan contact's QR code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Server connected" xml:space="preserve">
<source>Server connected</source>
<target>Server connected</target>
@@ -645,13 +760,6 @@
<target>Share link</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Show QR code to your contact&#10;to scan from the app" xml:space="preserve">
<source>Show QR code to your contact
to scan from the app</source>
<target>Show QR code to your contact
to scan from the app</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Show pending connections" xml:space="preserve">
<source>Show pending connections</source>
<target>Show pending connections</target>
@@ -672,6 +780,11 @@ to scan from the app</target>
<target>Thank you for installing SimpleX Chat!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The 1st platform without any user identifiers private by design." xml:space="preserve">
<source>The 1st platform without any user identifiers private by design.</source>
<target>The 1st platform without any user identifiers private by design.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The app can notify you when you receive messages or contact requests - please open settings to enable." xml:space="preserve">
<source>The app can notify you when you receive messages or contact requests - please open settings to enable.</source>
<target>The app can notify you when you receive messages or contact requests - please open settings to enable.</target>
@@ -694,9 +807,14 @@ to scan from the app</target>
<target>The contact you shared this link with will NOT be able to connect!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The messaging and application platform 100% private by design!" xml:space="preserve">
<source>The messaging and application platform 100% private by design!</source>
<target>The messaging and application platform 100% private by design!</target>
<trans-unit id="The next generation of private messaging" xml:space="preserve">
<source>The next generation of private messaging</source>
<target>The next generation of private messaging</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>The profile is only shared with your contacts.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">
@@ -704,19 +822,29 @@ to scan from the app</target>
<target>The sender will NOT be notified</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To ask any questions and to receive SimpleX Chat updates." xml:space="preserve">
<source>To ask any questions and to receive SimpleX Chat updates.</source>
<target>To ask any questions and to receive SimpleX Chat updates.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To ask any questions and to receive updates:" xml:space="preserve">
<source>To ask any questions and to receive updates:</source>
<target>To ask any questions and to receive updates:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To connect via link" xml:space="preserve">
<source>To connect via link</source>
<target>To connect via link</target>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>To make a new connection</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To start a new chat" xml:space="preserve">
<source>To start a new chat</source>
<target>To start a new chat</target>
<trans-unit id="To make your first private connection, choose **one of the following**:" xml:space="preserve">
<source>To make your first private connection, choose **one of the following**:</source>
<target>To make your first private connection, choose **one of the following**:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts." xml:space="preserve">
<source>To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts.</source>
<target>To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Trying to connect to the server used to receive messages from this contact (error: %@)." xml:space="preserve">
@@ -806,9 +934,9 @@ To connect, please ask your contact to create another connection link and check
<target>You can use markdown to format messages:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You control your chat!" xml:space="preserve">
<source>You control your chat!</source>
<target>You control your chat!</target>
<trans-unit id="You control through which server(s) **to receive** the messages, your contacts the servers you use to message them." xml:space="preserve">
<source>You control through which server(s) **to receive** the messages, your contacts the servers you use to message them.</source>
<target>You control through which server(s) **to receive** the messages, your contacts the servers you use to message them.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You invited your contact" xml:space="preserve">
@@ -856,6 +984,11 @@ To connect, please ask your contact to create another connection link and check
<target>Your chats</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact can scan it from the app" xml:space="preserve">
<source>Your contact can scan it from the app</source>
<target>Your contact can scan it from the app</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact needs to be online for the connection to complete.&#10;You can cancel this connection and remove the contact (and try later with a new link)." xml:space="preserve">
<source>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).</source>
@@ -880,9 +1013,9 @@ SimpleX servers cannot see your profile.</target>
<target>Your profile will be sent to the contact that you received this link from</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile, contacts and messages (once delivered) are only stored locally on your device." xml:space="preserve">
<source>Your profile, contacts and messages (once delivered) are only stored locally on your device.</source>
<target>Your profile, contacts and messages (once delivered) are only stored locally on your device.</target>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Your profile, contacts and delivered messages are stored on your device.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your settings" xml:space="preserve">
@@ -905,9 +1038,9 @@ SimpleX servers cannot see your profile.</target>
<target>`a + b`</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="above, then:" xml:space="preserve">
<source>above, then:</source>
<target>above, then:</target>
<trans-unit id="above, then choose:" xml:space="preserve">
<source>above, then choose:</source>
<target>above, then choose:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="accepted" xml:space="preserve">
@@ -1001,6 +1134,11 @@ SimpleX servers cannot see your profile.</target>
<target>no end-to-end encryption</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="or" xml:space="preserve">
<source>or</source>
<target>or</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="received answer…" xml:space="preserve">
<source>received answer…</source>
<target>received answer…</target>
@@ -1066,16 +1204,6 @@ SimpleX servers cannot see your profile.</target>
<target>~strike~</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="💻 desktop: scan displayed QR code from the app, via **Scan QR code**." xml:space="preserve">
<source>💻 desktop: scan displayed QR code from the app, via **Scan QR code**.</source>
<target>💻 desktop: scan displayed QR code from the app, via **Scan QR code**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="📱 mobile: tap **Open in mobile app**, then tap **Connect** in the app." xml:space="preserve">
<source>📱 mobile: tap **Open in mobile app**, then tap **Connect** in the app.</source>
<target>📱 mobile: tap **Open in mobile app**, then tap **Connect** in the app.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
</body>
</file>
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="en" datatype="plaintext">

View File

@@ -1,6 +1,11 @@
/* No comment provided by engineer. */
"Choose file" = "Choose file (new in v2.0)";
/* No comment provided by engineer. */
"Connecting server…" = "Connecting to server…";
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Connecting to server… (error: %@)";
/* 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.";

View File

@@ -50,24 +50,29 @@
<target>%lldk</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(shared only with your contacts)" xml:space="preserve">
<source>(shared only with your contacts)</source>
<target>(отправляется только вашим контактам)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Add new contact**: to create your one-time QR Code for your contact." xml:space="preserve">
<source>**Add new contact**: to create your one-time QR Code for your contact.</source>
<source>**Add new contact**: to create your one-time QR Code or link for your contact.</source>
<target>**Добавить новый контакт**: чтобы создать одноразовый QR код или ссылку для вашего контакта.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Scan QR code**: to connect to your contact who shows QR code to you." xml:space="preserve">
<source>**Scan QR code**: to connect to your contact who shows QR code to you.</source>
<target>**Сканировать QR код**: чтобы соединиться с вашим контактом (который показывает вам QR код).</target>
<trans-unit id="**Create link / QR code** for your contact to use." xml:space="preserve">
<source>**Create link / QR code** for your contact to use.</source>
<target>**Создать ссылку / QR код** для вашего контакта.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Paste received link** or open it in the browser and tap **Open in mobile app**." xml:space="preserve">
<source>**Paste received link** or open it in the browser and tap **Open in mobile app**.</source>
<target>**Вставить полученную ссылку**, или откройте её в браузере и нажмите **Open in mobile app**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="**Scan QR code**: to connect to your contact in person or via video call." xml:space="preserve">
<source>**Scan QR code**: to connect to your contact in person or via video call.</source>
<target>**Сканировать QR код**: соединиться с вашим контактом при встрече или во время видеозвонка.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="*bold*" xml:space="preserve">
@@ -95,6 +100,16 @@
<target>: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="About SimpleX" xml:space="preserve">
<source>About SimpleX</source>
<target>О SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="About SimpleX Chat" xml:space="preserve">
<source>About SimpleX Chat</source>
<target>Информация о SimpleX Chat</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Accept" xml:space="preserve">
<source>Accept</source>
<target>Принять</target>
@@ -110,11 +125,6 @@
<target>Принять запрос на соединение от %@?</target>
<note>notification body</note>
</trans-unit>
<trans-unit id="Add contact" xml:space="preserve">
<source>Add contact</source>
<target>Добавить контакт</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Add contact to start a new chat" xml:space="preserve">
<source>Add contact to start a new chat</source>
<target>Добавьте контакт, чтобы начать разговор</target>
@@ -125,6 +135,11 @@
<target>Все контакты, которые соединились через этот адрес, сохранятся.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already connected?" xml:space="preserve">
<source>Already connected?</source>
<target>Соединение уже установлено?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Answer" xml:space="preserve">
<source>Answer</source>
<target>Ответить</target>
@@ -171,7 +186,7 @@
<note>notification</note>
</trans-unit>
<trans-unit id="Choose file" xml:space="preserve">
<source>Choose file</source>
<source>Choose file (new in v2.0)</source>
<target>Выбрать файл (v2.0)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
@@ -215,6 +230,11 @@
<target>Соединиться через одноразовую ссылку?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect with the developers" xml:space="preserve">
<source>Connect with the developers</source>
<target>Соединиться с разработчиками</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Устанавливается соединение с сервером…</target>
@@ -285,6 +305,11 @@
<target>Создать</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create 1-time link / QR code" xml:space="preserve">
<source>Create 1-time link / QR code</source>
<target>Создать ссылку / QR код</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create address" xml:space="preserve">
<source>Create address</source>
<target>Создать адрес</target>
@@ -295,8 +320,8 @@
<target>Создать ссылку / QR код</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<trans-unit id="Create your profile" xml:space="preserve">
<source>Create your profile</source>
<target>Создать профиль</target>
<note>No comment provided by engineer.</note>
</trans-unit>
@@ -305,6 +330,11 @@
<target>Максимальный размер файла - %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Decentralized" xml:space="preserve">
<source>Decentralized</source>
<target>Децентрализованный</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete" xml:space="preserve">
<source>Delete</source>
<target>Удалить</target>
@@ -435,14 +465,24 @@
<target>Помощь</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How SimpleX works" xml:space="preserve">
<source>How SimpleX works</source>
<target>Как SimpleX работает</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How it works" xml:space="preserve">
<source>How it works</source>
<target>Как это работает</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How to" xml:space="preserve">
<source>How to</source>
<target>Инфо</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How to use SimpleX Chat" xml:space="preserve">
<source>How to use SimpleX Chat</source>
<target>Как использовать SimpleX Chat</target>
<trans-unit id="How to use it" xml:space="preserve">
<source>How to use it</source>
<target>Как использовать</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="How to use markdown" xml:space="preserve">
@@ -450,21 +490,16 @@
<target>Как форматировать</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, **show QR code in the video call**, or share the link." xml:space="preserve">
<source>If you can't meet in person, **show QR code in the video call**, or share the link.</source>
<target>Если вы не можете встретиться лично, вы можете **показать QR код во время видеозвонка**, или поделиться ссылкой.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link." xml:space="preserve">
<source>If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link.</source>
<target>Если вы не можете встретиться лично, вы можете **сосканировать QR код во время видеозвонка**, или ваш контакт может отправить вам ссылку.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you cannot meet in person, you can **show QR code in the video call**, or you can share the invitation link via any other channel." xml:space="preserve">
<source>If you cannot meet in person, you can **show QR code in the video call**, or you can share the invitation link via any other channel.</source>
<target>Если вы не можете встретиться лично, вы можете **показать QR код во время видеозвонка** или отправить ссылку через любой другой канал связи.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you received SimpleX Chat invitation link you can open it in your browser:" xml:space="preserve">
<source>If you received SimpleX Chat invitation link you can open it in your browser:</source>
<target>Если вы получили ссылку с приглашением из SimpleX Chat, вы можете открыть её в браузере:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Ignore" xml:space="preserve">
<source>Ignore</source>
<target>Не отвечать</target>
@@ -475,6 +510,16 @@
<target>Изображение будет принято, когда ваш контакт будет в сети, подождите или проверьте позже!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Immune to spam and abuse" xml:space="preserve">
<source>Immune to spam and abuse</source>
<target>Защищен от спама</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="In person or via a video call the most secure way to connect." xml:space="preserve">
<source>In person or via a video call the most secure way to connect.</source>
<target>При встрече или в видеозвонке самый безопасный способ установить соединение</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incoming %@ call" xml:space="preserve">
<source>Incoming %@ call</source>
<target>Входящий звонок</target>
@@ -495,16 +540,36 @@
<target>Ошибка в ссылке контакта</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="It seems like you are already connected via this link. If it is not the case, there was an error (%@)." xml:space="preserve">
<source>It seems like you are already connected via this link. If it is not the case, there was an error (%@).</source>
<target>Возможно, вы уже соединились через эту ссылку. Если это не так, то это ошибка (%@).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="It's secure to share - only one contact can use it." xml:space="preserve">
<source>It's secure to share - only one contact can use it.</source>
<target>Ей безопасно поделиться - только один контакт может использовать её.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Large file!" xml:space="preserve">
<source>Large file!</source>
<target>Большой файл!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make a private connection" xml:space="preserve">
<source>Make a private connection</source>
<target>Создайте соединение</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Make sure SMP server addresses are in correct format, line separated and are not duplicated." xml:space="preserve">
<source>Make sure SMP server addresses are in correct format, line separated and are not duplicated.</source>
<target>Пожалуйста, проверьте, что адреса SMP серверов имеют правильный формат, каждый адрес на отдельной строке и не повторяется.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" xml:space="preserve">
<source>Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*</source>
<target>Много пользователей спросили: *как SimpleX доставляет сообщения без идентификаторов пользователей?*</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Markdown in messages" xml:space="preserve">
<source>Markdown in messages</source>
<target>Форматирование сообщений</target>
@@ -535,11 +600,31 @@
<target>Уведомления выключены</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="One-time invitation link" xml:space="preserve">
<source>One-time invitation link</source>
<target>Одноразовая ссылка</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." xml:space="preserve">
<source>Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**.</source>
<target>Только пользовательские устройства хранят контакты, группы и сообщения, которые отправляются **с двухуровневым end-to-end шифрованием**</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open Settings" xml:space="preserve">
<source>Open Settings</source>
<target>Открыть Настройки</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open-source protocol and code anybody can run the servers." xml:space="preserve">
<source>Open-source protocol and code anybody can run the servers.</source>
<target>Открытый протокол и код - кто угодно может запускать серверы.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Or open the link in the browser and tap **Open in mobile**." xml:space="preserve">
<source>Or open the link in the browser and tap **Open in mobile**.</source>
<target>Или откройте ссылку в браузере и нажмите **Open in mobile**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste" xml:space="preserve">
<source>Paste</source>
<target>Вставить</target>
@@ -550,11 +635,21 @@
<target>Вставить полученную ссылку</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste the link you received" xml:space="preserve">
<source>Paste the link you received</source>
<target>Вставьте полученную ссылку</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste the link you received into the box below to connect with your contact." xml:space="preserve">
<source>Paste the link you received into the box below to connect with your contact.</source>
<target>Чтобы соединиться, вставьте в это поле ссылку, полученную от вашего контакта.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="People can connect to you only via the links you share." xml:space="preserve">
<source>People can connect to you only via the links you share.</source>
<target>С вами можно соединиться только через созданные вами ссылки.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please check that you used the correct link or ask your contact to send you another one." xml:space="preserve">
<source>Please check that you used the correct link or ask your contact to send you another one.</source>
<target>Пожалуйста, проверьте, что вы использовали правильную ссылку или попросите, чтобы ваш контакт отправил вам другую ссылку.</target>
@@ -565,6 +660,11 @@
<target>Пожалуйста, проверьте ваше соединение с сетью и попробуйте еще раз.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Privacy redefined" xml:space="preserve">
<source>Privacy redefined</source>
<target>Более конфиденциальный</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile image" xml:space="preserve">
<source>Profile image</source>
<target>Аватар</target>
@@ -575,6 +675,16 @@
<target>Прочитано</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Read more in our GitHub repository." xml:space="preserve">
<source>Read more in our GitHub repository.</source>
<target>Узнайте больше из нашего GitHub репозитория.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme)." xml:space="preserve">
<source>Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme).</source>
<target>Узнайте больше из нашего [GitHub репозитория](https://github.com/simplex-chat/simplex-chat#readme).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reject" xml:space="preserve">
<source>Reject</source>
<target>Отклонить</target>
@@ -620,6 +730,11 @@
<target>Сканировать QR код</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan contact's QR code" xml:space="preserve">
<source>Scan contact's QR code</source>
<target>Сосканировать QR код контакта</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Server connected" xml:space="preserve">
<source>Server connected</source>
<target>Установлено соединение с сервером</target>
@@ -645,12 +760,6 @@
<target>Поделиться ссылкой</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Show QR code to your contact&#10;to scan from the app" xml:space="preserve">
<source>Show QR code to your contact
to scan from the app</source>
<target>Покажите QR код вашему контакту для сканирования в приложении</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Show pending connections" xml:space="preserve">
<source>Show pending connections</source>
<target>Показать ожидаемые соединения</target>
@@ -671,6 +780,11 @@ to scan from the app</source>
<target>Спасибо, что установили SimpleX Chat!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The 1st platform without any user identifiers private by design." xml:space="preserve">
<source>The 1st platform without any user identifiers private by design.</source>
<target>Первая в мире платформа без идентификации пользователей.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The app can notify you when you receive messages or contact requests - please open settings to enable." xml:space="preserve">
<source>The app can notify you when you receive messages or contact requests - please open settings to enable.</source>
<target>Приложение может посылать вам уведомления о сообщениях и запросах на соединение - уведомления можно включить в Настройках.</target>
@@ -693,9 +807,14 @@ to scan from the app</source>
<target>Контакт, которому вы отправили эту ссылку, не сможет соединиться!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The messaging and application platform 100% private by design!" xml:space="preserve">
<source>The messaging and application platform 100% private by design!</source>
<target>Платформа для сообщений и приложений, которая защищает вашу личную информацию и безопасность.</target>
<trans-unit id="The next generation of private messaging" xml:space="preserve">
<source>The next generation of private messaging</source>
<target>Новое поколение приватных сообщений</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Профиль отправляется только вашим контактам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">
@@ -703,19 +822,29 @@ to scan from the app</source>
<target>Отправитель не будет уведомлён</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To ask any questions and to receive SimpleX Chat updates." xml:space="preserve">
<source>To ask any questions and to receive SimpleX Chat updates.</source>
<target>Чтобы задать вопросы и получать уведомления о SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To ask any questions and to receive updates:" xml:space="preserve">
<source>To ask any questions and to receive updates:</source>
<target>Чтобы задать вопросы и получать уведомления о новых версиях,</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To connect via link" xml:space="preserve">
<source>To connect via link</source>
<target>Соединиться через ссылку</target>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Чтобы соединиться</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To start a new chat" xml:space="preserve">
<source>To start a new chat</source>
<target>Начать новый разговор</target>
<trans-unit id="To make your first private connection, choose **one of the following**:" xml:space="preserve">
<source>To make your first private connection, choose **one of the following**:</source>
<target>Чтобы сделать ваше первое приватное соединение, выберите **одно из**:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts." xml:space="preserve">
<source>To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts.</source>
<target>Чтобы защитить вашу конфиденциальность, вместо ID пользователей, которые есть в других платформах, SimpleX использует ID для очередей сообщений, разные для каждого контакта.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Trying to connect to the server used to receive messages from this contact (error: %@)." xml:space="preserve">
@@ -805,9 +934,9 @@ To connect, please ask your contact to create another connection link and check
<target>Вы можете форматировать сообщения:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You control your chat!" xml:space="preserve">
<source>You control your chat!</source>
<target>Вы котролируете Ваш чат!</target>
<trans-unit id="You control through which server(s) **to receive** the messages, your contacts the servers you use to message them." xml:space="preserve">
<source>You control through which server(s) **to receive** the messages, your contacts the servers you use to message them.</source>
<target>Вы определяете через какие серверы вы **получаете сообщения**, ваши контакты - серверы, которые вы используете для отправки.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You invited your contact" xml:space="preserve">
@@ -855,6 +984,11 @@ To connect, please ask your contact to create another connection link and check
<target>Ваши чаты</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact can scan it from the app" xml:space="preserve">
<source>Your contact can scan it from the app</source>
<target>Ваш контакт может сосканировать QR в приложении</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact needs to be online for the connection to complete.&#10;You can cancel this connection and remove the contact (and try later with a new link)." xml:space="preserve">
<source>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).</source>
@@ -879,9 +1013,9 @@ SimpleX серверы не могут получить доступ к ваше
<target>Ваш профиль будет отправлен контакту, от которого вы получили эту ссылку.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile, contacts and messages (once delivered) are only stored locally on your device." xml:space="preserve">
<source>Your profile, contacts and messages (once delivered) are only stored locally on your device.</source>
<target>Ваш профиль, контакты и сообщения (после доставки) хранятся только на вашем устройстве.</target>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Ваш профиль, контакты и доставленные сообщения хранятся на вашем устройстве.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your settings" xml:space="preserve">
@@ -904,9 +1038,9 @@ SimpleX серверы не могут получить доступ к ваше
<target>\`a + b`</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="above, then:" xml:space="preserve">
<source>above, then:</source>
<target>наверху, затем:</target>
<trans-unit id="above, then choose:" xml:space="preserve">
<source>above, then choose:</source>
<target>наверху, затем выберите:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="accepted" xml:space="preserve">
@@ -1000,6 +1134,11 @@ SimpleX серверы не могут получить доступ к ваше
<target>end-to-end шифрование не поддерживается</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="or" xml:space="preserve">
<source>or</source>
<target>или</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="received answer…" xml:space="preserve">
<source>received answer…</source>
<target>получен ответ…</target>
@@ -1065,16 +1204,6 @@ SimpleX серверы не могут получить доступ к ваше
<target>\~зачеркнуть~</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="💻 desktop: scan displayed QR code from the app, via **Scan QR code**." xml:space="preserve">
<source>💻 desktop: scan displayed QR code from the app, via **Scan QR code**.</source>
<target>💻 на компьютере: сосканируйте QR код из приложения через **Сканировать QR код**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="📱 mobile: tap **Open in mobile app**, then tap **Connect** in the app." xml:space="preserve">
<source>📱 mobile: tap **Open in mobile app**, then tap **Connect** in the app.</source>
<target>📱 на мобильном: намжите кнопку **Open in mobile app** на веб странице, затем нажмите **Соединиться** в приложении.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
</body>
</file>
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="ru" datatype="plaintext">

View File

@@ -1,6 +1,11 @@
/* No comment provided by engineer. */
"Choose file" = "Choose file (new in v2.0)";
/* No comment provided by engineer. */
"Connecting server…" = "Connecting to server…";
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Connecting to server… (error: %@)";
/* 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.";

View File

@@ -56,9 +56,13 @@
5CA059EB279559F40002BEB4 /* SimpleXApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059C3279559F40002BEB4 /* SimpleXApp.swift */; };
5CA059ED279559F40002BEB4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059C4279559F40002BEB4 /* ContentView.swift */; };
5CA059EF279559F40002BEB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5CA059C5279559F40002BEB4 /* Assets.xcassets */; };
5CA05A4C27974EB60002BEB4 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA05A4B27974EB60002BEB4 /* WelcomeView.swift */; };
5CB0BA882826CB3A00B3292C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CB0BA862826CB3A00B3292C /* InfoPlist.strings */; };
5CB0BA8B2826CB3A00B3292C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CB0BA892826CB3A00B3292C /* Localizable.strings */; };
5CB0BA8E2827126500B3292C /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB0BA8D2827126500B3292C /* OnboardingView.swift */; };
5CB0BA90282713D900B3292C /* SimpleXInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB0BA8F282713D900B3292C /* SimpleXInfo.swift */; };
5CB0BA92282713FD00B3292C /* CreateProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB0BA91282713FD00B3292C /* CreateProfile.swift */; };
5CB0BA962827143500B3292C /* MakeConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB0BA952827143500B3292C /* MakeConnection.swift */; };
5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB0BA992827FD8800B3292C /* HowItWorks.swift */; };
5CB924D427A853F100ACCCDD /* SettingsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB924D327A853F100ACCCDD /* SettingsButton.swift */; };
5CB924D727A8563F00ACCCDD /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB924D627A8563F00ACCCDD /* SettingsView.swift */; };
5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB924E027A867BA00ACCCDD /* UserProfile.swift */; };
@@ -191,9 +195,13 @@
5CA059D7279559F40002BEB4 /* Tests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
5CA059DB279559F40002BEB4 /* Tests_iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_iOS.swift; sourceTree = "<group>"; };
5CA059DD279559F40002BEB4 /* Tests_iOSLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_iOSLaunchTests.swift; sourceTree = "<group>"; };
5CA05A4B27974EB60002BEB4 /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = "<group>"; };
5CB0BA872826CB3A00B3292C /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
5CB0BA8A2826CB3A00B3292C /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
5CB0BA8D2827126500B3292C /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = "<group>"; };
5CB0BA8F282713D900B3292C /* SimpleXInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXInfo.swift; sourceTree = "<group>"; };
5CB0BA91282713FD00B3292C /* CreateProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateProfile.swift; sourceTree = "<group>"; };
5CB0BA952827143500B3292C /* MakeConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MakeConnection.swift; sourceTree = "<group>"; };
5CB0BA992827FD8800B3292C /* HowItWorks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HowItWorks.swift; sourceTree = "<group>"; };
5CB924D327A853F100ACCCDD /* SettingsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButton.swift; sourceTree = "<group>"; };
5CB924D627A8563F00ACCCDD /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
5CB924E027A867BA00ACCCDD /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = "<group>"; };
@@ -287,6 +295,7 @@
5C2E260D27A30E2400F70299 /* Views */ = {
isa = PBXGroup;
children = (
5CB0BA8C282711BC00B3292C /* Onboarding */,
3C714775281C080100CB4D4B /* Call */,
5C971E1F27AEBF7000C8A3CE /* Helpers */,
5C5F4AC227A5E9AF00B51EF1 /* Chat */,
@@ -294,7 +303,6 @@
5CB924DD27A8622200ACCCDD /* NewChat */,
5CB924DF27A8678B00ACCCDD /* UserSettings */,
5C2E261127A30FEA00F70299 /* TerminalView.swift */,
5CA05A4B27974EB60002BEB4 /* WelcomeView.swift */,
);
path = Views;
sourceTree = "<group>";
@@ -419,6 +427,18 @@
path = "Tests iOS";
sourceTree = "<group>";
};
5CB0BA8C282711BC00B3292C /* Onboarding */ = {
isa = PBXGroup;
children = (
5CB0BA8D2827126500B3292C /* OnboardingView.swift */,
5CB0BA8F282713D900B3292C /* SimpleXInfo.swift */,
5CB0BA91282713FD00B3292C /* CreateProfile.swift */,
5CB0BA952827143500B3292C /* MakeConnection.swift */,
5CB0BA992827FD8800B3292C /* HowItWorks.swift */,
);
path = Onboarding;
sourceTree = "<group>";
};
5CB924DD27A8622200ACCCDD /* NewChat */ = {
isa = PBXGroup;
children = (
@@ -660,6 +680,7 @@
5CDCAD7728188D3800503DA2 /* ChatTypes.swift in Sources */,
5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */,
5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */,
5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */,
5CDCAD5328186F9500503DA2 /* GroupDefaults.swift in Sources */,
5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */,
5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */,
@@ -672,10 +693,12 @@
5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */,
5CB924E427A8683A00ACCCDD /* UserAddress.swift in Sources */,
640F50E327CF991C001E05C2 /* SMPServers.swift in Sources */,
5CB0BA90282713D900B3292C /* SimpleXInfo.swift in Sources */,
5C063D2727A4564100AEC577 /* ChatPreviewView.swift in Sources */,
5C35CFCB27B2E91D00FB6C6D /* NtfManager.swift in Sources */,
3C8C548928133C84000A3EC7 /* PasteToConnectView.swift in Sources */,
5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */,
5CB0BA8E2827126500B3292C /* OnboardingView.swift in Sources */,
5C2E261227A30FEA00F70299 /* TerminalView.swift in Sources */,
5CDCAD7628188D3600503DA2 /* APITypes.swift in Sources */,
5C9FD96B27A56D4D0075386C /* JSON.swift in Sources */,
@@ -687,10 +710,10 @@
5CA059ED279559F40002BEB4 /* ContentView.swift in Sources */,
5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */,
5C3A88CE27DF50170060F1C2 /* DetermineWidth.swift in Sources */,
5CB0BA962827143500B3292C /* MakeConnection.swift in Sources */,
5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */,
5C7505A227B65FDB00BE3227 /* CIMetaView.swift in Sources */,
5C35CFC827B2782E00FB6C6D /* BGManager.swift in Sources */,
5CA05A4C27974EB60002BEB4 /* WelcomeView.swift in Sources */,
5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */,
5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */,
5C971E2127AEBF8300C8A3CE /* ChatInfoImage.swift in Sources */,
@@ -710,6 +733,7 @@
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */,
5CB924D427A853F100ACCCDD /* SettingsButton.swift in Sources */,
3C714777281C081000CB4D4B /* WebRTCView.swift in Sources */,
5CB0BA92282713FD00B3292C /* CreateProfile.swift in Sources */,
5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */,
5C5E5D3D282447AB00B0488A /* CallTypes.swift in Sources */,
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */,

View File

@@ -7,3 +7,5 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Connecting to server… (error: %@)";
/* 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.";

View File

@@ -22,9 +22,6 @@
/* No comment provided by engineer. */
"!1 colored!" = "!1 цвет!";
/* No comment provided by engineer. */
"(shared only with your contacts)" = "(отправляется только вашим контактам)";
/* No comment provided by engineer. */
")" = ")";
@@ -35,7 +32,13 @@
"**Add new contact**: to create your one-time QR Code for your contact." = "**Добавить новый контакт**: чтобы создать одноразовый QR код или ссылку для вашего контакта.";
/* No comment provided by engineer. */
"**Scan QR code**: to connect to your contact who shows QR code to you." = "**Сканировать QR код**: чтобы соединиться с вашим контактом (который показывает вам QR код).";
"**Create link / QR code** for your contact to use." = "**Создать ссылку / QR код** для вашего контакта.";
/* No comment provided by engineer. */
"**Paste received link** or open it in the browser and tap **Open in mobile app**." = "**Вставить полученную ссылку**, или откройте её в браузере и нажмите **Open in mobile app**.";
/* 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. */
"*bold*" = "\\*жирный*";
@@ -61,17 +64,17 @@
/* No comment provided by engineer. */
"~strike~" = "\\~зачеркнуть~";
/* No comment provided by engineer. */
"💻 desktop: scan displayed QR code from the app, via **Scan QR code**." = "💻 на компьютере: сосканируйте QR код из приложения через **Сканировать QR код**.";
/* No comment provided by engineer. */
"📱 mobile: tap **Open in mobile app**, then tap **Connect** in the app." = "📱 на мобильном: намжите кнопку **Open in mobile app** на веб странице, затем нажмите **Соединиться** в приложении.";
/* No comment provided by engineer. */
"6" = "6";
/* No comment provided by engineer. */
"above, then:" = "наверху, затем:";
"About SimpleX" = "О SimpleX";
/* No comment provided by engineer. */
"About SimpleX Chat" = "Информация о SimpleX Chat";
/* No comment provided by engineer. */
"above, then choose:" = "наверху, затем выберите:";
/* accept contact request via notification */
"Accept" = "Принять";
@@ -85,15 +88,15 @@
/* call status */
"accepted" = "принятый звонок";
/* No comment provided by engineer. */
"Add contact" = "Добавить контакт";
/* No comment provided by engineer. */
"Add contact to start a new chat" = "Добавьте контакт, чтобы начать разговор";
/* No comment provided by engineer. */
"All your contacts will remain connected" = "Все контакты, которые соединились через этот адрес, сохранятся.";
/* No comment provided by engineer. */
"Already connected?" = "Соединение уже установлено?";
/* accept incoming call via notification */
"Answer" = "Ответить";
@@ -160,6 +163,9 @@
/* No comment provided by engineer. */
"Connect via one-time link?" = "Соединиться через одноразовую ссылку?";
/* No comment provided by engineer. */
"Connect with the developers" = "Соединиться с разработчиками";
/* No comment provided by engineer. */
"connected" = "соединение установлено";
@@ -215,6 +221,9 @@
/* No comment provided by engineer. */
"Create" = "Создать";
/* No comment provided by engineer. */
"Create 1-time link / QR code" = "Создать ссылку / QR код";
/* No comment provided by engineer. */
"Create address" = "Создать адрес";
@@ -222,11 +231,14 @@
"Create link / QR code" = "Создать ссылку / QR код";
/* No comment provided by engineer. */
"Create profile" = "Создать профиль";
"Create your profile" = "Создать профиль";
/* No comment provided by engineer. */
"Currently maximum supported file size is %@." = "Максимальный размер файла - %@.";
/* No comment provided by engineer. */
"Decentralized" = "Децентрализованный";
/* No comment provided by engineer. */
"Delete" = "Удалить";
@@ -317,30 +329,39 @@
/* No comment provided by engineer. */
"Help" = "Помощь";
/* 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 markdown" = "Как форматировать";
/* No comment provided by engineer. */
"How to use SimpleX Chat" = "Как использовать SimpleX Chat";
"If you can't meet in person, **show QR code in the 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 cannot meet in person, you can **show QR code in the video call**, or you can share the invitation link via any other channel." = "Если вы не можете встретиться лично, вы можете **показать QR код во время видеозвонка** или отправить ссылку через любой другой канал связи.";
/* No comment provided by engineer. */
"If you received SimpleX Chat invitation link you can open it in your browser:" = "Если вы получили ссылку с приглашением из SimpleX Chat, вы можете открыть её в браузере:";
/* ignore incoming call via notification */
"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. */
"In person or via a video call the most secure way to connect." = "При встрече или в видеозвонке самый безопасный способ установить соединение";
/* call status */
"in progress" = "активный звонок";
@@ -359,15 +380,27 @@
/* chat list item title */
"invited to connect" = "приглашение соединиться";
/* 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. */
"It's secure to share - only one contact can use it." = "Ей безопасно поделиться - только один контакт может использовать её.";
/* No comment provided by engineer. */
"italic" = "курсив";
/* No comment provided by engineer. */
"Large file!" = "Большой файл!";
/* 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." = "Пожалуйста, проверьте, что адреса SMP серверов имеют правильный формат, каждый адрес на отдельной строке и не повторяется.";
/* 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. */
"Markdown in messages" = "Форматирование сообщений";
@@ -392,30 +425,60 @@
/* No comment provided by engineer. */
"Notifications are disabled!" = "Уведомления выключены";
/* No comment provided by engineer. */
"One-time invitation link" = "Одноразовая ссылка";
/* No comment provided by engineer. */
"Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Только пользовательские устройства хранят контакты, группы и сообщения, которые отправляются **с двухуровневым end-to-end шифрованием**";
/* No comment provided by engineer. */
"Open Settings" = "Открыть Настройки";
/* No comment provided by engineer. */
"Open-source protocol and code anybody can run the servers." = "Открытый протокол и код - кто угодно может запускать серверы.";
/* No comment provided by engineer. */
"or" = "или";
/* No comment provided by engineer. */
"Or open the link in the browser and tap **Open in mobile**." = "Или откройте ссылку в браузере и нажмите **Open in mobile**.";
/* No comment provided by engineer. */
"Paste" = "Вставить";
/* No comment provided by engineer. */
"Paste received link" = "Вставить полученную ссылку";
/* No comment provided by engineer. */
"Paste the link you received" = "Вставьте полученную ссылку";
/* 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. */
"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 and try again." = "Пожалуйста, проверьте ваше соединение с сетью и попробуйте еще раз.";
/* No comment provided by engineer. */
"Privacy redefined" = "Более конфиденциальный";
/* No comment provided by engineer. */
"Profile image" = "Аватар";
/* No comment provided by engineer. */
"Read" = "Прочитано";
/* 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. */
"received answer…" = "получен ответ…";
@@ -443,6 +506,9 @@
/* No comment provided by engineer. */
"Saved SMP servers will be removed" = "Сохраненные SMP серверы будут удалены";
/* No comment provided by engineer. */
"Scan contact's QR code" = "Сосканировать QR код контакта";
/* No comment provided by engineer. */
"Scan QR code" = "Сканировать QR код";
@@ -467,9 +533,6 @@
/* No comment provided by engineer. */
"Show pending connections" = "Показать ожидаемые соединения";
/* No comment provided by engineer. */
"Show QR code to your contact\nto scan from the app" = "Покажите QR код вашему контакту для сканирования в приложении";
/* No comment provided by engineer. */
"SMP servers" = "SMP серверы";
@@ -488,6 +551,9 @@
/* No comment provided by engineer. */
"Thank you for installing SimpleX Chat!" = "Спасибо, что установили SimpleX Chat!";
/* 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." = "Приложение может посылать вам уведомления о сообщениях и запросах на соединение - уведомления можно включить в Настройках.";
@@ -501,19 +567,28 @@
"The contact you shared this link with will NOT be able to connect!" = "Контакт, которому вы отправили эту ссылку, не сможет соединиться!";
/* No comment provided by engineer. */
"The messaging and application platform 100% private by design!" = "Платформа для сообщений и приложений, которая защищает вашу личную информацию и безопасность.";
"The next generation of private messaging" = "Новое поколение приватных сообщений";
/* 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. */
"To ask any questions and to receive SimpleX Chat updates." = "Чтобы задать вопросы и получать уведомления о SimpleX Chat.";
/* No comment provided by engineer. */
"To ask any questions and to receive updates:" = "Чтобы задать вопросы и получать уведомления о новых версиях,";
/* No comment provided by engineer. */
"To connect via link" = "Соединиться через ссылку";
"To make a new connection" = "Чтобы соединиться";
/* No comment provided by engineer. */
"To start a new chat" = "Начать новый разговор";
"To make your first private connection, choose **one of the following**:" = "Чтобы сделать ваше первое приватное соединение, выберите **одно из**:";
/* 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." = "Чтобы защитить вашу конфиденциальность, вместо ID пользователей, которые есть в других платформах, SimpleX использует ID для очередей сообщений, разные для каждого контакта.";
/* No comment provided by engineer. */
"Trying to connect to the server used to receive messages from this contact (error: %@)." = "Устанавливается соединение с сервером, через который вы получаете сообщения от этого контакта (ошибка: %@).";
@@ -585,7 +660,7 @@
"You can use markdown to format messages:" = "Вы можете форматировать сообщения:";
/* No comment provided by engineer. */
"You control your chat!" = "Вы котролируете Ваш чат!";
"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 invited your contact" = "Вы пригласили ваш контакт";
@@ -611,6 +686,9 @@
/* No comment provided by engineer. */
"Your chats" = "Ваши чаты";
/* No comment provided by engineer. */
"Your contact can scan it from the app" = "Ваш контакт может сосканировать QR в приложении";
/* 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Вы можете отменить соединение и удалить контакт (и попробовать позже с другой ссылкой).";
@@ -624,7 +702,7 @@
"Your profile will be sent to the contact that you received this link from" = "Ваш профиль будет отправлен контакту, от которого вы получили эту ссылку.";
/* No comment provided by engineer. */
"Your profile, contacts and messages (once delivered) are only stored locally on your device." = "Ваш профиль, контакты и сообщения (после доставки) хранятся только на вашем устройстве.";
"Your profile, contacts and delivered messages are stored on your device." = "Ваш профиль, контакты и доставленные сообщения хранятся на вашем устройстве.";
/* No comment provided by engineer. */
"Your settings" = "Настройки";