From 99ffbf8a29e9eec44124de0da3c64eec13f2f33d Mon Sep 17 00:00:00 2001 From: pythops Date: Mon, 22 Jan 2024 22:52:36 +0100 Subject: [PATCH] refactor: move help to separte module --- src/app.rs | 3 ++ src/handler.rs | 8 ++++ src/help.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + src/ui.rs | 36 ++--------------- 5 files changed, 120 insertions(+), 33 deletions(-) create mode 100644 src/help.rs diff --git a/src/app.rs b/src/app.rs index 67f3a59..35e15c0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,3 +1,4 @@ +use crate::help::Help; use crate::prompt::Prompt; use std; use std::collections::HashMap; @@ -58,6 +59,7 @@ pub struct App<'a> { pub spinner: Spinner, pub terminate_response_signal: Arc, pub clipboard: Option, + pub help: Help, pub config: Arc, pub formatter: &'a Formatter<'a>, } @@ -76,6 +78,7 @@ impl<'a> App<'a> { spinner: Spinner::default(), terminate_response_signal: Arc::new(AtomicBool::new(false)), clipboard: Clipboard::new().ok(), + help: Help::new(), config, formatter, } diff --git a/src/handler.rs b/src/handler.rs index 130a7c5..b991221 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -56,6 +56,9 @@ pub fn handle_key_events( FocusedBlock::Preview => { app.history.scroll = app.history.scroll.saturating_add(1); } + FocusedBlock::Help => { + app.help.scroll_down(); + } _ => (), }, @@ -70,6 +73,11 @@ pub fn handle_key_events( FocusedBlock::Chat => { app.chat.scroll = app.chat.scroll.saturating_sub(1); } + + FocusedBlock::Help => { + app.help.scroll_up(); + } + _ => (), }, diff --git a/src/help.rs b/src/help.rs new file mode 100644 index 0000000..7689e78 --- /dev/null +++ b/src/help.rs @@ -0,0 +1,104 @@ +use ratatui::{ + layout::{Alignment, Constraint, Rect}, + style::{Color, Style}, + widgets::{Block, BorderType, Borders, Clear, Padding, Row, Table, TableState}, + Frame, +}; + +pub struct Help { + block_height: usize, + state: TableState, + keys: &'static [(&'static str, &'static str)], +} + +impl Default for Help { + fn default() -> Self { + let mut state = TableState::new().with_offset(0); + state.select(Some(0)); + + Self { + block_height: 0, + state, + keys: &[ + ("Esc", "Switch to Normal mode"), + ("i", "Switch to Insert mode"), + ("v", "Switch to Visual mode"), + ("G", "Go to the end"), + ("gg", "Go to the top"), + ( + "ctrl + n", + "Start new chat and save the previous one to the history", + ), + ( + "ctrl + s", + "Save the chat to file in the current directory", + ), + ("Tab", "Switch the focus"), + ("ctrl + h", "Show history"), + ("ctrl + t", "Stop the stream response"), + ("j or Down", "Scroll down"), + ("k or Up", "Scroll up"), + ("?", "show help"), + ], + } + } +} + +impl Help { + pub fn new() -> Self { + Self::default() + } + + pub fn scroll_down(&mut self) { + let i = match self.state.selected() { + Some(i) => { + if i >= self.keys.len().saturating_sub(self.block_height - 4) { + i + } else { + i + 1 + } + } + None => 1, + }; + *self.state.offset_mut() = i; + self.state.select(Some(i)); + } + pub fn scroll_up(&mut self) { + let i = match self.state.selected() { + Some(i) => { + if i > 1 { + i - 1 + } else { + 0 + } + } + None => 1, + }; + *self.state.offset_mut() = i; + self.state.select(Some(i)); + } + + pub fn render(&mut self, frame: &mut Frame, block: Rect) { + self.block_height = block.height as usize; + let widths = [Constraint::Length(15), Constraint::Min(60)]; + let rows: Vec = self + .keys + .iter() + .map(|key| Row::new(vec![key.0, key.1])) + .collect(); + + let table = Table::new(rows, widths).block( + Block::default() + .padding(Padding::uniform(1)) + .title(" Help ") + .title_alignment(Alignment::Center) + .borders(Borders::ALL) + .style(Style::default()) + .border_type(BorderType::Thick) + .border_style(Style::default()), + ); + + frame.render_widget(Clear, block); + frame.render_stateful_widget(table, block, &mut self.state); + } +} diff --git a/src/lib.rs b/src/lib.rs index d28ac64..ee2284f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,3 +23,5 @@ pub mod spinner; pub mod formatter; pub mod prompt; + +pub mod help; diff --git a/src/ui.rs b/src/ui.rs index c6a2dea..960db4c 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -251,41 +251,11 @@ pub fn render(app: &mut App, frame: &mut Frame) { frame.render_widget(preview, preview_block); } + // Show Help if let FocusedBlock::Help = app.focused_block { - let help = format!( - " -`i` : Switch to Insert mode -`Esc` : Switch to Normal mode -`dd` : Clear the prompt -`G` : Go to the end -`gg` : Go to the top -`n` : Start new chat and save the previous one to the history -`s` : Save the chat to `{}` file in the current directory -`Tab` : Switch the focus -`h` : Show history -`t` : Stop the stream response -`j` or `Down` : Scroll down -`k` or `Up` : Scroll up -`?` : show help -`q` : Quit -", - app.config.archive_file_name - ); - - let block = Paragraph::new(help.as_str()) - .wrap(Wrap { trim: false }) - .block( - Block::default() - .title(" Help ") - .title_alignment(Alignment::Center) - .borders(Borders::ALL) - .style(Style::default()) - .border_type(BorderType::Rounded) - .border_style(Style::default().fg(Color::Yellow)), - ); + app.prompt.update(&FocusedBlock::Help); let area = help_rect(frame_size); - frame.render_widget(Clear, area); - frame.render_widget(block, area); + app.help.render(frame, area); } for (i, n) in app.notifications.iter().enumerate() {