dignifiedquire 3 лет назад
Родитель
Сommit
c1226dbc3f

+ 8 - 0
DcCore/DcCore.xcodeproj/project.pbxproj

@@ -30,6 +30,8 @@
 		30E8F2482449C98600CE2C90 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E8F2472449C98600CE2C90 /* UIView+Extensions.swift */; };
 		30E8F24B2449CF6500CE2C90 /* InitialsBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E8F24A2449CF6500CE2C90 /* InitialsBadge.swift */; };
 		30E8F24D2449D30200CE2C90 /* DcColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E8F24C2449D30200CE2C90 /* DcColors.swift */; };
+		78A8733F287766FA00690A0B /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 78A8733E287766FA00690A0B /* libc++.tbd */; };
+		78A873412877679B00690A0B /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78A873402877679B00690A0B /* SystemConfiguration.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -69,6 +71,8 @@
 		30E8F2472449C98600CE2C90 /* UIView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = "<group>"; };
 		30E8F24A2449CF6500CE2C90 /* InitialsBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialsBadge.swift; sourceTree = "<group>"; };
 		30E8F24C2449D30200CE2C90 /* DcColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DcColors.swift; sourceTree = "<group>"; };
+		78A8733E287766FA00690A0B /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/lib/libc++.tbd"; sourceTree = DEVELOPER_DIR; };
+		78A873402877679B00690A0B /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -76,6 +80,8 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				78A873412877679B00690A0B /* SystemConfiguration.framework in Frameworks */,
+				78A8733F287766FA00690A0B /* libc++.tbd in Frameworks */,
 				30421959243DE6AD00516852 /* libdeltachat.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -149,6 +155,8 @@
 		30421957243DE61400516852 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				78A873402877679B00690A0B /* SystemConfiguration.framework */,
+				78A8733E287766FA00690A0B /* libc++.tbd */,
 				30421958243DE61400516852 /* libdeltachat.a */,
 			);
 			name = Frameworks;

+ 26 - 0
DcCore/DcCore/DC/Wrapper.swift

@@ -550,6 +550,11 @@ public class DcContext {
     public func imex(what: Int32, directory: String, passphrase: String? = nil) {
         dc_imex(contextPointer, what, directory, passphrase)
     }
+  
+    public func send_backup(directory: String, passphrase: String? = nil) -> DcBackupSender? {
+      guard let dcBackupSenderPointer = dc_send_backup(contextPointer, directory, passphrase) else { return nil }
+      return DcBackupSender(dcBackupSenderPointer)
+    }
 
     public func imexHasBackup(filePath: String) -> String? {
         var file: String?
@@ -1391,6 +1396,27 @@ public class DcLot {
     }
 }
 
+public class DcBackupSender {
+  private var dcBackupSenderPointer: OpaquePointer?
+  
+  // takes ownership of specified pointer
+  public init(_ dcBackupSenderPointer: OpaquePointer) {
+      self.dcBackupSenderPointer = dcBackupSenderPointer
+  }
+
+  deinit {
+      dc_backup_sender_unref(dcBackupSenderPointer)
+  }
+  
+  public func qr_code(context: DcContext) -> String? {
+    guard let cString = dc_backup_sender_qr(context.contextPointer, dcBackupSenderPointer) else { return nil }
+    let swiftString = String(cString: cString)
+    dc_str_unref(cString)
+    return swiftString
+    
+  }
+}
+
 public class DcProvider {
     private var dcProviderPointer: OpaquePointer?
 

+ 1 - 0
DcCore/DcCore/DC/wrapper.h

@@ -12,5 +12,6 @@ typedef dc_msg_t dc_msg_t;
 typedef dc_lot_t dc_lot_t;
 typedef dc_array_t dc_array_t;
 typedef dc_chatlist_t dc_chatlist_t;
+typedef dc_backup_sender_t dc_backup_sender_t;
 
 #endif /* wrapper_h */

+ 4 - 0
deltachat-ios.xcodeproj/project.pbxproj

@@ -127,6 +127,7 @@
 		7837B64021E54DC600CDE126 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = 7837B63F21E54DC600CDE126 /* .swiftlint.yml */; };
 		785BE16821E247F1003BE98C /* MessageInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 785BE16721E247F1003BE98C /* MessageInfoViewController.swift */; };
 		789E879621D6CB58003ED1C5 /* QrCodeReaderController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E879521D6CB58003ED1C5 /* QrCodeReaderController.swift */; };
