Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 34 additions & 13 deletions Coder-Desktop/Coder-Desktop/UpdaterService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,63 @@ import Sparkle
import SwiftUI

final class UpdaterService: NSObject, ObservableObject {
private lazy var inner: SPUStandardUpdaterController = .init(
startingUpdater: true,
updaterDelegate: self,
userDriverDelegate: self
)
private var updater: SPUUpdater!
// The auto-updater can be entirely disabled by setting the
// `disableUpdater` UserDefaults key to `true`. This is designed for use in
// MDM configurations, where the value can be set to `true` permanently.
@Published var disabled: Bool = UserDefaults.standard.bool(forKey: Keys.disableUpdater) {
didSet {
UserDefaults.standard.set(disabled, forKey: Keys.disableUpdater)
}
}

@Published var canCheckForUpdates = true

@Published var autoCheckForUpdates: Bool! {
didSet {
if let autoCheckForUpdates, autoCheckForUpdates != oldValue {
updater.automaticallyChecksForUpdates = autoCheckForUpdates
inner?.updater.automaticallyChecksForUpdates = autoCheckForUpdates
}
}
}

@Published var updateChannel: UpdateChannel {
didSet {
UserDefaults.standard.set(updateChannel.rawValue, forKey: Self.updateChannelKey)
UserDefaults.standard.set(updateChannel.rawValue, forKey: Keys.updateChannel)
}
}

static let updateChannelKey = "updateChannel"
private var inner: (controller: SPUStandardUpdaterController, updater: SPUUpdater)?

override init() {
updateChannel = UserDefaults.standard.string(forKey: Self.updateChannelKey)
updateChannel = UserDefaults.standard.string(forKey: Keys.updateChannel)
.flatMap { UpdateChannel(rawValue: $0) } ?? .stable
super.init()
updater = inner.updater

guard !disabled else {
return
}

let inner = SPUStandardUpdaterController(
startingUpdater: true,
updaterDelegate: self,
userDriverDelegate: self
)

let updater = inner.updater
self.inner = (inner, updater)

autoCheckForUpdates = updater.automaticallyChecksForUpdates
updater.publisher(for: \.canCheckForUpdates).assign(to: &$canCheckForUpdates)
}

func checkForUpdates() {
guard canCheckForUpdates else { return }
updater.checkForUpdates()
guard let inner, canCheckForUpdates else { return }
inner.updater.checkForUpdates()
}

enum Keys {
static let disableUpdater = "disableUpdater"
static let updateChannel = "updateChannel"
}
}

Expand Down
24 changes: 13 additions & 11 deletions Coder-Desktop/Coder-Desktop/Views/Settings/GeneralTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@ struct GeneralTab: View {
Text("Start Coder Connect on launch")
}
}
Section {
Toggle(isOn: $updater.autoCheckForUpdates) {
Text("Automatically check for updates")
}
Picker("Update channel", selection: $updater.updateChannel) {
ForEach(UpdateChannel.allCases) { channel in
Text(channel.name).tag(channel)
if !updater.disabled {
Section {
Toggle(isOn: $updater.autoCheckForUpdates) {
Text("Automatically check for updates")
}
Picker("Update channel", selection: $updater.updateChannel) {
ForEach(UpdateChannel.allCases) { channel in
Text(channel.name).tag(channel)
}
}
HStack {
Spacer()
Button("Check for updates") { updater.checkForUpdates() }.disabled(!updater.canCheckForUpdates)
}
}
HStack {
Spacer()
Button("Check for updates") { updater.checkForUpdates() }.disabled(!updater.canCheckForUpdates)
}
}
}.formStyle(.grouped)
Expand Down
Loading