Move contacts panel styles into contacts popover

Antonio Scandurra created

Change summary

crates/collab_ui/src/contacts_popover.rs           |  36 +-
crates/collab_ui/src/incoming_call_notification.rs |   6 
crates/theme/src/theme.rs                          |  45 +--
styles/src/styleTree/contactsPanel.ts              | 165 ----------------
styles/src/styleTree/contactsPopover.ts            | 161 +++++++++++++++
styles/src/styleTree/workspace.ts                  |  10 
6 files changed, 198 insertions(+), 225 deletions(-)

Detailed changes

crates/collab_ui/src/contacts_popover.rs 🔗

@@ -118,7 +118,7 @@ impl ContactsPopover {
     ) -> Self {
         let filter_editor = cx.add_view(|cx| {
             let mut editor = Editor::single_line(
-                Some(|theme| theme.contacts_panel.user_query_editor.clone()),
+                Some(|theme| theme.contacts_popover.user_query_editor.clone()),
                 cx,
             );
             editor.set_placeholder_text("Filter contacts", cx);
@@ -151,7 +151,7 @@ impl ContactsPopover {
                     let is_collapsed = this.collapsed_sections.contains(section);
                     Self::render_header(
                         *section,
-                        &theme.contacts_panel,
+                        &theme.contacts_popover,
                         is_selected,
                         is_collapsed,
                         cx,
@@ -160,7 +160,7 @@ impl ContactsPopover {
                 ContactEntry::IncomingRequest(user) => Self::render_contact_request(
                     user.clone(),
                     this.user_store.clone(),
-                    &theme.contacts_panel,
+                    &theme.contacts_popover,
                     true,
                     is_selected,
                     cx,
@@ -168,7 +168,7 @@ impl ContactsPopover {
                 ContactEntry::OutgoingRequest(user) => Self::render_contact_request(
                     user.clone(),
                     this.user_store.clone(),
-                    &theme.contacts_panel,
+                    &theme.contacts_popover,
                     false,
                     is_selected,
                     cx,
@@ -176,7 +176,7 @@ impl ContactsPopover {
                 ContactEntry::Contact(contact) => Self::render_contact(
                     contact,
                     &this.project,
-                    &theme.contacts_panel,
+                    &theme.contacts_popover,
                     is_selected,
                     cx,
                 ),
@@ -418,7 +418,7 @@ impl ContactsPopover {
 
     fn render_active_call(&self, cx: &mut RenderContext<Self>) -> Option<ElementBox> {
         let room = ActiveCall::global(cx).read(cx).room()?;
-        let theme = &cx.global::<Settings>().theme.contacts_panel;
+        let theme = &cx.global::<Settings>().theme.contacts_popover;
 
         Some(
             Flex::column()
@@ -455,7 +455,7 @@ impl ContactsPopover {
 
     fn render_header(
         section: Section,
-        theme: &theme::ContactsPanel,
+        theme: &theme::ContactsPopover,
         is_selected: bool,
         is_collapsed: bool,
         cx: &mut RenderContext<Self>,
@@ -511,7 +511,7 @@ impl ContactsPopover {
     fn render_contact(
         contact: &Contact,
         project: &ModelHandle<Project>,
-        theme: &theme::ContactsPanel,
+        theme: &theme::ContactsPopover,
         is_selected: bool,
         cx: &mut RenderContext<Self>,
     ) -> ElementBox {
@@ -565,7 +565,7 @@ impl ContactsPopover {
     fn render_contact_request(
         user: Arc<User>,
         user_store: ModelHandle<UserStore>,
-        theme: &theme::ContactsPanel,
+        theme: &theme::ContactsPopover,
         is_incoming: bool,
         is_selected: bool,
         cx: &mut RenderContext<Self>,
@@ -705,18 +705,18 @@ impl View for ContactsPopover {
                     .with_child(
                         ChildView::new(self.filter_editor.clone())
                             .contained()
-                            .with_style(theme.contacts_panel.user_query_editor.container)
+                            .with_style(theme.contacts_popover.user_query_editor.container)
                             .flex(1., true)
                             .boxed(),
                     )
                     .with_child(
                         MouseEventHandler::<AddContact>::new(0, cx, |_, _| {
                             Svg::new("icons/user_plus_16.svg")
-                                .with_color(theme.contacts_panel.add_contact_button.color)
+                                .with_color(theme.contacts_popover.add_contact_button.color)
                                 .constrained()
                                 .with_height(16.)
                                 .contained()
-                                .with_style(theme.contacts_panel.add_contact_button.container)
+                                .with_style(theme.contacts_popover.add_contact_button.container)
                                 .aligned()
                                 .boxed()
                         })
@@ -727,7 +727,7 @@ impl View for ContactsPopover {
                         .boxed(),
                     )
                     .constrained()
-                    .with_height(theme.contacts_panel.user_query_editor_height)
+                    .with_height(theme.contacts_popover.user_query_editor_height)
                     .boxed(),
             )
             .with_children(self.render_active_call(cx))
@@ -744,7 +744,7 @@ impl View for ContactsPopover {
                             Some(
                                 MouseEventHandler::<InviteLink>::new(0, cx, |state, cx| {
                                     let style = theme
-                                        .contacts_panel
+                                        .contacts_popover
                                         .invite_row
                                         .style_for(state, false)
                                         .clone();
@@ -764,7 +764,7 @@ impl View for ContactsPopover {
                                     .aligned()
                                     .left()
                                     .constrained()
-                                    .with_height(theme.contacts_panel.row_height)
+                                    .with_height(theme.contacts_popover.row_height)
                                     .contained()
                                     .with_style(style.container)
                                     .boxed()
@@ -782,10 +782,10 @@ impl View for ContactsPopover {
                     }),
             )
             .contained()
-            .with_style(theme.workspace.titlebar.contacts_popover.container)
+            .with_style(theme.contacts_popover.container)
             .constrained()
-            .with_width(theme.workspace.titlebar.contacts_popover.width)
-            .with_height(theme.workspace.titlebar.contacts_popover.height)
+            .with_width(theme.contacts_popover.width)
+            .with_height(theme.contacts_popover.height)
             .boxed()
     }
 

crates/collab_ui/src/incoming_call_notification.rs 🔗

@@ -82,7 +82,7 @@ impl IncomingCallNotification {
     }
 
     fn render_caller(&self, cx: &mut RenderContext<Self>) -> ElementBox {
-        let theme = &cx.global::<Settings>().theme.contacts_panel;
+        let theme = &cx.global::<Settings>().theme.contacts_popover;
         Flex::row()
             .with_children(
                 self.call
@@ -108,7 +108,7 @@ impl IncomingCallNotification {
         Flex::row()
             .with_child(
                 MouseEventHandler::<Accept>::new(0, cx, |_, cx| {
-                    let theme = &cx.global::<Settings>().theme.contacts_panel;
+                    let theme = &cx.global::<Settings>().theme.contacts_popover;
                     Label::new("Accept".to_string(), theme.contact_username.text.clone()).boxed()
                 })
                 .on_click(MouseButton::Left, |_, cx| {
@@ -118,7 +118,7 @@ impl IncomingCallNotification {
             )
             .with_child(
                 MouseEventHandler::<Decline>::new(0, cx, |_, cx| {
-                    let theme = &cx.global::<Settings>().theme.contacts_panel;
+                    let theme = &cx.global::<Settings>().theme.contacts_popover;
                     Label::new("Decline".to_string(), theme.contact_username.text.clone()).boxed()
                 })
                 .on_click(MouseButton::Left, |_, cx| {

crates/theme/src/theme.rs 🔗

@@ -19,7 +19,7 @@ pub struct Theme {
     pub workspace: Workspace,
     pub context_menu: ContextMenu,
     pub chat_panel: ChatPanel,
-    pub contacts_panel: ContactsPanel,
+    pub contacts_popover: ContactsPopover,
     pub contact_finder: ContactFinder,
     pub project_panel: ProjectPanel,
     pub command_palette: CommandPalette,
@@ -79,15 +79,30 @@ pub struct Titlebar {
     pub share_button: Interactive<ContainedText>,
     pub toggle_contacts_button: Interactive<IconButton>,
     pub toggle_contacts_badge: ContainerStyle,
-    pub contacts_popover: AddParticipantPopover,
 }
 
-#[derive(Clone, Deserialize, Default)]
-pub struct AddParticipantPopover {
+#[derive(Deserialize, Default)]
+pub struct ContactsPopover {
     #[serde(flatten)]
     pub container: ContainerStyle,
     pub height: f32,
     pub width: f32,
+    pub user_query_editor: FieldEditor,
+    pub user_query_editor_height: f32,
+    pub add_contact_button: IconButton,
+    pub header_row: Interactive<ContainedText>,
+    pub contact_row: Interactive<ContainerStyle>,
+    pub project_row: Interactive<ProjectRow>,
+    pub row_height: f32,
+    pub contact_avatar: ImageStyle,
+    pub contact_username: ContainedText,
+    pub contact_button: Interactive<IconButton>,
+    pub contact_button_spacing: f32,
+    pub disabled_button: IconButton,
+    pub tree_branch: Interactive<TreeBranch>,
+    pub private_button: Interactive<IconButton>,
+    pub section_icon_size: f32,
+    pub invite_row: Interactive<ContainedLabel>,
 }
 
 #[derive(Clone, Deserialize, Default)]
@@ -329,28 +344,6 @@ pub struct CommandPalette {
     pub keystroke_spacing: f32,
 }
 
-#[derive(Deserialize, Default)]
-pub struct ContactsPanel {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub user_query_editor: FieldEditor,
-    pub user_query_editor_height: f32,
-    pub add_contact_button: IconButton,
-    pub header_row: Interactive<ContainedText>,
-    pub contact_row: Interactive<ContainerStyle>,
-    pub project_row: Interactive<ProjectRow>,
-    pub row_height: f32,
-    pub contact_avatar: ImageStyle,
-    pub contact_username: ContainedText,
-    pub contact_button: Interactive<IconButton>,
-    pub contact_button_spacing: f32,
-    pub disabled_button: IconButton,
-    pub tree_branch: Interactive<TreeBranch>,
-    pub private_button: Interactive<IconButton>,
-    pub section_icon_size: f32,
-    pub invite_row: Interactive<ContainedLabel>,
-}
-
 #[derive(Deserialize, Default)]
 pub struct InviteLink {
     #[serde(flatten)]

styles/src/styleTree/contactsPanel.ts 🔗

@@ -1,165 +0,0 @@
-import Theme from "../themes/common/theme";
-import { panel } from "./app";
-import {
-  backgroundColor,
-  border,
-  borderColor,
-  iconColor,
-  player,
-  text,
-} from "./components";
-
-export default function contactsPanel(theme: Theme) {
-  const nameMargin = 8;
-  const sidePadding = 12;
-
-  const projectRow = {
-    guestAvatarSpacing: 4,
-    height: 24,
-    guestAvatar: {
-      cornerRadius: 8,
-      width: 14,
-    },
-    name: {
-      ...text(theme, "mono", "placeholder", { size: "sm" }),
-      margin: {
-        left: nameMargin,
-        right: 6,
-      },
-    },
-    guests: {
-      margin: {
-        left: nameMargin,
-        right: nameMargin,
-      },
-    },
-    padding: {
-      left: sidePadding,
-      right: sidePadding,
-    },
-  };
-
-  const contactButton = {
-    background: backgroundColor(theme, 100),
-    color: iconColor(theme, "primary"),
-    iconWidth: 8,
-    buttonWidth: 16,
-    cornerRadius: 8,
-  };
-
-  return {
-    ...panel,
-    padding: { top: panel.padding.top, bottom: 0 },
-    userQueryEditor: {
-      background: backgroundColor(theme, 500),
-      cornerRadius: 6,
-      text: text(theme, "mono", "primary"),
-      placeholderText: text(theme, "mono", "placeholder", { size: "sm" }),
-      selection: player(theme, 1).selection,
-      border: border(theme, "secondary"),
-      padding: {
-        bottom: 4,
-        left: 8,
-        right: 8,
-        top: 4,
-      },
-      margin: {
-        left: sidePadding,
-        right: sidePadding,
-      },
-    },
-    userQueryEditorHeight: 32,
-    addContactButton: {
-      margin: { left: 6, right: 12 },
-      color: iconColor(theme, "primary"),
-      buttonWidth: 16,
-      iconWidth: 16,
-    },
-    privateButton: {
-      iconWidth: 12,
-      color: iconColor(theme, "primary"),
-      cornerRadius: 5,
-      buttonWidth: 12,
-    },
-    rowHeight: 28,
-    sectionIconSize: 8,
-    headerRow: {
-      ...text(theme, "mono", "secondary", { size: "sm" }),
-      margin: { top: 14 },
-      padding: {
-        left: sidePadding,
-        right: sidePadding,
-      },
-      active: {
-        ...text(theme, "mono", "primary", { size: "sm" }),
-        background: backgroundColor(theme, 100, "active"),
-      },
-    },
-    contactRow: {
-      padding: {
-        left: sidePadding,
-        right: sidePadding,
-      },
-      active: {
-        background: backgroundColor(theme, 100, "active"),
-      },
-    },
-    treeBranch: {
-      color: borderColor(theme, "active"),
-      width: 1,
-      hover: {
-        color: borderColor(theme, "active"),
-      },
-      active: {
-        color: borderColor(theme, "active"),
-      },
-    },
-    contactAvatar: {
-      cornerRadius: 10,
-      width: 18,
-    },
-    contactUsername: {
-      ...text(theme, "mono", "primary", { size: "sm" }),
-      margin: {
-        left: nameMargin,
-      },
-    },
-    contactButtonSpacing: nameMargin,
-    contactButton: {
-      ...contactButton,
-      hover: {
-        background: backgroundColor(theme, "on300", "hovered"),
-      },
-    },
-    disabledButton: {
-      ...contactButton,
-      background: backgroundColor(theme, 100),
-      color: iconColor(theme, "muted"),
-    },
-    projectRow: {
-      ...projectRow,
-      background: backgroundColor(theme, 300),
-      name: {
-        ...projectRow.name,
-        ...text(theme, "mono", "secondary", { size: "sm" }),
-      },
-      hover: {
-        background: backgroundColor(theme, 300, "hovered"),
-      },
-      active: {
-        background: backgroundColor(theme, 300, "active"),
-      },
-    },
-    inviteRow: {
-      padding: {
-        left: sidePadding,
-        right: sidePadding,
-      },
-      border: { top: true, width: 1, color: borderColor(theme, "primary") },
-      text: text(theme, "sans", "secondary", { size: "sm" }),
-      hover: {
-        text: text(theme, "sans", "active", { size: "sm" }),
-      },
-    },
-  };
-}

styles/src/styleTree/contactsPopover.ts 🔗

@@ -1,8 +1,163 @@
 import Theme from "../themes/common/theme";
-import { backgroundColor } from "./components";
+import { backgroundColor, border, borderColor, iconColor, player, popoverShadow, text } from "./components";
+
+export default function contactsPopover(theme: Theme) {
+  const nameMargin = 8;
+  const sidePadding = 12;
+
+  const projectRow = {
+    guestAvatarSpacing: 4,
+    height: 24,
+    guestAvatar: {
+      cornerRadius: 8,
+      width: 14,
+    },
+    name: {
+      ...text(theme, "mono", "placeholder", { size: "sm" }),
+      margin: {
+        left: nameMargin,
+        right: 6,
+      },
+    },
+    guests: {
+      margin: {
+        left: nameMargin,
+        right: nameMargin,
+      },
+    },
+    padding: {
+      left: sidePadding,
+      right: sidePadding,
+    },
+  };
+
+  const contactButton = {
+    background: backgroundColor(theme, 100),
+    color: iconColor(theme, "primary"),
+    iconWidth: 8,
+    buttonWidth: 16,
+    cornerRadius: 8,
+  };
 
-export default function workspace(theme: Theme) {
   return {
-    background: backgroundColor(theme, 300),
+    background: backgroundColor(theme, 300, "base"),
+    cornerRadius: 6,
+    padding: { top: 6 },
+    shadow: popoverShadow(theme),
+    border: border(theme, "primary"),
+    margin: { top: -5 },
+    width: 250,
+    height: 300,
+    userQueryEditor: {
+      background: backgroundColor(theme, 500),
+      cornerRadius: 6,
+      text: text(theme, "mono", "primary"),
+      placeholderText: text(theme, "mono", "placeholder", { size: "sm" }),
+      selection: player(theme, 1).selection,
+      border: border(theme, "secondary"),
+      padding: {
+        bottom: 4,
+        left: 8,
+        right: 8,
+        top: 4,
+      },
+      margin: {
+        left: sidePadding,
+        right: sidePadding,
+      },
+    },
+    userQueryEditorHeight: 32,
+    addContactButton: {
+      margin: { left: 6, right: 12 },
+      color: iconColor(theme, "primary"),
+      buttonWidth: 16,
+      iconWidth: 16,
+    },
+    privateButton: {
+      iconWidth: 12,
+      color: iconColor(theme, "primary"),
+      cornerRadius: 5,
+      buttonWidth: 12,
+    },
+    rowHeight: 28,
+    sectionIconSize: 8,
+    headerRow: {
+      ...text(theme, "mono", "secondary", { size: "sm" }),
+      margin: { top: 14 },
+      padding: {
+        left: sidePadding,
+        right: sidePadding,
+      },
+      active: {
+        ...text(theme, "mono", "primary", { size: "sm" }),
+        background: backgroundColor(theme, 100, "active"),
+      },
+    },
+    contactRow: {
+      padding: {
+        left: sidePadding,
+        right: sidePadding,
+      },
+      active: {
+        background: backgroundColor(theme, 100, "active"),
+      },
+    },
+    treeBranch: {
+      color: borderColor(theme, "active"),
+      width: 1,
+      hover: {
+        color: borderColor(theme, "active"),
+      },
+      active: {
+        color: borderColor(theme, "active"),
+      },
+    },
+    contactAvatar: {
+      cornerRadius: 10,
+      width: 18,
+    },
+    contactUsername: {
+      ...text(theme, "mono", "primary", { size: "sm" }),
+      margin: {
+        left: nameMargin,
+      },
+    },
+    contactButtonSpacing: nameMargin,
+    contactButton: {
+      ...contactButton,
+      hover: {
+        background: backgroundColor(theme, "on300", "hovered"),
+      },
+    },
+    disabledButton: {
+      ...contactButton,
+      background: backgroundColor(theme, 100),
+      color: iconColor(theme, "muted"),
+    },
+    projectRow: {
+      ...projectRow,
+      background: backgroundColor(theme, 300),
+      name: {
+        ...projectRow.name,
+        ...text(theme, "mono", "secondary", { size: "sm" }),
+      },
+      hover: {
+        background: backgroundColor(theme, 300, "hovered"),
+      },
+      active: {
+        background: backgroundColor(theme, 300, "active"),
+      },
+    },
+    inviteRow: {
+      padding: {
+        left: sidePadding,
+        right: sidePadding,
+      },
+      border: { top: true, width: 1, color: borderColor(theme, "primary") },
+      text: text(theme, "sans", "secondary", { size: "sm" }),
+      hover: {
+        text: text(theme, "sans", "active", { size: "sm" }),
+      },
+    },
   }
 }

styles/src/styleTree/workspace.ts 🔗

@@ -153,16 +153,6 @@ export default function workspace(theme: Theme) {
       },
       shareButton: {
         ...titlebarButton
-      },
-      contactsPopover: {
-        background: backgroundColor(theme, 300, "base"),
-        cornerRadius: 6,
-        padding: { top: 6 },
-        shadow: popoverShadow(theme),
-        border: border(theme, "primary"),
-        margin: { top: -5 },
-        width: 250,
-        height: 300
       }
     },
     toolbar: {