aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxbian <oxbian@mailbox.org>2025-02-21 16:17:00 -0500
committerOxbian <oxbian@mailbox.org>2025-02-21 16:17:00 -0500
commitbc53ad567b82ca354f2b8caf30f242717a5f46a6 (patch)
tree95da9eb36b5a905516bf98e3c88a7af3b19ced1d
parent3930939d96a50ab41deddbc9fd6ef2b5cc29369e (diff)
downloadNAI-bc53ad567b82ca354f2b8caf30f242717a5f46a6.tar.gz
NAI-bc53ad567b82ca354f2b8caf30f242717a5f46a6.zip
feat: scrollable chatbox
-rw-r--r--src/app/init.rs4
-rw-r--r--src/helper/init.rs12
-rw-r--r--src/helper/mod.rs1
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs1
-rw-r--r--src/ui/init.rs63
-rw-r--r--src/ui/inputfield.rs5
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;
diff --git a/src/lib.rs b/src/lib.rs
index 3e2facd..52c86c2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;
ArKa projects. All rights to me, and your next child right arm.