use super::{Fold, Kind, Row, TRAIL, fold};
use crate::ui::theme::{self, glyph};
pub(super) fn trail(ui: &mut egui::Ui, at: usize, steps: &[Row]) {
let id = ui.make_persistent_id(("trail", at));
let live = steps.iter().any(|row| row.live);
let mut open = ui.data(|d| d.get_temp::<bool>(id)).unwrap_or(live);
let calls = steps
.iter()
.filter(|row| matches!(row.kind, Kind::Call | Kind::Answered))
.count();
let head = format!(
"{} {TRAIL} ({calls})",
if open { glyph::OPEN } else { glyph::SHUT },
);
if theme::paint::tab(ui, &head, theme::INK_WEAK).clicked() {
open = !open;
ui.data_mut(|d| d.insert_temp(id, open));
}
if !open {
return;
}
let x = ui.cursor().min.x + theme::space::S;
for (i, row) in steps.iter().enumerate() {
let top = ui.cursor().min.y;
ui.horizontal_top(|ui| {
ui.add_space(theme::space::L);
step(ui, at + i, row);
});
let bottom = ui.min_rect().max.y;
let middle = top + theme::space::S;
theme::paint::elbow(ui, x, top, middle, x + theme::space::S);
if i + 1 < steps.len() {
theme::paint::rail(ui, x, middle, bottom);
}
}
}
fn step(ui: &mut egui::Ui, at: usize, row: &Row) {
let red = theme::accent(theme::State::Error);
let ended = |ui: &mut egui::Ui| {
let (mark, ink) = if row.failed {
(glyph::FAILED, red)
} else {
(glyph::DONE, theme::INK_WEAK)
};
ui.label(egui::RichText::new(mark).color(ink));
};
let (mark, ink) = match row.kind {
Kind::Call | Kind::Answered => (glyph::CALL, theme::BRAND),
_ => (glyph::NOTE, theme::INK_WEAK),
};
if row.kind == Kind::Result {
ended(ui);
} else {
ui.label(egui::RichText::new(mark).color(ink));
}
ui.vertical(|ui| {
let who = if row.failed { red } else { theme::INK_WEAK };
ui.horizontal_wrapped(|ui| {
ui.label(egui::RichText::new(&row.who).color(who));
if row.kind == Kind::Answered {
ended(ui);
}
});
match &row.fold {
Some(fold) => folded(ui, at, row, fold),
None if row.said.is_empty() => {}
None => {
theme::paint::prose(ui, &row.said, theme::INK_WEAK);
}
}
});
}
fn folded(ui: &mut egui::Ui, at: usize, row: &Row, fold: &Fold) {
let id = ui.make_persistent_id(at);
let mut open = ui.data(|d| d.get_temp::<bool>(id)).unwrap_or(false);
if ui
.button(if open { fold::UNFOLD } else { &fold.whole })
.clicked()
{
open = !open;
ui.data_mut(|d| d.insert_temp(id, open));
}
if open {
theme::paint::prose(ui, &row.said, theme::INK);
} else {
theme::paint::prose(ui, &fold.head, theme::INK_WEAK);
}
}