project_shared_notification.rs

  1use call::{room, ActiveCall};
  2use client::User;
  3use gpui::{
  4    actions,
  5    elements::*,
  6    geometry::{rect::RectF, vector::vec2f},
  7    Entity, MouseButton, MutableAppContext, RenderContext, View, ViewContext, WindowBounds,
  8    WindowKind, WindowOptions,
  9};
 10use settings::Settings;
 11use std::sync::Arc;
 12use workspace::JoinProject;
 13
 14actions!(project_shared_notification, [DismissProject]);
 15
 16pub fn init(cx: &mut MutableAppContext) {
 17    cx.add_action(ProjectSharedNotification::join);
 18    cx.add_action(ProjectSharedNotification::dismiss);
 19
 20    let active_call = ActiveCall::global(cx);
 21    cx.subscribe(&active_call, move |_, event, cx| match event {
 22        room::Event::RemoteProjectShared { owner, project_id } => {
 23            cx.add_window(
 24                WindowOptions {
 25                    bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(300., 400.))),
 26                    titlebar: None,
 27                    center: true,
 28                    kind: WindowKind::PopUp,
 29                    is_movable: false,
 30                },
 31                |_| ProjectSharedNotification::new(*project_id, owner.clone()),
 32            );
 33        }
 34    })
 35    .detach();
 36}
 37
 38pub struct ProjectSharedNotification {
 39    project_id: u64,
 40    owner: Arc<User>,
 41}
 42
 43impl ProjectSharedNotification {
 44    fn new(project_id: u64, owner: Arc<User>) -> Self {
 45        Self { project_id, owner }
 46    }
 47
 48    fn join(&mut self, _: &JoinProject, cx: &mut ViewContext<Self>) {
 49        let window_id = cx.window_id();
 50        cx.remove_window(window_id);
 51        cx.propagate_action();
 52    }
 53
 54    fn dismiss(&mut self, _: &DismissProject, cx: &mut ViewContext<Self>) {
 55        let window_id = cx.window_id();
 56        cx.remove_window(window_id);
 57    }
 58
 59    fn render_owner(&self, cx: &mut RenderContext<Self>) -> ElementBox {
 60        let theme = &cx.global::<Settings>().theme.project_shared_notification;
 61        Flex::row()
 62            .with_children(
 63                self.owner
 64                    .avatar
 65                    .clone()
 66                    .map(|avatar| Image::new(avatar).with_style(theme.owner_avatar).boxed()),
 67            )
 68            .with_child(
 69                Label::new(
 70                    format!("{} has shared a new project", self.owner.github_login),
 71                    theme.message.text.clone(),
 72                )
 73                .boxed(),
 74            )
 75            .boxed()
 76    }
 77
 78    fn render_buttons(&self, cx: &mut RenderContext<Self>) -> ElementBox {
 79        enum Join {}
 80        enum Dismiss {}
 81
 82        let project_id = self.project_id;
 83        let owner_user_id = self.owner.id;
 84        Flex::row()
 85            .with_child(
 86                MouseEventHandler::<Join>::new(0, cx, |_, cx| {
 87                    let theme = &cx.global::<Settings>().theme.project_shared_notification;
 88                    Label::new("Join".to_string(), theme.join_button.text.clone())
 89                        .contained()
 90                        .with_style(theme.join_button.container)
 91                        .boxed()
 92                })
 93                .on_click(MouseButton::Left, move |_, cx| {
 94                    cx.dispatch_action(JoinProject {
 95                        project_id,
 96                        follow_user_id: owner_user_id,
 97                    });
 98                })
 99                .boxed(),
100            )
101            .with_child(
102                MouseEventHandler::<Dismiss>::new(0, cx, |_, cx| {
103                    let theme = &cx.global::<Settings>().theme.project_shared_notification;
104                    Label::new("Dismiss".to_string(), theme.dismiss_button.text.clone())
105                        .contained()
106                        .with_style(theme.dismiss_button.container)
107                        .boxed()
108                })
109                .on_click(MouseButton::Left, |_, cx| {
110                    cx.dispatch_action(DismissProject);
111                })
112                .boxed(),
113            )
114            .boxed()
115    }
116}
117
118impl Entity for ProjectSharedNotification {
119    type Event = ();
120}
121
122impl View for ProjectSharedNotification {
123    fn ui_name() -> &'static str {
124        "ProjectSharedNotification"
125    }
126
127    fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
128        Flex::row()
129            .with_child(self.render_owner(cx))
130            .with_child(self.render_buttons(cx))
131            .boxed()
132    }
133}