Create channel adding modal

Mikayla Maki created

Change summary

crates/collab_ui/src/panel.rs           | 101 ++++++++++++++++++--------
crates/theme/src/theme.rs               |  13 ---
styles/src/style_tree/app.ts            |   2 
styles/src/style_tree/channels_panel.ts |  12 ---
styles/src/style_tree/collab_panel.ts   |   5 +
5 files changed, 76 insertions(+), 57 deletions(-)

Detailed changes

crates/collab_ui/src/panel.rs 🔗

@@ -1,3 +1,4 @@
+mod channel_modal;
 mod contact_finder;
 mod panel_settings;
 
@@ -16,7 +17,10 @@ use gpui::{
         Canvas, ChildView, Empty, Flex, Image, Label, List, ListOffset, ListState,
         MouseEventHandler, Orientation, Padding, ParentElement, Stack, Svg,
     },
-    geometry::{rect::RectF, vector::vec2f},
+    geometry::{
+        rect::RectF,
+        vector::vec2f,
+    },
     platform::{CursorStyle, MouseButton, PromptLevel},
     serde_json, AnyElement, AppContext, AsyncAppContext, Element, Entity, ModelHandle,
     Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle,
@@ -34,6 +38,8 @@ use workspace::{
     Workspace,
 };
 
+use self::channel_modal::ChannelModal;
+
 actions!(collab_panel, [ToggleFocus]);
 
 const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel";
@@ -41,6 +47,7 @@ const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel";
 pub fn init(_client: Arc<Client>, cx: &mut AppContext) {
     settings::register::<panel_settings::ChannelsPanelSettings>(cx);
     contact_finder::init(cx);
+    channel_modal::init(cx);
 
     cx.add_action(CollabPanel::cancel);
     cx.add_action(CollabPanel::select_next);
@@ -880,6 +887,7 @@ impl CollabPanel {
     ) -> AnyElement<Self> {
         enum Header {}
         enum LeaveCallContactList {}
+        enum AddChannel {}
 
         let tooltip_style = &theme.tooltip;
         let text = match section {
@@ -933,6 +941,22 @@ impl CollabPanel {
                     cx,
                 ),
             ),
+            Section::Channels => Some(
+                MouseEventHandler::<AddChannel, Self>::new(0, cx, |_, _| {
+                    render_icon_button(&theme.collab_panel.add_contact_button, "icons/plus_16.svg")
+                })
+                .with_cursor_style(CursorStyle::PointingHand)
+                .on_click(MouseButton::Left, |_, this, cx| {
+                    this.toggle_channel_finder(cx);
+                })
+                .with_tooltip::<AddChannel>(
+                    0,
+                    "Add or join a channel".into(),
+                    None,
+                    tooltip_style.clone(),
+                    cx,
+                ),
+            ),
             _ => None,
         };
 
@@ -1316,6 +1340,14 @@ impl CollabPanel {
         }
     }
 
+    fn toggle_channel_finder(&mut self, cx: &mut ViewContext<Self>) {
+        if let Some(workspace) = self.workspace.upgrade(cx) {
+            workspace.update(cx, |workspace, cx| {
+                workspace.toggle_modal(cx, |_, cx| cx.add_view(|cx| ChannelModal::new(cx)));
+            });
+        }
+    }
+
     fn remove_contact(&mut self, user_id: u64, github_login: &str, cx: &mut ViewContext<Self>) {
         let user_store = self.user_store.clone();
         let prompt_message = format!(
@@ -1388,36 +1420,43 @@ impl View for CollabPanel {
     fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement<Self> {
         let theme = &theme::current(cx).collab_panel;
 
-        Stack::new()
-            .with_child(
-                Flex::column()
-                    .with_child(
-                        Flex::row()
-                            .with_child(
-                                ChildView::new(&self.filter_editor, cx)
-                                    .contained()
-                                    .with_style(theme.user_query_editor.container)
-                                    .flex(1.0, true),
-                            )
-                            .constrained()
-                            .with_width(self.size(cx)),
-                    )
-                    .with_child(
-                        List::new(self.list_state.clone())
-                            .constrained()
-                            .with_width(self.size(cx))
-                            .flex(1., true)
-                            .into_any(),
-                    )
-                    .contained()
-                    .with_style(theme.container)
-                    .constrained()
-                    .with_width(self.size(cx))
-                    .into_any(),
-            )
-            .with_child(ChildView::new(&self.context_menu, cx))
-            .into_any_named("channels panel")
-            .into_any()
+        enum PanelFocus {}
+        MouseEventHandler::<PanelFocus, _>::new(0, cx, |_, cx| {
+            Stack::new()
+                .with_child(
+                    Flex::column()
+                        .with_child(
+                            Flex::row()
+                                .with_child(
+                                    ChildView::new(&self.filter_editor, cx)
+                                        .contained()
+                                        .with_style(theme.user_query_editor.container)
+                                        .flex(1.0, true),
+                                )
+                                .constrained()
+                                .with_width(self.size(cx)),
+                        )
+                        .with_child(
+                            List::new(self.list_state.clone())
+                                .constrained()
+                                .with_width(self.size(cx))
+                                .flex(1., true)
+                                .into_any(),
+                        )
+                        .contained()
+                        .with_style(theme.container)
+                        .constrained()
+                        .with_width(self.size(cx))
+                        .into_any(),
+                )
+                .with_child(ChildView::new(&self.context_menu, cx))
+                .into_any()
+        })
+        .on_click(MouseButton::Left, |_, v, cx| {
+            cx.focus_self()
+        })
+        .into_any_named("channels panel")
+
     }
 }
 

crates/theme/src/theme.rs 🔗

@@ -47,7 +47,6 @@ pub struct Theme {
     pub copilot: Copilot,
     pub collab_panel: CollabPanel,
     pub project_panel: ProjectPanel,
-    pub channels_panel: ChanelsPanelStyle,
     pub command_palette: CommandPalette,
     pub contact_finder: ContactFinder,
     pub picker: Picker,
@@ -225,6 +224,7 @@ pub struct CollabPanel {
     pub user_query_editor_height: f32,
     pub leave_call_button: IconButton,
     pub add_contact_button: IconButton,
+    pub add_channel_button: IconButton,
     pub header_row: ContainedText,
     pub subheader_row: Toggleable<Interactive<ContainedText>>,
     pub leave_call: Interactive<ContainedText>,
@@ -1064,17 +1064,6 @@ pub struct Contained<T> {
     contained: T,
 }
 
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FlexStyle {
-    // Between item spacing
-    item_spacing: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ChanelsPanelStyle {
-    pub contacts_header: TextStyle,
-}
-
 #[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct SavedConversation {
     pub container: Interactive<ContainerStyle>,

styles/src/style_tree/app.ts 🔗

@@ -23,7 +23,6 @@ import { titlebar } from "./titlebar"
 import editor from "./editor"
 import feedback from "./feedback"
 import { useTheme } from "../common"
-import channels_panel from "./channels_panel"
 
 export default function app(): any {
     const theme = useTheme()
@@ -46,7 +45,6 @@ export default function app(): any {
         editor: editor(),
         project_diagnostics: project_diagnostics(),
         project_panel: project_panel(),
-        channels_panel: channels_panel(),
         collab_panel: collab_panel(),
         contact_finder: contact_finder(),
         toolbar_dropdown_menu: toolbar_dropdown_menu(),

styles/src/style_tree/channels_panel.ts 🔗

@@ -1,12 +0,0 @@
-import {
-    text,
-} from "./components"
-import { useTheme } from "../theme"
-export default function channels_panel(): any {
-    const theme = useTheme()
-
-
-    return {
-        contacts_header: text(theme.middle, "sans", "variant", { size: "lg" }),
-    }
-}

styles/src/style_tree/collab_panel.ts 🔗

@@ -80,6 +80,11 @@ export default function contacts_panel(): any {
             button_width: 28,
             icon_width: 16,
         },
+        add_channel_button: {
+            color: foreground(layer, "on"),
+            button_width: 28,
+            icon_width: 16,
+        },
         leave_call_button: {
             color: foreground(layer, "on"),
             button_width: 28,