This commit is contained in:
2026-08-11 13:30:09 +07:00
parent e77cfe29d9
commit 6f381c68c3
8 changed files with 261 additions and 9 deletions
@@ -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 {