Merge pull request #39 from loki-project/qr-code

QR Code Scanning
pull/40/head
gmbnt 6 years ago committed by GitHub
commit b82329342c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -560,6 +560,8 @@
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 */; };
B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; };
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */; };
@ -1350,6 +1352,9 @@
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>"; };
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>"; };
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = "<group>"; };
@ -2615,6 +2620,9 @@
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */,
24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */,
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */,
B825848A230F94FE001B41CB /* QRCodeViewController.swift */,
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */,
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */,
);
path = Loki;
sourceTree = "<group>";
@ -3647,6 +3655,7 @@
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 */,
@ -3797,6 +3806,7 @@
34CA631B2097806F00E526A0 /* OWSContactShareView.m in Sources */,
34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */,
3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */,
B8258493230FA5E9001B41CB /* ScanQRCodeViewController.m in Sources */,
B90418E6183E9DD40038554A /* DateUtil.m in Sources */,
3448E15E221333F5004B052E /* OnboardingController.swift in Sources */,
340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */,

@ -127,7 +127,7 @@
<key>NSAppleMusicUsageDescription</key>
<string>Signal needs to use Apple Music to play media attachments.</string>
<key>NSCameraUsageDescription</key>
<string>Signal uses your camera to take photos and for video calls.</string>
<string>Loki Messenger needs camera access to scan QR codes.</string>
<key>NSContactsUsageDescription</key>
<string>Signal uses your contacts to find users you know. We do not store your contacts on the server.</string>
<key>NSFaceIDUsageDescription</key>

