zeta: Improve reviewing UI (#21838)
Starting to fine-tune it. | No edits scenario | Rated edits scenario | |--------|--------| | <img width="1577" alt="Screenshot 2024-12-11 at 01 57 46" src="https://github.com/user-attachments/assets/42926e84-7a7f-4692-af44-672b52d3d377"> | <img width="1577" alt="Screenshot 2024-12-11 at 01 58 37" src="https://github.com/user-attachments/assets/ee8ab0ef-75af-424c-b916-9f1ce8b5264d"> Release Notes: - N/A
This commit is contained in:
parent
62a6a755ec
commit
63e1bf01a4
5 changed files with 135 additions and 92 deletions
1
assets/icons/file_diff.svg
Normal file
1
assets/icons/file_diff.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-diff"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M9 10h6"/><path d="M12 13V7"/><path d="M9 17h6"/></svg>
|
After Width: | Height: | Size: 348 B |
1
assets/icons/thumbs_down.svg
Normal file
1
assets/icons/thumbs_down.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-thumbs-down"><path d="M17 14V2"/><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z"/></svg>
|
After Width: | Height: | Size: 405 B |
1
assets/icons/thumbs_up.svg
Normal file
1
assets/icons/thumbs_up.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-thumbs-up"><path d="M7 10v12"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/></svg>
|
After Width: | Height: | Size: 404 B |
|
@ -178,6 +178,7 @@ pub enum IconName {
|
||||||
File,
|
File,
|
||||||
FileCode,
|
FileCode,
|
||||||
FileDoc,
|
FileDoc,
|
||||||
|
FileDiff,
|
||||||
FileGeneric,
|
FileGeneric,
|
||||||
FileGit,
|
FileGit,
|
||||||
FileLock,
|
FileLock,
|
||||||
|
@ -278,6 +279,8 @@ pub enum IconName {
|
||||||
Tab,
|
Tab,
|
||||||
Terminal,
|
Terminal,
|
||||||
TextSnippet,
|
TextSnippet,
|
||||||
|
ThumbsUp,
|
||||||
|
ThumbsDown,
|
||||||
Trash,
|
Trash,
|
||||||
TrashAlt,
|
TrashAlt,
|
||||||
Triangle,
|
Triangle,
|
||||||
|
|
|
@ -7,7 +7,7 @@ use gpui::{
|
||||||
use language::{language_settings, OffsetRangeExt};
|
use language::{language_settings, OffsetRangeExt};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use theme::ThemeSettings;
|
use theme::ThemeSettings;
|
||||||
use ui::{prelude::*, ListItem, ListItemSpacing};
|
use ui::{prelude::*, List, ListItem, ListItemSpacing, TintColor};
|
||||||
use workspace::{ModalView, Workspace};
|
use workspace::{ModalView, Workspace};
|
||||||
|
|
||||||
pub struct RateCompletionModal {
|
pub struct RateCompletionModal {
|
||||||
|
@ -69,7 +69,7 @@ impl RateCompletionModal {
|
||||||
editor.set_show_wrap_guides(false, cx);
|
editor.set_show_wrap_guides(false, cx);
|
||||||
editor.set_show_indent_guides(false, cx);
|
editor.set_show_indent_guides(false, cx);
|
||||||
editor.set_show_inline_completions(Some(false), cx);
|
editor.set_show_inline_completions(Some(false), cx);
|
||||||
editor.set_placeholder_text("Your feedback about this completion...", cx);
|
editor.set_placeholder_text("Add your feedback about this completion…", cx);
|
||||||
editor
|
editor
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -134,62 +134,80 @@ impl RateCompletionModal {
|
||||||
};
|
};
|
||||||
|
|
||||||
let rated = self.zeta.read(cx).is_completion_rated(completion_id);
|
let rated = self.zeta.read(cx).is_completion_rated(completion_id);
|
||||||
|
|
||||||
|
let border_color = cx.theme().colors().border;
|
||||||
|
let bg_color = cx.theme().colors().editor_background;
|
||||||
|
|
||||||
|
let label_container = || h_flex().pl_1().gap_1p5();
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
v_flex()
|
v_flex()
|
||||||
.flex_1()
|
|
||||||
.size_full()
|
.size_full()
|
||||||
.gap_2()
|
.overflow_hidden()
|
||||||
.child(h_flex().justify_center().children(if rated {
|
|
||||||
Some(
|
|
||||||
Label::new("This completion was already rated")
|
|
||||||
.color(Color::Muted)
|
|
||||||
.size(LabelSize::Large),
|
|
||||||
)
|
|
||||||
} else if active_completion.completion.edits.is_empty() {
|
|
||||||
Some(
|
|
||||||
Label::new("This completion didn't produce any edits")
|
|
||||||
.color(Color::Warning)
|
|
||||||
.size(LabelSize::Large),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}))
|
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
div()
|
||||||
.id("diff")
|
.id("diff")
|
||||||
.flex_1()
|
.py_4()
|
||||||
.flex_basis(relative(0.75))
|
.px_6()
|
||||||
.bg(cx.theme().colors().editor_background)
|
.size_full()
|
||||||
.overflow_y_scroll()
|
.bg(bg_color)
|
||||||
.p_2()
|
.overflow_scroll()
|
||||||
.border_color(cx.theme().colors().border)
|
|
||||||
.border_1()
|
|
||||||
.rounded_lg()
|
|
||||||
.child(StyledText::new(diff).with_highlights(&text_style, diff_highlights)),
|
.child(StyledText::new(diff).with_highlights(&text_style, diff_highlights)),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex_1()
|
.h_40()
|
||||||
.flex_basis(relative(0.25))
|
.bg(bg_color)
|
||||||
.bg(cx.theme().colors().editor_background)
|
.border_t_1()
|
||||||
.border_color(cx.theme().colors().border)
|
.border_color(border_color)
|
||||||
.border_1()
|
|
||||||
.rounded_lg()
|
|
||||||
.child(active_completion.feedback_editor.clone()),
|
.child(active_completion.feedback_editor.clone()),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_2()
|
.p_1()
|
||||||
.justify_end()
|
.h_8()
|
||||||
|
.border_t_1()
|
||||||
|
.border_color(border_color)
|
||||||
|
.max_w_full()
|
||||||
|
.justify_between()
|
||||||
|
.children(if rated {
|
||||||
|
Some(
|
||||||
|
label_container()
|
||||||
.child(
|
.child(
|
||||||
Button::new("bad", "👎 Bad Completion")
|
Icon::new(IconName::Check)
|
||||||
.size(ButtonSize::Large)
|
.size(IconSize::Small)
|
||||||
|
.color(Color::Success),
|
||||||
|
)
|
||||||
|
.child(Label::new("Rated completion").color(Color::Muted)),
|
||||||
|
)
|
||||||
|
} else if active_completion.completion.edits.is_empty() {
|
||||||
|
Some(
|
||||||
|
label_container()
|
||||||
|
.child(
|
||||||
|
Icon::new(IconName::Warning)
|
||||||
|
.size(IconSize::Small)
|
||||||
|
.color(Color::Warning),
|
||||||
|
)
|
||||||
|
.child(Label::new("No edits produced").color(Color::Muted)),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Some(label_container())
|
||||||
|
})
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_1()
|
||||||
|
.child(
|
||||||
|
Button::new("bad", "Bad Completion")
|
||||||
|
.style(ButtonStyle::Tinted(TintColor::Negative))
|
||||||
|
.icon(IconName::ThumbsDown)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.icon_position(IconPosition::Start)
|
||||||
|
.icon_color(Color::Error)
|
||||||
.disabled(rated)
|
.disabled(rated)
|
||||||
.label_size(LabelSize::Large)
|
|
||||||
.color(Color::Error)
|
|
||||||
.on_click({
|
.on_click({
|
||||||
let completion = active_completion.completion.clone();
|
let completion = active_completion.completion.clone();
|
||||||
let feedback_editor = active_completion.feedback_editor.clone();
|
let feedback_editor =
|
||||||
|
active_completion.feedback_editor.clone();
|
||||||
cx.listener(move |this, _, cx| {
|
cx.listener(move |this, _, cx| {
|
||||||
this.zeta.update(cx, |zeta, cx| {
|
this.zeta.update(cx, |zeta, cx| {
|
||||||
zeta.rate_completion(
|
zeta.rate_completion(
|
||||||
|
@ -203,14 +221,17 @@ impl RateCompletionModal {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("good", "👍 Good Completion")
|
Button::new("good", "Good Completion")
|
||||||
.size(ButtonSize::Large)
|
.style(ButtonStyle::Tinted(TintColor::Positive))
|
||||||
|
.icon(IconName::ThumbsUp)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.icon_position(IconPosition::Start)
|
||||||
|
.icon_color(Color::Success)
|
||||||
.disabled(rated)
|
.disabled(rated)
|
||||||
.label_size(LabelSize::Large)
|
|
||||||
.color(Color::Success)
|
|
||||||
.on_click({
|
.on_click({
|
||||||
let completion = active_completion.completion.clone();
|
let completion = active_completion.completion.clone();
|
||||||
let feedback_editor = active_completion.feedback_editor.clone();
|
let feedback_editor =
|
||||||
|
active_completion.feedback_editor.clone();
|
||||||
cx.listener(move |this, _, cx| {
|
cx.listener(move |this, _, cx| {
|
||||||
this.zeta.update(cx, |zeta, cx| {
|
this.zeta.update(cx, |zeta, cx| {
|
||||||
zeta.rate_completion(
|
zeta.rate_completion(
|
||||||
|
@ -224,33 +245,45 @@ impl RateCompletionModal {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for RateCompletionModal {
|
impl Render for RateCompletionModal {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
|
let border_color = cx.theme().colors().border;
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_2()
|
|
||||||
.bg(cx.theme().colors().elevated_surface_background)
|
|
||||||
.w(cx.viewport_size().width - px(256.))
|
|
||||||
.h(cx.viewport_size().height - px(256.))
|
|
||||||
.rounded_lg()
|
|
||||||
.shadow_lg()
|
|
||||||
.p_2()
|
|
||||||
.key_context("RateCompletionModal")
|
.key_context("RateCompletionModal")
|
||||||
.track_focus(&self.focus_handle)
|
.track_focus(&self.focus_handle)
|
||||||
.on_action(cx.listener(Self::dismiss))
|
.on_action(cx.listener(Self::dismiss))
|
||||||
|
.bg(cx.theme().colors().elevated_surface_background)
|
||||||
|
.border_1()
|
||||||
|
.border_color(border_color)
|
||||||
|
.w(cx.viewport_size().width - px(320.))
|
||||||
|
.h(cx.viewport_size().height - px(300.))
|
||||||
|
.rounded_lg()
|
||||||
|
.shadow_lg()
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.id("completion_list")
|
.id("completion_list")
|
||||||
|
.border_r_1()
|
||||||
|
.border_color(border_color)
|
||||||
.w_96()
|
.w_96()
|
||||||
.h_full()
|
.h_full()
|
||||||
|
.p_0p5()
|
||||||
.overflow_y_scroll()
|
.overflow_y_scroll()
|
||||||
.child(
|
.child(
|
||||||
ui::List::new()
|
List::new()
|
||||||
.empty_message(
|
.empty_message(
|
||||||
"No completions, use the editor to generate some and rate them!",
|
div()
|
||||||
|
.p_2()
|
||||||
|
.child(
|
||||||
|
Label::new("No completions yet. Use the editor to generate some and rate them!")
|
||||||
|
.color(Color::Muted),
|
||||||
|
)
|
||||||
|
.into_any_element(),
|
||||||
)
|
)
|
||||||
.children(self.zeta.read(cx).recent_completions().cloned().map(
|
.children(self.zeta.read(cx).recent_completions().cloned().map(
|
||||||
|completion| {
|
|completion| {
|
||||||
|
@ -261,22 +294,26 @@ impl Render for RateCompletionModal {
|
||||||
let rated =
|
let rated =
|
||||||
self.zeta.read(cx).is_completion_rated(completion.id);
|
self.zeta.read(cx).is_completion_rated(completion.id);
|
||||||
ListItem::new(completion.id)
|
ListItem::new(completion.id)
|
||||||
|
.inset(true)
|
||||||
.spacing(ListItemSpacing::Sparse)
|
.spacing(ListItemSpacing::Sparse)
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.end_slot(if rated {
|
.start_slot(if rated {
|
||||||
Icon::new(IconName::Check).color(Color::Success)
|
Icon::new(IconName::Check).color(Color::Success)
|
||||||
} else if completion.edits.is_empty() {
|
} else if completion.edits.is_empty() {
|
||||||
Icon::new(IconName::Ellipsis).color(Color::Muted)
|
Icon::new(IconName::File).color(Color::Muted).size(IconSize::Small)
|
||||||
} else {
|
} else {
|
||||||
Icon::new(IconName::Diff).color(Color::Muted)
|
Icon::new(IconName::FileDiff).color(Color::Accent).size(IconSize::Small)
|
||||||
})
|
})
|
||||||
.child(Label::new(
|
.child(Label::new(
|
||||||
completion.path.to_string_lossy().to_string(),
|
completion.path.to_string_lossy().to_string(),
|
||||||
))
|
).size(LabelSize::Small))
|
||||||
.child(
|
.child(
|
||||||
Label::new(format!("({})", completion.id))
|
div()
|
||||||
|
.overflow_hidden()
|
||||||
|
.text_ellipsis()
|
||||||
|
.child(Label::new(format!("({})", completion.id))
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
.size(LabelSize::XSmall),
|
.size(LabelSize::XSmall)),
|
||||||
)
|
)
|
||||||
.on_click(cx.listener(move |this, _, cx| {
|
.on_click(cx.listener(move |this, _, cx| {
|
||||||
this.select_completion(Some(completion.clone()), cx);
|
this.select_completion(Some(completion.clone()), cx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue