assistant: Remove "Resolving" text for step resolution and use Transform instead (#16461)
That way, user can click on "Transform" straight away and get it applied immediately when it's resolved. https://github.com/user-attachments/assets/08c99804-3841-4eba-a5eb-7066a9f45b47 TODO: - [x] Tie "Send" button at the bottom into the same behavior Release Notes: - N/A
This commit is contained in:
parent
911112d94a
commit
56f1ab9459
2 changed files with 108 additions and 53 deletions
|
@ -1355,6 +1355,7 @@ struct WorkflowStep {
|
||||||
footer_block_id: CustomBlockId,
|
footer_block_id: CustomBlockId,
|
||||||
resolved_step: Option<Result<WorkflowStepResolution, Arc<anyhow::Error>>>,
|
resolved_step: Option<Result<WorkflowStepResolution, Arc<anyhow::Error>>>,
|
||||||
assist: Option<WorkflowAssist>,
|
assist: Option<WorkflowAssist>,
|
||||||
|
auto_apply: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkflowStep {
|
impl WorkflowStep {
|
||||||
|
@ -1391,13 +1392,16 @@ impl WorkflowStep {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Err(error)) => WorkflowStepStatus::Error(error.clone()),
|
Some(Err(error)) => WorkflowStepStatus::Error(error.clone()),
|
||||||
None => WorkflowStepStatus::Resolving,
|
None => WorkflowStepStatus::Resolving {
|
||||||
|
auto_apply: self.auto_apply,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
enum WorkflowStepStatus {
|
enum WorkflowStepStatus {
|
||||||
Resolving,
|
Resolving { auto_apply: bool },
|
||||||
Error(Arc<anyhow::Error>),
|
Error(Arc<anyhow::Error>),
|
||||||
Empty,
|
Empty,
|
||||||
Idle,
|
Idle,
|
||||||
|
@ -1474,16 +1478,6 @@ impl WorkflowStepStatus {
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
match self {
|
match self {
|
||||||
WorkflowStepStatus::Resolving => Label::new("Resolving")
|
|
||||||
.size(LabelSize::Small)
|
|
||||||
.with_animation(
|
|
||||||
("resolving-suggestion-animation", id),
|
|
||||||
Animation::new(Duration::from_secs(2))
|
|
||||||
.repeat()
|
|
||||||
.with_easing(pulsating_between(0.4, 0.8)),
|
|
||||||
|label, delta| label.alpha(delta),
|
|
||||||
)
|
|
||||||
.into_any_element(),
|
|
||||||
WorkflowStepStatus::Error(error) => Self::render_workflow_step_error(
|
WorkflowStepStatus::Error(error) => Self::render_workflow_step_error(
|
||||||
id,
|
id,
|
||||||
editor.clone(),
|
editor.clone(),
|
||||||
|
@ -1496,7 +1490,9 @@ impl WorkflowStepStatus {
|
||||||
step_range.clone(),
|
step_range.clone(),
|
||||||
"Model was unable to locate the code to edit".to_string(),
|
"Model was unable to locate the code to edit".to_string(),
|
||||||
),
|
),
|
||||||
WorkflowStepStatus::Idle => Button::new(("transform", id), "Transform")
|
WorkflowStepStatus::Idle | WorkflowStepStatus::Resolving { .. } => {
|
||||||
|
let status = self.clone();
|
||||||
|
Button::new(("transform", id), "Transform")
|
||||||
.icon(IconName::SparkleAlt)
|
.icon(IconName::SparkleAlt)
|
||||||
.icon_position(IconPosition::Start)
|
.icon_position(IconPosition::Start)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
|
@ -1525,14 +1521,41 @@ impl WorkflowStepStatus {
|
||||||
let editor = editor.clone();
|
let editor = editor.clone();
|
||||||
let step_range = step_range.clone();
|
let step_range = step_range.clone();
|
||||||
move |_, cx| {
|
move |_, cx| {
|
||||||
|
if let WorkflowStepStatus::Idle = &status {
|
||||||
editor
|
editor
|
||||||
.update(cx, |this, cx| {
|
.update(cx, |this, cx| {
|
||||||
this.apply_workflow_step(step_range.clone(), cx)
|
this.apply_workflow_step(step_range.clone(), cx)
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
} else if let WorkflowStepStatus::Resolving { auto_apply: false } =
|
||||||
|
&status
|
||||||
|
{
|
||||||
|
editor
|
||||||
|
.update(cx, |this, _| {
|
||||||
|
if let Some(step) = this.workflow_steps.get_mut(&step_range)
|
||||||
|
{
|
||||||
|
step.auto_apply = true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_any_element(),
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|this| {
|
||||||
|
if let WorkflowStepStatus::Resolving { auto_apply: true } = &self {
|
||||||
|
this.with_animation(
|
||||||
|
("resolving-suggestion-animation", id),
|
||||||
|
Animation::new(Duration::from_secs(2))
|
||||||
|
.repeat()
|
||||||
|
.with_easing(pulsating_between(0.4, 0.8)),
|
||||||
|
|label, delta| label.alpha(delta),
|
||||||
|
)
|
||||||
|
.into_any_element()
|
||||||
|
} else {
|
||||||
|
this.into_any_element()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
WorkflowStepStatus::Pending => h_flex()
|
WorkflowStepStatus::Pending => h_flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
|
@ -1856,7 +1879,7 @@ impl ContextEditor {
|
||||||
|
|
||||||
let range = step.range.clone();
|
let range = step.range.clone();
|
||||||
match step.status(cx) {
|
match step.status(cx) {
|
||||||
WorkflowStepStatus::Resolving | WorkflowStepStatus::Pending => true,
|
WorkflowStepStatus::Resolving { .. } | WorkflowStepStatus::Pending => true,
|
||||||
WorkflowStepStatus::Idle => {
|
WorkflowStepStatus::Idle => {
|
||||||
self.apply_workflow_step(range, cx);
|
self.apply_workflow_step(range, cx);
|
||||||
true
|
true
|
||||||
|
@ -2650,11 +2673,17 @@ impl ContextEditor {
|
||||||
footer_block_id: block_ids[1],
|
footer_block_id: block_ids[1],
|
||||||
resolved_step,
|
resolved_step,
|
||||||
assist: None,
|
assist: None,
|
||||||
|
auto_apply: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_active_workflow_step(cx);
|
self.update_active_workflow_step(cx);
|
||||||
|
if let Some(step) = self.workflow_steps.get_mut(&step_range) {
|
||||||
|
if step.auto_apply && matches!(step.status(cx), WorkflowStepStatus::Idle) {
|
||||||
|
self.apply_workflow_step(step_range, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_workflow_step(
|
fn open_workflow_step(
|
||||||
|
@ -3586,13 +3615,17 @@ impl ContextEditor {
|
||||||
|
|
||||||
fn render_send_button(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render_send_button(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
let focus_handle = self.focus_handle(cx).clone();
|
let focus_handle = self.focus_handle(cx).clone();
|
||||||
|
let mut should_pulsate = false;
|
||||||
let button_text = match self.active_workflow_step() {
|
let button_text = match self.active_workflow_step() {
|
||||||
Some(step) => match step.status(cx) {
|
Some(step) => match step.status(cx) {
|
||||||
WorkflowStepStatus::Resolving => "Resolving Step...",
|
|
||||||
WorkflowStepStatus::Empty | WorkflowStepStatus::Error(_) => "Retry Step Resolution",
|
WorkflowStepStatus::Empty | WorkflowStepStatus::Error(_) => "Retry Step Resolution",
|
||||||
|
WorkflowStepStatus::Resolving { auto_apply } => {
|
||||||
|
should_pulsate = auto_apply;
|
||||||
|
"Transform"
|
||||||
|
}
|
||||||
WorkflowStepStatus::Idle => "Transform",
|
WorkflowStepStatus::Idle => "Transform",
|
||||||
WorkflowStepStatus::Pending => "Transforming...",
|
WorkflowStepStatus::Pending => "Applying...",
|
||||||
WorkflowStepStatus::Done => "Accept Transformation",
|
WorkflowStepStatus::Done => "Accept",
|
||||||
WorkflowStepStatus::Confirmed => "Send",
|
WorkflowStepStatus::Confirmed => "Send",
|
||||||
},
|
},
|
||||||
None => "Send",
|
None => "Send",
|
||||||
|
@ -3636,7 +3669,20 @@ impl ContextEditor {
|
||||||
button.tooltip(move |_| tooltip.clone())
|
button.tooltip(move |_| tooltip.clone())
|
||||||
})
|
})
|
||||||
.layer(ElevationIndex::ModalSurface)
|
.layer(ElevationIndex::ModalSurface)
|
||||||
.child(Label::new(button_text))
|
.child(Label::new(button_text).map(|this| {
|
||||||
|
if should_pulsate {
|
||||||
|
this.with_animation(
|
||||||
|
"resolving-suggestion-send-button-animation",
|
||||||
|
Animation::new(Duration::from_secs(2))
|
||||||
|
.repeat()
|
||||||
|
.with_easing(pulsating_between(0.4, 0.8)),
|
||||||
|
|label, delta| label.alpha(delta),
|
||||||
|
)
|
||||||
|
.into_any_element()
|
||||||
|
} else {
|
||||||
|
this.into_any_element()
|
||||||
|
}
|
||||||
|
}))
|
||||||
.children(
|
.children(
|
||||||
KeyBinding::for_action_in(&Assist, &focus_handle, cx)
|
KeyBinding::for_action_in(&Assist, &focus_handle, cx)
|
||||||
.map(|binding| binding.into_any_element()),
|
.map(|binding| binding.into_any_element()),
|
||||||
|
|
|
@ -89,6 +89,7 @@ pub struct Button {
|
||||||
selected_icon: Option<IconName>,
|
selected_icon: Option<IconName>,
|
||||||
selected_icon_color: Option<Color>,
|
selected_icon_color: Option<Color>,
|
||||||
key_binding: Option<KeyBinding>,
|
key_binding: Option<KeyBinding>,
|
||||||
|
alpha: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Button {
|
impl Button {
|
||||||
|
@ -113,6 +114,7 @@ impl Button {
|
||||||
selected_icon: None,
|
selected_icon: None,
|
||||||
selected_icon_color: None,
|
selected_icon_color: None,
|
||||||
key_binding: None,
|
key_binding: None,
|
||||||
|
alpha: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +183,12 @@ impl Button {
|
||||||
self.key_binding = key_binding.into();
|
self.key_binding = key_binding.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the alpha property of the color of label.
|
||||||
|
pub fn alpha(mut self, alpha: f32) -> Self {
|
||||||
|
self.alpha = Some(alpha);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Selectable for Button {
|
impl Selectable for Button {
|
||||||
|
@ -409,6 +417,7 @@ impl RenderOnce for Button {
|
||||||
Label::new(label)
|
Label::new(label)
|
||||||
.color(label_color)
|
.color(label_color)
|
||||||
.size(self.label_size.unwrap_or_default())
|
.size(self.label_size.unwrap_or_default())
|
||||||
|
.when_some(self.alpha, |this, alpha| this.alpha(alpha))
|
||||||
.line_height_style(LineHeightStyle::UiLabel),
|
.line_height_style(LineHeightStyle::UiLabel),
|
||||||
)
|
)
|
||||||
.children(self.key_binding),
|
.children(self.key_binding),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue