From a525b4e5dba42a354a8c7d2dccac914ecd09681b Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Sat, 15 Oct 2022 18:09:25 +0400 Subject: [PATCH] ios: group links (#1214) * libraries * api * ui * via nav link * translations * align android translations --- .../app/src/main/res/values-de/strings.xml | 4 +- .../app/src/main/res/values/strings.xml | 4 +- apps/ios/Shared/Model/SimpleXAPI.swift | 23 ++++ .../Views/Chat/Group/GroupChatInfoView.swift | 20 +++- .../Views/Chat/Group/GroupLinkView.swift | 109 ++++++++++++++++++ .../Views/UserSettings/UserAddress.swift | 4 +- .../de.xcloc/Localized Contents/de.xliff | 55 +++++---- .../en.xcloc/Localized Contents/en.xliff | 55 +++++---- .../ru.xcloc/Localized Contents/ru.xliff | 55 +++++---- apps/ios/SimpleX.xcodeproj/project.pbxproj | 44 +++---- apps/ios/SimpleXChat/APITypes.swift | 20 ++++ apps/ios/de.lproj/Localizable.strings | 27 ++++- apps/ios/ru.lproj/Localizable.strings | 33 ++++-- 13 files changed, 348 insertions(+), 105 deletions(-) create mode 100644 apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift diff --git a/apps/android/app/src/main/res/values-de/strings.xml b/apps/android/app/src/main/res/values-de/strings.xml index 85ca6b7ce4..1ea4dc4da8 100644 --- a/apps/android/app/src/main/res/values-de/strings.xml +++ b/apps/android/app/src/main/res/values-de/strings.xml @@ -768,8 +768,8 @@ ***If you later delete it - you won\'t lose members of the group connected via the link. ***If you delete it - you won\'t lose members of the group connected via this link. ***All group members will remain connected. - ***Error creating a group link - ***Error deleting the group link + ***Error creating group link + ***Error deleting group link FÜR KONSOLE diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml index 08479dd430..d7db67af3e 100644 --- a/apps/android/app/src/main/res/values/strings.xml +++ b/apps/android/app/src/main/res/values/strings.xml @@ -768,8 +768,8 @@ If you later delete it - you won\'t lose members of the group connected via the link. If you delete it - you won\'t lose members of the group connected via this link. All group members will remain connected. - Error creating a group link - Error deleting the group link + Error creating group link + Error deleting group link FOR CONSOLE diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 768be40c98..b6f607fc4b 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -743,6 +743,29 @@ func apiUpdateGroup(_ groupId: Int64, _ groupProfile: GroupProfile) async throws throw r } +func apiCreateGroupLink(_ groupId: Int64) async throws -> String { + let r = await chatSendCmd(.apiCreateGroupLink(groupId: groupId)) + if case let .groupLinkCreated(_, connReq) = r { return connReq } + throw r +} + +func apiDeleteGroupLink(_ groupId: Int64) async throws { + let r = await chatSendCmd(.apiDeleteGroupLink(groupId: groupId)) + if case .groupLinkDeleted = r { return } + throw r +} + +func apiGetGroupLink(_ groupId: Int64) throws -> String? { + let r = chatSendCmdSync(.apiGetGroupLink(groupId: groupId)) + switch r { + case let .groupLink(_, connReq): + return connReq + case .chatCmdError(chatError: .errorStore(storeError: .groupLinkNotFound)): + return nil + default: throw r + } +} + func initializeChat(start: Bool, dbKey: String? = nil) throws { logger.debug("initializeChat") let m = ChatModel.shared diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index bbe54f5961..687357f030 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -16,6 +16,7 @@ struct GroupChatInfoView: View { var groupInfo: GroupInfo @ObservedObject private var alertManager = AlertManager.shared @State private var alert: GroupChatInfoViewAlert? = nil + @State private var groupLink: String? @State private var showAddMembersSheet: Bool = false @State private var selectedMember: GroupMember? = nil @State private var showGroupProfile: Bool = false @@ -43,6 +44,7 @@ struct GroupChatInfoView: View { Section("\(members.count + 1) members") { if groupInfo.canAddMembers { + groupLinkButton() if (chat.chatInfo.incognito) { Label("Invite members", systemImage: "plus") .foregroundColor(Color(uiColor: .tertiaryLabel)) @@ -105,7 +107,13 @@ struct GroupChatInfoView: View { case .clearChatAlert: return clearChatAlert() case .leaveGroupAlert: return leaveGroupAlert() case .cantInviteIncognitoAlert: return cantInviteIncognitoAlert() - + } + } + .onAppear { + do { + groupLink = try apiGetGroupLink(groupInfo.groupId) + } catch let error { + logger.error("GroupChatInfoView apiGetGroupLink: \(responseError(error))") } } } @@ -175,6 +183,16 @@ struct GroupChatInfoView: View { } } + private func groupLinkButton() -> some View { + NavigationLink { + GroupLinkView(groupId: groupInfo.groupId, groupLink: $groupLink) + .navigationBarTitleDisplayMode(.inline) + } label: { + Label("Group link", systemImage: "link") + .foregroundColor(.accentColor) + } + } + func editGroupButton() -> some View { Button { showGroupProfile = true diff --git a/apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift b/apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift new file mode 100644 index 0000000000..5e4b5bee78 --- /dev/null +++ b/apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift @@ -0,0 +1,109 @@ +// +// GroupLinkView.swift +// SimpleX (iOS) +// +// Created by JRoberts on 15.10.2022. +// Copyright © 2022 SimpleX Chat. All rights reserved. +// + +import SwiftUI +import SimpleXChat + +struct GroupLinkView: View { + var groupId: Int64 + @Binding var groupLink: String? + @State private var alert: GroupLinkAlert? + + private enum GroupLinkAlert: Identifiable { + case deleteLink + case error(title: LocalizedStringKey, error: String = "") + + var id: String { + switch self { + case .deleteLink: return "deleteLink" + case let .error(title, _): return "error \(title)" + } + } + } + + var body: some View { + ScrollView { + VStack (alignment: .leading) { + Text("Group link") + .font(.largeTitle) + .bold() + .padding(.bottom) + Text("You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it.") + .padding(.bottom) + if let groupLink = groupLink { + QRCode(uri: groupLink) + HStack { + Button { + showShareSheet(items: [groupLink]) + } label: { + Label("Share link", systemImage: "square.and.arrow.up") + } + .padding() + + Button(role: .destructive) { alert = .deleteLink } label: { + Label("Delete link", systemImage: "trash") + } + .padding() + } + .frame(maxWidth: .infinity) + } else { + Button { + Task { + do { + groupLink = try await apiCreateGroupLink(groupId) + } catch let error { + logger.error("GroupLinkView apiCreateGroupLink: \(responseError(error))") + let a = getErrorAlert(error, "Error creating group link") + alert = .error(title: a.title, error: "\(a.message)") + } + } + } label: { Label("Create link", systemImage: "link.badge.plus") } + .frame(maxWidth: .infinity) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .alert(item: $alert) { alert in + switch alert { + case .deleteLink: + return Alert( + title: Text("Delete link?"), + message: Text("All group members will remain connected."), + primaryButton: .destructive(Text("Delete")) { + Task { + do { + try await apiDeleteGroupLink(groupId) + await MainActor.run { + groupLink = nil + } + } catch let error { + logger.error("GroupLinkView apiDeleteGroupLink: \(responseError(error))") + } + } + }, secondaryButton: .cancel() + ) + case let .error(title, error): + return Alert(title: Text(title), message: Text("\(error)")) + } + } + } + } +} + +struct GroupLinkView_Previews: PreviewProvider { + static var previews: some View { + @State var groupLink: String? = "https://simplex.chat/contact#/?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23MCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%3D" + @State var noGroupLink: String? = nil + + return Group { + GroupLinkView(groupId: 1, groupLink: $groupLink) + GroupLinkView(groupId: 1, groupLink: $noGroupLink) + } + } +} + diff --git a/apps/ios/Shared/Views/UserSettings/UserAddress.swift b/apps/ios/Shared/Views/UserSettings/UserAddress.swift index 21fc893d40..647f421bc7 100644 --- a/apps/ios/Shared/Views/UserSettings/UserAddress.swift +++ b/apps/ios/Shared/Views/UserSettings/UserAddress.swift @@ -60,7 +60,7 @@ struct UserAddress: View { chatModel.userAddress = userAddress } } catch let error { - logger.error("UserAddress apiCreateUserAddress: \(error.localizedDescription)") + logger.error("UserAddress apiCreateUserAddress: \(responseError(error))") let a = getErrorAlert(error, "Error creating address") alert = .error(title: a.title, error: "\(a.message)") } @@ -85,7 +85,7 @@ struct UserAddress: View { chatModel.userAddress = nil } } catch let error { - logger.error("UserAddress apiDeleteUserAddress: \(error.localizedDescription)") + logger.error("UserAddress apiDeleteUserAddress: \(responseError(error))") } } }, secondaryButton: .cancel() 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 86e8d3bb7d..a2fd55db93 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -258,6 +258,11 @@ Erweiterte Netzwerkeinstellungen No comment provided by engineer. + + All group members will remain connected. + ***All group members will remain connected. + No comment provided by engineer. + All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. Alle Nachrichten werden gelöscht - dies kann nicht rückgängig gemacht werden! Die Nachrichten werden NUR bei Ihnen gelöscht. @@ -368,11 +373,6 @@ Die Mitgliederrolle ändern? No comment provided by engineer. - - Change role - Rolle ändern - No comment provided by engineer. - Chat archive Datenbank Archiv @@ -588,6 +588,11 @@ Adresse erstellen No comment provided by engineer. + + Create link + ***Create link + No comment provided by engineer. + Create one-time invitation link Erstellen Sie einen einmaligen Einladungslink @@ -801,6 +806,16 @@ Einladung löschen No comment provided by engineer. + + Delete link + ***Delete link + No comment provided by engineer. + + + Delete link? + ***Delete link? + No comment provided by engineer. + Delete message? Die Nachricht löschen? @@ -1016,6 +1031,11 @@ Fehler beim Erzeugen der Gruppe No comment provided by engineer. + + Error creating group link + ***Error creating group link + No comment provided by engineer. + Error deleting chat database Fehler beim Löschen der Chat-Datenbank @@ -1166,11 +1186,6 @@ Datei: %@ No comment provided by engineer. - - Files - Dateien - No comment provided by engineer. - For console Für Konsole @@ -1221,6 +1236,11 @@ Die Gruppeneinladung ist nicht mehr gültig, sie wurde vom Absender entfernt. No comment provided by engineer. + + Group link + ***Group link + No comment provided by engineer. + Group message: Grppennachricht: @@ -1958,11 +1978,6 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Zurückkehren No comment provided by engineer. - - Role - Rolle - No comment provided by engineer. - Run chat Chat starten @@ -2113,11 +2128,6 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Einmal-Einladungslink teilen No comment provided by engineer. - - Shared one-time link - Geteilter Einmal-Link - No comment provided by engineer. - Show QR code QR-Code anzeigen @@ -2577,6 +2587,11 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s Über die Geräte-Einstellungen können Sie die Benachrichtigungsvorschau im Sperrbildschirm erlauben. No comment provided by engineer. + + You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + ***You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + No comment provided by engineer. + You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it. Sie können Ihre Adresse als Link oder als QR-Code teilen – Jeder kann sich darüber mit Ihnen verbinden. Sie werden Ihre mit dieser Adresse verbundenen Kontakte nicht verlieren, wenn Sie diese Adresse später löschen. 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 703250df87..171468155f 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -258,6 +258,11 @@ Advanced network settings No comment provided by engineer. + + All group members will remain connected. + All group members will remain connected. + No comment provided by engineer. + All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. @@ -368,11 +373,6 @@ Change member role? No comment provided by engineer. - - Change role - Change role - No comment provided by engineer. - Chat archive Chat archive @@ -588,6 +588,11 @@ Create address No comment provided by engineer. + + Create link + Create link + No comment provided by engineer. + Create one-time invitation link Create one-time invitation link @@ -801,6 +806,16 @@ Delete invitation No comment provided by engineer. + + Delete link + Delete link + No comment provided by engineer. + + + Delete link? + Delete link? + No comment provided by engineer. + Delete message? Delete message? @@ -1016,6 +1031,11 @@ Error creating group No comment provided by engineer. + + Error creating group link + Error creating group link + No comment provided by engineer. + Error deleting chat database Error deleting chat database @@ -1166,11 +1186,6 @@ File: %@ No comment provided by engineer. - - Files - Files - No comment provided by engineer. - For console For console @@ -1221,6 +1236,11 @@ Group invitation is no longer valid, it was removed by sender. No comment provided by engineer. + + Group link + Group link + No comment provided by engineer. + Group message: Group message: @@ -1958,11 +1978,6 @@ We will be adding server redundancy to prevent lost messages. Revert No comment provided by engineer. - - Role - Role - No comment provided by engineer. - Run chat Run chat @@ -2113,11 +2128,6 @@ We will be adding server redundancy to prevent lost messages. Share one-time invitation link No comment provided by engineer. - - Shared one-time link - Shared one-time link - No comment provided by engineer. - Show QR code Show QR code @@ -2577,6 +2587,11 @@ To connect, please ask your contact to create another connection link and check You can set lock screen notification preview via settings. No comment provided by engineer. + + You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + No comment provided by engineer. + You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it. You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it. 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 7d9faae75a..93a31426f3 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -258,6 +258,11 @@ Настройки сети No comment provided by engineer. + + All group members will remain connected. + Все члены группы, которые соединились через эту ссылку, останутся в группе. + No comment provided by engineer. + All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you. Все сообщения будут удалены - это действие нельзя отменить! Сообщения будут удалены только для вас. @@ -368,11 +373,6 @@ Поменять роль члена группы? No comment provided by engineer. - - Change role - Поменять роль - No comment provided by engineer. - Chat archive Архив чата @@ -588,6 +588,11 @@ Создать адрес No comment provided by engineer. + + Create link + Создать ссылку + No comment provided by engineer. + Create one-time invitation link Создать ссылку-приглашение @@ -801,6 +806,16 @@ Удалить приглашение No comment provided by engineer. + + Delete link + Удалить ссылку + No comment provided by engineer. + + + Delete link? + Удалить ссылку? + No comment provided by engineer. + Delete message? Удалить сообщение? @@ -1016,6 +1031,11 @@ Ошибка при создании группы No comment provided by engineer. + + Error creating group link + Ошибка при создании ссылки группы + No comment provided by engineer. + Error deleting chat database Ошибка при удалении данных чата @@ -1166,11 +1186,6 @@ Файл: %@ No comment provided by engineer. - - Files - Файлы - No comment provided by engineer. - For console Для консоли @@ -1221,6 +1236,11 @@ Приглашение в группу больше не действительно, оно было удалено отправителем. No comment provided by engineer. + + Group link + Ссылка группы + No comment provided by engineer. + Group message: Групповое сообщение: @@ -1958,11 +1978,6 @@ We will be adding server redundancy to prevent lost messages. Отменить изменения No comment provided by engineer. - - Role - Роль - No comment provided by engineer. - Run chat Запустить chat @@ -2113,11 +2128,6 @@ We will be adding server redundancy to prevent lost messages. Поделиться ссылкой-приглашением No comment provided by engineer. - - Shared one-time link - Одноразовая ссылка-приглашение - No comment provided by engineer. - Show QR code Показать QR код @@ -2577,6 +2587,11 @@ To connect, please ask your contact to create another connection link and check Вы можете установить просмотр уведомлений на экране блокировки в настройках. No comment provided by engineer. + + You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it. + Вы можете поделиться ссылкой или QR кодом - через них можно присоединиться к группе. Вы сможете удалить ссылку, сохранив членов группы, которые через нее соединились. + No comment provided by engineer. + You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it. Вы можете использовать ваш адрес как ссылку или как QR код - кто угодно сможет соединиться с вами. Вы сможете удалить адрес, сохранив контакты, которые через него соединились. diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index dda996b937..d785211fa8 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -123,11 +123,12 @@ 6440CA03288AECA70062C672 /* AddGroupMembersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440CA02288AECA70062C672 /* AddGroupMembersView.swift */; }; 6442E0BA287F169300CEC0F9 /* AddGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6442E0B9287F169300CEC0F9 /* AddGroupView.swift */; }; 6442E0BE2880182D00CEC0F9 /* GroupChatInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6442E0BD2880182D00CEC0F9 /* GroupChatInfoView.swift */; }; - 6448BBA628EAF728000D2AB9 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBA128EAF728000D2AB9 /* libffi.a */; }; - 6448BBA728EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBA228EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI-ghc8.10.7.a */; }; - 6448BBA828EAF728000D2AB9 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBA328EAF728000D2AB9 /* libgmpxx.a */; }; - 6448BBA928EAF728000D2AB9 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBA428EAF728000D2AB9 /* libgmp.a */; }; - 6448BBAA28EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBA528EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI.a */; }; + 6448BBB028F9C5FF000D2AB9 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBAB28F9C5FF000D2AB9 /* libffi.a */; }; + 6448BBB128F9C5FF000D2AB9 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBAC28F9C5FF000D2AB9 /* libgmp.a */; }; + 6448BBB228F9C5FF000D2AB9 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBAD28F9C5FF000D2AB9 /* libgmpxx.a */; }; + 6448BBB328F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBAE28F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC-ghc8.10.7.a */; }; + 6448BBB428F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6448BBAF28F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC.a */; }; + 6448BBB628FA9D56000D2AB9 /* GroupLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6448BBB528FA9D56000D2AB9 /* GroupLinkView.swift */; }; 6454036F2822A9750090DDFF /* ComposeFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6454036E2822A9750090DDFF /* ComposeFileView.swift */; }; 646BB38C283BEEB9001CE359 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 646BB38B283BEEB9001CE359 /* LocalAuthentication.framework */; }; 646BB38E283FDB6D001CE359 /* LocalAuthenticationUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646BB38D283FDB6D001CE359 /* LocalAuthenticationUtils.swift */; }; @@ -320,11 +321,12 @@ 6440CA02288AECA70062C672 /* AddGroupMembersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupMembersView.swift; sourceTree = ""; }; 6442E0B9287F169300CEC0F9 /* AddGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupView.swift; sourceTree = ""; }; 6442E0BD2880182D00CEC0F9 /* GroupChatInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatInfoView.swift; sourceTree = ""; }; - 6448BBA128EAF728000D2AB9 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; - 6448BBA228EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI-ghc8.10.7.a"; sourceTree = ""; }; - 6448BBA328EAF728000D2AB9 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - 6448BBA428EAF728000D2AB9 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - 6448BBA528EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI.a"; sourceTree = ""; }; + 6448BBAB28F9C5FF000D2AB9 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 6448BBAC28F9C5FF000D2AB9 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + 6448BBAD28F9C5FF000D2AB9 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 6448BBAE28F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC-ghc8.10.7.a"; sourceTree = ""; }; + 6448BBAF28F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC.a"; sourceTree = ""; }; + 6448BBB528FA9D56000D2AB9 /* GroupLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupLinkView.swift; sourceTree = ""; }; 6454036E2822A9750090DDFF /* ComposeFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeFileView.swift; sourceTree = ""; }; 646BB38B283BEEB9001CE359 /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.4.sdk/System/Library/Frameworks/LocalAuthentication.framework; sourceTree = DEVELOPER_DIR; }; 646BB38D283FDB6D001CE359 /* LocalAuthenticationUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAuthenticationUtils.swift; sourceTree = ""; }; @@ -370,12 +372,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6448BBAA28EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, - 6448BBA828EAF728000D2AB9 /* libgmpxx.a in Frameworks */, - 6448BBA728EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI-ghc8.10.7.a in Frameworks */, - 6448BBA628EAF728000D2AB9 /* libffi.a in Frameworks */, - 6448BBA928EAF728000D2AB9 /* libgmp.a in Frameworks */, + 6448BBB428F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC.a in Frameworks */, + 6448BBB228F9C5FF000D2AB9 /* libgmpxx.a in Frameworks */, + 6448BBB028F9C5FF000D2AB9 /* libffi.a in Frameworks */, + 6448BBB328F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC-ghc8.10.7.a in Frameworks */, + 6448BBB128F9C5FF000D2AB9 /* libgmp.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -431,11 +433,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 6448BBA128EAF728000D2AB9 /* libffi.a */, - 6448BBA428EAF728000D2AB9 /* libgmp.a */, - 6448BBA328EAF728000D2AB9 /* libgmpxx.a */, - 6448BBA228EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI-ghc8.10.7.a */, - 6448BBA528EAF728000D2AB9 /* libHSsimplex-chat-4.0.1-FvHSNBJjHeqKQoixUekUiI.a */, + 6448BBAB28F9C5FF000D2AB9 /* libffi.a */, + 6448BBAC28F9C5FF000D2AB9 /* libgmp.a */, + 6448BBAD28F9C5FF000D2AB9 /* libgmpxx.a */, + 6448BBAE28F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC-ghc8.10.7.a */, + 6448BBAF28F9C5FF000D2AB9 /* libHSsimplex-chat-4.1.0-KX468bxbJE45DCoSvMEVhC.a */, ); path = Libraries; sourceTree = ""; @@ -679,6 +681,7 @@ 6442E0BD2880182D00CEC0F9 /* GroupChatInfoView.swift */, 647F090D288EA27B00644C40 /* GroupMemberInfoView.swift */, 5C9C2DA42894777E00CC63B1 /* GroupProfileView.swift */, + 6448BBB528FA9D56000D2AB9 /* GroupLinkView.swift */, ); path = Group; sourceTree = ""; @@ -943,6 +946,7 @@ 5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */, 5C577F7D27C83AA10006112D /* MarkdownHelp.swift in Sources */, 5CA059EB279559F40002BEB4 /* SimpleXApp.swift in Sources */, + 6448BBB628FA9D56000D2AB9 /* GroupLinkView.swift in Sources */, 5CB346E92869E8BA001FD2EF /* PushEnvironment.swift in Sources */, 5C55A91F283AD0E400C4E99E /* CallManager.swift in Sources */, 5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */, diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index a88ef3c19a..2d24367aa5 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -43,6 +43,9 @@ public enum ChatCommand { case apiLeaveGroup(groupId: Int64) case apiListMembers(groupId: Int64) case apiUpdateGroupProfile(groupId: Int64, groupProfile: GroupProfile) + case apiCreateGroupLink(groupId: Int64) + case apiDeleteGroupLink(groupId: Int64) + case apiGetGroupLink(groupId: Int64) case getUserSMPServers case setUserSMPServers(smpServers: [String]) case apiSetChatItemTTL(seconds: Int64?) @@ -114,6 +117,9 @@ public enum ChatCommand { case let .apiLeaveGroup(groupId): return "/_leave #\(groupId)" case let .apiListMembers(groupId): return "/_members #\(groupId)" case let .apiUpdateGroupProfile(groupId, groupProfile): return "/_group_profile #\(groupId) \(encodeJSON(groupProfile))" + case let .apiCreateGroupLink(groupId): return "/_create link #\(groupId)" + case let .apiDeleteGroupLink(groupId): return "/_delete link #\(groupId)" + case let .apiGetGroupLink(groupId): return "/_get link #\(groupId)" case .getUserSMPServers: return "/smp_servers" case let .setUserSMPServers(smpServers): return "/smp_servers \(smpServersStr(smpServers: smpServers))" case let .apiSetChatItemTTL(seconds): return "/_ttl \(chatItemTTLStr(seconds: seconds))" @@ -184,6 +190,9 @@ public enum ChatCommand { case .apiLeaveGroup: return "apiLeaveGroup" case .apiListMembers: return "apiListMembers" case .apiUpdateGroupProfile: return "apiUpdateGroupProfile" + case .apiCreateGroupLink: return "apiCreateGroupLink" + case .apiDeleteGroupLink: return "apiDeleteGroupLink" + case .apiGetGroupLink: return "apiGetGroupLink" case .getUserSMPServers: return "getUserSMPServers" case .setUserSMPServers: return "setUserSMPServers" case .apiSetChatItemTTL: return "apiSetChatItemTTL" @@ -327,6 +336,9 @@ public enum ChatResponse: Decodable, Error { case connectedToGroupMember(groupInfo: GroupInfo, member: GroupMember) case groupRemoved(groupInfo: GroupInfo) // unused case groupUpdated(toGroup: GroupInfo) + case groupLinkCreated(groupInfo: GroupInfo, connReqContact: String) + case groupLink(groupInfo: GroupInfo, connReqContact: String) + case groupLinkDeleted(groupInfo: GroupInfo) // receiving file events case rcvFileAccepted(chatItem: AChatItem) case rcvFileAcceptedSndCancelled(rcvFileTransfer: RcvFileTransfer) @@ -423,6 +435,9 @@ public enum ChatResponse: Decodable, Error { case .connectedToGroupMember: return "connectedToGroupMember" case .groupRemoved: return "groupRemoved" case .groupUpdated: return "groupUpdated" + case .groupLinkCreated: return "groupLinkCreated" + case .groupLink: return "groupLink" + case .groupLinkDeleted: return "groupLinkDeleted" case .rcvFileAccepted: return "rcvFileAccepted" case .rcvFileAcceptedSndCancelled: return "rcvFileAcceptedSndCancelled" case .rcvFileStart: return "rcvFileStart" @@ -520,6 +535,9 @@ public enum ChatResponse: Decodable, Error { case let .connectedToGroupMember(groupInfo, member): return "groupInfo: \(groupInfo)\nmember: \(member)" case let .groupRemoved(groupInfo): return String(describing: groupInfo) case let .groupUpdated(toGroup): return String(describing: toGroup) + case let .groupLinkCreated(groupInfo, connReqContact): return "groupInfo: \(groupInfo)\nconnReqContact: \(connReqContact)" + case let .groupLink(groupInfo, connReqContact): return "groupInfo: \(groupInfo)\nconnReqContact: \(connReqContact)" + case let .groupLinkDeleted(groupInfo): return String(describing: groupInfo) case let .rcvFileAccepted(chatItem): return String(describing: chatItem) case .rcvFileAcceptedSndCancelled: return noDetails case let .rcvFileStart(chatItem): return String(describing: chatItem) @@ -841,6 +859,8 @@ public enum StoreError: Decodable { case quotedChatItemNotFound case chatItemSharedMsgIdNotFound(sharedMsgId: String) case chatItemNotFoundByFileId(fileId: Int64) + case duplicateGroupLink(groupInfo: GroupInfo) + case groupLinkNotFound(groupInfo: GroupInfo) } public enum DatabaseError: Decodable { diff --git a/apps/ios/de.lproj/Localizable.strings b/apps/ios/de.lproj/Localizable.strings index 8a4adc36ef..4a62cf8d08 100644 --- a/apps/ios/de.lproj/Localizable.strings +++ b/apps/ios/de.lproj/Localizable.strings @@ -170,6 +170,9 @@ /* No comment provided by engineer. */ "Advanced network settings" = "Erweiterte Netzwerkeinstellungen"; +/* No comment provided by engineer. */ +"All group members will remain connected." = "***All group members will remain connected."; + /* No comment provided by engineer. */ "All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Alle Nachrichten werden gelöscht - dies kann nicht rückgängig gemacht werden! Die Nachrichten werden NUR bei Ihnen gelöscht."; @@ -431,6 +434,9 @@ /* No comment provided by engineer. */ "Create address" = "Adresse erstellen"; +/* No comment provided by engineer. */ +"Create link" = "***Create link"; + /* No comment provided by engineer. */ "Create one-time invitation link" = "Erstellen Sie einen einmaligen Einladungslink"; @@ -557,6 +563,12 @@ /* No comment provided by engineer. */ "Delete invitation" = "Einladung löschen"; +/* No comment provided by engineer. */ +"Delete link" = "***Delete link"; + +/* No comment provided by engineer. */ +"Delete link?" = "***Delete link?"; + /* No comment provided by engineer. */ "Delete message?" = "Die Nachricht löschen?"; @@ -710,6 +722,9 @@ /* No comment provided by engineer. */ "Error creating group" = "Fehler beim Erzeugen der Gruppe"; +/* No comment provided by engineer. */ +"Error creating group link" = "***Error creating group link"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Fehler beim Löschen der Chat-Datenbank"; @@ -800,9 +815,6 @@ /* No comment provided by engineer. */ "File: %@" = "Datei: %@"; -/* No comment provided by engineer. */ -"Files" = "Dateien"; - /* No comment provided by engineer. */ "For console" = "Für Konsole"; @@ -836,6 +848,9 @@ /* No comment provided by engineer. */ "Group invitation is no longer valid, it was removed by sender." = "Die Gruppeneinladung ist nicht mehr gültig, sie wurde vom Absender entfernt."; +/* No comment provided by engineer. */ +"Group link" = "***Group link"; + /* notification */ "Group message:" = "Grppennachricht:"; @@ -1452,9 +1467,6 @@ /* No comment provided by engineer. */ "Share one-time invitation link" = "Einmal-Einladungslink teilen"; -/* No comment provided by engineer. */ -"Shared one-time link" = "Geteilter Einmal-Link"; - /* No comment provided by engineer. */ "Show preview" = "Vorschau anzeigen"; @@ -1776,6 +1788,9 @@ /* No comment provided by engineer. */ "You can set lock screen notification preview via settings." = "Über die Geräte-Einstellungen können Sie die Benachrichtigungsvorschau im Sperrbildschirm erlauben."; +/* No comment provided by engineer. */ +"You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it." = "***You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it."; + /* No comment provided by engineer. */ "You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it." = "Sie können Ihre Adresse als Link oder als QR-Code teilen – Jeder kann sich darüber mit Ihnen verbinden. Sie werden Ihre mit dieser Adresse verbundenen Kontakte nicht verlieren, wenn Sie diese Adresse später löschen."; diff --git a/apps/ios/ru.lproj/Localizable.strings b/apps/ios/ru.lproj/Localizable.strings index b913ecdfa3..9dae0cfaf2 100644 --- a/apps/ios/ru.lproj/Localizable.strings +++ b/apps/ios/ru.lproj/Localizable.strings @@ -170,6 +170,9 @@ /* No comment provided by engineer. */ "Advanced network settings" = "Настройки сети"; +/* No comment provided by engineer. */ +"All group members will remain connected." = "Все члены группы, которые соединились через эту ссылку, останутся в группе."; + /* No comment provided by engineer. */ "All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Все сообщения будут удалены - это действие нельзя отменить! Сообщения будут удалены только для вас."; @@ -257,9 +260,6 @@ /* No comment provided by engineer. */ "Change member role?" = "Поменять роль члена группы?"; -/* No comment provided by engineer. */ -"Change role" = "Поменять роль"; - /* No comment provided by engineer. */ "Chat archive" = "Архив чата"; @@ -434,6 +434,9 @@ /* No comment provided by engineer. */ "Create address" = "Создать адрес"; +/* No comment provided by engineer. */ +"Create link" = "Создать ссылку"; + /* No comment provided by engineer. */ "Create one-time invitation link" = "Создать ссылку-приглашение"; @@ -560,6 +563,12 @@ /* No comment provided by engineer. */ "Delete invitation" = "Удалить приглашение"; +/* No comment provided by engineer. */ +"Delete link" = "Удалить ссылку"; + +/* No comment provided by engineer. */ +"Delete link?" = "Удалить ссылку?"; + /* No comment provided by engineer. */ "Delete message?" = "Удалить сообщение?"; @@ -713,6 +722,9 @@ /* No comment provided by engineer. */ "Error creating group" = "Ошибка при создании группы"; +/* No comment provided by engineer. */ +"Error creating group link" = "Ошибка при создании ссылки группы"; + /* No comment provided by engineer. */ "Error deleting chat database" = "Ошибка при удалении данных чата"; @@ -803,9 +815,6 @@ /* No comment provided by engineer. */ "File: %@" = "Файл: %@"; -/* No comment provided by engineer. */ -"Files" = "Файлы"; - /* No comment provided by engineer. */ "For console" = "Для консоли"; @@ -839,6 +848,9 @@ /* No comment provided by engineer. */ "Group invitation is no longer valid, it was removed by sender." = "Приглашение в группу больше не действительно, оно было удалено отправителем."; +/* No comment provided by engineer. */ +"Group link" = "Ссылка группы"; + /* notification */ "Group message:" = "Групповое сообщение:"; @@ -1365,9 +1377,6 @@ /* No comment provided by engineer. */ "Revert" = "Отменить изменения"; -/* No comment provided by engineer. */ -"Role" = "Роль"; - /* No comment provided by engineer. */ "Run chat" = "Запустить chat"; @@ -1458,9 +1467,6 @@ /* No comment provided by engineer. */ "Share one-time invitation link" = "Поделиться ссылкой-приглашением"; -/* No comment provided by engineer. */ -"Shared one-time link" = "Одноразовая ссылка-приглашение"; - /* No comment provided by engineer. */ "Show preview" = "Показывать уведомления"; @@ -1782,6 +1788,9 @@ /* No comment provided by engineer. */ "You can set lock screen notification preview via settings." = "Вы можете установить просмотр уведомлений на экране блокировки в настройках."; +/* No comment provided by engineer. */ +"You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it." = "Вы можете поделиться ссылкой или QR кодом - через них можно присоединиться к группе. Вы сможете удалить ссылку, сохранив членов группы, которые через нее соединились."; + /* No comment provided by engineer. */ "You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it." = "Вы можете использовать ваш адрес как ссылку или как QR код - кто угодно сможет соединиться с вами. Вы сможете удалить адрес, сохранив контакты, которые через него соединились.";