WIP

Joseph Lyons and Mikayla Maki created

Don't rely on contacts popover or contacts list for theming
Add metrics id to request body
Clean up some code and comments

Co-Authored-By: Mikayla Maki <mikayla.c.maki@gmail.com>

Change summary

crates/client/src/client.rs        |  4 ++
crates/client/src/telemetry.rs     |  4 ++
crates/theme/src/theme.rs          | 30 ++++++++---------
crates/zed/src/feedback_popover.rs | 54 +++++++++++--------------------
crates/zed/src/main.rs             |  2 
styles/src/styleTree/app.ts        |  2 +
styles/src/styleTree/feedback.ts   | 35 ++++++++++++++++++++
7 files changed, 80 insertions(+), 51 deletions(-)

Detailed changes

crates/client/src/client.rs 🔗

@@ -1294,6 +1294,10 @@ impl Client {
     pub fn telemetry_log_file_path(&self) -> Option<PathBuf> {
         self.telemetry.log_file_path()
     }
+
+    pub fn metrics_id(&self) -> Option<Arc<str>> {
+        self.telemetry.metrics_id()
+    }
 }
 
 impl WeakSubscriber {

crates/client/src/telemetry.rs 🔗

@@ -261,6 +261,10 @@ impl Telemetry {
         }
     }
 
