1use ratatui::{
4 buffer::Buffer,
5 layout::Rect,
6 widgets::{Block, Borders, Paragraph, Widget, Wrap},
7};
8
9use super::app::{App, Screen};
10use super::components::confirm::Confirm;
11use super::components::input::Input;
12use super::components::list::List;
13use super::helpers::{color_diff_lines, layouts};
14use super::style::BORDER_STYLE;
15
16impl Widget for &App {
17 fn render(self, area: Rect, buf: &mut Buffer) {
18 match self.screen() {
19 Screen::Input(screen) => {
20 if self.show_diff() {
21 let diff = self.pending_diff();
22 let diff_lines = diff.lines().count();
23 let (main_area, diff_area) =
24 layouts::content_with_diff_preview(area, diff_lines);
25 Input::new(
26 &screen.state,
27 &screen.prompt,
28 self.context(),
29 screen.label.as_deref(),
30 self.show_diff(),
31 )
32 .render(main_area, buf);
33 render_diff_preview(&diff, diff_area, buf);
34 } else {
35 Input::new(
36 &screen.state,
37 &screen.prompt,
38 self.context(),
39 screen.label.as_deref(),
40 self.show_diff(),
41 )
42 .render(area, buf);
43 }
44 }
45 Screen::List(screen) => {
46 if self.show_diff() {
47 let diff = self.pending_diff();
48 if !diff.is_empty() {
50 let diff_lines = diff.lines().count();
51 let (main_area, diff_area) =
52 layouts::content_with_diff_preview(area, diff_lines);
53 List::new(&screen.state, &screen.prompt, self.context())
54 .render(main_area, buf);
55 render_diff_preview(&diff, diff_area, buf);
56 } else {
57 List::new(&screen.state, &screen.prompt, self.context()).render(area, buf);
58 }
59 } else {
60 List::new(&screen.state, &screen.prompt, self.context()).render(area, buf);
61 }
62 }
63 Screen::Confirm(screen) => {
64 Confirm::new(&screen.diff, self.context()).render(area, buf);
65 }
66 }
67 }
68}
69
70fn render_diff_preview(diff: &str, area: Rect, buf: &mut Buffer) {
72 let content = Paragraph::new(color_diff_lines(diff))
73 .block(
74 Block::default()
75 .borders(Borders::TOP | Borders::BOTTOM)
76 .border_style(BORDER_STYLE),
77 )
78 .wrap(Wrap { trim: false });
79 content.render(area, buf);
80}