Prevent multiple submissions of the same feedback text

Joseph T. Lyons and Julia created

Co-Authored-By: Julia <30666851+ForLoveOfCats@users.noreply.github.com>

Change summary

crates/feedback/src/feedback_editor.rs        | 20 ++++++++++++++++++
crates/feedback/src/submit_feedback_button.rs | 22 +++++++++++++++++++-
styles/src/style_tree/feedback.ts             |  5 ++++
3 files changed, 44 insertions(+), 3 deletions(-)

Detailed changes

crates/feedback/src/feedback_editor.rs 🔗

@@ -60,6 +60,7 @@ pub(crate) struct FeedbackEditor {
     system_specs: SystemSpecs,
     editor: ViewHandle<Editor>,
     project: ModelHandle<Project>,
+    pub allow_submission: bool,
 }
 
 impl FeedbackEditor {
@@ -82,10 +83,15 @@ impl FeedbackEditor {
             system_specs: system_specs.clone(),
             editor,
             project,
+            allow_submission: true,
         }
     }
 
     pub fn submit(&mut self, cx: &mut ViewContext<Self>) -> Task<anyhow::Result<()>> {
+        if !self.allow_submission {
+            return Task::ready(Ok(()));
+        }
+
         let feedback_text = self.editor.read(cx).text(cx);
         let feedback_char_count = feedback_text.chars().count();
         let feedback_text = feedback_text.trim().to_string();
@@ -122,19 +128,26 @@ impl FeedbackEditor {
             let answer = answer.recv().await;
 
             if answer == Some(0) {
+                this.update(&mut cx, |feedback_editor, cx| {
+                    feedback_editor.set_allow_submission(false, cx);
+                })
+                .log_err();
+
                 match FeedbackEditor::submit_feedback(&feedback_text, client, specs).await {
                     Ok(_) => {
                         this.update(&mut cx, |_, cx| cx.emit(editor::Event::Closed))
                             .log_err();
                     }
+
                     Err(error) => {
                         log::error!("{}", error);
-                        this.update(&mut cx, |_, cx| {
+                        this.update(&mut cx, |feedback_editor, cx| {
                             cx.prompt(
                                 PromptLevel::Critical,
                                 FEEDBACK_SUBMISSION_ERROR_TEXT,
                                 &["OK"],
                             );
+                            feedback_editor.set_allow_submission(true, cx);
                         })
                         .log_err();
                     }
@@ -146,6 +159,11 @@ impl FeedbackEditor {
         Task::ready(Ok(()))
     }
 
+    fn set_allow_submission(&mut self, allow_submission: bool, cx: &mut ViewContext<Self>) {
+        self.allow_submission = allow_submission;
+        cx.notify();
+    }
+
     async fn submit_feedback(
         feedback_text: &str,
         zed_client: Arc<Client>,

crates/feedback/src/submit_feedback_button.rs 🔗

@@ -46,10 +46,28 @@ impl View for SubmitFeedbackButton {
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = theme::current(cx).clone();
+        let allow_submission = self
+            .active_item
+            .as_ref()
+            .map_or(true, |i| i.read(cx).allow_submission);
+
         enum SubmitFeedbackButton {}
         MouseEventHandler::<SubmitFeedbackButton, Self>::new(0, cx, |state, _| {
-            let style = theme.feedback.submit_button.style_for(state);
-            Label::new("Submit as Markdown", style.text.clone())
+            let text;
+            let style = if allow_submission {
+                text = "Submit as Markdown";
+                theme.feedback.submit_button.style_for(state)
+            } else {
+                text = "Submitting...";
+                theme
+                    .feedback
+                    .submit_button
+                    .disabled
+                    .as_ref()
+                    .unwrap_or(&theme.feedback.submit_button.default)
+            };
+
+            Label::new(text, style.text.clone())
                 .contained()
                 .with_style(style.container)
         })

styles/src/style_tree/feedback.ts 🔗

@@ -33,6 +33,11 @@ export default function feedback(): any {
                     background: background(theme.highest, "on", "hovered"),
                     border: border(theme.highest, "on", "hovered"),
                 },
+                disabled: {
+                    ...text(theme.highest, "mono", "on", "disabled"),
+                    background: background(theme.highest, "on", "disabled"),
+                    border: border(theme.highest, "on", "disabled"),
+                }
             },
         }),
         button_margin: 8,