assistant2: Add ChatNotice component (#11262)

This PR adds a new `ChatNotice` component for displaying notices within
the assistant.

We will be able to use this for allowing the user to confirm a project
index request.

<img width="518" alt="Screenshot 2024-05-01 at 2 41 31 PM"
src="https://github.com/zed-industries/zed/assets/1486634/3beaeeaf-6046-4284-ac0a-4248e1f9ac20">

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-05-01 14:51:28 -04:00 committed by GitHub
parent 0858e3f0e2
commit 3dc5d48e0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 102 additions and 3 deletions

View File

@ -1,10 +1,12 @@
mod chat_message;
mod chat_notice;
mod composer;
#[cfg(feature = "stories")]
mod stories;
pub use chat_message::*;
pub use chat_notice::*;
pub use composer::*;
#[cfg(feature = "stories")]

View File

@ -118,7 +118,7 @@ impl RenderOnce for ChatMessageHeader {
h_flex()
.gap_3()
.map(|this| {
let avatar_size = rems(20.0 / 16.0);
let avatar_size = rems_from_px(20.);
if let Some(avatar_uri) = avatar_uri {
this.child(Avatar::new(avatar_uri).size(avatar_size))
} else {

View File

@ -0,0 +1,71 @@
use ui::{prelude::*, Avatar, IconButtonShape};
#[derive(IntoElement)]
pub struct ChatNotice {
message: SharedString,
meta: Option<SharedString>,
}
impl ChatNotice {
pub fn new(message: impl Into<SharedString>) -> Self {
Self {
message: message.into(),
meta: None,
}
}
pub fn meta(mut self, meta: impl Into<SharedString>) -> Self {
self.meta = Some(meta.into());
self
}
}
impl RenderOnce for ChatNotice {
fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
h_flex()
.w_full()
.items_start()
.mt_4()
.gap_3()
.child(
// TODO: Replace with question mark.
Avatar::new("https://zed.dev/assistant_avatar.png").size(rems_from_px(20.)),
)
.child(
v_flex()
.size_full()
.gap_1()
.pr_4()
.overflow_hidden()
.child(
h_flex()
.justify_between()
.overflow_hidden()
.child(
h_flex()
.flex_none()
.overflow_hidden()
.child(Label::new(self.message)),
)
.child(
h_flex()
.flex_shrink_0()
.gap_1()
.child(Button::new("allow", "Allow"))
.child(
IconButton::new("deny", IconName::Close)
.shape(IconButtonShape::Square)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.icon_size(IconSize::XSmall),
),
),
)
.children(
self.meta.map(|meta| {
Label::new(meta).size(LabelSize::Small).color(Color::Muted)
}),
),
)
}
}

View File

@ -38,10 +38,10 @@ impl Composer {
impl RenderOnce for Composer {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let mut player_avatar = div().size(rems(20.0 / 16.0)).into_any_element();
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())
.size(rems(20.0 / 16.0))
.size(rems_from_px(20.))
.into_any_element();
}

View File

@ -1,3 +1,5 @@
mod chat_message;
mod chat_notice;
pub use chat_message::*;
pub use chat_notice::*;

View File

@ -0,0 +1,22 @@
use story::{StoryContainer, StoryItem, StorySection};
use ui::prelude::*;
use crate::ui::ChatNotice;
pub struct ChatNoticeStory;
impl Render for ChatNoticeStory {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
StoryContainer::new(
"ChatNotice Story",
"crates/assistant2/src/ui/stories/chat_notice.rs",
)
.child(
StorySection::new().child(StoryItem::new(
"Project index request",
ChatNotice::new("Allow assistant to index your project?")
.meta("Enabling will allow responses more relevant to this project."),
)),
)
}
}

View File

@ -13,6 +13,7 @@ use ui::prelude::*;
#[strum(serialize_all = "snake_case")]
pub enum ComponentStory {
AssistantChatMessage,
AssistantChatNotice,
AutoHeightEditor,
Avatar,
Button,
@ -46,6 +47,7 @@ impl ComponentStory {
Self::AssistantChatMessage => {
cx.new_view(|_cx| assistant2::ui::ChatMessageStory).into()
}
Self::AssistantChatNotice => cx.new_view(|_cx| assistant2::ui::ChatNoticeStory).into(),
Self::AutoHeightEditor => AutoHeightEditorStory::new(cx).into(),
Self::Avatar => cx.new_view(|_| ui::AvatarStory).into(),
Self::Button => cx.new_view(|_| ui::ButtonStory).into(),