mirror of
https://github.com/wavetermdev/waveapps.git
synced 2026-08-05 13:48:00 -07:00
vdom toolbar
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user