Path: blob/main/Signal/src/ViewControllers/AppSettings/Payments/PaymentsDeactivateViewController.swift
1 views
//
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
public import SignalUI
public class PaymentsDeactivateViewController: OWSViewController {
var paymentBalance: PaymentBalance
public init(paymentBalance: PaymentBalance) {
owsAssertDebug(paymentBalance.amount.isValidAmount(canBeEmpty: false))
self.paymentBalance = paymentBalance
super.init()
}
override public func viewDidLoad() {
super.viewDidLoad()
title = OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATE_TITLE",
comment: "Label for the 'de-activate payments' view of the app settings.",
)
navigationItem.leftBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .done,
target: self,
action: #selector(didTapDismiss),
accessibilityIdentifier: "dismiss",
)
addListeners()
updateContents()
}
override public func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
SUIEnvironment.shared.paymentsSwiftRef.updateCurrentPaymentBalance()
}
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
updateContents()
}
override public func themeDidChange() {
super.themeDidChange()
updateContents()
}
private func addListeners() {
NotificationCenter.default.addObserver(
self,
selector: #selector(arePaymentsEnabledDidChange),
name: PaymentsConstants.arePaymentsEnabledDidChange,
object: nil,
)
NotificationCenter.default.addObserver(
self,
selector: #selector(currentPaymentBalanceDidChange),
name: PaymentsImpl.currentPaymentBalanceDidChange,
object: nil,
)
}
@objc
private func arePaymentsEnabledDidChange() {
Logger.info("")
dismiss(animated: true, completion: nil)
}
@objc
private func currentPaymentBalanceDidChange() {
guard
let currentPaymentBalance = SUIEnvironment.shared.paymentsSwiftRef.currentPaymentBalance,
currentPaymentBalance.amount.isValidAmount(canBeEmpty: false)
else {
// We need to abort the "deactivate payments with outstanding balance"
// flow if:
//
// * The balance becomes unavailable (this should never happen).
// * The balance becomes zero (this should be extremely rare).
Logger.warn("Missing or empty balance.")
dismiss(animated: true, completion: nil)
return
}
self.paymentBalance = currentPaymentBalance
self.updateContents()
}
private func updateContents() {
let backgroundColor = OWSTableViewController2.tableBackgroundColor(isUsingPresentedStyle: true)
view.backgroundColor = backgroundColor
view.removeAllSubviews()
let titleLabel = UILabel()
titleLabel.font = UIFont.regularFont(ofSize: 54)
titleLabel.textColor = Theme.primaryTextColor
titleLabel.attributedText = PaymentsFormat.attributedFormat(
paymentAmount: paymentBalance.amount,
isShortForm: false,
)
titleLabel.adjustsFontSizeToFitWidth = true
titleLabel.textAlignment = .center
let subtitleLabel = UILabel()
subtitleLabel.text = OWSLocalizedString(
"SETTINGS_PAYMENTS_REMAINING_BALANCE",
comment: "Label for the current balance in the 'deactivate payments' settings.",
)
subtitleLabel.font = .dynamicTypeBodyClamped
subtitleLabel.textColor = Theme.secondaryTextAndIconColor
subtitleLabel.textAlignment = .center
let explanationLabel = PaymentsViewUtils.buildTextWithLearnMoreLinkTextView(
text: OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATE_WITH_BALANCE_EXPLANATION",
comment: "Explanation of the 'deactivate payments with balance' process in the 'deactivate payments' settings.",
),
font: .dynamicTypeSubheadlineClamped,
learnMoreUrl: URL.Support.Payments.deactivate,
)
explanationLabel.backgroundColor = backgroundColor
explanationLabel.textAlignment = .center
let transferBalanceButton = OWSFlatButton.button(
title: OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATE_AFTER_TRANSFERRING_BALANCE",
comment: "Label for 'transfer balance' button in the 'deactivate payments' settings.",
),
font: UIFont.dynamicTypeHeadline,
titleColor: .white,
backgroundColor: .ows_accentBlue,
target: self,
selector: #selector(didTapTransferBalanceButton),
)
transferBalanceButton.autoSetHeightUsingFont()
let deactivateImmediatelyButton = OWSFlatButton.button(
title: OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATE_WITHOUT_TRANSFERRING_BALANCE",
comment: "Label for 'deactivate payments without transferring balance' button in the 'deactivate payments' settings.",
),
font: UIFont.dynamicTypeHeadline,
titleColor: .ows_accentRed,
backgroundColor: backgroundColor,
target: self,
selector: #selector(didTapDeactivateImmediatelyButton),
)
deactivateImmediatelyButton.autoSetHeightUsingFont()
let topStack = UIStackView(arrangedSubviews: [
titleLabel,
UIView.spacer(withHeight: 8),
subtitleLabel,
UIView.spacer(withHeight: 44),
explanationLabel,
])
topStack.axis = .vertical
topStack.alignment = .center
topStack.isLayoutMarginsRelativeArrangement = true
topStack.layoutMargins = UIEdgeInsets(hMargin: 20, vMargin: 0)
let stackView = UIStackView(arrangedSubviews: [
UIView.spacer(withHeight: 40),
topStack,
UIView.vStretchingSpacer(),
transferBalanceButton,
UIView.spacer(withHeight: 8),
deactivateImmediatelyButton,
UIView.spacer(withHeight: 8),
])
stackView.axis = .vertical
stackView.alignment = .fill
view.addSubview(stackView)
stackView.autoPinWidthToSuperviewMargins()
stackView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
stackView.autoPin(toBottomLayoutGuideOf: self, withInset: 0)
}
// MARK: - Events
@objc
private func didTapTransferBalanceButton() {
ModalActivityIndicatorViewController.present(
fromViewController: self,
canCancel: false,
asyncBlock: { modalActivityIndicator in
do {
let transferAmount = try await SUIEnvironment.shared.paymentsSwiftRef.maximumPaymentAmount()
modalActivityIndicator.dismiss {
guard let navigationController = self.navigationController else {
owsFailDebug("Missing navigationController.")
return
}
let view = PaymentsTransferOutViewController(transferAmount: transferAmount)
navigationController.pushViewController(view, animated: true)
}
} catch {
owsFailDebug("Error: \(error)")
modalActivityIndicator.dismiss {
OWSActionSheets.showErrorAlert(message: OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATION_FAILED",
comment: "Error indicating that payments could not be deactivated in the payments settings.",
))
}
}
},
)
}
@objc
private func didTapDeactivateImmediatelyButton() {
let actionSheet = ActionSheetController(
title: OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATE_WITHOUT_TRANSFER_CONFIRM_TITLE",
comment: "Title for the 'deactivate payments confirmation' UI in the payment settings.",
),
message: OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATE_WITHOUT_TRANSFER_CONFIRM_DESCRIPTION",
comment: "Description for the 'deactivate payments confirmation' UI in the payment settings.",
),
)
actionSheet.addAction(ActionSheetAction(
title: OWSLocalizedString(
"SETTINGS_PAYMENTS_DEACTIVATE_BUTTON",
comment: "Label for the 'deactivate payments' button in the payment settings.",
),
style: .destructive,
) { [weak self] _ in
self?.deactivateImmediately()
})
actionSheet.addAction(OWSActionSheets.cancelAction)
presentActionSheet(actionSheet)
}
private func deactivateImmediately() {
dismiss(animated: true) {
SSKEnvironment.shared.databaseStorageRef.write { transaction in
SSKEnvironment.shared.paymentsHelperRef.disablePayments(transaction: transaction)
}
}
}
@objc
private func didTapDismiss() {
dismiss(animated: true, completion: nil)
}
}