diff --git a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift index 0e7d37cf77..5e68e13672 100644 --- a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift +++ b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift @@ -23,7 +23,7 @@ struct AddGroupMembersView: View { private enum AddGroupMembersAlert: Identifiable { case prohibitedToInviteIncognito - case error(title: LocalizedStringKey, error: String = "") + case error(title: LocalizedStringKey, error: LocalizedStringKey = "") var id: String { switch self { @@ -101,7 +101,7 @@ struct AddGroupMembersView: View { message: Text("You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile") ) case let .error(title, error): - return Alert(title: Text(title), message: Text("\(error)")) + return Alert(title: Text(title), message: Text(error)) } } } @@ -128,14 +128,8 @@ struct AddGroupMembersView: View { await MainActor.run { dismiss() } if let cb = addedMembersCb { cb(selectedContacts) } } catch { - switch error as? ChatResponse { - case .chatCmdError(.errorAgent(.BROKER(.TIMEOUT))): - alert = .error(title: "Connection timeout", error: NSLocalizedString("Please check your network connection and try again.", comment: "alert message")) - case .chatCmdError(.errorAgent(.BROKER(.NETWORK))): - alert = .error(title: "Connection error", error: NSLocalizedString("Please check your network connection and try again.", comment: "alert message")) - default: - alert = .error(title: "Error adding member(s)", error: responseError(error)) - } + let a = getErrorAlert(error, "Error adding member(s)") + alert = .error(title: a.title, error: a.message) } } } diff --git a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift index 4040cb844b..2dc7554fb0 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift @@ -22,7 +22,7 @@ struct GroupMemberInfoView: View { enum GroupMemberInfoViewAlert: Identifiable { case removeMemberAlert case changeMemberRoleAlert(role: GroupMemberRole) - case error(title: LocalizedStringKey, error: String) + case error(title: LocalizedStringKey, error: LocalizedStringKey) var id: String { switch self { @@ -176,7 +176,8 @@ struct GroupMemberInfoView: View { } } catch let error { logger.error("apiRemoveMember error: \(responseError(error))") - alert = errorAlert(error, "Error removing member") + let a = getErrorAlert(error, "Error removing member") + alert = .error(title: a.title, error: a.message) } } }, @@ -199,7 +200,8 @@ struct GroupMemberInfoView: View { } catch let error { newRole = member.memberRole logger.error("apiMemberRole error: \(responseError(error))") - alert = errorAlert(error, "Error changing role") + let a = getErrorAlert(error, "Error changing role") + alert = .error(title: a.title, error: a.message) } } }, @@ -208,17 +210,6 @@ struct GroupMemberInfoView: View { } ) } - - private func errorAlert(_ error: Error, _ title: LocalizedStringKey) -> GroupMemberInfoViewAlert { - switch error as? ChatResponse { - case .chatCmdError(.errorAgent(.BROKER(.TIMEOUT))): - return .error(title: "Connection timeout", error: NSLocalizedString("Please check your network connection and try again.", comment: "alert message")) - case .chatCmdError(.errorAgent(.BROKER(.NETWORK))): - return .error(title: "Connection error", error: NSLocalizedString("Please check your network connection and try again.", comment: "alert message")) - default: - return .error(title: title, error: responseError(error)) - } - } } struct GroupMemberInfoView_Previews: PreviewProvider { diff --git a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift index c4d82252c3..672a279cc6 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift @@ -30,6 +30,7 @@ struct ChatListNavLink: View { @State var chat: Chat @State private var showContactRequestDialog = false @State private var showJoinGroupDialog = false + @State private var showContactConnectionInfo = false var body: some View { switch chat.chatInfo { @@ -199,24 +200,32 @@ struct ChatListNavLink: View { } private func contactConnectionNavLink(_ contactConnection: PendingContactConnection) -> some View { - ContactConnectionView(contactConnection: contactConnection) + ContactConnectionView(chat: chat) .swipeActions(edge: .trailing, allowsFullSwipe: true) { Button { - AlertManager.shared.showAlert(deleteContactConnectionAlert(contactConnection)) + AlertManager.shared.showAlert(deleteContactConnectionAlert(contactConnection) { a in + AlertManager.shared.showAlertMsg(title: a.title, message: a.message) + }) } label: { Label("Delete", systemImage: "trash") } .tint(.red) + + Button { + showContactConnectionInfo = true + } label: { + Label("Name", systemImage: "pencil") + } + .tint(.accentColor) } .frame(height: rowHeights[dynamicTypeSize]) + .sheet(isPresented: $showContactConnectionInfo) { + if case let .contactConnection(contactConnection) = chat.chatInfo { + ContactConnectionInfo(contactConnection: contactConnection) + } + } .onTapGesture { - AlertManager.shared.showAlertMsg( - title: contactConnection.initiated - ? "You invited your contact" - : "You accepted connection", - // below are the same messages that are shown in alert - message: contactConnectionText(contactConnection) - ) + showContactConnectionInfo = true } } @@ -279,29 +288,6 @@ struct ChatListNavLink: View { ) } - private func deleteContactConnectionAlert(_ contactConnection: PendingContactConnection) -> Alert { - Alert( - title: Text("Delete pending connection?"), - message: - contactConnection.initiated - ? Text("The contact you shared this link with will NOT be able to connect!") - : Text("The connection you accepted will be cancelled!"), - primaryButton: .destructive(Text("Delete")) { - Task { - do { - try await apiDeleteChat(type: .contactConnection, id: contactConnection.apiId) - DispatchQueue.main.async { - chatModel.removeChat(contactConnection.id) - } - } catch let error { - logger.error("ChatListNavLink.deleteContactConnectionAlert apiDeleteChat error: \(responseError(error))") - } - } - }, - secondaryButton: .cancel() - ) - } - private func pendingContactAlert(_ chat: Chat, _ contact: Contact) -> Alert { Alert( title: Text("Contact is not connected yet!"), @@ -345,6 +331,32 @@ struct ChatListNavLink: View { } } +func deleteContactConnectionAlert(_ contactConnection: PendingContactConnection, showError: @escaping (ErrorAlert) -> Void, success: @escaping () -> Void = {}) -> Alert { + Alert( + title: Text("Delete pending connection?"), + message: + contactConnection.initiated + ? Text("The contact you shared this link with will NOT be able to connect!") + : Text("The connection you accepted will be cancelled!"), + primaryButton: .destructive(Text("Delete")) { + Task { + do { + try await apiDeleteChat(type: .contactConnection, id: contactConnection.apiId) + await MainActor.run { + ChatModel.shared.removeChat(contactConnection.id) + success() + } + } catch let error { + await MainActor.run { + showError(getErrorAlert(error, "Error deleting connection")) + } + } + } + }, + secondaryButton: .cancel() + ) +} + func joinGroup(_ groupId: Int64) { Task { logger.debug("joinGroup") @@ -361,15 +373,8 @@ func joinGroup(_ groupId: Int64) { await deleteGroup() } } catch let error { - switch error as? ChatResponse { - case .chatCmdError(.errorAgent(.BROKER(.TIMEOUT))): - AlertManager.shared.showAlertMsg(title: "Connection timeout", message: "Please check your network connection and try again.") - case .chatCmdError(.errorAgent(.BROKER(.NETWORK))): - AlertManager.shared.showAlertMsg(title: "Connection error", message: "Please check your network connection and try again.") - default: - logger.error("apiJoinGroup error: \(responseError(error))") - AlertManager.shared.showAlertMsg(title: "Error joining group", message: "\(responseError(error))") - } + let a = getErrorAlert(error, "Error joining group") + AlertManager.shared.showAlertMsg(title: a.title, message: a.message) } func deleteGroup() async { @@ -384,10 +389,20 @@ func joinGroup(_ groupId: Int64) { } } -func contactConnectionText(_ contactConnection: PendingContactConnection) -> LocalizedStringKey { - contactConnection.viaContactUri - ? "You will be connected when your connection request is accepted, please wait or check later!" - : "You will be connected when your contact's device is online, please wait or check later!" +struct ErrorAlert { + var title: LocalizedStringKey + var message: LocalizedStringKey +} + +func getErrorAlert(_ error: Error, _ title: LocalizedStringKey) -> ErrorAlert { + switch error as? ChatResponse { + case .chatCmdError(.errorAgent(.BROKER(.TIMEOUT))): + return ErrorAlert(title: "Connection timeout", message: "Please check your network connection and try again.") + case .chatCmdError(.errorAgent(.BROKER(.NETWORK))): + return ErrorAlert(title: "Connection error", message: "Please check your network connection and try again.") + default: + return ErrorAlert(title: title, message: "Error: \(responseError(error))") + } } struct ChatListNavLink_Previews: PreviewProvider { diff --git a/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift b/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift index 3b7b899bf6..8a6e2141df 100644 --- a/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift +++ b/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift @@ -2,7 +2,7 @@ // ContactConnectionInfo.swift // SimpleX (iOS) // -// Created by Evgeny on 30/09/2022. +// Created by Evgeny on 06/10/2022. // Copyright © 2022 SimpleX Chat. All rights reserved. // @@ -11,54 +11,128 @@ import SimpleXChat struct ContactConnectionInfo: View { @EnvironmentObject var m: ChatModel - var contactConnection: PendingContactConnection - var connReqInvitation: String + @Environment(\.dismiss) var dismiss: DismissAction + @State var contactConnection: PendingContactConnection + @State private var alert: CCInfoAlert? + @State private var showQRCodeView = false + @State private var localAlias = "" + @FocusState private var aliasTextFieldFocused: Bool + + enum CCInfoAlert: Identifiable { + case deleteInvitationAlert + case error(title: LocalizedStringKey, error: LocalizedStringKey) + + var id: String { + switch self { + case .deleteInvitationAlert: return "deleteInvitationAlert" + case let .error(title, _): return "error \(title)" + } + } + } var body: some View { - ScrollView { - VStack(alignment: .leading) { - Text("Shared one-time link") - .font(.largeTitle) - .bold() - .padding(.vertical) + NavigationView { + List { + Group { + Text(contactConnection.initiated ? "You invited your contact" : "You accepted connection") + .font(.largeTitle) + .bold() + .padding(.bottom, 16) - HStack { - if contactConnection.incognito { - Image(systemName: "theatermasks").foregroundColor(.indigo).font(.footnote) - Spacer().frame(width: 8) - Text("A random profile will be sent to your contact").font(.footnote) - } else { - Image(systemName: "info.circle").foregroundColor(.secondary).font(.footnote) - Spacer().frame(width: 8) - Text("Your chat profile will be sent to your contact").font(.footnote) + Text(contactConnectionText(contactConnection)) + } + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + .onTapGesture { aliasTextFieldFocused = false } + + Section { + HStack(spacing: 20) { + Image(systemName: "pencil") + .foregroundColor(.secondary) + .padding(.leading, 6) + .onTapGesture { aliasTextFieldFocused = true } + TextField("Set contact name…", text: $localAlias) + .autocapitalization(.none) + .autocorrectionDisabled(true) + .focused($aliasTextFieldFocused) + .submitLabel(.done) + .onSubmit(setConnectionAlias) + } + + if contactConnection.initiated && contactConnection.connReqInv != nil { + Button { + showQRCodeView = true + } label: { + Label("Show QR code", systemImage: "qrcode") + .foregroundColor(contactConnection.incognito ? .indigo : .accentColor) + } + } + + Button(role: .destructive) { + alert = .deleteInvitationAlert + } label: { + Label("Delete connection", systemImage: "trash") + .foregroundColor(Color.red) } } - - Text(contactConnectionText(contactConnection)) - .padding(.top, 4) - .padding(.bottom, 8) - - QRCode(uri: connReqInvitation).padding(.bottom) - - Text("If you can't meet in person, **show QR code in the video call**, or share the link.") - .padding(.bottom) - Button { - showShareSheet(items: [connReqInvitation]) - } label: { - Label("Share invitation link", systemImage: "square.and.arrow.up") - } - .frame(maxWidth: .infinity, alignment: .center) } - .padding() - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .onAppear { m.connReqInv = connReqInvitation } - .onDisappear { m.connReqInv = nil } + .listStyle(.insetGrouped) } + .sheet(isPresented: $showQRCodeView) { + if let connReqInv = contactConnection.connReqInv { + AddContactView(contactConnection: contactConnection, connReqInvitation: connReqInv) + } + } + .alert(item: $alert) { _alert in + switch _alert { + case .deleteInvitationAlert: + return deleteContactConnectionAlert(contactConnection) { a in + alert = .error(title: a.title, error: a.message) + } success: { + dismiss() + } + case let .error(title, error): return Alert(title: Text(title), message: Text(error)) + } + } + .onAppear { + localAlias = contactConnection.localAlias + aliasTextFieldFocused = true + } + } + + private func setConnectionAlias() { + if localAlias == contactConnection.localAlias { + aliasTextFieldFocused = false + return + } + Task { + let prevAlias = contactConnection.localAlias + contactConnection.localAlias = localAlias + do { + if let conn = try await apiSetConnectionAlias(connId: contactConnection.pccConnId, localAlias: localAlias) { + await MainActor.run { + contactConnection = conn + ChatModel.shared.updateContactConnection(conn) + dismiss() + } + } + } catch { + logger.error("setContactAlias error: \(responseError(error))") + contactConnection.localAlias = prevAlias + } + } + } + + private func contactConnectionText(_ contactConnection: PendingContactConnection) -> LocalizedStringKey { + contactConnection.viaContactUri + ? "You will be connected when your connection request is accepted, please wait or check later!" + : "You will be connected when your contact's device is online, please wait or check later!" } } struct ContactConnectionInfo_Previews: PreviewProvider { static var previews: some View { - ContactConnectionInfo(contactConnection: PendingContactConnection.getSampleData(), connReqInvitation: "") + ContactConnectionInfo(contactConnection: PendingContactConnection.getSampleData()) } } diff --git a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift index 59d8c5f401..a49789aeaa 100644 --- a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift +++ b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift @@ -11,80 +11,41 @@ import SimpleXChat struct ContactConnectionView: View { @EnvironmentObject var m: ChatModel - @State var contactConnection: PendingContactConnection - @State private var editLocalAlias = false + @ObservedObject var chat: Chat @State private var localAlias = "" @FocusState private var aliasTextFieldFocused: Bool @State private var showContactConnectionInfo = false var body: some View { + if case let .contactConnection(conn) = chat.chatInfo { + contactConnectionView(conn) + } + } + + func contactConnectionView(_ contactConnection: PendingContactConnection) -> some View { HStack(spacing: 8) { Group { - if contactConnection.initiated { - let v = Image(systemName: "qrcode") - .resizable() - .scaledToFill() - .frame(width: 40, height: 40) - if contactConnection.connReqInv == nil { - v.foregroundColor(Color(uiColor: .secondarySystemBackground)) - } else { - v.foregroundColor(contactConnection.incognito ? .indigo : .accentColor) - .onTapGesture { showContactConnectionInfo = true } - } - } else { - Image(systemName: "link") - .resizable() - .scaledToFill() - .frame(width: 48, height: 48) - .foregroundColor(Color(uiColor: .secondarySystemBackground)) - } + Image(systemName: contactConnection.initiated ? "link.badge.plus" : "link") + .resizable() + .scaledToFill() + .frame(width: 48, height: 48) + .foregroundColor(Color(uiColor: .secondarySystemBackground)) + .onTapGesture { showContactConnectionInfo = true } } .frame(width: 63, height: 63) .padding(.leading, 4) VStack(alignment: .leading, spacing: 0) { HStack(alignment: .top) { - Image(systemName: "pencil") - .resizable() - .scaledToFill() - .frame(width: 16, height: 16) + Text(contactConnection.chatViewName) + .font(.title3) + .bold() + .allowsTightening(false) .foregroundColor(.secondary) - .padding(.leading, 8) - .padding(.top, 8) - .onTapGesture(perform: enableEditing) - - if editLocalAlias { - let v = TextField("Set contact name…", text: $localAlias) - .font(.title3) - .disableAutocorrection(true) - .focused($aliasTextFieldFocused) - .submitLabel(.done) - .onSubmit(setConnectionAlias) - .foregroundColor(.secondary) - .padding(.trailing, 8) - .onTapGesture {} - .onChange(of: aliasTextFieldFocused) { focussed in - if !focussed { - editLocalAlias = false - } - } - if #available(iOS 16.0, *) { - v.bold() - } else { - v - } - } else { - Text(contactConnection.chatViewName) - .font(.title3) - .bold() - .allowsTightening(false) - .foregroundColor(.secondary) - .padding(.trailing, 8) - .padding(.top, 1) - .padding(.bottom, 0.5) - .frame(alignment: .topLeading) - .onTapGesture(perform: enableEditing) - } + .padding(.horizontal, 8) + .padding(.top, 1) + .padding(.bottom, 0.5) + .frame(alignment: .topLeading) Spacer() @@ -106,40 +67,7 @@ struct ContactConnectionView: View { } .frame(maxHeight: .infinity) .sheet(isPresented: $showContactConnectionInfo) { - if let connReqInv = contactConnection.connReqInv { - ContactConnectionInfo(contactConnection: contactConnection, connReqInvitation: connReqInv) - } - } - } - } - - private func enableEditing() { - editLocalAlias = true - aliasTextFieldFocused = true - localAlias = contactConnection.localAlias - } - - private func setConnectionAlias() { - if localAlias == contactConnection.localAlias { - aliasTextFieldFocused = false - editLocalAlias = false - return - } - Task { - let prevAlias = contactConnection.localAlias - contactConnection.localAlias = localAlias - do { - if let conn = try await apiSetConnectionAlias(connId: contactConnection.pccConnId, localAlias: localAlias) { - await MainActor.run { - contactConnection = conn - ChatModel.shared.updateContactConnection(conn) - aliasTextFieldFocused = false - editLocalAlias = false - } - } - } catch { - logger.error("setContactAlias error: \(responseError(error))") - contactConnection.localAlias = prevAlias + ContactConnectionInfo(contactConnection: contactConnection) } } } @@ -147,7 +75,7 @@ struct ContactConnectionView: View { struct ContactConnectionView_Previews: PreviewProvider { static var previews: some View { - ContactConnectionView(contactConnection: PendingContactConnection.getSampleData()) + ContactConnectionView(chat: Chat(chatInfo: ChatInfo.sampleData.contactConnection)) .previewLayout(.fixed(width: 360, height: 80)) } } diff --git a/apps/ios/Shared/Views/NewChat/AddContactView.swift b/apps/ios/Shared/Views/NewChat/AddContactView.swift index 031e1d9114..d6a1c128a7 100644 --- a/apps/ios/Shared/Views/NewChat/AddContactView.swift +++ b/apps/ios/Shared/Views/NewChat/AddContactView.swift @@ -8,9 +8,11 @@ import SwiftUI import CoreImage.CIFilterBuiltins +import SimpleXChat struct AddContactView: View { @EnvironmentObject private var chatModel: ChatModel + var contactConnection: PendingContactConnection? = nil var connReqInvitation: String var viaSettings = false @@ -23,7 +25,7 @@ struct AddContactView: View { .padding(viaSettings ? .bottom : .vertical) Text("Your contact can scan it from the app.") .padding(.bottom, 4) - if (chatModel.incognito) { + if (contactConnection?.incognito ?? chatModel.incognito) { HStack { Image(systemName: "theatermasks").foregroundColor(.indigo).font(.footnote) Spacer().frame(width: 8) diff --git a/apps/ios/Shared/Views/UserSettings/UserAddress.swift b/apps/ios/Shared/Views/UserSettings/UserAddress.swift index a522553111..89b8a93b01 100644 --- a/apps/ios/Shared/Views/UserSettings/UserAddress.swift +++ b/apps/ios/Shared/Views/UserSettings/UserAddress.swift @@ -61,14 +61,8 @@ struct UserAddress: View { } } catch let error { logger.error("UserAddress apiCreateUserAddress: \(error.localizedDescription)") - switch error as? ChatResponse { - case .chatCmdError(.errorAgent(.BROKER(.TIMEOUT))): - alert = .error(title: "Connection timeout", error: "Please check your network connection and try again.") - case .chatCmdError(.errorAgent(.BROKER(.NETWORK))): - alert = .error(title: "Connection error", error: "Please check your network connection and try again.") - default: - alert = .error(title: "Error creating address", error: "Error: \(responseError(error))") - } + let a = getErrorAlert(error, "Error creating address") + alert = .error(title: a.title, error: "\(a.message)") } } } label: { Label("Create address", systemImage: "qrcode") } 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 32f5766596..608ce90185 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -746,6 +746,11 @@ Chat-Profil löschen? No comment provided by engineer. + + Delete connection + *** Delete connection + No comment provided by engineer. + Delete contact Kontakt löschen @@ -1021,6 +1026,11 @@ Fehler beim Löschen des Chats! No comment provided by engineer. + + Error deleting connection + *** Error deleting connection + No comment provided by engineer. + Error deleting database Fehler beim Löschen der Datenbank @@ -1573,6 +1583,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Stummschalten No comment provided by engineer. + + Name + *** Name + No comment provided by engineer. + Network & servers Netzwerk & Server @@ -1766,7 +1781,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Please check your network connection and try again. Bitte überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut. - alert message + No comment provided by engineer. Please enter correct current passphrase. @@ -2103,6 +2118,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v *** Shared one-time link No comment provided by engineer. + + Show QR code + *** Show QR code + No comment provided by engineer. + Show preview Vorschau anzeigen 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 45d0a0807e..6864c9435f 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -746,6 +746,11 @@ Delete chat profile? No comment provided by engineer. + + Delete connection + Delete connection + No comment provided by engineer. + Delete contact Delete contact @@ -1021,6 +1026,11 @@ Error deleting chat! No comment provided by engineer. + + Error deleting connection + Error deleting connection + No comment provided by engineer. + Error deleting database Error deleting database @@ -1573,6 +1583,11 @@ We will be adding server redundancy to prevent lost messages. Mute No comment provided by engineer. + + Name + Name + No comment provided by engineer. + Network & servers Network & servers @@ -1766,7 +1781,7 @@ We will be adding server redundancy to prevent lost messages. Please check your network connection and try again. Please check your network connection and try again. - alert message + No comment provided by engineer. Please enter correct current passphrase. @@ -2103,6 +2118,11 @@ We will be adding server redundancy to prevent lost messages. Shared one-time link No comment provided by engineer. + + Show QR code + Show QR code + No comment provided by engineer. + Show preview Show preview 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 3dd48e40d1..bb7ab7a06e 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -746,6 +746,11 @@ Удалить профиль? No comment provided by engineer. + + Delete connection + Удалить соединение + No comment provided by engineer. + Delete contact Удалить контакт @@ -1021,6 +1026,11 @@ Ошибка при удалении чата! No comment provided by engineer. + + Error deleting connection + Ошибка при удалении соединения + No comment provided by engineer. + Error deleting database Ошибка при удалении данных чата @@ -1573,6 +1583,11 @@ We will be adding server redundancy to prevent lost messages. Без звука No comment provided by engineer. + + Name + Имя + No comment provided by engineer. + Network & servers Сеть & серверы @@ -1766,7 +1781,7 @@ We will be adding server redundancy to prevent lost messages. Please check your network connection and try again. Пожалуйста, проверьте ваше соединение с сетью и попробуйте еще раз. - alert message + No comment provided by engineer. Please enter correct current passphrase. @@ -2103,6 +2118,11 @@ We will be adding server redundancy to prevent lost messages. Одноразовая ссылка-приглашение No comment provided by engineer. + + Show QR code + Показать QR код + No comment provided by engineer. + Show preview Показывать уведомления diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 011fa6a75c..48175c85ff 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 5C029EAA283942EA004A9677 /* CallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C029EA9283942EA004A9677 /* CallController.swift */; }; 5C05DF532840AA1D00C683F9 /* CallSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C05DF522840AA1D00C683F9 /* CallSettings.swift */; }; 5C063D2727A4564100AEC577 /* ChatPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C063D2627A4564100AEC577 /* ChatPreviewView.swift */; }; + 5C10D88828EED12E00E58BF0 /* ContactConnectionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C10D88728EED12E00E58BF0 /* ContactConnectionInfo.swift */; }; 5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C116CDB27AABE0400E66D01 /* ContactRequestView.swift */; }; 5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C13730A28156D2700F43030 /* ContactConnectionView.swift */; }; 5C1A4C1E27A715B700EAD5AD /* ChatItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1A4C1D27A715B700EAD5AD /* ChatItemView.swift */; }; @@ -90,7 +91,6 @@ 5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403327A5F6DF00368C90 /* AddContactView.swift */; }; 5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; }; 5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD472818589900503DA2 /* NotificationService.swift */; }; - 5CE1331028E7391000FFFD8C /* ContactConnectionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE1330F28E7391000FFFD8C /* ContactConnectionInfo.swift */; }; 5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; }; 5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5CE2BA77284530BF00EC33A6 /* SimpleXChat.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */; }; @@ -208,6 +208,7 @@ 5C029EA9283942EA004A9677 /* CallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallController.swift; sourceTree = ""; }; 5C05DF522840AA1D00C683F9 /* CallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallSettings.swift; sourceTree = ""; }; 5C063D2627A4564100AEC577 /* ChatPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatPreviewView.swift; sourceTree = ""; }; + 5C10D88728EED12E00E58BF0 /* ContactConnectionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactConnectionInfo.swift; sourceTree = ""; }; 5C116CDB27AABE0400E66D01 /* ContactRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactRequestView.swift; sourceTree = ""; }; 5C13730A28156D2700F43030 /* ContactConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactConnectionView.swift; sourceTree = ""; }; 5C13730C2815740A00F43030 /* DebugJSON.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = DebugJSON.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; @@ -300,7 +301,6 @@ 5CDCAD80281A7E2700503DA2 /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; 5CE1330328E118CC00FFFD8C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = "de.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; 5CE1330428E118CC00FFFD8C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; - 5CE1330F28E7391000FFFD8C /* ContactConnectionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactConnectionInfo.swift; sourceTree = ""; }; 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SimpleXChat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleXChat.h; sourceTree = ""; }; 5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SimpleXChat.docc; sourceTree = ""; }; @@ -588,7 +588,7 @@ 5C063D2627A4564100AEC577 /* ChatPreviewView.swift */, 5C116CDB27AABE0400E66D01 /* ContactRequestView.swift */, 5C13730A28156D2700F43030 /* ContactConnectionView.swift */, - 5CE1330F28E7391000FFFD8C /* ContactConnectionInfo.swift */, + 5C10D88728EED12E00E58BF0 /* ContactConnectionInfo.swift */, ); path = ChatList; sourceTree = ""; @@ -891,6 +891,7 @@ 648010AB281ADD15009009B9 /* CIFileView.swift in Sources */, 5C4B3B0A285FB130003915F2 /* DatabaseView.swift in Sources */, 5CB2084F28DA4B4800D024EC /* RTCServers.swift in Sources */, + 5C10D88828EED12E00E58BF0 /* ContactConnectionInfo.swift in Sources */, 3CDBCF4227FAE51000354CDD /* ComposeLinkView.swift in Sources */, 3CDBCF4827FF621E00354CDD /* CILinkView.swift in Sources */, 5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */, @@ -908,7 +909,6 @@ 5CB0BA8E2827126500B3292C /* OnboardingView.swift in Sources */, 6442E0BE2880182D00CEC0F9 /* GroupChatInfoView.swift in Sources */, 5C2E261227A30FEA00F70299 /* TerminalView.swift in Sources */, - 5CE1331028E7391000FFFD8C /* ContactConnectionInfo.swift in Sources */, 5CB2085128DB64CA00D024EC /* CreateLinkView.swift in Sources */, 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */, 64E972072881BB22008DBC02 /* CIGroupInvitationView.swift in Sources */, diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index 5f758adccb..58c4fc6f2f 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -283,12 +283,14 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat { public var direct: ChatInfo public var group: ChatInfo public var contactRequest: ChatInfo + public var contactConnection: ChatInfo } public static var sampleData: ChatInfo.SampleData = SampleData( direct: ChatInfo.direct(contact: Contact.sampleData), group: ChatInfo.group(groupInfo: GroupInfo.sampleData), - contactRequest: ChatInfo.contactRequest(contactRequest: UserContactRequest.sampleData) + contactRequest: ChatInfo.contactRequest(contactRequest: UserContactRequest.sampleData), + contactConnection: ChatInfo.contactConnection(contactConnection: PendingContactConnection.getSampleData()) ) } diff --git a/apps/ios/de.lproj/Localizable.strings b/apps/ios/de.lproj/Localizable.strings index 2d7c2776e5..e7b35f5d99 100644 --- a/apps/ios/de.lproj/Localizable.strings +++ b/apps/ios/de.lproj/Localizable.strings @@ -524,6 +524,9 @@ /* No comment provided by engineer. */ "Delete chat profile?" = "Chat-Profil löschen?"; +/* No comment provided by engineer. */ +"Delete connection" = "*** Delete connection"; + /* No comment provided by engineer. */ "Delete contact" = "Kontakt löschen"; @@ -716,6 +719,9 @@ /* No comment provided by engineer. */ "Error deleting chat!" = "Fehler beim Löschen des Chats!"; +/* No comment provided by engineer. */ +"Error deleting connection" = "*** Error deleting connection"; + /* No comment provided by engineer. */ "Error deleting database" = "Fehler beim Löschen der Datenbank"; @@ -1098,6 +1104,9 @@ /* No comment provided by engineer. */ "Mute" = "Stummschalten"; +/* No comment provided by engineer. */ +"Name" = "*** Name"; + /* No comment provided by engineer. */ "Network & servers" = "Netzwerk & Server"; @@ -1230,7 +1239,7 @@ /* No comment provided by engineer. */ "Please check that you used the correct link or ask your contact to send you another one." = "Überprüfen Sie bitte, ob Sie den richtigen Link genutzt haben oder bitten Sie Ihren Kontakt nochmal darum, Ihnen einen Link zuzusenden."; -/* alert message */ +/* No comment provided by engineer. */ "Please check your network connection and try again." = "Bitte überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut."; /* No comment provided by engineer. */ @@ -1455,6 +1464,9 @@ /* No comment provided by engineer. */ "Show preview" = "Vorschau anzeigen"; +/* No comment provided by engineer. */ +"Show QR code" = "*** Show QR code"; + /* notification */ "SimpleX encrypted message or connection event" = "SimpleX verschlüsselte Nachricht oder Verbindungs-Ereignis"; diff --git a/apps/ios/ru.lproj/Localizable.strings b/apps/ios/ru.lproj/Localizable.strings index 6bae21eea9..cfac100095 100644 --- a/apps/ios/ru.lproj/Localizable.strings +++ b/apps/ios/ru.lproj/Localizable.strings @@ -524,6 +524,9 @@ /* No comment provided by engineer. */ "Delete chat profile?" = "Удалить профиль?"; +/* No comment provided by engineer. */ +"Delete connection" = "Удалить соединение"; + /* No comment provided by engineer. */ "Delete contact" = "Удалить контакт"; @@ -716,6 +719,9 @@ /* No comment provided by engineer. */ "Error deleting chat!" = "Ошибка при удалении чата!"; +/* No comment provided by engineer. */ +"Error deleting connection" = "Ошибка при удалении соединения"; + /* No comment provided by engineer. */ "Error deleting database" = "Ошибка при удалении данных чата"; @@ -1098,6 +1104,9 @@ /* No comment provided by engineer. */ "Mute" = "Без звука"; +/* No comment provided by engineer. */ +"Name" = "Имя"; + /* No comment provided by engineer. */ "Network & servers" = "Сеть & серверы"; @@ -1230,7 +1239,7 @@ /* No comment provided by engineer. */ "Please check that you used the correct link or ask your contact to send you another one." = "Пожалуйста, проверьте, что вы использовали правильную ссылку или попросите, чтобы ваш контакт отправил вам другую ссылку."; -/* alert message */ +/* No comment provided by engineer. */ "Please check your network connection and try again." = "Пожалуйста, проверьте ваше соединение с сетью и попробуйте еще раз."; /* No comment provided by engineer. */ @@ -1455,6 +1464,9 @@ /* No comment provided by engineer. */ "Show preview" = "Показывать уведомления"; +/* No comment provided by engineer. */ +"Show QR code" = "Показать QR код"; + /* notification */ "SimpleX encrypted message or connection event" = "SimpleX: зашифрованное сообщение или соединение контакта";