Add 'choose nick' dialog
This commit is contained in:
parent
7818855cb6
commit
77c5b479aa
2 changed files with 74 additions and 19 deletions
|
|
@ -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),
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue