submit_feedback_button.rs

  1use crate::feedback_editor::{FeedbackEditor, SubmitFeedback};
  2use anyhow::Result;
  3use gpui::{
  4    elements::{Label, MouseEventHandler},
  5    platform::{CursorStyle, MouseButton},
  6    AnyElement, AppContext, Element, Entity, Task, View, ViewContext, ViewHandle,
  7};
  8use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
  9
 10pub fn init(cx: &mut AppContext) {
 11    cx.add_async_action(SubmitFeedbackButton::submit);
 12}
 13
 14pub struct SubmitFeedbackButton {
 15    pub(crate) active_item: Option<ViewHandle<FeedbackEditor>>,
 16}
 17
 18impl SubmitFeedbackButton {
 19    pub fn new() -> Self {
 20        Self {
 21            active_item: Default::default(),
 22        }
 23    }
 24
 25    pub fn submit(
 26        &mut self,
 27        _: &SubmitFeedback,
 28        cx: &mut ViewContext<Self>,
 29    ) -> Option<Task<Result<()>>> {
 30        if let Some(active_item) = self.active_item.as_ref() {
 31            Some(active_item.update(cx, |feedback_editor, cx| feedback_editor.submit(cx)))
 32        } else {
 33            None
 34        }
 35    }
 36}
 37
 38impl Entity for SubmitFeedbackButton {
 39    type Event = ();
 40}
 41
 42impl View for SubmitFeedbackButton {
 43    fn ui_name() -> &'static str {
 44        "SubmitFeedbackButton"
 45    }
 46
 47    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
 48        let theme = theme::current(cx).clone();
 49        let allow_submission = self
 50            .active_item
 51            .as_ref()
 52            .map_or(true, |i| i.read(cx).allow_submission);
 53
 54        enum SubmitFeedbackButton {}
 55        MouseEventHandler::new::<SubmitFeedbackButton, _>(0, cx, |state, _| {
 56            let text;
 57            let style = if allow_submission {
 58                text = "Submit as Markdown";
 59                theme.feedback.submit_button.style_for(state)
 60            } else {
 61                text = "Submitting...";
 62                theme
 63                    .feedback
 64                    .submit_button
 65                    .disabled
 66                    .as_ref()
 67                    .unwrap_or(&theme.feedback.submit_button.default)
 68            };
 69
 70            Label::new(text, style.text.clone())
 71                .contained()
 72                .with_style(style.container)
 73        })
 74        .with_cursor_style(CursorStyle::PointingHand)
 75        .on_click(MouseButton::Left, |_, this, cx| {
 76            this.submit(&Default::default(), cx);
 77        })
 78        .aligned()
 79        .contained()
 80        .with_margin_left(theme.feedback.button_margin)
 81        .with_tooltip::<Self>(
 82            0,
 83            "cmd-s",
 84            Some(Box::new(SubmitFeedback)),
 85            theme.tooltip.clone(),
 86            cx,
 87        )
 88        .into_any()
 89    }
 90}
 91
 92impl ToolbarItemView for SubmitFeedbackButton {
 93    fn set_active_pane_item(
 94        &mut self,
 95        active_pane_item: Option<&dyn ItemHandle>,
 96        cx: &mut ViewContext<Self>,
 97    ) -> workspace::ToolbarItemLocation {
 98        cx.notify();
 99        if let Some(feedback_editor) = active_pane_item.and_then(|i| i.downcast::<FeedbackEditor>())
100        {
101            self.active_item = Some(feedback_editor);
102            ToolbarItemLocation::PrimaryRight { flex: None }
103        } else {
104            self.active_item = None;
105            ToolbarItemLocation::Hidden
106        }
107    }
108}