Implement QR code scanning

pull/39/head
Niels Andriesse 5 years ago
parent e72af6dec3
commit 8744d732a9

@ -561,6 +561,7 @@
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 */; };
@ -1352,6 +1353,8 @@
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>"; };
@ -2618,6 +2621,8 @@
24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */,
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */,
B825848A230F94FE001B41CB /* QRCodeViewController.swift */,
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */,
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */,
);
path = Loki;
sourceTree = "<group>";
@ -3801,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,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"

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

@ -2608,3 +2608,9 @@
"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