Fix inconsistent modal usage

This commit is contained in:
Niels Andriesse 2019-09-24 10:57:32 +10:00
parent f88a0f3c1f
commit f3c80e9790
7 changed files with 191 additions and 108 deletions

View File

@ -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 = "<group>"; };
B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDetailsViewController.swift; sourceTree = "<group>"; };
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedViewController.swift; sourceTree = "<group>"; };
B825848A230F94FE001B41CB /* QRCodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeViewController.swift; sourceTree = "<group>"; };
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScanQRCodeViewController.h; sourceTree = "<group>"; };
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScanQRCodeViewController.m; sourceTree = "<group>"; };
B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = "<group>"; };
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = "<group>"; };
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
B86BD08023399883000F5AE3 /* QRCodeModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeModal.swift; sourceTree = "<group>"; };
B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = "<group>"; };
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModal.swift; sourceTree = "<group>"; };
B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = "<group>"; };
B891105B2320872800F15FCC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
@ -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 = "<group>";
};
B86BD08223399ABF000F5AE3 /* Modals */ = {
isa = PBXGroup;
children = (
B86BD08323399ACF000F5AE3 /* Modal.swift */,
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */,
B86BD08023399883000F5AE3 /* QRCodeModal.swift */,
B86BD08523399CEF000F5AE3 /* SeedModal.swift */,
);
path = Modals;
sourceTree = "<group>";
};
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 */,

View File

@ -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<UITouch>, 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)
}
}

View File

@ -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<UITouch>, 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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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