mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-27 12:54:42 +00:00
Split concepts out into self contained files in feedback editor
This commit is contained in:
parent
912c396b37
commit
b31813fad3
6 changed files with 197 additions and 167 deletions
44
crates/feedback/src/deploy_feedback_button.rs
Normal file
44
crates/feedback/src/deploy_feedback_button.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use gpui::{
|
||||
elements::{MouseEventHandler, ParentElement, Stack, Text},
|
||||
CursorStyle, Element, ElementBox, Entity, MouseButton, RenderContext, View, ViewContext,
|
||||
};
|
||||
use settings::Settings;
|
||||
use workspace::{item::ItemHandle, StatusItemView};
|
||||
|
||||
use crate::feedback_editor::GiveFeedback;
|
||||
|
||||
pub struct DeployFeedbackButton;
|
||||
|
||||
impl Entity for DeployFeedbackButton {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl View for DeployFeedbackButton {
|
||||
fn ui_name() -> &'static str {
|
||||
"DeployFeedbackButton"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox {
|
||||
Stack::new()
|
||||
.with_child(
|
||||
MouseEventHandler::<Self>::new(0, cx, |state, cx| {
|
||||
let theme = &cx.global::<Settings>().theme;
|
||||
let theme = &theme.workspace.status_bar.feedback;
|
||||
|
||||
Text::new(
|
||||
"Give Feedback".to_string(),
|
||||
theme.style_for(state, true).clone(),
|
||||
)
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, |_, cx| cx.dispatch_action(GiveFeedback))
|
||||
.boxed(),
|
||||
)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl StatusItemView for DeployFeedbackButton {
|
||||
fn set_active_pane_item(&mut self, _: Option<&dyn ItemHandle>, _: &mut ViewContext<Self>) {}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
pub mod deploy_feedback_button;
|
||||
pub mod feedback_editor;
|
||||
pub mod feedback_info_text;
|
||||
pub mod submit_feedback_button;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod feedback_editor;
|
||||
mod system_specs;
|
||||
use gpui::{actions, impl_actions, ClipboardItem, MutableAppContext, PromptLevel, ViewContext};
|
||||
use serde::Deserialize;
|
||||
|
|
|
@ -10,10 +10,10 @@ use editor::{Anchor, Editor};
|
|||
use futures::AsyncReadExt;
|
||||
use gpui::{
|
||||
actions,
|
||||
elements::{ChildView, Flex, Label, MouseEventHandler, ParentElement, Stack, Text},
|
||||
serde_json, AnyViewHandle, AppContext, CursorStyle, Element, ElementBox, Entity, ModelHandle,
|
||||
MouseButton, MutableAppContext, PromptLevel, RenderContext, Task, View, ViewContext,
|
||||
ViewHandle, WeakViewHandle,
|
||||
elements::{ChildView, Flex, Label, ParentElement},
|
||||
serde_json, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle,
|
||||
MutableAppContext, PromptLevel, RenderContext, Task, View, ViewContext, ViewHandle,
|
||||
WeakViewHandle,
|
||||
};
|
||||
use isahc::Request;
|
||||
use language::Buffer;
|
||||
|
@ -21,14 +21,13 @@ use postage::prelude::Stream;
|
|||
|
||||
use project::Project;
|
||||
use serde::Serialize;
|
||||
use settings::Settings;
|
||||
use workspace::{
|
||||
item::{Item, ItemHandle},
|
||||
searchable::{SearchableItem, SearchableItemHandle},
|
||||
AppState, StatusItemView, ToolbarItemLocation, ToolbarItemView, Workspace,
|
||||
AppState, Workspace,
|
||||
};
|
||||
|
||||
use crate::system_specs::SystemSpecs;
|
||||
use crate::{submit_feedback_button::SubmitFeedbackButton, system_specs::SystemSpecs};
|
||||
|
||||
const FEEDBACK_CHAR_LIMIT: RangeInclusive<usize> = 10..=5000;
|
||||
const FEEDBACK_SUBMISSION_ERROR_TEXT: &str =
|
||||
|
@ -54,42 +53,6 @@ pub fn init(system_specs: SystemSpecs, app_state: Arc<AppState>, cx: &mut Mutabl
|
|||
);
|
||||
}
|
||||
|
||||
pub struct DeployFeedbackButton;
|
||||
|
||||
impl Entity for DeployFeedbackButton {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl View for DeployFeedbackButton {
|
||||
fn ui_name() -> &'static str {
|
||||
"DeployFeedbackButton"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox {
|
||||
Stack::new()
|
||||
.with_child(
|
||||
MouseEventHandler::<Self>::new(0, cx, |state, cx| {
|
||||
let theme = &cx.global::<Settings>().theme;
|
||||
let theme = &theme.workspace.status_bar.feedback;
|
||||
|
||||
Text::new(
|
||||
"Give Feedback".to_string(),
|
||||
theme.style_for(state, true).clone(),
|
||||
)
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, |_, cx| cx.dispatch_action(GiveFeedback))
|
||||
.boxed(),
|
||||
)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl StatusItemView for DeployFeedbackButton {
|
||||
fn set_active_pane_item(&mut self, _: Option<&dyn ItemHandle>, _: &mut ViewContext<Self>) {}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct FeedbackRequestBody<'a> {
|
||||
feedback_text: &'a str,
|
||||
|
@ -100,7 +63,7 @@ struct FeedbackRequestBody<'a> {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct FeedbackEditor {
|
||||
pub(crate) struct FeedbackEditor {
|
||||
system_specs: SystemSpecs,
|
||||
editor: ViewHandle<Editor>,
|
||||
project: ModelHandle<Project>,
|
||||
|
@ -442,123 +405,3 @@ impl SearchableItem for FeedbackEditor {
|
|||
.update(cx, |editor, cx| editor.active_match_index(matches, cx))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SubmitFeedbackButton {
|
||||
active_item: Option<ViewHandle<FeedbackEditor>>,
|
||||
}
|
||||
|
||||
impl SubmitFeedbackButton {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
active_item: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for SubmitFeedbackButton {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl View for SubmitFeedbackButton {
|
||||
fn ui_name() -> &'static str {
|
||||
"SubmitFeedbackButton"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
enum SubmitFeedbackButton {}
|
||||
MouseEventHandler::<SubmitFeedbackButton>::new(0, cx, |state, _| {
|
||||
let style = theme.feedback.submit_button.style_for(state, false);
|
||||
Label::new("Submit as Markdown".into(), style.text.clone())
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, |_, cx| {
|
||||
cx.dispatch_action(SubmitFeedback)
|
||||
})
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_left(theme.feedback.button_margin)
|
||||
.with_tooltip::<Self, _>(
|
||||
0,
|
||||
"cmd-s".into(),
|
||||
Some(Box::new(SubmitFeedback)),
|
||||
theme.tooltip.clone(),
|
||||
cx,
|
||||
)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToolbarItemView for SubmitFeedbackButton {
|
||||
fn set_active_pane_item(
|
||||
&mut self,
|
||||
active_pane_item: Option<&dyn ItemHandle>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> workspace::ToolbarItemLocation {
|
||||
cx.notify();
|
||||
if let Some(feedback_editor) = active_pane_item.and_then(|i| i.downcast::<FeedbackEditor>())
|
||||
{
|
||||
self.active_item = Some(feedback_editor);
|
||||
ToolbarItemLocation::PrimaryRight { flex: None }
|
||||
} else {
|
||||
self.active_item = None;
|
||||
ToolbarItemLocation::Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FeedbackInfoText {
|
||||
active_item: Option<ViewHandle<FeedbackEditor>>,
|
||||
}
|
||||
|
||||
impl FeedbackInfoText {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
active_item: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for FeedbackInfoText {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl View for FeedbackInfoText {
|
||||
fn ui_name() -> &'static str {
|
||||
"FeedbackInfoText"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
let text = "We read whatever you submit here. For issues and discussions, visit the community repo on GitHub.";
|
||||
Label::new(text.to_string(), theme.feedback.info_text.text.clone())
|
||||
.contained()
|
||||
.aligned()
|
||||
.left()
|
||||
.clipped()
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToolbarItemView for FeedbackInfoText {
|
||||
fn set_active_pane_item(
|
||||
&mut self,
|
||||
active_pane_item: Option<&dyn ItemHandle>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> workspace::ToolbarItemLocation {
|
||||
cx.notify();
|
||||
if let Some(feedback_editor) = active_pane_item.and_then(|i| i.downcast::<FeedbackEditor>())
|
||||
{
|
||||
self.active_item = Some(feedback_editor);
|
||||
ToolbarItemLocation::PrimaryLeft {
|
||||
flex: Some((1., false)),
|
||||
}
|
||||
} else {
|
||||
self.active_item = None;
|
||||
ToolbarItemLocation::Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
60
crates/feedback/src/feedback_info_text.rs
Normal file
60
crates/feedback/src/feedback_info_text.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use gpui::{
|
||||
elements::Label, Element, ElementBox, Entity, RenderContext, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use settings::Settings;
|
||||
use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
|
||||
|
||||
use crate::feedback_editor::FeedbackEditor;
|
||||
|
||||
pub struct FeedbackInfoText {
|
||||
active_item: Option<ViewHandle<FeedbackEditor>>,
|
||||
}
|
||||
|
||||
impl FeedbackInfoText {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
active_item: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for FeedbackInfoText {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl View for FeedbackInfoText {
|
||||
fn ui_name() -> &'static str {
|
||||
"FeedbackInfoText"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
let text = "We read whatever you submit here. For issues and discussions, visit the community repo on GitHub.";
|
||||
Label::new(text.to_string(), theme.feedback.info_text.text.clone())
|
||||
.contained()
|
||||
.aligned()
|
||||
.left()
|
||||
.clipped()
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToolbarItemView for FeedbackInfoText {
|
||||
fn set_active_pane_item(
|
||||
&mut self,
|
||||
active_pane_item: Option<&dyn ItemHandle>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> workspace::ToolbarItemLocation {
|
||||
cx.notify();
|
||||
if let Some(feedback_editor) = active_pane_item.and_then(|i| i.downcast::<FeedbackEditor>())
|
||||
{
|
||||
self.active_item = Some(feedback_editor);
|
||||
ToolbarItemLocation::PrimaryLeft {
|
||||
flex: Some((1., false)),
|
||||
}
|
||||
} else {
|
||||
self.active_item = None;
|
||||
ToolbarItemLocation::Hidden
|
||||
}
|
||||
}
|
||||
}
|
76
crates/feedback/src/submit_feedback_button.rs
Normal file
76
crates/feedback/src/submit_feedback_button.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
use gpui::{
|
||||
elements::{Label, MouseEventHandler},
|
||||
CursorStyle, Element, ElementBox, Entity, MouseButton, RenderContext, View, ViewContext,
|
||||
ViewHandle,
|
||||
};
|
||||
use settings::Settings;
|
||||
use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
|
||||
|
||||
use crate::feedback_editor::{FeedbackEditor, SubmitFeedback};
|
||||
|
||||
pub struct SubmitFeedbackButton {
|
||||
pub(crate) active_item: Option<ViewHandle<FeedbackEditor>>,
|
||||
}
|
||||
|
||||
impl SubmitFeedbackButton {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
active_item: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for SubmitFeedbackButton {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl View for SubmitFeedbackButton {
|
||||
fn ui_name() -> &'static str {
|
||||
"SubmitFeedbackButton"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
enum SubmitFeedbackButton {}
|
||||
MouseEventHandler::<SubmitFeedbackButton>::new(0, cx, |state, _| {
|
||||
let style = theme.feedback.submit_button.style_for(state, false);
|
||||
Label::new("Submit as Markdown".into(), style.text.clone())
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, |_, cx| {
|
||||
cx.dispatch_action(SubmitFeedback)
|
||||
})
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_left(theme.feedback.button_margin)
|
||||
.with_tooltip::<Self, _>(
|
||||
0,
|
||||
"cmd-s".into(),
|
||||
Some(Box::new(SubmitFeedback)),
|
||||
theme.tooltip.clone(),
|
||||
cx,
|
||||
)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToolbarItemView for SubmitFeedbackButton {
|
||||
fn set_active_pane_item(
|
||||
&mut self,
|
||||
active_pane_item: Option<&dyn ItemHandle>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> workspace::ToolbarItemLocation {
|
||||
cx.notify();
|
||||
if let Some(feedback_editor) = active_pane_item.and_then(|i| i.downcast::<FeedbackEditor>())
|
||||
{
|
||||
self.active_item = Some(feedback_editor);
|
||||
ToolbarItemLocation::PrimaryRight { flex: None }
|
||||
} else {
|
||||
self.active_item = None;
|
||||
ToolbarItemLocation::Hidden
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,9 @@ use collections::VecDeque;
|
|||
pub use editor;
|
||||
use editor::{Editor, MultiBuffer};
|
||||
|
||||
use feedback::feedback_editor::{FeedbackInfoText, SubmitFeedbackButton};
|
||||
use feedback::{
|
||||
feedback_info_text::FeedbackInfoText, submit_feedback_button::SubmitFeedbackButton,
|
||||
};
|
||||
use futures::StreamExt;
|
||||
use gpui::{
|
||||
actions,
|
||||
|
@ -349,7 +351,8 @@ pub fn initialize_workspace(
|
|||
let activity_indicator =
|
||||
activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
|
||||
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
||||
let feedback_button = cx.add_view(|_| feedback::feedback_editor::DeployFeedbackButton {});
|
||||
let feedback_button =
|
||||
cx.add_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton {});
|
||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||
status_bar.add_left_item(diagnostic_summary, cx);
|
||||
status_bar.add_left_item(activity_indicator, cx);
|
||||
|
|
Loading…
Reference in a new issue