use std::collections::HashMap; use std::sync::Arc; use tokio::sync::Mutex; use tui::buffer::Buffer; use tui::layout::Rect; use tui::style::{Color, Modifier, Style}; use tui::text::{Span, Spans}; use tui::widgets::{Paragraph, Widget}; use crate::room::Room; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] struct RoomInfo { name: String, } pub struct Rooms { rooms: Vec, selected: Option, } impl Rooms { pub fn new(rooms: &HashMap>>) -> Self { let mut rooms = rooms .iter() .map(|(name, _room)| RoomInfo { name: name.clone() }) .collect::>(); rooms.sort(); Self { rooms, selected: None, } } pub fn select(mut self, name: &str) -> Self { for (i, room) in self.rooms.iter().enumerate() { if room.name == name { self.selected = Some(i); } } self } pub fn dummy() -> Self { fn r(s: &str) -> RoomInfo { RoomInfo { name: s.to_string(), } } let mut rooms = vec![r("xkcd"), r("test"), r("welcome"), r("music")]; rooms.sort(); Rooms { rooms, selected: None, } .select("welcome") } } impl Widget for Rooms { fn render(self, area: Rect, buf: &mut Buffer) { let title_style = Style::default().add_modifier(Modifier::BOLD); let room_style = Style::default().fg(Color::LightBlue); let selected_room_style = room_style.add_modifier(Modifier::BOLD); let title = if let Some(selected) = self.selected { format!("Rooms ({}/{})", selected + 1, self.rooms.len()) } else { format!("Rooms ({})", self.rooms.len()) }; let mut lines = vec![Spans::from(Span::styled(title, title_style))]; for (i, room) in self.rooms.iter().enumerate() { let name = format!("&{}", room.name); if Some(i) == self.selected { lines.push(Spans::from(vec![ Span::raw("\n>"), Span::styled(name, selected_room_style), ])); } else { lines.push(Spans::from(vec![ Span::raw("\n "), Span::styled(name, room_style), ])); } } Paragraph::new(lines).render(area, buf); } }