add Sparkle appcast
This commit is contained in:
@@ -12,15 +12,13 @@ struct MainView: View {
|
||||
private static let serverOrderKeyStatic = "serverOrder"
|
||||
private static let storedServersKeyStatic = "storedServers"
|
||||
|
||||
@EnvironmentObject private var updateViewModel: UpdateViewModel
|
||||
@EnvironmentObject private var sparkleUpdater: SparkleUpdater
|
||||
@State var showAddServerSheet: Bool = false
|
||||
@State private var serverBeingEdited: Server?
|
||||
@State private var serverToDelete: Server?
|
||||
@State private var showDeleteConfirmation = false
|
||||
@State private var isFetchingInfo: Bool = false
|
||||
@State private var refreshTimer = Timer.publish(every: 60, on: .main, in: .common).autoconnect()
|
||||
@State private var progress: Double = 0
|
||||
@State private var lastRefresh = Date()
|
||||
@State private var pingTimer: Timer?
|
||||
private let serverOrderKey = MainView.serverOrderKeyStatic
|
||||
private let storedServersKey = MainView.storedServersKeyStatic
|
||||
@@ -64,14 +62,9 @@ struct MainView: View {
|
||||
}
|
||||
ToolbarItem {
|
||||
Button {
|
||||
updateViewModel.checkForUpdates(userInitiated: true)
|
||||
sparkleUpdater.checkForUpdates()
|
||||
} label: {
|
||||
if updateViewModel.isChecking {
|
||||
ProgressView()
|
||||
.scaleEffect(0.6)
|
||||
} else {
|
||||
Image(systemName: "square.and.arrow.down")
|
||||
}
|
||||
Image(systemName: "square.and.arrow.down")
|
||||
}
|
||||
.help("Check for Updates")
|
||||
}
|
||||
@@ -144,26 +137,8 @@ struct MainView: View {
|
||||
pingTimer = Timer.scheduledTimer(withTimeInterval: 10.0, repeats: true) { _ in
|
||||
pingAllServers()
|
||||
}
|
||||
updateViewModel.startAutomaticCheckIfNeeded()
|
||||
}
|
||||
.frame(minWidth: 800, minHeight: 450)
|
||||
.alert(item: availableReleaseBinding) { release in
|
||||
Alert(
|
||||
title: Text("Update Available"),
|
||||
message: Text("iKeyMon \(release.versionString) is available."),
|
||||
primaryButton: .default(Text("Download")) {
|
||||
updateViewModel.downloadLatest()
|
||||
},
|
||||
secondaryButton: .cancel(Text("Later"))
|
||||
)
|
||||
}
|
||||
.alert(item: statusAlertBinding) { alert in
|
||||
Alert(
|
||||
title: Text(alert.title),
|
||||
message: Text(alert.message),
|
||||
dismissButton: .default(Text("OK"))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchServerInfo(for id: UUID) {
|
||||
@@ -290,23 +265,9 @@ struct MainView: View {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
private var availableReleaseBinding: Binding<ReleaseInfo?> {
|
||||
Binding(
|
||||
get: { updateViewModel.availableRelease },
|
||||
set: { updateViewModel.availableRelease = $0 }
|
||||
)
|
||||
}
|
||||
|
||||
private var statusAlertBinding: Binding<UpdateViewModel.StatusAlert?> {
|
||||
Binding(
|
||||
get: { updateViewModel.statusAlert },
|
||||
set: { updateViewModel.statusAlert = $0 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
MainView()
|
||||
.environmentObject(UpdateViewModel())
|
||||
.environmentObject(SparkleUpdater())
|
||||
}
|
||||
|
||||
@@ -22,13 +22,11 @@ struct PreferencesView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
@EnvironmentObject private var updateViewModel: UpdateViewModel
|
||||
@EnvironmentObject private var sparkleUpdater: SparkleUpdater
|
||||
|
||||
@AppStorage("pingInterval") private var storedPingInterval: Int = 10
|
||||
@AppStorage("refreshInterval") private var storedRefreshInterval: Int = 60
|
||||
@AppStorage("showIntervalIndicator") private var showIntervalIndicator: Bool = true
|
||||
@AppStorage("autoCheckUpdates") private var autoCheckUpdates: Bool = true
|
||||
@AppStorage("includePrereleaseUpdates") private var includePrereleaseUpdates: Bool = true
|
||||
|
||||
@State private var pingIntervalSlider: Double = 10
|
||||
@State private var refreshIntervalSlider: Double = 60
|
||||
@@ -126,11 +124,8 @@ struct PreferencesView: View {
|
||||
case .alerts:
|
||||
AlertsPreferencesView()
|
||||
case .updates:
|
||||
UpdatesPreferencesView(
|
||||
autoCheckUpdates: $autoCheckUpdates,
|
||||
includePrereleaseUpdates: $includePrereleaseUpdates
|
||||
)
|
||||
.environmentObject(updateViewModel)
|
||||
UpdatesPreferencesView()
|
||||
.environmentObject(sparkleUpdater)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,46 +227,39 @@ private struct MonitorPreferencesView: View {
|
||||
}
|
||||
|
||||
private struct UpdatesPreferencesView: View {
|
||||
@Binding var autoCheckUpdates: Bool
|
||||
@Binding var includePrereleaseUpdates: Bool
|
||||
@EnvironmentObject var updateViewModel: UpdateViewModel
|
||||
@EnvironmentObject var sparkleUpdater: SparkleUpdater
|
||||
|
||||
private var automaticallyChecksBinding: Binding<Bool> {
|
||||
Binding(
|
||||
get: { sparkleUpdater.automaticallyChecksForUpdates },
|
||||
set: { sparkleUpdater.automaticallyChecksForUpdates = $0 }
|
||||
)
|
||||
}
|
||||
|
||||
private var automaticallyDownloadsBinding: Binding<Bool> {
|
||||
Binding(
|
||||
get: { sparkleUpdater.automaticallyDownloadsUpdates },
|
||||
set: { sparkleUpdater.automaticallyDownloadsUpdates = $0 }
|
||||
)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 16) {
|
||||
Toggle("Automatically check for updates", isOn: $autoCheckUpdates)
|
||||
.toggleStyle(.switch)
|
||||
VStack(alignment: .leading, spacing: 18) {
|
||||
Toggle("Automatically check for updates", isOn: automaticallyChecksBinding)
|
||||
Toggle("Automatically download updates", isOn: automaticallyDownloadsBinding)
|
||||
|
||||
Toggle("Include pre-release builds", isOn: $includePrereleaseUpdates)
|
||||
.toggleStyle(.switch)
|
||||
|
||||
HStack {
|
||||
if updateViewModel.isChecking {
|
||||
ProgressView()
|
||||
.progressViewStyle(.circular)
|
||||
Text("Checking for updates…")
|
||||
.foregroundColor(.secondary)
|
||||
} else {
|
||||
Button("Check Now") {
|
||||
updateViewModel.checkForUpdates(userInitiated: true)
|
||||
}
|
||||
}
|
||||
Button(action: sparkleUpdater.checkForUpdates) {
|
||||
Label("Check for Updates Now", systemImage: "sparkles")
|
||||
}
|
||||
|
||||
if let release = updateViewModel.latestFetchedRelease {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Latest available: \(release.versionString)")
|
||||
.font(.subheadline)
|
||||
if release.prerelease {
|
||||
Text("Pre-release build")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
Text("Updates are delivered via Sparkle. Configure your appcast URL and public EdDSA key in Info.plist (keys `SUFeedURL` and `SUPublicEDKey`).")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
.padding(.top, 4)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.toggleStyle(.switch)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user