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.
This commit is contained in:
parent
32959cf691
commit
168acbf6dc
4 changed files with 54 additions and 17 deletions
|
|
@ -91,6 +91,10 @@ impl CoveRoom {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn identify(&self, nick: &str, identity: &str) {
|
||||||
|
self.conn().await.identify(nick, identity).await;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Disallow modification via this MutexGuard
|
// TODO Disallow modification via this MutexGuard
|
||||||
pub async fn conn(&self) -> MutexGuard<'_, CoveConn> {
|
pub async fn conn(&self) -> MutexGuard<'_, CoveConn> {
|
||||||
self.conn.lock().await
|
self.conn.lock().await
|
||||||
|
|
|
||||||
|
|
@ -267,11 +267,14 @@ impl Ui {
|
||||||
event: KeyEvent,
|
event: KeyEvent,
|
||||||
) -> Option<EventHandleResult> {
|
) -> Option<EventHandleResult> {
|
||||||
match &self.room {
|
match &self.room {
|
||||||
Some(RoomId::Cove(name)) => self
|
Some(RoomId::Cove(name)) => {
|
||||||
.cove_rooms
|
if let Some(ui) = self.cove_rooms.get_mut(name) {
|
||||||
.get_mut(name)
|
ui.handle_key(event).await;
|
||||||
.and_then(|ui| ui.handle_key(event))
|
Some(EventHandleResult::Continue)
|
||||||
.and(Some(EventHandleResult::Continue)),
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use tui::Frame;
|
||||||
|
|
||||||
use crate::client::cove::room::CoveRoom;
|
use crate::client::cove::room::CoveRoom;
|
||||||
|
|
||||||
use self::body::Body;
|
use self::body::{Body, Reaction};
|
||||||
use self::users::CoveUsers;
|
use self::users::CoveUsers;
|
||||||
|
|
||||||
use super::input::EventHandler;
|
use super::input::EventHandler;
|
||||||
|
|
@ -78,12 +78,14 @@ impl CoveUi {
|
||||||
frame.render_widget(CoveUsers::new(present), area);
|
frame.render_widget(CoveUsers::new(present), area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl EventHandler for CoveUi {
|
pub async fn handle_key(&mut self, event: KeyEvent) -> Option<()> {
|
||||||
type Reaction = ();
|
match self.body.handle_key(event)? {
|
||||||
|
Reaction::Handled => Some(()),
|
||||||
fn handle_key(&mut self, event: KeyEvent) -> Option<Self::Reaction> {
|
Reaction::Identify(nick) => {
|
||||||
None
|
self.room.identify(&nick, &nick).await;
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crossterm::event::{KeyCode, KeyEvent};
|
||||||
use tui::backend::Backend;
|
use tui::backend::Backend;
|
||||||
use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
|
use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
|
||||||
use tui::text::Span;
|
use tui::text::Span;
|
||||||
|
|
@ -7,6 +8,7 @@ use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use crate::client::cove::conn::{State, Status};
|
use crate::client::cove::conn::{State, Status};
|
||||||
use crate::client::cove::room::CoveRoom;
|
use crate::client::cove::room::CoveRoom;
|
||||||
|
use crate::ui::input::EventHandler;
|
||||||
use crate::ui::textline::{TextLine, TextLineState};
|
use crate::ui::textline::{TextLine, TextLineState};
|
||||||
use crate::ui::{layout, styles};
|
use crate::ui::{layout, styles};
|
||||||
|
|
||||||
|
|
@ -86,10 +88,11 @@ impl Body {
|
||||||
let text_area = areas[1];
|
let text_area = areas[1];
|
||||||
|
|
||||||
frame.render_widget(
|
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,
|
title_area,
|
||||||
);
|
);
|
||||||
frame.render_stateful_widget(TextLine, text_area, nick);
|
frame.render_stateful_widget(TextLine, layout::centered(50, 1, text_area), nick);
|
||||||
}
|
}
|
||||||
Body::ChooseNick {
|
Body::ChooseNick {
|
||||||
nick,
|
nick,
|
||||||
|
|
@ -109,12 +112,14 @@ impl Body {
|
||||||
let error_area = areas[2];
|
let error_area = areas[2];
|
||||||
|
|
||||||
frame.render_widget(
|
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,
|
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(
|
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,
|
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<Self::Reaction> {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue