assistant_panel.rs

  1use std::marker::PhantomData;
  2
  3use gpui3::{rems, AbsoluteLength};
  4
  5use crate::prelude::*;
  6use crate::{Icon, IconButton, Label, Panel, PanelSide};
  7
  8#[derive(Element)]
  9pub struct AssistantPanel<S: 'static + Send + Sync + Clone> {
 10    state_type: PhantomData<S>,
 11    scroll_state: ScrollState,
 12    current_side: PanelSide,
 13}
 14
 15impl<S: 'static + Send + Sync + Clone> AssistantPanel<S> {
 16    pub fn new() -> Self {
 17        Self {
 18            state_type: PhantomData,
 19            scroll_state: ScrollState::default(),
 20            current_side: PanelSide::default(),
 21        }
 22    }
 23
 24    pub fn side(mut self, side: PanelSide) -> Self {
 25        self.current_side = side;
 26        self
 27    }
 28
 29    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
 30        let theme = theme(cx);
 31
 32        struct PanelPayload {
 33            pub scroll_state: ScrollState,
 34        }
 35
 36        Panel::new(
 37            self.scroll_state.clone(),
 38            |_, payload| {
 39                let payload = payload.downcast_ref::<PanelPayload>().unwrap();
 40
 41                vec![div()
 42                    .flex()
 43                    .flex_col()
 44                    .h_full()
 45                    .px_2()
 46                    .gap_2()
 47                    // Header
 48                    .child(
 49                        div()
 50                            .flex()
 51                            .justify_between()
 52                            .gap_2()
 53                            .child(
 54                                div()
 55                                    .flex()
 56                                    .child(IconButton::new(Icon::Menu))
 57                                    .child(Label::new("New Conversation")),
 58                            )
 59                            .child(
 60                                div()
 61                                    .flex()
 62                                    .items_center()
 63                                    .gap_px()
 64                                    .child(IconButton::new(Icon::SplitMessage))
 65                                    .child(IconButton::new(Icon::Quote))
 66                                    .child(IconButton::new(Icon::MagicWand))
 67                                    .child(IconButton::new(Icon::Plus))
 68                                    .child(IconButton::new(Icon::Maximize)),
 69                            ),
 70                    )
 71                    // Chat Body
 72                    .child(
 73                        div()
 74                            .w_full()
 75                            .flex()
 76                            .flex_col()
 77                            .gap_3()
 78                            .overflow_y_scroll(payload.scroll_state.clone())
 79                            .child(Label::new("Is this thing on?")),
 80                    )
 81                    .into_any()]
 82            },
 83            Box::new(PanelPayload {
 84                scroll_state: self.scroll_state.clone(),
 85            }),
 86        )
 87        .side(self.current_side)
 88        .width(AbsoluteLength::Rems(rems(32.)))
 89    }
 90}
 91
 92#[cfg(feature = "stories")]
 93pub use stories::*;
 94
 95#[cfg(feature = "stories")]
 96mod stories {
 97    use crate::Story;
 98
 99    use super::*;
100
101    #[derive(Element)]
102    pub struct AssistantPanelStory<S: 'static + Send + Sync + Clone> {
103        state_type: PhantomData<S>,
104    }
105
106    impl<S: 'static + Send + Sync + Clone> AssistantPanelStory<S> {
107        pub fn new() -> Self {
108            Self {
109                state_type: PhantomData,
110            }
111        }
112
113        fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
114            Story::container(cx)
115                .child(Story::title_for::<_, AssistantPanel<S>>(cx))
116                .child(Story::label(cx, "Default"))
117                .child(AssistantPanel::new())
118        }
119    }
120}