Render a user query editor in the contacts panel

Nathan Sobo created

Change summary

Cargo.lock                                  |  1 
assets/themes/cave-dark.json                | 28 +++++++++++++++++++++++
assets/themes/cave-light.json               | 28 +++++++++++++++++++++++
assets/themes/dark.json                     | 28 +++++++++++++++++++++++
assets/themes/light.json                    | 28 +++++++++++++++++++++++
assets/themes/solarized-dark.json           | 28 +++++++++++++++++++++++
assets/themes/solarized-light.json          | 28 +++++++++++++++++++++++
assets/themes/sulphurpool-dark.json         | 28 +++++++++++++++++++++++
assets/themes/sulphurpool-light.json        | 28 +++++++++++++++++++++++
crates/contacts_panel/Cargo.toml            |  1 
crates/contacts_panel/src/contacts_panel.rs | 25 +++++++++++++++++---
crates/theme/src/theme.rs                   |  1 
styles/src/styleTree/contactsPanel.ts       | 16 ++++++++++++
13 files changed, 263 insertions(+), 5 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -930,6 +930,7 @@ name = "contacts_panel"
 version = "0.1.0"
 dependencies = [
  "client",
+ "editor",
  "gpui",
  "postage",
  "settings",

assets/themes/cave-dark.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#19171c",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#e2dfe7",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#7e7887",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#576ddb",
+        "selection": "#576ddb3d"
+      },
+      "border": {
+        "color": "#26232a",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#655f6d",
     "tree_branch_width": 1,

assets/themes/cave-light.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#efecf4",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#26232a",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#655f6d",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#576ddb",
+        "selection": "#576ddb3d"
+      },
+      "border": {
+        "color": "#e2dfe7",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#7e7887",
     "tree_branch_width": 1,

assets/themes/dark.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#000000",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#f1f1f1",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#474747",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#2472f2",
+        "selection": "#2472f23d"
+      },
+      "border": {
+        "color": "#232323",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#404040",
     "tree_branch_width": 1,

assets/themes/light.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#ffffff",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#2b2b2b",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#808080",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#2472f2",
+        "selection": "#2472f23d"
+      },
+      "border": {
+        "color": "#d5d5d5",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#e3e3e3",
     "tree_branch_width": 1,

assets/themes/solarized-dark.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#002b36",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#eee8d5",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#839496",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#268bd2",
+        "selection": "#268bd23d"
+      },
+      "border": {
+        "color": "#073642",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#657b83",
     "tree_branch_width": 1,

assets/themes/solarized-light.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#fdf6e3",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#073642",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#657b83",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#268bd2",
+        "selection": "#268bd23d"
+      },
+      "border": {
+        "color": "#eee8d5",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#839496",
     "tree_branch_width": 1,

assets/themes/sulphurpool-dark.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#202746",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#dfe2f1",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#898ea4",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#3d8fd1",
+        "selection": "#3d8fd13d"
+      },
+      "border": {
+        "color": "#293256",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#6b7394",
     "tree_branch_width": 1,

assets/themes/sulphurpool-light.json 🔗

@@ -1212,6 +1212,34 @@
       "bottom": 12,
       "right": 12
     },
+    "user_query_editor": {
+      "background": "#f5f7ff",
+      "corner_radius": 6,
+      "text": {
+        "family": "Zed Mono",
+        "color": "#293256",
+        "size": 14
+      },
+      "placeholder_text": {
+        "family": "Zed Mono",
+        "color": "#6b7394",
+        "size": 14
+      },
+      "selection": {
+        "cursor": "#3d8fd1",
+        "selection": "#3d8fd13d"
+      },
+      "border": {
+        "color": "#dfe2f1",
+        "width": 1
+      },
+      "padding": {
+        "bottom": 7,
+        "left": 8,
+        "right": 8,
+        "top": 7
+      }
+    },
     "host_row_height": 28,
     "tree_branch_color": "#898ea4",
     "tree_branch_width": 1,

crates/contacts_panel/Cargo.toml 🔗

@@ -9,6 +9,7 @@ doctest = false
 
 [dependencies]
 client = { path = "../client" }
+editor = { path = "../editor" }
 gpui = { path = "../gpui" }
 settings = { path = "../settings" }
 theme = { path = "../theme" }

crates/contacts_panel/src/contacts_panel.rs 🔗

@@ -1,10 +1,11 @@
 use client::{Contact, UserStore};
+use editor::Editor;
 use gpui::{
     elements::*,
     geometry::{rect::RectF, vector::vec2f},
     platform::CursorStyle,
     Element, ElementBox, Entity, LayoutContext, ModelHandle, RenderContext, Subscription, View,
-    ViewContext,
+    ViewContext, ViewHandle,
 };
 use settings::Settings;
 use std::sync::Arc;
@@ -13,6 +14,7 @@ use workspace::{AppState, JoinProject};
 pub struct ContactsPanel {
     contacts: ListState,
     user_store: ModelHandle<UserStore>,
+    user_query_editor: ViewHandle<Editor>,
     _maintain_contacts: Subscription,
 }
 
@@ -38,6 +40,12 @@ impl ContactsPanel {
                     }
                 },
             ),
+            user_query_editor: cx.add_view(|cx| {
+                Editor::single_line(
+                    Some(|theme| theme.contacts_panel.user_query_editor.clone()),
+                    cx,
+                )
+            }),
             _maintain_contacts: cx.observe(&app_state.user_store, Self::update_contacts),
             user_store: app_state.user_store.clone(),
         }
@@ -237,8 +245,17 @@ impl View for ContactsPanel {
 
     fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
         let theme = &cx.global::<Settings>().theme.contacts_panel;
-        Container::new(List::new(self.contacts.clone()).boxed())
-            .with_style(theme.container)
-            .boxed()
+        Container::new(
+            Flex::column()
+                .with_child(
+                    Container::new(ChildView::new(self.user_query_editor.clone()).boxed())
+                        .with_style(theme.user_query_editor.container)
+                        .boxed(),
+                )
+                .with_child(List::new(self.contacts.clone()).flex(1., false).boxed())
+                .boxed(),
+        )
+        .with_style(theme.container)
+        .boxed()
     }
 }

crates/theme/src/theme.rs 🔗

@@ -234,6 +234,7 @@ pub struct CommandPalette {
 pub struct ContactsPanel {
     #[serde(flatten)]
     pub container: ContainerStyle,
+    pub user_query_editor: FieldEditor,
     pub host_row_height: f32,
     pub host_avatar: ImageStyle,
     pub host_username: ContainedText,

styles/src/styleTree/contactsPanel.ts 🔗

@@ -1,6 +1,6 @@
 import Theme from "../themes/theme";
 import { panel } from "./app";
-import { backgroundColor, borderColor, text } from "./components";
+import { backgroundColor, border, borderColor, player, text } from "./components";
 
 export default function(theme: Theme) {
   const project = {
@@ -33,6 +33,20 @@ export default function(theme: Theme) {
 
   return {
     ...panel,
+    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: 7,
+        left: 8,
+        right: 8,
+        top: 7,
+      },
+    },
     hostRowHeight: 28,
     treeBranchColor: borderColor(theme, "muted"),
     treeBranchWidth: 1,