Working stuff

This commit is contained in:
Hariharan Mudaliar 2025-10-19 08:43:58 +05:30
commit 7a1945dd21
5 changed files with 162 additions and 30 deletions

View file

@ -73,11 +73,11 @@ private struct NetworkOverview: View {
Text("Download")
.font(.headline)
.foregroundColor(downloadColor)
Text(StatsFormatting.mbPerSecond(download))
Text(StatsFormatting.throughput(download))
.font(.system(size: 26, weight: .bold, design: .rounded))
.foregroundColor(.primary)
DetailRow(color: downloadColor.opacity(0.6), label: "Average", value: StatsFormatting.mbPerSecond(avgDownload))
DetailRow(color: downloadColor.opacity(0.45), label: "Peak", value: StatsFormatting.mbPerSecond(peakDownload))
DetailRow(color: downloadColor.opacity(0.6), label: "Average", value: StatsFormatting.throughput(avgDownload))
DetailRow(color: downloadColor.opacity(0.45), label: "Peak", value: StatsFormatting.throughput(peakDownload))
}
.frame(maxWidth: .infinity, alignment: .leading)
@ -89,11 +89,11 @@ private struct NetworkOverview: View {
Text("Upload")
.font(.headline)
.foregroundColor(uploadColor)
Text(StatsFormatting.mbPerSecond(upload))
Text(StatsFormatting.throughput(upload))
.font(.system(size: 26, weight: .bold, design: .rounded))
.foregroundColor(.primary)
DetailRow(color: uploadColor.opacity(0.6), label: "Average", value: StatsFormatting.mbPerSecond(avgUpload))
DetailRow(color: uploadColor.opacity(0.45), label: "Peak", value: StatsFormatting.mbPerSecond(peakUpload))
DetailRow(color: uploadColor.opacity(0.6), label: "Average", value: StatsFormatting.throughput(avgUpload))
DetailRow(color: uploadColor.opacity(0.45), label: "Peak", value: StatsFormatting.throughput(peakUpload))
}
.frame(maxWidth: .infinity, alignment: .leading)
}
@ -213,8 +213,8 @@ private struct NetworkInterfaceRow: View {
Spacer()
VStack(alignment: .trailing, spacing: 4) {
metricRow(label: "Down", value: StatsFormatting.mbPerSecond(interface.currentDownload), color: downloadColor)
metricRow(label: "Up", value: StatsFormatting.mbPerSecond(interface.currentUpload), color: uploadColor)
metricRow(label: "Down", value: StatsFormatting.throughput(interface.currentDownload), color: downloadColor)
metricRow(label: "Up", value: StatsFormatting.throughput(interface.currentUpload), color: uploadColor)
}
}
}

View file

@ -6,6 +6,9 @@
// Adapted from boring.notch implementation
import SwiftUI
#if os(macOS)
import AppKit
#endif
struct RankedProcessPopover: View {
let rankingType: ProcessRankingType
@ -44,8 +47,12 @@ struct RankedProcessPopover: View {
}
.buttonStyle(PlainButtonStyle())
}
.onHover { hovering in
onHoverChange?(hovering)
.overlay(alignment: .center) {
PopoverHoverSensor { hovering in
onHoverChange?(hovering)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.allowsHitTesting(false)
}
}
@ -64,4 +71,51 @@ struct RankedProcessPopover: View {
DiskStatsDetailView()
}
}
}
}
#if os(macOS)
private struct PopoverHoverSensor: NSViewRepresentable {
var onHoverChange: ((Bool) -> Void)?
func makeNSView(context: Context) -> TrackingView {
let view = TrackingView()
view.onHoverChange = onHoverChange
return view
}
func updateNSView(_ nsView: TrackingView, context: Context) {
nsView.onHoverChange = onHoverChange
}
final class TrackingView: NSView {
var onHoverChange: ((Bool) -> Void)?
private var trackingArea: NSTrackingArea?
override func updateTrackingAreas() {
super.updateTrackingAreas()
if let trackingArea {
removeTrackingArea(trackingArea)
}
let options: NSTrackingArea.Options = [.mouseEnteredAndExited, .activeAlways, .inVisibleRect]
let area = NSTrackingArea(rect: bounds, options: options, owner: self, userInfo: nil)
addTrackingArea(area)
trackingArea = area
}
override func mouseEntered(with event: NSEvent) {
onHoverChange?(true)
}
override func mouseExited(with event: NSEvent) {
onHoverChange?(false)
}
deinit {
onHoverChange?(false)
if let trackingArea {
removeTrackingArea(trackingArea)
}
}
}
}
#endif

View file

@ -26,6 +26,36 @@ enum StatsFormatting {
let formatted = formatter.string(from: number) ?? String(format: "%.2f", value)
return "\(formatted) MB/s"
}
static func throughput(_ valueInMegabytesPerSecond: Double) -> String {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
if valueInMegabytesPerSecond >= 1 {
formatter.maximumFractionDigits = valueInMegabytesPerSecond >= 10 ? 1 : 2
let formatted = formatter.string(from: NSNumber(value: valueInMegabytesPerSecond))
?? String(format: "%.2f", valueInMegabytesPerSecond)
return "\(formatted) MB/s"
}
let valueInKilobytesPerSecond = valueInMegabytesPerSecond * 1024
if valueInKilobytesPerSecond >= 1 {
formatter.maximumFractionDigits = valueInKilobytesPerSecond >= 10 ? 0 : 1
let formatted = formatter.string(from: NSNumber(value: valueInKilobytesPerSecond))
?? String(format: valueInKilobytesPerSecond >= 10 ? "%.0f" : "%.1f", valueInKilobytesPerSecond)
return "\(formatted) KB/s"
}
let valueInBytesPerSecond = valueInMegabytesPerSecond * 1_048_576
if valueInBytesPerSecond >= 1 {
formatter.maximumFractionDigits = 0
let formatted = formatter.string(from: NSNumber(value: valueInBytesPerSecond))
?? String(format: "%.0f", valueInBytesPerSecond)
return "\(formatted) B/s"
}
return "0 B/s"
}
static func percentage(_ value: Double) -> String {
String(format: "%.1f%%", value)