multiverse/widgets/search/
mod.rs

1use crossterm::event::KeyEvent;
2use matrix_sdk::ruma::OwnedEventId;
3use ratatui::{
4    layout::Flex,
5    prelude::*,
6    widgets::{Block, Borders, Cell, Clear, Padding, Row, Table, TableState},
7};
8
9use crate::widgets::popup_input::PopupInput;
10
11#[derive(Default)]
12pub struct SearchingView {
13    input: PopupInput,
14    results: Option<Vec<OwnedEventId>>,
15}
16
17impl SearchingView {
18    pub fn new() -> Self {
19        Self {
20            input: PopupInput::new("Search", "(Enter search query)")
21                .height_constraint(Constraint::Percentage(100))
22                .width_constraint(Constraint::Percentage(100)),
23            results: None,
24        }
25    }
26
27    pub fn results(&mut self, values: Vec<OwnedEventId>) {
28        self.results = Some(values);
29    }
30
31    pub fn get_text(&self) -> Option<String> {
32        let name = self.input.get_input();
33        if !name.is_empty() { Some(name) } else { None }
34    }
35
36    pub fn handle_key_press(&mut self, key: KeyEvent) {
37        self.input.handle_key_press(key);
38    }
39}
40
41impl Widget for &mut SearchingView {
42    fn render(self, area: Rect, buf: &mut Buffer) {
43        let vertical = Layout::vertical([Constraint::Length(3), Constraint::Percentage(80)])
44            .flex(Flex::Center);
45        let horizontal = Layout::horizontal([Constraint::Percentage(50)]).flex(Flex::Center);
46        let [area] = horizontal.areas(area);
47        let [search_area, results_area] = vertical.areas(area);
48
49        let rows = if let Some(results) = &self.results {
50            results
51                .iter()
52                .map(|ev_id| Row::new([Cell::new(ev_id.to_string())]))
53                .collect::<Vec<Row<'_>>>()
54        } else {
55            vec![Row::new([Cell::new("No results found!")])]
56        };
57
58        let block =
59            Block::bordered().title(" Search ").borders(Borders::ALL).padding(Padding::left(2));
60
61        let results_table = Table::new(rows, [Constraint::Percentage(100)]).block(block);
62
63        Clear.render(results_area, buf);
64        StatefulWidget::render(results_table, results_area, buf, &mut TableState::default());
65
66        self.input.render(search_area, buf);
67    }
68}