ZIm/crates/assistant2/src/assistant_model_selector.rs
Danilo Leal 2627a5fdbe
assistant: Improve the language model selector (#25125)
This PR includes change such as:

- Ensures the popover width is fixed/not dancing around
- Ensures the popover is not obscuring the trigger in the buffer and
terminal inline assistant scenarios
- Removes ellipsis from the trigger button label
- Ensures the scrollbar doesn't hide the check icon

| Terminal | Prompt Editor | Buffer |
|--------|--------|--------|
| ![Screenshot 2025-02-18 at 8 43
46 PM](https://github.com/user-attachments/assets/9cdfbaf1-f27e-4f48-877e-9cf61767ecee)
| ![Screenshot 2025-02-18 at 8 43
49 PM](https://github.com/user-attachments/assets/7abf9be2-bd2a-43d7-9a5d-d665e7e9fda3)
| ![Screenshot 2025-02-18 at 8 43
52 PM](https://github.com/user-attachments/assets/017bbdb3-185a-4bf6-9005-018ecafef9dd)
|

Release Notes:

- N/A
2025-02-18 21:01:09 -03:00

87 lines
2.9 KiB
Rust

use assistant_settings::AssistantSettings;
use fs::Fs;
use gpui::{Entity, FocusHandle, SharedString};
use language_model::LanguageModelRegistry;
use language_model_selector::{LanguageModelSelector, LanguageModelSelectorPopoverMenu};
use settings::update_settings_file;
use std::sync::Arc;
use ui::{prelude::*, ButtonLike, PopoverMenuHandle, Tooltip};
use crate::ToggleModelSelector;
pub struct AssistantModelSelector {
selector: Entity<LanguageModelSelector>,
menu_handle: PopoverMenuHandle<LanguageModelSelector>,
focus_handle: FocusHandle,
}
impl AssistantModelSelector {
pub(crate) fn new(
fs: Arc<dyn Fs>,
menu_handle: PopoverMenuHandle<LanguageModelSelector>,
focus_handle: FocusHandle,
window: &mut Window,
cx: &mut App,
) -> Self {
Self {
selector: cx.new(|cx| {
let fs = fs.clone();
LanguageModelSelector::new(
move |model, cx| {
update_settings_file::<AssistantSettings>(
fs.clone(),
cx,
move |settings, _cx| settings.set_model(model.clone()),
);
},
window,
cx,
)
}),
menu_handle,
focus_handle,
}
}
}
impl Render for AssistantModelSelector {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let active_model = LanguageModelRegistry::read_global(cx).active_model();
let focus_handle = self.focus_handle.clone();
let model_name = match active_model {
Some(model) => model.name().0,
_ => SharedString::from("No model selected"),
};
LanguageModelSelectorPopoverMenu::new(
self.selector.clone(),
ButtonLike::new("active-model")
.style(ButtonStyle::Subtle)
.child(
h_flex()
.gap_0p5()
.child(
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted),
)
.child(
Icon::new(IconName::ChevronDown)
.color(Color::Muted)
.size(IconSize::XSmall),
),
),
move |window, cx| {
Tooltip::for_action_in(
"Change Model",
&ToggleModelSelector,
&focus_handle,
window,
cx,
)
},
gpui::Corner::BottomRight,
)
.with_handle(self.menu_handle.clone())
}
}