TM-SGNL-iOS/SignalShareExtension/SAEScreenLockViewController.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

143 lines
3.9 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
import SignalUI
final class SAEScreenLockViewController: ScreenLockViewController {
private weak var shareViewDelegate: ShareViewDelegate?
init(shareViewDelegate: ShareViewDelegate) {
self.shareViewDelegate = shareViewDelegate
super.init(nibName: nil, bundle: nil)
delegate = self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - UIViewController
override func loadView() {
super.loadView()
view.backgroundColor = Theme.launchScreenBackgroundColor
title = OWSLocalizedString("SHARE_EXTENSION_VIEW_TITLE", comment: "Title for the 'share extension' view.")
navigationItem.leftBarButtonItem = .systemItem(.stop) { [weak self] in
Logger.debug("tapped dismiss share button")
self?.cancelShareExperience()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
ensureUI()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
ensureUI()
if !hasShownAuthUIOnce {
hasShownAuthUIOnce = true
tryToPresentAuthUIToUnlockScreenLock()
}
}
// MARK: - Lock Screen UI
private var hasShownAuthUIOnce = false
private var isShowingAuthUI = false
private func ensureUI() {
updateUIWithState(.screenLock)
}
private func tryToPresentAuthUIToUnlockScreenLock() {
AssertIsOnMainThread()
guard !isShowingAuthUI else { return }
isShowingAuthUI = true
ScreenLock.shared.tryToUnlockScreenLock(
success: {
AssertIsOnMainThread()
Logger.info("unlock screen lock succeeded.")
self.isShowingAuthUI = false
self.shareViewDelegate?.shareViewWasUnlocked()
},
failure: { error in
AssertIsOnMainThread()
Logger.info("unlock screen lock failed.")
self.isShowingAuthUI = false
self.ensureUI()
self.showScreenLockFailureAlertWithMessage(error.userErrorDescription)
},
unexpectedFailure: { error in
AssertIsOnMainThread()
Logger.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: {
AssertIsOnMainThread()
Logger.info("unlock screen lock cancelled.")
self.isShowingAuthUI = false
self.ensureUI()
}
)
ensureUI()
}
private func showScreenLockFailureAlertWithMessage(_ message: String) {
AssertIsOnMainThread()
OWSActionSheets.showActionSheet(
title: OWSLocalizedString(
"SCREEN_LOCK_UNLOCK_FAILED",
comment: "Title for alert indicating that screen lock could not be unlocked."
),
buttonAction: { _ in
// After the alert, update the UI.
self.ensureUI()
},
fromViewController: self
)
}
private func cancelShareExperience() {
shareViewDelegate?.shareViewWasCancelled()
}
}
extension SAEScreenLockViewController: ScreenLockViewDelegate {
func unlockButtonWasTapped() {
AssertIsOnMainThread()
Logger.info("unlockButtonWasTapped")
tryToPresentAuthUIToUnlockScreenLock()
}
}