+    pub fn metrics_id(self: &Arc<Self>) -> Option<Arc<str>> {
+        self.state.lock().metrics_id.clone()
+    }
+
     fn flush(self: &Arc<Self>) {
         let mut state = self.state.lock();
         let mut events = mem::take(&mut state.queue);

crates/theme/src/theme.rs 🔗

@@ -25,7 +25,7 @@ pub struct Theme {
     pub command_palette: CommandPalette,
     pub picker: Picker,
     pub editor: Editor,
-    // pub feedback_box: Editor,
+    pub feedback: Feedback,
     pub search: Search,
     pub project_diagnostics: ProjectDiagnostics,
     pub breadcrumbs: ContainedText,
@@ -120,21 +120,19 @@ pub struct ContactList {
     pub calling_indicator: ContainedText,
 }
 
-// TODO FEEDBACK: Remove or use this
-// #[derive(Deserialize, Default)]
-// pub struct FeedbackPopover {
-//     #[serde(flatten)]
-//     pub container: ContainerStyle,
-//     pub height: f32,
-//     pub width: f32,
-//     pub invite_row_height: f32,
-//     pub invite_row: Interactive<ContainedLabel>,
-// }
-
-// #[derive(Deserialize, Default)]
-// pub struct FeedbackBox {
-//     pub feedback_editor: FieldEditor,
-// }
+#[derive(Deserialize, Default)]
+pub struct Feedback {
+    pub feedback_popover: FeedbackPopover,
+    pub feedback_editor: FieldEditor,
+}
+
+#[derive(Deserialize, Default)]
+pub struct FeedbackPopover {
+    #[serde(flatten)]
+    pub container: ContainerStyle,
+    pub height: f32,
+    pub width: f32,
+}
 
 #[derive(Deserialize, Default)]
 pub struct ProjectRow {

crates/zed/src/feedback_popover.rs 🔗

@@ -1,7 +1,7 @@
 use std::{ops::Range, sync::Arc};
 
 use anyhow::bail;
-use client::{http::HttpClient, ZED_SECRET_CLIENT_TOKEN};
+use client::{Client, ZED_SECRET_CLIENT_TOKEN};
 use editor::Editor;
 use futures::AsyncReadExt;
 use gpui::{
@@ -93,19 +93,11 @@ impl View for FeedbackButton {
                 .boxed(),
             )
             .with_children(self.feedback_popover.as_ref().map(|popover| {
-                Overlay::new(
-                    ChildView::new(popover, cx)
-                        .contained()
-                        // .with_height(theme.contact_list.user_query_editor_height)
-                        // .with_margin_top(-50.0)
-                        // .with_margin_left(titlebar.toggle_contacts_button.default.button_width)
-                        // .with_margin_right(-titlebar.toggle_contacts_button.default.button_width)
-                        .boxed(),
-                )
-                .with_fit_mode(OverlayFitMode::SwitchAnchor)
-                .with_anchor_corner(AnchorCorner::TopLeft)
-                .with_z_index(999)
-                .boxed()
+                Overlay::new(ChildView::new(popover, cx).contained().boxed())
+                    .with_fit_mode(OverlayFitMode::SwitchAnchor)
+                    .with_anchor_corner(AnchorCorner::TopLeft)
+                    .with_z_index(999)
+                    .boxed()
             }))
             .boxed()
     }
@@ -142,9 +134,7 @@ impl FeedbackPopover {
     pub fn new(cx: &mut ViewContext<Self>) -> Self {
         let feedback_editor = cx.add_view(|cx| {
             let editor = Editor::multi_line(
-                Some(Arc::new(|theme| {
-                    theme.contact_list.user_query_editor.clone()
-                })),
+                Some(Arc::new(|theme| theme.feedback.feedback_editor.clone())),
                 cx,
             );
             editor
@@ -174,19 +164,20 @@ impl FeedbackPopover {
 
     fn submit_feedback(&mut self, _: &SubmitFeedback, cx: &mut ViewContext<'_, Self>) {
         let feedback_text = self.feedback_editor.read(cx).text(cx);
-        let http_client = cx.global::<Arc<dyn HttpClient>>().clone();
+        let zed_client = cx.global::<Arc<Client>>();
         let system_specs = SystemSpecs::new(cx);
         let feedback_endpoint = format!("{}/api/feedback", *ZED_SERVER_URL);
 
-        cx.spawn(|this, async_cx| {
+        let metrics_id = zed_client.metrics_id();
+        let http_client = zed_client.http_client();
+
+        cx.spawn(|_, _| {
             async move {
                 // TODO FEEDBACK: Use or remove
                 // this.read_with(&async_cx, |this, cx| {
                 //     // Now we have a &self and a &AppContext
                 // });
 
-                let metrics_id = None;
-
                 let request = FeedbackRequestBody {
                     feedback_text: &feedback_text,
                     metrics_id,
@@ -240,28 +231,23 @@ impl View for FeedbackPopover {
         enum SubmitFeedback {}
 
         let theme = cx.global::<Settings>().theme.clone();
-        let status_bar_height = theme.workspace.status_bar.height;
         let submit_feedback_text_button_height = 20.0;
 
-        // I'd like to just define:
-
-        // 1. Overall popover width x height dimensions
-        // 2. Submit Feedback button height dimensions
-        // 3. Allow editor to dynamically fill in the remaining space
-
         Flex::column()
             .with_child(
                 Flex::row()
                     .with_child(
                         ChildView::new(self.feedback_editor.clone(), cx)
                             .contained()
-                            .with_style(theme.contact_list.user_query_editor.container)
+                            .with_style(theme.feedback.feedback_editor.container)
                             .flex(1., true)
                             .boxed(),
                     )
                     .constrained()
-                    .with_width(theme.contacts_popover.width)
-                    .with_height(theme.contacts_popover.height - submit_feedback_text_button_height)
+                    .with_width(theme.feedback.feedback_popover.width)
+                    .with_height(
+                        theme.feedback.feedback_popover.height - submit_feedback_text_button_height,
+                    )
                     .boxed(),
             )
             .with_child(
@@ -286,10 +272,10 @@ impl View for FeedbackPopover {
                 .boxed(),
             )
             .contained()
-            .with_style(theme.contacts_popover.container)
+            .with_style(theme.feedback.feedback_popover.container)
             .constrained()
-            .with_width(theme.contacts_popover.width + 200.0)
-            .with_height(theme.contacts_popover.height)
+            .with_width(theme.feedback.feedback_popover.width)
+            .with_height(theme.feedback.feedback_popover.height)
             .boxed()
     }
 }

crates/zed/src/main.rs 🔗

@@ -108,7 +108,7 @@ fn main() {
         watch_settings_file(default_settings, settings_file_content, themes.clone(), cx);
         watch_keymap_file(keymap_file, cx);
 
-        cx.set_global(http.clone());
+        cx.set_global(client.clone());
 
         feedback_popover::init(cx);
         context_menu::init(cx);

styles/src/styleTree/app.ts 🔗

@@ -19,6 +19,7 @@ import terminal from "./terminal";
 import contactList from "./contactList";
 import incomingCallNotification from "./incomingCallNotification";
 import { ColorScheme } from "../themes/common/colorScheme";
+import feedback from "./feedback";
 
 export default function app(colorScheme: ColorScheme): Object {
   return {
@@ -37,6 +38,7 @@ export default function app(colorScheme: ColorScheme): Object {
     projectDiagnostics: projectDiagnostics(colorScheme),
     projectPanel: projectPanel(colorScheme),
     contactsPopover: contactsPopover(colorScheme),
+    feedback: feedback(colorScheme),
     contactFinder: contactFinder(colorScheme),
     contactList: contactList(colorScheme),
     search: search(colorScheme),

styles/src/styleTree/feedback.ts 🔗

@@ -0,0 +1,35 @@
+import { ColorScheme } from "../themes/common/colorScheme";
+import { background, border, text } from "./components";
+
+export default function feedback(colorScheme: ColorScheme) {
+  let layer = colorScheme.middle;
+  return {
+    feedbackEditor: {
+      background: background(layer, "on"),
+      cornerRadius: 6,
+      text: text(layer, "mono", "on"),
+      placeholderText: text(layer, "mono", "on", "disabled", { size: "xs" }),
+      selection: colorScheme.players[0],
+      border: border(layer, "on"),
+      padding: {
+        bottom: 4,
+        left: 8,
+        right: 8,
+        top: 4,
+      },
+      margin: {
+        left: 6,
+      }
+    },
+    feedbackPopover: {
+      background: background(layer),
+      cornerRadius: 6,
+      padding: { top: 6 },
+      margin: { top: -6 },
+      shadow: colorScheme.popoverShadow,
+      border: border(layer),
+      width: 500,
+      height: 400
+    }
+  }
+}