use crate::AppModel;
use crate::actions::DraftKey;
use crate::cli_outbound::Cli;
use crate::start;
use lernie::mint::SplitMix64;
use super::ShellState;
use super::inbox_queue;
use super::verb_row::{VerbCtx, verb_buttons};
pub fn composer(
ui: &mut egui::Ui,
model: &mut AppModel,
state: &mut ShellState,
lernie: &Cli,
bl: &Cli,
cap: f32,
) {
let Some(ws) = model.focused_workspace() else {
return;
};
let titles =
crate::nav::convs::Titles::of_rows(&super::convs::forest(model).value.unwrap_or_default());
let seat = super::seat::selection(model);
state.actions.selected_branch = seat.as_ref().map(|s| s.agent_id.clone());
let target = state.actions.selected_branch.clone();
let mint_seed = state.start.mint_seed;
let conv_name = seat.as_ref().map(|s| s.name.clone());
let detail = target
.as_deref()
.and_then(|agent| super::seat::detail(model, &ws, agent).value);
if conv_name.is_none() {
ui.weak(
start::preview(
&model.start_bare_inputs(),
&SplitMix64::from_seed(mint_seed),
)
.preview,
);
}
let key = DraftKey::composer(Some(ws.clone()), target.clone());
let pending = target
.as_deref()
.map(|agent| {
let landed = super::inspector::inbox(model, &ws, agent)
.value
.unwrap_or_default();
model.echoed_pending(agent, landed)
})
.unwrap_or_default();
let prompts = target
.as_deref()
.map(|agent| {
let tx = super::inspector::transcript(model, &ws, agent)
.value
.unwrap_or_default();
crate::composer::prompts(&pending, &tx)
})
.unwrap_or_default();
let queue = inbox_queue::QueueCtx {
key: key.clone(),
agent_id: target.clone(),
pending,
prompts,
hint: match conv_name.as_deref() {
Some(name) => format!("message {name}"),
None => "start a conversation".to_owned(),
},
cap,
};
let before = state.actions.drafts.text(&key);
let edit = inbox_queue::region(
ui,
&mut state.composer,
&mut state.actions.drafts,
&queue,
&titles,
);
if state.actions.drafts.text(&key) != before {
state.slash = None;
}
super::focus::take(state, ui, &edit);
let returned = edit.has_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter));
let (bare, command) = ui.input(|i| (i.modifiers.is_none(), i.modifiers.command_only()));
let entered = returned && bare;
let interrupted = returned && command;
let ctx = VerbCtx {
ws,
stoppable: seat.as_ref().is_some_and(|s| s.stoppable),
stop_children: seat.as_ref().is_some_and(|s| s.stop_children),
present: seat.as_ref().is_some_and(|s| s.present),
nudgeable: detail.as_ref().is_some_and(|d| d.nudgeable),
held: detail.and_then(|d| d.held),
key: key.clone(),
text: state.actions.drafts.text(&key),
conv_name,
entered,
interrupted,
};
verb_buttons(ui, model, state, lernie, bl, &ctx);
super::slash::note_ui(ui, state);
let ball = super::chrome::focused_balls(model).first().cloned();
let targets = match &ball {
Some(ball) => crate::nav::tabs::move_targets(&super::chrome::ws_rows(model), &ball.owner),
None => Vec::new(),
};
super::ball_bar::actions(ui, model, ball.as_ref(), &targets);
if let Some(failure) = model.last_failure(crate::opslog::Origin::Conversation) {
super::banner::failure_banner(ui, model, state, &failure);
}
}