use beyonder_core::{Block, BlockContent, BlockKind, BlockStatus};
use crate::pipeline::RectInstance;
#[allow(clippy::too_many_arguments)]
pub fn render_shell_block(
block: &Block,
x: f32,
y: f32,
width: f32,
height: f32,
font_size: f32,
scale: f32,
rects: &mut Vec<RectInstance>,
) {
let BlockContent::ShellCommand {
output, exit_code, ..
} = &block.content
else {
return;
};
let cmd_bar_h = font_size * 2.8;
let inner_gap = font_size * 0.4;
let last_content = output
.rows
.iter()
.rposition(|row| {
row.cells.iter().any(|c| {
let fc = c.grapheme.chars().next().unwrap_or('\0');
fc != ' ' && fc != '\0'
})
})
.map(|i| i + 1)
.unwrap_or(0);
let has_output = last_content > 0;
rects.push(
RectInstance::filled(x, y, width, cmd_bar_h, [0.118, 0.118, 0.180, 1.0])
.with_radius(3.0 * scale),
);
let accent = match block.kind {
BlockKind::Human => [0.271, 0.278, 0.353, 0.7],
BlockKind::Agent => [0.537, 0.706, 0.980, 0.85],
BlockKind::Approval => [0.976, 0.886, 0.686, 0.90],
BlockKind::System => [0.271, 0.278, 0.353, 0.4],
BlockKind::Tool => [0.580, 0.886, 0.835, 0.75],
};
let stripe_w = 3.0 * scale;
rects.push(RectInstance::filled(x, y, stripe_w, cmd_bar_h, accent).with_radius(scale));
if block.status == BlockStatus::Running {
rects.push(
RectInstance::filled(x, y, stripe_w, cmd_bar_h, [0.796, 0.651, 0.969, 0.95]) .with_radius(scale),
);
}
if let Some(code) = exit_code {
let indicator = if *code == 0 {
[0.651, 0.890, 0.631, 0.80] } else {
[0.953, 0.545, 0.659, 0.85] };
rects.push(
RectInstance::filled(x + width - stripe_w, y, stripe_w, cmd_bar_h, indicator)
.with_radius(scale),
);
}
if has_output || block.status == BlockStatus::Running {
let out_y = y + cmd_bar_h + inner_gap;
let out_h = height - cmd_bar_h - inner_gap;
if out_h > 1.0 {
rects.push(
RectInstance::filled(x, out_y, width, out_h, [0.118, 0.118, 0.180, 1.0])
.with_radius(3.0 * scale),
);
}
}
}