Redirect the user to the in-app camera for Quick Restore scans

This commit is contained in:
Pete Walters 2025-12-10 18:22:42 -06:00 committed by GitHub
parent aa2992a85c
commit a5a8943e7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 97 additions and 15 deletions

View File

@ -105,6 +105,14 @@ extension SignalApp {
conversationSplitViewController.showAppSettingsWithMode(mode, completion: completion)
}
func showCameraCaptureView(completion: ((UINavigationController) -> Void)? = nil) {
guard let conversationSplitViewController else {
owsFailDebug("Missing conversationSplitViewController.")
return
}
conversationSplitViewController.showCameraView(completion: completion)
}
func showRegistration(
loader: RegistrationCoordinatorLoader,
desiredMode: RegistrationMode,

View File

@ -43,8 +43,8 @@ class OutgoingDeviceRestorePresenter: OutgoingDeviceRestoreInitialPresenter {
deviceProvisioningURL: provisioningURL
)
internalNavigationController.pushViewController(
OutgoingDeviceRestoreIntialViewController(presenter: self),
internalNavigationController.setViewControllers(
[OutgoingDeviceRestoreIntialViewController(presenter: self)],
animated: false
)

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"filename" : "phone_qr.pdf",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "phone_qr_dark 1.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Binary file not shown.

View File

@ -214,22 +214,44 @@ class UrlOpener {
linkDeviceWarningActionSheet.addAction(.cancel)
rootViewController.presentActionSheet(linkDeviceWarningActionSheet)
case .quickRestore(let url):
case .quickRestore:
let registeredState = try tsAccountManager.registeredStateWithMaybeSneakyTransaction()
guard registeredState.isPrimary else {
Logger.warn("Ignoring URL; not primary device.")
return
}
let provisioningURL = DeviceProvisioningURL(urlString: url.absoluteString)
if let provisioningURL {
AppEnvironment.shared.outgoingDeviceRestorePresenter.present(
provisioningURL: provisioningURL,
presentingViewController: CurrentAppContext().frontmostViewController()!,
animated: true
let quickRestoreWarningActionSheet = ActionSheetController(
message: OWSLocalizedString(
"QUICK_RESTORE_URL_OPENED_ACTION_SHEET_EXTERNAL_URL_MESSAGE",
comment: "Message for an action sheet telling users how to use quick restore, when trying to open an external quick restore URL."
)
)
let showCameraViewAction = ActionSheetAction(
title: CommonStrings.continueButton
) { _ in
SignalApp.shared.showCameraCaptureView { navController in
let sheet = HeroSheetViewController(
hero: .image(UIImage(named: "phone-qr")!),
title: OWSLocalizedString(
"QUICK_RESTORE_URL_OPENED_ACTION_SHEET_EXTERNAL_URL_ACTION_TITLE",
comment: "Title for sheet with info about scanning a Quick Restore QR code"
),
body: OWSLocalizedString(
"QUICK_RESTORE_URL_OPENED_ACTION_SHEET_EXTERNAL_URL_ACTION_BODY",
comment: "Body for sheet with info about scanning a Quick Restore QR code"
),
primaryButton: .dismissing(title: CommonStrings.okButton)
)
navController.topViewController?.present(sheet, animated: true)
}
}
quickRestoreWarningActionSheet.addAction(showCameraViewAction)
quickRestoreWarningActionSheet.addAction(.cancel)
rootViewController.presentActionSheet(quickRestoreWarningActionSheet)
case .completeIDEALDonation(let donationType):
_ = try tsAccountManager.registeredStateWithMaybeSneakyTransaction()
Task { [appReadiness, databaseStorage] in

View File

@ -10,6 +10,10 @@ extension ChatListViewController: CameraFirstCaptureDelegate {
@objc
func showCameraView() {
presentCameraView()
}
func presentCameraView(completion: ((UINavigationController) -> Void)? = nil) {
// Dismiss any message actions if they're presented
conversationSplitViewController?.selectedConversationViewController?.dismissMessageContextMenu(animated: true)
@ -39,6 +43,7 @@ extension ChatListViewController: CameraFirstCaptureDelegate {
cameraModal.modalPresentationCapturesStatusBarAppearance = true
cameraModal.setNeedsStatusBarAppearanceUpdate()
}
completion?(cameraModal)
})
}
}

View File

@ -562,6 +562,11 @@ class ConversationSplitViewController: UISplitViewController, ConversationSplit
homeVC.chatListViewController.showAppSettings()
}
@objc
func showCameraView(completion: ((UINavigationController) -> Void)? = nil) {
homeVC.chatListViewController.presentCameraView(completion: completion)
}
func showAppSettingsWithMode(_ mode: ChatListViewController.ShowAppSettingsMode, completion: (() -> Void)? = nil) {
homeVC.chatListViewController.showAppSettings(mode: mode, completion: completion)
}

View File

@ -1340,12 +1340,23 @@ extension PhotoCaptureViewController: QRCodeSampleBufferScannerDelegate {
linkDeviceWarningActionSheet.addAction(cancelAction)
presentActionSheet(linkDeviceWarningActionSheet)
case .quickRestore:
self.dismiss(animated: true) {
AppEnvironment.shared.outgoingDeviceRestorePresenter.present(
provisioningURL: provisioningURL,
presentingViewController: CurrentAppContext().frontmostViewController()!,
animated: true
)
let presentBlock = {
self.dismiss(animated: true) {
AppEnvironment.shared.outgoingDeviceRestorePresenter.present(
provisioningURL: provisioningURL,
presentingViewController: CurrentAppContext().frontmostViewController()!,
animated: true
)
}
}
// If anything is presented over the phone capture view, dismiss it first -
// then dismiss the photo view and present the restore UI
if navigationController?.presentedViewController != nil {
self.navigationController?.presentedViewController?.dismiss(animated: true) {
presentBlock()
}
} else {
presentBlock()
}
}
}

View File

@ -6889,6 +6889,15 @@
/* Title of alert shown when push tokens sync job succeeds. */
"PUSH_REGISTER_SUCCESS" = "Successfully re-registered for push notifications.";
/* Body for sheet with info about scanning a Quick Restore QR code */
"QUICK_RESTORE_URL_OPENED_ACTION_SHEET_EXTERNAL_URL_ACTION_BODY" = "Use this device to scan the QR code on the device you want to transfer to";
/* Title for sheet with info about scanning a Quick Restore QR code */
"QUICK_RESTORE_URL_OPENED_ACTION_SHEET_EXTERNAL_URL_ACTION_TITLE" = "Scan QR Code";
/* Message for an action sheet telling users how to use quick restore, when trying to open an external quick restore URL. */
"QUICK_RESTORE_URL_OPENED_ACTION_SHEET_EXTERNAL_URL_MESSAGE" = "To transfer this account to a new device, tap “Continue” and scan the QR code with the Signal camera. Make sure you only scan QR codes that come directly from Signal.";
/* Accessibility label stating the author of the message to which you are replying. Embeds: {{ the author of the message to which you are replying }}. */
"QUOTED_REPLY_ACCESSIBILITY_LABEL_FORMAT" = "Replying to %@.";