Desktop client with egui + wgpu UI, audio pipeline (cpal/opus/rodio), networking (LNEx protocol), and identity management with encrypted vault. Jitter buffer module extracted from voice-node for standalone operation.
93 lines
3.4 KiB
Rust
93 lines
3.4 KiB
Rust
use eframe::egui::{self, Context, Frame, TopBottomPanel};
|
|
|
|
use crate::state::{ConnState, UiState};
|
|
use crate::theme as t;
|
|
|
|
pub const TITLEBAR_H: f32 = 30.0;
|
|
|
|
pub(crate) fn show_titlebar(ctx: &Context, s: &mut UiState) {
|
|
TopBottomPanel::top("titlebar")
|
|
.exact_height(TITLEBAR_H)
|
|
.frame(Frame::NONE.fill(t::BG_SURFACE))
|
|
.show_separator_line(false)
|
|
.show(ctx, |ui| {
|
|
ui.horizontal(|ui| {
|
|
ui.add_space(12.0);
|
|
|
|
ui.with_layout(
|
|
egui::Layout::left_to_right(egui::Align::Center).with_main_justify(true),
|
|
|ui| {
|
|
let w = ui.available_width();
|
|
if w.is_finite() && w > 0.0 {
|
|
ui.set_width(w);
|
|
}
|
|
let title = match &s.conn {
|
|
ConnState::Connected { node_name, .. } => {
|
|
format!("VNOX · {node_name}")
|
|
}
|
|
ConnState::Connecting => "VNOX · connecting…".into(),
|
|
ConnState::Reconnecting { attempt } => {
|
|
format!("VNOX · reconnect #{attempt}")
|
|
}
|
|
ConnState::Disconnected => "VNOX · offline".into(),
|
|
};
|
|
ui.label(
|
|
egui::RichText::new(title)
|
|
.font(egui::FontId::monospace(11.0))
|
|
.color(t::TEXT_MUTED),
|
|
);
|
|
},
|
|
);
|
|
|
|
if matches!(s.conn, ConnState::Connected { .. })
|
|
&& s.overlay_latency
|
|
&& let Some(rtt) = s.rtt_ms
|
|
{
|
|
let color = if rtt < 80 {
|
|
t::SUCCESS
|
|
} else if rtt < 200 {
|
|
t::WARNING
|
|
} else {
|
|
t::ERROR
|
|
};
|
|
ui.label(
|
|
egui::RichText::new(format!("{rtt} ms"))
|
|
.font(egui::FontId::monospace(10.0))
|
|
.color(color),
|
|
);
|
|
ui.add_space(8.0);
|
|
}
|
|
|
|
let transport = match &s.conn {
|
|
ConnState::Connected { .. } => "quic/v1",
|
|
ConnState::Connecting => "connecting…",
|
|
ConnState::Reconnecting { .. } => "reconnecting…",
|
|
ConnState::Disconnected => "idle",
|
|
};
|
|
ui.label(
|
|
egui::RichText::new(transport)
|
|
.font(egui::FontId::monospace(10.0))
|
|
.color(t::TEXT_DISABLED),
|
|
);
|
|
ui.add_space(10.0);
|
|
|
|
let settings_color = if s.settings_open {
|
|
Some(t::ACCENT)
|
|
} else {
|
|
None
|
|
};
|
|
if t::icon_btn_drawn(
|
|
ui,
|
|
crate::theme::icons::gear,
|
|
"Settings",
|
|
settings_color,
|
|
18.0,
|
|
)
|
|
.clicked()
|
|
{
|
|
s.settings_open = !s.settings_open;
|
|
}
|
|
ui.add_space(12.0);
|
|
});
|
|
});
|
|
}
|