From 77c5b479aa617abd0497b124517cd06260623c63 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 23 Jul 2022 23:00:09 +0200 Subject: [PATCH] Add 'choose nick' dialog --- src/ui/room.rs | 83 ++++++++++++++++++++++++++++++++-------- src/ui/widgets/editor.rs | 10 +++-- 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/ui/room.rs b/src/ui/room.rs index a0b3067..d0c6bc0 100644 --- a/src/ui/room.rs +++ b/src/ui/room.rs @@ -15,16 +15,27 @@ use crate::vault::{EuphMsg, EuphVault}; use super::chat::ChatState; use super::widgets::background::Background; use super::widgets::border::Border; +use super::widgets::editor::EditorState; use super::widgets::empty::Empty; +use super::widgets::float::Float; use super::widgets::join::{HJoin, Segment, VJoin}; +use super::widgets::layer::Layer; use super::widgets::list::{List, ListState}; use super::widgets::padding::Padding; use super::widgets::text::Text; use super::widgets::BoxedWidget; -use super::{util, UiEvent}; +use super::UiEvent; + +enum State { + Normal, + ChooseNick(EditorState), +} pub struct EuphRoom { ui_event_tx: mpsc::UnboundedSender, + + state: State, + room: Option, chat: ChatState, nick_list: ListState, @@ -34,6 +45,7 @@ impl EuphRoom { pub fn new(vault: EuphVault, ui_event_tx: mpsc::UnboundedSender) -> Self { Self { ui_event_tx, + state: State::Normal, room: None, chat: ChatState::new(vault), nick_list: ListState::new(), @@ -75,9 +87,29 @@ impl EuphRoom { pub async fn widget(&self) -> BoxedWidget { let status = self.status().await; - match &status { + let chat = match &status { Some(Some(Status::Joined(joined))) => self.widget_with_nick_list(&status, joined), _ => self.widget_without_nick_list(&status), + }; + match &self.state { + State::Normal => chat, + State::ChooseNick(ed) => Layer::new(vec![ + chat, + Float::new(Border::new( + Padding::new(VJoin::new(vec![ + Segment::new(Text::new("Choose nick ")), + Segment::new( + ed.widget() + .highlight(|s| Styled::new((s, euph::nick_style(s)))), + ), + ])) + .left(1), + )) + .horizontal(0.5) + .vertical(0.5) + .into(), + ]) + .into(), } } @@ -245,24 +277,43 @@ impl EuphRoom { crossterm_lock: &Arc>, event: KeyEvent, ) { - self.chat.handle_navigation(event).await; + match &self.state { + State::Normal => { + self.chat.handle_navigation(event).await; - if let Some(room) = &self.room { - if let Ok(Some(Status::Joined(_))) = room.status().await { - if let KeyCode::Char('n' | 'N') = event.code { - if let Some(new_nick) = util::prompt(terminal, crossterm_lock) { - let _ = room.nick(new_nick); + if let Some(room) = &self.room { + if let Ok(Some(Status::Joined(joined))) = room.status().await { + if let KeyCode::Char('n' | 'N') = event.code { + self.state = State::ChooseNick(EditorState::with_initial_text( + joined.session.name.clone(), + )); + } + + let potential_message = self + .chat + .handle_messaging(terminal, crossterm_lock, event) + .await; + if let Some((parent, content)) = potential_message { + let _ = room.send(parent, content); + } } } - - let potential_message = self - .chat - .handle_messaging(terminal, crossterm_lock, event) - .await; - if let Some((parent, content)) = potential_message { - let _ = room.send(parent, content); - } } + State::ChooseNick(ed) => match event.code { + KeyCode::Esc => self.state = State::Normal, + KeyCode::Enter => { + if let Some(room) = &self.room { + let _ = room.nick(ed.text()); + } + self.state = State::Normal; + } + KeyCode::Backspace => ed.backspace(), + KeyCode::Left => ed.move_cursor_left(), + KeyCode::Right => ed.move_cursor_right(), + KeyCode::Delete => ed.delete(), + KeyCode::Char(ch) => ed.insert_char(ch), + _ => {} + }, } } } diff --git a/src/ui/widgets/editor.rs b/src/ui/widgets/editor.rs index d2eb564..9a20de1 100644 --- a/src/ui/widgets/editor.rs +++ b/src/ui/widgets/editor.rs @@ -28,9 +28,9 @@ struct InnerEditorState { } impl InnerEditorState { - fn new() -> Self { + fn new(text: String) -> Self { Self { - text: String::new(), + text, idx: 0, last_width: 0, } @@ -179,7 +179,11 @@ pub struct EditorState(Arc>); impl EditorState { pub fn new() -> Self { - Self(Arc::new(Mutex::new(InnerEditorState::new()))) + Self(Arc::new(Mutex::new(InnerEditorState::new(String::new())))) + } + + pub fn with_initial_text(text: String) -> Self { + Self(Arc::new(Mutex::new(InnerEditorState::new(text)))) } pub fn widget(&self) -> Editor {