Add 'choose nick' dialog

This commit is contained in:
Joscha 2022-07-23 23:00:09 +02:00
parent 7818855cb6
commit 77c5b479aa
2 changed files with 74 additions and 19 deletions

View file

@ -15,16 +15,27 @@ 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::border::Border; use super::widgets::border::Border;
use super::widgets::editor::EditorState;
use super::widgets::empty::Empty; use super::widgets::empty::Empty;
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::list::{List, ListState}; use super::widgets::list::{List, ListState};
use super::widgets::padding::Padding; use super::widgets::padding::Padding;
use super::widgets::text::Text; use super::widgets::text::Text;
use super::widgets::BoxedWidget; use super::widgets::BoxedWidget;
use super::{util, UiEvent}; use super::UiEvent;
enum State {
Normal,
ChooseNick(EditorState),
}
pub struct EuphRoom { pub struct EuphRoom {
ui_event_tx: mpsc::UnboundedSender<UiEvent>, ui_event_tx: mpsc::UnboundedSender<UiEvent>,
state: State,
room: Option<euph::Room>, room: Option<euph::Room>,
chat: ChatState<EuphMsg, EuphVault>, chat: ChatState<EuphMsg, EuphVault>,
nick_list: ListState<String>, nick_list: ListState<String>,
@ -34,6 +45,7 @@ impl EuphRoom {
pub fn new(vault: EuphVault, ui_event_tx: mpsc::UnboundedSender<UiEvent>) -> Self { pub fn new(vault: EuphVault, ui_event_tx: mpsc::UnboundedSender<UiEvent>) -> Self {
Self { Self {
ui_event_tx, ui_event_tx,
state: State::Normal,
room: None, room: None,
chat: ChatState::new(vault), chat: ChatState::new(vault),
nick_list: ListState::new(), nick_list: ListState::new(),
@ -75,9 +87,29 @@ impl EuphRoom {
pub async fn widget(&self) -> BoxedWidget { pub async fn widget(&self) -> BoxedWidget {
let status = self.status().await; let status = self.status().await;
match &status { let chat = match &status {
Some(Some(Status::Joined(joined))) => self.widget_with_nick_list(&status, joined), Some(Some(Status::Joined(joined))) => self.widget_with_nick_list(&status, joined),
_ => self.widget_without_nick_list(&status), _ => 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<FairMutex<()>>, crossterm_lock: &Arc<FairMutex<()>>,
event: KeyEvent, 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 Some(room) = &self.room {
if let Ok(Some(Status::Joined(_))) = room.status().await { if let Ok(Some(Status::Joined(joined))) = room.status().await {
if let KeyCode::Char('n' | 'N') = event.code { if let KeyCode::Char('n' | 'N') = event.code {
if let Some(new_nick) = util::prompt(terminal, crossterm_lock) { self.state = State::ChooseNick(EditorState::with_initial_text(
let _ = room.nick(new_nick); 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),
_ => {}
},
} }
} }
} }

View file

@ -28,9 +28,9 @@ struct InnerEditorState {
} }
impl InnerEditorState { impl InnerEditorState {
fn new() -> Self { fn new(text: String) -> Self {
Self { Self {
text: String::new(), text,
idx: 0, idx: 0,
last_width: 0, last_width: 0,
} }
@ -179,7 +179,11 @@ pub struct EditorState(Arc<Mutex<InnerEditorState>>);
impl EditorState { impl EditorState {
pub fn new() -> Self { 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 { pub fn widget(&self) -> Editor {