use super::{Component, DrawableComponent, EventState}; use crate::event::Key; use crate::user_config::Connection; use anyhow::Result; use tui::{ backend::Backend, layout::Rect, style::{Color, Style}, text::{Span, Spans}, widgets::{Block, Borders, Clear, List, ListItem, ListState}, Frame, }; pub struct ConnectionsComponent { pub connections: Vec, pub state: ListState, } impl Default for ConnectionsComponent { fn default() -> Self { Self { connections: Vec::new(), state: ListState::default(), } } } impl ConnectionsComponent { pub fn new(connections: Vec) -> Self { Self { connections, ..Self::default() } } pub fn next_connection(&mut self) { let i = match self.state.selected() { Some(i) => { if i >= self.connections.len() - 1 { 0 } else { i + 1 } } None => 0, }; self.state.select(Some(i)); } pub fn previous_connection(&mut self) { let i = match self.state.selected() { Some(i) => { if i == 0 { self.connections.len() - 1 } else { i - 1 } } None => 0, }; self.state.select(Some(i)); } pub fn selected_connection(&self) -> Option<&Connection> { match self.state.selected() { Some(i) => self.connections.get(i), None => None, } } } impl DrawableComponent for ConnectionsComponent { fn draw(&mut self, f: &mut Frame, _area: Rect, _focused: bool) -> Result<()> { let width = 80; let height = 20; let conns = &self.connections; let connections: Vec = conns .iter() .map(|i| { ListItem::new(vec![Spans::from(Span::raw(i.database_url()))]) .style(Style::default()) }) .collect(); let tasks = List::new(connections) .block(Block::default().borders(Borders::ALL).title("Connections")) .highlight_style(Style::default().bg(Color::Blue)) .style(Style::default()); let area = Rect::new( (f.size().width.saturating_sub(width)) / 2, (f.size().height.saturating_sub(height)) / 2, width.min(f.size().width), height.min(f.size().height), ); f.render_widget(Clear, area); f.render_stateful_widget(tasks, area, &mut self.state); Ok(()) } } impl Component for ConnectionsComponent { fn event(&mut self, key: Key) -> Result { match key { Key::Char('j') => { self.next_connection(); return Ok(EventState::Consumed); } Key::Char('k') => { self.previous_connection(); return Ok(EventState::Consumed); } _ => (), } Ok(EventState::NotConsumed) } }