feat: add Dioxus and GPUI UI prototypes for framework comparison
Dioxus (ui-dioxus/): 2,169 lines, WebView mode (same wry as Tauri), Catppuccin theme, 12 components, agor-core integration, compiles clean. Evolution path — keeps xterm.js, gradual migration from Tauri. GPUI (ui-gpui/): 2,490 lines, GPU-accelerated rendering, alacritty_terminal for native terminal, 17 files, Catppuccin palette, demo data. Revolution path — pure Rust UI, 120fps target, no WebView. Both are standalone (not in workspace), share agor-core backend. Created for side-by-side comparison to inform framework decision.
This commit is contained in:
parent
90c7315336
commit
f3d2ca78ba
34 changed files with 17467 additions and 0 deletions
85
ui-dioxus/src/components/status_bar.rs
Normal file
85
ui-dioxus/src/components/status_bar.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/// StatusBar — bottom bar showing agent fleet state, cost, and attention.
|
||||
///
|
||||
/// Mirrors the Svelte app's StatusBar.svelte (Mission Control bar).
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct FleetState {
|
||||
pub running: usize,
|
||||
pub idle: usize,
|
||||
pub stalled: usize,
|
||||
pub total_cost: f64,
|
||||
pub total_tokens: u64,
|
||||
pub project_count: usize,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn StatusBar(fleet: FleetState) -> Element {
|
||||
rsx! {
|
||||
div { class: "status-bar",
|
||||
// Left section: agent counts
|
||||
div { class: "status-bar-left",
|
||||
// Running
|
||||
div { class: "status-item",
|
||||
div {
|
||||
class: "status-dot running",
|
||||
style: "width: 6px; height: 6px; border-radius: 50%; display: inline-block;",
|
||||
}
|
||||
span { class: "status-count running", "{fleet.running}" }
|
||||
span { "running" }
|
||||
}
|
||||
|
||||
// Idle
|
||||
div { class: "status-item",
|
||||
div {
|
||||
class: "status-dot idle",
|
||||
style: "width: 6px; height: 6px; border-radius: 50%; display: inline-block;",
|
||||
}
|
||||
span { class: "status-count idle", "{fleet.idle}" }
|
||||
span { "idle" }
|
||||
}
|
||||
|
||||
// Stalled
|
||||
if fleet.stalled > 0 {
|
||||
div { class: "status-item",
|
||||
div {
|
||||
class: "status-dot stalled",
|
||||
style: "width: 6px; height: 6px; border-radius: 50%; display: inline-block;",
|
||||
}
|
||||
span { class: "status-count stalled", "{fleet.stalled}" }
|
||||
span { "stalled" }
|
||||
}
|
||||
}
|
||||
|
||||
// Separator
|
||||
span { style: "color: var(--ctp-surface1);", "|" }
|
||||
|
||||
// Projects
|
||||
div { class: "status-item",
|
||||
span { "{fleet.project_count} projects" }
|
||||
}
|
||||
}
|
||||
|
||||
// Right section: cost + tokens
|
||||
div { class: "status-bar-right",
|
||||
div { class: "status-item",
|
||||
span { class: "status-cost", "${fleet.total_cost:.4}" }
|
||||
}
|
||||
div { class: "status-item",
|
||||
span { "{format_tokens(fleet.total_tokens)} tokens" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_tokens(tokens: u64) -> String {
|
||||
if tokens >= 1_000_000 {
|
||||
format!("{:.1}M", tokens as f64 / 1_000_000.0)
|
||||
} else if tokens >= 1_000 {
|
||||
format!("{:.1}K", tokens as f64 / 1_000.0)
|
||||
} else {
|
||||
tokens.to_string()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue