use crate::ui::{Model, theme};
pub fn version() -> String {
crate::cli::version()
}
pub const WAYS_IN: &str = "/help for commands · Ctrl+X for a conversation";
fn card(ui: &mut egui::Ui, body: impl FnOnce(&mut egui::Ui)) {
egui::Frame::none()
.fill(theme::SURFACE)
.stroke(egui::Stroke::new(1.0, theme::HAIRLINE))
.rounding(theme::RADIUS)
.inner_margin(egui::Margin::symmetric(theme::space::M, theme::space::S))
.show(ui, |ui| {
ui.set_width(ui.available_width());
body(ui);
});
ui.add_space(theme::space::M);
}
fn line(ui: &mut egui::Ui, said: &str, ink: egui::Color32) {
ui.add(egui::Label::new(egui::RichText::new(said).color(ink)).wrap());
}
fn answered_by(model: &Model) -> Option<String> {
model
.transcript
.entries
.iter()
.rev()
.find_map(|entry| match &entry.kind {
crate::reply::transcript::EntryKind::Model { model_id, .. } => Some(model_id.clone()),
_ => None,
})
}
pub fn conversation(ui: &mut egui::Ui, model: &Model, id: &str) {
let row = model.rows().into_iter().find(|row| row.root_id == id);
card(ui, |ui| {
let name = row
.as_ref()
.map_or_else(|| id.to_owned(), |row| row.display.clone());
line(ui, &name, theme::INK);
if let Some(aim) = &model.aim {
line(
ui,
&format!("on {} — {}", aim.address, aim.channel),
theme::INK_WEAK,
);
}
let mut cost = Vec::new();
if let Some(model_id) = answered_by(model) {
cost.push(model_id);
}
if let Some(agent) = &model.records.agent {
cost.push(crate::ui::records::header::costing(agent));
}
if !cost.is_empty() {
line(ui, &cost.join(" · "), theme::INK_WEAK);
}
if let Some(path) = model
.records
.agent
.as_ref()
.and_then(crate::ui::records::header::descent)
{
line(ui, &path, theme::INK_WEAK);
}
});
}
pub fn seat(ui: &mut egui::Ui, model: &Model) {
card(ui, |ui| {
line(ui, &version(), theme::INK);
for chunk in &model.roster {
let walls = chunk.walls.len();
let conversations: u64 = chunk.walls.iter().map(|wall| wall.agents).sum();
let asking: u64 = chunk.walls.iter().map(|wall| wall.attention).sum();
let waiting = if asking > 0 {
format!(", {asking} waiting")
} else {
String::new()
};
let said = format!(
"{} — {walls} {}, {conversations} {}{waiting}",
crate::ui::roster::header(&chunk.channel),
if walls == 1 { "wall" } else { "walls" },
if conversations == 1 {
"conversation"
} else {
"conversations"
}
);
let ink = if asking > 0 {
theme::accent(theme::State::Attention)
} else {
theme::INK_WEAK
};
line(ui, &said, ink);
}
line(ui, WAYS_IN, theme::INK_WEAK);
});
}
#[cfg(test)]
mod tests;