mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
Fix when agent-powered merge conflict button shows up (#54791)
This PR fixes the logic to dismiss the "resolve merge conflict with agent" button. Previously, we were just observing `merge_heads_by_conflicted_path`, which seems to be intentionally sticky, preserving the conflicted paths until changes are either committed or aborted. This would make the button to resolve conflicts show up even _after_ the changes get resolved. Now, we're checking whether paths are _currently_ conflicted (`is_conflicted()`), and if they are not, we don't display the button, even though the resolution might have not been committed or aborted yet. As a bonus, in this PR, I'm also putting the resolve conflict button _before_ the activity indicator, so as to avoid bounciness, and did a quick polish of the activity indicator button itself, by using the `Button` component. Release Notes: - Fixed a bug with the merge conflict "resolve with agent" button where it would be displayed even though all conflicts have already been resolved.
This commit is contained in:
parent
f59c122bee
commit
f2e9c5a025
3 changed files with 39 additions and 40 deletions
|
|
@ -3,8 +3,8 @@ use editor::Editor;
|
|||
use extension_host::{ExtensionOperation, ExtensionStore};
|
||||
use futures::StreamExt;
|
||||
use gpui::{
|
||||
App, Context, CursorStyle, Entity, EventEmitter, InteractiveElement as _, ParentElement as _,
|
||||
Render, SharedString, StatefulInteractiveElement, Styled, Window, actions,
|
||||
App, Context, Entity, EventEmitter, InteractiveElement as _, ParentElement as _, Render,
|
||||
SharedString, Styled, Window, actions,
|
||||
};
|
||||
use language::{
|
||||
BinaryStatus, LanguageRegistry, LanguageServerId, LanguageServerName,
|
||||
|
|
@ -22,10 +22,7 @@ use std::{
|
|||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use ui::{
|
||||
ButtonLike, CommonAnimationExt, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip,
|
||||
prelude::*,
|
||||
};
|
||||
use ui::{CommonAnimationExt, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
|
||||
use util::truncate_and_trailoff;
|
||||
use workspace::{StatusItemView, Workspace, item::ItemHandle};
|
||||
|
||||
|
|
@ -720,43 +717,39 @@ impl Render for ActivityIndicator {
|
|||
};
|
||||
let activity_indicator = cx.entity().downgrade();
|
||||
let truncate_content = content.message.len() > MAX_MESSAGE_LEN;
|
||||
|
||||
result.gap_2().child(
|
||||
PopoverMenu::new("activity-indicator-popover")
|
||||
.trigger(
|
||||
ButtonLike::new("activity-indicator-trigger").child(
|
||||
h_flex()
|
||||
.id("activity-indicator-status")
|
||||
.gap_2()
|
||||
.children(content.icon)
|
||||
.map(|button| {
|
||||
if truncate_content {
|
||||
button
|
||||
.child(
|
||||
Label::new(truncate_and_trailoff(
|
||||
&content.message,
|
||||
MAX_MESSAGE_LEN,
|
||||
))
|
||||
.size(LabelSize::Small),
|
||||
)
|
||||
.tooltip(Tooltip::text(content.message))
|
||||
} else {
|
||||
button
|
||||
.child(Label::new(content.message).size(LabelSize::Small))
|
||||
.when_some(
|
||||
content.tooltip_message,
|
||||
|this, tooltip_message| {
|
||||
this.tooltip(Tooltip::text(tooltip_message))
|
||||
},
|
||||
)
|
||||
}
|
||||
Button::new("activity-indicator-trigger", {
|
||||
if truncate_content {
|
||||
truncate_and_trailoff(&content.message, MAX_MESSAGE_LEN)
|
||||
} else {
|
||||
content.message.clone()
|
||||
}
|
||||
})
|
||||
.label_size(LabelSize::Small)
|
||||
.when(content.icon.is_some(), |this| {
|
||||
this.start_icon(
|
||||
Icon::new(IconName::LoadCircle)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::Small),
|
||||
)
|
||||
})
|
||||
.map(|button| {
|
||||
if truncate_content {
|
||||
button.tooltip(Tooltip::text(content.message))
|
||||
} else {
|
||||
button.when_some(content.tooltip_message, |this, tooltip_message| {
|
||||
this.tooltip(Tooltip::text(tooltip_message))
|
||||
})
|
||||
.when_some(content.on_click, |this, handler| {
|
||||
this.on_click(cx.listener(move |this, _, window, cx| {
|
||||
handler(this, window, cx);
|
||||
}))
|
||||
.cursor(CursorStyle::PointingHand)
|
||||
}),
|
||||
),
|
||||
}
|
||||
})
|
||||
.when_some(content.on_click, |this, handler| {
|
||||
this.on_click(cx.listener(move |this, _, window, cx| {
|
||||
handler(this, window, cx);
|
||||
}))
|
||||
}),
|
||||
)
|
||||
.anchor(gpui::Anchor::BottomLeft)
|
||||
.menu(move |window, cx| {
|
||||
|
|
|
|||
|
|
@ -418,6 +418,12 @@ fn collect_conflicted_file_paths(project: &Project, cx: &App) -> Vec<String> {
|
|||
for repo in git_store.repositories().values() {
|
||||
let snapshot = repo.read(cx).snapshot();
|
||||
for (repo_path, _) in snapshot.merge.merge_heads_by_conflicted_path.iter() {
|
||||
let is_currently_conflicted = snapshot
|
||||
.status_for_path(repo_path)
|
||||
.is_some_and(|entry| entry.status.is_conflicted());
|
||||
if !is_currently_conflicted {
|
||||
continue;
|
||||
}
|
||||
if let Some(project_path) = repo.read(cx).repo_path_to_project_path(repo_path, cx) {
|
||||
paths.push(
|
||||
project_path
|
||||
|
|
|
|||
|
|
@ -573,8 +573,8 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut App) {
|
|||
status_bar.add_left_item(lsp_button, window, cx);
|
||||
status_bar.add_left_item(diagnostic_summary, window, cx);
|
||||
status_bar.add_left_item(active_file_name, window, cx);
|
||||
status_bar.add_left_item(activity_indicator, window, cx);
|
||||
status_bar.add_left_item(merge_conflict_indicator, window, cx);
|
||||
status_bar.add_left_item(activity_indicator, window, cx);
|
||||
status_bar.add_right_item(edit_prediction_ui, window, cx);
|
||||
status_bar.add_right_item(active_buffer_encoding, window, cx);
|
||||
status_bar.add_right_item(active_buffer_language, window, cx);
|
||||
|
|
|
|||
Loading…
Reference in a new issue