121 lines
3.6 KiB
Rust
121 lines
3.6 KiB
Rust
use crate::client::tui::app::{App, MessageRole};
|
|
use crate::protocol::serialize_inbound;
|
|
use crate::protocol::WsInbound;
|
|
use crossterm::event::{KeyCode, KeyEvent};
|
|
use futures_util::SinkExt;
|
|
|
|
pub async fn handle_key_event(app: &mut App, key: KeyEvent) {
|
|
if app.show_help {
|
|
match key.code {
|
|
KeyCode::Esc | KeyCode::Char('q') => {
|
|
app.toggle_help();
|
|
}
|
|
_ => {}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if app.show_command_menu {
|
|
match key.code {
|
|
KeyCode::Esc => {
|
|
app.show_command_menu = false;
|
|
app.selected_command_idx = 0;
|
|
}
|
|
KeyCode::Up => {
|
|
app.select_prev_command();
|
|
}
|
|
KeyCode::Down => {
|
|
app.select_next_command();
|
|
}
|
|
KeyCode::Enter => {
|
|
app.insert_command();
|
|
app.show_command_menu = false;
|
|
app.selected_command_idx = 0;
|
|
}
|
|
KeyCode::Tab => {
|
|
app.insert_command();
|
|
}
|
|
_ => {
|
|
// Handle normal input and check if menu should stay open
|
|
handle_normal_input(app, key).await;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
handle_normal_input(app, key).await;
|
|
}
|
|
|
|
async fn handle_normal_input(app: &mut App, key: KeyEvent) {
|
|
match key.code {
|
|
KeyCode::Esc | KeyCode::Char('q') => {
|
|
app.quit();
|
|
}
|
|
KeyCode::Char('?') => {
|
|
app.toggle_help();
|
|
}
|
|
KeyCode::Char(c) => {
|
|
app.input_insert_char(c);
|
|
|
|
// Show command menu when input starts with /
|
|
if !app.show_command_menu && (app.input == "/" || (app.input.len() > 1 && app.input.starts_with('/'))) {
|
|
app.show_command_menu = true;
|
|
app.selected_command_idx = 0;
|
|
} else if app.show_command_menu && !app.input.starts_with('/') {
|
|
app.show_command_menu = false;
|
|
}
|
|
}
|
|
KeyCode::Backspace => {
|
|
app.input_delete_char();
|
|
|
|
// Hide menu if input no longer starts with /
|
|
if app.show_command_menu && !app.input.starts_with('/') {
|
|
app.show_command_menu = false;
|
|
app.selected_command_idx = 0;
|
|
}
|
|
}
|
|
KeyCode::Left => {
|
|
app.input_move_cursor_left();
|
|
}
|
|
KeyCode::Right => {
|
|
app.input_move_cursor_right();
|
|
}
|
|
KeyCode::Home => {
|
|
app.input_move_cursor_to_start();
|
|
}
|
|
KeyCode::End => {
|
|
app.input_move_cursor_to_end();
|
|
}
|
|
KeyCode::Up => {
|
|
app.scroll_chat_up();
|
|
}
|
|
KeyCode::Down => {
|
|
app.scroll_chat_down();
|
|
}
|
|
KeyCode::Enter => {
|
|
let input = app.take_input();
|
|
app.show_command_menu = false;
|
|
app.selected_command_idx = 0;
|
|
if !input.is_empty() {
|
|
process_input(app, input).await;
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
async fn process_input(app: &mut App, input: String) {
|
|
app.add_message(MessageRole::User, input.clone());
|
|
if let Some(sender) = &mut app.ws_sender {
|
|
let inbound = WsInbound::UserInput {
|
|
content: input,
|
|
chat_id: app.current_session_id.clone(),
|
|
channel: None,
|
|
sender_id: None,
|
|
};
|
|
if let Ok(text) = serialize_inbound(&inbound) {
|
|
let _ = sender.send(tokio_tungstenite::tungstenite::Message::Text(text.into())).await;
|
|
}
|
|
}
|
|
}
|