Style project shared notifications

Antonio Scandurra created

Change summary

crates/collab_ui/src/incoming_call_notification.rs  | 13 -
crates/collab_ui/src/project_shared_notification.rs | 81 ++++++++++++--
crates/theme/src/theme.rs                           |  6 +
styles/src/styleTree/projectSharedNotification.ts   | 28 ++++-
4 files changed, 98 insertions(+), 30 deletions(-)

Detailed changes

crates/collab_ui/src/incoming_call_notification.rs 🔗

@@ -26,7 +26,7 @@ pub fn init(cx: &mut MutableAppContext) {
             if let Some(incoming_call) = incoming_call {
                 const PADDING: f32 = 16.;
                 let screen_size = cx.platform().screen_size();
-                let window_size = vec2f(304., 64.);
+                let window_size = vec2f(274., 64.);
                 let (window_id, _) = cx.add_window(
                     WindowOptions {
                         bounds: WindowBounds::Fixed(RectF::new(
@@ -108,13 +108,10 @@ impl IncomingCallNotification {
                         .boxed(),
                     )
                     .with_child(
-                        Label::new(
-                            "Incoming Zed call...".into(),
-                            theme.caller_message.text.clone(),
-                        )
-                        .contained()
-                        .with_style(theme.caller_message.container)
-                        .boxed(),
+                        Label::new("is calling you".into(), theme.caller_message.text.clone())
+                            .contained()
+                            .with_style(theme.caller_message.container)
+                            .boxed(),
                     )
                     .contained()
                     .with_style(theme.caller_metadata)

crates/collab_ui/src/project_shared_notification.rs 🔗

@@ -4,8 +4,8 @@ use gpui::{
     actions,
     elements::*,
     geometry::{rect::RectF, vector::vec2f},
-    Entity, MouseButton, MutableAppContext, RenderContext, View, ViewContext, WindowBounds,
-    WindowKind, WindowOptions,
+    CursorStyle, Entity, MouseButton, MutableAppContext, RenderContext, View, ViewContext,
+    WindowBounds, WindowKind, WindowOptions,
 };
 use settings::Settings;
 use std::sync::Arc;
@@ -20,11 +20,17 @@ pub fn init(cx: &mut MutableAppContext) {
     let active_call = ActiveCall::global(cx);
     cx.subscribe(&active_call, move |_, event, cx| match event {
         room::Event::RemoteProjectShared { owner, project_id } => {
+            const PADDING: f32 = 16.;
+            let screen_size = cx.platform().screen_size();
+            let window_size = vec2f(366., 64.);
             cx.add_window(
                 WindowOptions {
-                    bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(300., 400.))),
+                    bounds: WindowBounds::Fixed(RectF::new(
+                        vec2f(screen_size.x() - window_size.x() - PADDING, PADDING),
+                        window_size,
+                    )),
                     titlebar: None,
-                    center: true,
+                    center: false,
                     kind: WindowKind::PopUp,
                     is_movable: false,
                 },
@@ -59,19 +65,40 @@ impl ProjectSharedNotification {
     fn render_owner(&self, cx: &mut RenderContext<Self>) -> ElementBox {
         let theme = &cx.global::<Settings>().theme.project_shared_notification;
         Flex::row()
-            .with_children(
-                self.owner
-                    .avatar
-                    .clone()
-                    .map(|avatar| Image::new(avatar).with_style(theme.owner_avatar).boxed()),
-            )
+            .with_children(self.owner.avatar.clone().map(|avatar| {
+                Image::new(avatar)
+                    .with_style(theme.owner_avatar)
+                    .aligned()
+                    .boxed()
+            }))
             .with_child(
-                Label::new(
-                    format!("{} has shared a new project", self.owner.github_login),
-                    theme.message.text.clone(),
-                )
-                .boxed(),
+                Flex::column()
+                    .with_child(
+                        Label::new(
+                            self.owner.github_login.clone(),
+                            theme.owner_username.text.clone(),
+                        )
+                        .contained()
+                        .with_style(theme.owner_username.container)
+                        .boxed(),
+                    )
+                    .with_child(
+                        Label::new(
+                            "has shared a project with you".into(),
+                            theme.message.text.clone(),
+                        )
+                        .contained()
+                        .with_style(theme.message.container)
+                        .boxed(),
+                    )
+                    .contained()
+                    .with_style(theme.owner_metadata)
+                    .aligned()
+                    .boxed(),
             )
+            .contained()
+            .with_style(theme.owner_container)
+            .flex(1., true)
             .boxed()
     }
 
@@ -81,36 +108,50 @@ impl ProjectSharedNotification {
 
         let project_id = self.project_id;
         let owner_user_id = self.owner.id;
-        Flex::row()
+
+        Flex::column()
             .with_child(
                 MouseEventHandler::<Join>::new(0, cx, |_, cx| {
                     let theme = &cx.global::<Settings>().theme.project_shared_notification;
                     Label::new("Join".to_string(), theme.join_button.text.clone())
+                        .aligned()
                         .contained()
                         .with_style(theme.join_button.container)
                         .boxed()
                 })
+                .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, move |_, cx| {
                     cx.dispatch_action(JoinProject {
                         project_id,
                         follow_user_id: owner_user_id,
                     });
                 })
+                .flex(1., true)
                 .boxed(),
             )
             .with_child(
                 MouseEventHandler::<Dismiss>::new(0, cx, |_, cx| {
                     let theme = &cx.global::<Settings>().theme.project_shared_notification;
                     Label::new("Dismiss".to_string(), theme.dismiss_button.text.clone())
+                        .aligned()
                         .contained()
                         .with_style(theme.dismiss_button.container)
                         .boxed()
                 })
+                .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, |_, cx| {
                     cx.dispatch_action(DismissProject);
                 })
+                .flex(1., true)
                 .boxed(),
             )
+            .constrained()
+            .with_width(
+                cx.global::<Settings>()
+                    .theme
+                    .project_shared_notification
+                    .button_width,
+            )
             .boxed()
     }
 }
@@ -125,9 +166,17 @@ impl View for ProjectSharedNotification {
     }
 
     fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
+        let background = cx
+            .global::<Settings>()
+            .theme
+            .project_shared_notification
+            .background;
         Flex::row()
             .with_child(self.render_owner(cx))
             .with_child(self.render_buttons(cx))
+            .contained()
+            .with_background_color(background)
+            .expanded()
             .boxed()
     }
 }

crates/theme/src/theme.rs 🔗

@@ -471,8 +471,14 @@ pub struct UpdateNotification {
 
 #[derive(Deserialize, Default)]
 pub struct ProjectSharedNotification {
+    #[serde(default)]
+    pub background: Color,
+    pub owner_container: ContainerStyle,
     pub owner_avatar: ImageStyle,
+    pub owner_metadata: ContainerStyle,
+    pub owner_username: ContainedText,
     pub message: ContainedText,
+    pub button_width: f32,
     pub join_button: ContainedText,
     pub dismiss_button: ContainedText,
 }

styles/src/styleTree/projectSharedNotification.ts 🔗

@@ -1,22 +1,38 @@
 import Theme from "../themes/common/theme";
-import { text } from "./components";
+import { backgroundColor, borderColor, text } from "./components";
 
 export default function projectSharedNotification(theme: Theme): Object {
-  const avatarSize = 12;
+  const avatarSize = 32;
   return {
+    background: backgroundColor(theme, 300),
+    ownerContainer: {
+      padding: 12,
+    },
     ownerAvatar: {
       height: avatarSize,
       width: avatarSize,
-      cornerRadius: 6,
+      cornerRadius: avatarSize / 2,
+    },
+    ownerMetadata: {
+      margin: { left: 10 },
+    },
+    ownerUsername: {
+      ...text(theme, "sans", "active", { size: "sm", weight: "bold" }),
+      margin: { top: -3 },
     },
     message: {
-      ...text(theme, "sans", "primary", { size: "xs" }),
+      ...text(theme, "sans", "secondary", { size: "xs" }),
+      margin: { top: -3 },
     },
+    buttonWidth: 96,
     joinButton: {
-      ...text(theme, "sans", "primary", { size: "xs" })
+      background: backgroundColor(theme, "info", "active"),
+      border: { left: true, bottom: true, width: 1, color: borderColor(theme, "primary") },
+      ...text(theme, "sans", "info", { size: "xs", weight: "extra_bold" })
     },
     dismissButton: {
-      ...text(theme, "sans", "primary", { size: "xs" })
+      border: { left: true, width: 1, color: borderColor(theme, "primary") },
+      ...text(theme, "sans", "secondary", { size: "xs", weight: "extra_bold" })
     },
   };
 }