diff options
author | Oxbian <oxbian@mailbox.org> | 2025-02-21 16:17:00 -0500 |
---|---|---|
committer | Oxbian <oxbian@mailbox.org> | 2025-02-21 16:17:00 -0500 |
commit | bc53ad567b82ca354f2b8caf30f242717a5f46a6 (patch) | |
tree | 95da9eb36b5a905516bf98e3c88a7af3b19ced1d | |
parent | 3930939d96a50ab41deddbc9fd6ef2b5cc29369e (diff) | |
download | NAI-bc53ad567b82ca354f2b8caf30f242717a5f46a6.tar.gz NAI-bc53ad567b82ca354f2b8caf30f242717a5f46a6.zip |
feat: scrollable chatbox
-rw-r--r-- | src/app/init.rs | 4 | ||||
-rw-r--r-- | src/helper/init.rs | 12 | ||||
-rw-r--r-- | src/helper/mod.rs | 1 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/ui/init.rs | 63 | ||||
-rw-r--r-- | src/ui/inputfield.rs | 5 |
7 files changed, 52 insertions, 35 deletions
diff --git a/src/app/init.rs b/src/app/init.rs index ff9f130..eabf204 100644 --- a/src/app/init.rs +++ b/src/app/init.rs @@ -1,3 +1,4 @@ +use crate::helper::init::print_in_file; use color_eyre::Result; use reqwest; use serde_json::Value; @@ -48,7 +49,7 @@ impl App { .post("http://localhost:8080/completion") .json(&serde_json::json!({ "prompt": &content, - "n_predict": 128, + "n_predict": 400, })) .send()?; @@ -56,6 +57,7 @@ impl App { // Désérialiser la réponse JSON let json_response: Value = response.json()?; + //print_in_file(json_response.to_string().clone()); // Accéder à la partie spécifique du JSON if let Some(msg) = json_response["content"].as_str() { self.messages.push(Message { diff --git a/src/helper/init.rs b/src/helper/init.rs new file mode 100644 index 0000000..392e4fb --- /dev/null +++ b/src/helper/init.rs @@ -0,0 +1,12 @@ +use std::fs::File; +use std::io::{self, Write}; + +pub fn print_in_file(content: String) -> io::Result<()> { + // Open the file (create it if it doesn't exist, or truncate it if it does) + let mut file = File::create("debug.txt")?; + + // Write the content to the file + file.write_all(content.as_bytes())?; + + Ok(()) +} diff --git a/src/helper/mod.rs b/src/helper/mod.rs new file mode 100644 index 0000000..43763f1 --- /dev/null +++ b/src/helper/mod.rs @@ -0,0 +1 @@ +pub mod init; @@ -1,2 +1,3 @@ pub mod app; +pub mod helper; pub mod ui; diff --git a/src/main.rs b/src/main.rs index a830969..7548f49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod app; +mod helper; mod ui; use crate::{app::init::App, ui::init::Ui}; use color_eyre::Result; diff --git a/src/ui/init.rs b/src/ui/init.rs index 82481cd..7c73d36 100644 --- a/src/ui/init.rs +++ b/src/ui/init.rs @@ -5,10 +5,8 @@ use ratatui::{ crossterm::event::{self, Event, KeyCode, KeyEventKind}, layout::{Constraint, Layout, Position}, style::{Color, Style, Stylize}, - text::{Line, Span, Text}, - widgets::{ - Block, List, ListItem, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState, Wrap, - }, + text::{Line, Text}, + widgets::{Block, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState, Wrap}, DefaultTerminal, Frame, }; @@ -37,9 +35,24 @@ impl Ui { } } - fn move_messages_up(&mut self) {} + fn move_messages_up(&mut self) { + if self.message_box_data.nb_line > self.message_box_data.max_line + && self.message_box_data.scroll_offset > 0 + { + self.message_box_data.scroll_offset -= 1; + } + } - fn move_messages_down(&mut self) {} + fn move_messages_down(&mut self) { + if self + .message_box_data + .nb_line + .saturating_sub(self.message_box_data.scroll_offset) + > self.message_box_data.max_line + { + self.message_box_data.scroll_offset += 1; + } + } pub fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> { loop { @@ -52,6 +65,8 @@ impl Ui { self.input_field.input_mode = InputMode::Editing; } KeyCode::Char('q') => return Ok(()), + KeyCode::Up => self.move_messages_up(), + KeyCode::Down => self.move_messages_down(), _ => {} }, InputMode::Editing if key.kind == KeyEventKind::Press => match key.code { @@ -63,8 +78,6 @@ impl Ui { KeyCode::Up => self.input_field.move_cursor_up(), KeyCode::Down => self.input_field.move_cursor_down(), KeyCode::Esc => self.input_field.input_mode = InputMode::Normal, - KeyCode::PageUp => self.move_messages_up(), - KeyCode::PageDown => self.move_messages_down(), _ => {} }, InputMode::Editing => {} @@ -73,21 +86,6 @@ impl Ui { } } - fn wrap_text(&self, text: String, max_width: usize) -> (Vec<Line<'_>>, usize) { - let mut count = 0; // number of line used - ( - text.chars() - .collect::<Vec<_>>() - .chunks(max_width) - .map(|chunk| { - count += 1; - Line::from(Span::raw(chunk.iter().collect::<String>())) - }) - .collect(), - count, - ) - } - fn draw(&mut self, frame: &mut Frame) { let vertical = Layout::vertical([ Constraint::Length(1), @@ -159,29 +157,32 @@ impl Ui { frame.render_stateful_widget(scrollbar_input, input_area, &mut scrollbar_state_input); let available_width_message = messages_area.width.saturating_sub(2); - let mut messages: Vec<ListItem> = Vec::new(); + let mut messages = Vec::new(); let mut max_char_per_line = self.message_box_data.max_char_per_line; - let mut msg_nb_line = 0; + let mut msg_nb_line: usize = 0; for m in &self.app.messages { let msg = format!("{}", m); let size = msg.chars().take(available_width_message as usize).count(); + let msg_lines = (msg.chars().count() as f64 / size as f64).ceil(); + msg_nb_line = msg_nb_line.saturating_add(msg_lines as usize); - let (content, count) = self.wrap_text(msg.clone(), max_char_per_line); - msg_nb_line = count; - messages.push(ListItem::new(content.clone())); + messages.push(Line::from(msg.clone())); if size > max_char_per_line { max_char_per_line = size; } } - - let messages = List::new(messages).block(Block::bordered().title("Chat with Néo AI")); + let messages = Paragraph::new(Text::from(messages)) + .block(Block::bordered().title("Chat with Néo AI")) + .wrap(Wrap { trim: true }) + .scroll((self.message_box_data.scroll_offset as u16, 0)); frame.render_widget(messages, messages_area); self.message_box_data.max_char_per_line = max_char_per_line; self.message_box_data.nb_line = msg_nb_line; + self.message_box_data.max_line = messages_area.height.saturating_sub(2) as usize; - let mut scrollbar_state_message = ScrollbarState::new(self.app.messages.len()) + let mut scrollbar_state_message = ScrollbarState::new(self.message_box_data.nb_line) .position(self.message_box_data.scroll_offset); let scrollbar_message = Scrollbar::new(ScrollbarOrientation::VerticalRight); frame.render_stateful_widget( diff --git a/src/ui/inputfield.rs b/src/ui/inputfield.rs index 8717cfe..7c3f4d2 100644 --- a/src/ui/inputfield.rs +++ b/src/ui/inputfield.rs @@ -150,11 +150,10 @@ impl InputField { if y > self.input_data.max_line { self.input_data.scroll_offset = y - self.input_data.max_line; y -= self.input_data.scroll_offset; - } - - if y < self.input_data.scroll_offset { + } else if y < self.input_data.scroll_offset { self.input_data.scroll_offset = y; } + return y.max(1); } else { return 1; |