mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-03-25 08:55:46 +00:00
Set up overall progress object
to track both downloading and unarchiving and reflect this in dock progress
This commit is contained in:
parent
de35bed9fa
commit
622fac605c
2 changed files with 46 additions and 10 deletions
|
|
@ -44,6 +44,8 @@ extension AppState {
|
|||
|
||||
Logger.appState.info("Using \(downloader) downloader")
|
||||
|
||||
setupDockProgress()
|
||||
|
||||
return validateSession()
|
||||
.flatMap { _ in
|
||||
self.getXcodeArchive(installationType, downloader: downloader)
|
||||
|
|
@ -52,6 +54,8 @@ extension AppState {
|
|||
self.installArchivedXcode(xcode, at: url)
|
||||
}
|
||||
.catch { error -> AnyPublisher<InstalledXcode, Swift.Error> in
|
||||
self.resetDockProgressTracking()
|
||||
|
||||
switch error {
|
||||
case InstallationError.damagedXIP(let damagedXIPURL):
|
||||
guard attemptNumber < 1 else { return Fail(error: error).eraseToAnyPublisher() }
|
||||
|
|
@ -100,6 +104,7 @@ extension AppState {
|
|||
self.downloadOrUseExistingArchive(for: availableXcode, downloader: downloader, progressChanged: { [unowned self] progress in
|
||||
DispatchQueue.main.async {
|
||||
self.setInstallationStep(of: availableXcode.version, to: .downloading(progress: progress))
|
||||
self.overallProgress.addChild(progress, withPendingUnitCount: AppState.totalProgressUnits - AppState.unxipProgressWeight)
|
||||
}
|
||||
})
|
||||
.map { return (availableXcode, $0) }
|
||||
|
|
@ -152,7 +157,7 @@ extension AppState {
|
|||
cookies
|
||||
)
|
||||
progressChanged(progress)
|
||||
updateDockIcon(withProgress: progress)
|
||||
|
||||
return publisher
|
||||
.map { _ in destination.url }
|
||||
.eraseToAnyPublisher()
|
||||
|
|
@ -162,12 +167,12 @@ extension AppState {
|
|||
let resumeDataPath = Path.xcodesApplicationSupport/"Xcode-\(availableXcode.version).resumedata"
|
||||
let persistedResumeData = Current.files.contents(atPath: resumeDataPath.string)
|
||||
|
||||
return attemptResumableTask(maximumRetryCount: 3) { [weak self] resumeData -> AnyPublisher<URL, Error> in
|
||||
return attemptResumableTask(maximumRetryCount: 3) { resumeData -> AnyPublisher<URL, Error> in
|
||||
let (progress, publisher) = Current.network.downloadTask(with: availableXcode.url,
|
||||
to: destination.url,
|
||||
resumingWith: resumeData ?? persistedResumeData)
|
||||
progressChanged(progress)
|
||||
self?.updateDockIcon(withProgress: progress)
|
||||
|
||||
return publisher
|
||||
.map { $0.saveLocation }
|
||||
.eraseToAnyPublisher()
|
||||
|
|
@ -177,13 +182,11 @@ extension AppState {
|
|||
})
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
private func updateDockIcon(withProgress progress: Progress) {
|
||||
DockProgress.style = .bar
|
||||
DockProgress.progressInstance = progress
|
||||
}
|
||||
|
||||
public func installArchivedXcode(_ availableXcode: AvailableXcode, at archiveURL: URL) -> AnyPublisher<InstalledXcode, Error> {
|
||||
unxipProgress.completedUnitCount = 0
|
||||
overallProgress.addChild(unxipProgress, withPendingUnitCount: AppState.unxipProgressWeight)
|
||||
|
||||
do {
|
||||
let destinationURL = Path.installDirectory.join("Xcode-\(availableXcode.version.descriptionWithoutBuildMetadata).app").url
|
||||
switch archiveURL.pathExtension {
|
||||
|
|
@ -423,6 +426,9 @@ extension AppState {
|
|||
}
|
||||
self.presentedAlert = .privilegedHelper
|
||||
}
|
||||
|
||||
unxipProgress.completedUnitCount = AppState.totalProgressUnits
|
||||
resetDockProgressTracking()
|
||||
|
||||
return helperInstallConsentSubject
|
||||
.flatMap {
|
||||
|
|
@ -463,6 +469,24 @@ extension AppState {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
// MARK: - Dock Progress Tracking
|
||||
|
||||
private func setupDockProgress() {
|
||||
DockProgress.progressInstance = nil
|
||||
DockProgress.style = .bar
|
||||
|
||||
let progress = Progress(totalUnitCount: AppState.totalProgressUnits)
|
||||
progress.kind = .file
|
||||
progress.fileOperationKind = .downloading
|
||||
overallProgress = progress
|
||||
|
||||
DockProgress.progressInstance = overallProgress
|
||||
}
|
||||
|
||||
func resetDockProgressTracking() {
|
||||
DockProgress.progress = 1 // Only way to completely remove overlay with DockProgress is setting progress to complete
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
func setInstallationStep(of version: Version, to step: InstallationStep) {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,19 @@ class AppState: ObservableObject {
|
|||
private var selectPublisher: AnyCancellable?
|
||||
private var uninstallPublisher: AnyCancellable?
|
||||
private var autoInstallTimer: Timer?
|
||||
|
||||
// MARK: - Dock Progress Tracking
|
||||
|
||||
public static let totalProgressUnits = Int64(10)
|
||||
public static let unxipProgressWeight = Int64(1)
|
||||
var overallProgress = Progress()
|
||||
var unxipProgress = {
|
||||
let progress = Progress(totalUnitCount: totalProgressUnits)
|
||||
progress.kind = .file
|
||||
progress.fileOperationKind = .copying
|
||||
return progress
|
||||
}()
|
||||
|
||||
// MARK: -
|
||||
|
||||
var dataSource: DataSource {
|
||||
|
|
@ -491,8 +504,7 @@ class AppState: ObservableObject {
|
|||
// Cancel the publisher
|
||||
installationPublishers[id] = nil
|
||||
|
||||
// Remove dock icon progress indicator
|
||||
DockProgress.progress = 1 // Only way to completely remove overlay with DockProgress is setting progress to complete
|
||||
resetDockProgressTracking()
|
||||
|
||||
// If the download is cancelled by the user, clean up the download files that aria2 creates.
|
||||
// This isn't done as part of the publisher with handleEvents(receiveCancel:) because it shouldn't happen when e.g. the app quits.
|
||||
|
|
|
|||
Loading…
Reference in a new issue