mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 08:58:21 +00:00
request commit based diff async
This commit is contained in:
parent
6a6fae9581
commit
9e1d8af264
4 changed files with 65 additions and 16 deletions
|
|
@ -9,10 +9,27 @@ use std::{
|
|||
Arc, Mutex,
|
||||
},
|
||||
};
|
||||
use sync::CommitId;
|
||||
|
||||
///
|
||||
#[derive(Default, Hash, Clone, PartialEq)]
|
||||
pub struct DiffParams(pub String, pub bool);
|
||||
#[derive(Hash, Clone, PartialEq)]
|
||||
pub enum DiffType {
|
||||
/// diff in a given commit
|
||||
Commit(CommitId),
|
||||
/// diff against staged file
|
||||
Stage,
|
||||
/// diff against file in workdir
|
||||
WorkDir,
|
||||
}
|
||||
|
||||
///
|
||||
#[derive(Hash, Clone, PartialEq)]
|
||||
pub struct DiffParams {
|
||||
/// path to the file to diff
|
||||
pub path: String,
|
||||
/// what kind of diff
|
||||
pub diff_type: DiffType,
|
||||
}
|
||||
|
||||
struct Request<R, A>(R, Option<A>);
|
||||
|
||||
|
|
@ -121,8 +138,19 @@ impl AsyncDiff {
|
|||
arc_current: Arc<Mutex<Request<u64, FileDiff>>>,
|
||||
hash: u64,
|
||||
) -> Result<bool> {
|
||||
let res =
|
||||
sync::diff::get_diff(CWD, params.0.clone(), params.1)?;
|
||||
let res = match params.diff_type {
|
||||
DiffType::Stage => {
|
||||
sync::diff::get_diff(CWD, params.path.clone(), true)?
|
||||
}
|
||||
DiffType::WorkDir => {
|
||||
sync::diff::get_diff(CWD, params.path.clone(), false)?
|
||||
}
|
||||
DiffType::Commit(id) => sync::diff::get_diff_commit(
|
||||
CWD,
|
||||
id,
|
||||
params.path.clone(),
|
||||
)?,
|
||||
};
|
||||
|
||||
let mut notify = false;
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub mod sync;
|
|||
|
||||
pub use crate::{
|
||||
commit_files::AsyncCommitFiles,
|
||||
diff::{AsyncDiff, DiffParams},
|
||||
diff::{AsyncDiff, DiffParams, DiffType},
|
||||
revlog::{AsyncLog, FetchStatus},
|
||||
status::{AsyncStatus, StatusParams},
|
||||
sync::{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ use crate::{
|
|||
accessors, keys, queue::Queue, strings, ui::style::Theme,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use asyncgit::{sync, AsyncNotification, CWD};
|
||||
use asyncgit::{
|
||||
sync, AsyncDiff, AsyncNotification, DiffParams, DiffType,
|
||||
};
|
||||
use crossbeam_channel::Sender;
|
||||
use crossterm::event::Event;
|
||||
use strings::commands;
|
||||
|
|
@ -23,6 +25,7 @@ pub struct InspectCommitComponent {
|
|||
commit_id: Option<CommitId>,
|
||||
diff: DiffComponent,
|
||||
details: CommitDetailsComponent,
|
||||
git_diff: AsyncDiff,
|
||||
visible: bool,
|
||||
}
|
||||
|
||||
|
|
@ -159,6 +162,7 @@ impl InspectCommitComponent {
|
|||
),
|
||||
diff: DiffComponent::new(None, theme),
|
||||
commit_id: None,
|
||||
git_diff: AsyncDiff::new(sender.clone()),
|
||||
visible: false,
|
||||
}
|
||||
}
|
||||
|
|
@ -173,7 +177,7 @@ impl InspectCommitComponent {
|
|||
|
||||
///
|
||||
pub fn any_work_pending(&self) -> bool {
|
||||
self.details.any_work_pending()
|
||||
self.git_diff.is_pending() || self.details.any_work_pending()
|
||||
}
|
||||
|
||||
///
|
||||
|
|
@ -185,7 +189,7 @@ impl InspectCommitComponent {
|
|||
if let AsyncNotification::CommitFiles = ev {
|
||||
self.update()?
|
||||
} else if let AsyncNotification::Diff = ev {
|
||||
self.update()?
|
||||
self.update_diff()?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,13 +202,21 @@ impl InspectCommitComponent {
|
|||
if let Some(id) = self.commit_id {
|
||||
if let Some(f) = self.details.files().selection_file()
|
||||
{
|
||||
self.diff.update(
|
||||
f.path.clone(),
|
||||
false,
|
||||
sync::get_diff_commit(CWD, id, f.path)?,
|
||||
)?;
|
||||
let diff_params = DiffParams {
|
||||
path: f.path.clone(),
|
||||
diff_type: DiffType::Commit(id),
|
||||
};
|
||||
|
||||
return Ok(());
|
||||
if let Some((params, last)) =
|
||||
self.git_diff.last()?
|
||||
{
|
||||
if params == diff_params {
|
||||
self.diff.update(f.path, false, last)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
self.git_diff.request(diff_params)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
use anyhow::Result;
|
||||
use asyncgit::{
|
||||
sync::{self, status::StatusType},
|
||||
AsyncDiff, AsyncNotification, AsyncStatus, DiffParams,
|
||||
AsyncDiff, AsyncNotification, AsyncStatus, DiffParams, DiffType,
|
||||
StatusParams, CWD,
|
||||
};
|
||||
use components::{command_pump, visibility_blocking};
|
||||
|
|
@ -243,7 +243,16 @@ impl Status {
|
|||
///
|
||||
pub fn update_diff(&mut self) -> Result<()> {
|
||||
if let Some((path, is_stage)) = self.selected_path() {
|
||||
let diff_params = DiffParams(path.clone(), is_stage);
|
||||
let diff_type = if is_stage {
|
||||
DiffType::Stage
|
||||
} else {
|
||||
DiffType::WorkDir
|
||||
};
|
||||
|
||||
let diff_params = DiffParams {
|
||||
path: path.clone(),
|
||||
diff_type,
|
||||
};
|
||||
|
||||
if self.diff.current() == (path.clone(), is_stage) {
|
||||
// we are already showing a diff of the right file
|
||||
|
|
|
|||
Loading…
Reference in a new issue