Linux runs exactly as before when both bridge interfaces exist. When they do not, the lone default-route interface is monitored, and a single interface now draws a single UI pane instead of an empty second one. macOS is newly supported: a running VPN tunnel (utun) is monitored as the primary pane alongside the physical default-route interface, or the physical interface alone when no VPN is up. Detection lives in internal/netdetect: interface/route data types, pure selection logic keyed on OS name, and route parsers, all unit-tested on Linux for both platforms. Only the real route query and the per-platform TCP dial binding (source address on Linux, IP_BOUND_IF on macOS) are build-tagged. Ping argument construction is a pure, OS-keyed function. NewMonitor now takes a list of interfaces. Model: opus-4-8
85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
package monitor
|
|
|
|
import tcell "github.com/gdamore/tcell/v2"
|
|
|
|
// Color styles
|
|
var (
|
|
CBrightGreen = tcell.StyleDefault.Foreground(tcell.ColorGreen).Bold(true)
|
|
CGreen = tcell.StyleDefault.Foreground(tcell.ColorGreen)
|
|
CDimGreen = tcell.StyleDefault.Foreground(tcell.ColorGreen).Dim(true)
|
|
CYellow = tcell.StyleDefault.Foreground(tcell.ColorYellow)
|
|
COrange = tcell.StyleDefault.Foreground(tcell.ColorOrange)
|
|
CRed = tcell.StyleDefault.Foreground(tcell.ColorRed)
|
|
CBrightRed = tcell.StyleDefault.Foreground(tcell.ColorRed).Bold(true)
|
|
CDefault = tcell.StyleDefault
|
|
|
|
// Rainbow colors for the spinner
|
|
CRainbow = []tcell.Style{
|
|
tcell.StyleDefault.Foreground(tcell.ColorRed),
|
|
tcell.StyleDefault.Foreground(tcell.ColorOrange),
|
|
tcell.StyleDefault.Foreground(tcell.ColorYellow),
|
|
tcell.StyleDefault.Foreground(tcell.ColorGreen),
|
|
tcell.StyleDefault.Foreground(tcell.ColorBlue),
|
|
tcell.StyleDefault.Foreground(tcell.ColorPurple),
|
|
}
|
|
)
|
|
|
|
// MeterColorForValue returns the appropriate color style for a meter value
|
|
// value: current value of the meter
|
|
// maxValue: maximum value of the meter
|
|
// reverse: if true, low values are good (green) and high values are bad (red)
|
|
//
|
|
// if false, high values are good (green) and low values are bad (red)
|
|
func MeterColorForValue(value, maxValue int, reverse bool) tcell.Style {
|
|
// Calculate percentage
|
|
percentage := float64(value) / float64(maxValue) * 100
|
|
|
|
// For reverse mode (low is good), invert the percentage
|
|
if reverse {
|
|
percentage = 100 - percentage
|
|
}
|
|
|
|
// Return color based on percentage (after any reversal)
|
|
// Now high percentage always means "good" and low percentage means "bad"
|
|
switch {
|
|
case percentage >= 90:
|
|
return CBrightGreen
|
|
case percentage >= 75:
|
|
return CGreen
|
|
case percentage >= 60:
|
|
return CDimGreen
|
|
case percentage >= 40:
|
|
return CYellow
|
|
case percentage >= 20:
|
|
return COrange
|
|
default:
|
|
return CRed
|
|
}
|
|
}
|
|
|
|
// StyleLatency returns the appropriate style for latency values
|
|
func StyleLatency(ms float64) tcell.Style {
|
|
switch {
|
|
case ms < 50:
|
|
return CBrightGreen
|
|
case ms < 100:
|
|
return CGreen
|
|
case ms < 200:
|
|
return CYellow
|
|
default:
|
|
return CRed
|
|
}
|
|
}
|
|
|
|
// StyleLoss returns the appropriate style for packet loss percentages
|
|
func StyleLoss(p float64) tcell.Style {
|
|
switch {
|
|
case p == 0:
|
|
return CBrightGreen
|
|
case p < 5:
|
|
return CYellow
|
|
default:
|
|
return CBrightRed
|
|
}
|
|
}
|