From 395d167f561c32b136db0693e23005ea8bf64352 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 24 Sep 2019 11:59:17 +1000 Subject: [PATCH] Update device linking modal for linkee --- Signal.xcodeproj/project.pbxproj | 4 ++ Signal/src/Loki/FriendRequestView.swift | 2 +- Signal/src/Loki/Onboarding/SeedVC.swift | 26 ++++++++++--- .../Loki/Settings/DeviceLinkingModal.swift | 38 +++++++++++++++++-- .../Settings/DeviceLinkingModalDelegate.swift | 6 +++ .../AppSettings/AppSettingsViewController.m | 2 +- .../translations/en.lproj/Localizable.strings | 4 ++ 7 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 Signal/src/Loki/Settings/DeviceLinkingModalDelegate.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index f22e74fc3..cbc2c678c 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -570,6 +570,7 @@ 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 */; }; + B86BD08C2339AE43000F5AE3 /* DeviceLinkingModalDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08B2339AE43000F5AE3 /* DeviceLinkingModalDelegate.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 */; }; @@ -1377,6 +1378,7 @@ 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 = ""; }; + B86BD08B2339AE43000F5AE3 /* DeviceLinkingModalDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModalDelegate.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 = ""; }; @@ -2666,6 +2668,7 @@ isa = PBXGroup; children = ( B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */, + B86BD08B2339AE43000F5AE3 /* DeviceLinkingModalDelegate.swift */, B86BD08023399883000F5AE3 /* QRCodeModal.swift */, B86BD08523399CEF000F5AE3 /* SeedModal.swift */, ); @@ -3910,6 +3913,7 @@ 45E5A6991F61E6DE001E4A8A /* MarqueeLabel.swift in Sources */, 34D1F0B01F867BFC0066283D /* OWSSystemMessageCell.m in Sources */, 45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */, + B86BD08C2339AE43000F5AE3 /* DeviceLinkingModalDelegate.swift in Sources */, 34CA631B2097806F00E526A0 /* OWSContactShareView.m in Sources */, B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */, 34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */, diff --git a/Signal/src/Loki/FriendRequestView.swift b/Signal/src/Loki/FriendRequestView.swift index 79458f5e5..e90cd83fa 100644 --- a/Signal/src/Loki/FriendRequestView.swift +++ b/Signal/src/Loki/FriendRequestView.swift @@ -39,7 +39,7 @@ final class FriendRequestView : UIView { private lazy var buttonFont = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight() private lazy var buttonHeight = buttonFont.pointSize * 48 / 17 - // MARK: Initialization + // MARK: Lifecycle @objc init(message: TSMessage) { self.message = message super.init(frame: CGRect.zero) diff --git a/Signal/src/Loki/Onboarding/SeedVC.swift b/Signal/src/Loki/Onboarding/SeedVC.swift index 6a9704223..d5df7123a 100644 --- a/Signal/src/Loki/Onboarding/SeedVC.swift +++ b/Signal/src/Loki/Onboarding/SeedVC.swift @@ -1,7 +1,7 @@ // TODO: Split this into multiple VCs -final class SeedVC : OnboardingBaseViewController { +final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate { private var mode: Mode = .register { didSet { if mode != oldValue { handleModeChanged() } } } private var seed: Data! { didSet { updateMnemonic() } } private var mnemonic: String! { didSet { handleMnemonicChanged() } } @@ -124,7 +124,7 @@ final class SeedVC : OnboardingBaseViewController { }() private lazy var explanationLabel3: UILabel = { - let result = createExplanationLabel(text: NSLocalizedString("Link an existing device by going into Loki Messenger's in-app settings and clicking \"Link Device\".", comment: "")) + let result = createExplanationLabel(text: NSLocalizedString("Link to an existing device by going into Loki Messenger's in-app settings and clicking \"Link Device\".", comment: "")) result.accessibilityIdentifier = "onboarding.keyPairStep.explanationLabel3" result.textColor = Theme.primaryColor var fontTraits = result.font.fontDescriptor.symbolicTraits @@ -302,7 +302,7 @@ final class SeedVC : OnboardingBaseViewController { var seed: Data let mode = self.mode switch mode { - case .register, .link: seed = self.seed + case .register: seed = self.seed case .restore: let mnemonic = mnemonicTextField.text! do { @@ -313,6 +313,13 @@ final class SeedVC : OnboardingBaseViewController { errorLabel1Spacer.isHidden = false return errorLabel1.text = error.errorDescription } + case .link: + seed = self.seed + let hexEncodedPublicKey = masterHexEncodedPublicKeyTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces) + if !ECKeyPair.isValidHexEncodedPublicKey(candidate: hexEncodedPublicKey) { + errorLabel2Spacer.isHidden = false + return errorLabel2.text = NSLocalizedString("Invalid public key", comment: "") + } } // Use KVC to access dbConnection even though it's private let identityManager = OWSIdentityManager.shared() @@ -330,8 +337,17 @@ final class SeedVC : OnboardingBaseViewController { case .link: Analytics.shared.track("Device Linked") } if mode == .link { - + let deviceLinkingModal = DeviceLinkingModal(mode: .slave, delegate: self) + deviceLinkingModal.modalPresentationStyle = .overFullScreen + present(deviceLinkingModal, animated: true, completion: nil) + } else { + onboardingController.pushDisplayNameVC(from: self) } - onboardingController.pushDisplayNameVC(from: self) + } + + func handleDeviceLinked() { + TSAccountManager.sharedInstance().didRegister() + UserDefaults.standard.set(true, forKey: "didUpdateForMainnet") + onboardingController.verificationDidComplete(fromView: self) } } diff --git a/Signal/src/Loki/Settings/DeviceLinkingModal.swift b/Signal/src/Loki/Settings/DeviceLinkingModal.swift index dccbb75f3..cc11f317e 100644 --- a/Signal/src/Loki/Settings/DeviceLinkingModal.swift +++ b/Signal/src/Loki/Settings/DeviceLinkingModal.swift @@ -2,8 +2,13 @@ import NVActivityIndicatorView @objc(LKDeviceLinkingModal) final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { + private let mode: Mode + private let delegate: DeviceLinkingModalDelegate? private var deviceLink: DeviceLink? + // MARK: Types + enum Mode : String { case master, slave } + // MARK: Components private lazy var topSpacer = UIView.spacer(withHeight: 8) @@ -13,7 +18,6 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { let result = UILabel() result.textColor = Theme.primaryColor result.font = UIFont.ows_dynamicTypeHeadlineClamped - result.text = NSLocalizedString("Waiting for Device", comment: "") result.numberOfLines = 0 result.lineBreakMode = .byWordWrapping result.textAlignment = .center @@ -24,7 +28,6 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { let result = UILabel() result.textColor = Theme.primaryColor result.font = UIFont.ows_dynamicTypeCaption1Clamped - result.text = NSLocalizedString("Click the \"Link Device\" button on your other device to start the linking process", comment: "") result.numberOfLines = 0 result.lineBreakMode = .byWordWrapping result.textAlignment = .center @@ -49,6 +52,23 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { }() // MARK: Lifecycle + init(mode: Mode, delegate: DeviceLinkingModalDelegate?) { + self.mode = mode + if mode == .slave { + guard delegate != nil else { preconditionFailure("Missing delegate for device linking modal in slave mode.") } + } + self.delegate = delegate + super.init(nibName: nil, bundle: nil) + } + + @objc convenience init(modeAsString: String, delegate: DeviceLinkingModalDelegate?) { + guard let mode = Mode(rawValue: modeAsString) else { preconditionFailure("Invalid mode: \(modeAsString).") } + self.init(mode: mode, delegate: delegate) + } + + required init?(coder: NSCoder) { preconditionFailure() } + override init(nibName: String?, bundle: Bundle?) { preconditionFailure() } + override func viewDidLoad() { super.viewDidLoad() let _ = DeviceLinkingSession.startListeningForLinkingRequests(with: self) @@ -64,7 +84,19 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { buttonStackView.distribution = .fillEqually spinner.set(.height, to: 64) spinner.startAnimating() - mnemonicLabel.isHidden = true + titleLabel.text = { + switch mode { + case .master: return NSLocalizedString("Waiting for Device", comment: "") + case .slave: return NSLocalizedString("Waiting for Authorization", comment: "") + } + }() + subtitleLabel.text = { + switch mode { + case .master: return NSLocalizedString("Click the \"Link Device\" button on your other device to start the linking process", comment: "") + case .slave: return NSLocalizedString("Please verify that the words below match the ones shown on your other device.", comment: "") + } + }() + mnemonicLabel.isHidden = (mode == .master) let buttonHeight = cancelButton.button.titleLabel!.font.pointSize * 48 / 17 authorizeButton.set(.height, to: buttonHeight) cancelButton.set(.height, to: buttonHeight) diff --git a/Signal/src/Loki/Settings/DeviceLinkingModalDelegate.swift b/Signal/src/Loki/Settings/DeviceLinkingModalDelegate.swift new file mode 100644 index 000000000..210becab1 --- /dev/null +++ b/Signal/src/Loki/Settings/DeviceLinkingModalDelegate.swift @@ -0,0 +1,6 @@ + +@objc(LKDeviceLinkingModalDelegate) +protocol DeviceLinkingModalDelegate { + + func handleDeviceLinked() +} diff --git a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m index 48bf6515b..e8b8b8ed5 100644 --- a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m @@ -515,7 +515,7 @@ - (void)linkDevice { - LKDeviceLinkingModal *deviceLinkingModal = [LKDeviceLinkingModal new]; + LKDeviceLinkingModal *deviceLinkingModal = [[LKDeviceLinkingModal alloc] initWithModeAsString:@"master" delegate:nil]; deviceLinkingModal.modalPresentationStyle = UIModalPresentationOverFullScreen; [self presentViewController:deviceLinkingModal animated:YES completion:nil]; } diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 4e02a60e5..b6480af45 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -2623,5 +2623,9 @@ "Copy Public Key" = "Copy Public Key"; "Link Device" = "Link Device"; "Waiting for Device" = "Waiting for Device"; +"Waiting for Authorization" = "Waiting for Authorization"; "Click the \"Link Device\" button on your other device to start the linking process" = "Click the \"Link Device\" button on your other device to start the linking process"; "Linking Request Received" = "Linking Request Received"; +"Invalid public key" = "Invalid public key"; +"Please verify that the words below match the ones shown on your other device." = "Please verify that the words below match the ones shown on your other device."; +"Link to an existing device by going into Loki Messenger's in-app settings and clicking \"Link Device\"." = "Link to an existing device by going into Loki Messenger's in-app settings and clicking \"Link Device\".";