+		78A8733D2877608200690A0B /* QrViewBackupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78A8733C2877608200690A0B /* QrViewBackupController.swift */; };
 		78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3921D3CFBC00D4B15E /* SettingsController.swift */; };
 		78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */; };
 		78ED838321D5379000243125 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED838221D5379000243125 /* TextFieldCell.swift */; };
@@ -400,6 +401,7 @@
 		785BE16721E247F1003BE98C /* MessageInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageInfoViewController.swift; sourceTree = "<group>"; };
 		787D6699229F2237000A7A9D /* libdeltachat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdeltachat.a; path = "deltachat-ios/libraries/deltachat-core-rust/target/universal/debug/libdeltachat.a"; sourceTree = "<group>"; };
 		789E879521D6CB58003ED1C5 /* QrCodeReaderController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrCodeReaderController.swift; sourceTree = "<group>"; };
+		78A8733C2877608200690A0B /* QrViewBackupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrViewBackupController.swift; sourceTree = "<group>"; };
 		78C7036A21D46752005D4525 /* deltachat-ios.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "deltachat-ios.entitlements"; sourceTree = "<group>"; };
 		78E45E3921D3CFBC00D4B15E /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
 		78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = "<group>"; };
@@ -931,6 +933,7 @@
 				789E879521D6CB58003ED1C5 /* QrCodeReaderController.swift */,
 				AECEF03D244F2D55006C90DA /* QrPageController.swift */,
 				30149D9222F21129003C12B5 /* QrViewController.swift */,
+				78A8733C2877608200690A0B /* QrViewBackupController.swift */,
 				B21005DA23383664004C70C5 /* SettingsClassicViewController.swift */,
 				30B0ACF924AB5B99004D5E29 /* SettingsEphemeralMessageController.swift */,
 				78E45E3921D3CFBC00D4B15E /* SettingsController.swift */,
@@ -1479,6 +1482,7 @@
 				30653081254358B10093E196 /* QuoteView.swift in Sources */,
 				3067AAC62667F3FE00525036 /* ImageFormat.swift in Sources */,
 				30E348DF24F3F819005C93D1 /* ChatTableView.swift in Sources */,
+				78A8733D2877608200690A0B /* QrViewBackupController.swift in Sources */,
 				30EF7308252F6A3300E2C54A /* PaddingTextView.swift in Sources */,
 				30E348E124F53772005C93D1 /* ImageTextCell.swift in Sources */,
 				3008CB7624F95B6D00E6A617 /* AudioController.swift in Sources */,

+ 12 - 2
deltachat-ios/Controller/QrPageController.swift

