Improve ngrok authentication UX and move update settings

- Show alert dialog when attempting to enable ngrok without auth token
- Move update channel and check for updates from Advanced to General settings
- Place update controls under Application section for better accessibility
- Add AppKit import for NSAlert functionality
This commit is contained in:
Peter Steinberger 2025-06-16 06:07:03 +02:00
parent e8fb468a19
commit d4fae5631a
5 changed files with 16 additions and 10 deletions

View file

@ -950,7 +950,6 @@ public final class TunnelServer {
} }
} }
} }
}
private func getSessionSnapshot(sessionId: String) async -> Response { private func getSessionSnapshot(sessionId: String) async -> Response {
let streamOutPath = URL(fileURLWithPath: ttyFwdControlDir).appendingPathComponent(sessionId) let streamOutPath = URL(fileURLWithPath: ttyFwdControlDir).appendingPathComponent(sessionId)

View file

@ -1,4 +1,5 @@
import SwiftUI import SwiftUI
import AppKit
/// Represents the available tabs in the Settings window /// Represents the available tabs in the Settings window
enum SettingsTab: String, CaseIterable { enum SettingsTab: String, CaseIterable {
@ -460,6 +461,16 @@ struct AdvancedSettingsView: View {
print("No auth token found") print("No auth token found")
ngrokError = "Please enter your ngrok auth token first" ngrokError = "Please enter your ngrok auth token first"
ngrokEnabled = false ngrokEnabled = false
// Show alert dialog
Task { @MainActor in
let alert = NSAlert()
alert.messageText = "ngrok Auth Token Required"
alert.informativeText = "Please enter your ngrok auth token before enabling the tunnel. You can get a free auth token at ngrok.com"
alert.alertStyle = .warning
alert.addButton(withTitle: "OK")
alert.runModal()
}
return return
} }

View file

@ -159,23 +159,22 @@ final class ApplicationMover {
task.standardError = Pipe() // Suppress stderr task.standardError = Pipe() // Suppress stderr
do { do {
logger.info("ApplicationMover: Running hdiutil info -plist") logger.debug("ApplicationMover: Running hdiutil info -plist")
try task.run() try task.run()
task.waitUntilExit() task.waitUntilExit()
guard task.terminationStatus == 0 else { guard task.terminationStatus == 0 else {
logger.warning("ApplicationMover: hdiutil command failed with status: \(task.terminationStatus)") logger.debug("ApplicationMover: hdiutil command failed with status: \(task.terminationStatus)")
return nil return nil
} }
let data = pipe.fileHandleForReading.readDataToEndOfFile() let data = pipe.fileHandleForReading.readDataToEndOfFile()
logger.info("ApplicationMover: hdiutil returned \(data.count) bytes") logger.debug("ApplicationMover: hdiutil returned \(data.count) bytes")
guard let plist = try PropertyListSerialization guard let plist = try PropertyListSerialization
.propertyList(from: data, options: [], format: nil) as? [String: Any], .propertyList(from: data, options: [], format: nil) as? [String: Any],
let images = plist["images"] as? [[String: Any]] else { let images = plist["images"] as? [[String: Any]] else {
logger.info("ApplicationMover: Failed to parse hdiutil plist or no images found") logger.debug("ApplicationMover: No disk images found in hdiutil output")
logger.warning("Failed to parse hdiutil output")
return nil return nil
} }
@ -196,7 +195,7 @@ final class ApplicationMover {
return nil return nil
} catch { } catch {
logger.error("Error running hdiutil: \(error)") logger.debug("ApplicationMover: Unable to run hdiutil (expected in some environments): \(error)")
return nil return nil
} }
} }

View file

@ -13,9 +13,6 @@ struct MenuBarView: View {
.padding(.horizontal, 12) .padding(.horizontal, 12)
.padding(.vertical, 8) .padding(.vertical, 8)
Divider()
.padding(.horizontal, 12)
// Open Dashboard button // Open Dashboard button
Button(action: { Button(action: {
let dashboardURL = URL(string: "http://127.0.0.1:\(serverMonitor.port)")! let dashboardURL = URL(string: "http://127.0.0.1:\(serverMonitor.port)")!