Signal-iOS/Signal/Registration/UserInterface/RegistrationPermissionsViewController.swift
2024-03-25 13:26:31 -05:00

181 lines
6.3 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Lottie
import SignalCoreKit
import SignalUI
// MARK: - RegistrationPermissionsState
public struct RegistrationPermissionsState: Equatable {
let shouldRequestAccessToContacts: Bool
}
// MARK: - RegistrationPermissionsPresenter
protocol RegistrationPermissionsPresenter: AnyObject {
func requestPermissions() -> Guarantee<Void>
}
// MARK: - RegistrationPermissionsViewController
class RegistrationPermissionsViewController: OWSViewController {
private let state: RegistrationPermissionsState
private weak var presenter: RegistrationPermissionsPresenter?
public init(
state: RegistrationPermissionsState,
presenter: RegistrationPermissionsPresenter?
) {
self.state = state
self.presenter = presenter
super.init()
}
@available(*, unavailable)
public override init() {
owsFail("This should not be called")
}
// MARK: Rendering
private lazy var animationView: AnimationView = {
let animationView = AnimationView(name: "notificationPermission")
animationView.loopMode = .playOnce
animationView.backgroundBehavior = .pauseAndRestore
animationView.contentMode = .scaleAspectFit
return animationView
}()
private var giveAccessButton: OWSFlatButton?
public override func viewDidLoad() {
super.viewDidLoad()
navigationItem.setHidesBackButton(true, animated: false)
view.backgroundColor = Theme.backgroundColor
let scrollView = UIScrollView()
view.addSubview(scrollView)
scrollView.autoPinEdgesToSuperviewEdges()
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .fill
stackView.layoutMargins = UIEdgeInsets.layoutMarginsForRegistration(
traitCollection.horizontalSizeClass
)
stackView.isLayoutMarginsRelativeArrangement = true
stackView.setContentHuggingHigh()
scrollView.addSubview(stackView)
stackView.autoPinEdgesToSuperviewEdges()
stackView.autoMatch(
.width,
to: .width,
of: view,
withOffset: -view.layoutMargins.totalWidth,
relation: .equal
)
let heightConstraint = stackView.heightAnchor.constraint(
greaterThanOrEqualTo: view.layoutMarginsGuide.heightAnchor
)
heightConstraint.isActive = true
let titleText: String
let explanationText: String
let giveAccessText: String
if state.shouldRequestAccessToContacts {
titleText = OWSLocalizedString(
"ONBOARDING_PERMISSIONS_TITLE",
comment: "Title of the 'onboarding permissions' view."
)
explanationText = OWSLocalizedString(
"ONBOARDING_PERMISSIONS_EXPLANATION",
comment: "Explanation in the 'onboarding permissions' view."
)
giveAccessText = OWSLocalizedString(
"ONBOARDING_PERMISSIONS_ENABLE_PERMISSIONS_BUTTON",
comment: "Label for the 'give access' button in the 'onboarding permissions' view."
)
} else {
titleText = OWSLocalizedString(
"LINKED_ONBOARDING_PERMISSIONS_TITLE",
comment: "Title of the 'onboarding permissions' view."
)
explanationText = OWSLocalizedString(
"LINKED_ONBOARDING_PERMISSIONS_EXPLANATION",
comment: "Explanation in the 'onboarding permissions' view."
)
giveAccessText = OWSLocalizedString(
"LINKED_ONBOARDING_PERMISSIONS_ENABLE_PERMISSIONS_BUTTON",
comment: "Label for the 'give access' button in the 'onboarding permissions' view."
)
}
let titleLabel = UILabel.titleLabelForRegistration(text: titleText)
titleLabel.accessibilityIdentifier = "registration.permissions.titleLabel"
titleLabel.setCompressionResistanceVerticalHigh()
stackView.addArrangedSubview(titleLabel)
stackView.setCustomSpacing(20, after: titleLabel)
let explanationLabel = UILabel.explanationLabelForRegistration(text: explanationText)
explanationLabel.accessibilityIdentifier = "registration.permissions.explanationLabel"
explanationLabel.setCompressionResistanceVerticalHigh()
stackView.addArrangedSubview(explanationLabel)
stackView.setCustomSpacing(60, after: explanationLabel)
stackView.addArrangedSubview(animationView)
animationView.setContentHuggingHigh()
let animationSize = animationView.intrinsicContentSize
animationView.autoPin(toAspectRatio: animationSize.width / animationSize.height)
stackView.addArrangedSubview(UIView.vStretchingSpacer(minHeight: 60))
let giveAccessButton = OWSFlatButton.primaryButtonForRegistration(
title: giveAccessText,
target: self,
selector: #selector(giveAccessPressed)
)
giveAccessButton.accessibilityIdentifier = "registration.permissions.giveAccessButton"
stackView.addArrangedSubview(giveAccessButton)
giveAccessButton.autoHCenterInSuperview()
NSLayoutConstraint.autoSetPriority(.defaultLow) {
giveAccessButton.autoPinEdge(toSuperviewEdge: .leading)
giveAccessButton.autoPinEdge(toSuperviewEdge: .trailing)
}
NSLayoutConstraint.autoSetPriority(.required) {
giveAccessButton.autoSetDimension(.width, toSize: 280, relation: .greaterThanOrEqual)
giveAccessButton.autoSetDimension(.height, toSize: 50, relation: .greaterThanOrEqual)
}
self.giveAccessButton = giveAccessButton
}
public override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
animationView.play()
}
// MARK: Events
@objc
private func giveAccessPressed() {
Logger.info("")
requestPermissions()
}
// MARK: Requesting permissions
private func requestPermissions() {
giveAccessButton?.setEnabled(false)
presenter?.requestPermissions().observe(on: DispatchQueue.main) { [weak self] _ in
self?.giveAccessButton?.setEnabled(true)
}
}
}