From 168acbf6dcda0574358654ecb7a11df82d01247f Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 5 Mar 2022 23:34:12 +0100 Subject: [PATCH] Set nick and join room While entering a nick and while present, events seem to get swallowed by the room. I'll need to rethink my event handling strategy and key bindings. For the key bindings, I'll either need global bindings that don't interfere with text boxes, or I'll need modal editing or something similar where pressing ESC enough brings you back to the global focus. Global key bindings are things like switching rooms and quitting. --- cove-tui/src/client/cove/room.rs | 4 ++++ cove-tui/src/ui.rs | 13 ++++++----- cove-tui/src/ui/cove.rs | 16 ++++++++------ cove-tui/src/ui/cove/body.rs | 38 +++++++++++++++++++++++++++----- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/cove-tui/src/client/cove/room.rs b/cove-tui/src/client/cove/room.rs index eb7a27f..1fb9fdc 100644 --- a/cove-tui/src/client/cove/room.rs +++ b/cove-tui/src/client/cove/room.rs @@ -91,6 +91,10 @@ impl CoveRoom { &self.name } + pub async fn identify(&self, nick: &str, identity: &str) { + self.conn().await.identify(nick, identity).await; + } + // TODO Disallow modification via this MutexGuard pub async fn conn(&self) -> MutexGuard<'_, CoveConn> { self.conn.lock().await diff --git a/cove-tui/src/ui.rs b/cove-tui/src/ui.rs index 82c49f4..5e17461 100644 --- a/cove-tui/src/ui.rs +++ b/cove-tui/src/ui.rs @@ -267,11 +267,14 @@ impl Ui { event: KeyEvent, ) -> Option { match &self.room { - Some(RoomId::Cove(name)) => self - .cove_rooms - .get_mut(name) - .and_then(|ui| ui.handle_key(event)) - .and(Some(EventHandleResult::Continue)), + Some(RoomId::Cove(name)) => { + if let Some(ui) = self.cove_rooms.get_mut(name) { + ui.handle_key(event).await; + Some(EventHandleResult::Continue) + } else { + None + } + } None => None, } } diff --git a/cove-tui/src/ui/cove.rs b/cove-tui/src/ui/cove.rs index e739cf6..d0a8e0d 100644 --- a/cove-tui/src/ui/cove.rs +++ b/cove-tui/src/ui/cove.rs @@ -10,7 +10,7 @@ use tui::Frame; use crate::client::cove::room::CoveRoom; -use self::body::Body; +use self::body::{Body, Reaction}; use self::users::CoveUsers; use super::input::EventHandler; @@ -78,12 +78,14 @@ impl CoveUi { frame.render_widget(CoveUsers::new(present), area); } } -} -impl EventHandler for CoveUi { - type Reaction = (); - - fn handle_key(&mut self, event: KeyEvent) -> Option { - None + pub async fn handle_key(&mut self, event: KeyEvent) -> Option<()> { + match self.body.handle_key(event)? { + Reaction::Handled => Some(()), + Reaction::Identify(nick) => { + self.room.identify(&nick, &nick).await; + Some(()) + } + } } } diff --git a/cove-tui/src/ui/cove/body.rs b/cove-tui/src/ui/cove/body.rs index 1ce7986..1c234cb 100644 --- a/cove-tui/src/ui/cove/body.rs +++ b/cove-tui/src/ui/cove/body.rs @@ -1,3 +1,4 @@ +use crossterm::event::{KeyCode, KeyEvent}; use tui::backend::Backend; use tui::layout::{Alignment, Constraint, Direction, Layout, Rect}; use tui::text::Span; @@ -7,6 +8,7 @@ use unicode_width::UnicodeWidthStr; use crate::client::cove::conn::{State, Status}; use crate::client::cove::room::CoveRoom; +use crate::ui::input::EventHandler; use crate::ui::textline::{TextLine, TextLineState}; use crate::ui::{layout, styles}; @@ -86,10 +88,11 @@ impl Body { let text_area = areas[1]; frame.render_widget( - Paragraph::new(Span::styled("Choose a nick:", styles::title())), + Paragraph::new(Span::styled("Choose a nick:", styles::title())) + .alignment(Alignment::Center), title_area, ); - frame.render_stateful_widget(TextLine, text_area, nick); + frame.render_stateful_widget(TextLine, layout::centered(50, 1, text_area), nick); } Body::ChooseNick { nick, @@ -109,12 +112,14 @@ impl Body { let error_area = areas[2]; frame.render_widget( - Paragraph::new(Span::styled("Choose a nick:", styles::title())), + Paragraph::new(Span::styled("Choose a nick:", styles::title())) + .alignment(Alignment::Center), title_area, ); - frame.render_stateful_widget(TextLine, text_area, nick); + frame.render_stateful_widget(TextLine, layout::centered(50, 1, text_area), nick); frame.render_widget( - Paragraph::new(Span::styled(error as &str, styles::error())), + Paragraph::new(Span::styled(error as &str, styles::error())) + .alignment(Alignment::Center), error_area, ); } @@ -131,3 +136,26 @@ impl Body { } } } + +pub enum Reaction { + Handled, + Identify(String), +} + +impl EventHandler for Body { + type Reaction = Reaction; + + fn handle_key(&mut self, event: KeyEvent) -> Option { + match self { + Body::ChooseNick { nick, .. } => { + if event.code == KeyCode::Enter { + Some(Reaction::Identify(nick.content().to_string())) + } else { + nick.handle_key(event).and(Some(Reaction::Handled)) + } + } + Body::Present => None, // TODO Implement + _ => None, + } + } +}