mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Working stuff
This commit is contained in:
parent
630431a008
commit
7a1945dd21
5 changed files with 162 additions and 30 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue