Show users if room knows them
Also selects the current room in the rooms list
This commit is contained in:
parent
ccf6a59f39
commit
f34bf63be4
7 changed files with 104 additions and 27 deletions
|
|
@ -36,9 +36,9 @@ struct Connected {
|
|||
}
|
||||
|
||||
/// State for when a client has fully joined a room.
|
||||
struct Present {
|
||||
session: Session,
|
||||
others: HashMap<SessionId, Session>,
|
||||
pub struct Present {
|
||||
pub session: Session,
|
||||
pub others: HashMap<SessionId, Session>,
|
||||
}
|
||||
|
||||
enum Status {
|
||||
|
|
@ -95,6 +95,10 @@ impl Room {
|
|||
room
|
||||
}
|
||||
|
||||
pub fn present(&self) -> Option<&Present> {
|
||||
self.present.as_ref()
|
||||
}
|
||||
|
||||
async fn bg_task(room: Arc<Mutex<Room>>, config: &'static Config) {
|
||||
let mut room_verified = false;
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -237,10 +237,18 @@ impl Ui {
|
|||
let users_pane_border = areas[3];
|
||||
let users_pane_area = areas[4];
|
||||
|
||||
// Rooms pane
|
||||
frame.render_widget(Rooms::new(&self.rooms), rooms_pane_area);
|
||||
// Main pane and users pane
|
||||
if let Some(room) = &mut self.room {
|
||||
room.render_main(frame, main_pane_area).await;
|
||||
room.render_users(frame, users_pane_area).await;
|
||||
}
|
||||
|
||||
// TODO Main pane and users pane
|
||||
// Rooms pane
|
||||
let mut rooms = Rooms::new(&self.rooms);
|
||||
if let Some(room) = &self.room {
|
||||
rooms = rooms.select(room.name());
|
||||
}
|
||||
frame.render_widget(rooms, rooms_pane_area);
|
||||
|
||||
// Pane borders and width
|
||||
self.rooms_pane.restrict_width(rooms_pane_area.width);
|
||||
|
|
@ -248,7 +256,7 @@ impl Ui {
|
|||
self.users_pane.restrict_width(users_pane_area.width);
|
||||
frame.render_widget(self.users_pane.border(), users_pane_border);
|
||||
|
||||
// Overlays
|
||||
// Overlay
|
||||
if let Some(overlay) = &mut self.overlay {
|
||||
match overlay {
|
||||
Overlay::JoinRoom(state) => {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
mod users;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use tokio::sync::Mutex;
|
||||
use tui::backend::Backend;
|
||||
use tui::layout::Rect;
|
||||
use tui::widgets::{Block, BorderType, Borders};
|
||||
use tui::Frame;
|
||||
|
||||
use crate::room::Room;
|
||||
|
||||
use self::users::Users;
|
||||
|
||||
pub struct RoomInfo {
|
||||
name: String,
|
||||
room: Arc<Mutex<Room>>,
|
||||
|
|
@ -21,11 +26,24 @@ impl RoomInfo {
|
|||
&self.name
|
||||
}
|
||||
|
||||
pub async fn render_messages<B: Backend>(&mut self, frame: &mut Frame<'_, B>, area: Rect) {
|
||||
pub async fn render_main<B: Backend>(&mut self, frame: &mut Frame<'_, B>, area: Rect) {
|
||||
// TODO Implement
|
||||
frame.render_widget(
|
||||
Block::default()
|
||||
.borders(Borders::TOP)
|
||||
.border_type(BorderType::Double),
|
||||
Rect {
|
||||
x: area.x,
|
||||
y: area.y + 1,
|
||||
width: area.width,
|
||||
height: 1,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
pub async fn render_users<B: Backend>(&mut self, frame: &mut Frame<'_, B>, area: Rect) {
|
||||
// TODO Implement
|
||||
if let Some(present) = self.room.lock().await.present() {
|
||||
frame.render_widget(Users::new(present), area);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
63
cove-tui/src/ui/room/users.rs
Normal file
63
cove-tui/src/ui/room/users.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
use std::collections::HashSet;
|
||||
use std::iter;
|
||||
|
||||
use cove_core::{Identity, Session};
|
||||
use tui::buffer::Buffer;
|
||||
use tui::layout::Rect;
|
||||
use tui::style::{Modifier, Style};
|
||||
use tui::text::{Span, Spans};
|
||||
use tui::widgets::{Paragraph, Widget};
|
||||
|
||||
use crate::room::Present;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct UserInfo {
|
||||
nick: String,
|
||||
identity: Identity,
|
||||
}
|
||||
|
||||
impl From<&Session> for UserInfo {
|
||||
fn from(s: &Session) -> Self {
|
||||
UserInfo {
|
||||
nick: s.nick.clone(),
|
||||
identity: s.identity,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Users {
|
||||
users: Vec<UserInfo>,
|
||||
}
|
||||
|
||||
impl Users {
|
||||
pub fn new(present: &Present) -> Self {
|
||||
let mut users: Vec<UserInfo> = iter::once(&present.session)
|
||||
.chain(present.others.values())
|
||||
.map(<&Session as Into<UserInfo>>::into)
|
||||
.collect();
|
||||
users.sort();
|
||||
Self { users }
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Users {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let title_style = Style::default().add_modifier(Modifier::BOLD);
|
||||
|
||||
let sessions = self.users.len();
|
||||
let identities = self
|
||||
.users
|
||||
.iter()
|
||||
.map(|i| i.identity)
|
||||
.collect::<HashSet<_>>()
|
||||
.len();
|
||||
let title = format!("Users ({identities}/{sessions})");
|
||||
|
||||
let mut lines = vec![Spans::from(Span::styled(title, title_style))];
|
||||
for user in self.users {
|
||||
// TODO Colour users based on identity
|
||||
lines.push(Spans::from(Span::from(user.nick)));
|
||||
}
|
||||
Paragraph::new(lines).render(area, buf);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,22 +41,6 @@ impl Rooms {
|
|||
}
|
||||
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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue