Git UI papercuts (#26316)
Release Notes: - Git Beta: added `git:Add` as an alias for the existing `git::Diff` - Git Beta: Fixed a bug where the 'generate commit message' keybinding wasn't working. - Git Beta: Made the empty project diff state a little more helpful with a button to push, and a button to close the item.
This commit is contained in:
parent
450d727a04
commit
cb543f9546
4 changed files with 460 additions and 373 deletions
|
@ -10,7 +10,8 @@ use editor::{
|
|||
use feature_flags::FeatureFlagViewExt;
|
||||
use futures::StreamExt;
|
||||
use git::{
|
||||
status::FileStatus, Commit, StageAll, StageAndNext, ToggleStaged, UnstageAll, UnstageAndNext,
|
||||
repository::Branch, status::FileStatus, Commit, StageAll, StageAndNext, ToggleStaged,
|
||||
UnstageAll, UnstageAndNext,
|
||||
};
|
||||
use gpui::{
|
||||
actions, Action, AnyElement, AnyView, App, AppContext as _, AsyncWindowContext, Entity,
|
||||
|
@ -24,27 +25,27 @@ use project::{
|
|||
};
|
||||
use std::any::{Any, TypeId};
|
||||
use theme::ActiveTheme;
|
||||
use ui::{prelude::*, vertical_divider, Tooltip};
|
||||
use ui::{prelude::*, vertical_divider, KeyBinding, Tooltip};
|
||||
use util::ResultExt as _;
|
||||
use workspace::{
|
||||
item::{BreadcrumbText, Item, ItemEvent, ItemHandle, TabContentParams},
|
||||
searchable::SearchableItemHandle,
|
||||
ItemNavHistory, SerializableItem, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
|
||||
Workspace,
|
||||
CloseActiveItem, ItemNavHistory, SerializableItem, ToolbarItemEvent, ToolbarItemLocation,
|
||||
ToolbarItemView, Workspace,
|
||||
};
|
||||
|
||||
actions!(git, [Diff]);
|
||||
actions!(git, [Diff, Add]);
|
||||
|
||||
pub struct ProjectDiff {
|
||||
project: Entity<Project>,
|
||||
multibuffer: Entity<MultiBuffer>,
|
||||
editor: Entity<Editor>,
|
||||
project: Entity<Project>,
|
||||
git_store: Entity<GitStore>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
focus_handle: FocusHandle,
|
||||
update_needed: postage::watch::Sender<()>,
|
||||
pending_scroll: Option<PathKey>,
|
||||
|
||||
current_branch: Option<Branch>,
|
||||
_task: Task<Result<()>>,
|
||||
_subscription: Subscription,
|
||||
}
|
||||
|
@ -70,6 +71,9 @@ impl ProjectDiff {
|
|||
let Some(window) = window else { return };
|
||||
cx.when_flag_enabled::<feature_flags::GitUiFeatureFlag>(window, |workspace, _, _cx| {
|
||||
workspace.register_action(Self::deploy);
|
||||
workspace.register_action(|workspace, _: &Add, window, cx| {
|
||||
Self::deploy(workspace, &Diff, window, cx);
|
||||
});
|
||||
});
|
||||
|
||||
workspace::register_serializable_item::<ProjectDiff>(cx);
|
||||
|
@ -179,6 +183,7 @@ impl ProjectDiff {
|
|||
multibuffer,
|
||||
pending_scroll: None,
|
||||
update_needed: send,
|
||||
current_branch: None,
|
||||
_task: worker,
|
||||
_subscription: git_store_subscription,
|
||||
}
|
||||
|
@ -444,6 +449,20 @@ impl ProjectDiff {
|
|||
mut cx: AsyncWindowContext,
|
||||
) -> Result<()> {
|
||||
while let Some(_) = recv.next().await {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let new_branch =
|
||||
this.git_store
|
||||
.read(cx)
|
||||
.active_repository()
|
||||
.and_then(|active_repository| {
|
||||
active_repository.read(cx).current_branch().cloned()
|
||||
});
|
||||
if new_branch != this.current_branch {
|
||||
this.current_branch = new_branch;
|
||||
cx.notify();
|
||||
}
|
||||
})?;
|
||||
|
||||
let buffers_to_load = this.update(&mut cx, |this, cx| this.load_buffers(cx))?;
|
||||
for buffer_to_load in buffers_to_load {
|
||||
if let Some(buffer) = buffer_to_load.await.log_err() {
|
||||
|
@ -642,9 +661,11 @@ impl Item for ProjectDiff {
|
|||
}
|
||||
|
||||
impl Render for ProjectDiff {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let is_empty = self.multibuffer.read(cx).is_empty();
|
||||
|
||||
let can_push_and_pull = crate::can_push_and_pull(&self.project, cx);
|
||||
|
||||
div()
|
||||
.track_focus(&self.focus_handle)
|
||||
.key_context(if is_empty { "EmptyPane" } else { "GitDiff" })
|
||||
|
@ -654,7 +675,61 @@ impl Render for ProjectDiff {
|
|||
.justify_center()
|
||||
.size_full()
|
||||
.when(is_empty, |el| {
|
||||
el.child(Label::new("No uncommitted changes"))
|
||||
el.child(
|
||||
v_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_around()
|
||||
.child(Label::new("No uncommitted changes")),
|
||||
)
|
||||
.when(can_push_and_pull, |this_div| {
|
||||
let keybinding_focus_handle = self.focus_handle(cx);
|
||||
|
||||
this_div.when_some(self.current_branch.as_ref(), |this_div, branch| {
|
||||
let remote_button = crate::render_remote_button(
|
||||
"project-diff-remote-button",
|
||||
branch,
|
||||
Some(keybinding_focus_handle.clone()),
|
||||
false,
|
||||
);
|
||||
|
||||
match remote_button {
|
||||
Some(button) => {
|
||||
this_div.child(h_flex().justify_around().child(button))
|
||||
}
|
||||
None => this_div.child(
|
||||
h_flex()
|
||||
.justify_around()
|
||||
.child(Label::new("Remote up to date")),
|
||||
),
|
||||
}
|
||||
})
|
||||
})
|
||||
.map(|this| {
|
||||
let keybinding_focus_handle = self.focus_handle(cx).clone();
|
||||
|
||||
this.child(
|
||||
h_flex().justify_around().mt_1().child(
|
||||
Button::new("project-diff-close-button", "Close")
|
||||
// .style(ButtonStyle::Transparent)
|
||||
.key_binding(KeyBinding::for_action_in(
|
||||
&CloseActiveItem::default(),
|
||||
&keybinding_focus_handle,
|
||||
window,
|
||||
cx,
|
||||
))
|
||||
.on_click(move |_, window, cx| {
|
||||
window.focus(&keybinding_focus_handle);
|
||||
window.dispatch_action(
|
||||
Box::new(CloseActiveItem::default()),
|
||||
cx,
|
||||
);
|
||||
}),
|
||||
),
|
||||
)
|
||||
}),
|
||||
)
|
||||
})
|
||||
.when(!is_empty, |el| el.child(self.editor.clone()))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue