use super::{Acting, Owes, Seat, fan, start};
use crate::AppModel;
use crate::actions::DraftKey;
use crate::shell::ShellState;
pub(in crate::shell) fn settle(model: &mut AppModel, state: &mut ShellState) {
let Some(ticket) = state.acting.as_ref().map(|a| a.ticket) else {
return;
};
let Some(landed) = model.act_receipt(ticket) else {
return;
};
let Some(acting) = state.acting.take() else {
return;
};
let trouble = crate::shell::act::trouble(&landed);
if trouble.is_none() && acted(model, state, &acting, &landed) {
return;
}
let started = match (&acting.owes, &landed) {
(Owes::Started { .. }, Ok(crate::boundary::reply::Reply::Started { conversation })) => {
Some(conversation.clone())
}
_ => None,
};
match acting.seat {
Seat::Quiet => quietly(state, trouble),
Seat::Draft(key, fired) => match trouble {
None => {
state.actions.drafts.sent(&key, &fired);
if let Some(name) = started {
let now = DraftKey::composer(model.focused_workspace(), Some(name));
state.actions.drafts.carry(&key, &now);
}
}
Some(reason) => state.slash = Some(reason),
},
Seat::Line(key) => {
if crate::shell::slash::note(state, landed) {
state.actions.drafts.set(key, String::new());
}
}
}
}
fn acted(
model: &mut AppModel,
state: &mut ShellState,
acting: &Acting,
landed: &Result<crate::boundary::reply::Reply, String>,
) -> bool {
use crate::boundary::reply::Reply;
match (&acting.owes, landed) {
(
Owes::Message {
agent,
content,
queued,
},
_,
) => {
model.await_message(&acting.ws, agent, content, *queued);
false
}
(Owes::Prepared { goal }, Ok(Reply::Prepared(prepared))) => {
start::staged(model, state, acting, prepared, goal.clone())
}
(Owes::Started { goal }, Ok(Reply::Started { conversation })) => {
start::fired(model, state, &acting.ws, conversation, goal);
false
}
(Owes::Fanned { goal }, Ok(Reply::Fanned(candidates))) => {
fan::fanned(model, state, &acting.ws, candidates, goal)
}
(_, _) => false,
}
}
fn quietly(state: &mut ShellState, trouble: Option<String>) {
if let Some(reason) = trouble {
state.slash = Some(reason);
}
}