multiverse/widgets/search/
mod.rs1use 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}