use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::style::Style;
use ratatui::widgets::Block;
use ratatui::Frame;
use crate::app::{App, AppScreen};
use crate::features;
use crate::widgets;
pub fn render(app: &mut App, frame: &mut Frame) {
let bg = app.theme().bg;
frame.render_widget(
Block::default().style(Style::default().bg(bg)),
frame.area(),
);
match app.screen {
AppScreen::Welcome => {
features::repo::view::render(&*app, frame, frame.area());
}
AppScreen::DirBrowser => {
features::repo::view::render_browser(app, frame, frame.area());
}
AppScreen::Main => {
render_main(app, frame);
}
}
}
fn render_main(app: &mut App, frame: &mut Frame) {
let initial_load = app.tab().is_loading && app.tab().commits.is_empty();
if initial_load {
features::skeleton::render(app, frame);
return;
}
let outer = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(3),
Constraint::Percentage(60),
Constraint::Percentage(40),
Constraint::Length(1),
])
.split(frame.area());
widgets::header::render(app, frame, outer[0]);
let longest_branch = app
.tab()
.branches
.iter()
.map(|b| b.name.chars().count())
.max()
.unwrap_or(10);
let ideal_sidebar = (longest_branch + 6) as u16;
let term_width = outer[1].width;
let max_sidebar = (term_width * 30 / 100).clamp(22, 50);
let sidebar_width = ideal_sidebar.min(max_sidebar).max(22);
let main_cols = Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Length(sidebar_width),
Constraint::Percentage(40),
Constraint::Min(20),
])
.split(outer[1]);
let sidebar = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Min(6), Constraint::Length(5), Constraint::Length(5), ])
.split(main_cols[0]);
features::branches::view::render(app, frame, sidebar[0]);
features::stash::view::render(app, frame, sidebar[1]);
features::remotes::view::render(app, frame, sidebar[2]);
features::commits::view::render(app, frame, main_cols[1]);
let overlay_rect = Rect {
x: main_cols[2].x,
y: main_cols[2].y,
width: main_cols[2].width,
height: main_cols[2].height + outer[2].height,
};
if app.show_about_panel {
features::about::view::render(app, frame, overlay_rect);
} else if app.show_theme_panel {
features::theme::view::render(app, frame, overlay_rect);
} else if app.show_options_panel {
features::options::view::render(app, frame, overlay_rect);
} else if app.show_editor_panel {
features::editor::view::render(app, frame, main_cols[2]);
} else if app.tab().file_history_path.is_some() {
features::diff::view::render_file_history(app, frame, main_cols[2]);
} else if app.tab().blame_path.is_some() {
features::diff::view::render_blame(app, frame, main_cols[2]);
} else {
features::diff::view::render(app, frame, main_cols[2]);
}
if !app.show_theme_panel && !app.show_options_panel && !app.show_about_panel {
features::staging::view::render(app, frame, outer[2]);
} else {
let staging_partial = Rect {
x: outer[2].x,
y: outer[2].y,
width: main_cols[2].x.saturating_sub(outer[2].x),
height: outer[2].height,
};
features::staging::view::render(app, frame, staging_partial);
}
widgets::status_bar::render(app, frame, outer[3]);
}