1use gpui::{App, ClipboardItem, PromptLevel, actions};
2use system_specs::{CopySystemSpecsIntoClipboard, SystemSpecs};
3use util::ResultExt;
4use workspace::Workspace;
5use zed_actions::feedback::FileBugReport;
6
7pub mod feedback_modal;
8
9actions!(
10 zed,
11 [
12 /// Opens email client to send feedback to Zed support.
13 EmailZed,
14 /// Opens the Zed repository on GitHub.
15 OpenZedRepo,
16 /// Opens the feature request form.
17 RequestFeature,
18 ]
19);
20
21const ZED_REPO_URL: &str = "https://github.com/zed-industries/zed";
22
23const REQUEST_FEATURE_URL: &str = "https://github.com/zed-industries/zed/discussions/new/choose";
24
25fn file_bug_report_url(specs: &SystemSpecs) -> String {
26 format!(
27 concat!(
28 "https://github.com/zed-industries/zed/issues/new",
29 "?",
30 "template=10_bug_report.yml",
31 "&",
32 "environment={}"
33 ),
34 urlencoding::encode(&specs.to_string())
35 )
36}
37
38fn email_zed_url(specs: &SystemSpecs) -> String {
39 format!(
40 concat!("mailto:hi@zed.dev", "?", "body={}"),
41 email_body(specs)
42 )
43}
44
45fn email_body(specs: &SystemSpecs) -> String {
46 let body = format!("\n\nSystem Information:\n\n{}", specs);
47 urlencoding::encode(&body).to_string()
48}
49
50pub fn init(cx: &mut App) {
51 cx.observe_new(|workspace: &mut Workspace, window, cx| {
52 let Some(window) = window else {
53 return;
54 };
55 feedback_modal::FeedbackModal::register(workspace, window, cx);
56 workspace
57 .register_action(|_, _: &CopySystemSpecsIntoClipboard, window, cx| {
58 let specs = SystemSpecs::new(window, cx);
59
60 cx.spawn_in(window, async move |_, cx| {
61 let specs = specs.await.to_string();
62
63 cx.update(|_, cx| {
64 cx.write_to_clipboard(ClipboardItem::new_string(specs.clone()))
65 })
66 .log_err();
67
68 cx.prompt(
69 PromptLevel::Info,
70 "Copied into clipboard",
71 Some(&specs),
72 &["OK"],
73 )
74 .await
75 })
76 .detach();
77 })
78 .register_action(|_, _: &RequestFeature, _, cx| {
79 cx.open_url(REQUEST_FEATURE_URL);
80 })
81 .register_action(move |_, _: &FileBugReport, window, cx| {
82 let specs = SystemSpecs::new(window, cx);
83 cx.spawn_in(window, async move |_, cx| {
84 let specs = specs.await;
85 cx.update(|_, cx| {
86 cx.open_url(&file_bug_report_url(&specs));
87 })
88 .log_err();
89 })
90 .detach();
91 })
92 .register_action(move |_, _: &EmailZed, window, cx| {
93 let specs = SystemSpecs::new(window, cx);
94 cx.spawn_in(window, async move |_, cx| {
95 let specs = specs.await;
96 cx.update(|_, cx| {
97 cx.open_url(&email_zed_url(&specs));
98 })
99 .log_err();
100 })
101 .detach();
102 })
103 .register_action(move |_, _: &OpenZedRepo, _, cx| {
104 cx.open_url(ZED_REPO_URL);
105 });
106 })
107 .detach();
108}