Skip to content

Commit 5765ada

Browse files
committed
Add a message about camera permissions and a link to the Settings app
1 parent c2816ba commit 5765ada

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

Authenticator/Source/TokenScannerViewController.swift

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,32 @@ import OneTimePassword
3030
class TokenScannerViewController: UIViewController, QRScannerDelegate {
3131
private let scanner = QRScanner()
3232
private let videoLayer = AVCaptureVideoPreviewLayer()
33-
private let messageView = UIView()
33+
private let messageView = UIButton()
3434

3535
private var viewModel: TokenScanner.ViewModel
3636
private let dispatchAction: (TokenScanner.Action) -> Void
3737

38+
fileprivate let permissionLabel: UILabel = {
39+
let linkTitle = "Go to Settings →"
40+
let message = "To add a new token via QR code, Authenticator needs permission to access the camera.\n\(linkTitle)"
41+
let paragraphStyle = NSMutableParagraphStyle()
42+
paragraphStyle.lineHeightMultiple = 1.3
43+
paragraphStyle.paragraphSpacing = 5
44+
let attributedMessage = NSMutableAttributedString(string: message, attributes: [
45+
NSFontAttributeName: UIFont.systemFont(ofSize: 15, weight: UIFontWeightLight),
46+
NSParagraphStyleAttributeName: paragraphStyle,
47+
])
48+
attributedMessage.addAttribute(NSFontAttributeName, value: UIFont.boldSystemFont(ofSize: 15),
49+
range: (attributedMessage.string as NSString).range(of: linkTitle))
50+
51+
let label = UILabel()
52+
label.numberOfLines = 0
53+
label.attributedText = attributedMessage
54+
label.textAlignment = .center
55+
label.textColor = UIColor.otpForegroundColor
56+
return label
57+
}()
58+
3859
// MARK: Initialization
3960

4061
init(viewModel: TokenScanner.ViewModel, dispatchAction: @escaping (TokenScanner.Action) -> Void) {
@@ -78,8 +99,13 @@ class TokenScannerViewController: UIViewController, QRScannerDelegate {
7899
messageView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
79100
messageView.frame = view.bounds
80101
messageView.isHidden = true
102+
messageView.addTarget(self, action: #selector(TokenScannerViewController.editPermissions), for: .touchUpInside)
81103
view.addSubview(messageView)
82104

105+
permissionLabel.autoresizingMask = [.flexibleWidth, .flexibleHeight]
106+
permissionLabel.frame = messageView.bounds.insetBy(dx: 35, dy: 35)
107+
messageView.addSubview(permissionLabel)
108+
83109
if CommandLine.isDemo {
84110
// If this is a demo, display an image in place of the AVCaptureVideoPreviewLayer.
85111
let imageView = UIImageView(frame: view.bounds)
@@ -90,6 +116,7 @@ class TokenScannerViewController: UIViewController, QRScannerDelegate {
90116
}
91117

92118
let overlayView = ScannerOverlayView(frame: view.bounds)
119+
overlayView.isUserInteractionEnabled = false
93120
view.addSubview(overlayView)
94121
}
95122

@@ -141,6 +168,12 @@ class TokenScannerViewController: UIViewController, QRScannerDelegate {
141168
dispatchAction(.beginManualTokenEntry)
142169
}
143170

171+
func editPermissions() {
172+
if let applicationSettingsURL = URL(string: UIApplicationOpenSettingsURLString) {
173+
UIApplication.shared.openURL(applicationSettingsURL)
174+
}
175+
}
176+
144177
// MARK: QRScannerDelegate
145178

146179
func handleDecodedText(_ text: String) {

0 commit comments

Comments
 (0)