From dc1a5b9b3ce08c95ebc0e7f5a7120e3141884b99 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Thu, 27 Nov 2025 14:06:51 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Make=20NVAlert=20invocatio?= =?UTF-8?q?n=20more=20consistent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- phpmon/Domain/App/AppUpdater.swift | 40 +++++++++++--------- phpmon/Domain/Menu/MainMenu+Actions.swift | 2 +- phpmon/Domain/Menu/MainMenu+FixMyValet.swift | 4 +- phpmon/Domain/Menu/MainMenu+Switcher.swift | 2 +- phpmon/Domain/PHP/PhpGuard.swift | 2 +- phpmon/Domain/Presets/Preset.swift | 2 +- 6 files changed, 29 insertions(+), 23 deletions(-) diff --git a/phpmon/Domain/App/AppUpdater.swift b/phpmon/Domain/App/AppUpdater.swift index ea6b24c4..58330402 100644 --- a/phpmon/Domain/App/AppUpdater.swift +++ b/phpmon/Domain/App/AppUpdater.swift @@ -29,32 +29,44 @@ class AppUpdater { var interactive: Bool = false public func checkForUpdates(userInitiated: Bool) async -> UpdateCheckResult { + // If user initiated, we always expect to see an alert self.interactive = userInitiated + // Log that we're looking for updates Log.info("The app will search for updates...") - let caskUrl = Constants.Urls.UpdateCheckEndpoint - - guard let caskFile = try? await CaskFile.fromUrl(App.shared.container, caskUrl) else { - await presentCouldNotRetrieveUpdateIfInteractive() + // Attempt to get the latest CaskFile from the API + guard let caskFile = try? await CaskFile.fromUrl( + App.shared.container, + Constants.Urls.UpdateCheckEndpoint + ) else { + // ERROR #1: The endpoint is unreachable or the response is invalid. + Log.err("Could not get a valid CaskFile from the endpoint.") + if interactive { + await presentCouldNotRetrieveUpdate() + } return .networkError } + // We will now persist the CaskFile so we can reference it later self.caskFile = caskFile - let currentVersion = AppVersion.fromCurrentVersion() - + // Let's parse the latest online version if we can guard let onlineVersion = AppVersion.from(caskFile.version) else { + // ERROR #2: The CaskFile's version string is invalid. Log.err("The version string from the CaskFile could not be read.") - await presentCouldNotRetrieveUpdateIfInteractive() + if interactive { + await presentCouldNotRetrieveUpdate() + } return .parseError } + // We will now persist the version number so we can reference it later latestVersionOnline = onlineVersion - Log.info("The latest version read from '\(caskUrl.lastPathComponent)' is: v\(onlineVersion.computerReadable).") + Log.info("The latest version read from the endpoint is: v\(onlineVersion.computerReadable).") Task { // Present this concurrently w/ returning the .success value - if latestVersionOnline > currentVersion { + if latestVersionOnline > AppVersion.fromCurrentVersion() { await presentNewerVersionAvailableAlert() } else if interactive { await presentNoNewerVersionAvailableAlert() @@ -64,12 +76,6 @@ class AppUpdater { return .success } - @MainActor private func presentCouldNotRetrieveUpdateIfInteractive() { - if interactive { - return presentCouldNotRetrieveUpdate() - } - } - // MARK: - Alerts @MainActor public func presentNewerVersionAvailableAlert() { @@ -117,7 +123,7 @@ class AppUpdater { description: "" ) .withPrimary(text: "generic.ok".localized) - .show(urgency: interactive ? .bringToFront : .none) + .show(urgency: .bringToFront) } @MainActor public func presentCouldNotRetrieveUpdate() { @@ -135,7 +141,7 @@ class AppUpdater { } ) .withPrimary(text: "generic.ok".localized) - .show(urgency: interactive ? .bringToFront : .normalRequestAttention) + .show(urgency: .bringToFront) } // MARK: - Preparing for Self-Updater diff --git a/phpmon/Domain/Menu/MainMenu+Actions.swift b/phpmon/Domain/Menu/MainMenu+Actions.swift index 9789c3a1..cbed971c 100644 --- a/phpmon/Domain/Menu/MainMenu+Actions.swift +++ b/phpmon/Domain/Menu/MainMenu+Actions.swift @@ -54,7 +54,7 @@ extension MainMenu { description: "alert.fix_homebrew_permissions_done.desc".localized ) .withPrimary(text: "generic.ok".localized) - .show(urgency: .urgentRequestAttention) + .show(urgency: .bringToFront) } failure: { error in NVAlert.show(for: error as! HomebrewPermissionError) } diff --git a/phpmon/Domain/Menu/MainMenu+FixMyValet.swift b/phpmon/Domain/Menu/MainMenu+FixMyValet.swift index 0da8020e..0e095d57 100644 --- a/phpmon/Domain/Menu/MainMenu+FixMyValet.swift +++ b/phpmon/Domain/Menu/MainMenu+FixMyValet.swift @@ -65,7 +65,7 @@ extension MainMenu { description: "alert.fix_my_valet_done.desc".localized ) .withPrimary(text: "generic.ok".localized) - .show(urgency: .normalRequestAttention) + .show(urgency: .bringToFront) } @MainActor private func presentAlertForDifferentVersion(version: String) { @@ -87,7 +87,7 @@ extension MainMenu { .withTertiary(text: "", action: { _ in NSWorkspace.shared.open(Constants.Urls.FrequentlyAskedQuestions) }) - .show(urgency: .urgentRequestAttention) + .show(urgency: .bringToFront) } } diff --git a/phpmon/Domain/Menu/MainMenu+Switcher.swift b/phpmon/Domain/Menu/MainMenu+Switcher.swift index 4addc502..0284449a 100644 --- a/phpmon/Domain/Menu/MainMenu+Switcher.swift +++ b/phpmon/Domain/Menu/MainMenu+Switcher.swift @@ -113,7 +113,7 @@ extension MainMenu { alert.close(with: .OK) self.terminateApp() }) - .show(urgency: .urgentRequestAttention) + .show(urgency: .bringToFront) } private func reloadDomainListData() async { diff --git a/phpmon/Domain/PHP/PhpGuard.swift b/phpmon/Domain/PHP/PhpGuard.swift index 3e56c1f9..4efb00a1 100644 --- a/phpmon/Domain/PHP/PhpGuard.swift +++ b/phpmon/Domain/PHP/PhpGuard.swift @@ -69,7 +69,7 @@ class PhpGuard { Stats.persistCurrentGlobalPhpVersion(version: currentVersion) alert.close(with: .OK) }) - .show(urgency: .normalRequestAttention) + .show(urgency: .urgentRequestAttention) } } } diff --git a/phpmon/Domain/Presets/Preset.swift b/phpmon/Domain/Presets/Preset.swift index 2f9de3fe..a654f0ee 100644 --- a/phpmon/Domain/Presets/Preset.swift +++ b/phpmon/Domain/Presets/Preset.swift @@ -153,7 +153,7 @@ struct Preset: Codable, Equatable { ) ).withPrimary( text: "alert.php_switch_unavailable.ok".localized - ).show(urgency: .urgentRequestAttention) + ).show(urgency: .bringToFront) } return false }