leetcode_tui_rs/widgets/
question.rs

1use super::stats;
2use crate::ctx::Ctx;
3use leetcode_tui_config::CONFIG;
4use leetcode_tui_shared::layout::GetWindowStats;
5use ratatui::prelude::*;
6use ratatui::widgets::{Block, BorderType, Borders, List, ListItem, Widget};
7
8pub struct Questions<'a> {
9    cx: &'a Ctx,
10}
11
12impl<'a> Questions<'a> {
13    pub(super) fn new(cx: &'a Ctx) -> Self {
14        Self { cx }
15    }
16
17    fn prepare_list_item<'b>(
18        &self,
19        q: &'b leetcode_tui_db::DbQuestion,
20        hovered: &'b leetcode_tui_db::DbQuestion,
21    ) -> ListItem<'b> {
22        let config = &CONFIG.as_ref().theme.question;
23        let c_hovered = &config.hovered;
24        let normal = &config.normal;
25        let easy_hovered: Style = c_hovered.easy.into();
26        let medium_hovered = c_hovered.medium.into();
27        let hard_hovered = c_hovered.hard.into();
28        let easy = normal.easy.into();
29        let medium = normal.medium.into();
30        let hard = normal.hard.into();
31
32        ListItem::new(q.to_string()).style(if q.id == hovered.id {
33            if q.is_easy() {
34                easy_hovered
35            } else if q.is_medium() {
36                medium_hovered
37            } else {
38                hard_hovered
39            }
40        } else {
41            if q.is_easy() {
42                easy
43            } else if q.is_medium() {
44                medium
45            } else {
46                hard
47            }
48        })
49    }
50
51    fn get_questions_list(&self) -> Option<Vec<ListItem<'_>>> {
52        if let Some(hovered) = self.cx.content.get_questions().hovered() {
53            return Some(
54                self.cx
55                    .content
56                    .get_questions()
57                    .window()
58                    .iter()
59                    .map(|q| self.prepare_list_item(q, hovered))
60                    .collect::<Vec<_>>(),
61            );
62        }
63        None
64    }
65}
66
67impl<'a> Widget for Questions<'a> {
68    fn render(self, _area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) {
69        let medium: Style = CONFIG.as_ref().theme.border.hovered.into();
70        let q_area_surrounding_block = Block::default()
71            .borders(Borders::ALL)
72            .border_type(BorderType::Rounded)
73            .border_style(medium)
74            .cyan()
75            .title("Questions")
76            .title_alignment(Alignment::Center);
77
78        let term_window = self.get_window();
79
80        q_area_surrounding_block.render(term_window.root.center_layout.question.outer, buf);
81
82        if let Some(ql) = self.get_questions_list() {
83            let list = List::new(ql);
84            ratatui::prelude::Widget::render(
85                list,
86                term_window.root.center_layout.question.inner,
87                buf,
88            );
89            if self.cx.content.get_questions().is_stats_visible() {
90                stats::Stats::new(&self.cx.content.get_questions())
91                    .render(term_window.root.q_stats.outer, buf);
92            }
93        }
94    }
95}