1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! Handles user input for the chat UI.
use super::state::{InputMode, State};
use color_eyre::Result;
use crossterm::event::KeyCode;
/// Handles user input for the chat UI.
#[derive(Default)]
pub struct InputHandler;
impl InputHandler {
/// Creates a new `InputHandler` instance.
#[must_use]
pub fn new() -> Self {
InputHandler
}
/// Handles input in normal mode.
///
/// # Arguments
///
/// * `ui_state` - A mutable reference to the current UI state.
/// * `key` - The key code of the pressed key.
pub fn handle_normal_mode(&self, ui_state: &mut State, key: KeyCode) {
match key {
KeyCode::Char('q') => ui_state.quit = true,
KeyCode::Char('?') => ui_state.show_toggle = !ui_state.show_toggle,
KeyCode::Char('e') => ui_state.input_mode = InputMode::Editing,
KeyCode::Up => ui_state.scroll_up(),
KeyCode::Down => ui_state.scroll_down(),
_ => {}
}
}
/// Handles input in editing mode.
///
/// # Arguments
///
/// * `ui_state` - A mutable reference to the current UI state.
/// * `key` - The key code of the pressed key.
///
/// # Returns
///
/// A `Result` containing an `Option<String>` with the user's message if Enter was pressed.
///
/// # Errors
///
/// This function will return an error if there are issues updating the UI state.
pub fn handle_editing_mode(
&self,
ui_state: &mut State,
key: KeyCode,
) -> Result<Option<String>> {
match key {
KeyCode::Enter => {
let message: String = ui_state.input.drain(..).collect();
ui_state
.messages
.push(("user".to_string(), message.clone()));
ui_state.input_mode = InputMode::Waiting;
ui_state
.messages
.push(("system".to_string(), "Generating...".to_string()));
ui_state.horizontal_scroll = 0;
ui_state.horizontal_scroll_state = ratatui::widgets::ScrollbarState::default();
Ok(Some(message))
}
KeyCode::Char(c) => {
ui_state.input.push(c);
Ok(None)
}
KeyCode::Backspace => {
ui_state.input.pop();
Ok(None)
}
KeyCode::Esc => {
ui_state.input_mode = InputMode::Normal;
Ok(None)
}
KeyCode::Left => {
ui_state.horizontal_scroll = ui_state.horizontal_scroll.saturating_sub(1);
Ok(None)
}
KeyCode::Right => {
let max_scroll = ui_state
.input
.len()
.saturating_sub(ui_state.input_width as usize);
ui_state.horizontal_scroll = (ui_state.horizontal_scroll + 1).min(max_scroll);
Ok(None)
}
_ => Ok(None),
}
}
}