TM-SGNL-iOS/Signal/Registration/UserInterface/RegistrationSplashViewController.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

209 lines
7.8 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import PureLayout
import SafariServices
import SignalServiceKit
public import SignalUI
// MARK: - RegistrationSplashPresenter
public protocol RegistrationSplashPresenter: AnyObject {
func continueFromSplash()
func restoreOrTransfer()
func switchToDeviceLinkingMode()
func transferDevice()
}
// MARK: - RegistrationSplashViewController
public class RegistrationSplashViewController: OWSViewController {
private weak var presenter: RegistrationSplashPresenter?
public init(presenter: RegistrationSplashPresenter) {
self.presenter = presenter
super.init()
}
public override func viewDidLoad() {
super.viewDidLoad()
navigationItem.setHidesBackButton(true, animated: false)
view.backgroundColor = Theme.backgroundColor
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .fill
stackView.directionalLayoutMargins = {
let horizontalSizeClass = traitCollection.horizontalSizeClass
var result = NSDirectionalEdgeInsets.layoutMarginsForRegistration(horizontalSizeClass)
// We want the hero image a bit closer to the top.
result.top = 16
return result
}()
stackView.isLayoutMarginsRelativeArrangement = true
view.addSubview(stackView)
stackView.autoPinEdgesToSuperviewMargins()
let canSwitchModes = UIDevice.current.isIPad || FeatureFlags.linkedPhones
var transferButtonTrailingView: UIView = self.view
var transferButtonTrailingEdge: ALEdge = .trailing
if canSwitchModes {
let modeSwitchButton = UIButton()
modeSwitchButton.setTemplateImageName(
UIDevice.current.isIPad ? "link" : "link-slash",
tintColor: .ows_gray25
)
modeSwitchButton.addTarget(self, action: #selector(didTapModeSwitch), for: .touchUpInside)
modeSwitchButton.accessibilityIdentifier = "onboarding.splash.modeSwitch"
view.addSubview(modeSwitchButton)
modeSwitchButton.autoSetDimensions(to: CGSize(square: 40))
modeSwitchButton.autoPinEdge(toSuperviewMargin: .trailing)
modeSwitchButton.autoPinEdge(toSuperviewMargin: .top)
transferButtonTrailingEdge = .leading
transferButtonTrailingView = modeSwitchButton
}
if FeatureFlags.preRegDeviceTransfer {
let transferButton = UIButton()
transferButton.setImage(Theme.iconImage(.transfer), animated: false)
transferButton.addTarget(self, action: #selector(didTapTransfer), for: .touchUpInside)
transferButton.accessibilityIdentifier = "onboarding.splash.transfer"
view.addSubview(transferButton)
transferButton.autoSetDimensions(to: CGSize(square: 40))
transferButton.autoPinEdge(
.trailing,
to: transferButtonTrailingEdge,
of: transferButtonTrailingView
)
transferButton.autoPinEdge(toSuperviewMargin: .top)
}
let heroImage = UIImage(named: "onboarding_splash_hero")
let heroImageView = UIImageView(image: heroImage)
heroImageView.contentMode = .scaleAspectFit
heroImageView.layer.minificationFilter = .trilinear
heroImageView.layer.magnificationFilter = .trilinear
heroImageView.setCompressionResistanceLow()
heroImageView.setContentHuggingVerticalLow()
heroImageView.accessibilityIdentifier = "registration.splash.heroImageView"
stackView.addArrangedSubview(heroImageView)
stackView.setCustomSpacing(22, after: heroImageView)
let titleText = {
if TSConstants.isUsingProductionService {
return OWSLocalizedString(
"ONBOARDING_SPLASH_TITLE",
comment: "Title of the 'onboarding splash' view."
)
} else {
return "Internal Staging Build\n\(AppVersionImpl.shared.currentAppVersion)"
}
}()
let titleLabel = UILabel.titleLabelForRegistration(text: titleText)
titleLabel.accessibilityIdentifier = "registration.splash.titleLabel"
stackView.addArrangedSubview(titleLabel)
stackView.setCustomSpacing(12, after: titleLabel)
let explanationButton = UIButton()
explanationButton.setTitle(
OWSLocalizedString(
"ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY",
comment: "Link to the 'terms and privacy policy' in the 'onboarding splash' view."
),
for: .normal
)
explanationButton.setTitleColor(Theme.secondaryTextAndIconColor, for: .normal)
explanationButton.titleLabel?.font = UIFont.dynamicTypeBody2
explanationButton.titleLabel?.numberOfLines = 0
explanationButton.titleLabel?.textAlignment = .center
explanationButton.titleLabel?.lineBreakMode = .byWordWrapping
explanationButton.addTarget(
self,
action: #selector(explanationButtonTapped),
for: .touchUpInside
)
explanationButton.accessibilityIdentifier = "registration.splash.explanationLabel"
stackView.addArrangedSubview(explanationButton)
stackView.setCustomSpacing(57, after: explanationButton)
let continueButton = OWSFlatButton.primaryButtonForRegistration(
title: CommonStrings.continueButton,
target: self,
selector: #selector(continuePressed)
)
continueButton.accessibilityIdentifier = "registration.splash.continueButton"
stackView.addArrangedSubview(continueButton)
continueButton.autoSetDimension(.width, toSize: 280)
continueButton.autoHCenterInSuperview()
NSLayoutConstraint.autoSetPriority(.defaultLow) {
continueButton.autoPinEdge(toSuperviewEdge: .leading)
continueButton.autoPinEdge(toSuperviewEdge: .trailing)
}
if FeatureFlags.messageBackupQuickRestoreFlow {
stackView.setCustomSpacing(16, after: continueButton)
let restoreOrTransferButton = OWSFlatButton.secondaryButtonForRegistration(
title: OWSLocalizedString(
"ONBOARDING_SPLASH_RESTORE_OR_TRANSFER_BUTTON_TITLE",
comment: "Button for restoring or transferring account in the 'onboarding splash' view."
),
target: self,
selector: #selector(didTapRestoreOrTransfer)
)
restoreOrTransferButton.accessibilityIdentifier = "registration.splash.continueButton"
stackView.addArrangedSubview(restoreOrTransferButton)
restoreOrTransferButton.autoSetDimension(.width, toSize: 280)
restoreOrTransferButton.autoHCenterInSuperview()
NSLayoutConstraint.autoSetPriority(.defaultLow) {
restoreOrTransferButton.autoPinEdge(toSuperviewEdge: .leading)
restoreOrTransferButton.autoPinEdge(toSuperviewEdge: .trailing)
}
}
}
// MARK: - Events
@objc
private func didTapModeSwitch() {
Logger.info("")
presenter?.switchToDeviceLinkingMode()
}
@objc
private func didTapTransfer() {
Logger.info("")
presenter?.transferDevice()
}
@objc
private func explanationButtonTapped(sender: UIGestureRecognizer) {
let safariVC = SFSafariViewController(url: TSConstants.legalTermsUrl)
present(safariVC, animated: true)
}
@objc
private func continuePressed() {
Logger.info("")
presenter?.continueFromSplash()
}
@objc
private func didTapRestoreOrTransfer() {
Logger.info("")
presenter?.restoreOrTransfer()
}
}