Signal-iOS/Signal/Provisioning/UserInterface/ProvisioningTransferQRCodeViewController.swift

197 lines
7.1 KiB
Swift

//
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import MultipeerConnectivity
import SignalServiceKit
import SignalUI
class ProvisioningTransferQRCodeViewController: ProvisioningBaseViewController {
private let qrCodeView = QRCodeView()
override func loadView() {
view = UIView()
view.addSubview(primaryView)
primaryView.autoPinEdgesToSuperviewEdges()
view.backgroundColor = Theme.backgroundColor
let titleLabel = self.createTitleLabel(
text: OWSLocalizedString("DEVICE_TRANSFER_QRCODE_TITLE",
comment: "The title for the device transfer qr code view")
)
primaryView.addSubview(titleLabel)
titleLabel.accessibilityIdentifier = "onboarding.transferQRCode.titleLabel"
titleLabel.setContentHuggingHigh()
let explanationLabel = self.createExplanationLabel(
explanationText: OWSLocalizedString("DEVICE_TRANSFER_QRCODE_EXPLANATION",
comment: "The explanation for the device transfer qr code view")
)
explanationLabel.accessibilityIdentifier = "onboarding.transferQRCode.bodyLabel"
explanationLabel.setContentHuggingHigh()
qrCodeView.setContentHuggingVerticalLow()
let explanationLabel2 = self.createExplanationLabel(
explanationText: OWSLocalizedString("DEVICE_TRANSFER_QRCODE_EXPLANATION2",
comment: "The second explanation for the device transfer qr code view")
)
explanationLabel2.setContentHuggingHigh()
let helpButton = self.linkButton(
title: OWSLocalizedString(
"DEVICE_TRANSFER_QRCODE_NOT_SEEING",
comment: "A prompt to provide further explanation if the user is not seeing the transfer on both devices."
),
selector: #selector(didTapHelp)
)
helpButton.button.titleLabel?.textAlignment = .center
helpButton.button.titleLabel?.numberOfLines = 0
helpButton.button.titleLabel?.lineBreakMode = .byWordWrapping
let cancelButton = self.linkButton(title: CommonStrings.cancelButton, selector: #selector(didTapCancel))
let stackView = UIStackView(arrangedSubviews: [
titleLabel,
explanationLabel,
qrCodeView,
explanationLabel2,
UIView.vStretchingSpacer(),
helpButton,
cancelButton
])
stackView.axis = .vertical
stackView.alignment = .fill
stackView.spacing = 12
primaryView.addSubview(stackView)
stackView.autoPinEdgesToSuperviewMargins()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
AppEnvironment.shared.deviceTransferServiceRef.addObserver(self)
do {
let url = try AppEnvironment.shared.deviceTransferServiceRef.startAcceptingTransfersFromOldDevices(
mode: .linked // TODO: .primary
)
qrCodeView.setQR(url: url)
} catch {
owsFailDebug("error \(error)")
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
AppEnvironment.shared.deviceTransferServiceRef.removeObserver(self)
AppEnvironment.shared.deviceTransferServiceRef.stopAcceptingTransfersFromOldDevices()
}
// MARK: - Events
weak var permissionActionSheetController: ActionSheetController?
@objc
private func didTapHelp() {
let turnOnView = TurnOnPermissionView(
title: OWSLocalizedString(
"LOCAL_NETWORK_PERMISSION_ACTION_SHEET_TITLE",
comment: "Title for local network permission action sheet"
),
message: OWSLocalizedString(
"LOCAL_NETWORK_PERMISSION_ACTION_SHEET_BODY",
comment: "Body for local network permission action sheet"
),
steps: [
.init(
icon: #imageLiteral(resourceName: "settings-app-icon-32"),
text: OWSLocalizedString(
"LOCAL_NETWORK_PERMISSION_ACTION_SHEET_STEP_ONE",
comment: "First step for local network permission action sheet"
)
),
.init(
icon: UIImage(resource: UIApplication.shared.currentAppIcon.previewImageResource),
text: OWSLocalizedString(
"LOCAL_NETWORK_PERMISSION_ACTION_SHEET_STEP_TWO",
comment: "Second step for local network permission action sheet"
)
),
.init(
icon: UIImage(imageLiteralResourceName: "toggle-32"),
text: OWSLocalizedString(
"LOCAL_NETWORK_PERMISSION_ACTION_SHEET_STEP_THREE",
comment: "Third step for local network permission action sheet"
)
)
],
button: primaryButton(
title: OWSLocalizedString(
"LOCAL_NETWORK_PERMISSION_ACTION_SHEET_NEED_HELP",
comment: "A button asking the user if they need further help getting their transfer working."
),
selector: #selector(didTapContactSupport)
)
)
let actionSheetController = ActionSheetController()
permissionActionSheetController = actionSheetController
actionSheetController.customHeader = turnOnView
actionSheetController.isCancelable = true
presentActionSheet(actionSheetController)
}
@objc
private func didTapCancel() {
Logger.info("")
guard let navigationController = navigationController else {
return owsFailDebug("unexpectedly missing nav controller")
}
provisioningController.pushTransferChoiceView(onto: navigationController)
}
@objc
private func didTapContactSupport() {
Logger.info("")
permissionActionSheetController?.dismiss(animated: true)
permissionActionSheetController = nil
ContactSupportAlert.presentStep2(
emailSupportFilter: "Signal iOS Transfer",
fromViewController: self
)
}
override func shouldShowBackButton() -> Bool {
// Never show the back button here
return false
}
}
extension ProvisioningTransferQRCodeViewController: DeviceTransferServiceObserver {
func deviceTransferServiceDiscoveredNewDevice(peerId: MCPeerID, discoveryInfo: [String: String]?) {}
func deviceTransferServiceDidStartTransfer(progress: Progress) {
provisioningController.accountTransferInProgress(fromViewController: self, progress: progress)
}
func deviceTransferServiceDidEndTransfer(error: DeviceTransferService.Error?) {
if let error = error {
owsFailDebug("unexpected error while rendering QR code \(error)")
}
}
func deviceTransferServiceDidRequestAppRelaunch() {
owsFail("Relaunch not supported for provisioning; only on the receiving device during transfer")
}
}