Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ pub fn get_save_backup_file_path() -> PathBuf {

pub const ORANGE: ratatui::style::Color = ratatui::style::Color::Rgb(255, 165, 0);
pub const DAEMONIZE_ARG: &str = "__thoth_copy_daemonize";
pub const MIN_TEXTAREA_HEIGHT: usize = 3;
6 changes: 4 additions & 2 deletions src/markdown_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ fn into_span((style, text): (SyntectStyle, &str)) -> Span<'static> {

#[cfg(test)]
mod tests {
use crate::MIN_TEXTAREA_HEIGHT;

use super::*;

#[test]
Expand All @@ -267,7 +269,7 @@ mod tests {
.render_markdown(markdown.to_string(), "".to_string(), 40)
.unwrap();

assert!(rendered.lines.len() >= 3);
assert!(rendered.lines.len() >= MIN_TEXTAREA_HEIGHT);
assert!(rendered.lines[0]
.spans
.iter()
Expand Down Expand Up @@ -337,7 +339,7 @@ mod tests {
.render_markdown(markdown, "".to_string(), 40)
.unwrap();

assert!(rendered.lines.len() > 3);
assert!(rendered.lines.len() > MIN_TEXTAREA_HEIGHT);
assert!(rendered.lines[0]
.spans
.iter()
Expand Down
49 changes: 45 additions & 4 deletions src/scrollable_textarea.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
rc::Rc,
};

use crate::EditorClipboard;
use crate::{EditorClipboard, MIN_TEXTAREA_HEIGHT};
use crate::{MarkdownRenderer, ORANGE};
use anyhow;
use anyhow::Result;
Expand Down Expand Up @@ -95,6 +95,7 @@ impl ScrollableTextArea {
self.full_screen_mode = !self.full_screen_mode;
if self.full_screen_mode {
self.edit_mode = false;
self.scroll = 0
}
}

Expand Down Expand Up @@ -184,7 +185,8 @@ impl ScrollableTextArea {
} else {
let mut height_sum = 0;
for i in self.scroll..=self.focused_index {
let textarea_height = self.textareas[i].lines().len().max(3) as u16 + 2;
let textarea_height =
self.textareas[i].lines().len().max(MIN_TEXTAREA_HEIGHT) as u16 + 2;
height_sum += textarea_height;

if height_sum > self.viewport_height {
Expand All @@ -204,7 +206,7 @@ impl ScrollableTextArea {
pub fn calculate_height_to_focused(&self) -> u16 {
self.textareas[self.scroll..=self.focused_index]
.iter()
.map(|ta| ta.lines().len().max(3) as u16 + 2)
.map(|ta| ta.lines().len().max(MIN_TEXTAREA_HEIGHT) as u16 + 2)
.sum()
}

Expand Down Expand Up @@ -284,7 +286,9 @@ impl ScrollableTextArea {
let height = if is_editing {
remaining_height
} else {
content_height.min(remaining_height).max(3)
content_height
.min(remaining_height)
.max(MIN_TEXTAREA_HEIGHT as u16)
};

visible_textareas.push((i, textarea, height));
Expand Down Expand Up @@ -349,6 +353,43 @@ impl ScrollableTextArea {
Ok(())
}

pub fn handle_scroll(&mut self, direction: isize) {
if !self.full_screen_mode {
return;
}

let current_height = self.textareas[self.focused_index].lines().len();
let is_scrolling_down = direction > 0;
let is_at_last_textarea = self.focused_index == self.textareas.len() - 1;
let is_at_first_textarea = self.focused_index == 0;

// Scrolling down
if is_scrolling_down {
let can_scroll_further = self.scroll < current_height.saturating_sub(1);
let can_move_to_next = !is_at_last_textarea;

if can_scroll_further {
self.scroll += 1;
} else if can_move_to_next {
self.focused_index += 1;
self.scroll = 0;
}
return;
}

// Scrolling up
let can_scroll_up = self.scroll > 0;
let can_move_to_previous = !is_at_first_textarea;

if can_scroll_up {
self.scroll -= 1;
} else if can_move_to_previous {
self.focused_index -= 1;
let prev_height = self.textareas[self.focused_index].lines().len();
self.scroll = prev_height.saturating_sub(1);
}
}

fn render_full_screen(&mut self, f: &mut Frame, area: Rect) -> Result<()> {
let textarea = &mut self.textareas[self.focused_index];
textarea.set_selection_style(Style::default().bg(Color::Red));
Expand Down
20 changes: 18 additions & 2 deletions src/ui_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ fn handle_full_screen_input(state: &mut UIState, key: event::KeyEvent) -> Result
} else {
state.scrollable_textarea.toggle_full_screen();
}

state
.scrollable_textarea
.jump_to_textarea(state.scrollable_textarea.focused_index);
}
KeyCode::Enter => {
if !state.scrollable_textarea.edit_mode {
Expand All @@ -141,8 +145,20 @@ fn handle_full_screen_input(state: &mut UIState, key: event::KeyEvent) -> Result
.insert_newline();
}
}
KeyCode::Up => handle_up_key(state, key),
KeyCode::Down => handle_down_key(state, key),
KeyCode::Up => {
if state.scrollable_textarea.edit_mode {
handle_up_key(state, key);
} else {
state.scrollable_textarea.handle_scroll(-1);
}
}
KeyCode::Down => {
if state.scrollable_textarea.edit_mode {
handle_down_key(state, key);
} else {
state.scrollable_textarea.handle_scroll(1);
}
}
KeyCode::Char('y') if key.modifiers.contains(KeyModifiers::CONTROL) => {
match state.scrollable_textarea.copy_focused_textarea_contents() {
Ok(_) => {
Expand Down
Loading