103 lines
3.4 KiB
Swift
103 lines
3.4 KiB
Swift
//
|
|
// Copyright 2025 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
import MultipeerConnectivity
|
|
import SignalServiceKit
|
|
|
|
public class RegistrationTransferStatusState: DeviceTransferServiceObserver, Equatable {
|
|
let transferStatusViewModel = TransferStatusViewModel()
|
|
|
|
private let deviceTransferService: RegistrationCoordinatorImpl.Shims.DeviceTransferService
|
|
private let quickRestoreManager: RegistrationCoordinatorImpl.Shims.QuickRestoreManager
|
|
private let restoreMethodToken: String
|
|
|
|
public var onCancel: (() -> Void) {
|
|
get {
|
|
transferStatusViewModel.onCancel
|
|
}
|
|
set {
|
|
transferStatusViewModel.onCancel = { [weak self] in
|
|
self?.stopAcceptingTransfers()
|
|
self?.cancelTransfer()
|
|
newValue()
|
|
}
|
|
}
|
|
}
|
|
|
|
public var onSuccess: (() -> Void) {
|
|
get {
|
|
transferStatusViewModel.onSuccess
|
|
}
|
|
set {
|
|
transferStatusViewModel.onSuccess = { [weak self] in
|
|
self?.stopAcceptingTransfers()
|
|
newValue()
|
|
}
|
|
}
|
|
}
|
|
|
|
init(
|
|
deviceTransferService: RegistrationCoordinatorImpl.Shims.DeviceTransferService,
|
|
quickRestoreManager: RegistrationCoordinatorImpl.Shims.QuickRestoreManager,
|
|
restoreMethodToken: String
|
|
) {
|
|
self.deviceTransferService = deviceTransferService
|
|
self.quickRestoreManager = quickRestoreManager
|
|
self.restoreMethodToken = restoreMethodToken
|
|
}
|
|
|
|
public func start() async throws {
|
|
transferStatusViewModel.state = .starting
|
|
deviceTransferService.addObserver(self)
|
|
let url = try deviceTransferService.startAcceptingTransfersFromOldDevices(mode: .primary)
|
|
let transferData = url.absoluteString.data(using: .utf8)!.base64EncodedStringWithoutPadding()
|
|
|
|
try await quickRestoreManager.reportRestoreMethodChoice(
|
|
method: .deviceTransfer(transferData),
|
|
restoreMethodToken: restoreMethodToken
|
|
)
|
|
}
|
|
|
|
private func cancelTransfer() {
|
|
deviceTransferService.cancelTransferFromOldDevice()
|
|
}
|
|
|
|
public func stopAcceptingTransfers() {
|
|
deviceTransferService.removeObserver(self)
|
|
deviceTransferService.stopAcceptingTransfersFromOldDevices()
|
|
}
|
|
|
|
func deviceTransferServiceDiscoveredNewDevice(peerId: MCPeerID, discoveryInfo: [String: String]?) {
|
|
transferStatusViewModel.state = .connecting
|
|
}
|
|
|
|
private var progressObserver: NSKeyValueObservation?
|
|
func deviceTransferServiceDidStartTransfer(progress: Progress) {
|
|
self.progressObserver = progress.observe(\.fractionCompleted, options: [.new]) { [weak self] _, change in
|
|
DispatchQueue.main.async {
|
|
let newValue = change.newValue ?? 0
|
|
self?.transferStatusViewModel.state = .transferring(newValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
func deviceTransferServiceDidEndTransfer(error: DeviceTransferService.Error?) {
|
|
if let error {
|
|
transferStatusViewModel.state = .error(error)
|
|
} else {
|
|
transferStatusViewModel.state = .done
|
|
}
|
|
}
|
|
|
|
func deviceTransferServiceDidRequestAppRelaunch() {
|
|
transferStatusViewModel.onSuccess()
|
|
}
|
|
|
|
public static func == (lhs: RegistrationTransferStatusState, rhs: RegistrationTransferStatusState) -> Bool {
|
|
lhs.restoreMethodToken == rhs.restoreMethodToken
|
|
}
|
|
}
|