use crate::ui::model::Server;
use crate::ui::{Aim, Model, Stand, theme};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Step {
Stand(Stand),
Workspace(Aim),
Conversation(String),
}
impl Step {
pub fn holding(&self, model: &Model) -> bool {
match self {
Self::Stand(stand) => model.standing.as_ref() == Some(stand),
Self::Workspace(aim) => {
model.standing.is_none()
&& model.conversation.is_none()
&& model.aim.as_ref() == Some(aim)
}
Self::Conversation(root_id) => {
model.standing.is_none() && model.conversation.as_deref() == Some(root_id.as_str())
}
}
}
}
pub fn track(model: &Model) -> Vec<Step> {
let open = model.server_open();
let mut rows = Vec::new();
for server in model.server_rows() {
let name = server.name().to_owned();
rows.push(Step::Stand(Stand::Server(name.clone())));
if open.as_deref() != Some(name.as_str()) {
continue;
}
for workspace in super::ordered(&server.workspaces()) {
let Some(aim) = server.aim(&workspace) else {
continue;
};
let aimed = model.aim.as_ref() == Some(&aim);
rows.push(Step::Workspace(aim.clone()));
if aimed {
rows.extend(
model
.rows()
.into_iter()
.map(|row| Step::Conversation(row.root_id)),
);
}
rows.push(Step::Stand(Stand::Begin(aim)));
}
if let Some(channel) = founds(&server) {
rows.push(Step::Stand(Stand::Found(channel.to_owned())));
}
}
rows
}
pub fn render(ui: &mut egui::Ui, model: &mut Model, server: &Server, open: bool, reveal: bool) {
let name = server.name().to_owned();
let standing = model.standing == Some(Stand::Server(name.clone()));
let seat = theme::paint::row(
ui,
&server.header(),
theme::INK,
standing.then_some(theme::BRAND),
open,
0.0,
if open { CLOSE_HELP } else { OPEN_HELP },
);
if standing && reveal {
seat.scroll_to_me(None);
}
if seat.gained_focus() {
model.standing = Some(Stand::Server(name.clone()));
}
if seat.clicked() {
model.open_server(&name);
}
}
pub const FOUND: &str = "+ new workspace";
pub const FOUND_HELP: &str =
"founds a workspace on this server: the box asks for its name and what it is for, on one line";
pub const OPEN_HELP: &str = "opens this server: its workspaces stand beneath";
pub const CLOSE_HELP: &str = "closes this server's list";
pub fn found(ui: &mut egui::Ui, model: &mut Model, server: &Server, reveal: bool) {
let Some(channel) = founds(server) else {
return;
};
if model.covered() && !model.switching {
return;
}
let stand = Stand::Found(channel.to_owned());
if super::workspace::standing_row(ui, model, (FOUND, FOUND_HELP), stand, 0.0, reveal) {
model.begin_founding(channel);
model.chose();
}
}
fn founds(server: &Server) -> Option<&str> {
let chunk = &server.lead;
(chunk.channel.name == crate::seat::OWN && !matches!(chunk.held, crate::ui::Held::Unheld(_)))
.then_some(chunk.channel.name.as_str())
}