use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::style::Style;
use ratatui::widgets::{Block, Borders};
use ratatui::Frame;
use tui_skeleton::{AnimationMode, SkeletonBlock, SkeletonList, SkeletonTable};
use crate::app::App;
pub fn render(app: &mut App, frame: &mut Frame) {
let theme = app.theme();
let elapsed_ms = app.tick_count.saturating_mul(33);
let base = theme.border_inactive; let hi = theme.sel_bg;
let area = frame.area();
let outer = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(3),
Constraint::Percentage(60),
Constraint::Percentage(40),
Constraint::Length(1),
])
.split(area);
crate::widgets::header::render(app, frame, outer[0]);
let main_cols = Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Length(24),
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]);
let inner = pane(
frame,
sidebar[0],
" Branches ",
theme.border_inactive,
theme.bg,
);
frame.render_widget(
SkeletonList::new(elapsed_ms)
.mode(AnimationMode::Sweep)
.items(10)
.base(base)
.highlight(hi),
inner,
);
let inner = pane(
frame,
sidebar[1],
" Stashes ",
theme.border_inactive,
theme.bg,
);
frame.render_widget(
SkeletonList::new(elapsed_ms)
.mode(AnimationMode::Sweep)
.items(3)
.base(base)
.highlight(hi),
inner,
);
let inner = pane(
frame,
sidebar[2],
" Remotes ",
theme.border_inactive,
theme.bg,
);
frame.render_widget(
SkeletonList::new(elapsed_ms)
.mode(AnimationMode::Sweep)
.items(2)
.base(base)
.highlight(hi),
inner,
);
let inner = pane(
frame,
main_cols[1],
" Commit Log ",
theme.border_inactive,
theme.bg,
);
frame.render_widget(
SkeletonTable::new(elapsed_ms)
.mode(AnimationMode::Sweep)
.rows(30)
.columns(&[
Constraint::Length(2), Constraint::Length(8), Constraint::Fill(1), Constraint::Length(14), Constraint::Length(9), ])
.zebra(true)
.base(base)
.highlight(hi),
inner,
);
let inner = pane(
frame,
main_cols[2],
" Diff ",
theme.border_inactive,
theme.bg,
);
frame.render_widget(
SkeletonBlock::new(elapsed_ms)
.mode(AnimationMode::Sweep)
.base(base)
.highlight(hi),
inner,
);
let staging_cols = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)])
.split(outer[2]);
let inner = pane(
frame,
staging_cols[0],
" Unstaged ",
theme.border_inactive,
theme.bg,
);
frame.render_widget(
SkeletonList::new(elapsed_ms)
.mode(AnimationMode::Sweep)
.items(5)
.base(base)
.highlight(hi),
inner,
);
let inner = pane(
frame,
staging_cols[1],
" Staged ",
theme.border_inactive,
theme.bg,
);
frame.render_widget(
SkeletonList::new(elapsed_ms)
.mode(AnimationMode::Sweep)
.items(5)
.base(base)
.highlight(hi),
inner,
);
crate::widgets::status_bar::render(app, frame, outer[3]);
}
fn pane(
frame: &mut Frame,
area: Rect,
title: &str,
border_color: ratatui::style::Color,
bg_color: ratatui::style::Color,
) -> Rect {
let block = Block::default()
.title(title)
.borders(Borders::ALL)
.border_style(Style::default().fg(border_color))
.style(Style::default().bg(bg_color));
let inner = block.inner(area);
frame.render_widget(block, area);
inner
}