6 Commits
5 changed files with 18 additions and 8 deletions
+2 -1
View File
@@ -4,8 +4,9 @@ import SwiftUI
/// Sidebar tab showing currently breached thresholds and the in-app /// Sidebar tab showing currently breached thresholds and the in-app
/// alert history log maintained by `AlertEngine`. /// alert history log maintained by `AlertEngine`.
@MainActor
public struct AlertsView: View { public struct AlertsView: View {
@State private var engine = AlertEngine.shared @ObservedObject private var engine = AlertEngine.shared
public init() {} public init() {}
+12 -6
View File
@@ -1,5 +1,6 @@
import SwiftUI import SwiftUI
@MainActor
public struct ContentView: View { public struct ContentView: View {
@StateObject private var store = SystemTelemetryStore.shared @StateObject private var store = SystemTelemetryStore.shared
@State private var selectedTab: String? = "Dashboard" @State private var selectedTab: String? = "Dashboard"
@@ -168,7 +169,7 @@ public struct ContentView: View {
} }
.padding(24) .padding(24)
} }
.navigationTitle("MacMonitor — \(selectedTab)") .navigationTitle("MacMonitor — \(selectedTab ?? "Dashboard")")
} }
// MARK: - Dashboard Composite View // MARK: - Dashboard Composite View
@@ -1005,8 +1006,6 @@ public struct ContentView: View {
HStack { HStack {
Text("Target Architecture:").foregroundStyle(.secondary) Text("Target Architecture:").foregroundStyle(.secondary)
Text("Intel x86_64").bold() Text("Intel x86_64").bold()
Text("Deployment Target:").foregroundStyle(.secondary)
Text("macOS 14.0 (Sonoma)").bold()
} }
} }
} }
@@ -1220,6 +1219,7 @@ public struct ContentView: View {
} }
// MARK: - Process Detail Inspector Sheet // MARK: - Process Detail Inspector Sheet
@MainActor
struct ProcessDetailSheet: View { struct ProcessDetailSheet: View {
let inspector: MMProcessDetailInspector let inspector: MMProcessDetailInspector
let pid: Int32 let pid: Int32
@@ -1248,8 +1248,9 @@ struct ProcessDetailSheet: View {
if selectedDetailTab == "Threads" { if selectedDetailTab == "Threads" {
List(threads.indices, id: \.self) { idx in List(threads.indices, id: \.self) { idx in
let t = threads[idx] let t = threads[idx]
let threadID = "\(t["threadID"] ?? idx)"
HStack { HStack {
Text("Thread \(t["threadID"] ?? idx)").bold() Text("Thread \(threadID)").bold()
Spacer() Spacer()
Text("CPU: \(String(format: "%.1f%%", (t["cpuPercent"] as? Double) ?? 0.0))").monospacedDigit() Text("CPU: \(String(format: "%.1f%%", (t["cpuPercent"] as? Double) ?? 0.0))").monospacedDigit()
Text(t["state"] as? String ?? "").foregroundStyle(.secondary) Text(t["state"] as? String ?? "").foregroundStyle(.secondary)
@@ -1262,10 +1263,15 @@ struct ProcessDetailSheet: View {
} else { } else {
List(sockets.indices, id: \.self) { idx in List(sockets.indices, id: \.self) { idx in
let s = sockets[idx] let s = sockets[idx]
let proto = s["protocol"] as? String ?? "TCP"
let localAddr = (s["localAddress"] as? String) ?? ""
let localPort = (s["localPort"] as? Int) ?? 0
let remoteAddr = (s["remoteAddress"] as? String) ?? ""
let remotePort = (s["remotePort"] as? Int) ?? 0
HStack { HStack {
Text(s["protocol"] as? String ?? "TCP").bold() Text(proto).bold()
Spacer() Spacer()
Text("\(s["localAddress"] ?? ""):\(s["localPort"] ?? 0) → \(s["remoteAddress"] ?? ""):\(s["remotePort"] ?? 0)") Text("\(localAddr):\(localPort) → \(remoteAddr):\(remotePort)")
.mmMonospaced() .mmMonospaced()
Text(s["tcpState"] as? String ?? "").foregroundStyle(.secondary) Text(s["tcpState"] as? String ?? "").foregroundStyle(.secondary)
} }
@@ -1,7 +1,8 @@
import SwiftUI import SwiftUI
@MainActor
public struct QuickGlancePopoverView: View { public struct QuickGlancePopoverView: View {
var store: SystemTelemetryStore @ObservedObject var store: SystemTelemetryStore
public init(store: SystemTelemetryStore) { public init(store: SystemTelemetryStore) {
self.store = store self.store = store
@@ -5,6 +5,7 @@ import UserNotifications
/// Preferences UI for threshold alert rules. Bound directly to /// Preferences UI for threshold alert rules. Bound directly to
/// `AlertEngine.shared.configuration`, which auto-persists to `UserDefaults`. /// `AlertEngine.shared.configuration`, which auto-persists to `UserDefaults`.
@MainActor
public struct AlertsSettingsView: View { public struct AlertsSettingsView: View {
@ObservedObject private var engine = AlertEngine.shared @ObservedObject private var engine = AlertEngine.shared
@State private var authorizationStatus: UNAuthorizationStatus = .notDetermined @State private var authorizationStatus: UNAuthorizationStatus = .notDetermined
+1
View File
@@ -2,6 +2,7 @@ import XCTest
import SwiftUI import SwiftUI
@testable import MacMonitor @testable import MacMonitor
@MainActor
final class MMMenuBarTests: XCTestCase { final class MMMenuBarTests: XCTestCase {
func testMenuBarStatusViewInitialization() { func testMenuBarStatusViewInitialization() {