1use gpui::{
2 div, rems, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Render,
3 ViewContext,
4};
5use ui::{prelude::*, Button, ButtonStyle, Label, Tooltip};
6use workspace::Workspace;
7
8use crate::feedback_editor::GiveFeedback;
9
10pub struct FeedbackModal {
11 // editor: View<Editor>,
12 tmp_focus_handle: FocusHandle, // TODO: should be editor.focus_handle(cx)
13}
14
15impl FocusableView for FeedbackModal {
16 fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
17 self.tmp_focus_handle.clone()
18 }
19}
20impl EventEmitter<DismissEvent> for FeedbackModal {}
21
22impl FeedbackModal {
23 pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
24 let _handle = cx.view().downgrade();
25 workspace.register_action(move |workspace, _: &GiveFeedback, cx| {
26 workspace.toggle_modal(cx, move |cx| FeedbackModal::new(cx));
27 });
28 }
29
30 pub fn new(cx: &mut ViewContext<Self>) -> Self {
31 // let line_editor = cx.build_view(|cx| Editor::single_line(cx));
32 // let line_editor_change = cx.subscribe(&line_editor, Self::on_line_editor_event);
33
34 // let editor = active_editor.read(cx);
35 // let cursor = editor.selections.last::<Point>(cx).head();
36 // let last_line = editor.buffer().read(cx).snapshot(cx).max_point().row;
37 // let scroll_position = active_editor.update(cx, |editor, cx| editor.scroll_position(cx));
38
39 // let current_text = format!(
40 // "line {} of {} (column {})",
41 // cursor.row + 1,
42 // last_line + 1,
43 // cursor.column + 1,
44 // );
45 Self {
46 // editor: line_editor,
47 tmp_focus_handle: cx.focus_handle(),
48 }
49 }
50
51 // fn release(&mut self, cx: &mut WindowContext) {
52 // let scroll_position = self.prev_scroll_position.take();
53 // self.active_editor.update(cx, |editor, cx| {
54 // editor.highlight_rows(None);
55 // if let Some(scroll_position) = scroll_position {
56 // editor.set_scroll_position(scroll_position, cx);
57 // }
58 // cx.notify();
59 // })
60 // }
61
62 // fn on_feedback_editor_event(
63 // &mut self,
64 // _: View<Editor>,
65 // event: &editor::EditorEvent,
66 // cx: &mut ViewContext<Self>,
67 // ) {
68 // match event {
69 // // todo!() this isn't working...
70 // editor::EditorEvent::Blurred => cx.emit(DismissEvent),
71 // editor::EditorEvent::BufferEdited { .. } => self.highlight_current_line(cx),
72 // _ => {}
73 // }
74 // }
75
76 // fn highlight_current_line(&mut self, cx: &mut ViewContext<Self>) {
77 // if let Some(point) = self.point_from_query(cx) {
78 // self.active_editor.update(cx, |active_editor, cx| {
79 // let snapshot = active_editor.snapshot(cx).display_snapshot;
80 // let point = snapshot.buffer_snapshot.clip_point(point, Bias::Left);
81 // let display_point = point.to_display_point(&snapshot);
82 // let row = display_point.row();
83 // active_editor.highlight_rows(Some(row..row + 1));
84 // active_editor.request_autoscroll(Autoscroll::center(), cx);
85 // });
86 // cx.notify();
87 // }
88 // }
89
90 // fn point_from_query(&self, cx: &ViewContext<Self>) -> Option<Point> {
91 // let line_editor = self.line_editor.read(cx).text(cx);
92 // let mut components = line_editor
93 // .splitn(2, FILE_ROW_COLUMN_DELIMITER)
94 // .map(str::trim)
95 // .fuse();
96 // let row = components.next().and_then(|row| row.parse::<u32>().ok())?;
97 // let column = components.next().and_then(|col| col.parse::<u32>().ok());
98 // Some(Point::new(
99 // row.saturating_sub(1),
100 // column.unwrap_or(0).saturating_sub(1),
101 // ))
102 // }
103
104 // fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
105 // cx.emit(DismissEvent);
106 // }
107
108 // fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
109 // if let Some(point) = self.point_from_query(cx) {
110 // self.active_editor.update(cx, |editor, cx| {
111 // let snapshot = editor.snapshot(cx).display_snapshot;
112 // let point = snapshot.buffer_snapshot.clip_point(point, Bias::Left);
113 // editor.change_selections(Some(Autoscroll::center()), cx, |s| {
114 // s.select_ranges([point..point])
115 // });
116 // editor.focus(cx);
117 // cx.notify();
118 // });
119 // self.prev_scroll_position.take();
120 // }
121
122 // cx.emit(DismissEvent);
123 // }
124}
125
126impl Render for FeedbackModal {
127 type Element = Div;
128
129 fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
130 let dismiss = cx.listener(|_, _, cx| cx.emit(DismissEvent));
131
132 v_stack()
133 .elevation_3(cx)
134 .min_w(rems(40.))
135 .max_w(rems(96.))
136 .h(rems(40.))
137 .p_2()
138 .gap_2()
139 .child(h_stack().child(Label::new("Give Feedback").color(Color::Default)))
140 .child(
141 div()
142 .flex_1()
143 .bg(cx.theme().colors().editor_background)
144 .border()
145 .border_color(cx.theme().colors().border)
146 .child("editor"),
147 )
148 .child(
149 h_stack()
150 .justify_end()
151 .gap_1()
152 .child(
153 Button::new("cancel_feedback", "Cancel")
154 .style(ButtonStyle::Subtle)
155 .color(Color::Muted)
156 .on_click(dismiss),
157 )
158 .child(
159 Button::new("send_feedback", "Send Feedback")
160 .color(Color::Accent)
161 .style(ButtonStyle::Filled)
162 .tooltip(|cx| {
163 Tooltip::with_meta(
164 "Submit feedback to the Zed team.",
165 None,
166 "Provide an email address if you want us to be able to reply.",
167 cx,
168 )
169 }),
170 ),
171 )
172
173 // Header
174 // - has some info, maybe some links
175 // Body
176 // - Markdown Editor
177 // - Email address
178 // Footer
179 // - CTA buttons (Send, Cancel)
180
181 // div()
182 // .elevation_2(cx)
183 // .key_context(
184 // "FeedbackModal
185 // ",
186 // )
187 // .on_action(cx.listener(Self::cancel))
188 // .on_action(cx.listener(Self::confirm))
189 // .w_96()
190 // .child(
191 // v_stack()
192 // .px_1()
193 // .pt_0p5()
194 // .gap_px()
195 // .child(
196 // v_stack()
197 // .py_0p5()
198 // .px_1()
199 // .child(div().px_1().py_0p5().child(self.line_editor.clone())),
200 // )
201 // .child(
202 // div()
203 // .h_px()
204 // .w_full()
205 // .bg(cx.theme().colors().element_background),
206 // )
207 // .child(
208 // h_stack()
209 // .justify_between()
210 // .px_2()
211 // .py_1()
212 // .child(Label::new(self.current_text.clone()).color(Color::Muted)),
213 // ),
214 // )
215 }
216}