import AppKit import SwiftUI struct NewTaskView: View { @Binding var isPresented: Bool @State private var path = "" @State private var errorMessage: String? var body: some View { VStack(alignment: .leading, spacing: 18) { HStack(spacing: 14) { Image(systemName: "plus.square.dashed") .font(.system(size: 32)) .foregroundStyle(.tint) VStack(alignment: .leading, spacing: 3) { Text("Run new task").font(.title2.weight(.semibold)) Text("Open an application, document, or executable.").foregroundStyle(.secondary) } } HStack { TextField("Application or executable path", text: $path) .textFieldStyle(.roundedBorder) .onSubmit { launch() } Button("Browse…") { browse() } } if let errorMessage { Label(errorMessage, systemImage: "exclamationmark.triangle.fill") .font(.callout) .foregroundStyle(.red) } HStack { Text("Tip: drag an app or file from Finder into the path field.") .font(.caption) .foregroundStyle(.secondary) Spacer() Button("Cancel") { isPresented = false } .keyboardShortcut(.cancelAction) Button("Run") { launch() } .keyboardShortcut(.defaultAction) .buttonStyle(.borderedProminent) .disabled(path.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty) } } .padding(24) .frame(width: 560) } private func browse() { let panel = NSOpenPanel() panel.title = "Choose an application, executable, or document" panel.canChooseDirectories = false panel.canChooseFiles = true panel.allowsMultipleSelection = false if panel.runModal() == .OK, let url = panel.url { path = url.path } } private func launch() { let cleaned = (path as NSString).expandingTildeInPath.trimmingCharacters(in: .whitespacesAndNewlines) let url = URL(fileURLWithPath: cleaned) guard FileManager.default.fileExists(atPath: cleaned) else { errorMessage = "That file could not be found." return } if NSWorkspace.shared.open(url) { isPresented = false } else { errorMessage = "macOS could not open this item." } } } struct SettingsView: View { @Environment(SystemMonitor.self) private var monitor @AppStorage("alwaysOnTop") private var alwaysOnTop = false @AppStorage("defaultStartPage") private var defaultStartPage: TaskSection = .processes @AppStorage("diagnosticReportDuration") private var diagnosticDuration = 5 @AppStorage("diagnosticAskEveryTime") private var diagnosticAskEveryTime = true @AppStorage("diagnosticReportDirectory") private var diagnosticDirectory = "" var body: some View { @Bindable var monitor = monitor VStack(spacing: 0) { PageHeader(title: "Settings", subtitle: "Customize Puter") Form { Section("General") { Picker("Default start page", selection: $defaultStartPage) { ForEach(TaskSection.allCases.filter { $0 != .settings }) { section in Text(section.rawValue).tag(section) } } Picker("Real-time update speed", selection: $monitor.updateSpeed) { ForEach(UpdateSpeed.allCases) { speed in Text(speed.rawValue).tag(speed) } } Toggle("Always on top", isOn: $alwaysOnTop) .onChange(of: alwaysOnTop) { _, enabled in NSApp.keyWindow?.level = enabled ? .floating : .normal } } Section("Process data") { LabeledContent("Refresh interval", value: intervalLabel) LabeledContent("Process source", value: "macOS process table") LabeledContent("Memory units", value: "Automatic") } Section("Diagnostic reports") { Picker("Sample duration", selection: $diagnosticDuration) { Text("1 second").tag(1) Text("5 seconds").tag(5) Text("10 seconds").tag(10) } Toggle("Ask where to save each report", isOn: $diagnosticAskEveryTime) LabeledContent("Output folder") { HStack(spacing: 10) { Text(diagnosticDirectory.isEmpty ? "Not selected" : URL(fileURLWithPath: diagnosticDirectory).lastPathComponent) .foregroundStyle(.secondary) Button("Choose…") { chooseDiagnosticDirectory() } } } } Section("About") { LabeledContent("Application", value: "Puter") LabeledContent("Version", value: appVersion) LabeledContent("Framework", value: "Native SwiftUI") } } .formStyle(.grouped) .scrollContentBackground(.hidden) .frame(maxWidth: 720) .frame(maxWidth: .infinity, alignment: .leading) } .task { NSApp.keyWindow?.level = alwaysOnTop ? .floating : .normal } } private var intervalLabel: String { switch monitor.updateSpeed { case .high: "Every second" case .normal: "Every 2 seconds" case .low: "Every 5 seconds" case .paused: "Paused" } } private var appVersion: String { Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "Development" } private func chooseDiagnosticDirectory() { let panel = NSOpenPanel() panel.title = "Choose diagnostic report folder" panel.prompt = "Choose" panel.canChooseFiles = false panel.canChooseDirectories = true panel.allowsMultipleSelection = false if !diagnosticDirectory.isEmpty { panel.directoryURL = URL(fileURLWithPath: diagnosticDirectory, isDirectory: true) } if panel.runModal() == .OK, let url = panel.url { diagnosticDirectory = url.path } } }