use super::{PICKER_MODAL, draw_modal_panel, picker_modal_list_area};
use crate::tui::{state::MissionControlState, theme::MATRIX_GREEN};
use ratatui::{
Frame,
layout::{Rect, Size},
text::{Line, Span},
widgets::{List, ListItem, ListState, Paragraph},
};
use tui_scrollview::{ScrollView, ScrollbarVisibility};
pub(crate) fn models_modal_list_area(area: Rect) -> Option<Rect> {
picker_modal_list_area(area, "Models", 2)
}
pub(in crate::tui::render) fn draw_models_modal(
frame: &mut Frame<'_>,
area: Rect,
state: &MissionControlState,
) {
let Some(modal_state) = &state.modals.models_modal else {
return;
};
let Some(text_area) = draw_modal_panel(frame, area, "Models", PICKER_MODAL) else {
return;
};
if text_area.height == 0 {
return;
}
frame.render_widget(
Paragraph::new(super::super::hotkey_line(
"[Tab] switch scope • [Up]/[Down] move • [Enter] toggle • [Esc] close",
MATRIX_GREEN.muted(false),
))
.style(MATRIX_GREEN.muted(false)),
Rect::new(text_area.x, text_area.y, text_area.width, 1),
);
frame.render_widget(
Paragraph::new(format!("Scope: {}", modal_state.scope_label)).style(MATRIX_GREEN.pane()),
Rect::new(
text_area.x,
text_area.y.saturating_add(1),
text_area.width,
1,
),
);
let list_y = text_area.y.saturating_add(2);
let list_height = text_area
.y
.saturating_add(text_area.height)
.saturating_sub(list_y);
if list_height == 0 {
return;
}
if modal_state.loading {
frame.render_widget(
Paragraph::new("Loading models...").style(MATRIX_GREEN.pane()),
Rect::new(text_area.x, list_y, text_area.width, list_height),
);
return;
}
if modal_state.rows.is_empty() {
frame.render_widget(
Paragraph::new("No models discovered").style(MATRIX_GREEN.pane()),
Rect::new(text_area.x, list_y, text_area.width, list_height),
);
return;
}
let content_height =
super::super::usize_to_u16_saturating(modal_state.rows.len().max(usize::from(list_height)));
let content_width =
super::super::scroll_view_content_width(Rect::new(0, 0, text_area.width, list_height));
let mut view = ScrollView::new(Size::new(content_width, content_height))
.vertical_scrollbar_visibility(ScrollbarVisibility::Always)
.horizontal_scrollbar_visibility(ScrollbarVisibility::Never);
let items = modal_state
.rows
.iter()
.map(|row| {
let mark = if row.enabled { "[x]" } else { "[ ]" };
let disabled = if row.enabled { "" } else { " [disabled]" };
let label = if row.display_name.is_empty() || row.display_name == row.id {
format!("{mark} {}{disabled}", row.id)
} else {
format!("{mark} {} {}{disabled}", row.id, row.display_name)
};
ListItem::new(Line::from(vec![Span::raw(label)]))
})
.collect::<Vec<_>>();
let mut list_state = ListState::default().with_selected(Some(modal_state.selected));
view.render_stateful_widget(
List::new(items)
.style(MATRIX_GREEN.pane())
.highlight_style(MATRIX_GREEN.selection())
.highlight_symbol("> "),
Rect::new(0, 0, content_width, content_height),
&mut list_state,
);
frame.render_stateful_widget(
view,
Rect::new(text_area.x, list_y, text_area.width, list_height),
&mut *state.scroll_views.models_modal.borrow_mut(),
);
}