diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 31bbcdced3..44b712822d 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -8658,7 +8658,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 57.5.0; + version = 57.6.0; }; }; AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index e35f9772f1..58f8bb1024 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "7b5cc081607b638d5a2826d11a8ecdb667e489c2", - "version" : "57.5.0" + "revision" : "b19b5e4383a7fdae5e69f1ecbf64ee8f5dbb4a55", + "version" : "57.6.0" } }, { diff --git a/DuckDuckGo/Preferences/Model/SyncPreferences.swift b/DuckDuckGo/Preferences/Model/SyncPreferences.swift index a4b034573f..3e86fbf68c 100644 --- a/DuckDuckGo/Preferences/Model/SyncPreferences.swift +++ b/DuckDuckGo/Preferences/Model/SyncPreferences.swift @@ -73,13 +73,12 @@ final class SyncPreferences: ObservableObject, SyncUI.ManagementViewModel { @MainActor func presentShowOrEnterCodeDialog() { Task { @MainActor in - let devicesAtStart = self.devices self.$devices .removeDuplicates() .dropFirst() .prefix(1) - .sink { [weak self] _ in - self?.managementDialogModel.endFlow() + .sink { [weak self] value in + self?.presentDialog(for: .deviceSynced(value.filter { !$0.isCurrent })) self?.objectWillChange.send() }.store(in: &cancellables) managementDialogModel.codeToDisplay = syncService.account?.recoveryCode @@ -241,10 +240,15 @@ extension SyncPreferences: ManagementDialogModelDelegate { } @MainActor - private func login(_ recoveryKey: SyncCode.RecoveryKey) async throws { + private func loginAndShowPresentedDialog(_ recoveryKey: SyncCode.RecoveryKey) async throws { let device = deviceInfo() - try await syncService.login(recoveryKey, deviceName: device.name, deviceType: device.type) + let knownDevices = Set(self.devices.map { $0.id }) + let devices = try await syncService.login(recoveryKey, deviceName: device.name, deviceType: device.type) + mapDevices(devices) + let syncedDevices = self.devices.filter { !knownDevices.contains($0.id) && !$0.isCurrent } + managementDialogModel.endFlow() + presentDialog(for: .deviceSynced(syncedDevices)) } @MainActor @@ -277,24 +281,16 @@ extension SyncPreferences: ManagementDialogModelDelegate { } if let recoveryKey = syncCode.recovery { // This will error if the account already exists, we don't have good UI for this just now - try await login(recoveryKey) - presentDialog(for: .deviceSynced) + try await loginAndShowPresentedDialog(recoveryKey) } else if let connectKey = syncCode.connect { - var isNewAccount = false if syncService.account == nil { let device = deviceInfo() try await syncService.createAccount(deviceName: device.name, deviceType: device.type) - isNewAccount = true } try await syncService.transmitRecoveryKey(connectKey) - if isNewAccount { - presentDialog(for: .deviceSynced) - } else { - managementDialogModel.endFlow() - } - + // The UI will update when the devices list changes. } else { managementDialogModel.errorMessage = "Invalid code" return @@ -312,8 +308,7 @@ extension SyncPreferences: ManagementDialogModelDelegate { managementDialogModel.codeToDisplay = connector?.code presentDialog(for: .syncAnotherDevice) if let recoveryKey = try await connector?.pollForRecoveryKey() { - try await login(recoveryKey) - presentDialog(for: .deviceSynced) + try await loginAndShowPresentedDialog(recoveryKey) } else { // Polling was likeley cancelled elsewhere (e.g. dialog closed) return diff --git a/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/DeleteAccountView.swift b/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/DeleteAccountView.swift index 80575e3279..634fd75897 100644 --- a/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/DeleteAccountView.swift +++ b/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/DeleteAccountView.swift @@ -52,7 +52,7 @@ struct DeleteAccountView: View { } .frame(width: 360, // Grow with the number of devices, up to a point - height: min(410, 280 + (CGFloat(devices.count) * 40))) + height: min(410, 272 + (CGFloat(devices.count) * 44))) } } diff --git a/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/SyncSetupCompleteView.swift b/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/SyncSetupCompleteView.swift index 6d01261319..3e17a09e18 100644 --- a/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/SyncSetupCompleteView.swift +++ b/LocalPackages/SyncUI/Sources/SyncUI/Views/Dialogs/SyncSetupCompleteView.swift @@ -21,9 +21,7 @@ import SwiftUI struct SyncSetupCompleteView: View { @EnvironmentObject var model: ManagementDialogModel - var device: SyncDevice { - .init(kind: .mobile, name: "Dave's iPhone 14", id: UUID().uuidString) - } + let devices: [SyncDevice] var body: some View { SyncDialog(spacing: 20.0) { @@ -34,18 +32,19 @@ struct SyncSetupCompleteView: View { Text(UserText.deviceSyncedExplanation) .multilineTextAlignment(.center) - SyncPreferencesRow { - SyncedDeviceIcon(kind: device.kind) - } centerContent: { - Text(device.name) + ScrollView { + SyncedDevicesList(devices: devices) } - .roundedBorder() + } } buttons: { Button(UserText.next) { model.delegate?.confirmSetupComplete() } } - .frame(width: 360, height: 298) + .frame(width: 360, + // Grow with the number of devices, up to a point + height: min(410, 258 + (CGFloat(devices.count) * 44))) + } } diff --git a/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementDialog.swift b/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementDialog.swift index 5cba4c7136..41ec3b01b1 100644 --- a/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementDialog.swift +++ b/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementDialog.swift @@ -24,7 +24,7 @@ public enum ManagementDialogKind: Equatable { case deleteAccount(_ devices: [SyncDevice]) case askToSyncAnotherDevice case syncAnotherDevice - case deviceSynced + case deviceSynced(_ devices: [SyncDevice]) case saveRecoveryPDF case turnOffSync case deviceDetails(_ device: SyncDevice) @@ -62,8 +62,8 @@ public struct ManagementDialog: View { RecoverAccountView() case .syncAnotherDevice: SyncAnotherDeviceView() - case .deviceSynced: - SyncSetupCompleteView() + case .deviceSynced(let devices): + SyncSetupCompleteView(devices: devices) case .saveRecoveryPDF: SaveRecoveryPDFView() case .turnOffSync: diff --git a/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementView/SyncedDevicesView.swift b/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementView/SyncedDevicesView.swift index 94ad754f83..9a1fed1835 100644 --- a/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementView/SyncedDevicesView.swift +++ b/LocalPackages/SyncUI/Sources/SyncUI/Views/ManagementView/SyncedDevicesView.swift @@ -22,7 +22,7 @@ struct SyncedDevicesView: View where ViewModel: ManagementViewModel { @EnvironmentObject var model: ViewModel - let timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect() + let timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect() var body: some View { SyncedDevicesList(devices: model.devices,