Files
TS3-vibed/client_node/src/ui/components/operator_card.rs
2026-05-10 23:56:54 +02:00

78 lines
3.2 KiB
Rust

use eframe::egui;
use crate::ui::theme::Theme;
pub struct OperatorCard {
pub is_muted: bool,
}
impl OperatorCard {
pub fn new() -> Self {
Self { is_muted: false }
}
pub fn show(&mut self, ctx: &egui::Context) {
let screen_rect = ctx.content_rect();
let width = 280.0;
// Floating at top-right
egui::Area::new(egui::Id::new("operator_card"))
.fixed_pos(egui::pos2(screen_rect.max.x - width - 24.0, 88.0))
.show(ctx, |ui| {
Theme::glass_frame().show(ui, |ui| {
ui.set_width(width);
// Header
ui.horizontal(|ui| {
// Avatar Placeholder
let (rect, _) = ui.allocate_exact_size(egui::vec2(48.0, 48.0), egui::Sense::hover());
ui.painter().circle_filled(rect.center(), 24.0, Theme::COBALT_BLUE);
ui.vertical(|ui| {
ui.label(egui::RichText::new("SAMUEL").size(16.0).strong().color(Theme::TEXT_PRIMARY));
ui.label(egui::RichText::new("CONNECTED").size(10.0).color(Theme::SIGNAL_GREEN));
});
});
ui.add_space(16.0);
ui.separator();
ui.add_space(16.0);
// Telemetry Section (3-column)
ui.columns(3, |columns| {
Self::telemetry_item(&mut columns[0], "VERSION", "v1.0.4-T");
Self::telemetry_item(&mut columns[1], "UPTIME", "04:22:15");
Self::telemetry_item(&mut columns[2], "LATENCY", "24ms");
});
ui.add_space(24.0);
// Primary Action: Large Mute Toggle
let mute_color = if self.is_muted { Theme::CRIMSON_ALERT } else { Theme::COBALT_BLUE };
let btn_text = if self.is_muted { "󰍭" } else { "󰍬" };
ui.vertical_centered(|ui| {
if ui.add_sized(
[200.0, 56.0],
egui::Button::new(egui::RichText::new(btn_text).size(32.0))
.fill(mute_color.linear_multiply(0.2))
.stroke(egui::Stroke::new(1.0, mute_color))
.corner_radius(4.0)
).clicked() {
self.is_muted = !self.is_muted;
}
ui.add_space(4.0);
ui.label(egui::RichText::new(if self.is_muted { "UNMUTE UNIT" } else { "MUTE UNIT" })
.size(10.0).strong().color(mute_color));
});
});
});
}
fn telemetry_item(ui: &mut egui::Ui, label: &str, value: &str) {
ui.vertical_centered(|ui| {
ui.label(egui::RichText::new(label).size(8.0).color(Theme::TEXT_SECONDARY).strong());
ui.label(egui::RichText::new(value).size(11.0).color(Theme::TEXT_PRIMARY).strong());
});
}
}