mod chat_modal;
mod commit_count;
mod confirm;
mod emoji_selector;
mod help;
mod instructions;
mod preset_selector;
mod ref_selector;
mod search;
mod settings;
mod theme_selector;
use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::widgets::Clear;
use std::time::Instant;
use crate::studio::state::{Modal, StudioState};
fn modal_size(modal: &Modal, area: Rect) -> (u16, u16) {
let max_width = area.width.saturating_sub(4);
let max_height = area.height.saturating_sub(4);
match modal {
Modal::Chat => (
(area.width * 4 / 5).max(80).min(max_width),
(area.height * 4 / 5).min(max_height),
),
Modal::Help => (70.min(max_width), 40.min(max_height)),
Modal::Instructions { .. } => (60.min(max_width), 8.min(max_height)),
Modal::Search { .. } => (60.min(max_width), 15.min(max_height)),
Modal::Confirm { .. } => (60.min(max_width), 6.min(max_height)),
Modal::RefSelector { refs, .. } => {
let needed_width = refs
.iter()
.map(std::string::String::len)
.max()
.unwrap_or(30) as u16
+ 10;
let list_height = (refs.len() as u16 + 4).min(20);
(
needed_width.max(40).min(max_width),
list_height.min(max_height),
)
}
Modal::PresetSelector { presets, .. } => {
let list_height = (presets.len() as u16 + 5).min(30);
(70.min(max_width), list_height.min(max_height))
}
Modal::EmojiSelector { .. } => (55.min(max_width), 26.min(max_height)),
Modal::Settings(_) => (70.min(max_width), 24.min(max_height)),
Modal::ThemeSelector { themes, .. } => {
let list_height = (themes.len() as u16 + 8).min(28);
(75.min(max_width), list_height.min(max_height))
}
Modal::CommitCount { .. } => (45.min(max_width), 9.min(max_height)),
}
}
pub fn render_modal(state: &StudioState, frame: &mut Frame, last_render: Instant) {
let Some(modal) = &state.modal else {
return;
};
let area = frame.area();
let (modal_width, modal_height) = modal_size(modal, area);
let x = (area.width.saturating_sub(modal_width)) / 2;
let y = (area.height.saturating_sub(modal_height)) / 2;
let modal_area = Rect::new(x, y, modal_width, modal_height);
frame.render_widget(Clear, modal_area);
match modal {
Modal::Help => help::render(frame, modal_area),
Modal::Instructions { input } => instructions::render(frame, modal_area, input),
Modal::Search {
query,
results,
selected,
} => {
search::render(frame, modal_area, query, results, *selected);
}
Modal::Confirm { message, .. } => confirm::render(frame, modal_area, message),
Modal::Chat => chat_modal::render(frame, modal_area, &state.chat_state, last_render),
Modal::RefSelector {
input,
refs,
selected,
target,
} => ref_selector::render(frame, modal_area, input, refs, *selected, *target),
Modal::PresetSelector {
input,
presets,
selected,
scroll,
} => preset_selector::render(frame, modal_area, input, presets, *selected, *scroll),
Modal::EmojiSelector {
input,
emojis,
selected,
scroll,
} => emoji_selector::render(frame, modal_area, input, emojis, *selected, *scroll),
Modal::Settings(settings_state) => settings::render(frame, modal_area, settings_state),
Modal::ThemeSelector {
input,
themes,
selected,
scroll,
} => theme_selector::render(frame, modal_area, input, themes, *selected, *scroll),
Modal::CommitCount { input, target } => {
commit_count::render(frame, modal_area, input, *target);
}
}
}