@ -1,6 +1,6 @@
@objc(LKNewConversationViewController)
final class NewConversationViewController : OWSViewController {
final class NewConversationViewController : OWSViewController, OWSQRScannerDelegate {
// MARK: Components
private lazy var publicKeyTextField: UITextField = {
@ -34,20 +34,29 @@ final class NewConversationViewController : OWSViewController {
explanationLabel.text = NSLocalizedString("Enter the public key of the person you'd like to securely message. They can share their public key with you by going into Loki Messenger's in-app settings and clicking \"Share Public Key\".", comment: "")
explanationLabel.numberOfLines = 0
explanationLabel.lineBreakMode = .byWordWrapping
// Button
let buttonFont = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight()
let buttonHeight = buttonFont.pointSize * 48 / 17
let startNewConversationButton = OWSFlatButton.button(title: NSLocalizedString("Next", comment: ""), font: buttonFont, titleColor: .white, backgroundColor: .lokiGreen(), target: self, selector: #selector(startNewConversationIfPossible))
startNewConversationButton.autoSetDimension(.height, toSize: buttonHeight)
// QR code button
let qrCodeButtonFont = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight()
let qrCodeButtonHeight = qrCodeButtonFont.pointSize * 48 / 17
let qrCodeButton = OWSFlatButton.button(title: NSLocalizedString("Scan a QR Code Instead", comment: ""), font: qrCodeButtonFont, titleColor: .lokiGreen(), backgroundColor: .clear, target: self, selector: #selector(scanQRCode))
qrCodeButton.setBackgroundColors(upColor: .clear, downColor: .clear)
qrCodeButton.autoSetDimension(.height, toSize: qrCodeButtonHeight)
qrCodeButton.button.contentHorizontalAlignment = .left
// Next button
let nextButtonFont = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight()
let nextButtonHeight = nextButtonFont.pointSize * 48 / 17
let nextButton = OWSFlatButton.button(title: NSLocalizedString("Next", comment: ""), font: nextButtonFont, titleColor: .white, backgroundColor: .lokiGreen(), target: self, selector: #selector(startNewConversationIfPossible))
nextButton.autoSetDimension(.height, toSize: nextButtonHeight)
// Stack view
let stackView = UIStackView(arrangedSubviews: [
publicKeyTextField,
UIView.spacer(withHeight: 8),
separator,
UIView.spacer(withHeight: 8),
UIView.spacer(withHeight: 24),
explanationLabel,
UIView.spacer(withHeight: 8),
qrCodeButton,
UIView.vStretchingSpacer(),
startNewConversationButton
nextButton
])
stackView.axis = .vertical
stackView.alignment = .fill
@ -69,8 +78,29 @@ final class NewConversationViewController : OWSViewController {
dismiss(animated: true, completion: nil)
}
@objc private func startNewConversationIfPossible() {
@objc private func scanQRCode() {
ows_ask(forCameraPermissions: { [weak self] hasCameraAccess in
if hasCameraAccess {
let scanQRCodeVC = ScanQRCodeViewController()
scanQRCodeVC.delegate = self
self?.navigationController!.pushViewController(scanQRCodeVC, animated: true)
} else {
// Do nothing
}
})
}
func controller(_ controller: OWSQRCodeScanningViewController, didDetectQRCodeWith string: String) {
let hexEncodedPublicKey = string
startNewConversationIfPossible(with: hexEncodedPublicKey)
}
private func handleNextButtonTapped() {
let hexEncodedPublicKey = publicKeyTextField.text?.trimmingCharacters(in: .whitespaces) ?? ""
startNewConversationIfPossible(with: hexEncodedPublicKey)
}
@objc private func startNewConversationIfPossible(with hexEncodedPublicKey: String) {
if !ECKeyPair.isValidHexEncodedPublicKey(candidate: hexEncodedPublicKey) {
let alert = UIAlertController(title: NSLocalizedString("Invalid Public Key", comment: ""), message: NSLocalizedString("Please check the public key you entered and try again.", comment: ""), preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default, handler: nil))

@ -0,0 +1,39 @@
final class QRCodeViewController : OWSViewController {
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait}
public override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent}
override func viewDidLoad() {
super.viewDidLoad()
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)
}
}

@ -0,0 +1,12 @@
#import <SignalMessaging/OWSViewController.h>
#import "OWSQRCodeScanningViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface ScanQRCodeViewController : OWSViewController
@property (nonatomic, weak) UIViewController<OWSQRScannerDelegate> *delegate;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,62 @@
#import "ScanQRCodeViewController.h"
#import "Session-Swift.h"
NS_ASSUME_NONNULL_BEGIN
@interface ScanQRCodeViewController ()
@property (nonatomic) OWSQRCodeScanningViewController *qrCodeScanningVC;
@end
@implementation ScanQRCodeViewController
- (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
- (void)viewDidLoad
{
[super viewDidLoad];
// Background color
self.view.backgroundColor = Theme.backgroundColor;
// QR code scanning VC
self.qrCodeScanningVC = [OWSQRCodeScanningViewController new];
self.qrCodeScanningVC.scanDelegate = self.delegate;
[self.view addSubview:self.qrCodeScanningVC.view];
[self.qrCodeScanningVC.view autoPinEdgeToSuperviewEdge:ALEdgeLeading];
[self.qrCodeScanningVC.view autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
[self.qrCodeScanningVC.view autoPinToTopLayoutGuideOfViewController:self withInset:0.0];
[self.qrCodeScanningVC.view autoPinToSquareAspectRatio];
// Explanation label
UILabel *explanationLabel = [UILabel new];
explanationLabel.text = NSLocalizedString(@"Scan the QR code of the person you'd like to securely message. They can find their QR code by going into Loki Messenger's in-app settings and clicking \"Show QR Code\".", @"");
explanationLabel.textColor = Theme.primaryColor;
explanationLabel.font = UIFont.ows_dynamicTypeSubheadlineClampedFont;
explanationLabel.numberOfLines = 0;
explanationLabel.lineBreakMode = NSLineBreakByWordWrapping;
explanationLabel.textAlignment = NSTextAlignmentCenter;
// Bottom view
UIView *bottomView = [UIView new];
[self.view addSubview:bottomView];
[bottomView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.qrCodeScanningVC.view];
[bottomView autoPinEdgeToSuperviewEdge:ALEdgeLeading];
[bottomView autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
[bottomView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[bottomView addSubview:explanationLabel];
[explanationLabel autoPinWidthToSuperviewWithMargin:32];
[explanationLabel autoPinHeightToSuperviewWithMargin:32];
// Title
self.title = NSLocalizedString(@"Scan QR Code", "");
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[UIDevice.currentDevice ows_setOrientation:UIInterfaceOrientationPortrait];
dispatch_async(dispatch_get_main_queue(), ^{
[self.qrCodeScanningVC startCapture];
});
}
@end
NS_ASSUME_NONNULL_END

@ -43,6 +43,7 @@
#import "PrivacySettingsTableViewController.h"
#import "ProfileViewController.h"
#import "RemoteVideoView.h"
#import "ScanQRCodeViewController.h"
#import "SignalApp.h"
#import "UIViewController+Permissions.h"
#import "ViewControllerUtils.h"

@ -239,6 +239,7 @@
#endif
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Share Public Key", @"") actionBlock:^{ [weakSelf sharePublicKey]; }]];
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Show QR Code", @"") actionBlock:^{ [weakSelf showQRCode]; }]];
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Show Seed", @"") actionBlock:^{ [weakSelf showSeed]; }]];
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Clear All Data", @"") actionBlock:^{ [weakSelf clearAllData]; }]];
@ -503,6 +504,12 @@
[self presentViewController:shareVC animated:YES completion:nil];
}
- (void)showQRCode
{
QRCodeViewController *qrCodeVC = [QRCodeViewController new];
[self.navigationController pushViewController:qrCodeVC animated:YES];
}
- (void)showSeed
{
NSString *title = NSLocalizedString(@"Your Seed", @"");

@ -39,8 +39,8 @@ NS_ASSUME_NONNULL_BEGIN
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (status == AVAuthorizationStatusDenied) {
UIAlertController *alert = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"MISSING_CAMERA_PERMISSION_TITLE", @"Alert title")
message:NSLocalizedString(@"MISSING_CAMERA_PERMISSION_MESSAGE", @"Alert body")
alertControllerWithTitle:NSLocalizedString(@"Loki Messenger needs camera access to scan QR codes.", @"")
message:NSLocalizedString(@"You can enable camera access in your device settings.", @"")
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *openSettingsAction =

@ -2607,3 +2607,10 @@
"Update Required" = "Update Required";
"This version of Loki Messenger is no longer supported. Please press OK to reset your account and migrate to the latest version." = "This version of Loki Messenger is no longer supported. Please press OK to reset your account and migrate to the latest version.";
"Loki Public Chat" = "Loki Public Chat";
"Show QR Code" = "Show QR Code";
"This is your personal QR code. Other people can scan it to start a secure conversation with you." = "This is your personal QR code. Other people can scan it to start a secure conversation with you.";
"Scan a QR Code Instead" = "Scan a QR Code Instead";
"Loki Messenger needs camera access to scan QR codes." = "Loki Messenger needs camera access to scan QR codes.";
"You can enable camera access in your device settings." = "You can enable camera access in your device settings.";
"Scan the QR code of the person you'd like to securely message. They can find their QR code by going into Loki Messenger's in-app settings and clicking \"Show QR Code\"." = "Scan the QR code of the person you'd like to securely message. They can find their QR code by going into Loki Messenger's in-app settings and clicking \"Show QR Code\".";
"Scan QR Code" = "Scan QR Code";

@ -8,7 +8,7 @@ import SignalServiceKit
@objc
public class OWSFlatButton: UIView {
private let button: UIButton
public let button: UIButton
private var pressedBlock : (() -> Void)?

Loading…
Cancel
Save