coco/tui/widgets/
commit_msg.rs

1use {
2    crate::{core::state::commit::ConventionalCommitMessage, tui::color},
3    matetui::ratatui::{
4        prelude::{Buffer, Line, Rect, Span, Stylize, Widget},
5        widgets::Paragraph,
6    },
7};
8
9pub struct CommitMessage {
10    msg: ConventionalCommitMessage,
11}
12
13impl CommitMessage {
14    pub fn new(msg: ConventionalCommitMessage) -> Self {
15        Self { msg }
16    }
17}
18
19impl Widget for CommitMessage {
20    fn render(self, area: Rect, buf: &mut Buffer) {
21        let mut lines = vec![];
22        // # Title
23
24        // kind(scope)!: {emoji} summary
25        // the ! is only shown if breaking change
26        // the (scope) is only shown if scope is present
27        // the emoji is only shown if emoji is present
28        let mut description_line = vec![Span::from(self.msg.kind).bold().fg(color("#8cc265"))];
29
30        if !self.msg.scope.is_empty() {
31            description_line.extend_from_slice(&[
32                "(".black(),
33                Span::from(self.msg.scope).bold().fg(color("#125acc")),
34                ")".black(),
35            ]);
36        }
37
38        if self.msg.breaking {
39            description_line.push(Span::from("!").black());
40        }
41
42        description_line.push(Span::from(": ").black());
43
44        description_line.extend_from_slice(&[Span::from(format!("{} ", self.msg.emoji)).bold()]);
45
46        description_line.push(Span::from(self.msg.summary).fg(color("#6a4ac3")));
47
48        lines.push(Line::from(description_line));
49
50        if !is_empty(&self.msg.body) {
51            lines.push(Line::from(vec![Span::from("")]));
52
53            for line in self.msg.body {
54                lines.push(Line::from(vec![Span::from(line)]).fg(color("#f34e70")));
55            }
56        }
57
58        if !is_empty(&self.msg.footer) {
59            lines.push(Line::from(vec![Span::from("")]));
60
61            for line in self.msg.footer {
62                lines.push(Line::from(vec![Span::from(line)]).fg(color("#db279f")));
63            }
64        }
65
66        Paragraph::new(lines).render(area, buf);
67    }
68}
69
70/// returns true if the given all strings joined by \n ends up being empty or None
71fn is_empty(s: &[String]) -> bool {
72    s.join("\n").is_empty()
73}