session-ios/SessionShareExtension/SAEScreenLockViewController...

194 lines
6.3 KiB
Swift

// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import UIKit
import SignalCoreKit
import SignalUtilitiesKit
import SessionUIKit
import SessionUtilitiesKit
import SignalCoreKit
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(),
body: .text(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()
}
}