vdom toolbar

This commit is contained in:
sawka
2024-11-10 13:59:39 -08:00
parent 13b547c69e
commit cb928db233
4 changed files with 223 additions and 8 deletions
+58
View File
@@ -0,0 +1,58 @@
.toolbar {
--low-usage: var(--term-bright-green);
--medium-usage: var(--term-bright-yellow);
--high-usage: var(--term-bright-red);
--text-color: var(--term-cmdtext);
--secondary-text: var(--term-gray);
--divider-color: var(--term-bright-black);
}
.toolbar {
height: 1.5em;
line-height: 1.5em;
padding: 0 0.5em;
display: flex;
align-items: center;
font-family: system-ui, -apple-system, sans-serif;
gap: 1em;
color: var(--text-color);
}
.metric-group {
display: flex;
align-items: center;
gap: 0.5em;
}
.label {
font-size: 0.8em;
color: var(--secondary-text);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.value {
font-size: 0.9em;
min-width: 3em;
color: var(--term-foreground);
}
.progress-container {
width: 4em;
height: 0.5em;
background: var(--term-bright-black);
border-radius: 3px;
overflow: hidden;
}
.progress-bar {
height: 100%;
transition: width 0.3s ease, background-color 0.3s ease;
}
.divider {
width: 1px;
height: 1em;
background: var(--divider-color);
margin: 0 0.25em;
}
+122
View File
@@ -0,0 +1,122 @@
package main
import (
"context"
_ "embed"
"fmt"
"time"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/load"
"github.com/wavetermdev/waveterm/pkg/vdom"
"github.com/wavetermdev/waveterm/pkg/vdom/vdomclient"
)
//go:embed style.css
var styleCSS []byte
var AppClient = vdomclient.MakeClient(vdomclient.AppOpts{
CloseOnCtrlC: true,
GlobalStyles: styleCSS,
TargetToolbar: &vdom.VDomTargetToolbar{Toolbar: true, Height: "1.5em"},
})
type Metrics struct {
CPUPercent float64
LoadAvg [3]float64
}
var App = vdomclient.DefineComponent(AppClient, "App",
func(ctx context.Context, _ any) any {
metrics, setMetrics := vdom.UseState(ctx, Metrics{})
// Update metrics every second
vdom.UseEffect(ctx, func() func() {
done := make(chan bool)
go func() {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case <-ticker.C:
if cpuPercent, err := cpu.Percent(0, false); err == nil && len(cpuPercent) > 0 {
if loadAvg, err := load.Avg(); err == nil {
setMetrics(Metrics{
CPUPercent: cpuPercent[0],
LoadAvg: [3]float64{loadAvg.Load1, loadAvg.Load5, loadAvg.Load15},
})
AppClient.SendAsyncInitiation()
}
}
}
}
}()
return func() {
close(done)
}
}, []any{})
// Helper to get color based on CPU usage
getCPUColor := func(cpu float64) string {
switch {
case cpu >= 80:
return "var(--high-usage)"
case cpu >= 50:
return "var(--medium-usage)"
default:
return "var(--low-usage)"
}
}
return vdom.E("div",
vdom.Class("toolbar"),
// CPU Section
vdom.E("div",
vdom.Class("metric-group"),
vdom.E("span",
vdom.Class("label"),
"CPU",
),
vdom.E("div",
vdom.Class("progress-container"),
vdom.E("div",
vdom.Class("progress-bar"),
vdom.PStyle("width", fmt.Sprintf("%d%%", int(metrics.CPUPercent))),
vdom.PStyle("backgroundColor", getCPUColor(metrics.CPUPercent)),
),
),
vdom.E("span",
vdom.Class("value"),
fmt.Sprintf("%.1f%%", metrics.CPUPercent),
),
),
// Divider
vdom.E("div", vdom.Class("divider")),
// Load Average Section
vdom.E("div",
vdom.Class("metric-group"),
vdom.E("span",
vdom.Class("label"),
"Load",
),
vdom.E("span",
vdom.Class("value"),
fmt.Sprintf("%.2f %.2f %.2f",
metrics.LoadAvg[0],
metrics.LoadAvg[1],
metrics.LoadAvg[2],
),
),
),
)
},
)
func main() {
AppClient.RunMain()
}