Use popup widget builder

This commit is contained in:
Joscha 2022-08-20 23:17:48 +02:00
parent 4094ba3e3d
commit 6c637390e4
3 changed files with 44 additions and 58 deletions

View file

@ -1,19 +1,16 @@
use crossterm::style::{ContentStyle, Stylize}; use crossterm::style::{ContentStyle, Stylize};
use toss::styled::Styled; use toss::styled::Styled;
use crate::ui::widgets::background::Background;
use crate::ui::widgets::border::Border;
use crate::ui::widgets::float::Float; use crate::ui::widgets::float::Float;
use crate::ui::widgets::layer::Layer; use crate::ui::widgets::popup::Popup;
use crate::ui::widgets::padding::Padding;
use crate::ui::widgets::text::Text; use crate::ui::widgets::text::Text;
use crate::ui::widgets::BoxedWidget; use crate::ui::widgets::BoxedWidget;
pub enum Popup { pub enum RoomPopup {
ServerError { description: String, reason: String }, ServerError { description: String, reason: String },
} }
impl Popup { impl RoomPopup {
fn server_error_widget(description: &str, reason: &str) -> BoxedWidget { fn server_error_widget(description: &str, reason: &str) -> BoxedWidget {
let border_style = ContentStyle::default().red().bold(); let border_style = ContentStyle::default().red().bold();
let text = Styled::new_plain(description) let text = Styled::new_plain(description)
@ -21,15 +18,10 @@ impl Popup {
.then("Reason:", ContentStyle::default().bold()) .then("Reason:", ContentStyle::default().bold())
.then_plain(" ") .then_plain(" ")
.then_plain(reason); .then_plain(reason);
Layer::new(vec![ Popup::new(Text::new(text))
Border::new(Background::new(Padding::new(Text::new(text)).horizontal(1))) .title(("Error", border_style))
.style(border_style) .border(border_style)
.into(), .build()
Float::new(Padding::new(Text::new(("Error", border_style))).horizontal(1))
.horizontal(0.5)
.into(),
])
.into()
} }
pub fn widget(&self) -> BoxedWidget { pub fn widget(&self) -> BoxedWidget {

View file

@ -21,17 +21,17 @@ use crate::ui::widgets::background::Background;
use crate::ui::widgets::border::Border; use crate::ui::widgets::border::Border;
use crate::ui::widgets::editor::EditorState; use crate::ui::widgets::editor::EditorState;
use crate::ui::widgets::empty::Empty; use crate::ui::widgets::empty::Empty;
use crate::ui::widgets::float::Float;
use crate::ui::widgets::join::{HJoin, Segment, VJoin}; use crate::ui::widgets::join::{HJoin, Segment, VJoin};
use crate::ui::widgets::layer::Layer; use crate::ui::widgets::layer::Layer;
use crate::ui::widgets::list::{List, ListState}; use crate::ui::widgets::list::{List, ListState};
use crate::ui::widgets::padding::Padding; use crate::ui::widgets::padding::Padding;
use crate::ui::widgets::popup::Popup;
use crate::ui::widgets::text::Text; use crate::ui::widgets::text::Text;
use crate::ui::widgets::BoxedWidget; use crate::ui::widgets::BoxedWidget;
use crate::ui::{util, UiEvent}; use crate::ui::{util, UiEvent};
use crate::vault::EuphVault; use crate::vault::EuphVault;
use super::popup::Popup; use super::popup::RoomPopup;
enum State { enum State {
Normal, Normal,
@ -45,7 +45,7 @@ pub struct EuphRoom {
room: Option<euph::Room>, room: Option<euph::Room>,
state: State, state: State,
popups: VecDeque<Popup>, popups: VecDeque<RoomPopup>,
chat: ChatState<euph::SmallMessage, EuphVault>, chat: ChatState<euph::SmallMessage, EuphVault>,
last_msg_sent: Option<oneshot::Receiver<Snowflake>>, last_msg_sent: Option<oneshot::Receiver<Snowflake>>,
@ -155,21 +155,7 @@ impl EuphRoom {
match &self.state { match &self.state {
State::Normal => {} State::Normal => {}
State::ChooseNick(ed) => layers.push( State::ChooseNick(editor) => layers.push(Self::choose_nick_widget(editor)),
Float::new(Border::new(Background::new(VJoin::new(vec![
Segment::new(Padding::new(Text::new("Choose nick")).horizontal(1)),
Segment::new(
Padding::new(
ed.widget()
.highlight(|s| Styled::new(s, euph::nick_style(s))),
)
.left(1),
),
]))))
.horizontal(0.5)
.vertical(0.5)
.into(),
),
} }
for popup in &self.popups { for popup in &self.popups {
@ -179,6 +165,16 @@ impl EuphRoom {
Layer::new(layers).into() Layer::new(layers).into()
} }
fn choose_nick_widget(editor: &EditorState) -> BoxedWidget {
let editor = editor
.widget()
.highlight(|s| Styled::new(s, euph::nick_style(s)));
Popup::new(Padding::new(editor).left(1))
.title("Choose nick")
.inner_padding(false)
.build()
}
async fn widget_without_nick_list(&self, status: &Option<Option<Status>>) -> BoxedWidget { async fn widget_without_nick_list(&self, status: &Option<Option<Status>>) -> BoxedWidget {
VJoin::new(vec![ VJoin::new(vec![
Segment::new(Border::new( Segment::new(Border::new(
@ -470,7 +466,7 @@ impl EuphRoom {
pub fn handle_euph_room_event(&mut self, event: EuphRoomEvent) -> bool { pub fn handle_euph_room_event(&mut self, event: EuphRoomEvent) -> bool {
match event { match event {
EuphRoomEvent::Connected | EuphRoomEvent::Disconnected => true, EuphRoomEvent::Connected | EuphRoomEvent::Disconnected | EuphRoomEvent::Stopped => true,
EuphRoomEvent::Packet(packet) => match packet.content { EuphRoomEvent::Packet(packet) => match packet.content {
Ok(data) => self.handle_euph_data(data), Ok(data) => self.handle_euph_data(data),
Err(reason) => self.handle_euph_error(packet.r#type, reason), Err(reason) => self.handle_euph_error(packet.r#type, reason),
@ -521,7 +517,7 @@ impl EuphRoom {
_ => return false, _ => return false,
}; };
let description = format!("Failed to {action}."); let description = format!("Failed to {action}.");
self.popups.push_front(Popup::ServerError { self.popups.push_front(RoomPopup::ServerError {
description, description,
reason, reason,
}); });

View file

@ -16,14 +16,12 @@ use crate::vault::Vault;
use super::euph::room::EuphRoom; use super::euph::room::EuphRoom;
use super::input::{key, InputEvent, KeyBindingsList, KeyEvent}; use super::input::{key, InputEvent, KeyBindingsList, KeyEvent};
use super::widgets::background::Background;
use super::widgets::border::Border;
use super::widgets::editor::EditorState; use super::widgets::editor::EditorState;
use super::widgets::float::Float;
use super::widgets::join::{HJoin, Segment, VJoin}; use super::widgets::join::{HJoin, Segment, VJoin};
use super::widgets::layer::Layer; use super::widgets::layer::Layer;
use super::widgets::list::{List, ListState}; use super::widgets::list::{List, ListState};
use super::widgets::padding::Padding; use super::widgets::padding::Padding;
use super::widgets::popup::Popup;
use super::widgets::text::Text; use super::widgets::text::Text;
use super::widgets::BoxedWidget; use super::widgets::BoxedWidget;
use super::{util, UiEvent}; use super::{util, UiEvent};
@ -104,29 +102,29 @@ impl Rooms {
.widget() .widget()
.await .await
} }
State::Connect(ed) => { State::Connect(editor) => Layer::new(vec![
let room_style = ContentStyle::default().bold().blue(); self.rooms_widget().await,
Layer::new(vec![ Self::new_room_widget(editor),
self.rooms_widget().await, ])
Float::new(Border::new(Background::new(VJoin::new(vec![ .into(),
Segment::new(Padding::new(Text::new("Connect to")).horizontal(1)),
Segment::new(
Padding::new(HJoin::new(vec![
Segment::new(Text::new(("&", room_style))),
Segment::new(ed.widget().highlight(|s| Styled::new(s, room_style))),
]))
.left(1),
),
]))))
.horizontal(0.5)
.vertical(0.5)
.into(),
])
.into()
}
} }
} }
fn new_room_widget(editor: &EditorState) -> BoxedWidget {
let room_style = ContentStyle::default().bold().blue();
let editor = editor.widget().highlight(|s| Styled::new(s, room_style));
Popup::new(
Padding::new(HJoin::new(vec![
Segment::new(Text::new(("&", room_style))),
Segment::new(editor).priority(0),
]))
.left(1),
)
.title("Connect to")
.inner_padding(false)
.build()
}
fn format_pbln(joined: &Joined) -> String { fn format_pbln(joined: &Joined) -> String {
let mut p = 0_usize; let mut p = 0_usize;
let mut b = 0_usize; let mut b = 0_usize;