Allow codebase search to be turned on or off within the composer for assistant2 (#11315)
   Release Notes: - N/A
This commit is contained in:
parent
43ad470e58
commit
1915a756a0
8 changed files with 209 additions and 138 deletions
|
@ -1,4 +1,4 @@
|
|||
use assistant_tooling::ToolRegistry;
|
||||
use crate::{ui::ProjectIndexButton, AssistantChat, CompletionProvider};
|
||||
use client::User;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use gpui::{AnyElement, FontStyle, FontWeight, TextStyle, View, WeakView, WhiteSpace};
|
||||
|
@ -7,13 +7,11 @@ use std::sync::Arc;
|
|||
use theme::ThemeSettings;
|
||||
use ui::{popover_menu, prelude::*, Avatar, ButtonLike, ContextMenu, Tooltip};
|
||||
|
||||
use crate::{AssistantChat, CompletionProvider};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct Composer {
|
||||
editor: View<Editor>,
|
||||
player: Option<Arc<User>>,
|
||||
tool_registry: Arc<ToolRegistry>,
|
||||
project_index_button: Option<View<ProjectIndexButton>>,
|
||||
model_selector: AnyElement,
|
||||
}
|
||||
|
||||
|
@ -21,20 +19,28 @@ impl Composer {
|
|||
pub fn new(
|
||||
editor: View<Editor>,
|
||||
player: Option<Arc<User>>,
|
||||
tool_registry: Arc<ToolRegistry>,
|
||||
project_index_button: Option<View<ProjectIndexButton>>,
|
||||
model_selector: AnyElement,
|
||||
) -> Self {
|
||||
Self {
|
||||
editor,
|
||||
player,
|
||||
tool_registry,
|
||||
project_index_button,
|
||||
model_selector,
|
||||
}
|
||||
}
|
||||
|
||||
fn render_tools(&mut self, _cx: &mut WindowContext) -> impl IntoElement {
|
||||
h_flex().children(
|
||||
self.project_index_button
|
||||
.clone()
|
||||
.map(|view| view.into_any_element()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for Composer {
|
||||
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||
fn render(mut self, cx: &mut WindowContext) -> impl IntoElement {
|
||||
let mut player_avatar = div().size(rems_from_px(20.)).into_any_element();
|
||||
if let Some(player) = self.player.clone() {
|
||||
player_avatar = Avatar::new(player.avatar_uri.clone())
|
||||
|
@ -95,9 +101,7 @@ impl RenderOnce for Composer {
|
|||
.gap_2()
|
||||
.justify_between()
|
||||
.w_full()
|
||||
.child(h_flex().gap_1().children(
|
||||
self.tool_registry.status_views().iter().cloned(),
|
||||
))
|
||||
.child(h_flex().gap_1().child(self.render_tools(cx)))
|
||||
.child(h_flex().gap_1().child(self.model_selector)),
|
||||
),
|
||||
),
|
||||
|
|
109
crates/assistant2/src/ui/project_index_button.rs
Normal file
109
crates/assistant2/src/ui/project_index_button.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
use assistant_tooling::ToolRegistry;
|
||||
use gpui::{percentage, prelude::*, Animation, AnimationExt, Model, Transformation};
|
||||
use semantic_index::{ProjectIndex, Status};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use ui::{prelude::*, ButtonLike, Color, Icon, IconName, Indicator, Tooltip};
|
||||
|
||||
use crate::tools::ProjectIndexTool;
|
||||
|
||||
pub struct ProjectIndexButton {
|
||||
project_index: Model<ProjectIndex>,
|
||||
tool_registry: Arc<ToolRegistry>,
|
||||
}
|
||||
|
||||
impl ProjectIndexButton {
|
||||
pub fn new(
|
||||
project_index: Model<ProjectIndex>,
|
||||
tool_registry: Arc<ToolRegistry>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
cx.subscribe(&project_index, |_this, _, _status: &Status, cx| {
|
||||
cx.notify();
|
||||
})
|
||||
.detach();
|
||||
Self {
|
||||
project_index,
|
||||
tool_registry,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_enabled(&mut self, enabled: bool) {
|
||||
self.tool_registry
|
||||
.set_tool_enabled::<ProjectIndexTool>(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ProjectIndexButton {
|
||||
// Expanded information on ToolView
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let status = self.project_index.read(cx).status();
|
||||
let is_enabled = self.tool_registry.is_tool_enabled::<ProjectIndexTool>();
|
||||
|
||||
let icon = if is_enabled {
|
||||
match status {
|
||||
Status::Idle => Icon::new(IconName::Code)
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Default),
|
||||
Status::Loading => Icon::new(IconName::Code)
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Muted),
|
||||
Status::Scanning { .. } => Icon::new(IconName::Code)
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Muted),
|
||||
}
|
||||
} else {
|
||||
Icon::new(IconName::Code)
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Disabled)
|
||||
};
|
||||
|
||||
let indicator = if is_enabled {
|
||||
match status {
|
||||
Status::Idle => Some(Indicator::dot().color(Color::Success)),
|
||||
Status::Scanning { .. } => Some(Indicator::dot().color(Color::Warning)),
|
||||
Status::Loading => Some(Indicator::icon(
|
||||
Icon::new(IconName::Spinner)
|
||||
.color(Color::Accent)
|
||||
.with_animation(
|
||||
"arrow-circle",
|
||||
Animation::new(Duration::from_secs(2)).repeat(),
|
||||
|icon, delta| icon.transform(Transformation::rotate(percentage(delta))),
|
||||
),
|
||||
)),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
ButtonLike::new("project-index")
|
||||
.child(
|
||||
ui::IconWithIndicator::new(icon, indicator)
|
||||
.indicator_border_color(Some(gpui::transparent_black())),
|
||||
)
|
||||
.tooltip({
|
||||
move |cx| {
|
||||
let (tooltip, meta) = match status {
|
||||
Status::Idle => (
|
||||
"Project index ready".to_string(),
|
||||
Some("Click to disable".to_string()),
|
||||
),
|
||||
Status::Loading => ("Project index loading...".to_string(), None),
|
||||
Status::Scanning { remaining_count } => (
|
||||
"Project index scanning...".to_string(),
|
||||
Some(format!("{} remaining...", remaining_count)),
|
||||
),
|
||||
};
|
||||
|
||||
if let Some(meta) = meta {
|
||||
Tooltip::with_meta(tooltip, None, meta, cx)
|
||||
} else {
|
||||
Tooltip::text(tooltip, cx)
|
||||
}
|
||||
}
|
||||
})
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.set_enabled(!is_enabled);
|
||||
cx.notify();
|
||||
}))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue