diff --git a/Sources/Firelink/Aria2DownloadEngine.swift b/Sources/Firelink/Aria2DownloadEngine.swift index 0938a4e..d23ca0c 100644 --- a/Sources/Firelink/Aria2DownloadEngine.swift +++ b/Sources/Firelink/Aria2DownloadEngine.swift @@ -57,6 +57,32 @@ final class Aria2DownloadEngine { return nil } + static func versionString() -> String? { + guard let executableURL = findExecutable() else { return nil } + + let process = Process() + let outputPipe = Pipe() + process.executableURL = executableURL + process.arguments = ["--version"] + process.standardOutput = outputPipe + process.standardError = Pipe() + + do { + try process.run() + process.waitUntilExit() + guard process.terminationStatus == 0 else { return nil } + + let data = outputPipe.fileHandleForReading.readDataToEndOfFile() + let output = String(data: data, encoding: .utf8) ?? "" + return output + .split(whereSeparator: { $0 == "\n" || $0 == "\r" }) + .first + .map(String.init) + } catch { + return nil + } + } + func start( item: DownloadItem, proxyConfiguration: DownloadProxyConfiguration, diff --git a/Sources/Firelink/SettingsView.swift b/Sources/Firelink/SettingsView.swift index aa09202..009cec2 100644 --- a/Sources/Firelink/SettingsView.swift +++ b/Sources/Firelink/SettingsView.swift @@ -6,6 +6,7 @@ private enum SettingsSection: String, CaseIterable, Hashable { case locations = "Locations" case siteLogins = "Site Logins" case power = "Power" + case engine = "Engine" var symbolName: String { switch self { @@ -14,6 +15,7 @@ private enum SettingsSection: String, CaseIterable, Hashable { case .locations: "folder" case .siteLogins: "key.fill" case .power: "moon.zzz" + case .engine: "terminal" } } } @@ -73,10 +75,55 @@ struct SettingsView: View { SiteLoginsSettingsPane() case .power: PowerSettingsPane() + case .engine: + EngineSettingsPane() } } } +private struct EngineSettingsPane: View { + private var executableURL: URL? { + Aria2DownloadEngine.findExecutable() + } + + private var version: String { + Aria2DownloadEngine.versionString() ?? "Unavailable" + } + + var body: some View { + Form { + Section { + LabeledContent("Status") { + Label( + executableURL == nil ? "Missing" : "Ready", + systemImage: executableURL == nil ? "exclamationmark.triangle.fill" : "checkmark.seal.fill" + ) + .foregroundStyle(executableURL == nil ? .orange : .green) + } + + LabeledContent("Binary") { + Text(executableURL?.path ?? "Not found") + .font(.system(.body, design: .monospaced)) + .textSelection(.enabled) + } + + LabeledContent("Version") { + Text(version) + .font(.system(.body, design: .monospaced)) + .textSelection(.enabled) + } + + if executableURL == nil { + Text("Install aria2 with Homebrew or bundle aria2c inside the app resources.") + .font(.caption) + .foregroundStyle(.secondary) + } + } + } + .formStyle(.grouped) + } +} + private struct NetworkSettingsPane: View { @EnvironmentObject private var settings: AppSettings diff --git a/Sources/Firelink/SidebarView.swift b/Sources/Firelink/SidebarView.swift index 5a81279..264c781 100644 --- a/Sources/Firelink/SidebarView.swift +++ b/Sources/Firelink/SidebarView.swift @@ -56,14 +56,6 @@ struct SidebarView: View { .tag(SidebarSelection.downloads(.category(category))) } } - - Section("Engine") { - HStack { - Image(systemName: controller.hasAria2 ? "checkmark.seal.fill" : "exclamationmark.triangle.fill") - .foregroundStyle(controller.hasAria2 ? .green : .orange) - Text(controller.hasAria2 ? "aria2c ready" : "aria2c missing") - } - } } .listStyle(.sidebar) .safeAreaInset(edge: .bottom) {