diff --git a/DynamicIsland/components/Notch/NotchStatsView.swift b/DynamicIsland/components/Notch/NotchStatsView.swift index 8bfc75a..6deac34 100644 --- a/DynamicIsland/components/Notch/NotchStatsView.swift +++ b/DynamicIsland/components/Notch/NotchStatsView.swift @@ -90,8 +90,8 @@ struct NotchStatsView: View { if showNetworkGraph { graphs.append(DualGraphData( title: "Network", - positiveValue: String(format: "↓%.1f MB/s", statsManager.networkDownload), - negativeValue: String(format: "↑%.1f MB/s", statsManager.networkUpload), + positiveValue: "↓" + statsManager.networkDownloadString, + negativeValue: "↑" + statsManager.networkUploadString, positiveData: statsManager.networkDownloadHistory, negativeData: statsManager.networkUploadHistory, positiveColor: .orange, @@ -104,8 +104,8 @@ struct NotchStatsView: View { if showDiskGraph { graphs.append(DualGraphData( title: "Disk", - positiveValue: String(format: "R %.1f MB/s", statsManager.diskRead), - negativeValue: String(format: "W %.1f MB/s", statsManager.diskWrite), + positiveValue: "R " + statsManager.diskReadString, + negativeValue: "W " + statsManager.diskWriteString, positiveData: statsManager.diskReadHistory, negativeData: statsManager.diskWriteHistory, positiveColor: .cyan, diff --git a/DynamicIsland/components/Stats/DetailedTimelineGraph.swift b/DynamicIsland/components/Stats/DetailedTimelineGraph.swift new file mode 100644 index 0000000..e69de29 diff --git a/DynamicIsland/components/Stats/DualTimelineGraph.swift b/DynamicIsland/components/Stats/DualTimelineGraph.swift new file mode 100644 index 0000000..e69de29 diff --git a/DynamicIsland/components/Stats/StatsPanel.swift b/DynamicIsland/components/Stats/StatsPanel.swift index ef98789..b6b8f0e 100644 --- a/DynamicIsland/components/Stats/StatsPanel.swift +++ b/DynamicIsland/components/Stats/StatsPanel.swift @@ -64,7 +64,7 @@ class StatsPanel: NSPanel { self.contentView = hostingView // Set initial size - let preferredSize = CGSize(width: 600, height: 500) + let preferredSize = CGSize(width: 600, height: 400) hostingView.setFrameSize(preferredSize) setContentSize(preferredSize) } diff --git a/DynamicIsland/components/Stats/StatsPanelView.swift b/DynamicIsland/components/Stats/StatsPanelView.swift index 72f02d6..149eae3 100644 --- a/DynamicIsland/components/Stats/StatsPanelView.swift +++ b/DynamicIsland/components/Stats/StatsPanelView.swift @@ -125,7 +125,7 @@ struct StatsPanelView: View { .padding(16) } } - .frame(width: 600, height: 500) + .frame(width: 650, height: 300) .background(VisualEffectView(material: .hudWindow, blendingMode: .behindWindow)) .cornerRadius(12) .shadow(color: .black.opacity(0.4), radius: 20, x: 0, y: 10) diff --git a/DynamicIsland/managers/StatsManager.swift b/DynamicIsland/managers/StatsManager.swift index db8fdc7..f332de7 100644 --- a/DynamicIsland/managers/StatsManager.swift +++ b/DynamicIsland/managers/StatsManager.swift @@ -75,6 +75,15 @@ class StatsManager: ObservableObject { func startMonitoring() { guard !isMonitoring else { return } + // Reset baseline for accurate measurement + let initialStats = getNetworkStats() + previousNetworkStats = initialStats + + let initialDiskStats = getDiskStats() + previousDiskStats = initialDiskStats + + previousTimestamp = Date() + isMonitoring = true lastUpdated = Date() @@ -108,19 +117,35 @@ class StatsManager: ObservableObject { let currentTime = Date() let timeInterval = currentTime.timeIntervalSince(previousTimestamp) - let bytesDownloaded = currentNetworkStats.bytesIn - previousNetworkStats.bytesIn - let bytesUploaded = currentNetworkStats.bytesOut - previousNetworkStats.bytesOut + var downloadSpeed: Double = 0.0 + var uploadSpeed: Double = 0.0 - let downloadSpeed = timeInterval > 0 ? Double(bytesDownloaded) / timeInterval / 1_048_576 : 0.0 // Convert to MB/s - let uploadSpeed = timeInterval > 0 ? Double(bytesUploaded) / timeInterval / 1_048_576 : 0.0 // Convert to MB/s + // Only calculate speeds if we have a reasonable time interval and previous data + if timeInterval > 0.1 && previousNetworkStats.bytesIn > 0 && previousNetworkStats.bytesOut > 0 { + let bytesDownloaded = currentNetworkStats.bytesIn > previousNetworkStats.bytesIn ? + currentNetworkStats.bytesIn - previousNetworkStats.bytesIn : 0 + let bytesUploaded = currentNetworkStats.bytesOut > previousNetworkStats.bytesOut ? + currentNetworkStats.bytesOut - previousNetworkStats.bytesOut : 0 + + downloadSpeed = Double(bytesDownloaded) / timeInterval / 1_048_576 // Convert to MB/s + uploadSpeed = Double(bytesUploaded) / timeInterval / 1_048_576 // Convert to MB/s + } // Calculate disk speeds let currentDiskStats = getDiskStats() - let bytesRead = currentDiskStats.bytesRead - previousDiskStats.bytesRead - let bytesWritten = currentDiskStats.bytesWritten - previousDiskStats.bytesWritten + var readSpeed: Double = 0.0 + var writeSpeed: Double = 0.0 - let readSpeed = timeInterval > 0 ? Double(bytesRead) / timeInterval / 1_048_576 : 0.0 // Convert to MB/s - let writeSpeed = timeInterval > 0 ? Double(bytesWritten) / timeInterval / 1_048_576 : 0.0 // Convert to MB/s + // Only calculate speeds if we have a reasonable time interval and previous data + if timeInterval > 0.1 && previousDiskStats.bytesRead > 0 && previousDiskStats.bytesWritten > 0 { + let bytesRead = currentDiskStats.bytesRead > previousDiskStats.bytesRead ? + currentDiskStats.bytesRead - previousDiskStats.bytesRead : 0 + let bytesWritten = currentDiskStats.bytesWritten > previousDiskStats.bytesWritten ? + currentDiskStats.bytesWritten - previousDiskStats.bytesWritten : 0 + + readSpeed = Double(bytesRead) / timeInterval / 1_048_576 // Convert to MB/s + writeSpeed = Double(bytesWritten) / timeInterval / 1_048_576 // Convert to MB/s + } // Update current values cpuUsage = newCpuUsage @@ -136,8 +161,8 @@ class StatsManager: ObservableObject { updateHistory(value: newCpuUsage, history: &cpuHistory) updateHistory(value: newMemoryUsage, history: &memoryHistory) updateHistory(value: newGpuUsage, history: &gpuHistory) - updateHistory(value: networkDownload, history: &networkDownloadHistory) - updateHistory(value: networkUpload, history: &networkUploadHistory) + updateHistory(value: downloadSpeed, history: &networkDownloadHistory) + updateHistory(value: uploadSpeed, history: &networkUploadHistory) updateHistory(value: readSpeed, history: &diskReadHistory) updateHistory(value: writeSpeed, history: &diskWriteHistory) @@ -243,14 +268,22 @@ class StatsManager: ObservableObject { } let name = String(cString: interface.ifa_name) - // Skip loopback and non-active interfaces - guard !name.hasPrefix("lo") && !name.hasPrefix("gif") && !name.hasPrefix("stf") else { + // Skip loopback and virtual interfaces, but include en0, en1, etc. and Wi-Fi interfaces + guard !name.hasPrefix("lo") && + !name.hasPrefix("gif") && + !name.hasPrefix("stf") && + !name.hasPrefix("bridge") && + !name.hasPrefix("utun") && + !name.hasPrefix("awdl") else { continue } - if let data = interface.ifa_data?.assumingMemoryBound(to: if_data.self) { - totalBytesIn += UInt64(data.pointee.ifi_ibytes) - totalBytesOut += UInt64(data.pointee.ifi_obytes) + // Only count active interfaces (en0, en1, etc.) + if name.hasPrefix("en") || name.contains("Wi-Fi") { + if let data = interface.ifa_data?.assumingMemoryBound(to: if_data.self) { + totalBytesIn += UInt64(data.pointee.ifi_ibytes) + totalBytesOut += UInt64(data.pointee.ifi_obytes) + } } }