collab_panel.rs

  1use std::marker::PhantomData;
  2
  3use gpui2::elements::{img, svg};
  4use gpui2::ArcCow;
  5
  6use crate::prelude::*;
  7use crate::theme::{theme, Theme};
  8use crate::{
  9    static_collab_panel_channels, static_collab_panel_current_call, v_stack, Icon, List,
 10    ListHeader, ToggleState,
 11};
 12
 13#[derive(Element)]
 14pub struct CollabPanel<V: 'static> {
 15    view_type: PhantomData<V>,
 16    scroll_state: ScrollState,
 17}
 18
 19impl<V: 'static> CollabPanel<V> {
 20    pub fn new(scroll_state: ScrollState) -> Self {
 21        Self {
 22            view_type: PhantomData,
 23            scroll_state,
 24        }
 25    }
 26
 27    fn render(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
 28        let theme = theme(cx);
 29
 30        v_stack()
 31            .w_64()
 32            .h_full()
 33            .fill(theme.middle.base.default.background)
 34            .child(
 35                v_stack()
 36                    .w_full()
 37                    .overflow_y_scroll(self.scroll_state.clone())
 38                    .child(
 39                        div()
 40                            .fill(theme.lowest.base.default.background)
 41                            .pb_1()
 42                            .border_color(theme.lowest.base.default.border)
 43                            .border_b()
 44                            .child(
 45                                List::new(static_collab_panel_current_call())
 46                                    .header(
 47                                        ListHeader::new("CRDB")
 48                                            .left_icon(Icon::Hash.into())
 49                                            .set_toggle(ToggleState::Toggled),
 50                                    )
 51                                    .set_toggle(ToggleState::Toggled),
 52                            ),
 53                    )
 54                    .child(
 55                        v_stack().py_1().child(
 56                            List::new(static_collab_panel_channels())
 57                                .header(
 58                                    ListHeader::new("CHANNELS").set_toggle(ToggleState::Toggled),
 59                                )
 60                                .empty_message("No channels yet. Add a channel to get started.")
 61                                .set_toggle(ToggleState::Toggled),
 62                        ),
 63                    )
 64                    .child(
 65                        v_stack().py_1().child(
 66                            List::new(static_collab_panel_current_call())
 67                                .header(
 68                                    ListHeader::new("CONTACTS – ONLINE")
 69                                        .set_toggle(ToggleState::Toggled),
 70                                )
 71                                .set_toggle(ToggleState::Toggled),
 72                        ),
 73                    )
 74                    .child(
 75                        v_stack().py_1().child(
 76                            List::new(static_collab_panel_current_call())
 77                                .header(
 78                                    ListHeader::new("CONTACTS – OFFLINE")
 79                                        .set_toggle(ToggleState::NotToggled),
 80                                )
 81                                .set_toggle(ToggleState::NotToggled),
 82                        ),
 83                    ),
 84            )
 85            .child(
 86                div()
 87                    .h_7()
 88                    .px_2()
 89                    .border_t()
 90                    .border_color(theme.middle.variant.default.border)
 91                    .flex()
 92                    .items_center()
 93                    .child(
 94                        div()
 95                            .text_sm()
 96                            .text_color(theme.middle.variant.default.foreground)
 97                            .child("Find..."),
 98                    ),
 99            )
100    }
101
102    fn list_section_header(
103        &self,
104        label: impl Into<ArcCow<'static, str>>,
105        expanded: bool,
106        theme: &Theme,
107    ) -> impl Element<V> {
108        div()
109            .h_7()
110            .px_2()
111            .flex()
112            .justify_between()
113            .items_center()
114            .child(div().flex().gap_1().text_sm().child(label))
115            .child(
116                div().flex().h_full().gap_1().items_center().child(
117                    svg()
118                        .path(if expanded {
119                            "icons/caret_down.svg"
120                        } else {
121                            "icons/caret_up.svg"
122                        })
123                        .w_3p5()
124                        .h_3p5()
125                        .fill(theme.middle.variant.default.foreground),
126                ),
127            )
128    }
129
130    fn list_item(
131        &self,
132        avatar_uri: impl Into<ArcCow<'static, str>>,
133        label: impl Into<ArcCow<'static, str>>,
134        theme: &Theme,
135    ) -> impl Element<V> {
136        div()
137            .h_7()
138            .px_2()
139            .flex()
140            .items_center()
141            .hover()
142            .fill(theme.lowest.variant.hovered.background)
143            .active()
144            .fill(theme.lowest.variant.pressed.background)
145            .child(
146                div()
147                    .flex()
148                    .items_center()
149                    .gap_1()
150                    .text_sm()
151                    .child(
152                        img()
153                            .uri(avatar_uri)
154                            .size_3p5()
155                            .rounded_full()
156                            .fill(theme.middle.positive.default.foreground),
157                    )
158                    .child(label),
159            )
160    }
161}