From 7ba7b925ff77444738feda1431cc91a29168af14 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 13 Dec 2023 21:18:50 -0500 Subject: [PATCH 1/4] Simulate sending feedback in dev --- Cargo.lock | 1 + crates/feedback2/Cargo.toml | 7 ++++--- crates/feedback2/src/feedback_modal.rs | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba868ebbae5a95b5faf4b90918a6d53f33e978d8..52fadb73e1904bdaf9b59adef9582fa22fdc9aea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3265,6 +3265,7 @@ dependencies = [ "serde_derive", "settings2", "smallvec", + "smol", "sysinfo", "theme2", "tree-sitter-markdown", diff --git a/crates/feedback2/Cargo.toml b/crates/feedback2/Cargo.toml index 560c5a307f9b103c0a65aed5fee73f48f55ee738..0e34ee410b5aa26c1b0417b739c928c464447312 100644 --- a/crates/feedback2/Cargo.toml +++ b/crates/feedback2/Cargo.toml @@ -26,16 +26,17 @@ ui = { package = "ui2", path = "../ui2" } util = { path = "../util" } workspace = { package = "workspace2", path = "../workspace2"} -log.workspace = true -futures.workspace = true anyhow.workspace = true -smallvec.workspace = true +futures.workspace = true human_bytes = "0.4.1" isahc.workspace = true lazy_static.workspace = true +log.workspace = true postage.workspace = true serde.workspace = true serde_derive.workspace = true +smallvec.workspace = true +smol.workspace = true sysinfo.workspace = true tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" } urlencoding = "2.1.2" diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index e5c1ccdc9d12b80e91fd73fc9cb9ce7fd4dc902c..d1c6572f3e1e4c0eb68c9a3c1c969c9628df3c1d 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -22,6 +22,7 @@ use crate::{system_specs::SystemSpecs, GiveFeedback, OpenZedCommunityRepo}; // For UI testing purposes const SEND_SUCCESS_IN_DEV_MODE: bool = true; +const SEND_TIME_IN_DEV_MODE: Duration = Duration::from_secs(2); // Temporary, until tests are in place #[cfg(debug_assertions)] @@ -273,6 +274,8 @@ impl FeedbackModal { system_specs: SystemSpecs, ) -> anyhow::Result<()> { if DEV_MODE { + smol::Timer::after(SEND_TIME_IN_DEV_MODE).await; + if SEND_SUCCESS_IN_DEV_MODE { return Ok(()); } else { From 052e05fc745561c50419101486c44eafc5e1024a Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 13 Dec 2023 21:19:12 -0500 Subject: [PATCH 2/4] Use existing convention to silence warnings --- crates/feedback2/src/feedback_modal.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index d1c6572f3e1e4c0eb68c9a3c1c969c9628df3c1d..e6c4377186b66c9d69e62b1a4f5b97cdb551ed6c 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -206,14 +206,16 @@ impl FeedbackModal { if answer == Some(0) { match email.clone() { Some(email) => { - let _ = KEY_VALUE_STORE + KEY_VALUE_STORE .write_kvp(DATABASE_KEY_NAME.to_string(), email) - .await; + .await + .ok(); } None => { - let _ = KEY_VALUE_STORE + KEY_VALUE_STORE .delete_kvp(DATABASE_KEY_NAME.to_string()) - .await; + .await + .ok(); } }; From be2ad2ff860146b53b576f22ea997d251798dd8e Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 13 Dec 2023 21:19:36 -0500 Subject: [PATCH 3/4] Add Duration dependency --- crates/feedback2/src/feedback_modal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index e6c4377186b66c9d69e62b1a4f5b97cdb551ed6c..a124cf579d0446ef4e9cfc8fb89861b6eed3ea89 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -1,4 +1,4 @@ -use std::{ops::RangeInclusive, sync::Arc}; +use std::{ops::RangeInclusive, sync::Arc, time::Duration}; use anyhow::{anyhow, bail}; use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL}; From 900a2bfb87ad75691f02157e036a403924888e25 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 13 Dec 2023 21:20:09 -0500 Subject: [PATCH 4/4] Use an enum to represent modal states and simplify logic --- crates/feedback2/src/feedback_modal.rs | 51 ++++++++++++-------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index a124cf579d0446ef4e9cfc8fb89861b6eed3ea89..1d0339080b890e9c364779f80853d74ca1df1f2e 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -48,14 +48,19 @@ struct FeedbackRequestBody<'a> { token: &'a str, } +#[derive(PartialEq)] +enum FeedbackModalState { + CanSubmit, + DismissModal, + AwaitingSubmissionResponse, +} + pub struct FeedbackModal { system_specs: SystemSpecs, feedback_editor: View, email_address_editor: View, - awaiting_submission: bool, - user_submitted: bool, - user_discarded: bool, character_count: i32, + state: FeedbackModalState, } impl FocusableView for FeedbackModal { @@ -67,12 +72,7 @@ impl EventEmitter for FeedbackModal {} impl ModalView for FeedbackModal { fn on_before_dismiss(&mut self, cx: &mut ViewContext) -> bool { - if self.user_submitted { - self.set_user_submitted(false, cx); - return true; - } - - if self.user_discarded { + if self.state == FeedbackModalState::DismissModal { return true; } @@ -86,7 +86,7 @@ impl ModalView for FeedbackModal { cx.spawn(move |this, mut cx| async move { if answer.await.ok() == Some(0) { this.update(&mut cx, |this, cx| { - this.user_discarded = true; + this.state = FeedbackModalState::DismissModal; cx.emit(DismissEvent) }) .log_err(); @@ -183,9 +183,7 @@ impl FeedbackModal { system_specs: system_specs.clone(), feedback_editor, email_address_editor, - awaiting_submission: false, - user_submitted: false, - user_discarded: false, + state: FeedbackModalState::CanSubmit, character_count: 0, } } @@ -220,7 +218,8 @@ impl FeedbackModal { }; this.update(&mut cx, |this, cx| { - this.set_awaiting_submission(true, cx); + this.state = FeedbackModalState::AwaitingSubmissionResponse; + cx.notify(); }) .log_err(); @@ -230,7 +229,8 @@ impl FeedbackModal { match res { Ok(_) => { this.update(&mut cx, |this, cx| { - this.set_user_submitted(true, cx); + this.state = FeedbackModalState::DismissModal; + cx.notify(); cx.emit(DismissEvent) }) .ok(); @@ -247,7 +247,9 @@ impl FeedbackModal { prompt.await.ok(); }) .detach(); - this.set_awaiting_submission(false, cx); + + this.state = FeedbackModalState::CanSubmit; + cx.notify(); }) .log_err(); } @@ -259,16 +261,6 @@ impl FeedbackModal { Task::ready(Ok(())) } - fn set_awaiting_submission(&mut self, awaiting_submission: bool, cx: &mut ViewContext) { - self.awaiting_submission = awaiting_submission; - cx.notify(); - } - - fn set_user_submitted(&mut self, user_submitted: bool, cx: &mut ViewContext) { - self.user_submitted = user_submitted; - cx.notify(); - } - async fn submit_feedback( feedback_text: &str, email: Option, @@ -330,10 +322,13 @@ impl Render for FeedbackModal { let valid_character_count = FEEDBACK_CHAR_LIMIT.contains(&self.character_count); + let awaiting_submission_response = + self.state == FeedbackModalState::AwaitingSubmissionResponse; + let allow_submission = - valid_character_count && valid_email_address && !self.awaiting_submission; + valid_character_count && valid_email_address && !awaiting_submission_response; - let submit_button_text = if self.awaiting_submission { + let submit_button_text = if awaiting_submission_response { "Submitting..." } else { "Submit"