Signal-iOS/Signal/Registration/UserInterface/RegistrationEnterAccountEntropyPoolViewController.swift
2025-09-23 14:11:59 -05:00

165 lines
5.5 KiB
Swift

//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SafariServices
import SignalServiceKit
import SignalUI
import SwiftUI
protocol RegistrationEnterAccountEntropyPoolPresenter: AnyObject {
func next(accountEntropyPool: AccountEntropyPool)
func cancelKeyEntry()
func forgotKeyAction()
}
public struct RegistrationEnterAccountEntropyPoolState: Equatable {
let canShowBackButton: Bool
}
class RegistrationEnterAccountEntropyPoolViewController: EnterAccountEntropyPoolViewController {
private weak var presenter: RegistrationEnterAccountEntropyPoolPresenter?
private let state: RegistrationEnterAccountEntropyPoolState
init(
state: RegistrationEnterAccountEntropyPoolState,
presenter: RegistrationEnterAccountEntropyPoolPresenter,
aepValidationPolicy: AEPValidationPolicy = .acceptAnyWellFormed
) {
self.state = state
self.presenter = presenter
super.init()
var footerButtonConfig = FooterButtonConfig(
title: OWSLocalizedString(
"REGISTRATION_NO_BACKUP_KEY_BUTTON_TITLE",
comment: "Title of button to tap if you do not have a recovery key during registration."
),
action: { [weak self] in
self?.didTapNoKeyButton()
},
)
switch(aepValidationPolicy) {
case .acceptAnyWellFormed:
break
case .acceptOnly(_):
footerButtonConfig = FooterButtonConfig(
title: OWSLocalizedString(
"BACKUP_KEY_REMINDER_FORGOT_KEY",
comment: "Title of button to tap if you forgot your recovery key."
),
action: {
presenter.forgotKeyAction()
},
)
}
configure(
aepValidationPolicy: aepValidationPolicy,
colorConfig: ColorConfig(
background: UIColor.Signal.background,
aepEntryBackground: UIColor.Signal.quaternaryFill,
),
headerStrings: HeaderStrings(
title: OWSLocalizedString(
"REGISTRATION_ENTER_BACKUP_KEY_TITLE",
comment: "Title for the screen that allows users to enter their recovery key."
),
subtitle: OWSLocalizedString(
"REGISTRATION_ENTER_BACKUP_KEY_DESCRIPTION",
comment: "Description for the screen that allows users to enter their recovery key."
)
),
footerButtonConfig: footerButtonConfig,
onEntryConfirmed: { [weak self] aep in
self?.presenter?.next(accountEntropyPool: aep)
},
)
if state.canShowBackButton {
navigationItem.leftBarButtonItem = .button(title: CommonStrings.backButton, style: .done) { [weak self] in
self?.presenter?.cancelKeyEntry()
}
} else {
navigationItem.hidesBackButton = true
}
}
// MARK: OWSNavigationChildController
public var preferredNavigationBarStyle: OWSNavigationBarStyle { .solid }
public var navbarBackgroundColorOverride: UIColor? { .clear }
// MARK: UI
private func didTapNoKeyButton() {
let sheet = HeroSheetViewController(
hero: .circleIcon(
icon: UIImage(named: "key")!,
iconSize: 35,
tintColor: UIColor.Signal.label,
backgroundColor: UIColor.Signal.background
),
title: OWSLocalizedString(
"REGISTRATION_NO_BACKUP_KEY_SHEET_TITLE",
comment: "Title for sheet with info for what to do if you don't have a recovery key"
),
body: OWSLocalizedString(
"REGISTRATION_NO_BACKUP_KEY_SHEET_BODY",
comment: "Body text on a sheet with info for what to do if you don't have a recovery key"
),
primaryButton: .init(title: OWSLocalizedString(
"REGISTRATION_NO_BACKUP_KEY_SKIP_RESTORE_BUTTON_TITLE",
comment: "Title for button on sheet for when you don't have a recovery key"
)) { [weak self] _ in
self?.dismiss(animated: true) {
self?.presenter?.forgotKeyAction()
}
},
secondaryButton: .init(title: CommonStrings.learnMore, style: .secondary, action: .custom({ [weak self] sheet in
guard let self else { return }
let vc = SFSafariViewController(url: URL.Support.backups)
self.dismiss(animated: true) {
self.present(vc, animated: true, completion: nil)
}
}))
)
self.present(sheet, animated: true)
}
}
// MARK: -
#if DEBUG
private class PreviewRegistrationEnterAccountEntropyPoolPresenter: RegistrationEnterAccountEntropyPoolPresenter {
func next(accountEntropyPool: AccountEntropyPool) {
print("next")
}
func cancelKeyEntry() {
print("cancel")
}
func forgotKeyAction() {
print("forgotKeyAction")
}
}
@available(iOS 17, *)
#Preview {
let presenter = PreviewRegistrationEnterAccountEntropyPoolPresenter()
return UINavigationController(
rootViewController: RegistrationEnterAccountEntropyPoolViewController(
state: RegistrationEnterAccountEntropyPoolState(canShowBackButton: true),
presenter: presenter
)
)
}
#endif