Scrolling help
This commit is contained in:
parent
eb7790ff8f
commit
857362b558
2 changed files with 118 additions and 34 deletions
60
src/app.rs
60
src/app.rs
|
|
@ -60,6 +60,7 @@ pub struct App {
|
|||
pub log_view_content: Vec<String>,
|
||||
pub log_view_scroll: usize,
|
||||
pub log_view_selected: usize,
|
||||
pub help_scroll: usize,
|
||||
pub clipboard: Option<arboard::Clipboard>,
|
||||
pub status_message: Option<(String, std::time::Instant)>,
|
||||
}
|
||||
|
|
@ -97,6 +98,7 @@ impl App {
|
|||
log_view_content: Vec::new(),
|
||||
log_view_scroll: 0,
|
||||
log_view_selected: 0,
|
||||
help_scroll: 0,
|
||||
clipboard: arboard::Clipboard::new().ok(),
|
||||
status_message: None,
|
||||
})
|
||||
|
|
@ -141,7 +143,10 @@ impl App {
|
|||
(KeyCode::Char('p'), KeyModifiers::CONTROL) => self.change_pane(-1),
|
||||
(KeyCode::Enter, _) => self.toggle_current_item()?,
|
||||
(KeyCode::Char('e'), KeyModifiers::CONTROL) => self.edit_config()?,
|
||||
(KeyCode::Char('?'), _) => self.current_screen = Screen::Help,
|
||||
(KeyCode::Char('?'), _) => {
|
||||
self.help_scroll = 0;
|
||||
self.current_screen = Screen::Help;
|
||||
}
|
||||
(KeyCode::Char('c'), _) => self.edit_app_config()?,
|
||||
(KeyCode::Char('n'), _) => self.start_new_entry(),
|
||||
(KeyCode::Char('p'), _) => self.start_reassign_project(),
|
||||
|
|
@ -245,8 +250,26 @@ impl App {
|
|||
fn handle_help_event(&mut self, event: Event) -> anyhow::Result<bool> {
|
||||
match event {
|
||||
Event::Key(KeyEvent { code, .. }) => match code {
|
||||
KeyCode::Char('c') => self.current_screen = Screen::ConfigHelp,
|
||||
KeyCode::Esc | KeyCode::Char('q') => self.current_screen = Screen::Main,
|
||||
KeyCode::Char('c') => {
|
||||
self.help_scroll = 0;
|
||||
self.current_screen = Screen::ConfigHelp;
|
||||
}
|
||||
KeyCode::Char('j') | KeyCode::Down => {
|
||||
self.help_scroll = self.help_scroll.saturating_add(1);
|
||||
}
|
||||
KeyCode::Char('k') | KeyCode::Up => {
|
||||
self.help_scroll = self.help_scroll.saturating_sub(1);
|
||||
}
|
||||
KeyCode::PageDown => {
|
||||
self.help_scroll = self.help_scroll.saturating_add(10);
|
||||
}
|
||||
KeyCode::PageUp => {
|
||||
self.help_scroll = self.help_scroll.saturating_sub(10);
|
||||
}
|
||||
KeyCode::Esc | KeyCode::Char('q') | KeyCode::Char('?') => {
|
||||
self.help_scroll = 0;
|
||||
self.current_screen = Screen::Main;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
|
|
@ -257,7 +280,22 @@ impl App {
|
|||
fn handle_config_help_event(&mut self, event: Event) -> anyhow::Result<bool> {
|
||||
match event {
|
||||
Event::Key(KeyEvent { code, .. }) => match code {
|
||||
KeyCode::Esc | KeyCode::Char('q') => self.current_screen = Screen::Help,
|
||||
KeyCode::Char('j') | KeyCode::Down => {
|
||||
self.help_scroll = self.help_scroll.saturating_add(1);
|
||||
}
|
||||
KeyCode::Char('k') | KeyCode::Up => {
|
||||
self.help_scroll = self.help_scroll.saturating_sub(1);
|
||||
}
|
||||
KeyCode::PageDown => {
|
||||
self.help_scroll = self.help_scroll.saturating_add(10);
|
||||
}
|
||||
KeyCode::PageUp => {
|
||||
self.help_scroll = self.help_scroll.saturating_sub(10);
|
||||
}
|
||||
KeyCode::Esc | KeyCode::Char('q') | KeyCode::Char('?') => {
|
||||
self.help_scroll = 0;
|
||||
self.current_screen = Screen::Help;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
|
|
@ -268,7 +306,20 @@ impl App {
|
|||
fn handle_log_view_help_event(&mut self, event: Event) -> anyhow::Result<bool> {
|
||||
match event {
|
||||
Event::Key(KeyEvent { code, .. }) => match code {
|
||||
KeyCode::Char('j') | KeyCode::Down => {
|
||||
self.help_scroll = self.help_scroll.saturating_add(1);
|
||||
}
|
||||
KeyCode::Char('k') | KeyCode::Up => {
|
||||
self.help_scroll = self.help_scroll.saturating_sub(1);
|
||||
}
|
||||
KeyCode::PageDown => {
|
||||
self.help_scroll = self.help_scroll.saturating_add(10);
|
||||
}
|
||||
KeyCode::PageUp => {
|
||||
self.help_scroll = self.help_scroll.saturating_sub(10);
|
||||
}
|
||||
KeyCode::Esc | KeyCode::Char('q') | KeyCode::Char('?') => {
|
||||
self.help_scroll = 0;
|
||||
self.current_screen = Screen::LogView;
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -332,6 +383,7 @@ impl App {
|
|||
self.needs_clear = true;
|
||||
}
|
||||
KeyCode::Char('?') => {
|
||||
self.help_scroll = 0;
|
||||
self.current_screen = Screen::LogViewHelp;
|
||||
}
|
||||
KeyCode::Char('d') => {
|
||||
|
|
|
|||
92
src/ui.rs
92
src/ui.rs
|
|
@ -214,7 +214,7 @@ fn render_help_command_bar(frame: &mut Frame) {
|
|||
frame.render_widget(command_bar, bar_area);
|
||||
}
|
||||
|
||||
fn render_help(frame: &mut Frame, _app: &App) {
|
||||
fn render_help(frame: &mut Frame, app: &App) {
|
||||
let width = frame.size().width.saturating_sub(4).min(60);
|
||||
let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());
|
||||
|
||||
|
|
@ -231,43 +231,53 @@ fn render_help(frame: &mut Frame, _app: &App) {
|
|||
"3. Ad-Hoc Items: One-off tasks and quick entries",
|
||||
"",
|
||||
"Navigation:",
|
||||
"- Use j/k or ↑/↓ to move selection up/down",
|
||||
"- Use h/l or ←/→ to switch between panes",
|
||||
"- Use Ctrl+n/Ctrl+p to switch between panes",
|
||||
"- Press Enter to start/stop time tracking",
|
||||
"- Press n to create a new task in the current section",
|
||||
"- j/k or ↑/↓: Move selection up/down",
|
||||
"- h/l or ←/→: Switch between panes",
|
||||
"- Ctrl+n/Ctrl+p: Switch between panes",
|
||||
"- Enter: Start/stop time tracking for selected item",
|
||||
"- n: Create a new task in the current section",
|
||||
"",
|
||||
"Main Commands:",
|
||||
"j/k, arrows - Navigate",
|
||||
"h/l, arrows - Switch panes",
|
||||
"Enter - Start/stop timer",
|
||||
"d - Delete task",
|
||||
"p - Reassign project",
|
||||
"v - View Watson log (g to group, e to edit, x to delete, c to copy)",
|
||||
"Ctrl+e - Edit tasks config",
|
||||
"c - Edit app config",
|
||||
"d - Delete task from list",
|
||||
"p - Reassign project/tag",
|
||||
"v - View Watson log",
|
||||
"Ctrl+e - Edit tasks config file",
|
||||
"c - Edit app config file",
|
||||
"n - New task",
|
||||
"q - Quit",
|
||||
"? (or ESC) - Exit help",
|
||||
"? - Show/hide this help (ESC also works)",
|
||||
"",
|
||||
"Log View (press 'v'):",
|
||||
"Once in log view, you can:",
|
||||
"- Switch time periods: d (day), w (week), m (month)",
|
||||
"- Toggle grouping: g (by date or by project)",
|
||||
"- Change selection: h/l (entry → project → day → all)",
|
||||
"- Navigate: j/k to move through selections",
|
||||
"- Edit entry: e (entry level only)",
|
||||
"- Delete entry: x (entry level only)",
|
||||
"- Copy to clipboard: c (works at all levels)",
|
||||
"- Press ? for detailed log view help",
|
||||
];
|
||||
|
||||
let text = help_text.join("\n");
|
||||
|
||||
let block = Block::default()
|
||||
.title("Help")
|
||||
.title("Help (j/k to scroll)")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(Color::White));
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.scroll((app.help_scroll as u16, 0))
|
||||
.wrap(ratatui::widgets::Wrap { trim: true });
|
||||
|
||||
frame.render_widget(paragraph, area);
|
||||
render_help_command_bar(frame);
|
||||
}
|
||||
|
||||
fn render_config_help(frame: &mut Frame, _app: &App) {
|
||||
fn render_config_help(frame: &mut Frame, app: &App) {
|
||||
let width = frame.size().width.saturating_sub(4).min(60);
|
||||
let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());
|
||||
|
||||
|
|
@ -276,35 +286,49 @@ fn render_config_help(frame: &mut Frame, _app: &App) {
|
|||
let help_text = vec![
|
||||
"WAT Configuration",
|
||||
"",
|
||||
"The configuration file is in YAML format and supports these options:",
|
||||
"Configuration file location:",
|
||||
" ~/.config/wat/config.yaml",
|
||||
"",
|
||||
"Available options:",
|
||||
"",
|
||||
"show_help_hint: true/false",
|
||||
" Controls visibility of the help hint in the bottom bar",
|
||||
" Default: true",
|
||||
" Shows '(?) for help' hint in the bottom-right corner",
|
||||
"",
|
||||
"projects: [list of strings]",
|
||||
" List of available project names",
|
||||
"projects: [list of project names]",
|
||||
" Default: [] (empty)",
|
||||
" List of available project names shown when reassigning",
|
||||
" Example: [\"work\", \"personal\", \"client-a\"]",
|
||||
"",
|
||||
"strict_projects: true/false",
|
||||
" If true, only projects from the projects list are allowed",
|
||||
" Default: false",
|
||||
" When true, only allows projects from the 'projects' list",
|
||||
" When false, any project name can be used",
|
||||
"",
|
||||
"Example configuration:",
|
||||
"---",
|
||||
"show_help_hint: true",
|
||||
"projects:",
|
||||
" - project1",
|
||||
" - project2",
|
||||
"strict_projects: false",
|
||||
"projects:",
|
||||
" - work",
|
||||
" - personal",
|
||||
" - open-source",
|
||||
"",
|
||||
"Note: The config file is created automatically on first run.",
|
||||
"Edit it with 'c' from the main screen or manually with your editor.",
|
||||
];
|
||||
|
||||
let text = help_text.join("\n");
|
||||
|
||||
let block = Block::default()
|
||||
.title("Configuration Help")
|
||||
.title("Configuration Help (j/k to scroll)")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(Color::White));
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.scroll((app.help_scroll as u16, 0))
|
||||
.wrap(ratatui::widgets::Wrap { trim: true });
|
||||
|
||||
frame.render_widget(paragraph, area);
|
||||
|
|
@ -595,7 +619,7 @@ fn render_log_view(frame: &mut Frame, app: &App) {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_log_view_help(frame: &mut Frame, _app: &App) {
|
||||
fn render_log_view_help(frame: &mut Frame, app: &App) {
|
||||
let width = frame.size().width.saturating_sub(4).min(60);
|
||||
let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());
|
||||
|
||||
|
|
@ -622,34 +646,42 @@ fn render_log_view_help(frame: &mut Frame, _app: &App) {
|
|||
" - At Entry level: Move to next/previous entry",
|
||||
" - At Project level: Jump to next/previous project group",
|
||||
" - At Day level: Jump to next/previous day",
|
||||
"- h/l or ←/→: Change selection level (Entry ↔ Project ↔ Day)",
|
||||
" - At All level: No navigation (entire view selected)",
|
||||
"- h/l or ←/→: Change selection level",
|
||||
" - l (right): Zoom in (All → Day → Project → Entry)",
|
||||
" - h (left): Zoom out (Entry → Project → Day → All)",
|
||||
"- PageUp/PageDown: Jump 10 entries (Entry level only)",
|
||||
"",
|
||||
"Selection Levels:",
|
||||
"Selection Levels (use h/l to change):",
|
||||
"- Entry: Select individual entry (can edit/delete/copy)",
|
||||
"- Project: Select whole project group (can copy only)",
|
||||
"- Day: Select entire day (can copy only)",
|
||||
"- All: Select entire view/period (can copy only)",
|
||||
"",
|
||||
"Actions:",
|
||||
"- e: Edit the selected entry (Entry level only)",
|
||||
"- x: Delete the selected entry (Entry level only)",
|
||||
"- c: Copy selection to clipboard (works at all levels)",
|
||||
" Copies based on current selection level",
|
||||
"",
|
||||
"Other:",
|
||||
"- ?: Show this help",
|
||||
"- ?: Show/hide this help",
|
||||
"- q or ESC: Return to main screen",
|
||||
"",
|
||||
"Tip: Use h/l to quickly select larger blocks for copying!",
|
||||
];
|
||||
|
||||
let text = help_text.join("\n");
|
||||
|
||||
let block = Block::default()
|
||||
.title("Log View Help")
|
||||
.title("Log View Help (j/k to scroll)")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(Color::White));
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.scroll((app.help_scroll as u16, 0))
|
||||
.wrap(ratatui::widgets::Wrap { trim: true });
|
||||
|
||||
frame.render_widget(paragraph, area);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue