diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 52577c2b6..b20273368 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -563,11 +563,13 @@ B8162F0522892C5F00D46544 /* FriendRequestViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */; }; B821F2F82272CED3002C88C0 /* AccountDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */; }; B821F2FA2272CEEE002C88C0 /* SeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedViewController.swift */; }; - B825848B230F94FE001B41CB /* QRCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825848A230F94FE001B41CB /* QRCodeViewController.swift */; }; B8258493230FA5E9001B41CB /* ScanQRCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */; }; B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; }; B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; }; B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; }; + B86BD08123399883000F5AE3 /* QRCodeModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08023399883000F5AE3 /* QRCodeModal.swift */; }; + B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; }; + B86BD08623399CEF000F5AE3 /* SeedModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08523399CEF000F5AE3 /* SeedModal.swift */; }; B885D5F4233491AB00EE0D8E /* DeviceLinkingModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */; }; B885D5F62334A32100EE0D8E /* UIView+Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */; }; B891105C2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; }; @@ -1367,12 +1369,14 @@ B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendRequestViewDelegate.swift; sourceTree = ""; }; B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDetailsViewController.swift; sourceTree = ""; }; B821F2F92272CEEE002C88C0 /* SeedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedViewController.swift; sourceTree = ""; }; - B825848A230F94FE001B41CB /* QRCodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeViewController.swift; sourceTree = ""; }; B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScanQRCodeViewController.h; sourceTree = ""; }; B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScanQRCodeViewController.m; sourceTree = ""; }; B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = ""; }; B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = ""; }; B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = ""; }; + B86BD08023399883000F5AE3 /* QRCodeModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeModal.swift; sourceTree = ""; }; + B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = ""; }; + B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = ""; }; B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModal.swift; sourceTree = ""; }; B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = ""; }; B891105B2320872800F15FCC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -2633,15 +2637,14 @@ B8439518228510E9000563FE /* Loki */ = { isa = PBXGroup; children = ( + B86BD08223399ABF000F5AE3 /* Modals */, B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */, - B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */, B8162F0222891AD600D46544 /* FriendRequestView.swift */, B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */, B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */, 24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */, B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */, B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */, - B825848A230F94FE001B41CB /* QRCodeViewController.swift */, B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */, B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */, B821F2F92272CEEE002C88C0 /* SeedViewController.swift */, @@ -2661,6 +2664,17 @@ path = Loki; sourceTree = ""; }; + B86BD08223399ABF000F5AE3 /* Modals */ = { + isa = PBXGroup; + children = ( + B86BD08323399ACF000F5AE3 /* Modal.swift */, + B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */, + B86BD08023399883000F5AE3 /* QRCodeModal.swift */, + B86BD08523399CEF000F5AE3 /* SeedModal.swift */, + ); + path = Modals; + sourceTree = ""; + }; D221A07E169C9E5E00537ABF = { isa = PBXGroup; children = ( @@ -3695,6 +3709,7 @@ 348570A820F67575004FF32B /* OWSMessageHeaderView.m in Sources */, 450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */, 34B6A907218B5241007C4606 /* TypingIndicatorCell.swift in Sources */, + B86BD08123399883000F5AE3 /* QRCodeModal.swift in Sources */, 4CFD151D22415AA400F2450F /* CallVideoHintView.swift in Sources */, 34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */, 343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */, @@ -3721,7 +3736,6 @@ 4C2F454F214C00E1004871FF /* AvatarTableViewCell.swift in Sources */, 346E9D5421B040B700562252 /* RegistrationController.swift in Sources */, 340FC8AD204DAC8D007AEB0F /* OWSLinkedDevicesTableViewController.m in Sources */, - B825848B230F94FE001B41CB /* QRCodeViewController.swift in Sources */, 340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */, 4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */, 3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */, @@ -3746,6 +3760,7 @@ 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */, D221A09A169C9E5E00537ABF /* main.m in Sources */, 3496957221A301A100DCFE74 /* OWSBackup.m in Sources */, + B86BD08623399CEF000F5AE3 /* SeedModal.swift in Sources */, 34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */, 3448E1622213585C004B052E /* OnboardingBaseViewController.swift in Sources */, 34E5DC8220D8050D00C08145 /* RegistrationUtils.m in Sources */, @@ -3872,6 +3887,7 @@ 34D1F0B01F867BFC0066283D /* OWSSystemMessageCell.m in Sources */, 45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */, 34CA631B2097806F00E526A0 /* OWSContactShareView.m in Sources */, + B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */, 34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */, 3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */, B8258493230FA5E9001B41CB /* ScanQRCodeViewController.m in Sources */, diff --git a/Signal/src/Loki/DeviceLinkingModal.swift b/Signal/src/Loki/Modals/DeviceLinkingModal.swift similarity index 69% rename from Signal/src/Loki/DeviceLinkingModal.swift rename to Signal/src/Loki/Modals/DeviceLinkingModal.swift index 6d3e4ea6b..2b4024758 100644 --- a/Signal/src/Loki/DeviceLinkingModal.swift +++ b/Signal/src/Loki/Modals/DeviceLinkingModal.swift @@ -1,23 +1,10 @@ import NVActivityIndicatorView -// TODO: Use the same kind of modal to show the user their QR code and seed - @objc(LKDeviceLinkingModal) -final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDelegate { +final class DeviceLinkingModal : Modal, LokiDeviceLinkingSessionDelegate { private var deviceLink: LokiDeviceLink? // MARK: Components - private lazy var contentView: UIView = { - let result = UIView() - result.backgroundColor = .lokiDarkGray() - result.layer.cornerRadius = 4 - result.layer.masksToBounds = false - result.layer.shadowColor = UIColor.black.cgColor - result.layer.shadowRadius = 8 - result.layer.shadowOpacity = 0.64 - return result - }() - private lazy var topSpacer = UIView.spacer(withHeight: 8) private lazy var spinner = NVActivityIndicatorView(frame: CGRect.zero, type: .circleStrokeSpin, color: .white, padding: nil) @@ -61,36 +48,20 @@ final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDeleg return result }() - private lazy var cancelButton: OWSFlatButton = { - let result = OWSFlatButton.button(title: NSLocalizedString("Cancel", comment: ""), font: .ows_dynamicTypeBodyClamped, titleColor: .white, backgroundColor: .clear, target: self, selector: #selector(cancel)) - result.setBackgroundColors(upColor: .clear, downColor: .clear) - return result - }() - // MARK: Lifecycle override func viewDidLoad() { super.viewDidLoad() - setUpViewHierarchy() let _ = LokiDeviceLinkingSession.startListeningForLinkingRequests(with: self) } - private func setUpViewHierarchy() { - view.backgroundColor = .clear - view.addSubview(contentView) - contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32).isActive = true - view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 32).isActive = true - contentView.center(.vertical, in: view) + override func populateContentView() { let buttonStackView = UIStackView(arrangedSubviews: [ authorizeButton, cancelButton ]) + let stackView = UIStackView(arrangedSubviews: [ topSpacer, spinner, UIView.spacer(withHeight: 8), titleLabel, subtitleLabel, mnemonicLabel, buttonStackView ]) + contentView.addSubview(stackView) + stackView.spacing = 16 + stackView.axis = .vertical buttonStackView.axis = .horizontal buttonStackView.distribution = .fillEqually - let stackView = UIStackView(arrangedSubviews: [ topSpacer, spinner, UIView.spacer(withHeight: 8), titleLabel, subtitleLabel, mnemonicLabel, buttonStackView ]) - stackView.spacing = 16 - contentView.addSubview(stackView) - stackView.axis = .vertical - stackView.pin(.leading, to: .leading, of: contentView, withInset: 16) - stackView.pin(.top, to: .top, of: contentView, withInset: 16) - contentView.pin(.trailing, to: .trailing, of: stackView, withInset: 16) - contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16) spinner.set(.height, to: 64) spinner.startAnimating() mnemonicLabel.isHidden = true @@ -98,6 +69,10 @@ final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDeleg authorizeButton.set(.height, to: buttonHeight) cancelButton.set(.height, to: buttonHeight) authorizeButton.isHidden = true + stackView.pin(.leading, to: .leading, of: contentView, withInset: 16) + stackView.pin(.top, to: .top, of: contentView, withInset: 16) + contentView.pin(.trailing, to: .trailing, of: stackView, withInset: 16) + contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16) } // MARK: Device Linking @@ -112,17 +87,6 @@ final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDeleg self.authorizeButton.isHidden = false } - // MARK: Interaction - override func touchesBegan(_ touches: Set, with event: UIEvent?) { - let touch = touches.first! - let location = touch.location(in: view) - if contentView.frame.contains(location) { - super.touchesBegan(touches, with: event) - } else { - cancel() - } - } - @objc private func authorizeDeviceLink() { let deviceLink = self.deviceLink! let session = LokiDeviceLinkingSession.current! @@ -130,9 +94,4 @@ final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDeleg session.stopListeningForLinkingRequests() dismiss(animated: true, completion: nil) } - - @objc private func cancel() { - LokiDeviceLinkingSession.current?.stopListeningForLinkingRequests() - dismiss(animated: true, completion: nil) - } } diff --git a/Signal/src/Loki/Modals/Modal.swift b/Signal/src/Loki/Modals/Modal.swift new file mode 100644 index 000000000..97f1241d6 --- /dev/null +++ b/Signal/src/Loki/Modals/Modal.swift @@ -0,0 +1,57 @@ + +@objc(LKModal) +internal class Modal : UIViewController { + + // MARK: Components + lazy var contentView: UIView = { + let result = UIView() + result.backgroundColor = .lokiDarkGray() + result.layer.cornerRadius = 4 + result.layer.masksToBounds = false + result.layer.shadowColor = UIColor.black.cgColor + result.layer.shadowRadius = 8 + result.layer.shadowOpacity = 0.64 + return result + }() + + lazy var cancelButton: OWSFlatButton = { + let result = OWSFlatButton.button(title: NSLocalizedString("Cancel", comment: ""), font: .ows_dynamicTypeBodyClamped, titleColor: .white, backgroundColor: .clear, target: self, selector: #selector(cancel)) + result.setBackgroundColors(upColor: .clear, downColor: .clear) + return result + }() + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + setUpViewHierarchy() + } + + private func setUpViewHierarchy() { + view.backgroundColor = .clear + view.addSubview(contentView) + contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32).isActive = true + view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 32).isActive = true + contentView.center(.vertical, in: view) + populateContentView() + } + + /// To be overridden by subclasses. + func populateContentView() { + preconditionFailure("populateContentView() is abstract and must be overridden.") + } + + // MARK: Interaction + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + let touch = touches.first! + let location = touch.location(in: view) + if contentView.frame.contains(location) { + super.touchesBegan(touches, with: event) + } else { + cancel() + } + } + + @objc private func cancel() { + dismiss(animated: true, completion: nil) + } +} diff --git a/Signal/src/Loki/Modals/QRCodeModal.swift b/Signal/src/Loki/Modals/QRCodeModal.swift new file mode 100644 index 000000000..9b8095d4d --- /dev/null +++ b/Signal/src/Loki/Modals/QRCodeModal.swift @@ -0,0 +1,38 @@ + +@objc(LKQRCodeModal) +final class QRCodeModal : Modal { + + override func populateContentView() { + // Label + let label = UILabel() + label.font = UIFont.ows_dynamicTypeSubheadlineClamped + label.text = NSLocalizedString("This is your personal QR code. Other people can scan it to start a secure conversation with you.", comment: "") + label.numberOfLines = 0 + label.textAlignment = .center + label.lineBreakMode = .byWordWrapping + label.textColor = UIColor.ows_white + // Image view + let imageView = UIImageView() + let hexEncodedPublicKey = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey + let data = hexEncodedPublicKey.data(using: .utf8) + let filter = CIFilter(name: "CIQRCodeGenerator")! + filter.setValue(data, forKey: "inputMessage") + let qrCodeAsCIImage = filter.outputImage! + let scaledQRCodeAsCIImage = qrCodeAsCIImage.transformed(by: CGAffineTransform(scaleX: 4.8, y: 4.8)) + let qrCode = UIImage(ciImage: scaledQRCodeAsCIImage) + imageView.image = qrCode + // Cancel button + let buttonHeight = cancelButton.button.titleLabel!.font.pointSize * 48 / 17 + cancelButton.set(.height, to: buttonHeight) + // Stack view + let stackView = UIStackView(arrangedSubviews: [ UIView.spacer(withHeight: 2), label, UIView.spacer(withHeight: 2), imageView, cancelButton ]) + stackView.axis = .vertical + stackView.spacing = 16 + stackView.alignment = .center + contentView.addSubview(stackView) + stackView.pin(.leading, to: .leading, of: contentView, withInset: 16) + stackView.pin(.top, to: .top, of: contentView, withInset: 16) + contentView.pin(.trailing, to: .trailing, of: stackView, withInset: 16) + contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16) + } +} diff --git a/Signal/src/Loki/Modals/SeedModal.swift b/Signal/src/Loki/Modals/SeedModal.swift new file mode 100644 index 000000000..9318b08f5 --- /dev/null +++ b/Signal/src/Loki/Modals/SeedModal.swift @@ -0,0 +1,59 @@ +import NVActivityIndicatorView + +@objc(LKSeedModal) +final class SeedModal : Modal { + + private let mnemonic: String = { + let identityManager = OWSIdentityManager.shared() + let databaseConnection = identityManager.value(forKey: "dbConnection") as! YapDatabaseConnection + var hexEncodedSeed: String! = databaseConnection.object(forKey: "LKLokiSeed", inCollection: OWSPrimaryStorageIdentityKeyStoreCollection) as! String? + if hexEncodedSeed == nil { + hexEncodedSeed = identityManager.identityKeyPair()!.hexEncodedPrivateKey // Legacy account + } + return Mnemonic.encode(hexEncodedString: hexEncodedSeed) + }() + + // MARK: Lifecycle + override func populateContentView() { + // Label + let titleLabel = UILabel() + titleLabel.textColor = Theme.primaryColor + titleLabel.font = UIFont.ows_dynamicTypeHeadlineClamped + titleLabel.text = NSLocalizedString("Your Seed", comment: "") + titleLabel.numberOfLines = 0 + titleLabel.lineBreakMode = .byWordWrapping + titleLabel.textAlignment = .center + // Mnemonic label + let mnemonicLabel = UILabel() + mnemonicLabel.font = UIFont.ows_dynamicTypeCaption1Clamped + mnemonicLabel.text = mnemonic + mnemonicLabel.numberOfLines = 0 + mnemonicLabel.textAlignment = .center + mnemonicLabel.lineBreakMode = .byWordWrapping + mnemonicLabel.textColor = UIColor.ows_white + // Button stack view + let copyButton = OWSFlatButton.button(title: NSLocalizedString("Copy", comment: ""), font: .ows_dynamicTypeBodyClamped, titleColor: .white, backgroundColor: .clear, target: self, selector: #selector(copySeed)) + copyButton.setBackgroundColors(upColor: .clear, downColor: .clear) + let buttonStackView = UIStackView(arrangedSubviews: [ copyButton, cancelButton ]) + buttonStackView.axis = .horizontal + buttonStackView.distribution = .fillEqually + let buttonHeight = cancelButton.button.titleLabel!.font.pointSize * 48 / 17 + copyButton.set(.height, to: buttonHeight) + cancelButton.set(.height, to: buttonHeight) + // Stack view + let stackView = UIStackView(arrangedSubviews: [ UIView.spacer(withHeight: 2), titleLabel, mnemonicLabel, buttonStackView ]) + stackView.axis = .vertical + stackView.spacing = 16 + contentView.addSubview(stackView) + stackView.pin(.leading, to: .leading, of: contentView, withInset: 16) + stackView.pin(.top, to: .top, of: contentView, withInset: 16) + contentView.pin(.trailing, to: .trailing, of: stackView, withInset: 16) + contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16) + } + + // MARK: Interaction + @objc private func copySeed() { + UIPasteboard.general.string = mnemonic + dismiss(animated: true, completion: nil) + } +} diff --git a/Signal/src/Loki/QRCodeViewController.swift b/Signal/src/Loki/QRCodeViewController.swift deleted file mode 100644 index af269d67a..000000000 --- a/Signal/src/Loki/QRCodeViewController.swift +++ /dev/null @@ -1,40 +0,0 @@ - -final class QRCodeViewController : OWSViewController { - - public override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait} - public override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent} - - override func viewDidLoad() { - super.viewDidLoad() - view.backgroundColor = UIColor.lokiDarkestGray() - let stackView = UIStackView(arrangedSubviews: []) - stackView.axis = .vertical - stackView.spacing = 32 - stackView.alignment = .center - stackView.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(stackView) - NSLayoutConstraint.activate([ - stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32), - stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 24), - view.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: 32) - ]) - let label = UILabel() - label.font = UIFont.ows_dynamicTypeSubheadlineClamped - label.text = NSLocalizedString("This is your personal QR code. Other people can scan it to start a secure conversation with you.", comment: "") - label.numberOfLines = 0 - label.textAlignment = .center - label.lineBreakMode = .byWordWrapping - label.textColor = UIColor.ows_white - stackView.addArrangedSubview(label) - let imageView = UIImageView() - let hexEncodedPublicKey = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey - let data = hexEncodedPublicKey.data(using: .utf8) - let filter = CIFilter(name: "CIQRCodeGenerator")! - filter.setValue(data, forKey: "inputMessage") - let qrCodeAsCIImage = filter.outputImage! - let scaledQRCodeAsCIImage = qrCodeAsCIImage.transformed(by: CGAffineTransform(scaleX: 6.4, y: 6.4)) - let qrCode = UIImage(ciImage: scaledQRCodeAsCIImage) - imageView.image = qrCode - stackView.addArrangedSubview(imageView) - } -} diff --git a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m index bc70dee36..48bf6515b 100644 --- a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m @@ -508,8 +508,9 @@ - (void)showQRCode { - QRCodeViewController *qrCodeVC = [QRCodeViewController new]; - [self.navigationController pushViewController:qrCodeVC animated:YES]; + LKQRCodeModal *qrCodeModal = [LKQRCodeModal new]; + qrCodeModal.modalPresentationStyle = UIModalPresentationOverFullScreen; + [self presentViewController:qrCodeModal animated:YES completion:nil]; } - (void)linkDevice @@ -521,16 +522,9 @@ - (void)showSeed { - NSString *title = NSLocalizedString(@"Your Seed", @""); - OWSIdentityManager *identityManager = OWSIdentityManager.sharedManager; - YapDatabaseConnection *databaseConnection = (YapDatabaseConnection *)[identityManager valueForKey:@"dbConnection"]; - NSString *hexEncodedSeed = [databaseConnection objectForKey:@"LKLokiSeed" inCollection:OWSPrimaryStorageIdentityKeyStoreCollection]; - if (hexEncodedSeed == nil) { hexEncodedSeed = identityManager.identityKeyPair.hexEncodedPrivateKey; } // Legacy account - NSString *mnemonic = [LKMnemonic encodeHexEncodedString:hexEncodedSeed]; - UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:mnemonic preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { /* Do nothing */ }]]; - [alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Copy", @"") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { UIPasteboard.generalPasteboard.string = mnemonic; }]]; - [self presentAlert:alert]; + LKSeedModal *seedModal = [LKSeedModal new]; + seedModal.modalPresentationStyle = UIModalPresentationOverFullScreen; + [self presentViewController:seedModal animated:YES completion:nil]; } - (void)clearAllData