diff --git a/apps/ios/Shared/AppDelegate.swift b/apps/ios/Shared/AppDelegate.swift index 145e36279..24c0eeb60 100644 --- a/apps/ios/Shared/AppDelegate.swift +++ b/apps/ios/Shared/AppDelegate.swift @@ -15,6 +15,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { logger.debug("AppDelegate: didFinishLaunchingWithOptions") application.registerForRemoteNotifications() if #available(iOS 17.0, *) { trackKeyboard() } + NotificationCenter.default.addObserver(self, selector: #selector(pasteboardChanged), name: UIPasteboard.changedNotification, object: nil) return true } @@ -36,6 +37,10 @@ class AppDelegate: NSObject, UIApplicationDelegate { ChatModel.shared.keyboardHeight = 0 } + @objc func pasteboardChanged() { + ChatModel.shared.pasteboardHasStrings = UIPasteboard.general.hasStrings + } + func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let token = deviceToken.map { String(format: "%02hhx", $0) }.joined() logger.debug("AppDelegate: didRegisterForRemoteNotificationsWithDeviceToken \(token)") diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 0cc281fda..db0f13869 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -89,14 +89,15 @@ final class ChatModel: ObservableObject { @Published var showCallView = false // remote desktop @Published var remoteCtrlSession: RemoteCtrlSession? - // currently showing QR code - @Published var connReqInv: String? + // currently showing invitation + @Published var showingInvitation: ShowingInvitation? // audio recording and playback @Published var stopPreviousRecPlay: URL? = nil // coordinates currently playing source @Published var draft: ComposeState? @Published var draftChatId: String? // tracks keyboard height via subscription in AppDelegate @Published var keyboardHeight: CGFloat = 0 + @Published var pasteboardHasStrings: Bool = UIPasteboard.general.hasStrings var messageDelivery: Dictionary Void> = [:] @@ -620,14 +621,16 @@ final class ChatModel: ObservableObject { } func dismissConnReqView(_ id: String) { - if let connReqInv = connReqInv, - let c = getChat(id), - case let .contactConnection(contactConnection) = c.chatInfo, - connReqInv == contactConnection.connReqInv { + if id == showingInvitation?.connId { + markShowingInvitationUsed() dismissAllSheets() } } + func markShowingInvitationUsed() { + showingInvitation?.connChatUsed = true + } + func removeChat(_ id: String) { withAnimation { chats.removeAll(where: { $0.id == id }) @@ -704,6 +707,11 @@ final class ChatModel: ObservableObject { } } +struct ShowingInvitation { + var connId: String + var connChatUsed: Bool +} + struct NTFContactRequest { var incognito: Bool var chatId: String diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index eff311096..ddac78c3d 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -581,15 +581,15 @@ func apiVerifyGroupMember(_ groupId: Int64, _ groupMemberId: Int64, connectionCo return nil } -func apiAddContact(incognito: Bool) async -> (String, PendingContactConnection)? { +func apiAddContact(incognito: Bool) async -> ((String, PendingContactConnection)?, Alert?) { guard let userId = ChatModel.shared.currentUser?.userId else { logger.error("apiAddContact: no current user") - return nil + return (nil, nil) } let r = await chatSendCmd(.apiAddContact(userId: userId, incognito: incognito), bgTask: false) - if case let .invitation(_, connReqInvitation, connection) = r { return (connReqInvitation, connection) } - AlertManager.shared.showAlert(connectionErrorAlert(r)) - return nil + if case let .invitation(_, connReqInvitation, connection) = r { return ((connReqInvitation, connection), nil) } + let alert = connectionErrorAlert(r) + return (nil, alert) } func apiSetConnectionIncognito(connId: Int64, incognito: Bool) async throws -> PendingContactConnection? { diff --git a/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift b/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift index d0d2bdf3d..cad6401cc 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift @@ -9,7 +9,7 @@ import SwiftUI import SimpleXChat -private let uiLinkColor = UIColor(red: 0, green: 0.533, blue: 1, alpha: 1) +let uiLinkColor = UIColor(red: 0, green: 0.533, blue: 1, alpha: 1) private let noTyping = Text(" ") @@ -144,7 +144,7 @@ private func linkText(_ s: String, _ link: String, _ preview: Bool, prefix: Stri ]))).underline() } -private func simplexLinkText(_ linkType: SimplexLinkType, _ smpHosts: [String]) -> String { +func simplexLinkText(_ linkType: SimplexLinkType, _ smpHosts: [String]) -> String { linkType.description + " " + "(via \(smpHosts.first ?? "?"))" } diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 6e2c0c155..a09c5643b 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -250,8 +250,8 @@ struct ChatView: View { } private func searchToolbar() -> some View { - HStack { - HStack { + HStack(spacing: 12) { + HStack(spacing: 4) { Image(systemName: "magnifyingglass") TextField("Search", text: $searchText) .focused($searchFocussed) @@ -264,9 +264,9 @@ struct ChatView: View { Image(systemName: "xmark.circle.fill").opacity(searchText == "" ? 0 : 1) } } - .padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6)) + .padding(EdgeInsets(top: 7, leading: 7, bottom: 7, trailing: 7)) .foregroundColor(.secondary) - .background(Color(.secondarySystemBackground)) + .background(Color(.tertiarySystemFill)) .cornerRadius(10.0) Button ("Cancel") { diff --git a/apps/ios/Shared/Views/ChatList/ChatHelp.swift b/apps/ios/Shared/Views/ChatList/ChatHelp.swift index 774151243..2435c9a4f 100644 --- a/apps/ios/Shared/Views/ChatList/ChatHelp.swift +++ b/apps/ios/Shared/Views/ChatList/ChatHelp.swift @@ -11,7 +11,7 @@ import SwiftUI struct ChatHelp: View { @EnvironmentObject var chatModel: ChatModel @Binding var showSettings: Bool - @State private var showAddChat = false + @State private var newChatMenuOption: NewChatMenuOption? = nil var body: some View { ScrollView { chatHelp() } @@ -39,13 +39,12 @@ struct ChatHelp: View { HStack(spacing: 8) { Text("Tap button ") - NewChatButton(showAddChat: $showAddChat) + NewChatMenuButton(newChatMenuOption: $newChatMenuOption) Text("above, then choose:") } - 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.") + Text("**Add contact**: to create a new invitation link, or connect via a link you received.") + Text("**Create group**: to create a new group.") } .padding(.top, 24) diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 1d8673320..3d0551de6 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -12,8 +12,12 @@ import SimpleXChat struct ChatListView: View { @EnvironmentObject var chatModel: ChatModel @Binding var showSettings: Bool + @State private var searchMode = false + @FocusState private var searchFocussed @State private var searchText = "" - @State private var showAddChat = false + @State private var searchShowingSimplexLink = false + @State private var searchChatFilteredBySimplexLink: String? = nil + @State private var newChatMenuOption: NewChatMenuOption? = nil @State private var userPickerVisible = false @State private var showConnectDesktop = false @AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false @@ -62,11 +66,7 @@ struct ChatListView: View { private var chatListView: some View { VStack { - if chatModel.chats.count > 0 { - chatList.searchable(text: $searchText) - } else { - chatList - } + chatList } .onDisappear() { withAnimation { userPickerVisible = false } } .refreshable { @@ -85,9 +85,9 @@ struct ChatListView: View { secondaryButton: .cancel() )) } - .offset(x: -8) .listStyle(.plain) .navigationBarTitleDisplayMode(.inline) + .navigationBarHidden(searchMode) .toolbar { ToolbarItem(placement: .navigationBarLeading) { let user = chatModel.currentUser ?? User.sampleData @@ -124,7 +124,7 @@ struct ChatListView: View { } ToolbarItem(placement: .navigationBarTrailing) { switch chatModel.chatRunning { - case .some(true): NewChatButton(showAddChat: $showAddChat) + case .some(true): NewChatMenuButton(newChatMenuOption: $newChatMenuOption) case .some(false): chatStoppedIcon() case .none: EmptyView() } @@ -144,11 +144,25 @@ struct ChatListView: View { @ViewBuilder private var chatList: some View { let cs = filteredChats() ZStack { - List { - ForEach(cs, id: \.viewId) { chat in - ChatListNavLink(chat: chat) - .padding(.trailing, -16) - .disabled(chatModel.chatRunning != true) + VStack { + List { + if !chatModel.chats.isEmpty { + ChatListSearchBar( + searchMode: $searchMode, + searchFocussed: $searchFocussed, + searchText: $searchText, + searchShowingSimplexLink: $searchShowingSimplexLink, + searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink + ) + .listRowSeparator(.hidden) + .frame(maxWidth: .infinity) + } + ForEach(cs, id: \.viewId) { chat in + ChatListNavLink(chat: chat) + .padding(.trailing, -16) + .disabled(chatModel.chatRunning != true) + } + .offset(x: -8) } } .onChange(of: chatModel.chatId) { _ in @@ -182,7 +196,7 @@ struct ChatListView: View { .padding(.trailing, 12) connectButton("Tap to start a new chat") { - showAddChat = true + newChatMenuOption = .newContact } Spacer() @@ -214,22 +228,25 @@ struct ChatListView: View { } private func filteredChats() -> [Chat] { - let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase - return s == "" && !showUnreadAndFavorites + if let linkChatId = searchChatFilteredBySimplexLink { + return chatModel.chats.filter { $0.id == linkChatId } + } else { + let s = searchString() + return s == "" && !showUnreadAndFavorites ? chatModel.chats : chatModel.chats.filter { chat in let cInfo = chat.chatInfo switch cInfo { case let .direct(contact): return s == "" - ? filtered(chat) - : (viewNameContains(cInfo, s) || - contact.profile.displayName.localizedLowercase.contains(s) || - contact.fullName.localizedLowercase.contains(s)) + ? filtered(chat) + : (viewNameContains(cInfo, s) || + contact.profile.displayName.localizedLowercase.contains(s) || + contact.fullName.localizedLowercase.contains(s)) case let .group(gInfo): return s == "" - ? (filtered(chat) || gInfo.membership.memberStatus == .memInvited) - : viewNameContains(cInfo, s) + ? (filtered(chat) || gInfo.membership.memberStatus == .memInvited) + : viewNameContains(cInfo, s) case .contactRequest: return s == "" || viewNameContains(cInfo, s) case let .contactConnection(conn): @@ -238,6 +255,11 @@ struct ChatListView: View { return false } } + } + + func searchString() -> String { + searchShowingSimplexLink ? "" : searchText.trimmingCharacters(in: .whitespaces).localizedLowercase + } func filtered(_ chat: Chat) -> Bool { (chat.chatInfo.chatSettings?.favorite ?? false) || chat.chatStats.unreadCount > 0 || chat.chatStats.unreadChat @@ -249,6 +271,121 @@ struct ChatListView: View { } } +struct ChatListSearchBar: View { + @EnvironmentObject var m: ChatModel + @Binding var searchMode: Bool + @FocusState.Binding var searchFocussed: Bool + @Binding var searchText: String + @Binding var searchShowingSimplexLink: Bool + @Binding var searchChatFilteredBySimplexLink: String? + @State private var ignoreSearchTextChange = false + @State private var showScanCodeSheet = false + @State private var alert: PlanAndConnectAlert? + @State private var sheet: PlanAndConnectActionSheet? + + var body: some View { + VStack(spacing: 12) { + HStack(spacing: 12) { + HStack(spacing: 4) { + Image(systemName: "magnifyingglass") + TextField("Search or paste SimpleX link", text: $searchText) + .disabled(searchShowingSimplexLink) + .focused($searchFocussed) + .frame(maxWidth: .infinity) + if searchFocussed || searchShowingSimplexLink { + Image(systemName: "xmark.circle.fill") + .opacity(searchText == "" ? 0 : 1) + .onTapGesture { + searchText = "" + } + } else if searchText == "" { + HStack(spacing: 24) { + if m.pasteboardHasStrings { + Image(systemName: "doc") + .onTapGesture { + if let str = UIPasteboard.general.string { + searchText = str + } + } + } + + Image(systemName: "qrcode") + .resizable() + .scaledToFit() + .frame(width: 20, height: 20) + .onTapGesture { + showScanCodeSheet = true + } + } + .padding(.trailing, 2) + } + } + .padding(EdgeInsets(top: 7, leading: 7, bottom: 7, trailing: 7)) + .foregroundColor(.secondary) + .background(Color(.tertiarySystemFill)) + .cornerRadius(10.0) + + if searchFocussed { + Text("Cancel") + .foregroundColor(.accentColor) + .onTapGesture { + searchText = "" + searchFocussed = false + } + } + } + Divider() + } + .sheet(isPresented: $showScanCodeSheet) { + NewChatView(selection: .connect, showQRCodeScanner: true) + .environment(\EnvironmentValues.refresh as! WritableKeyPath, nil) // fixes .refreshable in ChatListView affecting nested view + } + .onChange(of: searchFocussed) { sf in + withAnimation { searchMode = sf } + } + .onChange(of: searchText) { t in + if ignoreSearchTextChange { + ignoreSearchTextChange = false + } else { + if let link = strHasSingleSimplexLink(t.trimmingCharacters(in: .whitespaces)) { // if SimpleX link is pasted, show connection dialogue + searchFocussed = false + if case let .simplexLink(linkType, _, smpHosts) = link.format { + ignoreSearchTextChange = true + searchText = simplexLinkText(linkType, smpHosts) + } + searchShowingSimplexLink = true + searchChatFilteredBySimplexLink = nil + connect(link.text) + } else { + if t != "" { // if some other text is pasted, enter search mode + searchFocussed = true + } + searchShowingSimplexLink = false + searchChatFilteredBySimplexLink = nil + } + } + } + .alert(item: $alert) { a in + planAndConnectAlert(a, dismiss: true, cleanup: { searchText = "" }) + } + .actionSheet(item: $sheet) { s in + planAndConnectActionSheet(s, dismiss: true, cleanup: { searchText = "" }) + } + } + + private func connect(_ link: String) { + planAndConnect( + link, + showAlert: { alert = $0 }, + showActionSheet: { sheet = $0 }, + dismiss: false, + incognito: nil, + filterKnownContact: { searchChatFilteredBySimplexLink = $0.id }, + filterKnownGroup: { searchChatFilteredBySimplexLink = $0.id } + ) + } +} + func chatStoppedIcon() -> some View { Button { AlertManager.shared.showAlertMsg( diff --git a/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift b/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift index 6d2fba99c..42e90232d 100644 --- a/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift +++ b/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift @@ -164,6 +164,28 @@ struct ContactConnectionInfo: View { } } +private func shareLinkButton(_ connReqInvitation: String) -> some View { + Button { + showShareSheet(items: [simplexChatLink(connReqInvitation)]) + } label: { + settingsRow("square.and.arrow.up") { + Text("Share 1-time link") + } + } +} + +private func oneTimeLinkLearnMoreButton() -> some View { + NavigationLink { + AddContactLearnMore(showTitle: false) + .navigationTitle("One-time invitation link") + .navigationBarTitleDisplayMode(.large) + } label: { + settingsRow("info.circle") { + Text("Learn more") + } + } +} + struct ContactConnectionInfo_Previews: PreviewProvider { static var previews: some View { ContactConnectionInfo(contactConnection: PendingContactConnection.getSampleData()) diff --git a/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift b/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift index 182149cbd..45eb78332 100644 --- a/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift +++ b/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift @@ -9,8 +9,20 @@ import SwiftUI struct AddContactLearnMore: View { + var showTitle: Bool + var body: some View { List { + if showTitle { + Text("One-time invitation link") + .font(.largeTitle) + .bold() + .fixedSize(horizontal: false, vertical: true) + .padding(.vertical) + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + } VStack(alignment: .leading, spacing: 18) { Text("To connect, your contact can scan QR code or use the link in the app.") Text("If you can't meet in person, show QR code in a video call, or share the link.") @@ -23,6 +35,6 @@ struct AddContactLearnMore: View { struct AddContactLearnMore_Previews: PreviewProvider { static var previews: some View { - AddContactLearnMore() + AddContactLearnMore(showTitle: true) } } diff --git a/apps/ios/Shared/Views/NewChat/AddContactView.swift b/apps/ios/Shared/Views/NewChat/AddContactView.swift deleted file mode 100644 index de8e35d2a..000000000 --- a/apps/ios/Shared/Views/NewChat/AddContactView.swift +++ /dev/null @@ -1,129 +0,0 @@ -// -// AddContactView.swift -// SimpleX -// -// Created by Evgeny Poberezkin on 29/01/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import SwiftUI -import CoreImage.CIFilterBuiltins -import SimpleXChat - -struct AddContactView: View { - @EnvironmentObject private var chatModel: ChatModel - @Binding var contactConnection: PendingContactConnection? - var connReqInvitation: String - @AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false - - var body: some View { - VStack { - List { - Section { - if connReqInvitation != "" { - SimpleXLinkQRCode(uri: connReqInvitation) - } else { - ProgressView() - .progressViewStyle(.circular) - .scaleEffect(2) - .frame(maxWidth: .infinity) - .padding(.vertical) - } - IncognitoToggle(incognitoEnabled: $incognitoDefault) - .disabled(contactConnection == nil) - shareLinkButton(connReqInvitation) - oneTimeLinkLearnMoreButton() - } header: { - Text("1-time link") - } footer: { - sharedProfileInfo(incognitoDefault) - } - } - } - .onAppear { chatModel.connReqInv = connReqInvitation } - .onChange(of: incognitoDefault) { incognito in - Task { - do { - if let contactConn = contactConnection, - let conn = try await apiSetConnectionIncognito(connId: contactConn.pccConnId, incognito: incognito) { - await MainActor.run { - contactConnection = conn - chatModel.updateContactConnection(conn) - } - } - } catch { - logger.error("apiSetConnectionIncognito error: \(responseError(error))") - } - } - } - } -} - -struct IncognitoToggle: View { - @Binding var incognitoEnabled: Bool - @State private var showIncognitoSheet = false - - var body: some View { - ZStack(alignment: .leading) { - Image(systemName: incognitoEnabled ? "theatermasks.fill" : "theatermasks") - .frame(maxWidth: 24, maxHeight: 24, alignment: .center) - .foregroundColor(incognitoEnabled ? Color.indigo : .secondary) - .font(.system(size: 14)) - Toggle(isOn: $incognitoEnabled) { - HStack(spacing: 6) { - Text("Incognito") - Image(systemName: "info.circle") - .foregroundColor(.accentColor) - .font(.system(size: 14)) - } - .onTapGesture { - showIncognitoSheet = true - } - } - .padding(.leading, 36) - } - .sheet(isPresented: $showIncognitoSheet) { - IncognitoHelp() - } - } -} - -func sharedProfileInfo(_ incognito: Bool) -> Text { - let name = ChatModel.shared.currentUser?.displayName ?? "" - return Text( - incognito - ? "A new random profile will be shared." - : "Your profile **\(name)** will be shared." - ) -} - -func shareLinkButton(_ connReqInvitation: String) -> some View { - Button { - showShareSheet(items: [simplexChatLink(connReqInvitation)]) - } label: { - settingsRow("square.and.arrow.up") { - Text("Share 1-time link") - } - } -} - -func oneTimeLinkLearnMoreButton() -> some View { - NavigationLink { - AddContactLearnMore() - .navigationTitle("One-time invitation link") - .navigationBarTitleDisplayMode(.large) - } label: { - settingsRow("info.circle") { - Text("Learn more") - } - } -} - -struct AddContactView_Previews: PreviewProvider { - static var previews: some View { - AddContactView( - contactConnection: Binding.constant(PendingContactConnection.getSampleData()), - connReqInvitation: "https://simplex.chat/invitation#/?v=1&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FFe5ICmvrm4wkrr6X1LTMii-lhBqLeB76%23MCowBQYDK2VuAyEAdhZZsHpuaAk3Hh1q0uNb_6hGTpuwBIrsp2z9U2T0oC0%3D&e2e=v%3D1%26x3dh%3DMEIwBQYDK2VvAzkAcz6jJk71InuxA0bOX7OUhddfB8Ov7xwQIlIDeXBRZaOntUU4brU5Y3rBzroZBdQJi0FKdtt_D7I%3D%2CMEIwBQYDK2VvAzkA-hDvk1duBi1hlOr08VWSI-Ou4JNNSQjseY69QyKm7Kgg1zZjbpGfyBqSZ2eqys6xtoV4ZtoQUXQ%3D" - ) - } -} diff --git a/apps/ios/Shared/Views/NewChat/ConnectViaLinkView.swift b/apps/ios/Shared/Views/NewChat/ConnectViaLinkView.swift deleted file mode 100644 index 9df767485..000000000 --- a/apps/ios/Shared/Views/NewChat/ConnectViaLinkView.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// ConnectViaLinkView.swift -// SimpleX (iOS) -// -// Created by Evgeny on 21/09/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import SwiftUI - -enum ConnectViaLinkTab: String { - case scan - case paste -} - -struct ConnectViaLinkView: View { - @State private var selection: ConnectViaLinkTab = connectViaLinkTabDefault.get() - - var body: some View { - TabView(selection: $selection) { - ScanToConnectView() - .tabItem { - Label("Scan QR code", systemImage: "qrcode") - } - .tag(ConnectViaLinkTab.scan) - PasteToConnectView() - .tabItem { - Label("Paste received link", systemImage: "doc.plaintext") - } - .tag(ConnectViaLinkTab.paste) - } - .onChange(of: selection) { _ in - connectViaLinkTabDefault.set(selection) - } - } -} - -struct ConnectViaLinkView_Previews: PreviewProvider { - static var previews: some View { - ConnectViaLinkView() - } -} diff --git a/apps/ios/Shared/Views/NewChat/CreateLinkView.swift b/apps/ios/Shared/Views/NewChat/CreateLinkView.swift deleted file mode 100644 index 3be9e1c3b..000000000 --- a/apps/ios/Shared/Views/NewChat/CreateLinkView.swift +++ /dev/null @@ -1,94 +0,0 @@ -// -// CreateLinkView.swift -// SimpleX (iOS) -// -// Created by Evgeny on 21/09/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import SwiftUI -import SimpleXChat - -enum CreateLinkTab { - case oneTime - case longTerm - - var title: LocalizedStringKey { - switch self { - case .oneTime: return "One-time invitation link" - case .longTerm: return "Your SimpleX address" - } - } -} - -struct CreateLinkView: View { - @EnvironmentObject var m: ChatModel - @State var selection: CreateLinkTab - @State var connReqInvitation: String = "" - @State var contactConnection: PendingContactConnection? = nil - @State private var creatingConnReq = false - var viaNavLink = false - - var body: some View { - if viaNavLink { - createLinkView() - } else { - NavigationView { - createLinkView() - } - } - } - - private func createLinkView() -> some View { - TabView(selection: $selection) { - AddContactView(contactConnection: $contactConnection, connReqInvitation: connReqInvitation) - .tabItem { - Label( - connReqInvitation == "" - ? "Create one-time invitation link" - : "One-time invitation link", - systemImage: "1.circle" - ) - } - .tag(CreateLinkTab.oneTime) - UserAddressView(viaCreateLinkView: true) - .tabItem { - Label("Your SimpleX address", systemImage: "infinity.circle") - } - .tag(CreateLinkTab.longTerm) - } - .onChange(of: selection) { _ in - if case .oneTime = selection, connReqInvitation == "", contactConnection == nil && !creatingConnReq { - createInvitation() - } - } - .onAppear { m.connReqInv = connReqInvitation } - .onDisappear { m.connReqInv = nil } - .navigationTitle(selection.title) - .navigationBarTitleDisplayMode(.large) - } - - private func createInvitation() { - creatingConnReq = true - Task { - if let (connReq, pcc) = await apiAddContact(incognito: incognitoGroupDefault.get()) { - await MainActor.run { - m.updateContactConnection(pcc) - connReqInvitation = connReq - contactConnection = pcc - m.connReqInv = connReq - } - } else { - await MainActor.run { - creatingConnReq = false - } - } - } - } -} - -struct CreateLinkView_Previews: PreviewProvider { - static var previews: some View { - CreateLinkView(selection: CreateLinkTab.oneTime) - } -} diff --git a/apps/ios/Shared/Views/NewChat/NewChatButton.swift b/apps/ios/Shared/Views/NewChat/NewChatButton.swift deleted file mode 100644 index 170805b48..000000000 --- a/apps/ios/Shared/Views/NewChat/NewChatButton.swift +++ /dev/null @@ -1,466 +0,0 @@ -// -// NewChatButton.swift -// SimpleX -// -// Created by Evgeny Poberezkin on 31/01/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import SwiftUI -import SimpleXChat - -enum NewChatAction: Identifiable { - case createLink(link: String, connection: PendingContactConnection) - case connectViaLink - case createGroup - - var id: String { - switch self { - case let .createLink(link, _): return "createLink \(link)" - case .connectViaLink: return "connectViaLink" - case .createGroup: return "createGroup" - } - } -} - -struct NewChatButton: View { - @Binding var showAddChat: Bool - @State private var actionSheet: NewChatAction? - - var body: some View { - Button { showAddChat = true } label: { - Image(systemName: "square.and.pencil") - .resizable() - .scaledToFit() - .frame(width: 24, height: 24) - } - .confirmationDialog("Start a new chat", isPresented: $showAddChat, titleVisibility: .visible) { - Button("Share one-time invitation link") { addContactAction() } - Button("Connect via link / QR code") { actionSheet = .connectViaLink } - Button("Create secret group") { actionSheet = .createGroup } - } - .sheet(item: $actionSheet) { sheet in - switch sheet { - case let .createLink(link, pcc): - CreateLinkView(selection: .oneTime, connReqInvitation: link, contactConnection: pcc) - case .connectViaLink: ConnectViaLinkView() - case .createGroup: AddGroupView() - } - } - } - - func addContactAction() { - Task { - if let (connReq, pcc) = await apiAddContact(incognito: incognitoGroupDefault.get()) { - await MainActor.run { - ChatModel.shared.updateContactConnection(pcc) - } - actionSheet = .createLink(link: connReq, connection: pcc) - } - } - } -} - -enum PlanAndConnectAlert: Identifiable { - case ownInvitationLinkConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) - case invitationLinkConnecting(connectionLink: String) - case ownContactAddressConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) - case contactAddressConnectingConfirmReconnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) - case groupLinkConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) - case groupLinkConnectingConfirmReconnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) - case groupLinkConnecting(connectionLink: String, groupInfo: GroupInfo?) - - var id: String { - switch self { - case let .ownInvitationLinkConfirmConnect(connectionLink, _, _): return "ownInvitationLinkConfirmConnect \(connectionLink)" - case let .invitationLinkConnecting(connectionLink): return "invitationLinkConnecting \(connectionLink)" - case let .ownContactAddressConfirmConnect(connectionLink, _, _): return "ownContactAddressConfirmConnect \(connectionLink)" - case let .contactAddressConnectingConfirmReconnect(connectionLink, _, _): return "contactAddressConnectingConfirmReconnect \(connectionLink)" - case let .groupLinkConfirmConnect(connectionLink, _, _): return "groupLinkConfirmConnect \(connectionLink)" - case let .groupLinkConnectingConfirmReconnect(connectionLink, _, _): return "groupLinkConnectingConfirmReconnect \(connectionLink)" - case let .groupLinkConnecting(connectionLink, _): return "groupLinkConnecting \(connectionLink)" - } - } -} - -func planAndConnectAlert(_ alert: PlanAndConnectAlert, dismiss: Bool) -> Alert { - switch alert { - case let .ownInvitationLinkConfirmConnect(connectionLink, connectionPlan, incognito): - return Alert( - title: Text("Connect to yourself?"), - message: Text("This is your own one-time link!"), - primaryButton: .destructive( - Text(incognito ? "Connect incognito" : "Connect"), - action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) } - ), - secondaryButton: .cancel() - ) - case .invitationLinkConnecting: - return Alert( - title: Text("Already connecting!"), - message: Text("You are already connecting via this one-time link!") - ) - case let .ownContactAddressConfirmConnect(connectionLink, connectionPlan, incognito): - return Alert( - title: Text("Connect to yourself?"), - message: Text("This is your own SimpleX address!"), - primaryButton: .destructive( - Text(incognito ? "Connect incognito" : "Connect"), - action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) } - ), - secondaryButton: .cancel() - ) - case let .contactAddressConnectingConfirmReconnect(connectionLink, connectionPlan, incognito): - return Alert( - title: Text("Repeat connection request?"), - message: Text("You have already requested connection via this address!"), - primaryButton: .destructive( - Text(incognito ? "Connect incognito" : "Connect"), - action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) } - ), - secondaryButton: .cancel() - ) - case let .groupLinkConfirmConnect(connectionLink, connectionPlan, incognito): - return Alert( - title: Text("Join group?"), - message: Text("You will connect to all group members."), - primaryButton: .default( - Text(incognito ? "Join incognito" : "Join"), - action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) } - ), - secondaryButton: .cancel() - ) - case let .groupLinkConnectingConfirmReconnect(connectionLink, connectionPlan, incognito): - return Alert( - title: Text("Repeat join request?"), - message: Text("You are already joining the group via this link!"), - primaryButton: .destructive( - Text(incognito ? "Join incognito" : "Join"), - action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) } - ), - secondaryButton: .cancel() - ) - case let .groupLinkConnecting(_, groupInfo): - if let groupInfo = groupInfo { - return Alert( - title: Text("Group already exists!"), - message: Text("You are already joining the group \(groupInfo.displayName).") - ) - } else { - return Alert( - title: Text("Already joining the group!"), - message: Text("You are already joining the group via this link.") - ) - } - } -} - -enum PlanAndConnectActionSheet: Identifiable { - case askCurrentOrIncognitoProfile(connectionLink: String, connectionPlan: ConnectionPlan?, title: LocalizedStringKey) - case askCurrentOrIncognitoProfileDestructive(connectionLink: String, connectionPlan: ConnectionPlan, title: LocalizedStringKey) - case askCurrentOrIncognitoProfileConnectContactViaAddress(contact: Contact) - case ownGroupLinkConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool?, groupInfo: GroupInfo) - - var id: String { - switch self { - case let .askCurrentOrIncognitoProfile(connectionLink, _, _): return "askCurrentOrIncognitoProfile \(connectionLink)" - case let .askCurrentOrIncognitoProfileDestructive(connectionLink, _, _): return "askCurrentOrIncognitoProfileDestructive \(connectionLink)" - case let .askCurrentOrIncognitoProfileConnectContactViaAddress(contact): return "askCurrentOrIncognitoProfileConnectContactViaAddress \(contact.contactId)" - case let .ownGroupLinkConfirmConnect(connectionLink, _, _, _): return "ownGroupLinkConfirmConnect \(connectionLink)" - } - } -} - -func planAndConnectActionSheet(_ sheet: PlanAndConnectActionSheet, dismiss: Bool) -> ActionSheet { - switch sheet { - case let .askCurrentOrIncognitoProfile(connectionLink, connectionPlan, title): - return ActionSheet( - title: Text(title), - buttons: [ - .default(Text("Use current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: false) }, - .default(Text("Use new incognito profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: true) }, - .cancel() - ] - ) - case let .askCurrentOrIncognitoProfileDestructive(connectionLink, connectionPlan, title): - return ActionSheet( - title: Text(title), - buttons: [ - .destructive(Text("Use current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: false) }, - .destructive(Text("Use new incognito profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: true) }, - .cancel() - ] - ) - case let .askCurrentOrIncognitoProfileConnectContactViaAddress(contact): - return ActionSheet( - title: Text("Connect with \(contact.chatViewName)"), - buttons: [ - .default(Text("Use current profile")) { connectContactViaAddress_(contact, dismiss: dismiss, incognito: false) }, - .default(Text("Use new incognito profile")) { connectContactViaAddress_(contact, dismiss: dismiss, incognito: true) }, - .cancel() - ] - ) - case let .ownGroupLinkConfirmConnect(connectionLink, connectionPlan, incognito, groupInfo): - if let incognito = incognito { - return ActionSheet( - title: Text("Join your group?\nThis is your link for group \(groupInfo.displayName)!"), - buttons: [ - .default(Text("Open group")) { openKnownGroup(groupInfo, dismiss: dismiss, showAlreadyExistsAlert: nil) }, - .destructive(Text(incognito ? "Join incognito" : "Join with current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) }, - .cancel() - ] - ) - } else { - return ActionSheet( - title: Text("Join your group?\nThis is your link for group \(groupInfo.displayName)!"), - buttons: [ - .default(Text("Open group")) { openKnownGroup(groupInfo, dismiss: dismiss, showAlreadyExistsAlert: nil) }, - .destructive(Text("Use current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: false) }, - .destructive(Text("Use new incognito profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: true) }, - .cancel() - ] - ) - } - } -} - -func planAndConnect( - _ connectionLink: String, - showAlert: @escaping (PlanAndConnectAlert) -> Void, - showActionSheet: @escaping (PlanAndConnectActionSheet) -> Void, - dismiss: Bool, - incognito: Bool? -) { - Task { - do { - let connectionPlan = try await apiConnectPlan(connReq: connectionLink) - switch connectionPlan { - case let .invitationLink(ilp): - switch ilp { - case .ok: - logger.debug("planAndConnect, .invitationLink, .ok, incognito=\(incognito?.description ?? "nil")") - if let incognito = incognito { - connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) - } else { - showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect via one-time link")) - } - case .ownLink: - logger.debug("planAndConnect, .invitationLink, .ownLink, incognito=\(incognito?.description ?? "nil")") - if let incognito = incognito { - showAlert(.ownInvitationLinkConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) - } else { - showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect to yourself?\nThis is your own one-time link!")) - } - case let .connecting(contact_): - logger.debug("planAndConnect, .invitationLink, .connecting, incognito=\(incognito?.description ?? "nil")") - if let contact = contact_ { - openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyConnectingAlert(contact)) } - } else { - showAlert(.invitationLinkConnecting(connectionLink: connectionLink)) - } - case let .known(contact): - logger.debug("planAndConnect, .invitationLink, .known, incognito=\(incognito?.description ?? "nil")") - openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyExistsAlert(contact)) } - } - case let .contactAddress(cap): - switch cap { - case .ok: - logger.debug("planAndConnect, .contactAddress, .ok, incognito=\(incognito?.description ?? "nil")") - if let incognito = incognito { - connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito) - } else { - showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect via contact address")) - } - case .ownLink: - logger.debug("planAndConnect, .contactAddress, .ownLink, incognito=\(incognito?.description ?? "nil")") - if let incognito = incognito { - showAlert(.ownContactAddressConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) - } else { - showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect to yourself?\nThis is your own SimpleX address!")) - } - case .connectingConfirmReconnect: - logger.debug("planAndConnect, .contactAddress, .connectingConfirmReconnect, incognito=\(incognito?.description ?? "nil")") - if let incognito = incognito { - showAlert(.contactAddressConnectingConfirmReconnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) - } else { - showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "You have already requested connection!\nRepeat connection request?")) - } - case let .connectingProhibit(contact): - logger.debug("planAndConnect, .contactAddress, .connectingProhibit, incognito=\(incognito?.description ?? "nil")") - openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyConnectingAlert(contact)) } - case let .known(contact): - logger.debug("planAndConnect, .contactAddress, .known, incognito=\(incognito?.description ?? "nil")") - openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyExistsAlert(contact)) } - case let .contactViaAddress(contact): - logger.debug("planAndConnect, .contactAddress, .contactViaAddress, incognito=\(incognito?.description ?? "nil")") - if let incognito = incognito { - connectContactViaAddress_(contact, dismiss: dismiss, incognito: incognito) - } else { - showActionSheet(.askCurrentOrIncognitoProfileConnectContactViaAddress(contact: contact)) - } - } - case let .groupLink(glp): - switch glp { - case .ok: - if let incognito = incognito { - showAlert(.groupLinkConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) - } else { - showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Join group")) - } - case let .ownLink(groupInfo): - logger.debug("planAndConnect, .groupLink, .ownLink, incognito=\(incognito?.description ?? "nil")") - showActionSheet(.ownGroupLinkConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito, groupInfo: groupInfo)) - case .connectingConfirmReconnect: - logger.debug("planAndConnect, .groupLink, .connectingConfirmReconnect, incognito=\(incognito?.description ?? "nil")") - if let incognito = incognito { - showAlert(.groupLinkConnectingConfirmReconnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) - } else { - showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "You are already joining the group!\nRepeat join request?")) - } - case let .connectingProhibit(groupInfo_): - logger.debug("planAndConnect, .groupLink, .connectingProhibit, incognito=\(incognito?.description ?? "nil")") - showAlert(.groupLinkConnecting(connectionLink: connectionLink, groupInfo: groupInfo_)) - case let .known(groupInfo): - logger.debug("planAndConnect, .groupLink, .known, incognito=\(incognito?.description ?? "nil")") - openKnownGroup(groupInfo, dismiss: dismiss) { AlertManager.shared.showAlert(groupAlreadyExistsAlert(groupInfo)) } - } - } - } catch { - logger.debug("planAndConnect, plan error") - if let incognito = incognito { - connectViaLink(connectionLink, connectionPlan: nil, dismiss: dismiss, incognito: incognito) - } else { - showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: nil, title: "Connect via link")) - } - } - } -} - -private func connectContactViaAddress_(_ contact: Contact, dismiss: Bool, incognito: Bool) { - Task { - if dismiss { - DispatchQueue.main.async { - dismissAllSheets(animated: true) - } - } - _ = await connectContactViaAddress(contact.contactId, incognito) - } -} - -private func connectViaLink(_ connectionLink: String, connectionPlan: ConnectionPlan?, dismiss: Bool, incognito: Bool) { - Task { - if let (connReqType, pcc) = await apiConnect(incognito: incognito, connReq: connectionLink) { - await MainActor.run { - ChatModel.shared.updateContactConnection(pcc) - } - let crt: ConnReqType - if let plan = connectionPlan { - crt = planToConnReqType(plan) - } else { - crt = connReqType - } - DispatchQueue.main.async { - if dismiss { - dismissAllSheets(animated: true) { - AlertManager.shared.showAlert(connReqSentAlert(crt)) - } - } else { - AlertManager.shared.showAlert(connReqSentAlert(crt)) - } - } - } else { - if dismiss { - DispatchQueue.main.async { - dismissAllSheets(animated: true) - } - } - } - } -} - -func openKnownContact(_ contact: Contact, dismiss: Bool, showAlreadyExistsAlert: (() -> Void)?) { - Task { - let m = ChatModel.shared - if let c = m.getContactChat(contact.contactId) { - DispatchQueue.main.async { - if dismiss { - dismissAllSheets(animated: true) { - m.chatId = c.id - showAlreadyExistsAlert?() - } - } else { - m.chatId = c.id - showAlreadyExistsAlert?() - } - } - } - } -} - -func openKnownGroup(_ groupInfo: GroupInfo, dismiss: Bool, showAlreadyExistsAlert: (() -> Void)?) { - Task { - let m = ChatModel.shared - if let g = m.getGroupChat(groupInfo.groupId) { - DispatchQueue.main.async { - if dismiss { - dismissAllSheets(animated: true) { - m.chatId = g.id - showAlreadyExistsAlert?() - } - } else { - m.chatId = g.id - showAlreadyExistsAlert?() - } - } - } - } -} - -func contactAlreadyConnectingAlert(_ contact: Contact) -> Alert { - mkAlert( - title: "Contact already exists", - message: "You are already connecting to \(contact.displayName)." - ) -} - -func groupAlreadyExistsAlert(_ groupInfo: GroupInfo) -> Alert { - mkAlert( - title: "Group already exists", - message: "You are already in group \(groupInfo.displayName)." - ) -} - -enum ConnReqType: Equatable { - case invitation - case contact - case groupLink - - var connReqSentText: LocalizedStringKey { - switch self { - case .invitation: return "You will be connected when your contact's device is online, please wait or check later!" - case .contact: return "You will be connected when your connection request is accepted, please wait or check later!" - case .groupLink: return "You will be connected when group link host's device is online, please wait or check later!" - } - } -} - -private func planToConnReqType(_ connectionPlan: ConnectionPlan) -> ConnReqType { - switch connectionPlan { - case .invitationLink: return .invitation - case .contactAddress: return .contact - case .groupLink: return .groupLink - } -} - -func connReqSentAlert(_ type: ConnReqType) -> Alert { - return mkAlert( - title: "Connection request sent!", - message: type.connReqSentText - ) -} - -struct NewChatButton_Previews: PreviewProvider { - static var previews: some View { - NewChatButton(showAddChat: Binding.constant(false)) - } -} diff --git a/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift b/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift new file mode 100644 index 000000000..c3452ce18 --- /dev/null +++ b/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift @@ -0,0 +1,52 @@ +// +// NewChatMenuButton.swift +// SimpleX (iOS) +// +// Created by spaced4ndy on 28.11.2023. +// Copyright © 2023 SimpleX Chat. All rights reserved. +// + +import SwiftUI + +enum NewChatMenuOption: Identifiable { + case newContact + case newGroup + + var id: Self { self } +} + +struct NewChatMenuButton: View { + @Binding var newChatMenuOption: NewChatMenuOption? + + var body: some View { + Menu { + Button { + newChatMenuOption = .newContact + } label: { + Text("Add contact") + } + Button { + newChatMenuOption = .newGroup + } label: { + Text("Create group") + } + } label: { + Image(systemName: "square.and.pencil") + .resizable() + .scaledToFit() + .frame(width: 24, height: 24) + } + .sheet(item: $newChatMenuOption) { opt in + switch opt { + case .newContact: NewChatView(selection: .invite) + case .newGroup: AddGroupView() + } + } + } +} + +#Preview { + NewChatMenuButton( + newChatMenuOption: Binding.constant(nil) + ) +} diff --git a/apps/ios/Shared/Views/NewChat/NewChatView.swift b/apps/ios/Shared/Views/NewChat/NewChatView.swift new file mode 100644 index 000000000..b78d92ffc --- /dev/null +++ b/apps/ios/Shared/Views/NewChat/NewChatView.swift @@ -0,0 +1,959 @@ +// +// NewChatView.swift +// SimpleX (iOS) +// +// Created by spaced4ndy on 28.11.2023. +// Copyright © 2023 SimpleX Chat. All rights reserved. +// + +import SwiftUI +import SimpleXChat +import CodeScanner +import AVFoundation + +enum SomeAlert: Identifiable { + case someAlert(alert: Alert, id: String) + + var id: String { + switch self { + case let .someAlert(_, id): return id + } + } +} + +private enum NewChatViewAlert: Identifiable { + case planAndConnectAlert(alert: PlanAndConnectAlert) + case newChatSomeAlert(alert: SomeAlert) + + var id: String { + switch self { + case let .planAndConnectAlert(alert): return "planAndConnectAlert \(alert.id)" + case let .newChatSomeAlert(alert): return "newChatSomeAlert \(alert.id)" + } + } +} + +enum NewChatOption: Identifiable { + case invite + case connect + + var id: Self { self } +} + +struct NewChatView: View { + @EnvironmentObject var m: ChatModel + @State var selection: NewChatOption + @State var showQRCodeScanner = false + @State private var invitationUsed: Bool = false + @State private var contactConnection: PendingContactConnection? = nil + @State private var connReqInvitation: String = "" + @State private var creatingConnReq = false + @State private var pastedLink: String = "" + @State private var alert: NewChatViewAlert? + + var body: some View { + VStack(alignment: .leading) { + HStack { + Text("New chat") + .font(.largeTitle) + .bold() + .fixedSize(horizontal: false, vertical: true) + Spacer() + InfoSheetButton { + AddContactLearnMore(showTitle: true) + } + } + .padding() + .padding(.top) + + Picker("New chat", selection: $selection) { + Label("Add contact", systemImage: "link") + .tag(NewChatOption.invite) + Label("Connect via link", systemImage: "qrcode") + .tag(NewChatOption.connect) + } + .pickerStyle(.segmented) + .padding() + + VStack { + // it seems there's a bug in iOS 15 if several views in switch (or if-else) statement have different transitions + // https://developer.apple.com/forums/thread/714977?answerId=731615022#731615022 + if case .invite = selection { + prepareAndInviteView() + .transition(.move(edge: .leading)) + .onAppear { + createInvitation() + } + } + if case .connect = selection { + ConnectView(showQRCodeScanner: showQRCodeScanner, pastedLink: $pastedLink, alert: $alert) + .transition(.move(edge: .trailing)) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background( + // Rectangle is needed for swipe gesture to work on mostly empty views (creatingLinkProgressView and retryButton) + Rectangle() + .fill(Color(uiColor: .systemGroupedBackground)) + ) + .animation(.easeInOut(duration: 0.3333), value: selection) + .gesture(DragGesture(minimumDistance: 20.0, coordinateSpace: .local) + .onChanged { value in + switch(value.translation.width, value.translation.height) { + case (...0, -30...30): // left swipe + if selection == .invite { + selection = .connect + } + case (0..., -30...30): // right swipe + if selection == .connect { + selection = .invite + } + default: () + } + } + ) + } + .background(Color(.systemGroupedBackground)) + .onChange(of: invitationUsed) { used in + if used && !(m.showingInvitation?.connChatUsed ?? true) { + m.markShowingInvitationUsed() + } + } + .onDisappear { + if !(m.showingInvitation?.connChatUsed ?? true), + let conn = contactConnection { + AlertManager.shared.showAlert(Alert( + title: Text("Keep unused invitation?"), + message: Text("You can view invitation link again in connection details."), + primaryButton: .default(Text("Keep")) {}, + secondaryButton: .destructive(Text("Delete")) { + Task { + await deleteChat(Chat( + chatInfo: .contactConnection(contactConnection: conn), + chatItems: [] + )) + } + } + )) + } + m.showingInvitation = nil + } + .alert(item: $alert) { a in + switch(a) { + case let .planAndConnectAlert(alert): + return planAndConnectAlert(alert, dismiss: true, cleanup: { pastedLink = "" }) + case let .newChatSomeAlert(.someAlert(alert, _)): + return alert + } + } + } + + private func prepareAndInviteView() -> some View { + ZStack { // ZStack is needed for views to not make transitions between each other + if connReqInvitation != "" { + InviteView( + invitationUsed: $invitationUsed, + contactConnection: $contactConnection, + connReqInvitation: connReqInvitation + ) + } else if creatingConnReq { + creatingLinkProgressView() + } else { + retryButton() + } + } + } + + private func createInvitation() { + if connReqInvitation == "" && contactConnection == nil && !creatingConnReq { + creatingConnReq = true + Task { + _ = try? await Task.sleep(nanoseconds: 250_000000) + let (r, apiAlert) = await apiAddContact(incognito: incognitoGroupDefault.get()) + if let (connReq, pcc) = r { + await MainActor.run { + m.updateContactConnection(pcc) + m.showingInvitation = ShowingInvitation(connId: pcc.id, connChatUsed: false) + connReqInvitation = connReq + contactConnection = pcc + } + } else { + await MainActor.run { + creatingConnReq = false + if let apiAlert = apiAlert { + alert = .newChatSomeAlert(alert: .someAlert(alert: apiAlert, id: "createInvitation error")) + } + } + } + } + } + } + + // Rectangle here and in retryButton are needed for gesture to work + private func creatingLinkProgressView() -> some View { + ProgressView("Creating link…") + .progressViewStyle(.circular) + } + + private func retryButton() -> some View { + Button(action: createInvitation) { + VStack(spacing: 6) { + Image(systemName: "arrow.counterclockwise") + Text("Retry") + } + } + } +} + +private struct InviteView: View { + @EnvironmentObject var chatModel: ChatModel + @Binding var invitationUsed: Bool + @Binding var contactConnection: PendingContactConnection? + var connReqInvitation: String + @AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false + + var body: some View { + List { + Section("Share this 1-time invite link") { + shareLinkView() + } + .listRowInsets(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 10)) + + qrCodeView() + + Section { + IncognitoToggle(incognitoEnabled: $incognitoDefault) + } footer: { + sharedProfileInfo(incognitoDefault) + } + } + .onChange(of: incognitoDefault) { incognito in + Task { + do { + if let contactConn = contactConnection, + let conn = try await apiSetConnectionIncognito(connId: contactConn.pccConnId, incognito: incognito) { + await MainActor.run { + contactConnection = conn + chatModel.updateContactConnection(conn) + } + } + } catch { + logger.error("apiSetConnectionIncognito error: \(responseError(error))") + } + } + setInvitationUsed() + } + } + + private func shareLinkView() -> some View { + HStack { + let link = simplexChatLink(connReqInvitation) + linkTextView(link) + Button { + showShareSheet(items: [link]) + setInvitationUsed() + } label: { + Image(systemName: "square.and.arrow.up") + .padding(.top, -7) + } + } + .frame(maxWidth: .infinity) + } + + private func qrCodeView() -> some View { + Section("Or show this code") { + SimpleXLinkQRCode(uri: connReqInvitation, onShare: setInvitationUsed) + .padding() + .background( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .fill(Color(uiColor: .secondarySystemGroupedBackground)) + ) + .padding(.horizontal) + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + } + } + + private func setInvitationUsed() { + if !invitationUsed { + invitationUsed = true + } + } +} + +private struct ConnectView: View { + @Environment(\.dismiss) var dismiss: DismissAction + @State var showQRCodeScanner = false + @State private var cameraAuthorizationStatus: AVAuthorizationStatus? + @Binding var pastedLink: String + @Binding var alert: NewChatViewAlert? + @State private var sheet: PlanAndConnectActionSheet? + + var body: some View { + List { + Section("Paste the link you received") { + pasteLinkView() + } + + scanCodeView() + } + .actionSheet(item: $sheet) { s in + planAndConnectActionSheet(s, dismiss: true, cleanup: { pastedLink = "" }) + } + .onAppear { + let status = AVCaptureDevice.authorizationStatus(for: .video) + cameraAuthorizationStatus = status + if showQRCodeScanner { + switch status { + case .notDetermined: askCameraAuthorization() + case .restricted: showQRCodeScanner = false + case .denied: showQRCodeScanner = false + case .authorized: () + @unknown default: askCameraAuthorization() + } + } + } + } + + func askCameraAuthorization(_ cb: (() -> Void)? = nil) { + AVCaptureDevice.requestAccess(for: .video) { allowed in + cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video) + if allowed { cb?() } + } + } + + @ViewBuilder private func pasteLinkView() -> some View { + if pastedLink == "" { + Button { + if let str = UIPasteboard.general.string { + if let link = strHasSingleSimplexLink(str.trimmingCharacters(in: .whitespaces)) { + pastedLink = link.text + // It would be good to hide it, but right now it is not clear how to release camera in CodeScanner + // https://github.com/twostraws/CodeScanner/issues/121 + // No known tricks worked (changing view ID, wrapping it in another view, etc.) + // showQRCodeScanner = false + connect(pastedLink) + } else { + alert = .newChatSomeAlert(alert: .someAlert( + alert: mkAlert(title: "Invalid link", message: "The text you pasted is not a SimpleX link."), + id: "pasteLinkView: code is not a SimpleX link" + )) + } + } + } label: { + Text("Tap to paste link") + } + .disabled(!ChatModel.shared.pasteboardHasStrings) + .frame(maxWidth: .infinity, alignment: .center) + } else { + linkTextView(pastedLink) + } + } + + private func scanCodeView() -> some View { + Section("Or scan QR code") { + if showQRCodeScanner, case .authorized = cameraAuthorizationStatus { + CodeScannerView(codeTypes: [.qr], scanMode: .continuous, completion: processQRCode) + .aspectRatio(1, contentMode: .fit) + .cornerRadius(12) + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + .padding(.horizontal) + } else { + Button { + switch cameraAuthorizationStatus { + case .notDetermined: askCameraAuthorization { showQRCodeScanner = true } + case .restricted: () + case .denied: UIApplication.shared.open(appSettingsURL) + case .authorized: showQRCodeScanner = true + default: askCameraAuthorization { showQRCodeScanner = true } + } + } label: { + ZStack { + Rectangle() + .aspectRatio(contentMode: .fill) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .foregroundColor(Color.clear) + switch cameraAuthorizationStatus { + case .restricted: Text("Camera not available") + case .denied: Label("Enable camera access", systemImage: "camera") + default: Label("Tap to scan", systemImage: "qrcode") + } + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) + .padding() + .background( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .fill(Color(uiColor: .secondarySystemGroupedBackground)) + ) + .padding(.horizontal) + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + .disabled(cameraAuthorizationStatus == .restricted) + } + } + } + + private func processQRCode(_ resp: Result) { + switch resp { + case let .success(r): + let link = r.string + if strIsSimplexLink(r.string) { + connect(link) + } else { + alert = .newChatSomeAlert(alert: .someAlert( + alert: mkAlert(title: "Invalid QR code", message: "The code you scanned is not a SimpleX link QR code."), + id: "processQRCode: code is not a SimpleX link" + )) + } + case let .failure(e): + logger.error("processQRCode QR code error: \(e.localizedDescription)") + alert = .newChatSomeAlert(alert: .someAlert( + alert: mkAlert(title: "Invalid QR code", message: "Error scanning code: \(e.localizedDescription)"), + id: "processQRCode: failure" + )) + } + } + + private func connect(_ link: String) { + planAndConnect( + link, + showAlert: { alert = .planAndConnectAlert(alert: $0) }, + showActionSheet: { sheet = $0 }, + dismiss: true, + incognito: nil + ) + } +} + +private func linkTextView(_ link: String) -> some View { + Text(link) + .lineLimit(1) + .font(.caption) + .truncationMode(.middle) +} + +struct InfoSheetButton: View { + @ViewBuilder let content: Content + @State private var showInfoSheet = false + + var body: some View { + Button { + showInfoSheet = true + } label: { + Image(systemName: "info.circle") + .resizable() + .scaledToFit() + .frame(width: 24, height: 24) + } + .sheet(isPresented: $showInfoSheet) { + content + } + } +} + +func strIsSimplexLink(_ str: String) -> Bool { + if let parsedMd = parseSimpleXMarkdown(str), + parsedMd.count == 1, + case .simplexLink = parsedMd[0].format { + return true + } else { + return false + } +} + +func strHasSingleSimplexLink(_ str: String) -> FormattedText? { + if let parsedMd = parseSimpleXMarkdown(str) { + let parsedLinks = parsedMd.filter({ $0.format?.isSimplexLink ?? false }) + if parsedLinks.count == 1 { + return parsedLinks[0] + } else { + return nil + } + } else { + return nil + } +} + +struct IncognitoToggle: View { + @Binding var incognitoEnabled: Bool + @State private var showIncognitoSheet = false + + var body: some View { + ZStack(alignment: .leading) { + Image(systemName: incognitoEnabled ? "theatermasks.fill" : "theatermasks") + .frame(maxWidth: 24, maxHeight: 24, alignment: .center) + .foregroundColor(incognitoEnabled ? Color.indigo : .secondary) + .font(.system(size: 14)) + Toggle(isOn: $incognitoEnabled) { + HStack(spacing: 6) { + Text("Incognito") + Image(systemName: "info.circle") + .foregroundColor(.accentColor) + .font(.system(size: 14)) + } + .onTapGesture { + showIncognitoSheet = true + } + } + .padding(.leading, 36) + } + .sheet(isPresented: $showIncognitoSheet) { + IncognitoHelp() + } + } +} + +func sharedProfileInfo(_ incognito: Bool) -> Text { + let name = ChatModel.shared.currentUser?.displayName ?? "" + return Text( + incognito + ? "A new random profile will be shared." + : "Your profile **\(name)** will be shared." + ) +} + +enum PlanAndConnectAlert: Identifiable { + case ownInvitationLinkConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) + case invitationLinkConnecting(connectionLink: String) + case ownContactAddressConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) + case contactAddressConnectingConfirmReconnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) + case groupLinkConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) + case groupLinkConnectingConfirmReconnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool) + case groupLinkConnecting(connectionLink: String, groupInfo: GroupInfo?) + + var id: String { + switch self { + case let .ownInvitationLinkConfirmConnect(connectionLink, _, _): return "ownInvitationLinkConfirmConnect \(connectionLink)" + case let .invitationLinkConnecting(connectionLink): return "invitationLinkConnecting \(connectionLink)" + case let .ownContactAddressConfirmConnect(connectionLink, _, _): return "ownContactAddressConfirmConnect \(connectionLink)" + case let .contactAddressConnectingConfirmReconnect(connectionLink, _, _): return "contactAddressConnectingConfirmReconnect \(connectionLink)" + case let .groupLinkConfirmConnect(connectionLink, _, _): return "groupLinkConfirmConnect \(connectionLink)" + case let .groupLinkConnectingConfirmReconnect(connectionLink, _, _): return "groupLinkConnectingConfirmReconnect \(connectionLink)" + case let .groupLinkConnecting(connectionLink, _): return "groupLinkConnecting \(connectionLink)" + } + } +} + +func planAndConnectAlert(_ alert: PlanAndConnectAlert, dismiss: Bool, cleanup: (() -> Void)? = nil) -> Alert { + switch alert { + case let .ownInvitationLinkConfirmConnect(connectionLink, connectionPlan, incognito): + return Alert( + title: Text("Connect to yourself?"), + message: Text("This is your own one-time link!"), + primaryButton: .destructive( + Text(incognito ? "Connect incognito" : "Connect"), + action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) } + ), + secondaryButton: .cancel() { cleanup?() } + ) + case .invitationLinkConnecting: + return Alert( + title: Text("Already connecting!"), + message: Text("You are already connecting via this one-time link!"), + dismissButton: .default(Text("OK")) { cleanup?() } + ) + case let .ownContactAddressConfirmConnect(connectionLink, connectionPlan, incognito): + return Alert( + title: Text("Connect to yourself?"), + message: Text("This is your own SimpleX address!"), + primaryButton: .destructive( + Text(incognito ? "Connect incognito" : "Connect"), + action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) } + ), + secondaryButton: .cancel() { cleanup?() } + ) + case let .contactAddressConnectingConfirmReconnect(connectionLink, connectionPlan, incognito): + return Alert( + title: Text("Repeat connection request?"), + message: Text("You have already requested connection via this address!"), + primaryButton: .destructive( + Text(incognito ? "Connect incognito" : "Connect"), + action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) } + ), + secondaryButton: .cancel() { cleanup?() } + ) + case let .groupLinkConfirmConnect(connectionLink, connectionPlan, incognito): + return Alert( + title: Text("Join group?"), + message: Text("You will connect to all group members."), + primaryButton: .default( + Text(incognito ? "Join incognito" : "Join"), + action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) } + ), + secondaryButton: .cancel() { cleanup?() } + ) + case let .groupLinkConnectingConfirmReconnect(connectionLink, connectionPlan, incognito): + return Alert( + title: Text("Repeat join request?"), + message: Text("You are already joining the group via this link!"), + primaryButton: .destructive( + Text(incognito ? "Join incognito" : "Join"), + action: { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) } + ), + secondaryButton: .cancel() { cleanup?() } + ) + case let .groupLinkConnecting(_, groupInfo): + if let groupInfo = groupInfo { + return Alert( + title: Text("Group already exists!"), + message: Text("You are already joining the group \(groupInfo.displayName)."), + dismissButton: .default(Text("OK")) { cleanup?() } + ) + } else { + return Alert( + title: Text("Already joining the group!"), + message: Text("You are already joining the group via this link."), + dismissButton: .default(Text("OK")) { cleanup?() } + ) + } + } +} + +enum PlanAndConnectActionSheet: Identifiable { + case askCurrentOrIncognitoProfile(connectionLink: String, connectionPlan: ConnectionPlan?, title: LocalizedStringKey) + case askCurrentOrIncognitoProfileDestructive(connectionLink: String, connectionPlan: ConnectionPlan, title: LocalizedStringKey) + case askCurrentOrIncognitoProfileConnectContactViaAddress(contact: Contact) + case ownGroupLinkConfirmConnect(connectionLink: String, connectionPlan: ConnectionPlan, incognito: Bool?, groupInfo: GroupInfo) + + var id: String { + switch self { + case let .askCurrentOrIncognitoProfile(connectionLink, _, _): return "askCurrentOrIncognitoProfile \(connectionLink)" + case let .askCurrentOrIncognitoProfileDestructive(connectionLink, _, _): return "askCurrentOrIncognitoProfileDestructive \(connectionLink)" + case let .askCurrentOrIncognitoProfileConnectContactViaAddress(contact): return "askCurrentOrIncognitoProfileConnectContactViaAddress \(contact.contactId)" + case let .ownGroupLinkConfirmConnect(connectionLink, _, _, _): return "ownGroupLinkConfirmConnect \(connectionLink)" + } + } +} + +func planAndConnectActionSheet(_ sheet: PlanAndConnectActionSheet, dismiss: Bool, cleanup: (() -> Void)? = nil) -> ActionSheet { + switch sheet { + case let .askCurrentOrIncognitoProfile(connectionLink, connectionPlan, title): + return ActionSheet( + title: Text(title), + buttons: [ + .default(Text("Use current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: false, cleanup: cleanup) }, + .default(Text("Use new incognito profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: true, cleanup: cleanup) }, + .cancel() { cleanup?() } + ] + ) + case let .askCurrentOrIncognitoProfileDestructive(connectionLink, connectionPlan, title): + return ActionSheet( + title: Text(title), + buttons: [ + .destructive(Text("Use current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: false, cleanup: cleanup) }, + .destructive(Text("Use new incognito profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: true, cleanup: cleanup) }, + .cancel() { cleanup?() } + ] + ) + case let .askCurrentOrIncognitoProfileConnectContactViaAddress(contact): + return ActionSheet( + title: Text("Connect with \(contact.chatViewName)"), + buttons: [ + .default(Text("Use current profile")) { connectContactViaAddress_(contact, dismiss: dismiss, incognito: false, cleanup: cleanup) }, + .default(Text("Use new incognito profile")) { connectContactViaAddress_(contact, dismiss: dismiss, incognito: true, cleanup: cleanup) }, + .cancel() { cleanup?() } + ] + ) + case let .ownGroupLinkConfirmConnect(connectionLink, connectionPlan, incognito, groupInfo): + if let incognito = incognito { + return ActionSheet( + title: Text("Join your group?\nThis is your link for group \(groupInfo.displayName)!"), + buttons: [ + .default(Text("Open group")) { openKnownGroup(groupInfo, dismiss: dismiss, showAlreadyExistsAlert: nil) }, + .destructive(Text(incognito ? "Join incognito" : "Join with current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) }, + .cancel() { cleanup?() } + ] + ) + } else { + return ActionSheet( + title: Text("Join your group?\nThis is your link for group \(groupInfo.displayName)!"), + buttons: [ + .default(Text("Open group")) { openKnownGroup(groupInfo, dismiss: dismiss, showAlreadyExistsAlert: nil) }, + .destructive(Text("Use current profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: false, cleanup: cleanup) }, + .destructive(Text("Use new incognito profile")) { connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: true, cleanup: cleanup) }, + .cancel() { cleanup?() } + ] + ) + } + } +} + +func planAndConnect( + _ connectionLink: String, + showAlert: @escaping (PlanAndConnectAlert) -> Void, + showActionSheet: @escaping (PlanAndConnectActionSheet) -> Void, + dismiss: Bool, + incognito: Bool?, + cleanup: (() -> Void)? = nil, + filterKnownContact: ((Contact) -> Void)? = nil, + filterKnownGroup: ((GroupInfo) -> Void)? = nil +) { + Task { + do { + let connectionPlan = try await apiConnectPlan(connReq: connectionLink) + switch connectionPlan { + case let .invitationLink(ilp): + switch ilp { + case .ok: + logger.debug("planAndConnect, .invitationLink, .ok, incognito=\(incognito?.description ?? "nil")") + if let incognito = incognito { + connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) + } else { + showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect via one-time link")) + } + case .ownLink: + logger.debug("planAndConnect, .invitationLink, .ownLink, incognito=\(incognito?.description ?? "nil")") + if let incognito = incognito { + showAlert(.ownInvitationLinkConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) + } else { + showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect to yourself?\nThis is your own one-time link!")) + } + case let .connecting(contact_): + logger.debug("planAndConnect, .invitationLink, .connecting, incognito=\(incognito?.description ?? "nil")") + if let contact = contact_ { + if let f = filterKnownContact { + f(contact) + } else { + openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyConnectingAlert(contact)) } + } + } else { + showAlert(.invitationLinkConnecting(connectionLink: connectionLink)) + } + case let .known(contact): + logger.debug("planAndConnect, .invitationLink, .known, incognito=\(incognito?.description ?? "nil")") + if let f = filterKnownContact { + f(contact) + } else { + openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyExistsAlert(contact)) } + } + } + case let .contactAddress(cap): + switch cap { + case .ok: + logger.debug("planAndConnect, .contactAddress, .ok, incognito=\(incognito?.description ?? "nil")") + if let incognito = incognito { + connectViaLink(connectionLink, connectionPlan: connectionPlan, dismiss: dismiss, incognito: incognito, cleanup: cleanup) + } else { + showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect via contact address")) + } + case .ownLink: + logger.debug("planAndConnect, .contactAddress, .ownLink, incognito=\(incognito?.description ?? "nil")") + if let incognito = incognito { + showAlert(.ownContactAddressConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) + } else { + showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Connect to yourself?\nThis is your own SimpleX address!")) + } + case .connectingConfirmReconnect: + logger.debug("planAndConnect, .contactAddress, .connectingConfirmReconnect, incognito=\(incognito?.description ?? "nil")") + if let incognito = incognito { + showAlert(.contactAddressConnectingConfirmReconnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) + } else { + showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "You have already requested connection!\nRepeat connection request?")) + } + case let .connectingProhibit(contact): + logger.debug("planAndConnect, .contactAddress, .connectingProhibit, incognito=\(incognito?.description ?? "nil")") + if let f = filterKnownContact { + f(contact) + } else { + openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyConnectingAlert(contact)) } + } + case let .known(contact): + logger.debug("planAndConnect, .contactAddress, .known, incognito=\(incognito?.description ?? "nil")") + if let f = filterKnownContact { + f(contact) + } else { + openKnownContact(contact, dismiss: dismiss) { AlertManager.shared.showAlert(contactAlreadyExistsAlert(contact)) } + } + case let .contactViaAddress(contact): + logger.debug("planAndConnect, .contactAddress, .contactViaAddress, incognito=\(incognito?.description ?? "nil")") + if let incognito = incognito { + connectContactViaAddress_(contact, dismiss: dismiss, incognito: incognito, cleanup: cleanup) + } else { + showActionSheet(.askCurrentOrIncognitoProfileConnectContactViaAddress(contact: contact)) + } + } + case let .groupLink(glp): + switch glp { + case .ok: + if let incognito = incognito { + showAlert(.groupLinkConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) + } else { + showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "Join group")) + } + case let .ownLink(groupInfo): + logger.debug("planAndConnect, .groupLink, .ownLink, incognito=\(incognito?.description ?? "nil")") + if let f = filterKnownGroup { + f(groupInfo) + } + showActionSheet(.ownGroupLinkConfirmConnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito, groupInfo: groupInfo)) + case .connectingConfirmReconnect: + logger.debug("planAndConnect, .groupLink, .connectingConfirmReconnect, incognito=\(incognito?.description ?? "nil")") + if let incognito = incognito { + showAlert(.groupLinkConnectingConfirmReconnect(connectionLink: connectionLink, connectionPlan: connectionPlan, incognito: incognito)) + } else { + showActionSheet(.askCurrentOrIncognitoProfileDestructive(connectionLink: connectionLink, connectionPlan: connectionPlan, title: "You are already joining the group!\nRepeat join request?")) + } + case let .connectingProhibit(groupInfo_): + logger.debug("planAndConnect, .groupLink, .connectingProhibit, incognito=\(incognito?.description ?? "nil")") + showAlert(.groupLinkConnecting(connectionLink: connectionLink, groupInfo: groupInfo_)) + case let .known(groupInfo): + logger.debug("planAndConnect, .groupLink, .known, incognito=\(incognito?.description ?? "nil")") + if let f = filterKnownGroup { + f(groupInfo) + } else { + openKnownGroup(groupInfo, dismiss: dismiss) { AlertManager.shared.showAlert(groupAlreadyExistsAlert(groupInfo)) } + } + } + } + } catch { + logger.debug("planAndConnect, plan error") + if let incognito = incognito { + connectViaLink(connectionLink, connectionPlan: nil, dismiss: dismiss, incognito: incognito, cleanup: cleanup) + } else { + showActionSheet(.askCurrentOrIncognitoProfile(connectionLink: connectionLink, connectionPlan: nil, title: "Connect via link")) + } + } + } +} + +private func connectContactViaAddress_(_ contact: Contact, dismiss: Bool, incognito: Bool, cleanup: (() -> Void)? = nil) { + Task { + if dismiss { + DispatchQueue.main.async { + dismissAllSheets(animated: true) + } + } + _ = await connectContactViaAddress(contact.contactId, incognito) + cleanup?() + } +} + +private func connectViaLink( + _ connectionLink: String, + connectionPlan: ConnectionPlan?, + dismiss: Bool, + incognito: Bool, + cleanup: (() -> Void)? +) { + Task { + if let (connReqType, pcc) = await apiConnect(incognito: incognito, connReq: connectionLink) { + await MainActor.run { + ChatModel.shared.updateContactConnection(pcc) + } + let crt: ConnReqType + if let plan = connectionPlan { + crt = planToConnReqType(plan) + } else { + crt = connReqType + } + DispatchQueue.main.async { + if dismiss { + dismissAllSheets(animated: true) { + AlertManager.shared.showAlert(connReqSentAlert(crt)) + } + } else { + AlertManager.shared.showAlert(connReqSentAlert(crt)) + } + } + } else { + if dismiss { + DispatchQueue.main.async { + dismissAllSheets(animated: true) + } + } + } + cleanup?() + } +} + +func openKnownContact(_ contact: Contact, dismiss: Bool, showAlreadyExistsAlert: (() -> Void)?) { + Task { + let m = ChatModel.shared + if let c = m.getContactChat(contact.contactId) { + DispatchQueue.main.async { + if dismiss { + dismissAllSheets(animated: true) { + m.chatId = c.id + showAlreadyExistsAlert?() + } + } else { + m.chatId = c.id + showAlreadyExistsAlert?() + } + } + } + } +} + +func openKnownGroup(_ groupInfo: GroupInfo, dismiss: Bool, showAlreadyExistsAlert: (() -> Void)?) { + Task { + let m = ChatModel.shared + if let g = m.getGroupChat(groupInfo.groupId) { + DispatchQueue.main.async { + if dismiss { + dismissAllSheets(animated: true) { + m.chatId = g.id + showAlreadyExistsAlert?() + } + } else { + m.chatId = g.id + showAlreadyExistsAlert?() + } + } + } + } +} + +func contactAlreadyConnectingAlert(_ contact: Contact) -> Alert { + mkAlert( + title: "Contact already exists", + message: "You are already connecting to \(contact.displayName)." + ) +} + +func groupAlreadyExistsAlert(_ groupInfo: GroupInfo) -> Alert { + mkAlert( + title: "Group already exists", + message: "You are already in group \(groupInfo.displayName)." + ) +} + +enum ConnReqType: Equatable { + case invitation + case contact + case groupLink + + var connReqSentText: LocalizedStringKey { + switch self { + case .invitation: return "You will be connected when your contact's device is online, please wait or check later!" + case .contact: return "You will be connected when your connection request is accepted, please wait or check later!" + case .groupLink: return "You will be connected when group link host's device is online, please wait or check later!" + } + } +} + +private func planToConnReqType(_ connectionPlan: ConnectionPlan) -> ConnReqType { + switch connectionPlan { + case .invitationLink: return .invitation + case .contactAddress: return .contact + case .groupLink: return .groupLink + } +} + +func connReqSentAlert(_ type: ConnReqType) -> Alert { + return mkAlert( + title: "Connection request sent!", + message: type.connReqSentText + ) +} + +#Preview { + NewChatView( + selection: .invite + ) +} diff --git a/apps/ios/Shared/Views/NewChat/PasteToConnectView.swift b/apps/ios/Shared/Views/NewChat/PasteToConnectView.swift deleted file mode 100644 index 7c272fb63..000000000 --- a/apps/ios/Shared/Views/NewChat/PasteToConnectView.swift +++ /dev/null @@ -1,106 +0,0 @@ -// -// PasteToConnectView.swift -// SimpleX (iOS) -// -// Created by Ian Davies on 22/04/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import SwiftUI -import SimpleXChat - -struct PasteToConnectView: View { - @Environment(\.dismiss) var dismiss: DismissAction - @State private var connectionLink: String = "" - @AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false - @FocusState private var linkEditorFocused: Bool - @State private var alert: PlanAndConnectAlert? - @State private var sheet: PlanAndConnectActionSheet? - - var body: some View { - List { - Text("Connect via link") - .font(.largeTitle) - .bold() - .fixedSize(horizontal: false, vertical: true) - .listRowBackground(Color.clear) - .listRowSeparator(.hidden) - .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) - .onTapGesture { linkEditorFocused = false } - - Section { - linkEditor() - - Button { - if connectionLink == "" { - connectionLink = UIPasteboard.general.string ?? "" - } else { - connectionLink = "" - } - } label: { - if connectionLink == "" { - settingsRow("doc.plaintext") { Text("Paste") } - } else { - settingsRow("multiply") { Text("Clear") } - } - } - - Button { - connect() - } label: { - settingsRow("link") { Text("Connect") } - } - .disabled(connectionLink == "" || connectionLink.trimmingCharacters(in: .whitespaces).firstIndex(of: " ") != nil) - - IncognitoToggle(incognitoEnabled: $incognitoDefault) - } footer: { - VStack(alignment: .leading, spacing: 4) { - sharedProfileInfo(incognitoDefault) - Text("You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button.") - } - .frame(maxWidth: .infinity, alignment: .leading) - } - } - .alert(item: $alert) { a in planAndConnectAlert(a, dismiss: true) } - .actionSheet(item: $sheet) { s in planAndConnectActionSheet(s, dismiss: true) } - } - - private func linkEditor() -> some View { - ZStack { - Group { - if connectionLink.isEmpty { - TextEditor(text: Binding.constant(NSLocalizedString("Paste the link you received to connect with your contact.", comment: "placeholder"))) - .foregroundColor(.secondary) - .disabled(true) - } - TextEditor(text: $connectionLink) - .onSubmit(connect) - .textInputAutocapitalization(.never) - .disableAutocorrection(true) - .focused($linkEditorFocused) - } - .allowsTightening(false) - .padding(.horizontal, -5) - .padding(.top, -8) - .frame(height: 180, alignment: .topLeading) - .frame(maxWidth: .infinity, alignment: .leading) - } - } - - private func connect() { - let link = connectionLink.trimmingCharacters(in: .whitespaces) - planAndConnect( - link, - showAlert: { alert = $0 }, - showActionSheet: { sheet = $0 }, - dismiss: true, - incognito: incognitoDefault - ) - } -} - -struct PasteToConnectView_Previews: PreviewProvider { - static var previews: some View { - PasteToConnectView() - } -} diff --git a/apps/ios/Shared/Views/NewChat/QRCode.swift b/apps/ios/Shared/Views/NewChat/QRCode.swift index 3ddb85079..e3bae9287 100644 --- a/apps/ios/Shared/Views/NewChat/QRCode.swift +++ b/apps/ios/Shared/Views/NewChat/QRCode.swift @@ -24,9 +24,10 @@ struct SimpleXLinkQRCode: View { let uri: String var withLogo: Bool = true var tintColor = UIColor(red: 0.023, green: 0.176, blue: 0.337, alpha: 1) + var onShare: (() -> Void)? = nil var body: some View { - QRCode(uri: simplexChatLink(uri), withLogo: withLogo, tintColor: tintColor) + QRCode(uri: simplexChatLink(uri), withLogo: withLogo, tintColor: tintColor, onShare: onShare) } } @@ -40,6 +41,7 @@ struct QRCode: View { let uri: String var withLogo: Bool = true var tintColor = UIColor(red: 0.023, green: 0.176, blue: 0.337, alpha: 1) + var onShare: (() -> Void)? = nil @State private var image: UIImage? = nil @State private var makeScreenshotFunc: () -> Void = {} @@ -65,6 +67,7 @@ struct QRCode: View { makeScreenshotFunc = { let size = CGSizeMake(1024 / UIScreen.main.scale, 1024 / UIScreen.main.scale) showShareSheet(items: [makeScreenshot(geo.frame(in: .local).origin, size)]) + onShare?() } } .frame(width: geo.size.width, height: geo.size.height) diff --git a/apps/ios/Shared/Views/NewChat/ScanToConnectView.swift b/apps/ios/Shared/Views/NewChat/ScanToConnectView.swift deleted file mode 100644 index 7f3f5e02f..000000000 --- a/apps/ios/Shared/Views/NewChat/ScanToConnectView.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// ConnectContactView.swift -// SimpleX -// -// Created by Evgeny Poberezkin on 29/01/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import SwiftUI -import SimpleXChat -import CodeScanner - -struct ScanToConnectView: View { - @Environment(\.dismiss) var dismiss: DismissAction - @AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false - @State private var alert: PlanAndConnectAlert? - @State private var sheet: PlanAndConnectActionSheet? - - var body: some View { - ScrollView { - VStack(alignment: .leading) { - Text("Scan QR code") - .font(.largeTitle) - .bold() - .fixedSize(horizontal: false, vertical: true) - .padding(.vertical) - - CodeScannerView(codeTypes: [.qr], scanMode: .continuous, completion: processQRCode) - .aspectRatio(1, contentMode: .fit) - .cornerRadius(12) - - IncognitoToggle(incognitoEnabled: $incognitoDefault) - .padding(.horizontal) - .padding(.vertical, 6) - .background( - RoundedRectangle(cornerRadius: 12, style: .continuous) - .fill(Color(uiColor: .systemBackground)) - ) - .padding(.top) - - VStack(alignment: .leading, spacing: 4) { - sharedProfileInfo(incognitoDefault) - Text("If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link.") - } - .frame(maxWidth: .infinity, alignment: .leading) - .font(.footnote) - .foregroundColor(.secondary) - .padding(.horizontal) - } - .padding() - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - .background(Color(.systemGroupedBackground)) - .alert(item: $alert) { a in planAndConnectAlert(a, dismiss: true) } - .actionSheet(item: $sheet) { s in planAndConnectActionSheet(s, dismiss: true) } - } - - func processQRCode(_ resp: Result) { - switch resp { - case let .success(r): - planAndConnect( - r.string, - showAlert: { alert = $0 }, - showActionSheet: { sheet = $0 }, - dismiss: true, - incognito: incognitoDefault - ) - case let .failure(e): - logger.error("ConnectContactView.processQRCode QR code error: \(e.localizedDescription)") - dismiss() - } - } -} - -struct ConnectContactView_Previews: PreviewProvider { - static var previews: some View { - ScanToConnectView() - } -} diff --git a/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift b/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift index 20dadb795..fc478596a 100644 --- a/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift +++ b/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift @@ -10,24 +10,23 @@ import SwiftUI struct IncognitoHelp: View { var body: some View { - VStack(alignment: .leading) { + List { Text("Incognito mode") .font(.largeTitle) .bold() + .fixedSize(horizontal: false, vertical: true) .padding(.vertical) - ScrollView { - VStack(alignment: .leading) { - Group { - Text("Incognito mode protects your privacy by using a new random profile for each contact.") - Text("It allows having many anonymous connections without any shared data between them in a single chat profile.") - Text("When you share an incognito profile with somebody, this profile will be used for the groups they invite you to.") - } - .padding(.bottom) - } + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + VStack(alignment: .leading, spacing: 18) { + Text("Incognito mode protects your privacy by using a new random profile for each contact.") + Text("It allows having many anonymous connections without any shared data between them in a single chat profile.") + Text("When you share an incognito profile with somebody, this profile will be used for the groups they invite you to.") + Text("Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).") } + .listRowBackground(Color.clear) } - .frame(maxWidth: .infinity) - .padding() } } diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index f889d9c39..b73d6b867 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -95,6 +95,12 @@ let appDefaults: [String: Any] = [ DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO: true, ] +// not used anymore +enum ConnectViaLinkTab: String { + case scan + case paste +} + enum SimpleXLinkMode: String, Identifiable { case description case full diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff index 44f2d878e..506df8cf1 100644 --- a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff @@ -303,14 +303,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Добави нов контакт**: за да създадете своя еднократен QR код или линк за вашия контакт. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Създай линк / QR код**, който вашият контакт да използва. + + **Create group**: to create a new group. No comment provided by engineer. @@ -323,11 +326,6 @@ **Най-поверително**: не използвайте сървъра за известия SimpleX Chat, периодично проверявайте съобщенията във фонов режим (зависи от това колко често използвате приложението). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Поставете получения линк** или го отворете в браузъра и докоснете **Отваряне в мобилно приложение**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Моля, обърнете внимание**: НЯМА да можете да възстановите или промените паролата, ако я загубите. @@ -338,11 +336,6 @@ **Препоръчително**: токенът на устройството и известията се изпращат до сървъра за уведомяване на SimpleX Chat, но не и съдържанието, размерът на съобщението или от кого е. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Сканирай QR код**: за да се свържете с вашия контакт лично или чрез видеообаждане. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Внимание**: Незабавните push известия изискват парола, запазена в Keychain. @@ -440,11 +433,6 @@ 1 седмица time interval - - 1-time link - Еднократен линк - No comment provided by engineer. - 5 minutes 5 минути @@ -560,6 +548,10 @@ Добавете адрес към вашия профил, така че вашите контакти да могат да го споделят с други хора. Актуализацията на профила ще бъде изпратена до вашите контакти. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Добави предварително зададени сървъри @@ -956,6 +948,10 @@ Обаждания No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Потребителският профил не може да се изтрие! @@ -1212,11 +1208,6 @@ This is your own one-time link! Свърване чрез линк No comment provided by engineer. - - Connect via link / QR code - Свърване чрез линк/QR код - No comment provided by engineer. - Connect via one-time link Свързване чрез еднократен линк за връзка @@ -1384,11 +1375,6 @@ This is your own one-time link! Създайте нов профил в [настолното приложение](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Създай линк за еднократна покана - No comment provided by engineer. - Create profile No comment provided by engineer. @@ -1413,6 +1399,10 @@ This is your own one-time link! Създаден на %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Текущ kод за достъп @@ -1954,6 +1944,10 @@ This cannot be undone! Активиране на автоматично изтриване на съобщения? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Активиране за всички @@ -2292,6 +2286,10 @@ This cannot be undone! Грешка при запазване на потребителска парола No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Грешка при изпращане на имейл @@ -2761,11 +2759,6 @@ This cannot be undone! Ако не можете да се срещнете лично, покажете QR код във видеоразговора или споделете линка. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Ако не можете да се срещнете на живо, можете да **сканирате QR код във видеообаждането** или вашият контакт може да сподели линк за покана. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Ако въведете този kод за достъп, когато отваряте приложението, всички данни от приложението ще бъдат необратимо изтрити! @@ -2921,11 +2914,19 @@ This cannot be undone! Интерфейс No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Невалиден линк за връзка No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! No comment provided by engineer. @@ -3048,10 +3049,18 @@ This is your link for group %@! Присъединяване към групата No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Запазете връзките си @@ -3378,6 +3387,10 @@ This is your link for group %@! Нов kод за достъп No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Нова заявка за контакт @@ -3501,6 +3514,10 @@ This is your link for group %@! - да деактивират членове (роля "наблюдател") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Изключено @@ -3649,6 +3666,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count PING бройка @@ -3689,11 +3714,6 @@ This is your link for group %@! Парола за показване No comment provided by engineer. - - Paste - Постави - No comment provided by engineer. - Paste desktop address No comment provided by engineer. @@ -3703,16 +3723,10 @@ This is your link for group %@! Постави изображение No comment provided by engineer. - - Paste received link - Постави получения линк + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Поставете линка, който сте получили, за да се свържете с вашия контакт. - placeholder - People can connect to you only via the links you share. Хората могат да се свържат с вас само чрез ликовете, които споделяте. @@ -3956,6 +3970,10 @@ Error: %@ Прочетете повече в [Ръководство за потребителя](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Прочетете повече в [Ръководство на потребителя](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4164,6 +4182,10 @@ Error: %@ Грешка при възстановяване на базата данни No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Покажи @@ -4318,6 +4340,10 @@ Error: %@ Търсене No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Сигурна опашка @@ -4592,9 +4618,8 @@ Error: %@ Сподели линк No comment provided by engineer. - - Share one-time invitation link - Сподели линк за еднократна покана + + Share this 1-time invite link No comment provided by engineer. @@ -4717,11 +4742,6 @@ Error: %@ Някой notification title - - Start a new chat - Започни нов чат - No comment provided by engineer. - Start chat Започни чат @@ -4855,6 +4875,14 @@ Error: %@ Докосни за инкогнито вход No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Докосни за започване на нов чат @@ -4917,6 +4945,10 @@ It can happen because of some bug or when the connection is compromised.Опитът за промяна на паролата на базата данни не беше завършен. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! Връзката, която приехте, ще бъде отказана! @@ -4982,6 +5014,10 @@ It can happen because of some bug or when the connection is compromised.Сървърите за нови връзки на текущия ви чат профил **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Тема @@ -5579,11 +5615,6 @@ Repeat join request? Можете да приемате обаждания от заключен екран, без идентификация на устройство и приложението. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Можете също да се свържете, като натиснете върху линка. Ако се отвори в браузъра, натиснете върху бутона **Отваряне в мобилно приложение**. - No comment provided by engineer. - You can create it later Можете да го създадете по-късно @@ -5648,6 +5679,10 @@ Repeat join request? Можете да използвате markdown за форматиране на съобщенията: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Не може да изпращате съобщения! diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff index f0abba7bb..076c2c97f 100644 --- a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff +++ b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff @@ -303,14 +303,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Přidat nový kontakt**: pro vytvoření jednorázového QR kódu nebo odkazu pro váš kontakt. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Vytvořte odkaz / QR kód** pro váš kontakt. + + **Create group**: to create a new group. No comment provided by engineer. @@ -323,11 +326,6 @@ **Nejsoukromější**: nepoužívejte server oznámení SimpleX Chat, pravidelně kontrolujte zprávy na pozadí (závisí na tom, jak často aplikaci používáte). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Vložte přijatý odkaz** nebo jej otevřete v prohlížeči a klepněte na **Otevřít v mobilní aplikaci**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Upozornění**: Pokud heslo ztratíte, NEBUDETE jej moci obnovit ani změnit. @@ -338,11 +336,6 @@ **Doporučeno**: Token zařízení a oznámení se odesílají na oznamovací server SimpleX Chat, ale nikoli obsah, velikost nebo od koho jsou zprávy. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - ** Naskenujte QR kód**: pro připojení ke kontaktu osobně nebo prostřednictvím videohovoru. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Upozornění**: Okamžitě doručovaná oznámení vyžadují přístupové heslo uložené v Klíčence. @@ -440,11 +433,6 @@ 1 týden time interval - - 1-time link - Jednorázový odkaz - No comment provided by engineer. - 5 minutes 5 minut @@ -560,6 +548,10 @@ Přidejte adresu do svého profilu, aby ji vaše kontakty mohly sdílet s dalšími lidmi. Aktualizace profilu bude zaslána vašim kontaktům. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Přidejte přednastavené servery @@ -956,6 +948,10 @@ Hovory No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Nemohu smazat uživatelský profil! @@ -1212,11 +1208,6 @@ This is your own one-time link! Připojte se prostřednictvím odkazu No comment provided by engineer. - - Connect via link / QR code - Připojit se prostřednictvím odkazu / QR kódu - No comment provided by engineer. - Connect via one-time link Připojit se jednorázovým odkazem @@ -1384,11 +1375,6 @@ This is your own one-time link! Vytvořit nový profil v [desktop app](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Vytvořit jednorázovou pozvánku - No comment provided by engineer. - Create profile No comment provided by engineer. @@ -1413,6 +1399,10 @@ This is your own one-time link! Vytvořeno na %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Aktuální heslo @@ -1954,6 +1944,10 @@ This cannot be undone! Povolit automatické mazání zpráv? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Povolit pro všechny @@ -2292,6 +2286,10 @@ This cannot be undone! Chyba ukládání hesla uživatele No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Chyba odesílání e-mailu @@ -2761,11 +2759,6 @@ This cannot be undone! Pokud se nemůžete setkat osobně, zobrazte QR kód ve videohovoru nebo sdílejte odkaz. 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. - Pokud se nemůžete setkat osobně, můžete **naskenovat QR kód během videohovoru**, nebo váš kontakt může sdílet odkaz na pozvánku. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Pokud tento přístupový kód zadáte při otevření aplikace, všechna data budou nenávratně smazána! @@ -2921,11 +2914,19 @@ This cannot be undone! Rozhranní No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Neplatný odkaz na spojení No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! No comment provided by engineer. @@ -3048,10 +3049,18 @@ This is your link for group %@! Připojování ke skupině No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Zachovat vaše připojení @@ -3378,6 +3387,10 @@ This is your link for group %@! Nové heslo No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Žádost o nový kontakt @@ -3501,6 +3514,10 @@ This is your link for group %@! - zakázat členy (role "pozorovatel") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Vypnout @@ -3649,6 +3666,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count Počet PING @@ -3689,11 +3714,6 @@ This is your link for group %@! Heslo k zobrazení No comment provided by engineer. - - Paste - Vložit - No comment provided by engineer. - Paste desktop address No comment provided by engineer. @@ -3703,16 +3723,10 @@ This is your link for group %@! Vložit obrázek No comment provided by engineer. - - Paste received link - Vložení přijatého odkazu + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Vložte odkaz, který jste obdrželi, do pole níže a spojte se se svým kontaktem. - placeholder - People can connect to you only via the links you share. Lidé se s vámi mohou spojit pouze prostřednictvím odkazů, které sdílíte. @@ -3956,6 +3970,10 @@ Error: %@ Další informace naleznete v [Uživatelské příručce](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Přečtěte si více v [Uživatelské příručce](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4164,6 +4182,10 @@ Error: %@ Chyba obnovení databáze No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Odhalit @@ -4318,6 +4340,10 @@ Error: %@ Hledat No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Zabezpečit frontu @@ -4592,9 +4618,8 @@ Error: %@ Sdílet odkaz No comment provided by engineer. - - Share one-time invitation link - Jednorázový zvací odkaz + + Share this 1-time invite link No comment provided by engineer. @@ -4717,11 +4742,6 @@ Error: %@ Někdo notification title - - Start a new chat - Začít nový chat - No comment provided by engineer. - Start chat Začít chat @@ -4855,6 +4875,14 @@ Error: %@ Klepnutím se připojíte inkognito No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Klepnutím na zahájíte nový chat @@ -4917,6 +4945,10 @@ Může se to stát kvůli nějaké chybě, nebo pokud je spojení kompromitován Pokus o změnu přístupové fráze databáze nebyl dokončen. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! Připojení, které jste přijali, bude zrušeno! @@ -4982,6 +5014,10 @@ Může se to stát kvůli nějaké chybě, nebo pokud je spojení kompromitován Servery pro nová připojení vašeho aktuálního chat profilu **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Téma @@ -5579,11 +5615,6 @@ Repeat join request? Můžete přijímat hovory z obrazovky zámku, bez ověření zařízení a aplikace. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Můžete se také připojit kliknutím na odkaz. Pokud se otevře v prohlížeči, klikněte na tlačítko **Otevřít v mobilní aplikaci**. - No comment provided by engineer. - You can create it later Můžete vytvořit později @@ -5648,6 +5679,10 @@ Repeat join request? K formátování zpráv můžete použít markdown: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Nemůžete posílat zprávy! diff --git a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff index dda89f5c0..2b877c32d 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Fügen Sie einen neuen Kontakt hinzu**: Erzeugen Sie einen Einmal-QR-Code oder -Link für Ihren Kontakt. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Generieren Sie einen Einladungs-Link / QR code** für Ihren Kontakt. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Beste Privatsphäre**: Es wird kein SimpleX-Chat-Benachrichtigungs-Server genutzt, Nachrichten werden in periodischen Abständen im Hintergrund geprüft (dies hängt davon ab, wie häufig Sie die App nutzen). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Fügen Sie den von Ihrem Kontakt erhaltenen Link ein** oder öffnen Sie ihn im Browser und tippen Sie auf **In mobiler App öffnen**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Bitte beachten Sie**: Das Passwort kann NICHT wiederhergestellt oder geändert werden, wenn Sie es vergessen haben oder verlieren. @@ -347,11 +345,6 @@ **Empfohlen**: Nur Ihr Geräte-Token und ihre Benachrichtigungen werden an den SimpleX-Chat-Benachrichtigungs-Server gesendet, aber weder der Nachrichteninhalt noch deren Größe oder von wem sie gesendet wurde. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Scannen Sie den QR-Code**, um sich während einem persönlichen Treffen oder per Videoanruf mit Ihrem Kontakt zu verbinden. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Warnung**: Sofortige Push-Benachrichtigungen erfordern die Eingabe eines Passworts, welches in Ihrem Schlüsselbund gespeichert ist. @@ -453,11 +446,6 @@ wöchentlich time interval - - 1-time link - Einmal-Link - No comment provided by engineer. - 5 minutes 5 Minuten @@ -573,6 +561,10 @@ Fügen Sie die Adresse zu Ihrem Profil hinzu, damit Ihre Kontakte sie mit anderen Personen teilen können. Es wird eine Profilaktualisierung an Ihre Kontakte gesendet. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Füge voreingestellte Server hinzu @@ -978,6 +970,10 @@ Anrufe No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Das Benutzerprofil kann nicht gelöscht werden! @@ -1242,11 +1238,6 @@ Das ist Ihr eigener Einmal-Link! Über einen Link verbinden No comment provided by engineer. - - Connect via link / QR code - Über einen Link / QR-Code verbinden - No comment provided by engineer. - Connect via one-time link Über einen Einmal-Link verbinden @@ -1422,11 +1413,6 @@ Das ist Ihr eigener Einmal-Link! Neues Profil in der [Desktop-App] erstellen (https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Einmal-Einladungslink erstellen - No comment provided by engineer. - Create profile Profil erstellen @@ -1452,6 +1438,10 @@ Das ist Ihr eigener Einmal-Link! Erstellt am %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Aktueller Zugangscode @@ -2002,6 +1992,10 @@ Das kann nicht rückgängig gemacht werden! Automatisches Löschen von Nachrichten aktivieren? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Für Alle aktivieren @@ -2345,6 +2339,10 @@ Das kann nicht rückgängig gemacht werden! Fehler beim Speichern des Benutzer-Passworts No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Fehler beim Senden der eMail @@ -2820,11 +2818,6 @@ Das kann nicht rückgängig gemacht werden! Falls Sie sich nicht persönlich treffen können, zeigen Sie den QR-Code in einem Videoanruf oder teilen Sie den Link. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Wenn Sie sich nicht persönlich treffen können, kann der **QR-Code während eines Videoanrufs gescannt werden**, oder Ihr Kontakt kann den Einladungslink über einen anderen Kanal mit Ihnen teilen. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Wenn Sie diesen Zugangscode während des Öffnens der App eingeben, werden alle App-Daten unwiederbringlich gelöscht! @@ -2982,11 +2975,19 @@ Das kann nicht rückgängig gemacht werden! Schnittstelle No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Ungültiger Verbindungslink No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! Ungültiger Name! @@ -3114,11 +3115,19 @@ Das ist Ihr Link für die Gruppe %@! Der Gruppe beitreten No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Die App muss geöffnet bleiben, um sie vom Desktop aus nutzen zu können No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Ihre Verbindungen beibehalten @@ -3449,6 +3458,10 @@ Das ist Ihr Link für die Gruppe %@! Neuer Zugangscode No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Neue Kontaktanfrage @@ -3573,6 +3586,10 @@ Das ist Ihr Link für die Gruppe %@! - Gruppenmitglieder deaktivieren ("Beobachter"-Rolle) No comment provided by engineer. + + OK + No comment provided by engineer. + Off Aus @@ -3722,6 +3739,14 @@ Das ist Ihr Link für die Gruppe %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count PING-Zähler @@ -3762,11 +3787,6 @@ Das ist Ihr Link für die Gruppe %@! Passwort anzeigen No comment provided by engineer. - - Paste - Einfügen - No comment provided by engineer. - Paste desktop address Desktop-Adresse einfügen @@ -3777,16 +3797,10 @@ Das ist Ihr Link für die Gruppe %@! Bild einfügen No comment provided by engineer. - - Paste received link - Fügen Sie den erhaltenen Link ein + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Um sich mit Ihrem Kontakt zu verbinden, fügen Sie den erhaltenen Link in das Feld unten ein. - placeholder - People can connect to you only via the links you share. Verbindungen mit Kontakten sind nur über Links möglich, die Sie oder Ihre Kontakte untereinander teilen. @@ -4032,6 +4046,10 @@ Error: %@ Mehr dazu in der [Benutzeranleitung](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address) lesen. No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Mehr dazu in der [Benutzeranleitung](https://simplex.chat/docs/guide/readme.html#connect-to-friends) lesen. @@ -4242,6 +4260,10 @@ Error: %@ Fehler bei der Wiederherstellung der Datenbank No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Aufdecken @@ -4397,6 +4419,10 @@ Error: %@ Suche No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Sichere Warteschlange @@ -4672,9 +4698,8 @@ Error: %@ Link teilen No comment provided by engineer. - - Share one-time invitation link - Einmal-Einladungslink teilen + + Share this 1-time invite link No comment provided by engineer. @@ -4797,11 +4822,6 @@ Error: %@ Jemand notification title - - Start a new chat - Starten Sie einen neuen Chat - No comment provided by engineer. - Start chat Starten Sie den Chat @@ -4936,6 +4956,14 @@ Error: %@ Tippen, um Inkognito beizutreten No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Tippen, um einen neuen Chat zu starten @@ -4998,6 +5026,10 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro Die Änderung des Datenbank-Passworts konnte nicht abgeschlossen werden. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! Die von Ihnen akzeptierte Verbindung wird abgebrochen! @@ -5063,6 +5095,10 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro Server der neuen Verbindungen von Ihrem aktuellen Chat-Profil **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Design @@ -5683,11 +5719,6 @@ Verbindungsanfrage wiederholen? Sie können Anrufe ohne Geräte- und App-Authentifizierung vom Sperrbildschirm aus annehmen. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Sie können sich auch verbinden, indem Sie auf den Link klicken. Wenn er im Browser geöffnet wird, klicken Sie auf die Schaltfläche **In mobiler App öffnen**. - No comment provided by engineer. - You can create it later Sie können dies später erstellen @@ -5752,6 +5783,10 @@ Verbindungsanfrage wiederholen? Um Nachrichteninhalte zu formatieren, können Sie Markdowns verwenden: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Sie können keine Nachrichten versenden! diff --git a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff index 4544b823f..7dd5db3b6 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -312,14 +312,19 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Add new contact**: to create your one-time QR Code or link for your contact. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Create link / QR code** for your contact to use. + + **Create group**: to create a new group. + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +337,6 @@ **Most private**: do not use SimpleX Chat notifications server, check messages periodically in the background (depends on how often you use the app). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Paste received link** or open it in the browser and tap **Open in mobile app**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Please note**: you will NOT be able to recover or change passphrase if you lose it. @@ -347,11 +347,6 @@ **Recommended**: device token and notifications are sent to SimpleX Chat notification server, but not the message content, size or who it is from. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Scan QR code**: to connect to your contact in person or via video call. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Warning**: Instant push notifications require passphrase saved in Keychain. @@ -453,11 +448,6 @@ 1 week time interval - - 1-time link - 1-time link - No comment provided by engineer. - 5 minutes 5 minutes @@ -573,6 +563,11 @@ Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. No comment provided by engineer. + + Add contact + Add contact + No comment provided by engineer. + Add preset servers Add preset servers @@ -978,6 +973,11 @@ Calls No comment provided by engineer. + + Camera not available + Camera not available + No comment provided by engineer. + Can't delete user profile! Can't delete user profile! @@ -1243,11 +1243,6 @@ This is your own one-time link! Connect via link No comment provided by engineer. - - Connect via link / QR code - Connect via link / QR code - No comment provided by engineer. - Connect via one-time link Connect via one-time link @@ -1423,11 +1418,6 @@ This is your own one-time link! Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Create one-time invitation link - No comment provided by engineer. - Create profile Create profile @@ -1453,6 +1443,11 @@ This is your own one-time link! Created on %@ No comment provided by engineer. + + Creating link… + Creating link… + No comment provided by engineer. + Current Passcode Current Passcode @@ -2003,6 +1998,11 @@ This cannot be undone! Enable automatic message deletion? No comment provided by engineer. + + Enable camera access + Enable camera access + No comment provided by engineer. + Enable for all Enable for all @@ -2348,6 +2348,11 @@ This cannot be undone! Error saving user password No comment provided by engineer. + + Error scanning code: %@ + Error scanning code: %@ + No comment provided by engineer. + Error sending email Error sending email @@ -2823,11 +2828,6 @@ This cannot be undone! If you can't meet in person, show QR code in a video call, or share the link. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! If you enter this passcode when opening the app, all app data will be irreversibly removed! @@ -2985,11 +2985,21 @@ This cannot be undone! Interface No comment provided by engineer. + + Invalid QR code + Invalid QR code + No comment provided by engineer. + Invalid connection link Invalid connection link No comment provided by engineer. + + Invalid link + Invalid link + No comment provided by engineer. + Invalid name! Invalid name! @@ -3118,11 +3128,21 @@ This is your link for group %@! Joining group No comment provided by engineer. + + Keep + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + Keep unused invitation? + No comment provided by engineer. + Keep your connections Keep your connections @@ -3453,6 +3473,11 @@ This is your link for group %@! New Passcode No comment provided by engineer. + + New chat + New chat + No comment provided by engineer. + New contact request New contact request @@ -3577,6 +3602,11 @@ This is your link for group %@! - disable members ("observer" role) No comment provided by engineer. + + OK + OK + No comment provided by engineer. + Off Off @@ -3727,6 +3757,16 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + Or scan QR code + No comment provided by engineer. + + + Or show this code + Or show this code + No comment provided by engineer. + PING count PING count @@ -3767,11 +3807,6 @@ This is your link for group %@! Password to show No comment provided by engineer. - - Paste - Paste - No comment provided by engineer. - Paste desktop address Paste desktop address @@ -3782,16 +3817,11 @@ This is your link for group %@! Paste image No comment provided by engineer. - - Paste received link - Paste received link + + Paste the link you received + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Paste the link you received to connect with your contact. - placeholder - People can connect to you only via the links you share. People can connect to you only via the links you share. @@ -4039,6 +4069,11 @@ Error: %@ Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4249,6 +4284,11 @@ Error: %@ Restore database error No comment provided by engineer. + + Retry + Retry + No comment provided by engineer. + Reveal Reveal @@ -4404,6 +4444,11 @@ Error: %@ Search No comment provided by engineer. + + Search or paste SimpleX link + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Secure queue @@ -4679,9 +4724,9 @@ Error: %@ Share link No comment provided by engineer. - - Share one-time invitation link - Share one-time invitation link + + Share this 1-time invite link + Share this 1-time invite link No comment provided by engineer. @@ -4804,11 +4849,6 @@ Error: %@ Somebody notification title - - Start a new chat - Start a new chat - No comment provided by engineer. - Start chat Start chat @@ -4944,6 +4984,16 @@ Error: %@ Tap to join incognito No comment provided by engineer. + + Tap to paste link + Tap to paste link + No comment provided by engineer. + + + Tap to scan + Tap to scan + No comment provided by engineer. + Tap to start a new chat Tap to start a new chat @@ -5006,6 +5056,11 @@ It can happen because of some bug or when the connection is compromised.The attempt to change database passphrase was not completed. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! The connection you accepted will be cancelled! @@ -5071,6 +5126,11 @@ It can happen because of some bug or when the connection is compromised.The servers for new connections of your current chat profile **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Theme @@ -5692,11 +5752,6 @@ Repeat join request? You can accept calls from lock screen, without device and app authentication. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - No comment provided by engineer. - You can create it later You can create it later @@ -5762,6 +5817,11 @@ Repeat join request? You can use markdown to format messages: No comment provided by engineer. + + You can view invitation link again in connection details. + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! You can't send messages! diff --git a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff index 5b3d820d6..0f2accb89 100644 --- a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff +++ b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Añadir nuevo contacto**: para crear tu código QR o enlace de un uso para tu contacto. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Crea enlace / código QR** para que tu contacto lo use. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Más privado**: no se usa el servidor de notificaciones de SimpleX Chat, los mensajes se comprueban periódicamente en segundo plano (dependiendo de la frecuencia con la que utilices la aplicación). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Pega el enlace recibido** o ábrelo en el navegador y pulsa **Abrir en aplicación móvil**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Atención**: NO podrás recuperar o cambiar la contraseña si la pierdes. @@ -347,11 +345,6 @@ **Recomendado**: el token del dispositivo y las notificaciones se envían al servidor de notificaciones de SimpleX Chat, pero no el contenido del mensaje, su tamaño o su procedencia. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Escanear código QR**: en persona para conectarte con tu contacto, o por videollamada. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Advertencia**: Las notificaciones automáticas instantáneas requieren una contraseña guardada en Keychain. @@ -453,11 +446,6 @@ una semana time interval - - 1-time link - Enlace un uso - No comment provided by engineer. - 5 minutes 5 minutos @@ -573,6 +561,10 @@ Añade la dirección a tu perfil para que tus contactos puedan compartirla con otros. La actualización del perfil se enviará a tus contactos. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Añadir servidores predefinidos @@ -978,6 +970,10 @@ Llamadas No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! ¡No se puede eliminar el perfil! @@ -1242,11 +1238,6 @@ This is your own one-time link! Conectar mediante enlace No comment provided by engineer. - - Connect via link / QR code - Conecta vía enlace / Código QR - No comment provided by engineer. - Connect via one-time link Conectar mediante enlace de un sólo uso @@ -1422,11 +1413,6 @@ This is your own one-time link! Crea perfil nuevo en la [aplicación para PC](https://simplex.Descargas/de chat/). 💻 No comment provided by engineer. - - Create one-time invitation link - Crea enlace de invitación de un uso - No comment provided by engineer. - Create profile Crear perfil @@ -1452,6 +1438,10 @@ This is your own one-time link! Creado en %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Código de Acceso @@ -2002,6 +1992,10 @@ This cannot be undone! ¿Activar eliminación automática de mensajes? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Activar para todos @@ -2345,6 +2339,10 @@ This cannot be undone! Error al guardar contraseña de usuario No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Error al enviar email @@ -2820,11 +2818,6 @@ This cannot be undone! Si no puedes reunirte en persona, muestra el código QR por videollamada, o comparte el enlace. 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. - Si no puedes reunirte en persona, puedes **escanear el código QR por videollamada**, o tu contacto puede compartir un enlace de invitación. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! ¡Si introduces este código al abrir la aplicación, todos los datos de la misma se eliminarán de forma irreversible! @@ -2982,11 +2975,19 @@ This cannot be undone! Interfaz No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Enlace de conexión no válido No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! ¡Nombre no válido! @@ -3114,11 +3115,19 @@ This is your link for group %@! Entrando al grupo No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Mantén la aplicación abierta para usarla desde el ordenador No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Conserva tus conexiones @@ -3449,6 +3458,10 @@ This is your link for group %@! Código Nuevo No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Nueva solicitud de contacto @@ -3573,6 +3586,10 @@ This is your link for group %@! - desactivar el rol miembro (a rol "observador") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Desactivado @@ -3722,6 +3739,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count Contador PING @@ -3762,11 +3787,6 @@ This is your link for group %@! Contraseña para hacerlo visible No comment provided by engineer. - - Paste - Pegar - No comment provided by engineer. - Paste desktop address Pegar dirección de ordenador @@ -3777,16 +3797,10 @@ This is your link for group %@! Pegar imagen No comment provided by engineer. - - Paste received link - Pegar enlace recibido + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Pega el enlace que has recibido en el recuadro para conectar con tu contacto. - placeholder - People can connect to you only via the links you share. Las personas pueden conectarse contigo solo mediante los enlaces que compartes. @@ -4032,6 +4046,10 @@ Error: %@ Más información en el [Manual de usuario](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Más información en el [Manual de usuario](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4242,6 +4260,10 @@ Error: %@ Error al restaurar base de datos No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Revelar @@ -4397,6 +4419,10 @@ Error: %@ Buscar No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Cola segura @@ -4672,9 +4698,8 @@ Error: %@ Compartir enlace No comment provided by engineer. - - Share one-time invitation link - Compartir enlace de invitación de un uso + + Share this 1-time invite link No comment provided by engineer. @@ -4797,11 +4822,6 @@ Error: %@ Alguien notification title - - Start a new chat - Iniciar chat nuevo - No comment provided by engineer. - Start chat Iniciar chat @@ -4936,6 +4956,14 @@ Error: %@ Pulsa para unirte en modo incógnito No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Pulsa para iniciar chat nuevo @@ -4998,6 +5026,10 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida. El intento de cambiar la contraseña de la base de datos no se ha completado. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! ¡La conexión que has aceptado se cancelará! @@ -5063,6 +5095,10 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida. Lista de servidores para las conexiones nuevas de tu perfil actual **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Tema @@ -5684,11 +5720,6 @@ Repeat join request? Puede aceptar llamadas desde la pantalla de bloqueo, sin autenticación de dispositivos y aplicaciones. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - También puedes conectarte haciendo clic en el enlace. Si se abre en el navegador, haz clic en el botón **Abrir en aplicación móvil**. - No comment provided by engineer. - You can create it later Puedes crearla más tarde @@ -5753,6 +5784,10 @@ Repeat join request? Puedes usar la sintaxis markdown para dar formato a tus mensajes: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! ¡No puedes enviar mensajes! diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff index 928666dda..81bc19013 100644 --- a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff +++ b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff @@ -303,14 +303,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Lisää uusi kontakti**: luo kertakäyttöinen QR-koodi tai linkki kontaktille. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Luo linkki / QR-koodi* kontaktille. + + **Create group**: to create a new group. No comment provided by engineer. @@ -323,11 +326,6 @@ **Yksityisin**: älä käytä SimpleX Chat -ilmoituspalvelinta, tarkista viestit ajoittain taustalla (riippuu siitä, kuinka usein käytät sovellusta). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Liitä vastaanotettu linkki** tai avaa se selaimessa ja napauta **Avaa mobiilisovelluksessa**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Huomaa**: et voi palauttaa tai muuttaa tunnuslausetta, jos kadotat sen. @@ -338,11 +336,6 @@ **Suositus**: laitetunnus ja ilmoitukset lähetetään SimpleX Chat -ilmoituspalvelimelle, mutta ei viestin sisältöä, kokoa tai sitä, keneltä se on peräisin. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Skannaa QR-koodi**: muodosta yhteys kontaktiisi henkilökohtaisesti tai videopuhelun kautta. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Varoitus**: Välittömät push-ilmoitukset vaativat tunnuslauseen, joka on tallennettu Keychainiin. @@ -437,11 +430,6 @@ 1 viikko time interval - - 1-time link - Kertakäyttölinkki - No comment provided by engineer. - 5 minutes 5 minuuttia @@ -557,6 +545,10 @@ Lisää osoite profiiliisi, jotta kontaktisi voivat jakaa sen muiden kanssa. Profiilipäivitys lähetetään kontakteillesi. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Lisää esiasetettuja palvelimia @@ -951,6 +943,10 @@ Puhelut No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Käyttäjäprofiilia ei voi poistaa! @@ -1207,11 +1203,6 @@ This is your own one-time link! Yhdistä linkin kautta No comment provided by engineer. - - Connect via link / QR code - Yhdistä linkillä / QR-koodilla - No comment provided by engineer. - Connect via one-time link Yhdistä kertalinkillä @@ -1379,11 +1370,6 @@ This is your own one-time link! Luo uusi profiili [työpöytäsovelluksessa](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Luo kertakutsulinkki - No comment provided by engineer. - Create profile No comment provided by engineer. @@ -1408,6 +1394,10 @@ This is your own one-time link! Luotu %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Nykyinen pääsykoodi @@ -1949,6 +1939,10 @@ This cannot be undone! Ota automaattinen viestien poisto käyttöön? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Salli kaikille @@ -2285,6 +2279,10 @@ This cannot be undone! Virhe käyttäjän salasanan tallentamisessa No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Virhe sähköpostin lähettämisessä @@ -2753,11 +2751,6 @@ This cannot be undone! Jos et voi tavata henkilökohtaisesti, näytä QR-koodi videopuhelussa tai jaa linkki. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Jos et voi tavata henkilökohtaisesti, voit **skannata QR-koodin videopuhelussa** tai kontaktisi voi jakaa kutsulinkin. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Jos syötät tämän pääsykoodin sovellusta avatessasi, kaikki sovelluksen tiedot poistetaan peruuttamattomasti! @@ -2913,11 +2906,19 @@ This cannot be undone! Käyttöliittymä No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Virheellinen yhteyslinkki No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! No comment provided by engineer. @@ -3040,10 +3041,18 @@ This is your link for group %@! Liittyy ryhmään No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Pidä kontaktisi @@ -3370,6 +3379,10 @@ This is your link for group %@! Uusi pääsykoodi No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Uusi kontaktipyyntö @@ -3492,6 +3505,10 @@ This is your link for group %@! - poista jäsenet käytöstä ("tarkkailija" rooli) No comment provided by engineer. + + OK + No comment provided by engineer. + Off Pois @@ -3639,6 +3656,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count PING-määrä @@ -3679,11 +3704,6 @@ This is your link for group %@! Salasana näytettäväksi No comment provided by engineer. - - Paste - Liitä - No comment provided by engineer. - Paste desktop address No comment provided by engineer. @@ -3693,16 +3713,10 @@ This is your link for group %@! Liitä kuva No comment provided by engineer. - - Paste received link - Liitä vastaanotettu linkki + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Liitä saamasi linkki, jonka avulla voit muodostaa yhteyden kontaktiisi. - placeholder - People can connect to you only via the links you share. Ihmiset voivat ottaa sinuun yhteyttä vain jakamiesi linkkien kautta. @@ -3946,6 +3960,10 @@ Error: %@ Lue lisää [Käyttöoppaasta](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Lue lisää [Käyttöoppaasta](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4154,6 +4172,10 @@ Error: %@ Virhe tietokannan palauttamisessa No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Paljasta @@ -4308,6 +4330,10 @@ Error: %@ Haku No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Turvallinen jono @@ -4581,9 +4607,8 @@ Error: %@ Jaa linkki No comment provided by engineer. - - Share one-time invitation link - Jaa kertakutsulinkki + + Share this 1-time invite link No comment provided by engineer. @@ -4705,11 +4730,6 @@ Error: %@ Joku notification title - - Start a new chat - Aloita uusi keskustelu - No comment provided by engineer. - Start chat Aloita keskustelu @@ -4843,6 +4863,14 @@ Error: %@ Napauta liittyäksesi incognito-tilassa No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Aloita uusi keskustelu napauttamalla @@ -4905,6 +4933,10 @@ Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut.Tietokannan tunnuslauseen muuttamista ei suoritettu loppuun. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! Hyväksymäsi yhteys peruuntuu! @@ -4970,6 +5002,10 @@ Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut.Palvelimet nykyisen keskusteluprofiilisi uusille yhteyksille **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Teema @@ -5566,11 +5602,6 @@ Repeat join request? Voit vastaanottaa puheluita lukitusnäytöltä ilman laitteen ja sovelluksen todennusta. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Voit myös muodostaa yhteyden klikkaamalla linkkiä. Jos se avautuu selaimessa, napsauta **Avaa mobiilisovelluksessa**-painiketta. - No comment provided by engineer. - You can create it later Voit luoda sen myöhemmin @@ -5635,6 +5666,10 @@ Repeat join request? Voit käyttää markdownia viestien muotoiluun: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Et voi lähettää viestejä! diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff index 6ec667ed9..4d08ee965 100644 --- a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff +++ b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Ajouter un nouveau contact** : pour créer un lien ou code QR unique pour votre contact. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Créer un lien / code QR** que votre contact pourra utiliser. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Confidentiel** : ne pas utiliser le serveur de notifications SimpleX, vérification de nouveaux messages periodiquement en arrière plan (dépend de l'utilisation de l'app). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Collez le lien reçu** ou ouvrez-le dans votre navigateur et appuyez sur **Open in mobile app**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Veuillez noter** : vous NE pourrez PAS récupérer ou modifier votre phrase secrète si vous la perdez. @@ -347,11 +345,6 @@ **Recommandé** : le token de l'appareil et les notifications sont envoyés au serveur de notifications SimpleX, mais pas le contenu du message, sa taille ou son auteur. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Scanner le code QR** : pour vous connecter à votre contact en personne ou par appel vidéo. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Avertissement** : les notifications push instantanées nécessitent une phrase secrète enregistrée dans la keychain. @@ -453,11 +446,6 @@ 1 semaine time interval - - 1-time link - Lien à usage unique - No comment provided by engineer. - 5 minutes 5 minutes @@ -573,6 +561,10 @@ Ajoutez une adresse à votre profil, afin que vos contacts puissent la partager avec d'autres personnes. La mise à jour du profil sera envoyée à vos contacts. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Ajouter des serveurs prédéfinis @@ -978,6 +970,10 @@ Appels No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Impossible de supprimer le profil d'utilisateur ! @@ -1242,11 +1238,6 @@ Il s'agit de votre propre lien unique ! Se connecter via un lien No comment provided by engineer. - - Connect via link / QR code - Se connecter via un lien / code QR - No comment provided by engineer. - Connect via one-time link Se connecter via un lien unique @@ -1422,11 +1413,6 @@ Il s'agit de votre propre lien unique ! Créer un nouveau profil sur [l'application de bureau](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Créer un lien d'invitation unique - No comment provided by engineer. - Create profile Créer le profil @@ -1452,6 +1438,10 @@ Il s'agit de votre propre lien unique ! Créé le %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Code d'accès actuel @@ -2002,6 +1992,10 @@ Cette opération ne peut être annulée ! Activer la suppression automatique des messages ? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Activer pour tous @@ -2345,6 +2339,10 @@ Cette opération ne peut être annulée ! Erreur d'enregistrement du mot de passe de l'utilisateur No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Erreur lors de l'envoi de l'e-mail @@ -2820,11 +2818,6 @@ Cette opération ne peut être annulée ! Si vous ne pouvez pas vous rencontrer en personne, montrez le code QR lors d'un appel vidéo ou partagez le lien. 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. - Si vous ne pouvez pas voir la personne, vous pouvez **scanner le code QR dans un appel vidéo**, ou votre contact peut vous partager un lien d'invitation. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Si vous saisissez ce code à l'ouverture de l'application, toutes les données de l'application seront irréversiblement supprimées ! @@ -2982,11 +2975,19 @@ Cette opération ne peut être annulée ! Interface No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Lien de connection invalide No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! Nom invalide ! @@ -3114,11 +3115,19 @@ Voici votre lien pour le groupe %@ ! Entrain de rejoindre le groupe No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Garder l'application ouverte pour l'utiliser depuis le bureau No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Conserver vos connexions @@ -3449,6 +3458,10 @@ Voici votre lien pour le groupe %@ ! Nouveau code d'accès No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Nouvelle demande de contact @@ -3573,6 +3586,10 @@ Voici votre lien pour le groupe %@ ! - désactiver des membres (rôle "observateur") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Off @@ -3722,6 +3739,14 @@ Voici votre lien pour le groupe %@ ! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count Nombre de PING @@ -3762,11 +3787,6 @@ Voici votre lien pour le groupe %@ ! Mot de passe à entrer No comment provided by engineer. - - Paste - Coller - No comment provided by engineer. - Paste desktop address Coller l'adresse du bureau @@ -3777,16 +3797,10 @@ Voici votre lien pour le groupe %@ ! Coller l'image No comment provided by engineer. - - Paste received link - Coller le lien reçu + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Collez le lien que vous avez reçu dans le cadre ci-dessous pour vous connecter avec votre contact. - placeholder - People can connect to you only via the links you share. On ne peut se connecter à vous qu’avec les liens que vous partagez. @@ -4032,6 +4046,10 @@ Error: %@ Pour en savoir plus, consultez le [Guide de l'utilisateur](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Pour en savoir plus, consultez le [Guide de l'utilisateur](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4242,6 +4260,10 @@ Error: %@ Erreur de restauration de la base de données No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Révéler @@ -4397,6 +4419,10 @@ Error: %@ Recherche No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue File d'attente sécurisée @@ -4672,9 +4698,8 @@ Error: %@ Partager le lien No comment provided by engineer. - - Share one-time invitation link - Partager un lien d'invitation unique + + Share this 1-time invite link No comment provided by engineer. @@ -4797,11 +4822,6 @@ Error: %@ Quelqu'un notification title - - Start a new chat - Commencer une nouvelle conversation - No comment provided by engineer. - Start chat Démarrer le chat @@ -4936,6 +4956,14 @@ Error: %@ Appuyez pour rejoindre incognito No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Appuyez ici pour démarrer une nouvelle discussion @@ -4998,6 +5026,10 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise. La tentative de modification de la phrase secrète de la base de données n'a pas abouti. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! La connexion que vous avez acceptée sera annulée ! @@ -5063,6 +5095,10 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise. Les serveurs pour les nouvelles connexions de votre profil de chat actuel **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Thème @@ -5683,11 +5719,6 @@ Répéter la demande d'adhésion ? Vous pouvez accepter des appels à partir de l'écran de verrouillage, sans authentification de l'appareil ou de l'application. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Vous pouvez également vous connecter en cliquant sur le lien. S'il s'ouvre dans le navigateur, cliquez sur le bouton **Open in mobile app**. - No comment provided by engineer. - You can create it later Vous pouvez la créer plus tard @@ -5752,6 +5783,10 @@ Répéter la demande d'adhésion ? Vous pouvez utiliser le format markdown pour mettre en forme les messages : No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Vous ne pouvez pas envoyer de messages ! diff --git a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff index d1a17a3af..d9d48bd99 100644 --- a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff +++ b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Aggiungi un contatto**: per creare il tuo codice QR o link una tantum per il tuo contatto. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Crea link / codice QR** da usare per il tuo contatto. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Il più privato**: non usare il server di notifica di SimpleX Chat, controlla i messaggi periodicamente in secondo piano (dipende da quanto spesso usi l'app). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Incolla il link ricevuto** o aprilo nel browser e tocca **Apri in app mobile**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Nota bene**: NON potrai recuperare o cambiare la password se la perdi. @@ -347,11 +345,6 @@ **Consigliato**: vengono inviati il token del dispositivo e le notifiche al server di notifica di SimpleX Chat, ma non il contenuto del messaggio,la sua dimensione o il suo mittente. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Scansiona codice QR**: per connetterti al contatto di persona o via videochiamata. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Attenzione**: le notifiche push istantanee richiedono una password salvata nel portachiavi. @@ -453,11 +446,6 @@ 1 settimana time interval - - 1-time link - Link una tantum - No comment provided by engineer. - 5 minutes 5 minuti @@ -573,6 +561,10 @@ Aggiungi l'indirizzo al tuo profilo, in modo che i tuoi contatti possano condividerlo con altre persone. L'aggiornamento del profilo verrà inviato ai tuoi contatti. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Aggiungi server preimpostati @@ -978,6 +970,10 @@ Chiamate No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Impossibile eliminare il profilo utente! @@ -1242,11 +1238,6 @@ Questo è il tuo link una tantum! Connetti via link No comment provided by engineer. - - Connect via link / QR code - Connetti via link / codice QR - No comment provided by engineer. - Connect via one-time link Connetti via link una tantum @@ -1422,11 +1413,6 @@ Questo è il tuo link una tantum! Crea un nuovo profilo nell'[app desktop](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Crea link di invito una tantum - No comment provided by engineer. - Create profile Crea profilo @@ -1452,6 +1438,10 @@ Questo è il tuo link una tantum! Creato il %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Codice di accesso attuale @@ -2002,6 +1992,10 @@ Non è reversibile! Attivare l'eliminazione automatica dei messaggi? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Attiva per tutti @@ -2345,6 +2339,10 @@ Non è reversibile! Errore nel salvataggio della password utente No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Errore nell'invio dell'email @@ -2820,11 +2818,6 @@ Non è reversibile! Se non potete incontrarvi di persona, mostra il codice QR in una videochiamata o condividi il link. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Se non potete incontrarvi di persona, puoi **scansionare il codice QR durante la videochiamata** oppure il tuo contatto può condividere un link di invito. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Se inserisci questo codice all'apertura dell'app, tutti i dati di essa verranno rimossi in modo irreversibile! @@ -2982,11 +2975,19 @@ Non è reversibile! Interfaccia No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Link di connessione non valido No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! Nome non valido! @@ -3114,11 +3115,19 @@ Questo è il tuo link per il gruppo %@! Ingresso nel gruppo No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Tieni aperta l'app per usarla dal desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Mantieni le tue connessioni @@ -3449,6 +3458,10 @@ Questo è il tuo link per il gruppo %@! Nuovo codice di accesso No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Nuova richiesta di contatto @@ -3573,6 +3586,10 @@ Questo è il tuo link per il gruppo %@! - disattivare i membri (ruolo "osservatore") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Off @@ -3722,6 +3739,14 @@ Questo è il tuo link per il gruppo %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count Conteggio PING @@ -3762,11 +3787,6 @@ Questo è il tuo link per il gruppo %@! Password per mostrare No comment provided by engineer. - - Paste - Incolla - No comment provided by engineer. - Paste desktop address Incolla l'indirizzo desktop @@ -3777,16 +3797,10 @@ Questo è il tuo link per il gruppo %@! Incolla immagine No comment provided by engineer. - - Paste received link - Incolla il link ricevuto + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Incolla il link che hai ricevuto nella casella sottostante per connetterti con il tuo contatto. - placeholder - People can connect to you only via the links you share. Le persone possono connettersi a te solo tramite i link che condividi. @@ -4032,6 +4046,10 @@ Error: %@ Maggiori informazioni nella [Guida per l'utente](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Maggiori informazioni nella [Guida per l'utente](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4242,6 +4260,10 @@ Error: %@ Errore di ripristino del database No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Rivela @@ -4397,6 +4419,10 @@ Error: %@ Cerca No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Coda sicura @@ -4672,9 +4698,8 @@ Error: %@ Condividi link No comment provided by engineer. - - Share one-time invitation link - Condividi link di invito una tantum + + Share this 1-time invite link No comment provided by engineer. @@ -4797,11 +4822,6 @@ Error: %@ Qualcuno notification title - - Start a new chat - Inizia una nuova chat - No comment provided by engineer. - Start chat Avvia chat @@ -4936,6 +4956,14 @@ Error: %@ Toccare per entrare in incognito No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Tocca per iniziare una chat @@ -4998,6 +5026,10 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.Il tentativo di cambiare la password del database non è stato completato. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! La connessione che hai accettato verrà annullata! @@ -5063,6 +5095,10 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.I server per le nuove connessioni del profilo di chat attuale **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Tema @@ -5683,11 +5719,6 @@ Ripetere la richiesta di ingresso? Puoi accettare chiamate dalla schermata di blocco, senza l'autenticazione del dispositivo e dell'app. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Puoi anche connetterti cliccando il link. Se si apre nel browser, clicca il pulsante **Apri nell'app mobile**. - No comment provided by engineer. - You can create it later Puoi crearlo più tardi @@ -5752,6 +5783,10 @@ Ripetere la richiesta di ingresso? Puoi usare il markdown per formattare i messaggi: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Non puoi inviare messaggi! diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff index ac7f535e3..de25ffb08 100644 --- a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff +++ b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff @@ -306,14 +306,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **新しい連絡先を追加**: 連絡先のワンタイム QR コードまたはリンクを作成します。 No comment provided by engineer. - - **Create link / QR code** for your contact to use. - 連絡先が使用する **リンク/QR コードを作成します**。 + + **Create group**: to create a new group. No comment provided by engineer. @@ -326,11 +329,6 @@ **最もプライベート**: SimpleX Chat 通知サーバーを使用せず、バックグラウンドで定期的にメッセージをチェックします (アプリの使用頻度によって異なります)。 No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **受信したリンク**を貼り付けるか、ブラウザーで開いて [**モバイル アプリで開く**] をタップします。 - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **注意**: パスフレーズを紛失すると、パスフレーズを復元または変更できなくなります。 @@ -341,11 +339,6 @@ **推奨**: デバイス トークンと通知は SimpleX Chat 通知サーバーに送信されますが、メッセージの内容、サイズ、送信者は送信されません。 No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **QR コードをスキャン**: 直接またはビデオ通話で連絡先に接続します。 - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **警告**: 即時の プッシュ通知には、キーチェーンに保存されたパスフレーズが必要です。 @@ -440,11 +433,6 @@ 1週間 time interval - - 1-time link - 使い捨てのリンク - No comment provided by engineer. - 5 minutes 5分 @@ -560,6 +548,10 @@ プロフィールにアドレスを追加し、連絡先があなたのアドレスを他の人と共有できるようにします。プロフィールの更新は連絡先に送信されます。 No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers 既存サーバを追加 @@ -956,6 +948,10 @@ 通話 No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! ユーザープロフィールが削除できません! @@ -1212,11 +1208,6 @@ This is your own one-time link! リンク経由で接続 No comment provided by engineer. - - Connect via link / QR code - リンク・QRコード経由で接続 - No comment provided by engineer. - Connect via one-time link 使い捨てリンク経由で接続しますか? @@ -1384,11 +1375,6 @@ This is your own one-time link! [デスクトップアプリ](https://simplex.chat/downloads/)で新しいプロファイルを作成します。 💻 No comment provided by engineer. - - Create one-time invitation link - 使い捨ての招待リンクを生成する - No comment provided by engineer. - Create profile No comment provided by engineer. @@ -1413,6 +1399,10 @@ This is your own one-time link! %@ によって作成されました No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode 現在のパスコード @@ -1954,6 +1944,10 @@ This cannot be undone! 自動メッセージ削除を有効にしますか? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all すべて有効 @@ -2291,6 +2285,10 @@ This cannot be undone! ユーザーパスワード保存エラー No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email メールの送信にエラー発生 @@ -2759,11 +2757,6 @@ This cannot be undone! 直接会えない場合は、ビデオ通話で QR コードを表示するか、リンクを共有してください。 No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - 直接会えない場合は、**ビデオ通話で QR コードを表示する**か、リンクを共有してください。 - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! アプリを開くときにこのパスコードを入力すると、アプリのすべてのデータが元に戻せないように削除されます! @@ -2919,11 +2912,19 @@ This cannot be undone! インターフェース No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link 無効な接続リンク No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! No comment provided by engineer. @@ -3046,10 +3047,18 @@ This is your link for group %@! グループに参加 No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections 接続を維持 @@ -3375,6 +3384,10 @@ This is your link for group %@! 新しいパスコード No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request 新しい繋がりのリクエスト @@ -3498,6 +3511,10 @@ This is your link for group %@! - メンバーを無効にする (メッセージの送信不可) No comment provided by engineer. + + OK + No comment provided by engineer. + Off オフ @@ -3646,6 +3663,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count PING回数 @@ -3686,11 +3711,6 @@ This is your link for group %@! パスワードを表示する No comment provided by engineer. - - Paste - 貼り付け - No comment provided by engineer. - Paste desktop address No comment provided by engineer. @@ -3700,16 +3720,10 @@ This is your link for group %@! 画像の貼り付け No comment provided by engineer. - - Paste received link - 頂いたリンクを貼り付ける + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - 連絡相手から頂いたリンクを以下の入力欄に貼り付けて繋がります。 - placeholder - People can connect to you only via the links you share. あなたと繋がることができるのは、あなたからリンクを頂いた方のみです。 @@ -3953,6 +3967,10 @@ Error: %@ 詳しくは[ユーザーガイド](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address)をご覧ください。 No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). 詳しくは[ユーザーガイド](https://simplex.chat/docs/guide/readme.html#connect-to-friends)をご覧ください。 @@ -4160,6 +4178,10 @@ Error: %@ データベース復元エラー No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal 開示する @@ -4314,6 +4336,10 @@ Error: %@ 検索 No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue 待ち行列セキュリティ確認 @@ -4580,9 +4606,8 @@ Error: %@ リンクを送る No comment provided by engineer. - - Share one-time invitation link - 使い捨ての招待リンクを共有 + + Share this 1-time invite link No comment provided by engineer. @@ -4705,11 +4730,6 @@ Error: %@ 誰か notification title - - Start a new chat - 新しいチャットを開始する - No comment provided by engineer. - Start chat チャットを開始する @@ -4843,6 +4863,14 @@ Error: %@ タップしてシークレットモードで参加 No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat タップして新しいチャットを始める @@ -4905,6 +4933,10 @@ It can happen because of some bug or when the connection is compromised.データベースのパスフレーズ変更が完了してません。 No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! 承認済の接続がキャンセルされます! @@ -4970,6 +5002,10 @@ It can happen because of some bug or when the connection is compromised.現在のチャットプロフィールの新しい接続のサーバ **%@**。 No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme テーマ @@ -5565,11 +5601,6 @@ Repeat join request? デバイスやアプリの認証を行わずに、ロック画面から通話を受けることができます。 No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - リンクをクリックすることでも接続できます。ブラウザで開いた場合は、**モバイルアプリで開く**ボタンをクリックしてください。 - No comment provided by engineer. - You can create it later 後からでも作成できます @@ -5634,6 +5665,10 @@ Repeat join request? メッセージの書式にmarkdownを使用することができます: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! メッセージを送信できませんでした! diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff index 6b90e549b..e8aef28d4 100644 --- a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff +++ b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Nieuw contact toevoegen**: om uw eenmalige QR-code of link voor uw contact te maken. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Maak een link / QR-code aan** die uw contact kan gebruiken. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Meest privé**: gebruik geen SimpleX Chat-notificatie server, controleer berichten regelmatig op de achtergrond (afhankelijk van hoe vaak u de app gebruikt). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Plak de ontvangen link** of open deze in de browser en tik op **Openen in mobiele app**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Let op**: u kunt het wachtwoord NIET herstellen of wijzigen als u het kwijtraakt. @@ -347,11 +345,6 @@ **Aanbevolen**: apparaattoken en meldingen worden naar de SimpleX Chat-meldingsserver gestuurd, maar niet de berichtinhoud, -grootte of van wie het afkomstig is. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Scan QR-code**: om persoonlijk of via een video gesprek verbinding te maken met uw contact. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Waarschuwing**: voor directe push meldingen is een wachtwoord vereist dat is opgeslagen in de Keychain. @@ -453,11 +446,6 @@ 1 week time interval - - 1-time link - Eenmalige link - No comment provided by engineer. - 5 minutes 5 minuten @@ -573,6 +561,10 @@ Voeg een adres toe aan uw profiel, zodat uw contacten het met andere mensen kunnen delen. Profiel update wordt naar uw contacten verzonden. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Vooraf ingestelde servers toevoegen @@ -978,6 +970,10 @@ Oproepen No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Kan gebruikers profiel niet verwijderen! @@ -1242,11 +1238,6 @@ Dit is uw eigen eenmalige link! Maak verbinding via link No comment provided by engineer. - - Connect via link / QR code - Maak verbinding via link / QR-code - No comment provided by engineer. - Connect via one-time link Verbinden via een eenmalige link? @@ -1422,11 +1413,6 @@ Dit is uw eigen eenmalige link! Maak een nieuw profiel aan in [desktop-app](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Maak een eenmalige uitnodiging link - No comment provided by engineer. - Create profile Maak een profiel aan @@ -1452,6 +1438,10 @@ Dit is uw eigen eenmalige link! Gemaakt op %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Huidige toegangscode @@ -2002,6 +1992,10 @@ Dit kan niet ongedaan gemaakt worden! Automatisch verwijderen van berichten aanzetten? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Inschakelen voor iedereen @@ -2345,6 +2339,10 @@ Dit kan niet ongedaan gemaakt worden! Fout bij opslaan gebruikers wachtwoord No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Fout bij het verzenden van e-mail @@ -2820,11 +2818,6 @@ Dit kan niet ongedaan gemaakt worden! Als je elkaar niet persoonlijk kunt ontmoeten, laat dan de QR-code zien in een videogesprek of deel de link. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Als u elkaar niet persoonlijk kunt ontmoeten, kunt u **de QR-code scannen in het video gesprek**, of uw contact kan een uitnodiging link delen. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Als u deze toegangscode invoert bij het openen van de app, worden alle app-gegevens onomkeerbaar verwijderd! @@ -2982,11 +2975,19 @@ Dit kan niet ongedaan gemaakt worden! Interface No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Ongeldige verbinding link No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! Ongeldige naam! @@ -3114,11 +3115,19 @@ Dit is jouw link voor groep %@! Deel nemen aan groep No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Houd de app geopend om deze vanaf de desktop te gebruiken No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Behoud uw verbindingen @@ -3449,6 +3458,10 @@ Dit is jouw link voor groep %@! Nieuwe toegangscode No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Nieuw contactverzoek @@ -3573,6 +3586,10 @@ Dit is jouw link voor groep %@! - schakel leden uit ("waarnemer" rol) No comment provided by engineer. + + OK + No comment provided by engineer. + Off Uit @@ -3722,6 +3739,14 @@ Dit is jouw link voor groep %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count PING count @@ -3762,11 +3787,6 @@ Dit is jouw link voor groep %@! Wachtwoord om weer te geven No comment provided by engineer. - - Paste - Plakken - No comment provided by engineer. - Paste desktop address Desktopadres plakken @@ -3777,16 +3797,10 @@ Dit is jouw link voor groep %@! Afbeelding plakken No comment provided by engineer. - - Paste received link - Plak de ontvangen link + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Plak de link die je hebt ontvangen in het vak hieronder om verbinding te maken met je contact. - placeholder - People can connect to you only via the links you share. Mensen kunnen alleen verbinding met u maken via de links die u deelt. @@ -4032,6 +4046,10 @@ Error: %@ Lees meer in de [Gebruikershandleiding](https://simplex.chat/docs/guide/app-settings.html#uw-simplex-contactadres). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Lees meer in de [Gebruikershandleiding](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4242,6 +4260,10 @@ Error: %@ Database fout herstellen No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Onthullen @@ -4397,6 +4419,10 @@ Error: %@ Zoeken No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Veilige wachtrij @@ -4672,9 +4698,8 @@ Error: %@ Deel link No comment provided by engineer. - - Share one-time invitation link - Eenmalige uitnodiging link delen + + Share this 1-time invite link No comment provided by engineer. @@ -4797,11 +4822,6 @@ Error: %@ Iemand notification title - - Start a new chat - Begin een nieuw gesprek - No comment provided by engineer. - Start chat Begin gesprek @@ -4936,6 +4956,14 @@ Error: %@ Tik om incognito lid te worden No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Tik om een nieuw gesprek te starten @@ -4998,6 +5026,10 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast. De poging om het wachtwoord van de database te wijzigen is niet voltooid. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! De door u geaccepteerde verbinding wordt geannuleerd! @@ -5063,6 +5095,10 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast. De servers voor nieuwe verbindingen van uw huidige chat profiel **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Thema @@ -5683,11 +5719,6 @@ Deelnameverzoek herhalen? U kunt oproepen van het vergrendelingsscherm accepteren, zonder apparaat- en app-verificatie. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - U kunt ook verbinding maken door op de link te klikken. Als het in de browser wordt geopend, klikt u op de knop **Openen in mobiele app**. - No comment provided by engineer. - You can create it later U kan het later maken @@ -5752,6 +5783,10 @@ Deelnameverzoek herhalen? U kunt markdown gebruiken voor opmaak in berichten: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Je kunt geen berichten versturen! diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff index 1ab569e3c..0cdbb8c7e 100644 --- a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff +++ b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Dodaj nowy kontakt**: aby stworzyć swój jednorazowy kod QR lub link dla kontaktu. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Utwórz link / kod QR**, aby Twój kontakt mógł z niego skorzystać. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Najbardziej prywatny**: nie korzystaj z serwera powiadomień SimpleX Chat, sprawdzaj wiadomości okresowo w tle (zależy jak często korzystasz z aplikacji). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Wklej otrzymany link** lub otwórz go w przeglądarce i dotknij **Otwórz w aplikacji mobilnej**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Uwaga**: NIE będziesz w stanie odzyskać lub zmienić hasła, jeśli je stracisz. @@ -347,11 +345,6 @@ **Zalecane**: token urządzenia i powiadomienia są wysyłane do serwera powiadomień SimpleX Chat, ale nie treść wiadomości, rozmiar lub od kogo jest. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Skanuj kod QR**: aby połączyć się z kontaktem osobiście lub za pomocą połączenia wideo. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Uwaga**: Natychmiastowe powiadomienia push wymagają hasła zapisanego w Keychain. @@ -453,11 +446,6 @@ 1 tydzień time interval - - 1-time link - 1-razowy link - No comment provided by engineer. - 5 minutes 5 minut @@ -573,6 +561,10 @@ Dodaj adres do swojego profilu, aby Twoje kontakty mogły go udostępnić innym osobom. Aktualizacja profilu zostanie wysłana do Twoich kontaktów. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Dodaj gotowe serwery @@ -978,6 +970,10 @@ Połączenia No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Nie można usunąć profilu użytkownika! @@ -1242,11 +1238,6 @@ To jest twój jednorazowy link! Połącz się przez link No comment provided by engineer. - - Connect via link / QR code - Połącz się przez link / kod QR - No comment provided by engineer. - Connect via one-time link Połącz przez jednorazowy link @@ -1422,11 +1413,6 @@ To jest twój jednorazowy link! Utwórz nowy profil w [aplikacji desktopowej](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Utwórz jednorazowy link do zaproszenia - No comment provided by engineer. - Create profile Utwórz profil @@ -1452,6 +1438,10 @@ To jest twój jednorazowy link! Utworzony w dniu %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Aktualny Pin @@ -2002,6 +1992,10 @@ To nie może być cofnięte! Czy włączyć automatyczne usuwanie wiadomości? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Włącz dla wszystkich @@ -2345,6 +2339,10 @@ To nie może być cofnięte! Błąd zapisu hasła użytkownika No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Błąd wysyłania e-mail @@ -2820,11 +2818,6 @@ To nie może być cofnięte! Jeśli nie możesz spotkać się osobiście, pokaż kod QR w rozmowie wideo lub udostępnij link. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Jeśli nie możesz spotkać się osobiście, możesz **zeskanować kod QR w rozmowie wideo** lub Twój kontakt może udostępnić link z zaproszeniem. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Jeśli wprowadzisz ten pin podczas otwierania aplikacji, wszystkie dane aplikacji zostaną nieodwracalnie usunięte! @@ -2982,11 +2975,19 @@ To nie może być cofnięte! Interfejs No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Nieprawidłowy link połączenia No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! Nieprawidłowa nazwa! @@ -3114,11 +3115,19 @@ To jest twój link do grupy %@! Dołączanie do grupy No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Zostaw aplikację otwartą i używaj ją z komputera No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Zachowaj swoje połączenia @@ -3449,6 +3458,10 @@ To jest twój link do grupy %@! Nowy Pin No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Nowa prośba o kontakt @@ -3573,6 +3586,10 @@ To jest twój link do grupy %@! - wyłączyć członków (rola "obserwatora") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Wyłączony @@ -3722,6 +3739,14 @@ To jest twój link do grupy %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count Liczba PINGÓW @@ -3762,11 +3787,6 @@ To jest twój link do grupy %@! Hasło do wyświetlenia No comment provided by engineer. - - Paste - Wklej - No comment provided by engineer. - Paste desktop address Wklej adres komputera @@ -3777,16 +3797,10 @@ To jest twój link do grupy %@! Wklej obraz No comment provided by engineer. - - Paste received link - Wklej otrzymany link + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Wklej otrzymany link w pole poniżej, aby połączyć się z kontaktem. - placeholder - People can connect to you only via the links you share. Ludzie mogą się z Tobą połączyć tylko poprzez linki, które udostępniasz. @@ -4032,6 +4046,10 @@ Error: %@ Przeczytaj więcej w [Podręczniku Użytkownika](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Przeczytaj więcej w [Podręczniku Użytkownika](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4242,6 +4260,10 @@ Error: %@ Błąd przywracania bazy danych No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Ujawnij @@ -4397,6 +4419,10 @@ Error: %@ Szukaj No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Bezpieczna kolejka @@ -4672,9 +4698,8 @@ Error: %@ Udostępnij link No comment provided by engineer. - - Share one-time invitation link - Jednorazowy link zaproszenia + + Share this 1-time invite link No comment provided by engineer. @@ -4797,11 +4822,6 @@ Error: %@ Ktoś notification title - - Start a new chat - Rozpocznij nowy czat - No comment provided by engineer. - Start chat Rozpocznij czat @@ -4936,6 +4956,14 @@ Error: %@ Dotnij, aby dołączyć w trybie incognito No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Dotknij, aby rozpocząć nowy czat @@ -4998,6 +5026,10 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom Próba zmiany hasła bazy danych nie została zakończona. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! Zaakceptowane przez Ciebie połączenie zostanie anulowane! @@ -5063,6 +5095,10 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom Serwery dla nowych połączeń bieżącego profilu czatu **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Motyw @@ -5683,11 +5719,6 @@ Powtórzyć prośbę dołączenia? Możesz przyjmować połączenia z ekranu blokady, bez uwierzytelniania urządzenia i aplikacji. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Możesz też połączyć się klikając w link. Jeśli otworzy się on w przeglądarce, kliknij przycisk **Otwórz w aplikacji mobilnej**. - No comment provided by engineer. - You can create it later Możesz go utworzyć później @@ -5752,6 +5783,10 @@ Powtórzyć prośbę dołączenia? Możesz używać markdown do formatowania wiadomości: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Nie możesz wysyłać wiadomości! diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff index 348b42c94..212945637 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Добавить новый контакт**: чтобы создать одноразовый QR код или ссылку для Вашего контакта. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Создать ссылку / QR код** для Вашего контакта. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Самый конфиденциальный**: не использовать сервер уведомлений SimpleX Chat, проверять сообщения периодически в фоновом режиме (зависит от того насколько часто Вы используете приложение). 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. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Внимание**: Вы не сможете восстановить или поменять пароль, если Вы его потеряете. @@ -347,11 +345,6 @@ **Рекомендовано**: токен устройства и уведомления отправляются на сервер SimpleX Chat, но сервер не получает сами сообщения, их размер или от кого они. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Сканировать QR код**: соединиться с Вашим контактом при встрече или во время видеозвонка. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Внимание**: для работы мгновенных уведомлений пароль должен быть сохранен в Keychain. @@ -453,11 +446,6 @@ 1 неделю time interval - - 1-time link - Одноразовая ссылка - No comment provided by engineer. - 5 minutes 5 минут @@ -573,6 +561,10 @@ Добавьте адрес в свой профиль, чтобы Ваши контакты могли поделиться им. Профиль будет отправлен Вашим контактам. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Добавить серверы по умолчанию @@ -978,6 +970,10 @@ Звонки No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Нельзя удалить профиль пользователя! @@ -1242,11 +1238,6 @@ This is your own one-time link! Соединиться через ссылку No comment provided by engineer. - - Connect via link / QR code - Соединиться через ссылку / QR код - No comment provided by engineer. - Connect via one-time link Соединиться через одноразовую ссылку @@ -1422,11 +1413,6 @@ This is your own one-time link! Создайте новый профиль в [приложении для компьютера](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Создать ссылку-приглашение - No comment provided by engineer. - Create profile Создать профиль @@ -1452,6 +1438,10 @@ This is your own one-time link! Дата создания %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Текущий Код @@ -2002,6 +1992,10 @@ This cannot be undone! Включить автоматическое удаление сообщений? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Включить для всех @@ -2345,6 +2339,10 @@ This cannot be undone! Ошибка при сохранении пароля пользователя No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Ошибка отправки email @@ -2820,11 +2818,6 @@ This cannot be undone! Если Вы не можете встретиться лично, покажите QR-код во время видеозвонка или поделитесь ссылкой. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Если Вы не можете встретиться лично, Вы можете **сосканировать QR код во время видеозвонка**, или Ваш контакт может отправить Вам ссылку. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Если Вы введете этот код при открытии приложения, все данные приложения будут безвозвратно удалены! @@ -2982,11 +2975,19 @@ This cannot be undone! Интерфейс No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Ошибка в ссылке контакта No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! Неверное имя! @@ -3114,11 +3115,19 @@ This is your link for group %@! Вступление в группу No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop Оставьте приложение открытым, чтобы использовать его с компьютера No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Сохраните Ваши соединения @@ -3449,6 +3458,10 @@ This is your link for group %@! Новый Код No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Новый запрос на соединение @@ -3573,6 +3586,10 @@ This is your link for group %@! - приостанавливать членов (роль "наблюдатель") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Выключено @@ -3722,6 +3739,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count Количество PING @@ -3762,11 +3787,6 @@ This is your link for group %@! Пароль чтобы раскрыть No comment provided by engineer. - - Paste - Вставить - No comment provided by engineer. - Paste desktop address Вставить адрес компьютера @@ -3777,16 +3797,10 @@ This is your link for group %@! Вставить изображение No comment provided by engineer. - - Paste received link - Вставить полученную ссылку + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Чтобы соединиться, вставьте ссылку, полученную от Вашего контакта. - placeholder - People can connect to you only via the links you share. С Вами можно соединиться только через созданные Вами ссылки. @@ -4032,6 +4046,10 @@ Error: %@ Узнать больше в [Руководстве пользователя](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Узнать больше в [Руководстве пользователя](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4242,6 +4260,10 @@ Error: %@ Ошибка при восстановлении базы данных No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Показать @@ -4397,6 +4419,10 @@ Error: %@ Поиск No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Защита очереди @@ -4672,9 +4698,8 @@ Error: %@ Поделиться ссылкой No comment provided by engineer. - - Share one-time invitation link - Поделиться ссылкой-приглашением + + Share this 1-time invite link No comment provided by engineer. @@ -4797,11 +4822,6 @@ Error: %@ Контакт notification title - - Start a new chat - Начать новый разговор - No comment provided by engineer. - Start chat Запустить чат @@ -4936,6 +4956,14 @@ Error: %@ Нажмите, чтобы вступить инкогнито No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Нажмите, чтобы начать чат @@ -4998,6 +5026,10 @@ It can happen because of some bug or when the connection is compromised.Попытка поменять пароль базы данных не была завершена. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! Подтвержденное соединение будет отменено! @@ -5063,6 +5095,10 @@ It can happen because of some bug or when the connection is compromised.Серверы для новых соединений Вашего текущего профиля чата **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Тема @@ -5683,11 +5719,6 @@ Repeat join request? Вы можете принимать звонки на экране блокировки, без аутентификации. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Вы также можете соединиться, открыв ссылку. Если ссылка откроется в браузере, нажмите кнопку **Open in mobile app**. - No comment provided by engineer. - You can create it later Вы можете создать его позже @@ -5752,6 +5783,10 @@ Repeat join request? Вы можете форматировать сообщения: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Вы не можете отправлять сообщения! diff --git a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff index c062999aa..b4520553c 100644 --- a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff +++ b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff @@ -297,14 +297,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **เพิ่มผู้ติดต่อใหม่**: เพื่อสร้างคิวอาร์โค้ดแบบใช้ครั้งเดียวหรือลิงก์สำหรับผู้ติดต่อของคุณ No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **สร้างลิงค์ / คิวอาร์โค้ด** เพื่อให้ผู้ติดต่อของคุณใช้ + + **Create group**: to create a new group. No comment provided by engineer. @@ -317,11 +320,6 @@ **ส่วนตัวที่สุด**: ไม่ใช้เซิร์ฟเวอร์การแจ้งเตือนของ SimpleX Chat ตรวจสอบข้อความเป็นระยะในพื้นหลัง (ขึ้นอยู่กับความถี่ที่คุณใช้แอป) No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **แปะลิงก์ที่ได้รับ** หรือเปิดในเบราว์เซอร์แล้วแตะ **เปิดในแอปมือถือ** - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **โปรดทราบ**: คุณจะไม่สามารถกู้คืนหรือเปลี่ยนรหัสผ่านได้หากคุณทำรหัสผ่านหาย @@ -332,11 +330,6 @@ **แนะนำ**: โทเค็นอุปกรณ์และการแจ้งเตือนจะถูกส่งไปยังเซิร์ฟเวอร์การแจ้งเตือนของ SimpleX Chat แต่ไม่ใช่เนื้อหาข้อความ ขนาด หรือผู้ที่ส่ง No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **สแกนคิวอาร์โค้ด**: เพื่อเชื่อมต่อกับผู้ติดต่อของคุณด้วยตนเองหรือผ่านการสนทนาทางวิดีโอ - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **คำเตือน**: การแจ้งเตือนแบบพุชทันทีจำเป็นต้องบันทึกรหัสผ่านไว้ใน Keychain @@ -431,11 +424,6 @@ 1 สัปดาห์ time interval - - 1-time link - ลิงก์สำหรับใช้ 1 ครั้ง - No comment provided by engineer. - 5 minutes 5 นาที @@ -549,6 +537,10 @@ เพิ่มที่อยู่ลงในโปรไฟล์ของคุณ เพื่อให้ผู้ติดต่อของคุณสามารถแชร์กับผู้อื่นได้ การอัปเดตโปรไฟล์จะถูกส่งไปยังผู้ติดต่อของคุณ No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers เพิ่มเซิร์ฟเวอร์ที่ตั้งไว้ล่วงหน้า @@ -943,6 +935,10 @@ โทร No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! ไม่สามารถลบโปรไฟล์ผู้ใช้ได้! @@ -1198,11 +1194,6 @@ This is your own one-time link! เชื่อมต่อผ่านลิงก์ No comment provided by engineer. - - Connect via link / QR code - เชื่อมต่อผ่านลิงค์ / คิวอาร์โค้ด - No comment provided by engineer. - Connect via one-time link No comment provided by engineer. @@ -1368,11 +1359,6 @@ This is your own one-time link! Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - สร้างลิงก์เชิญแบบใช้ครั้งเดียว - No comment provided by engineer. - Create profile No comment provided by engineer. @@ -1397,6 +1383,10 @@ This is your own one-time link! สร้างเมื่อ %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode รหัสผ่านปัจจุบัน @@ -1936,6 +1926,10 @@ This cannot be undone! เปิดใช้งานการลบข้อความอัตโนมัติ? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all เปิดใช้งานสําหรับทุกคน @@ -2270,6 +2264,10 @@ This cannot be undone! เกิดข้อผิดพลาดในการบันทึกรหัสผ่านผู้ใช้ No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email เกิดข้อผิดพลาดในการส่งอีเมล @@ -2738,11 +2736,6 @@ This cannot be undone! หากคุณไม่สามารถพบกันในชีวิตจริงได้ ให้แสดงคิวอาร์โค้ดในวิดีโอคอล หรือแชร์ลิงก์ 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. - หากคุณไม่สามารถพบปะด้วยตนเอง คุณสามารถ **สแกนคิวอาร์โค้ดผ่านการสนทนาทางวิดีโอ** หรือผู้ติดต่อของคุณสามารถแชร์ลิงก์เชิญได้ - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! หากคุณใส่รหัสผ่านนี้เมื่อเปิดแอป ข้อมูลแอปทั้งหมดจะถูกลบอย่างถาวร! @@ -2897,11 +2890,19 @@ This cannot be undone! อินเตอร์เฟซ No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link ลิงค์เชื่อมต่อไม่ถูกต้อง No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! No comment provided by engineer. @@ -3023,10 +3024,18 @@ This is your link for group %@! กำลังจะเข้าร่วมกลุ่ม No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections รักษาการเชื่อมต่อของคุณ @@ -3352,6 +3361,10 @@ This is your link for group %@! รหัสผ่านใหม่ No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request คำขอติดต่อใหม่ @@ -3473,6 +3486,10 @@ This is your link for group %@! - ปิดการใช้งานสมาชิก (บทบาท "ผู้สังเกตการณ์") No comment provided by engineer. + + OK + No comment provided by engineer. + Off ปิด @@ -3620,6 +3637,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count จํานวน PING @@ -3660,11 +3685,6 @@ This is your link for group %@! รหัสผ่านที่จะแสดง No comment provided by engineer. - - Paste - แปะ - No comment provided by engineer. - Paste desktop address No comment provided by engineer. @@ -3674,15 +3694,10 @@ This is your link for group %@! แปะภาพ No comment provided by engineer. - - Paste received link - แปะลิงก์ที่ได้รับ + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - placeholder - People can connect to you only via the links you share. ผู้คนสามารถเชื่อมต่อกับคุณผ่านลิงก์ที่คุณแบ่งปันเท่านั้น @@ -3926,6 +3941,10 @@ Error: %@ อ่านเพิ่มเติมใน[คู่มือผู้ใช้](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address) No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). อ่านเพิ่มเติมใน[คู่มือผู้ใช้](https://simplex.chat/docs/guide/readme.html#connect-to-friends) @@ -4132,6 +4151,10 @@ Error: %@ กู้คืนข้อผิดพลาดของฐานข้อมูล No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal เปิดเผย @@ -4286,6 +4309,10 @@ Error: %@ ค้นหา No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue คิวที่ปลอดภัย @@ -4557,9 +4584,8 @@ Error: %@ แชร์ลิงก์ No comment provided by engineer. - - Share one-time invitation link - แชร์ลิงก์เชิญแบบใช้ครั้งเดียว + + Share this 1-time invite link No comment provided by engineer. @@ -4679,11 +4705,6 @@ Error: %@ ใครบางคน notification title - - Start a new chat - เริ่มแชทใหม่ - No comment provided by engineer. - Start chat เริ่มแชท @@ -4817,6 +4838,14 @@ Error: %@ แตะเพื่อเข้าร่วมโหมดไม่ระบุตัวตน No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat แตะเพื่อเริ่มแชทใหม่ @@ -4880,6 +4909,10 @@ It can happen because of some bug or when the connection is compromised.ความพยายามในการเปลี่ยนรหัสผ่านของฐานข้อมูลไม่เสร็จสมบูรณ์ No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! การเชื่อมต่อที่คุณยอมรับจะถูกยกเลิก! @@ -4945,6 +4978,10 @@ It can happen because of some bug or when the connection is compromised.เซิร์ฟเวอร์สำหรับการเชื่อมต่อใหม่ของโปรไฟล์การแชทปัจจุบันของคุณ **%@** No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme ธีม @@ -5537,11 +5574,6 @@ Repeat join request? คุณสามารถรับสายจากหน้าจอล็อกโดยไม่ต้องมีการตรวจสอบสิทธิ์อุปกรณ์และแอป No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - คุณสามารถเชื่อมต่อได้โดยคลิกที่ลิงค์ หากเปิดในเบราว์เซอร์ ให้คลิกปุ่ม **เปิดในแอปมือถือ** - No comment provided by engineer. - You can create it later คุณสามารถสร้างได้ในภายหลัง @@ -5606,6 +5638,10 @@ Repeat join request? คุณสามารถใช้มาร์กดาวน์เพื่อจัดรูปแบบข้อความ: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! คุณไม่สามารถส่งข้อความได้! diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff index 2bb43ba73..2d219440f 100644 --- a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff +++ b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff @@ -312,14 +312,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **Додати новий контакт**: щоб створити одноразовий QR-код або посилання для свого контакту. No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **Створіть посилання / QR-код** для використання вашим контактом. + + **Create group**: to create a new group. No comment provided by engineer. @@ -332,11 +335,6 @@ **Найбільш приватний**: не використовуйте сервер сповіщень SimpleX Chat, періодично перевіряйте повідомлення у фоновому режимі (залежить від того, як часто ви користуєтесь додатком). No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **Вставте отримане посилання** або відкрийте його в браузері і натисніть **Відкрити в мобільному додатку**. - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **Зверніть увагу: ви НЕ зможете відновити або змінити пароль, якщо втратите його. @@ -347,11 +345,6 @@ **Рекомендується**: токен пристрою та сповіщення надсилаються на сервер сповіщень SimpleX Chat, але не вміст повідомлення, його розмір або від кого воно надійшло. No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **Відскануйте QR-код**: щоб з'єднатися з вашим контактом особисто або за допомогою відеодзвінка. - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **Попередження**: Для отримання миттєвих пуш-сповіщень потрібна парольна фраза, збережена у брелоку. @@ -453,11 +446,6 @@ 1 тиждень time interval - - 1-time link - 1-разове посилання - No comment provided by engineer. - 5 minutes 5 хвилин @@ -573,6 +561,10 @@ Додайте адресу до свого профілю, щоб ваші контакти могли поділитися нею з іншими людьми. Повідомлення про оновлення профілю буде надіслано вашим контактам. No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers Додавання попередньо встановлених серверів @@ -978,6 +970,10 @@ Дзвінки No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! Не можу видалити профіль користувача! @@ -1242,11 +1238,6 @@ This is your own one-time link! Підключіться за посиланням No comment provided by engineer. - - Connect via link / QR code - Підключитися за посиланням / QR-кодом - No comment provided by engineer. - Connect via one-time link Під'єднатися за одноразовим посиланням @@ -1415,11 +1406,6 @@ This is your own one-time link! Create new profile in [desktop app](https://simplex.chat/downloads/). 💻 No comment provided by engineer. - - Create one-time invitation link - Створіть одноразове посилання-запрошення - No comment provided by engineer. - Create profile No comment provided by engineer. @@ -1444,6 +1430,10 @@ This is your own one-time link! Створено %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode Поточний пароль @@ -1984,6 +1974,10 @@ This cannot be undone! Увімкнути автоматичне видалення повідомлень? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all Увімкнути для всіх @@ -2318,6 +2312,10 @@ This cannot be undone! Помилка збереження пароля користувача No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email Помилка надсилання електронного листа @@ -2786,11 +2784,6 @@ This cannot be undone! Якщо ви не можете зустрітися особисто, покажіть QR-код у відеодзвінку або поділіться посиланням. No comment provided by engineer. - - If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link. - Якщо ви не можете зустрітися особисто, ви можете **сканувати QR-код у відеодзвінку**, або ваш контакт може поділитися посиланням на запрошення. - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! Якщо ви введете цей пароль при відкритті програми, всі дані програми будуть безповоротно видалені! @@ -2946,11 +2939,19 @@ This cannot be undone! Інтерфейс No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link Неправильне посилання для підключення No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! No comment provided by engineer. @@ -3073,10 +3074,18 @@ This is your link for group %@! Приєднання до групи No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections Зберігайте свої зв'язки @@ -3403,6 +3412,10 @@ This is your link for group %@! Новий пароль No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request Новий запит на контакт @@ -3525,6 +3538,10 @@ This is your link for group %@! - відключати користувачів (роль "спостерігач") No comment provided by engineer. + + OK + No comment provided by engineer. + Off Вимкнено @@ -3672,6 +3689,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count Кількість PING @@ -3712,11 +3737,6 @@ This is your link for group %@! Показати пароль No comment provided by engineer. - - Paste - Вставити - No comment provided by engineer. - Paste desktop address No comment provided by engineer. @@ -3726,16 +3746,10 @@ This is your link for group %@! Вставити зображення No comment provided by engineer. - - Paste received link - Вставте отримане посилання + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - Вставте отримане посилання для зв'язку з вашим контактом. - placeholder - People can connect to you only via the links you share. Люди можуть зв'язатися з вами лише за посиланнями, якими ви ділитеся. @@ -3979,6 +3993,10 @@ Error: %@ Читайте більше в [Посібнику користувача](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address). No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). Читайте більше в [Посібнику користувача](https://simplex.chat/docs/guide/readme.html#connect-to-friends). @@ -4187,6 +4205,10 @@ Error: %@ Відновлення помилки бази даних No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal Показувати @@ -4341,6 +4363,10 @@ Error: %@ Пошук No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue Безпечна черга @@ -4614,9 +4640,8 @@ Error: %@ Поділіться посиланням No comment provided by engineer. - - Share one-time invitation link - Поділіться посиланням на одноразове запрошення + + Share this 1-time invite link No comment provided by engineer. @@ -4738,11 +4763,6 @@ Error: %@ Хтось notification title - - Start a new chat - Почніть новий чат - No comment provided by engineer. - Start chat Почати чат @@ -4876,6 +4896,14 @@ Error: %@ Натисніть, щоб приєднатися інкогніто No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat Натисніть, щоб почати новий чат @@ -4938,6 +4966,10 @@ It can happen because of some bug or when the connection is compromised.Спроба змінити пароль до бази даних не була завершена. No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! Прийняте вами з'єднання буде скасовано! @@ -5003,6 +5035,10 @@ It can happen because of some bug or when the connection is compromised.Сервери для нових підключень вашого поточного профілю чату **%@**. No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme Тема @@ -5599,11 +5635,6 @@ Repeat join request? Ви можете приймати дзвінки з екрана блокування без автентифікації пристрою та програми. No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - Ви також можете підключитися за посиланням. Якщо воно відкриється в браузері, натисніть кнопку **Відкрити в мобільному додатку**. - No comment provided by engineer. - You can create it later Ви можете створити його пізніше @@ -5668,6 +5699,10 @@ Repeat join request? Ви можете використовувати розмітку для форматування повідомлень: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! Ви не можете надсилати повідомлення! diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff index 6a07b2815..60434b166 100644 --- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff +++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff @@ -303,14 +303,17 @@ ) No comment provided by engineer. + + **Add contact**: to create a new invitation link, or connect via a link you received. + No comment provided by engineer. + **Add new contact**: to create your one-time QR Code or link for your contact. **添加新联系人**:为您的联系人创建一次性二维码或者链接。 No comment provided by engineer. - - **Create link / QR code** for your contact to use. - **创建链接 / 二维码** 给您的联系人使用。 + + **Create group**: to create a new group. No comment provided by engineer. @@ -323,11 +326,6 @@ **最私密**:不使用 SimpleX Chat 通知服务器,在后台定期检查消息(取决于您多经常使用应用程序)。 No comment provided by engineer. - - **Paste received link** or open it in the browser and tap **Open in mobile app**. - **粘贴收到的链接**或者在浏览器里打开并且点击**在移动应用程序里打开**。 - No comment provided by engineer. - **Please note**: you will NOT be able to recover or change passphrase if you lose it. **请注意**:如果您丢失密码,您将无法恢复或者更改密码。 @@ -338,11 +336,6 @@ **推荐**:设备令牌和通知会发送至 SimpleX Chat 通知服务器,但是消息内容、大小或者发送人不会。 No comment provided by engineer. - - **Scan QR code**: to connect to your contact in person or via video call. - **扫描二维码**:见面或者通过视频通话来连接您的联系人。 - No comment provided by engineer. - **Warning**: Instant push notifications require passphrase saved in Keychain. **警告**:及时推送通知需要保存在钥匙串的密码。 @@ -440,11 +433,6 @@ 1周 time interval - - 1-time link - 一次性链接 - No comment provided by engineer. - 5 minutes 5分钟 @@ -560,6 +548,10 @@ 将地址添加到您的个人资料,以便您的联系人可以与其他人共享。个人资料更新将发送给您的联系人。 No comment provided by engineer. + + Add contact + No comment provided by engineer. + Add preset servers 添加预设服务器 @@ -956,6 +948,10 @@ 通话 No comment provided by engineer. + + Camera not available + No comment provided by engineer. + Can't delete user profile! 无法删除用户个人资料! @@ -1212,11 +1208,6 @@ This is your own one-time link! 通过链接连接 No comment provided by engineer. - - Connect via link / QR code - 通过群组链接/二维码连接 - No comment provided by engineer. - Connect via one-time link 通过一次性链接连接 @@ -1384,11 +1375,6 @@ This is your own one-time link! 在[桌面应用程序](https://simplex.chat/downloads/)中创建新的个人资料。 💻 No comment provided by engineer. - - Create one-time invitation link - 创建一次性邀请链接 - No comment provided by engineer. - Create profile No comment provided by engineer. @@ -1413,6 +1399,10 @@ This is your own one-time link! 创建于 %@ No comment provided by engineer. + + Creating link… + No comment provided by engineer. + Current Passcode 当前密码 @@ -1954,6 +1944,10 @@ This cannot be undone! 启用自动删除消息? No comment provided by engineer. + + Enable camera access + No comment provided by engineer. + Enable for all 全部启用 @@ -2292,6 +2286,10 @@ This cannot be undone! 保存用户密码时出错 No comment provided by engineer. + + Error scanning code: %@ + No comment provided by engineer. + Error sending email 发送电邮错误 @@ -2761,11 +2759,6 @@ This cannot be undone! 如果您不能亲自见面,可以在视频通话中展示二维码,或分享链接。 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. - 如果您不能亲自见面,您可以**扫描视频通话中的二维码**,或者您的联系人可以分享邀请链接。 - No comment provided by engineer. - If you enter this passcode when opening the app, all app data will be irreversibly removed! 如果您在打开应用时输入该密码,所有应用程序数据将被不可撤回地删除! @@ -2921,11 +2914,19 @@ This cannot be undone! 界面 No comment provided by engineer. + + Invalid QR code + No comment provided by engineer. + Invalid connection link 无效的连接链接 No comment provided by engineer. + + Invalid link + No comment provided by engineer. + Invalid name! No comment provided by engineer. @@ -3048,10 +3049,18 @@ This is your link for group %@! 加入群组中 No comment provided by engineer. + + Keep + No comment provided by engineer. + Keep the app open to use it from desktop No comment provided by engineer. + + Keep unused invitation? + No comment provided by engineer. + Keep your connections 保持连接 @@ -3378,6 +3387,10 @@ This is your link for group %@! 新密码 No comment provided by engineer. + + New chat + No comment provided by engineer. + New contact request 新联系人请求 @@ -3501,6 +3514,10 @@ This is your link for group %@! - 禁用成员(“观察员”角色) No comment provided by engineer. + + OK + No comment provided by engineer. + Off 关闭 @@ -3649,6 +3666,14 @@ This is your link for group %@! Opening app… No comment provided by engineer. + + Or scan QR code + No comment provided by engineer. + + + Or show this code + No comment provided by engineer. + PING count PING 次数 @@ -3689,11 +3714,6 @@ This is your link for group %@! 显示密码 No comment provided by engineer. - - Paste - 粘贴 - No comment provided by engineer. - Paste desktop address No comment provided by engineer. @@ -3703,16 +3723,10 @@ This is your link for group %@! 粘贴图片 No comment provided by engineer. - - Paste received link - 粘贴收到的链接 + + Paste the link you received No comment provided by engineer. - - Paste the link you received to connect with your contact. - 将您收到的链接粘贴到下面的框中以与您的联系人联系。 - placeholder - People can connect to you only via the links you share. 人们只能通过您共享的链接与您建立联系。 @@ -3956,6 +3970,10 @@ Error: %@ 在 [用户指南](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address) 中阅读更多内容。 No comment provided by engineer. + + Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode). + No comment provided by engineer. + Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends). 在 [用户指南](https://simplex.chat/docs/guide/readme.html#connect-to-friends) 中阅读更多内容。 @@ -4164,6 +4182,10 @@ Error: %@ 恢复数据库错误 No comment provided by engineer. + + Retry + No comment provided by engineer. + Reveal 揭示 @@ -4318,6 +4340,10 @@ Error: %@ 搜索 No comment provided by engineer. + + Search or paste SimpleX link + No comment provided by engineer. + Secure queue 保护队列 @@ -4592,9 +4618,8 @@ Error: %@ 分享链接 No comment provided by engineer. - - Share one-time invitation link - 分享一次性邀请链接 + + Share this 1-time invite link No comment provided by engineer. @@ -4717,11 +4742,6 @@ Error: %@ 某人 notification title - - Start a new chat - 开始新聊天 - No comment provided by engineer. - Start chat 开始聊天 @@ -4855,6 +4875,14 @@ Error: %@ 点击以加入隐身聊天 No comment provided by engineer. + + Tap to paste link + No comment provided by engineer. + + + Tap to scan + No comment provided by engineer. + Tap to start a new chat 点击开始一个新聊天 @@ -4917,6 +4945,10 @@ It can happen because of some bug or when the connection is compromised.更改数据库密码的尝试未完成。 No comment provided by engineer. + + The code you scanned is not a SimpleX link QR code. + No comment provided by engineer. + The connection you accepted will be cancelled! 您接受的连接将被取消! @@ -4982,6 +5014,10 @@ It can happen because of some bug or when the connection is compromised.您当前聊天资料 **%@** 的新连接服务器。 No comment provided by engineer. + + The text you pasted is not a SimpleX link. + No comment provided by engineer. + Theme 主题 @@ -5579,11 +5615,6 @@ Repeat join request? 您可以从锁屏上接听电话,无需设备和应用程序的认证。 No comment provided by engineer. - - You can also connect by clicking the link. If it opens in the browser, click **Open in mobile app** button. - 您也可以通过点击链接进行连接。如果在浏览器中打开,请点击“在移动应用程序中打开”按钮。 - No comment provided by engineer. - You can create it later 您可以以后创建它 @@ -5648,6 +5679,10 @@ Repeat join request? 您可以使用 markdown 来编排消息格式: No comment provided by engineer. + + You can view invitation link again in connection details. + No comment provided by engineer. + You can't send messages! 您无法发送消息! diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 801116bf8..a6b5eb49e 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -16,7 +16,6 @@ 18415C6C56DBCEC2CBBD2F11 /* WebRTCClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18415323A4082FC92887F906 /* WebRTCClient.swift */; }; 18415F9A2D551F9757DA4654 /* CIVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18415FD2E36F13F596A45BB4 /* CIVideoView.swift */; }; 18415FEFE153C5920BFB7828 /* GroupWelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1841516F0CE5992B0EDFB377 /* GroupWelcomeView.swift */; }; - 3C8C548928133C84000A3EC7 /* PasteToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C8C548828133C84000A3EC7 /* PasteToConnectView.swift */; }; 3CDBCF4227FAE51000354CDD /* ComposeLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */; }; 3CDBCF4827FF621E00354CDD /* CILinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CDBCF4727FF621E00354CDD /* CILinkView.swift */; }; 5C00164428A26FBC0094D739 /* ContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C00164328A26FBC0094D739 /* ContextMenu.swift */; }; @@ -61,7 +60,6 @@ 5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */; }; 5C65DAF929D0CC20003CEE45 /* DeveloperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65DAF829D0CC20003CEE45 /* DeveloperView.swift */; }; 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65F341297D3F3600B67AF3 /* VersionView.swift */; }; - 5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6AD81227A834E300348BD7 /* NewChatButton.swift */; }; 5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6BA666289BD954009B8ECC /* DismissSheets.swift */; }; 5C7031162953C97F00150A12 /* CIFeaturePreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */; }; 5C7505A227B65FDB00BE3227 /* CIMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A127B65FDB00BE3227 /* CIMetaView.swift */; }; @@ -98,8 +96,6 @@ 5CB0BA92282713FD00B3292C /* CreateProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB0BA91282713FD00B3292C /* CreateProfile.swift */; }; 5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB0BA992827FD8800B3292C /* HowItWorks.swift */; }; 5CB2084F28DA4B4800D024EC /* RTCServers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB2084E28DA4B4800D024EC /* RTCServers.swift */; }; - 5CB2085128DB64CA00D024EC /* CreateLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB2085028DB64CA00D024EC /* CreateLinkView.swift */; }; - 5CB2085328DB7CAF00D024EC /* ConnectViaLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB2085228DB7CAF00D024EC /* ConnectViaLinkView.swift */; }; 5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB346E42868AA7F001FD2EF /* SuspendChat.swift */; }; 5CB346E72868D76D001FD2EF /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB346E62868D76D001FD2EF /* NotificationsView.swift */; }; 5CB346E92869E8BA001FD2EF /* PushEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB346E82869E8BA001FD2EF /* PushEnvironment.swift */; }; @@ -121,8 +117,6 @@ 5CC2C0FF2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CC2C0FD2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings */; }; 5CC868F329EB540C0017BBFD /* CIRcvDecryptionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC868F229EB540C0017BBFD /* CIRcvDecryptionError.swift */; }; 5CCB939C297EFCB100399E78 /* NavStackCompat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCB939B297EFCB100399E78 /* NavStackCompat.swift */; }; - 5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403327A5F6DF00368C90 /* AddContactView.swift */; }; - 5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; }; 5CD67B8F2B0E858A00C510B1 /* hs_init.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CD67B8D2B0E858A00C510B1 /* hs_init.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5CD67B902B0E858A00C510B1 /* hs_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 5CD67B8E2B0E858A00C510B1 /* hs_init.c */; }; 5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD472818589900503DA2 /* NotificationService.swift */; }; @@ -157,6 +151,8 @@ 5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFA59CF286477B400863A68 /* ChatArchiveView.swift */; }; 5CFE0921282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; }; 5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; }; + 640417CD2B29B8C200CCB412 /* NewChatMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640417CB2B29B8C200CCB412 /* NewChatMenuButton.swift */; }; + 640417CE2B29B8C200CCB412 /* NewChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640417CC2B29B8C200CCB412 /* NewChatView.swift */; }; 6407BA83295DA85D0082BA18 /* CIInvalidJSONView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */; }; 6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */; }; 6419EC582AB97507004A607A /* CIMemberCreatedContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */; }; @@ -177,6 +173,11 @@ 646BB38E283FDB6D001CE359 /* LocalAuthenticationUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646BB38D283FDB6D001CE359 /* LocalAuthenticationUtils.swift */; }; 647F090E288EA27B00644C40 /* GroupMemberInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647F090D288EA27B00644C40 /* GroupMemberInfoView.swift */; }; 648010AB281ADD15009009B9 /* CIFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648010AA281ADD15009009B9 /* CIFileView.swift */; }; + 64863B9B2B3C536500714A11 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64863B962B3C536500714A11 /* libgmpxx.a */; }; + 64863B9C2B3C536500714A11 /* libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64863B972B3C536500714A11 /* libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD-ghc9.6.3.a */; }; + 64863B9D2B3C536500714A11 /* libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64863B982B3C536500714A11 /* libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD.a */; }; + 64863B9E2B3C536500714A11 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64863B992B3C536500714A11 /* libgmp.a */; }; + 64863B9F2B3C536500714A11 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64863B9A2B3C536500714A11 /* libffi.a */; }; 649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */; }; 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; }; 64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; }; @@ -263,7 +264,6 @@ 18415B08031E8FB0F7FC27F9 /* CallViewRenderers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallViewRenderers.swift; sourceTree = ""; }; 18415DAAAD1ADBEDB0EDA852 /* VideoPlayerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerView.swift; sourceTree = ""; }; 18415FD2E36F13F596A45BB4 /* CIVideoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CIVideoView.swift; sourceTree = ""; }; - 3C8C548828133C84000A3EC7 /* PasteToConnectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteToConnectView.swift; sourceTree = ""; }; 3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeLinkView.swift; sourceTree = ""; }; 3CDBCF4727FF621E00354CDD /* CILinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CILinkView.swift; sourceTree = ""; }; 5C00164328A26FBC0094D739 /* ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenu.swift; sourceTree = ""; }; @@ -324,7 +324,6 @@ 5C65DAED29CB8908003CEE45 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 5C65DAF829D0CC20003CEE45 /* DeveloperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperView.swift; sourceTree = ""; }; 5C65F341297D3F3600B67AF3 /* VersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionView.swift; sourceTree = ""; }; - 5C6AD81227A834E300348BD7 /* NewChatButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatButton.swift; sourceTree = ""; }; 5C6BA666289BD954009B8ECC /* DismissSheets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissSheets.swift; sourceTree = ""; }; 5C6D183229E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = "pl.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; 5C6D183329E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -381,8 +380,6 @@ 5CB0BA91282713FD00B3292C /* CreateProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateProfile.swift; sourceTree = ""; }; 5CB0BA992827FD8800B3292C /* HowItWorks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HowItWorks.swift; sourceTree = ""; }; 5CB2084E28DA4B4800D024EC /* RTCServers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RTCServers.swift; sourceTree = ""; }; - 5CB2085028DB64CA00D024EC /* CreateLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateLinkView.swift; sourceTree = ""; }; - 5CB2085228DB7CAF00D024EC /* ConnectViaLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViaLinkView.swift; sourceTree = ""; }; 5CB2085428DE647400D024EC /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 5CB346E42868AA7F001FD2EF /* SuspendChat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuspendChat.swift; sourceTree = ""; }; 5CB346E62868D76D001FD2EF /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = ""; }; @@ -408,8 +405,6 @@ 5CC2C0FE2809BF11000C35E3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; 5CC868F229EB540C0017BBFD /* CIRcvDecryptionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIRcvDecryptionError.swift; sourceTree = ""; }; 5CCB939B297EFCB100399E78 /* NavStackCompat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavStackCompat.swift; sourceTree = ""; }; - 5CCD403327A5F6DF00368C90 /* AddContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactView.swift; sourceTree = ""; }; - 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanToConnectView.swift; sourceTree = ""; }; 5CD67B8D2B0E858A00C510B1 /* hs_init.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = hs_init.h; sourceTree = ""; }; 5CD67B8E2B0E858A00C510B1 /* hs_init.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = hs_init.c; sourceTree = ""; }; 5CDCAD452818589900503DA2 /* SimpleX NSE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SimpleX NSE.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -444,6 +439,8 @@ 5CFA59C32860BC6200863A68 /* MigrateToAppGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrateToAppGroupView.swift; sourceTree = ""; }; 5CFA59CF286477B400863A68 /* ChatArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatArchiveView.swift; sourceTree = ""; }; 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ZoomableScrollView.swift; path = Shared/Views/ZoomableScrollView.swift; sourceTree = SOURCE_ROOT; }; + 640417CB2B29B8C200CCB412 /* NewChatMenuButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewChatMenuButton.swift; sourceTree = ""; }; + 640417CC2B29B8C200CCB412 /* NewChatView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewChatView.swift; sourceTree = ""; }; 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIInvalidJSONView.swift; sourceTree = ""; }; 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextInvitingContactMemberView.swift; sourceTree = ""; }; 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMemberCreatedContactView.swift; sourceTree = ""; }; @@ -464,6 +461,11 @@ 646BB38D283FDB6D001CE359 /* LocalAuthenticationUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAuthenticationUtils.swift; sourceTree = ""; }; 647F090D288EA27B00644C40 /* GroupMemberInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupMemberInfoView.swift; sourceTree = ""; }; 648010AA281ADD15009009B9 /* CIFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIFileView.swift; sourceTree = ""; }; + 64863B962B3C536500714A11 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 64863B972B3C536500714A11 /* libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD-ghc9.6.3.a"; sourceTree = ""; }; + 64863B982B3C536500714A11 /* libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.2.0-1dXNnkvLJVS8FSAgswHDGD.a"; sourceTree = ""; }; + 64863B992B3C536500714A11 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + 64863B9A2B3C536500714A11 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; 6493D667280ED77F007A76FB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeImageView.swift; sourceTree = ""; }; 649BCDA12805D6EF00C3A862 /* CIImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIImageView.swift; sourceTree = ""; }; @@ -737,14 +739,10 @@ 5CB924DD27A8622200ACCCDD /* NewChat */ = { isa = PBXGroup; children = ( - 5C6AD81227A834E300348BD7 /* NewChatButton.swift */, - 5CCD403327A5F6DF00368C90 /* AddContactView.swift */, - 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */, - 3C8C548828133C84000A3EC7 /* PasteToConnectView.swift */, + 640417CB2B29B8C200CCB412 /* NewChatMenuButton.swift */, + 640417CC2B29B8C200CCB412 /* NewChatView.swift */, 5CC1C99127A6C7F5000D9FF6 /* QRCode.swift */, 6442E0B9287F169300CEC0F9 /* AddGroupView.swift */, - 5CB2085028DB64CA00D024EC /* CreateLinkView.swift */, - 5CB2085228DB7CAF00D024EC /* ConnectViaLinkView.swift */, 64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */, ); path = NewChat; @@ -1113,8 +1111,8 @@ buildActionMask = 2147483647; files = ( 64C06EB52A0A4A7C00792D4D /* ChatItemInfoView.swift in Sources */, + 640417CE2B29B8C200CCB412 /* NewChatView.swift in Sources */, 6440CA03288AECA70062C672 /* AddGroupMembersView.swift in Sources */, - 5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */, 5C3F1D58284363C400EC8A82 /* PrivacySettings.swift in Sources */, 5C55A923283CEDE600C4E99E /* SoundPlayer.swift in Sources */, 5C93292F29239A170090FFF9 /* ProtocolServersView.swift in Sources */, @@ -1161,13 +1159,11 @@ 5C063D2727A4564100AEC577 /* ChatPreviewView.swift in Sources */, 5CC868F329EB540C0017BBFD /* CIRcvDecryptionError.swift in Sources */, 5C35CFCB27B2E91D00FB6C6D /* NtfManager.swift in Sources */, - 3C8C548928133C84000A3EC7 /* PasteToConnectView.swift in Sources */, 5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */, 5C9A5BDB2871E05400A5B906 /* SetNotificationsMode.swift in Sources */, 5CB0BA8E2827126500B3292C /* OnboardingView.swift in Sources */, 6442E0BE2880182D00CEC0F9 /* GroupChatInfoView.swift in Sources */, 5C2E261227A30FEA00F70299 /* TerminalView.swift in Sources */, - 5CB2085128DB64CA00D024EC /* CreateLinkView.swift in Sources */, 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */, 5CA7DFC329302AF000F7FDDE /* AppSheet.swift in Sources */, 64E972072881BB22008DBC02 /* CIGroupInvitationView.swift in Sources */, @@ -1176,8 +1172,8 @@ 5CB9250D27A9432000ACCCDD /* ChatListNavLink.swift in Sources */, 649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */, 5CA059ED279559F40002BEB4 /* ContentView.swift in Sources */, - 5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */, 5C05DF532840AA1D00C683F9 /* CallSettings.swift in Sources */, + 640417CD2B29B8C200CCB412 /* NewChatMenuButton.swift in Sources */, 5CFE0921282EEAF60002594B /* ZoomableScrollView.swift in Sources */, 5C3A88CE27DF50170060F1C2 /* DetermineWidth.swift in Sources */, 5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */, @@ -1212,7 +1208,6 @@ 6448BBB628FA9D56000D2AB9 /* GroupLinkView.swift in Sources */, 5CB346E92869E8BA001FD2EF /* PushEnvironment.swift in Sources */, 5C55A91F283AD0E400C4E99E /* CallManager.swift in Sources */, - 5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */, 5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */, 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */, 8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */, @@ -1235,7 +1230,6 @@ 5C93293F2928E0FD0090FFF9 /* AudioRecPlay.swift in Sources */, 5C029EA82837DBB3004A9677 /* CICallItemView.swift in Sources */, 5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */, - 5CB2085328DB7CAF00D024EC /* ConnectViaLinkView.swift in Sources */, 5C9CC7A928C532AB00BEF955 /* DatabaseErrorView.swift in Sources */, 5C1A4C1E27A715B700EAD5AD /* ChatItemView.swift in Sources */, 64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */, diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index a545d3508..02c693cd2 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -3121,6 +3121,15 @@ public enum Format: Decodable, Equatable { case simplexLink(linkType: SimplexLinkType, simplexUri: String, smpHosts: [String]) case email case phone + + public var isSimplexLink: Bool { + get { + switch (self) { + case .simplexLink: return true + default: return false + } + } + } } public enum SimplexLinkType: String, Decodable {