Add outgoing device prompt if backup too old
This commit is contained in:
parent
4171b2fd07
commit
60d7270f80
@ -1789,6 +1789,7 @@
|
||||
C190F8F52C1B47E100D1EAC9 /* OWSOutgoingArchivedPaymentMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = C190F8F22C1B47E100D1EAC9 /* OWSOutgoingArchivedPaymentMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
C190F8F72C1B48BE00D1EAC9 /* OWSArchivedPaymentMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = C190F8F62C1B484A00D1EAC9 /* OWSArchivedPaymentMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
C1939F6F2A844E4D003BAEF0 /* SignalProtocolStoreMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1ED5C9E2A72DFC9009AD3FC /* SignalProtocolStoreMocks.swift */; };
|
||||
C197187D2EF9D28C002E4198 /* OutgoingDeviceRestoreBackupPromptViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C197187C2EF9D27E002E4198 /* OutgoingDeviceRestoreBackupPromptViewController.swift */; };
|
||||
C198FDD62A37C905000BCAC9 /* KyberPreKeyStoreImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C198FDD52A37C905000BCAC9 /* KyberPreKeyStoreImpl.swift */; };
|
||||
C1A0F79D2B9F57340009DC0D /* MessageRootBackupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A0F79C2B9F57340009DC0D /* MessageRootBackupKey.swift */; };
|
||||
C1A136C32DB044950049CD05 /* OutgoingDeviceRestorePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A136C22DB044950049CD05 /* OutgoingDeviceRestorePresenter.swift */; };
|
||||
@ -5943,6 +5944,7 @@
|
||||
C190F8F22C1B47E100D1EAC9 /* OWSOutgoingArchivedPaymentMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OWSOutgoingArchivedPaymentMessage.h; sourceTree = "<group>"; };
|
||||
C190F8F32C1B47E100D1EAC9 /* OWSOutgoingArchivedPaymentMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OWSOutgoingArchivedPaymentMessage.m; sourceTree = "<group>"; };
|
||||
C190F8F62C1B484A00D1EAC9 /* OWSArchivedPaymentMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OWSArchivedPaymentMessage.h; sourceTree = "<group>"; };
|
||||
C197187C2EF9D27E002E4198 /* OutgoingDeviceRestoreBackupPromptViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutgoingDeviceRestoreBackupPromptViewController.swift; sourceTree = "<group>"; };
|
||||
C198FDD52A37C905000BCAC9 /* KyberPreKeyStoreImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KyberPreKeyStoreImpl.swift; sourceTree = "<group>"; };
|
||||
C1A0F79C2B9F57340009DC0D /* MessageRootBackupKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRootBackupKey.swift; sourceTree = "<group>"; };
|
||||
C1A136C22DB044950049CD05 /* OutgoingDeviceRestorePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutgoingDeviceRestorePresenter.swift; sourceTree = "<group>"; };
|
||||
@ -10569,7 +10571,6 @@
|
||||
C17B31582D710DD80060664D /* ProvisioningManager+Shims.swift */,
|
||||
C17B31542D710DBD0060664D /* ProvisioningManager.swift */,
|
||||
C18087892D76023400B16D1E /* ProvisioningSocketManager.swift */,
|
||||
C1AE7C592D7B4451007A618D /* QuickRestoreManager.swift */,
|
||||
);
|
||||
path = Provisioning;
|
||||
sourceTree = "<group>";
|
||||
@ -11335,10 +11336,6 @@
|
||||
887CD47A247304B600FDD265 /* DeviceTransferService+URL.swift */,
|
||||
88C4E37F24635337009C9B97 /* DeviceTransferService.swift */,
|
||||
C147C1712D9C58D60026952D /* DeviceTransferStatusViewController.swift */,
|
||||
C14D475F2DAEC45C006178AC /* OutgoingDeviceRestoreInitialViewController.swift */,
|
||||
C1A136C22DB044950049CD05 /* OutgoingDeviceRestorePresenter.swift */,
|
||||
C14D47632DAEE351006178AC /* OutgoingDeviceRestoreProgressViewController.swift */,
|
||||
C1A136C42DB044A20049CD05 /* OutgoingDeviceRestoreViewModel.swift */,
|
||||
88C659AF24688335002AC115 /* SelfSignedIdentity.swift */,
|
||||
C1868F812DBAD04400DA512A /* TransferStatusState.swift */,
|
||||
);
|
||||
@ -11691,6 +11688,19 @@
|
||||
path = Upload;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C1F9F7D62F0FFFCD00FF3688 /* QuickRestore */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C197187C2EF9D27E002E4198 /* OutgoingDeviceRestoreBackupPromptViewController.swift */,
|
||||
C14D475F2DAEC45C006178AC /* OutgoingDeviceRestoreInitialViewController.swift */,
|
||||
C1A136C22DB044950049CD05 /* OutgoingDeviceRestorePresenter.swift */,
|
||||
C14D47632DAEE351006178AC /* OutgoingDeviceRestoreProgressViewController.swift */,
|
||||
C1A136C42DB044A20049CD05 /* OutgoingDeviceRestoreViewModel.swift */,
|
||||
C1AE7C592D7B4451007A618D /* QuickRestoreManager.swift */,
|
||||
);
|
||||
path = QuickRestore;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D221A07E169C9E5E00537ABF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -11793,6 +11803,7 @@
|
||||
50423CA22BBF426700DCB8F5 /* Profiles */,
|
||||
66CDB7532AFC3EFB009A36EC /* Provisioning */,
|
||||
D9DCFDAC2A3BB22800C73C0B /* QRCodes */,
|
||||
C1F9F7D62F0FFFCD00FF3688 /* QuickRestore */,
|
||||
6600F38C29918A5100B1EDB7 /* Registration */,
|
||||
50BF51062BB201AE00C2C309 /* Sharing */,
|
||||
34074F54203D0722004596AE /* Sounds */,
|
||||
@ -18045,6 +18056,7 @@
|
||||
887B380A25F0427F00685845 /* NotificationSettingsViewController.swift in Sources */,
|
||||
F9CA468828FF0CA600C074F6 /* OneTimeDonationCustomAmountTextField.swift in Sources */,
|
||||
F9952B2F29F1E59F00EA989E /* OsExpiry.swift in Sources */,
|
||||
C197187D2EF9D28C002E4198 /* OutgoingDeviceRestoreBackupPromptViewController.swift in Sources */,
|
||||
C14D47602DAEC45C006178AC /* OutgoingDeviceRestoreInitialViewController.swift in Sources */,
|
||||
C1A136C32DB044950049CD05 /* OutgoingDeviceRestorePresenter.swift in Sources */,
|
||||
C14D47642DAEE351006178AC /* OutgoingDeviceRestoreProgressViewController.swift in Sources */,
|
||||
|
||||
@ -122,6 +122,9 @@ public class AppEnvironment: NSObject {
|
||||
)
|
||||
|
||||
self.outgoingDeviceRestorePresenter = OutgoingDeviceRestorePresenter(
|
||||
dateProvider: Date.provider,
|
||||
db: DependenciesBridge.shared.db,
|
||||
backupSettingsStore: BackupSettingsStore(),
|
||||
deviceTransferService: deviceTransferServiceRef,
|
||||
quickRestoreManager: quickRestoreManager,
|
||||
)
|
||||
|
||||
@ -15,6 +15,7 @@ class BackupSettingsViewController:
|
||||
{
|
||||
enum OnAppearAction {
|
||||
case presentWelcomeToBackupsSheet
|
||||
case automaticallyStartBackup(completion: ((UIViewController) -> Void)?)
|
||||
}
|
||||
|
||||
private let accountEntropyPoolManager: AccountEntropyPoolManager
|
||||
@ -173,11 +174,13 @@ class BackupSettingsViewController:
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
switch onAppearAction.take() {
|
||||
switch onAppearAction {
|
||||
case nil:
|
||||
break
|
||||
case .presentWelcomeToBackupsSheet:
|
||||
presentWelcomeToBackupsSheet()
|
||||
case .automaticallyStartBackup:
|
||||
performManualBackup()
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +247,12 @@ class BackupSettingsViewController:
|
||||
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
switch onAppearAction {
|
||||
case .presentWelcomeToBackupsSheet, nil:
|
||||
break
|
||||
case .automaticallyStartBackup(let completion):
|
||||
completion?(self)
|
||||
}
|
||||
case .failure(let error):
|
||||
showSheetForBackupExportJobError(error)
|
||||
}
|
||||
|
||||
@ -46,15 +46,18 @@ class BackupOnboardingCoordinator {
|
||||
self.db = db
|
||||
}
|
||||
|
||||
/// - Parameter onAppearAction
|
||||
/// An on-appear action for Backup Settings, if onboarding is not necessary.
|
||||
func prepareForPresentation(
|
||||
inNavController navController: UINavigationController,
|
||||
onAppearAction: BackupSettingsViewController.OnAppearAction? = nil,
|
||||
) -> UIViewController {
|
||||
let haveBackupsEverBeenEnabled = db.read { tx in
|
||||
backupSettingsStore.haveBackupsEverBeenEnabled(tx: tx)
|
||||
}
|
||||
|
||||
if haveBackupsEverBeenEnabled {
|
||||
return BackupSettingsViewController(onAppearAction: nil)
|
||||
return BackupSettingsViewController(onAppearAction: onAppearAction)
|
||||
} else {
|
||||
// Weakly retain the nav controller, so we can use it throughout
|
||||
// onboarding.
|
||||
|
||||
@ -33,7 +33,7 @@ class BackupEnablementMegaphone: MegaphoneView {
|
||||
)
|
||||
|
||||
let primaryButton = MegaphoneView.Button(title: primaryButtonTitle) { [weak self] in
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
self?.markAsSnoozedWithSneakyTransaction()
|
||||
self?.dismiss(animated: true)
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ class BackupsEnabledNotificationMegaphone: MegaphoneView {
|
||||
comment: "Action text for backups enabled megaphone taking user to backup settings",
|
||||
)
|
||||
let primaryButton = MegaphoneView.Button(title: primaryButtonTitle) { [weak self] in
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
self?.markAsViewed()
|
||||
self?.dismiss(animated: true)
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ public class NotificationActionHandler {
|
||||
|
||||
@MainActor
|
||||
private class func showBackupsSettings() {
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
}
|
||||
|
||||
private struct NotificationMessage {
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
//
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SignalServiceKit
|
||||
import SignalUI
|
||||
import SwiftUI
|
||||
|
||||
class OutgoingDeviceRestoreBackupPromptViewController: HostingController<OutgoingDeviceRestoreBackupPromptView> {
|
||||
init(
|
||||
lastBackupDetails: BackupSettingsStore.LastBackupDetails,
|
||||
makeBackupCallback: @escaping (Bool) -> Void,
|
||||
) {
|
||||
super.init(wrappedView: OutgoingDeviceRestoreBackupPromptView(
|
||||
lastBackupDetails: lastBackupDetails,
|
||||
makeBackupCallback: makeBackupCallback,
|
||||
))
|
||||
self.modalPresentationStyle = .overFullScreen
|
||||
self.title = OWSLocalizedString(
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_INITIAL_VIEW_TITLE",
|
||||
comment: "Title text describing the outgoing transfer.",
|
||||
)
|
||||
self.navigationItem.leftBarButtonItem = .cancelButton(dismissingFrom: self)
|
||||
view.backgroundColor = UIColor.Signal.secondaryBackground
|
||||
OWSTableViewController2.removeBackButtonText(viewController: self)
|
||||
}
|
||||
}
|
||||
|
||||
struct OutgoingDeviceRestoreBackupPromptView: View {
|
||||
private let lastBackupDetails: BackupSettingsStore.LastBackupDetails
|
||||
private let makeBackupCallback: (Bool) -> Void
|
||||
init(
|
||||
lastBackupDetails: BackupSettingsStore.LastBackupDetails,
|
||||
makeBackupCallback: @escaping (Bool) -> Void,
|
||||
) {
|
||||
self.lastBackupDetails = lastBackupDetails
|
||||
self.makeBackupCallback = makeBackupCallback
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
SignalList {
|
||||
SignalSection {
|
||||
VStack(alignment: .center, spacing: 24) {
|
||||
Text(OWSLocalizedString(
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_INITIAL_VIEW_BODY",
|
||||
comment: "Body text describing the outgoing transfer.",
|
||||
))
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(Color.Signal.secondaryLabel)
|
||||
.tint(Color.Signal.label)
|
||||
|
||||
Image(.transferAccount)
|
||||
|
||||
Text(lastBackupDetailsString())
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(Color.Signal.secondaryLabel)
|
||||
.tint(Color.Signal.label)
|
||||
|
||||
Button(OWSLocalizedString(
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_BACKUP_ACTION",
|
||||
comment: "Action button to backup before continuing.",
|
||||
)) {
|
||||
self.makeBackupCallback(true)
|
||||
}
|
||||
.buttonStyle(Registration.UI.LargePrimaryButtonStyle())
|
||||
|
||||
Button(OWSLocalizedString(
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_SKIP_ACTION",
|
||||
comment: "Action button to skip backup and continue.",
|
||||
)) {
|
||||
self.makeBackupCallback(false)
|
||||
}
|
||||
.buttonStyle(Registration.UI.LargeSecondaryButtonStyle())
|
||||
}.padding([.top, .bottom], 12)
|
||||
}
|
||||
footer: {
|
||||
let footerString = OWSLocalizedString(
|
||||
"OUTGOING_DEVICE_RESTORE_INITIAL_VIEW_FOOTER",
|
||||
comment: "Body text describing the outgoing transfer.",
|
||||
)
|
||||
Text("\(SignalSymbol.lock.text(dynamicTypeBaseSize: 14)) \(footerString)")
|
||||
.font(.footnote)
|
||||
.foregroundStyle(Color.Signal.secondaryLabel)
|
||||
.padding([.top, .bottom], 12)
|
||||
}
|
||||
}
|
||||
.scrollBounceBehaviorIfAvailable(.basedOnSize)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
|
||||
private func lastBackupDetailsString() -> String {
|
||||
let date = lastBackupDetails.date
|
||||
return String(
|
||||
format: OWSLocalizedString(
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_RESTORE_DESCRIPTION",
|
||||
comment: "Description for form confirming restore from backup without size detail.",
|
||||
),
|
||||
DateUtil.dateFormatter.string(for: date) ?? "",
|
||||
DateUtil.timeFormatter.string(for: date) ?? "",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Previews
|
||||
|
||||
#if DEBUG
|
||||
@available(iOS 17, *)
|
||||
#Preview {
|
||||
OWSNavigationController(
|
||||
rootViewController: OutgoingDeviceRestoreBackupPromptViewController(
|
||||
lastBackupDetails: .init(
|
||||
date: Date(),
|
||||
backupFileSizeBytes: 1024,
|
||||
backupTotalSizeBytes: 4096,
|
||||
),
|
||||
makeBackupCallback: {
|
||||
print("Should do backup? \($0)")
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
#endif
|
||||
@ -17,7 +17,14 @@ extension Notification.Name {
|
||||
|
||||
class OutgoingDeviceRestorePresenter: OutgoingDeviceRestoreInitialPresenter {
|
||||
|
||||
private enum Constants {
|
||||
static let lastBackupAgeThreshold: TimeInterval = 30 * .minute
|
||||
}
|
||||
|
||||
private let internalNavigationController = OWSNavigationController()
|
||||
private let dateProvider: DateProvider
|
||||
private let db: DB
|
||||
private let backupSettingsStore: BackupSettingsStore
|
||||
private let deviceTransferService: DeviceTransferService
|
||||
private let quickRestoreManager: QuickRestoreManager
|
||||
|
||||
@ -25,9 +32,15 @@ class OutgoingDeviceRestorePresenter: OutgoingDeviceRestoreInitialPresenter {
|
||||
private var presentingViewController: UIViewController?
|
||||
|
||||
init(
|
||||
dateProvider: @escaping DateProvider,
|
||||
db: DB,
|
||||
backupSettingsStore: BackupSettingsStore,
|
||||
deviceTransferService: DeviceTransferService,
|
||||
quickRestoreManager: QuickRestoreManager,
|
||||
) {
|
||||
self.dateProvider = dateProvider
|
||||
self.db = db
|
||||
self.backupSettingsStore = backupSettingsStore
|
||||
self.deviceTransferService = deviceTransferService
|
||||
self.quickRestoreManager = quickRestoreManager
|
||||
}
|
||||
@ -82,6 +95,44 @@ class OutgoingDeviceRestorePresenter: OutgoingDeviceRestoreInitialPresenter {
|
||||
)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func pushBackupPropmtViewController(presentingViewController: UIViewController) async -> Bool {
|
||||
|
||||
let (
|
||||
backupPlan,
|
||||
lastBackupDetails,
|
||||
) = db.read { (
|
||||
backupSettingsStore.backupPlan(tx: $0),
|
||||
backupSettingsStore.lastBackupDetails(tx: $0),
|
||||
) }
|
||||
|
||||
switch backupPlan {
|
||||
case .disabled, .disabling: return false
|
||||
case .free, .paid, .paidAsTester, .paidExpiringSoon: break
|
||||
}
|
||||
|
||||
guard let lastBackupDetails else {
|
||||
owsFailDebug("Failed to load last backup details")
|
||||
return false
|
||||
}
|
||||
|
||||
if dateProvider().timeIntervalSince(lastBackupDetails.date) < Constants.lastBackupAgeThreshold {
|
||||
return false
|
||||
}
|
||||
|
||||
return await withCheckedContinuation { continuation in
|
||||
Task {
|
||||
await internalNavigationController.awaitablePush(
|
||||
OutgoingDeviceRestoreBackupPromptViewController(
|
||||
lastBackupDetails: lastBackupDetails,
|
||||
makeBackupCallback: { continuation.resume(returning: $0) },
|
||||
),
|
||||
animated: true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func displayTransferComplete(presentingViewController: UIViewController) async {
|
||||
let sheet = HeroSheetViewController(
|
||||
@ -158,6 +209,25 @@ class OutgoingDeviceRestorePresenter: OutgoingDeviceRestoreInitialPresenter {
|
||||
return
|
||||
}
|
||||
|
||||
if await pushBackupPropmtViewController(presentingViewController: presentingViewController) {
|
||||
await internalNavigationController.dismiss(animated: true)
|
||||
Task { @MainActor in
|
||||
SignalApp.shared.showAppSettings(
|
||||
mode: .backups(
|
||||
onAppearAction: .automaticallyStartBackup(
|
||||
completion: { [weak self] backupSettingsVC in
|
||||
guard let self else { return }
|
||||
showRestoreReturnSheetAfterBackup(
|
||||
presentingViewController: backupSettingsVC,
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Show a sheet while fetching the transfer data
|
||||
await presentSheet()
|
||||
let restoreMethodData = try await viewModel.waitForRestoreMethodResponse()
|
||||
@ -266,4 +336,39 @@ class OutgoingDeviceRestorePresenter: OutgoingDeviceRestoreInitialPresenter {
|
||||
await presentingViewController.awaitableDismiss(animated: true)
|
||||
await presentingViewController.awaitablePresent(sheet, animated: true)
|
||||
}
|
||||
|
||||
private func showRestoreReturnSheetAfterBackup(
|
||||
presentingViewController: UIViewController?,
|
||||
) {
|
||||
let returnSheet = HeroSheetViewController(
|
||||
hero: .image(.transferAccount),
|
||||
title: OWSLocalizedString(
|
||||
"BACKUP_SETTINGS_BACKUP_EXPORT_SUCCEEDED_READY_TO_RESTORE_TITLE",
|
||||
comment: "Title for an action sheet explaining the backup succeeded and a restore can continue.",
|
||||
),
|
||||
body: OWSLocalizedString(
|
||||
"BACKUP_SETTINGS_BACKUP_EXPORT_SUCCEEDED_READY_TO_RESTORE_BODY",
|
||||
comment: "Body for an action sheet explaining the backup succeeded and a restore can continue.",
|
||||
),
|
||||
primary: .button(HeroSheetViewController.Button(
|
||||
title: OWSLocalizedString(
|
||||
"BACKUP_SETTINGS_BACKUP_EXPORT_SUCCEEDED_READY_TO_RESTORE_ACTION_TITLE",
|
||||
comment: "Title for an action sheet action explaining the user can now scan a QR code to continue the restore.",
|
||||
),
|
||||
action: { sheet in
|
||||
sheet.dismiss(animated: true) {
|
||||
presentingViewController?.dismiss(animated: true) {
|
||||
SignalApp.shared.showCameraCaptureView()
|
||||
}
|
||||
}
|
||||
},
|
||||
)),
|
||||
secondary: .button(.dismissing(
|
||||
title: CommonStrings.cancelButton,
|
||||
style: .secondary,
|
||||
)),
|
||||
)
|
||||
|
||||
presentingViewController?.present(returnSheet, animated: true)
|
||||
}
|
||||
}
|
||||
@ -395,7 +395,7 @@ class ChatListFYISheetCoordinator {
|
||||
let sheet = BackupSubscriptionExpiredHeroSheet(
|
||||
subscriptionType: backupSubscriptionExpired.subscriptionType,
|
||||
onManageBackups: {
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
},
|
||||
)
|
||||
chatListViewController.present(sheet, animated: true) { [self] in
|
||||
@ -423,7 +423,7 @@ class ChatListFYISheetCoordinator {
|
||||
|
||||
let sheet = BackupSubscriptionFailedToRenewHeroSheet(
|
||||
onManageSubscription: {
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
},
|
||||
)
|
||||
chatListViewController.present(sheet, animated: true) { [self] in
|
||||
|
||||
@ -225,7 +225,7 @@ extension ChatListViewController {
|
||||
}
|
||||
|
||||
if isPrimaryDevice {
|
||||
showAppSettings(mode: .backups)
|
||||
showAppSettings(mode: .backups())
|
||||
} else {
|
||||
showCancelBackupDownloadsHeroSheet()
|
||||
}
|
||||
|
||||
@ -522,7 +522,7 @@ public class ChatListViewController: OWSViewController, HomeTabViewController {
|
||||
),
|
||||
image: image,
|
||||
handler: { [weak self] _ in
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
db.write { tx in
|
||||
backupSettingsStore.setErrorBadgeMuted(target: .chatListMenuItem, tx: tx)
|
||||
}
|
||||
@ -545,7 +545,7 @@ public class ChatListViewController: OWSViewController, HomeTabViewController {
|
||||
),
|
||||
image: image,
|
||||
handler: { [weak self] _ in
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
db.write { tx in
|
||||
backupSubscriptionIssueStore.setDidAckIAPSubscriptionAlreadyRedeemedChatListMenuItem(tx: tx)
|
||||
}
|
||||
@ -571,7 +571,7 @@ public class ChatListViewController: OWSViewController, HomeTabViewController {
|
||||
),
|
||||
image: image,
|
||||
handler: { [weak self] _ in
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
db.write { tx in
|
||||
backupSubscriptionIssueStore.setDidAckIAPSubscriptionNotFoundLocallyChatListMenuItem(tx: tx)
|
||||
}
|
||||
@ -594,7 +594,7 @@ public class ChatListViewController: OWSViewController, HomeTabViewController {
|
||||
),
|
||||
image: image,
|
||||
handler: { _ in
|
||||
SignalApp.shared.showAppSettings(mode: .backups)
|
||||
SignalApp.shared.showAppSettings(mode: .backups())
|
||||
},
|
||||
),
|
||||
]),
|
||||
@ -1355,7 +1355,7 @@ extension ChatListViewController {
|
||||
case paymentsTransferIn
|
||||
case appearance
|
||||
case avatarBuilder
|
||||
case backups
|
||||
case backups(onAppearAction: BackupSettingsViewController.OnAppearAction? = nil)
|
||||
case corruptedUsernameResolution
|
||||
case corruptedUsernameLinkResolution
|
||||
case donate(donateMode: DonateViewController.DonateMode)
|
||||
@ -1408,10 +1408,13 @@ extension ChatListViewController {
|
||||
viewControllers += [profile]
|
||||
internalCompletion = { profile.presentAvatarSettingsView() }
|
||||
|
||||
case .backups:
|
||||
case .backups(let onAppearAction):
|
||||
viewControllers += [
|
||||
BackupOnboardingCoordinator()
|
||||
.prepareForPresentation(inNavController: navigationController),
|
||||
.prepareForPresentation(
|
||||
inNavController: navigationController,
|
||||
onAppearAction: onAppearAction,
|
||||
),
|
||||
]
|
||||
|
||||
case .corruptedUsernameResolution:
|
||||
|
||||
@ -700,6 +700,15 @@
|
||||
/* Description for a progress bar tracking the processing of Backup media. */
|
||||
"BACKUP_SETTINGS_BACKUP_EXPORT_PROGRESS_DESCRIPTION_PROCESSING_MEDIA" = "Processing media...";
|
||||
|
||||
/* Title for an action sheet action explaining the user can now scan a QR code to continue the restore. */
|
||||
"BACKUP_SETTINGS_BACKUP_EXPORT_SUCCEEDED_READY_TO_RESTORE_ACTION_TITLE" = "Scan QR Code";
|
||||
|
||||
/* Body for an action sheet explaining the backup succeeded and a restore can continue. */
|
||||
"BACKUP_SETTINGS_BACKUP_EXPORT_SUCCEEDED_READY_TO_RESTORE_BODY" = "Use this device to scan the QR code on the device you want to transfer to";
|
||||
|
||||
/* Title for an action sheet explaining the backup succeeded and a restore can continue. */
|
||||
"BACKUP_SETTINGS_BACKUP_EXPORT_SUCCEEDED_READY_TO_RESTORE_TITLE" = "Ready to Transfer";
|
||||
|
||||
/* Message describing to the user that the last backup failed. */
|
||||
"BACKUP_SETTINGS_BACKUP_FAILED_MESSAGE" = "Your last backup couldn't be completed. Tap \"Back Up Now\" to try again.";
|
||||
|
||||
@ -5914,6 +5923,21 @@
|
||||
/* Title of prompt notifying restore failed for unknown reasons. */
|
||||
"OUTGOING_DEVICE_REGISTRATION_UNKNOWN_ERROR_TITLE" = "Unknown error";
|
||||
|
||||
/* Action button to backup before continuing. */
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_BACKUP_ACTION" = "Backup Up Now";
|
||||
|
||||
/* Body text describing the outgoing transfer. */
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_INITIAL_VIEW_BODY" = "Back up now before transferring. You may have received messages that haven’t been backed up yet.";
|
||||
|
||||
/* Title text describing the outgoing transfer. */
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_INITIAL_VIEW_TITLE" = "Getting Your Device Ready";
|
||||
|
||||
/* Action button to skip backup and continue. */
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_PROMPT_SKIP_ACTION" = "Skip and Continue";
|
||||
|
||||
/* Description for form confirming restore from backup without size detail. */
|
||||
"OUTGOING_DEVICE_RESTORE_BACKUP_RESTORE_DESCRIPTION" = "Your last backup was made on %1$@ at %2$@.";
|
||||
|
||||
/* Body of prompt notifying device restore started on the new device. */
|
||||
"OUTGOING_DEVICE_RESTORE_COMPLETE_BODY" = "Your Signal account and messages have started transferring to your other device. Signal is now inactive on this device.";
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user