diff options
Diffstat (limited to 'src/show_commit/show_commit.rs')
-rw-r--r-- | src/show_commit/show_commit.rs | 264 |
1 files changed, 51 insertions, 213 deletions
diff --git a/src/show_commit/show_commit.rs b/src/show_commit/show_commit.rs index 561e967..810053e 100644 --- a/src/show_commit/show_commit.rs +++ b/src/show_commit/show_commit.rs @@ -1,5 +1,4 @@ use crate::commit::Commit; -use crate::constants::MINIMUM_FULL_WINDOW_WIDTH; use crate::display::DisplayColor; use crate::git_interactive::GitInteractive; use crate::input::{Input, InputHandler}; @@ -12,32 +11,46 @@ use crate::process::{ State, }; use crate::scroll::ScrollPosition; -use crate::show_commit::util::get_stat_item_segments; -use crate::view::{LineSegment, View, ViewLine}; -use std::cmp; -use unicode_segmentation::UnicodeSegmentation; +use crate::show_commit::data::Data; +use crate::view::View; pub struct ShowCommit { + commit: Option<Result<Commit, String>>, + data: Data, scroll_position: ScrollPosition, } impl ProcessModule for ShowCommit { - fn activate(&mut self, _state: State, _git_interactive: &GitInteractive) { + fn activate(&mut self, _state: State, git_interactive: &GitInteractive) { self.scroll_position.reset(); + self.commit = Some(git_interactive.load_commit_stats()); } - fn process(&mut self, git_interactive: &mut GitInteractive, _view: &View) -> ProcessResult { + fn deactivate(&mut self) { + self.data.reset(); + } + + fn process(&mut self, _git_interactive: &mut GitInteractive, view: &View) -> ProcessResult { + let (view_width, view_height) = view.get_view_size(); let mut result = ProcessResultBuilder::new(); - if let Err(e) = git_interactive.load_commit_stats() { - result = result.error(e.as_str(), State::List(false)); + + if let Some(commit) = &self.commit { + match commit { + Ok(c) => self.data.update(&c, view_width, view_height), + Err(e) => { + result = result.error(e.as_str(), State::List(false)); + self.data.reset() + }, + } } + result.build() } fn handle_input( &mut self, input_handler: &InputHandler, - git_interactive: &mut GitInteractive, + _git_interactive: &mut GitInteractive, view: &View, ) -> HandleInputResult { @@ -47,40 +60,24 @@ impl ProcessModule for ShowCommit { let mut result = HandleInputResultBuilder::new(input); match input { Input::MoveCursorLeft => { - self.scroll_position.scroll_left( - view_width, - self.get_max_line_length( - git_interactive.get_commit_stats(), - view_height >= MINIMUM_FULL_WINDOW_WIDTH, - ), - ) + self.scroll_position + .scroll_left(view_width, self.get_max_line_length(view_height)) }, Input::MoveCursorRight => { - self.scroll_position.scroll_right( - view_width, - self.get_max_line_length( - git_interactive.get_commit_stats(), - view_height >= MINIMUM_FULL_WINDOW_WIDTH, - ), - ) + self.scroll_position + .scroll_right(view_width, self.get_max_line_length(view_height)) }, Input::MoveCursorDown => { - self.scroll_position.scroll_down( - view_height, - self.get_commit_stats_length(git_interactive.get_commit_stats()), - ) + self.scroll_position + .scroll_down(view_height, self.get_commit_stats_length()) }, Input::MoveCursorUp => { - self.scroll_position.scroll_up( - view_height, - self.get_commit_stats_length(git_interactive.get_commit_stats()), - ) + self.scroll_position + .scroll_up(view_height, self.get_commit_stats_length()) }, Input::Resize => { - self.scroll_position.scroll_up( - view_height as usize, - self.get_commit_stats_length(git_interactive.get_commit_stats()), - ); + self.scroll_position + .scroll_up(view_height as usize, self.get_commit_stats_length()); }, _ => { result = result.state(State::List(false)); @@ -89,105 +86,22 @@ impl ProcessModule for ShowCommit { result.build() } - fn render(&self, view: &View, git_interactive: &GitInteractive) { - let commit_data = git_interactive.get_commit_stats(); - let (window_width, window_height) = view.get_view_size(); + fn render(&self, view: &View, _git_interactive: &GitInteractive) { + let (_, window_height) = view.get_view_size(); let view_height = window_height - 2; - let is_full_width = window_width >= MINIMUM_FULL_WINDOW_WIDTH; - view.draw_title(false); - let commit = match commit_data { + match &self.commit { None => { view.draw_error("Not commit data to show"); return; }, - Some(c) => c, - }; - - let full_hash = commit.get_hash(); - let author = commit.get_author(); - let committer = commit.get_committer(); - let date = commit.get_date(); - let body = commit.get_body(); - let file_stats = commit.get_file_stats(); - - let mut lines: Vec<ViewLine> = vec![]; - - lines.push(ViewLine::new(vec![LineSegment::new_with_color( - if is_full_width { - format!("Commit: {}", full_hash) - } - else { - let max_index = cmp::min(full_hash.len(), 8); - format!("{:8} ", full_hash[0..max_index].to_string()) - } - .as_str(), - DisplayColor::IndicatorColor, - )])); - - lines.push(ViewLine::new(vec![LineSegment::new( - if is_full_width { - format!("Date: {}", date.format("%c %z")) - } - else { - format!("{}", date.format("%c %z")) - } - .as_str(), - )])); - - if let Some(a) = author.to_string() { - lines.push(ViewLine::new(vec![LineSegment::new( - if is_full_width { - format!("Author: {}", a) - } - else { - format!("A: {}", a) - } - .as_str(), - )])); - } - - if let Some(c) = committer.to_string() { - lines.push(ViewLine::new(vec![LineSegment::new( - if is_full_width { - format!("Committer: {}", c) - } - else { - format!("C: {}", c) - } - .as_str(), - )])) + Some(c) => c.as_ref().unwrap(), // safe unwrap }; - match body { - Some(b) => { - for line in b.lines() { - lines.push(ViewLine::new(vec![LineSegment::new(line)])); - } - }, - None => {}, - }; - - lines.push(ViewLine::new(vec![LineSegment::new("")])); - - match file_stats { - Some(stats) => { - for stat in stats { - lines.push(ViewLine::new(get_stat_item_segments( - *stat.get_status(), - stat.get_to_name().as_str(), - stat.get_from_name().as_str(), - is_full_width, - ))) - } - }, - None => {}, - } - view.draw_view_lines( - lines, + self.data.get_lines(), self.scroll_position.get_top_position(), self.scroll_position.get_left_position(), view_height, @@ -201,13 +115,15 @@ impl ProcessModule for ShowCommit { impl ShowCommit { pub fn new() -> Self { Self { + commit: None, + data: Data::new(), scroll_position: ScrollPosition::new(3, 6, 3), } } - fn get_commit_stats_length(&self, commit: &Option<Commit>) -> usize { - match commit { - Some(c) => { + fn get_commit_stats_length(&self) -> usize { + if let Some(commit) = &self.commit { + if let Ok(c) = commit { let mut len = c.get_file_stats_length(); match c.get_body() { @@ -216,94 +132,16 @@ impl ShowCommit { }, None => {}, } - len + 3 // author + date + commit hash - }, - None => 0, + return len + 3; // author + date + commit hash + } } + 0 } - fn get_max_line_length(&self, commit: &Option<Commit>, is_full_width: bool) -> usize { - match commit { - Some(c) => { - let full_hash = c.get_hash(); - let author = c.get_author(); - let committer = c.get_committer(); - let body = c.get_body(); - let file_stats = c.get_file_stats(); - - let mut max_line_length = if is_full_width { - full_hash.len() + 8 // 8 = "Commit: " - } - else { - cmp::min(full_hash.len(), 8) - }; - - max_line_length = cmp::max( - if is_full_width { - 35 // "Date: Sun Jul 8 00:34:60 2001+09:30" - } - else { - 29 // "Sun Jul 8 00:34:60 2001+09:30" - }, - max_line_length, - ); - - if let Some(a) = author.to_string() { - max_line_length = cmp::max( - if is_full_width { - UnicodeSegmentation::graphemes(a.as_str(), true).count() + 8 // 8 = "Author: " - } - else { - UnicodeSegmentation::graphemes(a.as_str(), true).count() + 3 // 3 = "A: " - }, - max_line_length, - ); - } - - if let Some(c) = committer.to_string() { - max_line_length = cmp::max( - if is_full_width { - UnicodeSegmentation::graphemes(c.as_str(), true).count() + 11 // 11 = "Committer: " - } - else { - UnicodeSegmentation::graphemes(c.as_str(), true).count() + 3 // 3 = "C: " - }, - max_line_length, - ); - }; - - if let Some(b) = body { - for line in b.lines() { - let line_length = UnicodeSegmentation::graphemes(line, true).count(); - if line_length > max_line_length { - max_line_length = line_length; - } - } - } - - if let Some(stats) = file_stats { - let additional_line_length = if is_full_width { - 13 // stat name + arrow - } - else { - 3 // stat name + arrow - }; - - for stat in stats { - let stat_line_length = - UnicodeSegmentation::graphemes(stat.get_to_name().as_str(), true).count() - + UnicodeSegmentation::graphemes(stat.get_from_name().as_str(), true).count() - + additional_line_length; - - if stat_line_length > max_line_length { - max_line_length = stat_line_length; - } - } - } - - max_line_length - }, - None => 0, - } + fn get_max_line_length(&self, view_height: usize) -> usize { + self.data.get_max_line_length( + self.scroll_position.get_top_position(), + self.scroll_position.get_top_position() + view_height, + ) } } |