mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-11 20:36:39 +00:00
macOS: Make a lot of things more robust
This commit is contained in:
@@ -998,8 +998,8 @@ class AppDelegate: NSObject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func checkForUpdates(_ sender: Any?) {
|
@IBAction func checkForUpdates(_ sender: Any?) {
|
||||||
updateController.checkForUpdates()
|
//updateController.checkForUpdates()
|
||||||
//UpdateSimulator.permissionRequest.simulate(with: updateViewModel)
|
UpdateSimulator.happyPath.simulate(with: updateViewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -17,14 +17,14 @@ struct UpdateBadge: View {
|
|||||||
switch model.state {
|
switch model.state {
|
||||||
case .downloading(let download):
|
case .downloading(let download):
|
||||||
if let expectedLength = download.expectedLength, expectedLength > 0 {
|
if let expectedLength = download.expectedLength, expectedLength > 0 {
|
||||||
let progress = Double(download.progress) / Double(expectedLength)
|
let progress = min(1, max(0, Double(download.progress) / Double(expectedLength)))
|
||||||
ProgressRingView(progress: progress)
|
ProgressRingView(progress: progress)
|
||||||
} else {
|
} else {
|
||||||
Image(systemName: "arrow.down.circle")
|
Image(systemName: "arrow.down.circle")
|
||||||
}
|
}
|
||||||
|
|
||||||
case .extracting(let extracting):
|
case .extracting(let extracting):
|
||||||
ProgressRingView(progress: extracting.progress)
|
ProgressRingView(progress: min(1, max(0, extracting.progress)))
|
||||||
|
|
||||||
case .checking, .installing:
|
case .checking, .installing:
|
||||||
if let iconName = model.iconName {
|
if let iconName = model.iconName {
|
||||||
|
@@ -32,9 +32,22 @@ class UpdateController {
|
|||||||
/// Start the updater.
|
/// Start the updater.
|
||||||
///
|
///
|
||||||
/// This must be called before the updater can check for updates. If starting fails,
|
/// This must be called before the updater can check for updates. If starting fails,
|
||||||
/// an error alert will be shown after a short delay.
|
/// the error will be shown to the user.
|
||||||
func startUpdater() {
|
func startUpdater() {
|
||||||
try? updater.start()
|
do {
|
||||||
|
try updater.start()
|
||||||
|
} catch {
|
||||||
|
userDriver.viewModel.state = .error(.init(
|
||||||
|
error: error,
|
||||||
|
retry: { [weak self] in
|
||||||
|
self?.userDriver.viewModel.state = .idle
|
||||||
|
self?.startUpdater()
|
||||||
|
},
|
||||||
|
dismiss: { [weak self] in
|
||||||
|
self?.userDriver.viewModel.state = .idle
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check for updates.
|
/// Check for updates.
|
||||||
|
@@ -86,9 +86,10 @@ class UpdateDriver: NSObject, SPUUserDriver {
|
|||||||
acknowledgement: @escaping () -> Void) {
|
acknowledgement: @escaping () -> Void) {
|
||||||
viewModel.state = .error(.init(
|
viewModel.state = .error(.init(
|
||||||
error: error,
|
error: error,
|
||||||
retry: { [weak viewModel] in
|
retry: { [weak self, weak viewModel] in
|
||||||
viewModel?.state = .idle
|
viewModel?.state = .idle
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
guard let delegate = NSApp.delegate as? AppDelegate else { return }
|
guard let delegate = NSApp.delegate as? AppDelegate else { return }
|
||||||
delegate.checkForUpdates(self)
|
delegate.checkForUpdates(self)
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,9 @@ struct UpdatePill: View {
|
|||||||
/// Whether the update popover is currently visible
|
/// Whether the update popover is currently visible
|
||||||
@State private var showPopover = false
|
@State private var showPopover = false
|
||||||
|
|
||||||
|
/// Task for auto-dismissing the "No Updates" state
|
||||||
|
@State private var resetTask: Task<Void, Never>?
|
||||||
|
|
||||||
/// The font used for the pill text
|
/// The font used for the pill text
|
||||||
private let textFont = NSFont.systemFont(ofSize: 11, weight: .medium)
|
private let textFont = NSFont.systemFont(ofSize: 11, weight: .medium)
|
||||||
|
|
||||||
@@ -19,13 +22,15 @@ struct UpdatePill: View {
|
|||||||
}
|
}
|
||||||
.transition(.opacity.combined(with: .scale(scale: 0.95)))
|
.transition(.opacity.combined(with: .scale(scale: 0.95)))
|
||||||
.onChange(of: model.state) { newState in
|
.onChange(of: model.state) { newState in
|
||||||
|
resetTask?.cancel()
|
||||||
if case .notFound = newState {
|
if case .notFound = newState {
|
||||||
Task {
|
resetTask = Task { [weak model] in
|
||||||
try? await Task.sleep(for: .seconds(5))
|
try? await Task.sleep(for: .seconds(5))
|
||||||
if case .notFound = model.state {
|
guard !Task.isCancelled, case .notFound? = model?.state else { return }
|
||||||
model.state = .idle
|
model?.state = .idle
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
resetTask = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -228,7 +228,7 @@ fileprivate struct DownloadingView: View {
|
|||||||
.font(.system(size: 13, weight: .semibold))
|
.font(.system(size: 13, weight: .semibold))
|
||||||
|
|
||||||
if let expectedLength = download.expectedLength, expectedLength > 0 {
|
if let expectedLength = download.expectedLength, expectedLength > 0 {
|
||||||
let progress = Double(download.progress) / Double(expectedLength)
|
let progress = min(1, max(0, Double(download.progress) / Double(expectedLength)))
|
||||||
VStack(alignment: .leading, spacing: 6) {
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
ProgressView(value: progress)
|
ProgressView(value: progress)
|
||||||
Text(String(format: "%.0f%%", progress * 100))
|
Text(String(format: "%.0f%%", progress * 100))
|
||||||
@@ -264,8 +264,8 @@ fileprivate struct ExtractingView: View {
|
|||||||
.font(.system(size: 13, weight: .semibold))
|
.font(.system(size: 13, weight: .semibold))
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 6) {
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
ProgressView(value: extracting.progress, total: 1.0)
|
ProgressView(value: min(1, max(0, extracting.progress)), total: 1.0)
|
||||||
Text(String(format: "%.0f%%", extracting.progress * 100))
|
Text(String(format: "%.0f%%", min(1, max(0, extracting.progress)) * 100))
|
||||||
.font(.system(size: 11))
|
.font(.system(size: 11))
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user