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.
session-ios/SignalUtilitiesKit/Screen Lock/ScreenLockViewController.swift

119 lines
4.0 KiB
Swift

// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import UIKit
import SessionUIKit
open class ScreenLockViewController: UIViewController {
public enum State {
case none
/// Shown while app is inactive or background, if enabled.
case protection
/// Shown while app is active, if enabled.
case lock
}
public override var preferredStatusBarStyle: UIStatusBarStyle {
return ThemeManager.currentTheme.statusBarStyle
}
public override var canBecomeFirstResponder: Bool { true }
public var onUnlockPressed: (() -> ())?
private var screenBlockingSignature: String?
// MARK: - UI
private let logoView: UIImageView = {
let result: UIImageView = UIImageView(image: #imageLiteral(resourceName: "SessionGreen64"))
result.contentMode = .scaleAspectFit
result.isHidden = true
return result
}()
public lazy var unlockButton: SessionButton = {
let result: SessionButton = SessionButton(style: .bordered, size: .medium)
result.translatesAutoresizingMaskIntoConstraints = false
result.setTitle("Unlock Session", for: .normal)
result.addTarget(self, action: #selector(showUnlockUI), for: .touchUpInside)
result.isHidden = true
// Need to match the launch screen so force the styling to be the primary green
result.setThemeTitleColorForced(.primary(.green), for: .normal)
result.setThemeBackgroundColorForced(.primary(.green), for: .highlighted)
result.themeBorderColorForced = .primary(.green)
return result
}()
// MARK: - Lifecycle
public init(onUnlockPressed: (() -> ())? = nil) {
self.onUnlockPressed = onUnlockPressed
super.init(nibName: nil, bundle: nil)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
open override func loadView() {
super.loadView()
view.themeBackgroundColorForced = .theme(.classicDark, color: .black) // Need to match the Launch screen
let edgesView: UIView = UIView.container()
self.view.addSubview(edgesView)
edgesView.pin(to: view)
edgesView.addSubview(logoView)
logoView.center(in: edgesView)
logoView.set(.width, to: 64)
logoView.set(.height, to: 64)
edgesView.addSubview(unlockButton)
unlockButton.pin(.top, to: .bottom, of: logoView, withInset: Values.mediumSpacing)
unlockButton.center(.horizontal, in: view)
updateUI(state: .protection, animated: false)
}
/// The "screen blocking" window has three possible states:
///
/// * "Just a logo". Used when app is launching and in app switcher. Must match the "Launch Screen" storyboard pixel-for-pixel.
/// * "Screen Lock, local auth UI presented". Must match the "Launch Screen" storyboard pixel-for-pixel.
/// * "Screen Lock, local auth UI not presented". Show "unlock" button.
public func updateUI(state: State, animated: Bool) {
guard isViewLoaded else { return }
let shouldShowBlockWindow: Bool = (state != .none)
let shouldHaveScreenLock: Bool = (state == .lock)
self.logoView.isHidden = !shouldShowBlockWindow
let signature: String = String(format: "%d", shouldHaveScreenLock)
// Skip redundant work to avoid interfering with ongoing animations
guard signature != self.screenBlockingSignature else { return }
self.unlockButton.isHidden = !shouldHaveScreenLock
self.screenBlockingSignature = signature
guard animated else {
self.view.setNeedsLayout()
return
}
UIView.animate(withDuration: 0.3) { [weak self] in
self?.view.layoutIfNeeded()
}
}
@objc private func showUnlockUI() {
self.onUnlockPressed?()
}
}