use crate::app::SubmoduleUpdateTarget;
use crate::ui::layout::{centered_rect, centered_rect_fixed};
use crate::ui::style::{ACCENT, CARD_BORDER, DANGER, WARNING, muted_style, primary_style};
use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, Borders, Clear, Padding, Paragraph};
pub fn draw_submodule_add_url_popup(f: &mut Frame, input_buffer: &str, area: Rect) {
let popup_area = centered_rect(60, 20, area);
f.render_widget(Clear, popup_area);
let block = Block::default()
.borders(Borders::ALL)
.border_type(CARD_BORDER())
.border_style(Style::default().fg(ACCENT()))
.title(Line::from(vec![
Span::raw(" "),
Span::styled("Add Submodule - Step 1/2", primary_style()),
Span::raw(" "),
]))
.padding(Padding::horizontal(1));
let content = vec![
Line::from(vec![Span::styled(
"Enter submodule repository URL (e.g. https://github.com/foo/bar.git):",
muted_style(),
)]),
Line::from(""),
Line::from(vec![
Span::styled("> ", Style::default().fg(ACCENT())),
Span::styled(input_buffer, Style::default()),
]),
Line::from(""),
Line::from(vec![
Span::styled("[Enter]", primary_style()),
Span::styled(" Next ", muted_style()),
Span::styled("[Esc]", primary_style()),
Span::styled(" Cancel", muted_style()),
]),
];
let inner_area = block.inner(popup_area);
f.render_widget(block, popup_area);
f.render_widget(Paragraph::new(content), inner_area);
let cursor_y = inner_area.y.saturating_add(2);
let cursor_x =
inner_area.x.saturating_add(2).saturating_add(input_buffer.chars().count() as u16);
f.set_cursor_position(ratatui::layout::Position::new(cursor_x, cursor_y));
}
pub fn draw_submodule_add_path_popup(f: &mut Frame, input_buffer: &str, url: &str, area: Rect) {
let popup_area = centered_rect(60, 20, area);
f.render_widget(Clear, popup_area);
let block = Block::default()
.borders(Borders::ALL)
.border_type(CARD_BORDER())
.border_style(Style::default().fg(ACCENT()))
.title(Line::from(vec![
Span::raw(" "),
Span::styled("Add Submodule - Step 2/2", primary_style()),
Span::raw(" "),
]))
.padding(Padding::horizontal(1));
let content = vec![
Line::from(vec![
Span::styled("Repository URL: ", muted_style()),
Span::styled(url, primary_style()),
]),
Line::from(""),
Line::from(vec![Span::styled("Enter destination path (e.g. libs/bar):", muted_style())]),
Line::from(""),
Line::from(vec![
Span::styled("> ", Style::default().fg(ACCENT())),
Span::styled(input_buffer, Style::default()),
]),
Line::from(""),
Line::from(vec![
Span::styled("[Enter]", primary_style()),
Span::styled(" Add ", muted_style()),
Span::styled("[Esc]", primary_style()),
Span::styled(" Cancel", muted_style()),
]),
];
let inner_area = block.inner(popup_area);
f.render_widget(block, popup_area);
f.render_widget(Paragraph::new(content), inner_area);
let cursor_y = inner_area.y.saturating_add(4);
let cursor_x =
inner_area.x.saturating_add(2).saturating_add(input_buffer.chars().count() as u16);
f.set_cursor_position(ratatui::layout::Position::new(cursor_x, cursor_y));
}
pub fn draw_submodule_delete_popup(f: &mut Frame, sub: &crate::repo::SubmoduleInfo, area: Rect) {
let block = Block::default()
.borders(Borders::ALL)
.border_type(CARD_BORDER())
.border_style(Style::default().fg(DANGER()))
.title(Line::from(vec![
Span::raw(" "),
Span::styled("Delete Submodule", primary_style()),
Span::raw(" "),
]))
.padding(Padding::horizontal(1));
let path = sub.path.display().to_string();
let mut content = vec![
Line::from(vec![Span::styled(
"Are you sure you want to completely delete the submodule at:",
primary_style(),
)]),
Line::from(""),
Line::from(vec![
Span::raw(" "),
Span::styled(path.clone(), Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
]),
];
if sub.name != path {
content.push(Line::from(vec![
Span::styled(" name: ", muted_style()),
Span::raw(sub.name.clone()),
]));
}
content.extend([
Line::from(""),
Line::from(vec![Span::styled(
"This will deinitialize and remove the submodule directory.",
Style::default().fg(DANGER()),
)]),
Line::from(""),
Line::from(vec![
Span::styled("Confirm: ", muted_style()),
Span::styled("y", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::styled(" / Cancel: ", muted_style()),
Span::styled("n", Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD)),
]),
]);
let popup_area = centered_rect_fixed(area.width * 55 / 100, content.len() as u16 + 2, area);
f.render_widget(Clear, popup_area);
let inner_area = block.inner(popup_area);
f.render_widget(block, popup_area);
f.render_widget(Paragraph::new(content), inner_area);
}
pub fn draw_submodule_update_popup(f: &mut Frame, target: &SubmoduleUpdateTarget, area: Rect) {
const MAX_LISTED: usize = 6;
let title = if target.path.is_some() { "Update Submodule" } else { "Update Submodules" };
let block = Block::default()
.borders(Borders::ALL)
.border_type(CARD_BORDER())
.border_style(Style::default().fg(WARNING()))
.title(Line::from(vec![
Span::raw(" "),
Span::styled(title, primary_style()),
Span::raw(" "),
]))
.padding(Padding::horizontal(1));
let mut content = vec![
Line::from(vec![Span::styled(
"This checks out the commit the repository records in:",
primary_style(),
)]),
Line::from(""),
];
for path in target.modified.iter().take(MAX_LISTED) {
content.push(Line::from(vec![
Span::raw(" "),
Span::styled(
path.display().to_string(),
Style::default().fg(WARNING()).add_modifier(Modifier::BOLD),
),
]));
}
if target.modified.len() > MAX_LISTED {
let more = format!(" ...and {} more", target.modified.len() - MAX_LISTED);
content.push(Line::from(vec![Span::styled(more, muted_style())]));
}
content.extend([
Line::from(""),
Line::from(vec![Span::styled(
"Commits made there that no branch holds are left behind.",
Style::default().fg(WARNING()),
)]),
Line::from(vec![Span::styled(
"Uncommitted changes are kept: the update fails instead.",
muted_style(),
)]),
Line::from(""),
Line::from(vec![
Span::styled("Confirm: ", muted_style()),
Span::styled("y", Style::default().fg(WARNING()).add_modifier(Modifier::BOLD)),
Span::styled(" / Cancel: ", muted_style()),
Span::styled("n", Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD)),
]),
]);
let popup_area = centered_rect_fixed(area.width * 55 / 100, content.len() as u16 + 2, area);
f.render_widget(Clear, popup_area);
let inner_area = block.inner(popup_area);
f.render_widget(block, popup_area);
f.render_widget(Paragraph::new(content), inner_area);
}