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.
		
		
		
		
		
			
		
			
				
	
	
		
			194 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			194 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Swift
		
	
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
 | 
						|
 | 
						|
import UIKit
 | 
						|
import PromiseKit
 | 
						|
import SignalCoreKit
 | 
						|
import SignalUtilitiesKit
 | 
						|
import SessionUIKit
 | 
						|
import SessionUtilitiesKit
 | 
						|
 | 
						|
final class SAEScreenLockViewController: ScreenLockViewController {
 | 
						|
    private var hasShownAuthUIOnce: Bool = false
 | 
						|
    private var isShowingAuthUI: Bool = false
 | 
						|
    
 | 
						|
    private weak var shareViewDelegate: ShareViewDelegate?
 | 
						|
    
 | 
						|
    // MARK: - Initialization
 | 
						|
    
 | 
						|
    init(shareViewDelegate: ShareViewDelegate) {
 | 
						|
        super.init()
 | 
						|
        
 | 
						|
        self.onUnlockPressed = { [weak self] in self?.unlockButtonWasTapped() }
 | 
						|
        self.shareViewDelegate = shareViewDelegate
 | 
						|
    }
 | 
						|
    
 | 
						|
    required init?(coder aDecoder: NSCoder) {
 | 
						|
        fatalError("init(coder:) has not been implemented")
 | 
						|
    }
 | 
						|
    
 | 
						|
    deinit {
 | 
						|
        OWSLogger.verbose("Dealloc: \(type(of: self))")
 | 
						|
    }
 | 
						|
    
 | 
						|
    // MARK: - UI
 | 
						|
    
 | 
						|
    private lazy var titleLabel: UILabel = {
 | 
						|
        let titleLabel: UILabel = UILabel()
 | 
						|
        titleLabel.font = UIFont.boldSystemFont(ofSize: Values.veryLargeFontSize)
 | 
						|
        titleLabel.text = "vc_share_title".localized()
 | 
						|
        titleLabel.themeTextColor = .textPrimary
 | 
						|
        
 | 
						|
        return titleLabel
 | 
						|
    }()
 | 
						|
    
 | 
						|
    private lazy var closeButton: UIBarButtonItem = {
 | 
						|
        let closeButton: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "X"), style: .plain, target: self, action: #selector(dismissPressed))
 | 
						|
        closeButton.themeTintColor = .textPrimary
 | 
						|
        
 | 
						|
        return closeButton
 | 
						|
    }()
 | 
						|
    
 | 
						|
    // MARK: - Lifecycle
 | 
						|
    
 | 
						|
    public override func loadView() {
 | 
						|
        super.loadView()
 | 
						|
        
 | 
						|
        UIView.appearance().themeTintColor = .textPrimary
 | 
						|
        
 | 
						|
        self.view.themeBackgroundColor = .backgroundPrimary
 | 
						|
        self.navigationItem.titleView = titleLabel
 | 
						|
        self.navigationItem.leftBarButtonItem = closeButton
 | 
						|
        
 | 
						|
        ThemeManager.onThemeChange(observer: self.unlockButton) { [weak self] theme, _ in
 | 
						|
            switch theme.interfaceStyle {
 | 
						|
                case .light:
 | 
						|
                    self?.unlockButton.setThemeTitleColorForced(.theme(theme, color: .textPrimary), for: .normal)
 | 
						|
                    self?.unlockButton.setThemeBackgroundColorForced(
 | 
						|
                        .theme(theme, color: .textPrimary),
 | 
						|
                        for: .highlighted
 | 
						|
                    )
 | 
						|
                    self?.unlockButton.themeBorderColorForced = .theme(theme, color: .textPrimary)
 | 
						|
                    
 | 
						|
                default:
 | 
						|
                    self?.unlockButton.setThemeTitleColorForced(.primary(.green), for: .normal)
 | 
						|
                    self?.unlockButton.setThemeBackgroundColorForced(
 | 
						|
                        .primary(.green, alpha: 0.3),
 | 
						|
                        for: .highlighted
 | 
						|
                    )
 | 
						|
                    self?.unlockButton.themeBorderColorForced = .primary(.green)
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    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: - 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
 | 
						|
        
 | 
						|
        ScreenLock.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(state: .lock, animated: false)
 | 
						|
    }
 | 
						|
    
 | 
						|
    private func showScreenLockFailureAlert(message: String) {
 | 
						|
        AssertIsOnMainThread()
 | 
						|
        
 | 
						|
        let modal: ConfirmationModal = ConfirmationModal(
 | 
						|
            targetView: self.view,
 | 
						|
            info: ConfirmationModal.Info(
 | 
						|
                title: "SCREEN_LOCK_UNLOCK_FAILED".localized(),
 | 
						|
                explanation: message,
 | 
						|
                cancelTitle: "BUTTON_OK".localized(),
 | 
						|
                cancelStyle: .alert_text,
 | 
						|
                afterClosed: { [weak self] in self?.ensureUI() } // After the alert, update the UI
 | 
						|
            )
 | 
						|
        )
 | 
						|
        self.present(modal, animated: true)
 | 
						|
    }
 | 
						|
    
 | 
						|
    func unlockButtonWasTapped() {
 | 
						|
        AssertIsOnMainThread()
 | 
						|
        OWSLogger.info("unlockButtonWasTapped")
 | 
						|
        
 | 
						|
        self.tryToPresentAuthUIToUnlockScreenLock()
 | 
						|
    }
 | 
						|
    
 | 
						|
    // MARK: - Transitions
 | 
						|
    
 | 
						|
    @objc private func dismissPressed() {
 | 
						|
        OWSLogger.debug("unlock screen lock cancelled.")
 | 
						|
        
 | 
						|
        self.cancelShareExperience()
 | 
						|
    }
 | 
						|
 | 
						|
    private func cancelShareExperience() {
 | 
						|
        self.shareViewDelegate?.shareViewWasCancelled()
 | 
						|
    }
 | 
						|
}
 |