diff --git a/CHANGELOG.md b/CHANGELOG.md index b14a97d7..f0b8291e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- pending load of a diff is visualized better ([#160](https://github.com/extrawurst/gitui/issues/160)) +- pending load of a diff/status is visualized ([#160](https://github.com/extrawurst/gitui/issues/160)) - entry on [git-scm.com](https://git-scm.com/downloads/guis) in the list of GUI tools [[@Vidar314](https://github.com/Vidar314)] (see [PR](https://github.com/git/git-scm.com/pull/1485)) - commits can be tagged in revlog [[@cruessler](https://github.com/cruessler)] ([#103](https://github.com/extrawurst/gitui/issues/103)) diff --git a/src/components/filetree.rs b/src/components/filetree.rs index 30a37e8a..02478ae4 100644 --- a/src/components/filetree.rs +++ b/src/components/filetree.rs @@ -9,7 +9,7 @@ use crate::{ components::{CommandInfo, Component}, keys, queue::{InternalEvent, NeedsUpdate, Queue}, - strings::{commands, order}, + strings::{self, commands, order}, ui, ui::style::SharedTheme, }; @@ -23,6 +23,7 @@ use tui::{backend::Backend, layout::Rect, widgets::Text, Frame}; pub struct FileTreeComponent { title: String, tree: StatusTree, + pending: bool, current_hash: u64, focused: bool, show_selection: bool, @@ -48,11 +49,13 @@ impl FileTreeComponent { queue, theme, scroll_top: Cell::new(0), + pending: true, } } /// pub fn update(&mut self, list: &[StatusItem]) -> Result<()> { + self.pending = false; let new_hash = hash(list); if self.current_hash != new_hash { self.tree.update(list)?; @@ -217,25 +220,58 @@ impl DrawableComponent for FileTreeComponent { f: &mut Frame, r: Rect, ) -> Result<()> { - let selection_offset = - self.tree.tree.items().iter().enumerate().fold( - 0, - |acc, (idx, e)| { - let visible = e.info.visible; - let index_above_select = - idx < self.tree.selection.unwrap_or(0); + if self.pending { + let items = vec![Text::Styled( + Cow::from(strings::LOADING_TEXT), + self.theme.text(false, false), + )]; - if !visible && index_above_select { - acc + 1 - } else { - acc - } - }, + ui::draw_list( + f, + r, + self.title.as_str(), + items.into_iter(), + None, + self.focused, + &self.theme, ); + } else { + let selection_offset = + self.tree.tree.items().iter().enumerate().fold( + 0, + |acc, (idx, e)| { + let visible = e.info.visible; + let index_above_select = + idx < self.tree.selection.unwrap_or(0); - let items = - self.tree.tree.items().iter().enumerate().filter_map( - |(idx, e)| { + if !visible && index_above_select { + acc + 1 + } else { + acc + } + }, + ); + + let select = self + .tree + .selection + .map(|idx| idx.saturating_sub(selection_offset)) + .unwrap_or_default(); + let tree_height = r.height.saturating_sub(2) as usize; + + self.scroll_top.set(ui::calc_scroll_top( + self.scroll_top.get(), + tree_height, + select, + )); + + let items = self + .tree + .tree + .items() + .iter() + .enumerate() + .filter_map(|(idx, e)| { Self::item_to_text( e, r.width, @@ -246,31 +282,19 @@ impl DrawableComponent for FileTreeComponent { .map_or(false, |e| e == idx), &self.theme, ) - }, + }) + .skip(self.scroll_top.get()); + + ui::draw_list( + f, + r, + self.title.as_str(), + items, + Some(select), + self.focused, + &self.theme, ); - - let select = self - .tree - .selection - .map(|idx| idx.saturating_sub(selection_offset)) - .unwrap_or_default(); - let tree_height = r.height.saturating_sub(2) as usize; - - self.scroll_top.set(ui::calc_scroll_top( - self.scroll_top.get(), - tree_height, - select, - )); - - ui::draw_list( - f, - r, - self.title.as_str(), - items.skip(self.scroll_top.get()), - Some(select), - self.focused, - &self.theme, - ); + } Ok(()) }