.
This commit is contained in:
@@ -14,6 +14,7 @@ use gpui_component::menu::PopupMenuItem;
|
||||
use gpui_component::tree::TreeState;
|
||||
use gpui_component::{ActiveTheme, IconName, StyledExt, h_flex, v_flex};
|
||||
use signed_core::Announcement;
|
||||
use signed_git::FileCommit;
|
||||
use signed_state::{GitStore, RepoStore};
|
||||
|
||||
mod browser;
|
||||
@@ -43,6 +44,10 @@ pub struct RepoDetailView {
|
||||
files: HashMap<String, FileContent>,
|
||||
/// Reads in flight, to avoid duplicate loads.
|
||||
loading_files: HashSet<String>,
|
||||
/// Latest commit touching a previewed file (or the README), keyed by path.
|
||||
commits: HashMap<String, FileCommit>,
|
||||
/// Commit queries in flight, to avoid duplicate loads.
|
||||
loading_commits: HashSet<String>,
|
||||
/// A clone/fetch is in flight.
|
||||
loading: bool,
|
||||
error: Option<SharedString>,
|
||||
@@ -71,6 +76,8 @@ impl RepoDetailView {
|
||||
selected_file: None,
|
||||
files: HashMap::new(),
|
||||
loading_files: HashSet::new(),
|
||||
commits: HashMap::new(),
|
||||
loading_commits: HashSet::new(),
|
||||
loading: true,
|
||||
error: None,
|
||||
focus_handle: cx.focus_handle(),
|
||||
@@ -113,6 +120,7 @@ impl RepoDetailView {
|
||||
});
|
||||
if let Some((path, bytes)) = readme_path.zip(readme) {
|
||||
this.readme_name = Some(path.to_string_lossy().into());
|
||||
this.load_commit(&path.to_string_lossy(), cx);
|
||||
if let Ok(text) = String::from_utf8(bytes) {
|
||||
this.set_markdown(None, &text, cx);
|
||||
}
|
||||
@@ -165,6 +173,7 @@ impl RepoDetailView {
|
||||
|
||||
self.loading_files.insert(path.to_string());
|
||||
let path = path.to_string();
|
||||
self.load_commit(&path, cx);
|
||||
|
||||
let task = cx.spawn(async move |this, cx| {
|
||||
let path_for_read = path.clone();
|
||||
@@ -222,6 +231,41 @@ impl RepoDetailView {
|
||||
|
||||
self.tasks.push(task);
|
||||
}
|
||||
|
||||
/// Query the latest commit touching `path` on a background task and cache
|
||||
/// it in [`Self::commits`], for the file header in the content column.
|
||||
fn load_commit(&mut self, path: &str, cx: &mut Context<Self>) {
|
||||
if self.commits.contains_key(path) || self.loading_commits.contains(path) {
|
||||
return;
|
||||
}
|
||||
let Some(worktree) = self.worktree.clone() else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.loading_commits.insert(path.to_string());
|
||||
let path = path.to_string();
|
||||
|
||||
let task = cx.spawn(async move |this, cx| {
|
||||
let path_for_query = path.clone();
|
||||
let result = cx
|
||||
.background_spawn(async move {
|
||||
signed_git::worktree_last_commit(&worktree, Path::new(&path_for_query))
|
||||
})
|
||||
.await;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.loading_commits.remove(&path);
|
||||
if let Ok(Some(commit)) = result {
|
||||
this.commits.insert(path, commit);
|
||||
}
|
||||
cx.notify();
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
self.tasks.push(task);
|
||||
}
|
||||
}
|
||||
|
||||
impl Panel for RepoDetailView {
|
||||
|
||||
Reference in New Issue
Block a user