Files
endorphin-tessera-gui/src/shell/developer_tools/network.rs
T
2026-10-25 21:25:43 +08:00

120 lines
3.3 KiB
Rust

use super::*;
pub(super) fn build(
p: &mut Painter,
state: &mut DeveloperToolsState,
records: &[Exchange],
viewport: Rect,
) {
let x = viewport.x;
let w = viewport.width;
let bottom = viewport.height - 22.0;
p.fill(Rect::new(x, 32.0, w, 30.0), BAR);
p.enabled_button(
Rect::new(x + 3.0, 32.0, 62.0, 29.0),
"Clear",
Action::ClearNetwork,
records.iter().any(|r| r.id > state.network_after),
);
let filter_area = Rect::new(x + 72.0, 35.0, (w - 85.0).max(100.0), 24.0);
p.ui.text_field(
filter_area,
Action::Focus(Focus::Filter),
state.focus == Some(Focus::Filter),
);
p.label(
filter_area.x + 7.0,
filter_area.y + 3.0,
&format!(
"Filter: {}{}",
state.filter,
if state.focus == Some(Focus::Filter) {
"│"
} else {
""
}
),
MUTED,
false,
);
p.label(
x + 10.0,
69.0,
"METHOD STATUS TIME PATH",
MUTED,
true,
);
let divider = 92.0 + (bottom - 92.0) * state.network_fraction;
let filter = state.filter.to_lowercase();
let visible = records
.iter()
.filter(|r| r.id > state.network_after)
.filter(|r| {
format!(
"{} {} {}",
r.method,
r.path,
r.status.map_or("pending".into(), |s| s.to_string())
)
.to_lowercase()
.contains(&filter)
})
.collect::<Vec<_>>();
let mut lines = Vec::new();
for r in &visible {
let mut l = Line::new(
format!(
"{:<7} {:<6} {:>5} ms {}",
r.method,
r.status.map_or("…".into(), |s| s.to_string()),
r.elapsed_ms,
r.path
),
if r.status.is_some_and(|s| s >= 400) {
ERROR
} else {
TEXT
},
);
l.selected = state.selected_request == Some(r.id);
l.action = Some(Action::Request(r.id));
lines.push(l);
}
if lines.is_empty() {
lines.push(Line::new(
"No matching requests. Listening to Tessera's local API.",
MUTED,
));
}
p.lines(
Rect::new(x + 1.0, 92.0, w - 2.0, divider - 92.0),
Region::Requests,
&lines,
state,
false,
);
p.split(Rect::new(x + 1.0, divider, w - 2.0, 1.0), Split::Network);
let selected = records
.iter()
.find(|r| Some(r.id) == state.selected_request);
let mut details = Vec::new();
if let Some(r) = selected {
request_details(&mut details, r);
} else {
multiline(
&mut details,
"Select a request to inspect headers and bodies.\n\nCapture scope: 127.0.0.1:4737 in this Tessera process.\n80 most recent requests; body previews up to 32 KiB.\nOnly Content-Type and Content-Length request headers are recorded.\nExternal browser / OS traffic is not captured.",
MUTED,
);
}
p.lines(
Rect::new(x + 1.0, divider + 5.0, w - 2.0, bottom - divider - 5.0),
Region::Details,
&details,
state,
false,
);
}