From d299afb82b907ce28531b4132bcb1d91e000aea0 Mon Sep 17 00:00:00 2001 From: Christoph Aldrian Date: Wed, 29 Jan 2025 22:41:24 +0100 Subject: [PATCH] show file importer --- .../BackupProgress/BackupProgressView.swift | 26 +---------------- .../Main/BackupRestoreMainView.swift | 18 +++++++++++- .../Root/BackupRestoreRootView.swift | 16 +++-------- .../Root/BackupRestoreRootViewModel.swift | 28 +------------------ .../SetBackupPasswordView.swift | 13 +++++---- 5 files changed, 31 insertions(+), 70 deletions(-) diff --git a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/BackupProgress/BackupProgressView.swift b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/BackupProgress/BackupProgressView.swift index ae15f96cec..521d1e8746 100644 --- a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/BackupProgress/BackupProgressView.swift +++ b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/BackupProgress/BackupProgressView.swift @@ -132,39 +132,15 @@ private final class BackupProgressViewController: UIViewController { descriptionLabel = .init() descriptionLabel.numberOfLines = 0 -// descriptionLabel.translatesAutoresizingMaskIntoConstraints = false -// view.addSubview(descriptionLabel) descriptionLabel.text = progressDescription progressView = .init(progressViewStyle: .bar) -// progressView.translatesAutoresizingMaskIntoConstraints = false -// view.addSubview(progressView) progressView.progress = progressValue exportButton = .init(type: .system) exportButton.setTitle("save", for: .normal) -// exportButton.translatesAutoresizingMaskIntoConstraints = false exportButton.addTarget(self, action: #selector(showActivityViewController(_:)), for: .primaryActionTriggered) exportButton.isEnabled = backupURL != nil -// view.addSubview(exportButton) - - /* - NSLayoutConstraint.activate([ - - descriptionLabel.leadingAnchor.constraint(equalToSystemSpacingAfter: view.leadingAnchor, multiplier: 3), - descriptionLabel.topAnchor.constraint(greaterThanOrEqualToSystemSpacingBelow: view.topAnchor, multiplier: 3), - view.trailingAnchor.constraint(equalToSystemSpacingAfter: descriptionLabel.trailingAnchor, multiplier: 3), - - progressView.leadingAnchor.constraint(equalTo: descriptionLabel.leadingAnchor), - progressView.topAnchor.constraint(equalToSystemSpacingBelow: descriptionLabel.bottomAnchor, multiplier: 3), - descriptionLabel.trailingAnchor.constraint(equalTo: progressView.trailingAnchor), - - exportButton.leadingAnchor.constraint(equalTo: descriptionLabel.leadingAnchor), - exportButton.topAnchor.constraint(equalToSystemSpacingBelow: progressView.bottomAnchor, multiplier: 3), - descriptionLabel.trailingAnchor.constraint(equalTo: exportButton.trailingAnchor), - view.bottomAnchor.constraint(equalToSystemSpacingBelow: exportButton.bottomAnchor, multiplier: 3) - ]) - */ scrollView = UIScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false @@ -195,10 +171,10 @@ private final class BackupProgressViewController: UIViewController { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() + // TODO: check calculation (e.g. regarding safe area bottom inset) let stackViewHeight = stackView.frame.maxY + (navigationController?.navigationBar.frame.height ?? 0) if let sheetPresentationController = navigationController?.sheetPresentationController { sheetPresentationController.detents = [.custom { _ in stackViewHeight }] - print("setting detend to \(stackViewHeight)") } } diff --git a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Main/BackupRestoreMainView.swift b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Main/BackupRestoreMainView.swift index e2736d977b..fd7fb7022d 100644 --- a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Main/BackupRestoreMainView.swift +++ b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Main/BackupRestoreMainView.swift @@ -23,6 +23,8 @@ struct BackupRestoreMainView: View { let backupAction: () -> Void let restoreAction: (_ url: URL) -> Void + @State private var isFileImporterPresented = false + var body: some View { List { backupSection @@ -42,7 +44,21 @@ struct BackupRestoreMainView: View { private var restoreSection: some View { Section(footer: Text(L10n.Localizable.Settings.RestoreFromBackup.description)) { Button(L10n.Localizable.Settings.RestoreFromBackup.action) { -// restoreAction() + isFileImporterPresented = true + } + .fileImporter( + isPresented: $isFileImporterPresented, + allowedContentTypes: [.json] + ) { result in + switch result { + case .success(let file): + let gotAccess = file.startAccessingSecurityScopedResource() + guard gotAccess else { return assertionFailure() } // TODO: also log before every assertionFailure + restoreAction(file) + file.stopAccessingSecurityScopedResource() + case .failure(let error): + print(error.localizedDescription) + } } } } diff --git a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootView.swift b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootView.swift index 9cfb41e36a..bd26c116b4 100644 --- a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootView.swift +++ b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootView.swift @@ -22,8 +22,6 @@ struct BackupRestoreRootView: View { @StateObject var viewModel: BackupRestoreRootViewModel - let details = Details(name: "name", error: "error") - var body: some View { BackupRestoreMainView( @@ -44,10 +42,10 @@ struct BackupRestoreRootView: View { .interactiveDismissDisabled() .presentationDetents([.medium]) .sheet(isPresented: $viewModel.isSetBackupPasswordPresented) { - SetBackupPasswordView { password in - guard let password else { return viewModel.cancel() } - viewModel.createBackup(password: password) - } + SetBackupPasswordView( + onProceed: { password in viewModel.createBackup(password: password) }, + onCancel: { viewModel.cancel() } + ) .interactiveDismissDisabled() .presentationDetents([.large]) } @@ -75,12 +73,6 @@ struct BackupRestoreRootView: View { typealias BackupState = BackupProgressView.CreateBackupState -struct Details: Identifiable { - let name: String - let error: String - let id = UUID() -} - #Preview { BackupRestoreRootView(viewModel: BackupRestoreRootViewModel()) } diff --git a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootViewModel.swift b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootViewModel.swift index 0464a0b1e0..26f4dea617 100644 --- a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootViewModel.swift +++ b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/Root/BackupRestoreRootViewModel.swift @@ -78,32 +78,6 @@ final class BackupRestoreRootViewModel: ObservableObject { } } -// func getItemForExport() -> URL { -// guard case .backup(.backupReadyAndExported) = state else { fatalError() } -// -// let fileManager = FileManager.default -// let documentsURL = try! fileManager.url( -// for: .documentDirectory, -// in: .userDomainMask, -// appropriateFor: nil, -// create: false -// ) -// let backupURL = documentsURL.appendingPathComponent("backup.json") -// -// // Example backup data -// let backupData: [String: Any] = [ -// "timestamp": "Date()", -// "data": "Your backup data here" -// ] -// -// let data = try! JSONSerialization.data(withJSONObject: backupData, options: .prettyPrinted) -// try! data.write(to: backupURL) -// -// state = .backup(.backupReadyAndExported) -// -// return backupURL -// } - func cancel() { switch state { case .backup(.enterPassword): @@ -138,7 +112,7 @@ final class BackupRestoreRootViewModel: ObservableObject { } isErrorAlertPresented = switch state { - case .backup(.backupFailed(let error)): + case .backup(.backupFailed): true default: false diff --git a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/SetBackupPassword/SetBackupPasswordView.swift b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/SetBackupPassword/SetBackupPasswordView.swift index aba8520fe5..22fbf3847b 100644 --- a/WireUI/Sources/WireSettingsUI/Account/BackupRestore/SetBackupPassword/SetBackupPasswordView.swift +++ b/WireUI/Sources/WireSettingsUI/Account/BackupRestore/SetBackupPassword/SetBackupPasswordView.swift @@ -20,23 +20,26 @@ import SwiftUI struct SetBackupPasswordView: View { - /// Password can be an empty string. If `nil` is returned, the user cancelled. - var result: (_ password: String?) -> Void + var onProceed: (_ password: String) -> Void + var onCancel: () -> Void @Environment(\.dismiss) private var dismiss var body: some View { VStack { Button("action") { - result("") + onProceed("") } Button("dismiss") { - result(nil) + onCancel() } } } } #Preview { - SetBackupPasswordView { _ in } + SetBackupPasswordView( + onProceed: { _ in }, + onCancel: {} + ) }