use crate::{
client::ui::MIN_ROOM_CODE_LEN,
common::{message::RpsData, result::DynResult, rps::simple_move::SimpleUserMove},
};
use super::app::App;
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent, KeyModifiers};
use tui_input::backend::crossterm::EventHandler;
pub async fn handle_key_events(key_event: KeyEvent, app: &mut App) -> DynResult<()> {
match key_event.code {
KeyCode::Enter => handle_confirm_action(app).await?,
KeyCode::Esc => {
if app.pop_up.is_some() {
app.close_err_pop_up();
} else {
app.quit();
}
}
KeyCode::Char('c') | KeyCode::Char('C') if key_event.modifiers == KeyModifiers::CONTROL => {
app.quit();
}
_ => {
if app.text_input_allowed() {
if let Some(state) = app.input.handle_event(&CrosstermEvent::Key(key_event)) {
if state.value {
app.close_err_pop_up();
}
}
}
}
};
Ok(())
}
pub async fn handle_confirm_action(app: &mut App) -> DynResult<()> {
if app.user_tried_to_change_state_already || app.is_waiting_for_others() {
return Ok(());
}
if app.submit_error.is_some() {
app.close_err_pop_up();
return Ok(());
}
app.submit_error = None;
use crate::common::rps::state::RpsState::*;
match app.client_state.state {
BeforeRoom => {
if app.input.value().len() < MIN_ROOM_CODE_LEN {
app.submit_error = Some(format!(
"The provided room code is too short, has to be at least {MIN_ROOM_CODE_LEN} long."
))
} else {
match app.input.value().parse() {
Ok(room_id) => {
app.do_move(SimpleUserMove::JoinRoom(room_id))?;
app.input.reset();
}
Err(err) => app.submit_error = Some(err.to_string()),
}
}
}
InRoom => {
let max_len = app.input_max_length() as usize;
let input_bytes = app.input.value().as_bytes();
if app.input.value().is_empty() {
app.submit_error = Some("Cannot submit an empty string.".into())
} else if input_bytes.len() > max_len {
app.submit_error = Some(format!(
"The provided input is too long, it can be at most {max_len} bytes long."
))
} else {
let mut arr = [0u8; 20];
arr[..input_bytes.len()].copy_from_slice(input_bytes);
let data = RpsData::new(arr).expect(
"should never fail as input_bytes has to be valid utf8 and can't be longer than allowed",
);
app.do_move(SimpleUserMove::Play(data))?;
app.input.reset();
}
}
Played => {
app.do_move(SimpleUserMove::ConfirmPlay)?;
}
Confirmed => {
app.do_move(SimpleUserMove::BackToRoom)?;
}
};
if app.submit_error.is_none() {
app.user_tried_to_change_state_already = true;
}
Ok(())
}