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;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub mod feedback_editor;
|
|
||||||
mod system_specs;
|
mod system_specs;
|
||||||
use gpui::{actions, impl_actions, ClipboardItem, MutableAppContext, PromptLevel, ViewContext};
|
use gpui::{actions, impl_actions, ClipboardItem, MutableAppContext, PromptLevel, ViewContext};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -10,10 +10,10 @@ use editor::{Anchor, Editor};
|
||||||
use futures::AsyncReadExt;
|
use futures::AsyncReadExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::{ChildView, Flex, Label, MouseEventHandler, ParentElement, Stack, Text},
|
elements::{ChildView, Flex, Label, ParentElement},
|
||||||
serde_json, AnyViewHandle, AppContext, CursorStyle, Element, ElementBox, Entity, ModelHandle,
|
serde_json, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle,
|
||||||
MouseButton, MutableAppContext, PromptLevel, RenderContext, Task, View, ViewContext,
|
MutableAppContext, PromptLevel, RenderContext, Task, View, ViewContext, ViewHandle,
|
||||||
ViewHandle, WeakViewHandle,
|
WeakViewHandle,
|
||||||
};
|
};
|
||||||
use isahc::Request;
|
use isahc::Request;
|
||||||
use language::Buffer;
|
use language::Buffer;
|
||||||
|
@ -21,14 +21,13 @@ use postage::prelude::Stream;
|
||||||
|
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use settings::Settings;
|
|
||||||
use workspace::{
|
use workspace::{
|
||||||
item::{Item, ItemHandle},
|
item::{Item, ItemHandle},
|
||||||
searchable::{SearchableItem, SearchableItemHandle},
|
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_CHAR_LIMIT: RangeInclusive<usize> = 10..=5000;
|
||||||
const FEEDBACK_SUBMISSION_ERROR_TEXT: &str =
|
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)]
|
#[derive(Serialize)]
|
||||||
struct FeedbackRequestBody<'a> {
|
struct FeedbackRequestBody<'a> {
|
||||||
feedback_text: &'a str,
|
feedback_text: &'a str,
|
||||||
|
@ -100,7 +63,7 @@ struct FeedbackRequestBody<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct FeedbackEditor {
|
pub(crate) struct FeedbackEditor {
|
||||||
system_specs: SystemSpecs,
|
system_specs: SystemSpecs,
|
||||||
editor: ViewHandle<Editor>,
|
editor: ViewHandle<Editor>,
|
||||||
project: ModelHandle<Project>,
|
project: ModelHandle<Project>,
|
||||||
|
@ -442,123 +405,3 @@ impl SearchableItem for FeedbackEditor {
|
||||||
.update(cx, |editor, cx| editor.active_match_index(matches, cx))
|
.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;
|
pub use editor;
|
||||||
use editor::{Editor, MultiBuffer};
|
use editor::{Editor, MultiBuffer};
|
||||||
|
|
||||||
use feedback::feedback_editor::{FeedbackInfoText, SubmitFeedbackButton};
|
use feedback::{
|
||||||
|
feedback_info_text::FeedbackInfoText, submit_feedback_button::SubmitFeedbackButton,
|
||||||
|
};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
|
@ -349,7 +351,8 @@ pub fn initialize_workspace(
|
||||||
let activity_indicator =
|
let activity_indicator =
|
||||||
activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
|
activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
|
||||||
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
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| {
|
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||||
status_bar.add_left_item(diagnostic_summary, cx);
|
status_bar.add_left_item(diagnostic_summary, cx);
|
||||||
status_bar.add_left_item(activity_indicator, cx);
|
status_bar.add_left_item(activity_indicator, cx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue