use super::{Door, Run, run};
use crate::ui::{Model, Reload, Selector, theme};
pub const NO_WORKSPACE: &str = "workspace";
pub const NO_PROVIDER: &str = "provider…";
pub const NO_MODEL: &str = "model…";
pub const EFFORT: &str = "effort";
pub const PRIORITY: &str = "priority";
pub(crate) fn ops(door: Door) -> &'static [&'static str] {
use crate::verbs;
match door {
Door::Row(row) => row.ops,
Door::Drop(Selector::Workspace) => &[verbs::WORKSPACES.word],
Door::Drop(Selector::Model) => &[verbs::MODELS.word],
Door::Drop(_) => &[verbs::PROVIDERS.word],
}
}
fn mark(model: &Model, selector: Selector) -> (&'static str, egui::Color32) {
match model
.dropup
.as_ref()
.filter(|open| open.selector == selector)
{
Some(open) if open.reload == Some(Reload::Asked) => (
theme::glyph::RELOAD,
theme::accent(theme::State::Annotation),
),
Some(open) if open.reload == Some(Reload::Landed) => {
(theme::glyph::DONE, theme::accent(theme::State::Attention))
}
_ => (theme::glyph::DROP, theme::INK_FAINT),
}
}
fn selector(model: &Model, selector: Selector, said: Option<String>, empty: &str) -> Run {
let (text, ink) = said.map_or((empty.to_owned(), theme::INK_WEAK), |said| {
(said, theme::INK)
});
Run {
door: Some(Door::Drop(selector)),
mark: Some(mark(model, selector)),
..run(text, ink)
}
}
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(crate) fn workspace(model: &Model) -> Run {
let wall = model.aim.as_ref().map(|aim| aim.address.clone());
selector(model, Selector::Workspace, wall, NO_WORKSPACE)
}
pub fn selectors(model: &Model) -> (Vec<Run>, usize) {
let mut out = Vec::new();
if model.aim.is_none() {
return (out, 0);
}
let worker = model.worker().cloned();
out.push(selector(
model,
Selector::Provider,
worker.as_ref().map(|w| w.provider.clone()),
NO_PROVIDER,
));
let said = worker
.as_ref()
.map(|w| w.model.clone())
.or_else(|| answered_by(model));
out.push(selector(model, Selector::Model, said, NO_MODEL));
let Some(worker) = worker else {
return (out, 2);
};
let row = model
.providers
.iter()
.flatten()
.find(|row| row.name == worker.provider);
if row.is_none_or(|row| row.effort) {
let level = crate::verbs::tuning::word(worker.effort.as_ref());
let said = Some(format!("{EFFORT} {level}"));
out.push(selector(model, Selector::Effort, said, EFFORT));
}
if row.is_none_or(|row| row.priority) {
let said = Some(format!("{PRIORITY} {}", crate::ui::lane(worker.priority)));
out.push(selector(model, Selector::Priority, said, PRIORITY));
}
(out, 2)
}