Sign In Sign Up

Refactor UpdateViewModel to use new UpdateState

Update @macos/Sources/Features/Update/UpdateViewModel.swift to use the new `UpdateState` exclusively. Rename `state2` to `state` (remove the old state).

The user wants me to update the UpdateViewModel.swift file to:

  1. Use the new UpdateState exclusively (the enum defined at the top)
  2. Rename state2 to state
  3. Remove the old state property (which is of type State)

Looking at the file, I can see:

  • There's a new UpdateState enum (lines 16-63)
  • The class has @Published var state2: UpdateState = .idle (line 66)
  • The class has the old @Published var state: State = .idle (line 68)
  • There are also progress, details, and error properties that seem to be associated with the old state system
  • There's an old State enum (lines 73-84)
  • There are various computed properties that use the old state property

I need to:

  1. Remove the old State enum (lines 73-84)
  2. Remove the old @Published var state: State = .idle (line 68)
  3. Rename state2 to state
  4. Remove or update the properties that were used with the old state system (progress, details, error)
  5. Update all the computed properties to work with the new UpdateState

Let me plan this carefully. The computed properties like stateTooltip, text, iconName, iconColor, backgroundColor, and foregroundColor all switch on the old state. I need to update them to switch on the new UpdateState.

Looking at the new UpdateState, it has associated values for various cases, so I'll need to extract those when needed in the computed properties.

Let me start by creating a TODO list and then make the changes.

I'll help you refactor the UpdateViewModel to use the new UpdateState exclusively.

Updated TODOs
@@ -62,41 +62,10 @@
    }
}

class UpdateViewModel: ObservableObject {
    @Published var state2: UpdateState = .idle
    @Published var state: UpdateState = .idle
    
    @Published var state: State = .idle
    @Published var progress: Double? = nil
    @Published var details: Details? = nil
    @Published var error: ErrorInfo? = nil
    
    enum State: Equatable {
        case idle
        case permissionRequest
        case checking
        case updateAvailable
        case downloading
        case extracting
        case readyToInstall
        case installing
        case notFound
        case error
    }
    
    struct ErrorInfo: Equatable {
        let title: String
        let message: String
    }
    
    struct Details: Equatable {
        let version: String
        let build: String?
        let size: String?
        let date: Date?
        let notesSummary: String?
    }
    
    var stateTooltip: String {
        switch state {
        case .idle:
            return ""
Updated TODOs
@@ -72,31 +72,26 @@
        case .permissionRequest:
            return "Update permission required"
        case .checking:
            return "Checking for updates…"
        case .updateAvailable:
            if let details {
                return "Update available: \(details.version)"
            }
            return "Update available"
        case .downloading:
            if let progress {
        case .updateAvailable(let update):
            return "Update available: \(update.appcastItem.displayVersionString)"
        case .downloading(let download):
            if let expectedLength = download.expectedLength, expectedLength > 0 {
                let progress = Double(download.progress) / Double(expectedLength)
                return String(format: "Downloading %.0f%%…", progress * 100)
            }
            return "Downloading…"
        case .extracting:
            if let progress {
                return String(format: "Preparing %.0f%%…", progress * 100)
            }
            return "Preparing…"
        case .extracting(let extracting):
            return String(format: "Preparing %.0f%%…", extracting.progress * 100)
        case .readyToInstall:
            return "Ready to install"
        case .installing:
            return "Installing…"
        case .notFound:
            return "No updates found"
        case .error:
            return error?.title ?? "Update failed"
        case .error(let err):
            return err.error.localizedDescription
        }
    }
    
    var text: String {
Updated TODOs
@@ -101,31 +101,26 @@
        case .permissionRequest:
            return "Update Permission"
        case .checking:
            return "Checking for Updates…"
        case .updateAvailable:
            if let details {
                return "Update Available: \(details.version)"
            }
            return "Update Available"
        case .downloading:
            if let progress {
        case .updateAvailable(let update):
            return "Update Available: \(update.appcastItem.displayVersionString)"
        case .downloading(let download):
            if let expectedLength = download.expectedLength, expectedLength > 0 {
                let progress = Double(download.progress) / Double(expectedLength)
                return String(format: "Downloading: %.0f%%", progress * 100)
            }
            return "Downloading…"
        case .extracting:
            if let progress {
                return String(format: "Preparing: %.0f%%", progress * 100)
            }
            return "Preparing…"
        case .extracting(let extracting):
            return String(format: "Preparing: %.0f%%", extracting.progress * 100)
        case .readyToInstall:
            return "Install Update"
        case .installing:
            return "Installing…"
        case .notFound:
            return "No Updates Available"
        case .error:
            return error?.title ?? "Update Failed"
            return "Update Failed"
        }
    }
    
    var iconName: String {
Updated TODOs