@@ -30,7 +30,7 @@ class QrPageController: UIPageViewController {
 
     private lazy var qrSegmentControl: UISegmentedControl = {
         let control = UISegmentedControl(
-            items: [String.localized("qrshow_title"), String.localized("qrscan_title")]
+            items: [String.localized("qrshow_title"), String.localized("qrscan_title"), "qrshow_backup"]
         )
         control.tintColor = DcColors.primary
         control.addTarget(self, action: #selector(qrSegmentControlChanged), for: .valueChanged)
@@ -85,10 +85,13 @@ class QrPageController: UIPageViewController {
         if sender.selectedSegmentIndex == 0 {
             let qrController = QrViewController(dcContext: dcContext, qrCodeHint: qrCodeHint)
             setViewControllers([qrController], direction: .reverse, animated: true, completion: nil)
-        } else {
+        } else if sender.selectedSegmentIndex == 1 {
             let qrCodeReaderController = makeQRReader()
             self.qrCodeReaderController = qrCodeReaderController
             setViewControllers([qrCodeReaderController], direction: .forward, animated: false, completion: nil)
+        } else {
+            let qrController = QrViewBackupController(dcContext: dcContext, qrCodeHint: qrCodeHint)
+            setViewControllers([qrController], direction: .reverse, animated: true, completion: nil)
         }
     }
 
@@ -107,6 +110,13 @@ class QrPageController: UIPageViewController {
                 qrViewController.qrCodeHint = newHint
             }
         }
+        
+        for case let qrViewController as QrViewBackupController in self.viewControllers ?? [] {
+            let newHint = qrCodeHint
+            if qrCodeHint != qrViewController.qrCodeHint {
+                qrViewController.qrCodeHint = newHint
+            }
+        }
     }
 
     // MARK: - coordinator

+ 74 - 0
deltachat-ios/Controller/QrViewBackupController.swift

@@ -0,0 +1,74 @@
+import Foundation
+import UIKit
+import DcCore
+import SDWebImageSVGKitPlugin
+
+class QrViewBackupController: UIViewController {
+
+    private let dcContext: DcContext
+    var onDismissed: (() -> Void)?
+    
+    private lazy var qrContentView: UIImageView = {
+        let svg = dcContext.getSecurejoinQrSVG(chatId: chatId)
+        let view = UIImageView()
+        view.contentMode = .scaleAspectFit
+        view.translatesAutoresizingMaskIntoConstraints = false
+        view.image = getQrImage(svg: svg)
+        return view
+    }()
+
+    var qrCodeHint: String {
+        willSet {
+            let svg = dcContext.getSecurejoinQrSVG(chatId: chatId)
+            qrContentView.image = getQrImage(svg: svg)
+            qrContentView.accessibilityHint = newValue
+        }
+    }
+    private let chatId: Int
+
+    init(dcContext: DcContext, chatId: Int? = 0, qrCodeHint: String?) {
+        self.dcContext = dcContext
+        self.chatId = chatId ?? 0
+        self.qrCodeHint = qrCodeHint ?? ""
+        super.init(nibName: nil, bundle: nil)
+    }
+
+    required init?(coder _: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    // MARK: - lifecycle
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        title = String.localized("qrshow_title")
+        setupSubviews()
+        view.backgroundColor = DcColors.defaultBackgroundColor
+    }
+
+    override func viewDidDisappear(_ animated: Bool) {
+        onDismissed?()
+    }
+
+    // MARK: - setup
+    private func setupSubviews() {
+        view.addSubview(qrContentView)
+        let qrDefaultWidth = qrContentView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, multiplier: 0.75)
+        qrDefaultWidth.priority = UILayoutPriority(500)
+        qrDefaultWidth.isActive = true
+        let qrMinWidth = qrContentView.widthAnchor.constraint(lessThanOrEqualToConstant: 260)
+        qrMinWidth.priority = UILayoutPriority(999)
+        qrMinWidth.isActive = true
+        qrContentView.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor, multiplier: 1.05).isActive = true
+        qrContentView.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor).isActive = true
+        qrContentView.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
+    }
+    
+    func getQrImage(svg: String?) -> UIImage? {
+        if let svg = svg {
+            let svgData = svg.data(using: .utf8)
+            return SDImageSVGKCoder.shared.decodedImage(with: svgData, options: [:])
+        }
+        return nil
+    }
+
+}

+ 1 - 1
deltachat-ios/libraries/deltachat-core-rust

@@ -1 +1 @@
-Subproject commit e149cd7afe7c8610b8babc5d7752819d40b5f6b6
+Subproject commit b5324d377b70913805635a869956aa4df7f30108