mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			207 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Swift
		
	
		
		
			
		
	
	
			207 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Swift
		
	
| 
											4 years ago
										 | // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. | ||
|  | 
 | ||
|  | import UIKit | ||
|  | import PromiseKit | ||
|  | import SignalCoreKit | ||
|  | import SignalUtilitiesKit | ||
|  | import SessionUIKit | ||
|  | import SessionUtilitiesKit | ||
|  | 
 | ||
|  | final class SAEScreenLockViewController: ScreenLockViewController, ScreenLockViewDelegate { | ||
|  |     private var hasShownAuthUIOnce: Bool = false | ||
|  |     private var isShowingAuthUI: Bool = false | ||
|  |      | ||
|  |     private weak var shareViewDelegate: ShareViewDelegate? | ||
|  |      | ||
|  |     // MARK: - Initialization | ||
|  |      | ||
|  |     init(shareViewDelegate: ShareViewDelegate) { | ||
|  |         super.init(nibName: nil, bundle: nil) | ||
|  |          | ||
|  |         self.shareViewDelegate = shareViewDelegate | ||
|  |         self.delegate = self | ||
|  |     } | ||
|  |      | ||
|  |     required init?(coder aDecoder: NSCoder) { | ||
|  |         fatalError("init(coder:) has not been implemented") | ||
|  |     } | ||
|  |      | ||
|  |     deinit { | ||
|  |         OWSLogger.verbose("Dealloc: \(type(of: self))") | ||
|  |     } | ||
|  |      | ||
|  |     // MARK: - UI | ||
|  |      | ||
|  |     private lazy var gradientBackground: CAGradientLayer = { | ||
|  |         let layer: CAGradientLayer = CAGradientLayer() | ||
|  |          | ||
|  |         let gradientStartColor: UIColor = (LKAppModeUtilities.isLightMode ? | ||
|  |             UIColor(rgbHex: 0xFCFCFC) : | ||
|  |             UIColor(rgbHex: 0x171717) | ||
|  |         ) | ||
|  |         let gradientEndColor: UIColor = (LKAppModeUtilities.isLightMode ? | ||
|  |             UIColor(rgbHex: 0xFFFFFF) : | ||
|  |             UIColor(rgbHex: 0x121212) | ||
|  |         ) | ||
|  |         layer.colors = [gradientStartColor.cgColor, gradientEndColor.cgColor] | ||
|  |          | ||
|  |         return layer | ||
|  |     }() | ||
|  |      | ||
|  |     private lazy var titleLabel: UILabel = { | ||
|  |         let titleLabel: UILabel = UILabel() | ||
|  |         titleLabel.font = UIFont.boldSystemFont(ofSize: Values.veryLargeFontSize) | ||
|  |         titleLabel.text = "vc_share_title".localized() | ||
|  |         titleLabel.textColor = Colors.text | ||
|  |          | ||
|  |         return titleLabel | ||
|  |     }() | ||
|  |      | ||
|  |     private lazy var closeButton: UIBarButtonItem = { | ||
|  |         let closeButton: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "X"), style: .plain, target: self, action: #selector(dismissPressed)) | ||
|  |         closeButton.tintColor = Colors.text | ||
|  |          | ||
|  |         return closeButton | ||
|  |     }() | ||
|  |      | ||
|  |     // MARK: - Lifecycle | ||
|  |      | ||
|  |     override func loadView() { | ||
|  |         super.loadView() | ||
|  |          | ||
|  |         UIView.appearance().tintColor = Colors.text | ||
|  |          | ||
|  |         self.view.backgroundColor = UIColor.clear | ||
|  |         self.view.layer.insertSublayer(gradientBackground, at: 0) | ||
|  |          | ||
|  |         self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) | ||
|  |         self.navigationController?.navigationBar.shadowImage = UIImage() | ||
|  |         self.navigationController?.navigationBar.isTranslucent = false | ||
|  |         self.navigationController?.navigationBar.tintColor = Colors.navigationBarBackground | ||
|  |          | ||
|  |         self.navigationItem.titleView = titleLabel | ||
|  |         self.navigationItem.leftBarButtonItem = closeButton | ||
|  |          | ||
|  |         setupLayout() | ||
|  |     } | ||
|  |      | ||
|  |     override func viewWillAppear(_ animated: Bool) { | ||
|  |         super.viewWillAppear(animated) | ||
|  |          | ||
|  |         self.ensureUI() | ||
|  |     } | ||
|  |      | ||
|  |     override func viewDidAppear(_ animated: Bool) { | ||
|  |         super.viewDidAppear(animated) | ||
|  |          | ||
|  |         self.ensureUI() | ||
|  |          | ||
|  |         // Auto-show the auth UI f | ||
|  |         if !hasShownAuthUIOnce { | ||
|  |             hasShownAuthUIOnce = true | ||
|  |              | ||
|  |             self.tryToPresentAuthUIToUnlockScreenLock() | ||
|  |         } | ||
|  |     } | ||
|  |      | ||
|  |     // MARK: - Layout | ||
|  |      | ||
|  |     private func setupLayout() { | ||
|  |         gradientBackground.frame = UIScreen.main.bounds | ||
|  |     } | ||
|  |      | ||
|  |     // MARK: - Functions | ||
|  |      | ||
|  |     private func tryToPresentAuthUIToUnlockScreenLock() { | ||
|  |         AssertIsOnMainThread() | ||
|  | 
 | ||
|  |         // If we're already showing the auth UI; abort. | ||
|  |         if self.isShowingAuthUI { return } | ||
|  |          | ||
|  |         OWSLogger.info("try to unlock screen lock") | ||
|  | 
 | ||
|  |         isShowingAuthUI = true | ||
|  |          | ||
|  |         OWSScreenLock.shared.tryToUnlockScreenLock( | ||
|  |             success: { [weak self] in | ||
|  |                 AssertIsOnMainThread() | ||
|  |                 OWSLogger.info("unlock screen lock succeeded.") | ||
|  |                  | ||
|  |                 self?.isShowingAuthUI = false | ||
|  |                 self?.shareViewDelegate?.shareViewWasUnlocked() | ||
|  |             }, | ||
|  |             failure: { [weak self] error in | ||
|  |                 AssertIsOnMainThread() | ||
|  |                 OWSLogger.info("unlock screen lock failed.") | ||
|  |                  | ||
|  |                 self?.isShowingAuthUI = false | ||
|  |                 self?.ensureUI() | ||
|  |                 self?.showScreenLockFailureAlert(message: error.localizedDescription) | ||
|  |             }, | ||
|  |             unexpectedFailure: { [weak self] error in | ||
|  |                 AssertIsOnMainThread() | ||
|  |                 OWSLogger.info("unlock screen lock unexpectedly failed.") | ||
|  |                  | ||
|  |                 self?.isShowingAuthUI = false | ||
|  |                  | ||
|  |                 // Local Authentication isn't working properly. | ||
|  |                 // This isn't covered by the docs or the forums but in practice | ||
|  |                 // it appears to be effective to retry again after waiting a bit. | ||
|  |                 DispatchQueue.main.async { | ||
|  |                     self?.ensureUI() | ||
|  |                 } | ||
|  |             }, | ||
|  |             cancel: { [weak self] in | ||
|  |                 AssertIsOnMainThread() | ||
|  |                 OWSLogger.info("unlock screen lock cancelled.") | ||
|  |                  | ||
|  |                 self?.isShowingAuthUI = false | ||
|  |                 self?.ensureUI() | ||
|  |             } | ||
|  |         ) | ||
|  |          | ||
|  |         self.ensureUI() | ||
|  |     } | ||
|  |      | ||
|  |     private func ensureUI() { | ||
|  |         self.updateUI(with: .screenLock, isLogoAtTop: false, animated: false) | ||
|  |     } | ||
|  |      | ||
|  |     private func showScreenLockFailureAlert(message: String) { | ||
|  |         AssertIsOnMainThread() | ||
|  |          | ||
|  |         OWSAlerts.showAlert( | ||
|  |             // Title for alert indicating that screen lock could not be unlocked. | ||
|  |             title: "SCREEN_LOCK_UNLOCK_FAILED".localized(), | ||
|  |             message: message, | ||
|  |             buttonTitle: nil, | ||
|  |             buttonAction: { [weak self] action in | ||
|  |                 // After the alert, update the UI | ||
|  |                 self?.ensureUI() | ||
|  |             }, | ||
|  |             fromViewController: self | ||
|  |         ) | ||
|  |     } | ||
|  |      | ||
|  |     // MARK: - Transitions | ||
|  |      | ||
|  |     @objc private func dismissPressed() { | ||
|  |         OWSLogger.debug("unlock screen lock cancelled.") | ||
|  |          | ||
|  |         self.cancelShareExperience() | ||
|  |     } | ||
|  | 
 | ||
|  |     private func cancelShareExperience() { | ||
|  |         self.shareViewDelegate?.shareViewWasCancelled() | ||
|  |     } | ||
|  | 
 | ||
|  |     // MARK: - ScreenLockViewDelegate | ||
|  |      | ||
|  |     func unlockButtonWasTapped() { | ||
|  |         AssertIsOnMainThread() | ||
|  |         OWSLogger.info("unlockButtonWasTapped") | ||
|  |          | ||
|  |         self.tryToPresentAuthUIToUnlockScreenLock() | ||
|  |     } | ||
|  | } |