diff --git a/crates/git_graph/src/git_graph.rs b/crates/git_graph/src/git_graph.rs index f74d25fc6205ca3a39b098a37532d2a9b8ca9746..78e2bac486385b2a0228c8f98d95415f6ec66946 100644 --- a/crates/git_graph/src/git_graph.rs +++ b/crates/git_graph/src/git_graph.rs @@ -20,7 +20,10 @@ use smallvec::{SmallVec, smallvec}; use std::{ops::Range, rc::Rc, sync::Arc, sync::OnceLock}; use theme::{AccentColors, ThemeSettings}; use time::{OffsetDateTime, UtcOffset, format_description::BorrowedFormatItem}; -use ui::{ContextMenu, ScrollableHandle, Table, TableInteractionState, Tooltip, prelude::*}; +use ui::{ + CommonAnimationExt as _, ContextMenu, ScrollableHandle, Table, TableInteractionState, Tooltip, + prelude::*, +}; use workspace::{ Workspace, item::{Item, ItemEvent, SerializableItem}, @@ -623,7 +626,7 @@ impl GitGraph { // This won't overlap with loading commits from the repository because // we either have all commits or commits loaded in chunks and loading commits // from the repository event is always adding the last chunk of commits. - let commits = + let (commits, _) = repository.graph_data(log_source.clone(), log_order, 0..usize::MAX, cx); graph.add_commits(commits); }); @@ -674,7 +677,7 @@ impl GitGraph { let old_count = self.graph_data.commits.len(); repository.update(cx, |repository, cx| { - let commits = repository.graph_data( + let (commits, _) = repository.graph_data( self.log_source.clone(), self.log_order, old_count..*commit_count, @@ -882,6 +885,15 @@ impl GitGraph { }) } + fn render_loading_spinner(&self, cx: &App) -> AnyElement { + let rems = TextSize::Large.rems(cx); + Icon::new(IconName::LoadCircle) + .size(IconSize::Custom(rems)) + .color(Color::Accent) + .with_rotate_animation(3) + .into_any_element() + } + fn render_commit_detail_panel( &self, window: &mut Window, @@ -1443,35 +1455,45 @@ impl Render for GitGraph { let author_width_fraction = 0.10; let commit_width_fraction = 0.06; - let commit_count = match self.graph_data.max_commit_count { - AllCommitCount::Loaded(count) => count, + let (commit_count, is_loading) = match self.graph_data.max_commit_count { + AllCommitCount::Loaded(count) => (count, true), AllCommitCount::NotLoaded => { - self.project.update(cx, |project, cx| { + let is_loading = self.project.update(cx, |project, cx| { if let Some(repository) = project.active_repository(cx) { repository.update(cx, |repository, cx| { // Start loading the graph data if we haven't started already - repository.graph_data( - self.log_source.clone(), - self.log_order, - 0..0, - cx, - ); + repository + .graph_data(self.log_source.clone(), self.log_order, 0..0, cx) + .1 }) + } else { + false } - }); + }) && self.graph_data.commits.is_empty(); - self.graph_data.commits.len() + (self.graph_data.commits.len(), is_loading) } }; let content = if self.graph_data.commits.is_empty() { - let message = "No commits found"; + let message = if is_loading { + "Loading" + } else { + "No commits found" + }; + let label = Label::new(message) + .color(Color::Muted) + .size(LabelSize::Large); div() .size_full() - .flex() + .h_flex() + .gap_1() .items_center() .justify_center() - .child(Label::new(message).color(Color::Muted)) + .child(label) + .when(is_loading, |this| { + this.child(self.render_loading_spinner(cx)) + }) } else { div() .size_full() @@ -2349,6 +2371,7 @@ mod tests { 0..usize::MAX, cx, ) + .0 .to_vec() }); diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index 2f77ac31a0f55ae2e6e219d7275bab54cd99e2a7..1f7056711637421ab142a7ce43ba5839380b4fd6 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -4240,8 +4240,8 @@ impl Repository { log_order: LogOrder, range: Range, cx: &mut Context, - ) -> &[Arc] { - let initial_commit_data = &self + ) -> (&[Arc], bool) { + let (loading_task, initial_commit_data) = self .initial_graph_data .entry((log_order, log_source.clone())) .or_insert_with(|| { @@ -4267,12 +4267,14 @@ impl Repository { }), vec![], ) - }) - .1; + }); let max_start = initial_commit_data.len().saturating_sub(1); let max_end = initial_commit_data.len(); - &initial_commit_data[range.start.min(max_start)..range.end.min(max_end)] + ( + &initial_commit_data[range.start.min(max_start)..range.end.min(max_end)], + !loading_task.is_ready(), + ) } async fn local_git_graph_data(