multiverse/widgets/search/
indexing.rs1use ratatui::{
2 layout::Flex,
3 prelude::*,
4 widgets::{Block, BorderType, Clear, Paragraph, Wrap},
5};
6use throbber_widgets_tui::ThrobberState;
7
8use crate::{HEADER_BG, NORMAL_ROW_COLOR, TEXT_COLOR, popup_area};
9
10pub enum IndexingMessage {
11 Progress(usize),
12 Error(String),
13}
14
15impl Default for IndexingMessage {
16 fn default() -> Self {
17 IndexingMessage::Progress(0)
18 }
19}
20
21#[derive(Default)]
22pub struct IndexingView {
23 throbber_state: ThrobberState,
24 message: IndexingMessage,
25}
26
27impl IndexingView {
28 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn on_tick(&mut self) {
33 self.throbber_state.calc_next();
34 }
35
36 pub fn set_message(&mut self, message: IndexingMessage) {
37 self.message = message;
38 }
39}
40
41impl Widget for &mut IndexingView {
42 fn render(self, area: Rect, buf: &mut Buffer) {
43 let outer_area = popup_area(area, 80, 80);
44 let block = Block::bordered()
45 .border_type(BorderType::Double)
46 .border_style(Style::default().fg(TEXT_COLOR).bg(HEADER_BG))
47 .style(Style::default().fg(TEXT_COLOR).bg(NORMAL_ROW_COLOR));
48 Clear.render(outer_area, buf);
49
50 let inner_area = block.inner(outer_area);
51 block.render(outer_area, buf);
52
53 match &self.message {
54 IndexingMessage::Error(err) => {
55 let message = format!(
56 "An error occurred during indexing, press Escape to return to main screen: {err}"
57 );
58
59 let [area] = Layout::horizontal([Constraint::Length(message.len() as u16)])
60 .flex(Flex::Center)
61 .areas(inner_area);
62 let [area] =
63 Layout::vertical([Constraint::Length(1)]).flex(Flex::Center).areas(area);
64
65 let paragraph = Paragraph::new(message).wrap(Wrap { trim: true });
66
67 paragraph.render(area, buf);
68 }
69 IndexingMessage::Progress(progress) => {
70 let label = format!("Indexing...({})", progress);
71
72 let [area] = Layout::horizontal([Constraint::Length(label.len() as u16)])
73 .flex(Flex::Center)
74 .areas(inner_area);
75 let [area] =
76 Layout::vertical([Constraint::Length(1)]).flex(Flex::Center).areas(area);
77
78 let throbber = throbber_widgets_tui::Throbber::default()
79 .label(label)
80 .style(Style::default().fg(TEXT_COLOR).bg(NORMAL_ROW_COLOR))
81 .throbber_style(Style::default().fg(TEXT_COLOR).bg(NORMAL_ROW_COLOR))
82 .throbber_set(throbber_widgets_tui::BRAILLE_EIGHT_DOUBLE)
83 .use_type(throbber_widgets_tui::WhichUse::Spin);
84
85 StatefulWidget::render(throbber, area, buf, &mut self.throbber_state);
86 }
87 }
88 }
89}