Render room using only widgets
This commit is contained in:
parent
3e6b214e81
commit
8b3166c6d7
2 changed files with 45 additions and 89 deletions
132
src/ui/room.rs
132
src/ui/room.rs
|
|
@ -5,7 +5,6 @@ use crossterm::event::{KeyCode, KeyEvent};
|
||||||
use crossterm::style::{Color, ContentStyle, Stylize};
|
use crossterm::style::{Color, ContentStyle, Stylize};
|
||||||
use parking_lot::FairMutex;
|
use parking_lot::FairMutex;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use toss::frame::{Frame, Pos, Size};
|
|
||||||
use toss::styled::Styled;
|
use toss::styled::Styled;
|
||||||
use toss::terminal::Terminal;
|
use toss::terminal::Terminal;
|
||||||
|
|
||||||
|
|
@ -16,10 +15,11 @@ use crate::vault::{EuphMsg, EuphVault};
|
||||||
use super::chat::ChatState;
|
use super::chat::ChatState;
|
||||||
use super::widgets::background::Background;
|
use super::widgets::background::Background;
|
||||||
use super::widgets::empty::Empty;
|
use super::widgets::empty::Empty;
|
||||||
|
use super::widgets::join::{HJoin, Segment, VJoin};
|
||||||
use super::widgets::list::{List, ListState};
|
use super::widgets::list::{List, ListState};
|
||||||
use super::widgets::rules::{HRule, VRule};
|
use super::widgets::rules::{HRule, VRule};
|
||||||
use super::widgets::text::Text;
|
use super::widgets::text::Text;
|
||||||
use super::widgets::Widget;
|
use super::widgets::BoxedWidget;
|
||||||
use super::{util, UiEvent};
|
use super::{util, UiEvent};
|
||||||
|
|
||||||
pub struct EuphRoom {
|
pub struct EuphRoom {
|
||||||
|
|
@ -75,82 +75,43 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn render(&mut self, frame: &mut Frame) {
|
pub async fn widget(&self) -> BoxedWidget {
|
||||||
let status = self.status().await;
|
let status = self.status().await;
|
||||||
match &status {
|
match &status {
|
||||||
Some(Some(Status::Joined(joined))) => {
|
Some(Some(Status::Joined(joined))) => self.widget_with_nick_list(&status, joined),
|
||||||
self.render_with_nick_list(frame, &status, joined).await
|
_ => self.widget_without_nick_list(&status),
|
||||||
}
|
|
||||||
_ => self.render_without_nick_list(frame, &status).await,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn render_without_nick_list(
|
fn widget_without_nick_list(&self, status: &Option<Option<Status>>) -> BoxedWidget {
|
||||||
&mut self,
|
VJoin::new(vec![
|
||||||
frame: &mut Frame,
|
Segment::new(self.status_widget(status)),
|
||||||
status: &Option<Option<Status>>,
|
Segment::new(HRule),
|
||||||
) {
|
Segment::new(self.chat.widget()).expanding(true),
|
||||||
let size = frame.size();
|
])
|
||||||
|
.into()
|
||||||
// Position of horizontal line between status and chat
|
|
||||||
let hsplit = 1_i32;
|
|
||||||
|
|
||||||
let status_pos = Pos::new(0, 0);
|
|
||||||
// let status_size = Size::new(size.width, 1);
|
|
||||||
|
|
||||||
let chat_pos = Pos::new(0, hsplit + 1);
|
|
||||||
let chat_size = Size::new(size.width, size.height.saturating_sub(hsplit as u16 + 1));
|
|
||||||
|
|
||||||
frame.push(chat_pos, chat_size);
|
|
||||||
Box::new(self.chat.widget()).render(frame).await;
|
|
||||||
frame.pop();
|
|
||||||
self.render_status(frame, status_pos, status);
|
|
||||||
|
|
||||||
frame.push(Pos::new(0, hsplit), Size::new(size.width, 1));
|
|
||||||
Box::new(HRule).render(frame).await;
|
|
||||||
frame.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn render_with_nick_list(
|
fn widget_with_nick_list(
|
||||||
&mut self,
|
&self,
|
||||||
frame: &mut Frame,
|
|
||||||
status: &Option<Option<Status>>,
|
status: &Option<Option<Status>>,
|
||||||
joined: &Joined,
|
joined: &Joined,
|
||||||
) {
|
) -> BoxedWidget {
|
||||||
let size = frame.size();
|
HJoin::new(vec![
|
||||||
|
Segment::new(VJoin::new(vec![
|
||||||
// Position of vertical line between main part and nick list
|
Segment::new(self.status_widget(status)),
|
||||||
let vsplit = size.width.saturating_sub(self.nick_list_width + 1) as i32;
|
Segment::new(HRule),
|
||||||
// Position of horizontal line between status and chat
|
Segment::new(self.chat.widget()).expanding(true),
|
||||||
let hsplit = 1_i32;
|
]))
|
||||||
|
.expanding(true),
|
||||||
let status_pos = Pos::new(0, 0);
|
Segment::new(VRule),
|
||||||
// let status_size = Size::new(vsplit as u16, 1);
|
// TODO Fix nick list width
|
||||||
|
Segment::new(self.nick_list_widget(joined)),
|
||||||
let chat_pos = Pos::new(0, hsplit + 1);
|
])
|
||||||
let chat_size = Size::new(vsplit as u16, size.height.saturating_sub(hsplit as u16 + 1));
|
.into()
|
||||||
|
|
||||||
let nick_list_pos = Pos::new(vsplit + 1, 0);
|
|
||||||
let nick_list_size = Size::new(self.nick_list_width, size.height);
|
|
||||||
|
|
||||||
frame.push(chat_pos, chat_size);
|
|
||||||
Box::new(self.chat.widget()).render(frame).await;
|
|
||||||
frame.pop();
|
|
||||||
|
|
||||||
self.render_status(frame, status_pos, status);
|
|
||||||
self.render_nick_list(frame, nick_list_pos, nick_list_size, joined)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
frame.push(Pos::new(0, hsplit), Size::new(vsplit as u16, 1));
|
|
||||||
Box::new(HRule).render(frame).await;
|
|
||||||
frame.pop();
|
|
||||||
|
|
||||||
frame.push(Pos::new(vsplit, 0), Size::new(1, size.height));
|
|
||||||
Box::new(VRule).render(frame).await;
|
|
||||||
frame.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_status(&self, frame: &mut Frame, pos: Pos, status: &Option<Option<Status>>) {
|
fn status_widget(&self, status: &Option<Option<Status>>) -> BoxedWidget {
|
||||||
let room = self.chat.store().room();
|
let room = self.chat.store().room();
|
||||||
let room_style = ContentStyle::default().bold().blue();
|
let room_style = ContentStyle::default().bold().blue();
|
||||||
let mut info = Styled::new((format!("&{room}"), room_style));
|
let mut info = Styled::new((format!("&{room}"), room_style));
|
||||||
|
|
@ -169,10 +130,14 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
frame.write(pos, info);
|
Text::new(info).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_row(list: &mut List<String>, session: &SessionView, own_session: &SessionView) {
|
fn render_nick_list_row(
|
||||||
|
list: &mut List<String>,
|
||||||
|
session: &SessionView,
|
||||||
|
own_session: &SessionView,
|
||||||
|
) {
|
||||||
let id = session.session_id.clone();
|
let id = session.session_id.clone();
|
||||||
|
|
||||||
let (name, style, style_inv) = if session.name.is_empty() {
|
let (name, style, style_inv) = if session.name.is_empty() {
|
||||||
|
|
@ -214,7 +179,7 @@ impl EuphRoom {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_section(
|
fn render_nick_list_section(
|
||||||
list: &mut List<String>,
|
list: &mut List<String>,
|
||||||
name: &str,
|
name: &str,
|
||||||
sessions: &[&SessionView],
|
sessions: &[&SessionView],
|
||||||
|
|
@ -234,11 +199,11 @@ impl EuphRoom {
|
||||||
list.add_unsel(Text::new(row));
|
list.add_unsel(Text::new(row));
|
||||||
|
|
||||||
for session in sessions {
|
for session in sessions {
|
||||||
Self::render_row(list, session, own_session);
|
Self::render_nick_list_row(list, session, own_session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_rows(list: &mut List<String>, joined: &Joined) {
|
fn render_nick_list_rows(list: &mut List<String>, joined: &Joined) {
|
||||||
let mut people = vec![];
|
let mut people = vec![];
|
||||||
let mut bots = vec![];
|
let mut bots = vec![];
|
||||||
let mut lurkers = vec![];
|
let mut lurkers = vec![];
|
||||||
|
|
@ -262,25 +227,16 @@ impl EuphRoom {
|
||||||
lurkers.sort_unstable_by_key(|s| &s.session_id);
|
lurkers.sort_unstable_by_key(|s| &s.session_id);
|
||||||
nurkers.sort_unstable_by_key(|s| &s.session_id);
|
nurkers.sort_unstable_by_key(|s| &s.session_id);
|
||||||
|
|
||||||
Self::render_section(list, "People", &people, &joined.session);
|
Self::render_nick_list_section(list, "People", &people, &joined.session);
|
||||||
Self::render_section(list, "Bots", &bots, &joined.session);
|
Self::render_nick_list_section(list, "Bots", &bots, &joined.session);
|
||||||
Self::render_section(list, "Lurkers", &lurkers, &joined.session);
|
Self::render_nick_list_section(list, "Lurkers", &lurkers, &joined.session);
|
||||||
Self::render_section(list, "Nurkers", &nurkers, &joined.session);
|
Self::render_nick_list_section(list, "Nurkers", &nurkers, &joined.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn render_nick_list(&mut self, frame: &mut Frame, pos: Pos, size: Size, joined: &Joined) {
|
fn nick_list_widget(&self, joined: &Joined) -> BoxedWidget {
|
||||||
// Clear area in case there's overdraw from the chat or status
|
|
||||||
for y in pos.y..(pos.y + size.height as i32) {
|
|
||||||
for x in pos.x..(pos.x + size.width as i32) {
|
|
||||||
frame.write(Pos::new(x, y), " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut list = self.nick_list.list();
|
let mut list = self.nick_list.list();
|
||||||
Self::render_rows(&mut list, joined);
|
Self::render_nick_list_rows(&mut list, joined);
|
||||||
frame.push(pos, size);
|
list.into()
|
||||||
Box::new(list).render(frame).await;
|
|
||||||
frame.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_key_event(
|
pub async fn handle_key_event(
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ impl Rooms {
|
||||||
let actual_room = self.euph_rooms.entry(room.clone()).or_insert_with(|| {
|
let actual_room = self.euph_rooms.entry(room.clone()).or_insert_with(|| {
|
||||||
EuphRoom::new(self.vault.euph(room.clone()), self.ui_event_tx.clone())
|
EuphRoom::new(self.vault.euph(room.clone()), self.ui_event_tx.clone())
|
||||||
});
|
});
|
||||||
actual_room.render(frame).await;
|
actual_room.widget().await.render(frame).await;
|
||||||
} else {
|
} else {
|
||||||
self.render_rooms(frame).await;
|
self.render_rooms(frame).await;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue