Add placeholder implementation

Mikayla created

Change summary

crates/collab_ui/src/collab_panel.rs  | 23 +++++++++++++++++++++++
crates/theme/src/theme.rs             |  1 +
styles/src/style_tree/collab_panel.ts |  4 ++++
3 files changed, 28 insertions(+)

Detailed changes

crates/collab_ui/src/collab_panel.rs 🔗

@@ -200,6 +200,7 @@ enum ListEntry {
         contact: Arc<Contact>,
         calling: bool,
     },
+    ContactPlaceholder,
 }
 
 impl Entity for CollabPanel {
@@ -368,6 +369,9 @@ impl CollabPanel {
                         ListEntry::ChannelEditor { depth } => {
                             this.render_channel_editor(&theme, *depth, cx)
                         }
+                        ListEntry::ContactPlaceholder => {
+                            this.render_contact_placeholder(&theme.collab_panel)
+                        }
                     }
                 });
 
@@ -821,6 +825,10 @@ impl CollabPanel {
             }
         }
 
+        if incoming.is_empty() && outgoing.is_empty() && contacts.is_empty() {
+            self.entries.push(ListEntry::ContactPlaceholder);
+        }
+
         if select_same_item {
             if let Some(prev_selected_entry) = prev_selected_entry {
                 self.selection.take();
@@ -1394,6 +1402,16 @@ impl CollabPanel {
         event_handler.into_any()
     }
 
+    fn render_contact_placeholder(&self, theme: &theme::CollabPanel) -> AnyElement<Self> {
+        Label::new(
+            "Add contacts to begin collaborating",
+            theme.placeholder.text.clone(),
+        )
+        .contained()
+        .with_style(theme.placeholder.container)
+        .into_any()
+    }
+
     fn render_channel_editor(
         &self,
         theme: &theme::Theme,
@@ -2385,6 +2403,11 @@ impl PartialEq for ListEntry {
                     return depth == other_depth;
                 }
             }
+            ListEntry::ContactPlaceholder => {
+                if let ListEntry::ContactPlaceholder = other {
+                    return true;
+                }
+            }
         }
         false
     }

crates/theme/src/theme.rs 🔗

@@ -220,6 +220,7 @@ pub struct CopilotAuthAuthorized {
 pub struct CollabPanel {
     #[serde(flatten)]
     pub container: ContainerStyle,
+    pub placeholder: ContainedText,
     pub log_in_button: Interactive<ContainedText>,
     pub channel_editor: ContainerStyle,
     pub channel_hash: Icon,

styles/src/style_tree/collab_panel.ts 🔗

@@ -110,6 +110,10 @@ export default function contacts_panel(): any {
 
     return {
         channel_modal: channel_modal(),
+        placeholder: {
+            ...text(theme.middle, "sans", "default", { size: "sm" }),
+            padding: 5,
+        },
         log_in_button: interactive({
             base: {
                 background: background(theme.middle),