From 0ba656aa0ea69f25630ac8a11130633e71a7cc9b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 11 May 2022 14:20:05 -0700 Subject: [PATCH] Improve layout and styling of contact notifications Co-authored-by: Nathan Sobo --- assets/icons/{reject.svg => decline.svg} | 0 assets/themes/cave-dark.json | 14 +++- assets/themes/cave-light.json | 14 +++- assets/themes/dark.json | 14 +++- assets/themes/light.json | 14 +++- assets/themes/solarized-dark.json | 14 +++- assets/themes/solarized-light.json | 14 +++- assets/themes/sulphurpool-dark.json | 14 +++- assets/themes/sulphurpool-light.json | 14 +++- crates/client/src/user.rs | 2 +- crates/contacts_panel/src/contact_finder.rs | 2 +- .../src/contact_notification.rs | 67 +++++++++++-------- crates/contacts_panel/src/contacts_panel.rs | 8 +-- crates/rpc/proto/zed.proto | 2 +- crates/theme/src/theme.rs | 4 +- crates/workspace/src/workspace.rs | 2 +- styles/src/styleTree/contactNotification.ts | 17 +++-- styles/src/styleTree/workspace.ts | 2 +- 18 files changed, 152 insertions(+), 66 deletions(-) rename assets/icons/{reject.svg => decline.svg} (100%) diff --git a/assets/icons/reject.svg b/assets/icons/decline.svg similarity index 100% rename from assets/icons/reject.svg rename to assets/icons/decline.svg diff --git a/assets/themes/cave-dark.json b/assets/themes/cave-dark.json index ae8e32e945d377cdc07fbd8f26f86b0c80d331f4..bdc611b830065dfee72f0e0104eb08373579ee80 100644 --- a/assets/themes/cave-dark.json +++ b/assets/themes/cave-dark.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#e2dfe7", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#8b8792", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#26232a3d" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#e2dfe7" + } } } } \ No newline at end of file diff --git a/assets/themes/cave-light.json b/assets/themes/cave-light.json index bf444d4758fbc81e2c9b2b774bd703f0883357d8..b97b7f13fd9a45238c0bee8a9408c775ec6dfd1b 100644 --- a/assets/themes/cave-light.json +++ b/assets/themes/cave-light.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#26232a", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#585260", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#e2dfe71f" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#26232a" + } } } } \ No newline at end of file diff --git a/assets/themes/dark.json b/assets/themes/dark.json index b4b86e2f4921be27385070701bc77d755cdefc6f..37cb0a80bbde9b35a5e725c674380adad86a02d7 100644 --- a/assets/themes/dark.json +++ b/assets/themes/dark.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#f1f1f1", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#9c9c9c", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#070707" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#c6c6c6" + } } } } \ No newline at end of file diff --git a/assets/themes/light.json b/assets/themes/light.json index 0ac7535acb88180f0d6df69f51babf3ea784a988..7491b039b91eb91b780f4a815a018d2eafde5549 100644 --- a/assets/themes/light.json +++ b/assets/themes/light.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#2b2b2b", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#474747", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#e3e3e3" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#393939" + } } } } \ No newline at end of file diff --git a/assets/themes/solarized-dark.json b/assets/themes/solarized-dark.json index e9c50a1eaebc4e2c96549cbe1b8b00a9168cf442..b1fc074ff73131023d55aeb5d78678164d488db4 100644 --- a/assets/themes/solarized-dark.json +++ b/assets/themes/solarized-dark.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#eee8d5", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#93a1a1", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#0736423d" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#eee8d5" + } } } } \ No newline at end of file diff --git a/assets/themes/solarized-light.json b/assets/themes/solarized-light.json index 1ef6a6835198babdc2a5ff273bde5fef4dc06bc3..72e12bcb5b5b00653056c79ca2d33caaebdf4bef 100644 --- a/assets/themes/solarized-light.json +++ b/assets/themes/solarized-light.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#073642", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#586e75", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#eee8d51f" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#073642" + } } } } \ No newline at end of file diff --git a/assets/themes/sulphurpool-dark.json b/assets/themes/sulphurpool-dark.json index 37264cd20398aa866f10797eabd59411fd8f8e7b..26568e91b2be123ca2005cc5c165736fab776f36 100644 --- a/assets/themes/sulphurpool-dark.json +++ b/assets/themes/sulphurpool-dark.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#dfe2f1", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#979db4", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#2932563d" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#dfe2f1" + } } } } \ No newline at end of file diff --git a/assets/themes/sulphurpool-light.json b/assets/themes/sulphurpool-light.json index d5adf576ddc00a9ed8e273b02a6c7173bd42df06..031d6652b9f9acc8aa1c123d993b0dd7db231a77 100644 --- a/assets/themes/sulphurpool-light.json +++ b/assets/themes/sulphurpool-light.json @@ -505,7 +505,7 @@ } }, "notifications": { - "width": 256, + "width": 380, "margin": { "right": 10, "bottom": 10 @@ -1698,7 +1698,8 @@ "color": "#293256", "size": 12, "margin": { - "left": 4 + "left": 8, + "right": 8 } }, "header_height": 18, @@ -1707,6 +1708,7 @@ "color": "#5e6687", "size": 12, "margin": { + "left": 20, "top": 6, "bottom": 6 } @@ -1720,6 +1722,9 @@ "corner_radius": 6, "margin": { "left": 6 + }, + "hover": { + "background": "#dfe2f11f" } }, "dismiss_button": { @@ -1727,7 +1732,10 @@ "icon_width": 8, "icon_height": 8, "button_width": 8, - "button_height": 8 + "button_height": 8, + "hover": { + "color": "#293256" + } } } } \ No newline at end of file diff --git a/crates/client/src/user.rs b/crates/client/src/user.rs index 7de32e80774ee64dae3e37f1739ed3f427d52bb7..84254da73a5bb0815acf3b66bf0cef112088f030 100644 --- a/crates/client/src/user.rs +++ b/crates/client/src/user.rs @@ -371,7 +371,7 @@ impl UserStore { response: if accept { proto::ContactRequestResponse::Accept } else { - proto::ContactRequestResponse::Reject + proto::ContactRequestResponse::Decline } as i32, }, cx, diff --git a/crates/contacts_panel/src/contact_finder.rs b/crates/contacts_panel/src/contact_finder.rs index 3b88eaf11797c5b6eaa8b56ec391cf50067e2500..18e17a93d9ba448f533d83a0a09701b5d3ae84cc 100644 --- a/crates/contacts_panel/src/contact_finder.rs +++ b/crates/contacts_panel/src/contact_finder.rs @@ -118,7 +118,7 @@ impl PickerDelegate for ContactFinder { "icons/accept.svg" } ContactRequestStatus::RequestSent | ContactRequestStatus::RequestAccepted => { - "icons/reject.svg" + "icons/decline.svg" } }; let button_style = if self.user_store.read(cx).is_contact_request_pending(&user) { diff --git a/crates/contacts_panel/src/contact_notification.rs b/crates/contacts_panel/src/contact_notification.rs index cf3b9aa5590f9ee97e818ab1368339ef1fd01c4d..6369f70ce0244fdd0a1a8540d4a91a0d86c0acbc 100644 --- a/crates/contacts_panel/src/contact_notification.rs +++ b/crates/contacts_panel/src/contact_notification.rs @@ -6,6 +6,8 @@ use gpui::{ use settings::Settings; use workspace::Notification; +use crate::render_icon_button; + impl_internal_actions!(contact_notifications, [Dismiss, RespondToContactRequest]); pub fn init(cx: &mut MutableAppContext) { @@ -31,7 +33,7 @@ pub enum Event { Dismiss, } -enum Reject {} +enum Decline {} enum Accept {} impl Entity for ContactNotification { @@ -87,7 +89,7 @@ impl ContactNotification { let user_id = user.id; Flex::column() - .with_child(self.render_header("added you", theme, cx)) + .with_child(self.render_header("wants to add you as a contact.", theme, cx)) .with_child( Label::new( "They won't know if you decline.".to_string(), @@ -100,13 +102,14 @@ impl ContactNotification { .with_child( Flex::row() .with_child( - MouseEventHandler::new::( + MouseEventHandler::new::( self.event.user.id as usize, cx, - |_, _| { - Label::new("Reject".to_string(), theme.button.text.clone()) + |state, _| { + let button = theme.button.style_for(state, false); + Label::new("Decline".to_string(), button.text.clone()) .contained() - .with_style(theme.button.container) + .with_style(button.container) .boxed() }, ) @@ -120,10 +123,11 @@ impl ContactNotification { .boxed(), ) .with_child( - MouseEventHandler::new::(user.id as usize, cx, |_, _| { - Label::new("Accept".to_string(), theme.button.text.clone()) + MouseEventHandler::new::(user.id as usize, cx, |state, _| { + let button = theme.button.style_for(state, false); + Label::new("Accept".to_string(), button.text.clone()) .contained() - .with_style(theme.button.container) + .with_style(button.container) .boxed() }) .with_cursor_style(CursorStyle::PointingHand) @@ -163,42 +167,51 @@ impl ContactNotification { Image::new(avatar) .with_style(theme.header_avatar) .aligned() - .left() + .constrained() + .with_height( + cx.font_cache() + .line_height(theme.header_message.text.font_size), + ) + .aligned() + .top() .boxed() })) .with_child( - Label::new( + Text::new( format!("{} {}", user.github_login, message), theme.header_message.text.clone(), ) .contained() .with_style(theme.header_message.container) .aligned() + .top() + .left() + .flex(1., true) .boxed(), ) .with_child( - MouseEventHandler::new::(user.id as usize, cx, |_, _| { - Svg::new("icons/reject.svg") - .with_color(theme.dismiss_button.color) - .constrained() - .with_width(theme.dismiss_button.icon_width) - .aligned() - .contained() - .with_style(theme.dismiss_button.container) - .constrained() - .with_width(theme.dismiss_button.button_width) - .with_height(theme.dismiss_button.button_width) - .aligned() - .boxed() + MouseEventHandler::new::(user.id as usize, cx, |state, _| { + render_icon_button( + theme.dismiss_button.style_for(state, false), + "icons/decline.svg", + ) + .boxed() }) .with_cursor_style(CursorStyle::PointingHand) + .with_padding(Padding::uniform(5.)) .on_click(move |_, cx| cx.dispatch_action(Dismiss(user_id))) + .aligned() + .constrained() + .with_height( + cx.font_cache() + .line_height(theme.header_message.text.font_size), + ) + .aligned() + .top() .flex_float() .boxed(), ) - .constrained() - .with_height(theme.header_height) - .boxed() + .named("contact notification header") } fn dismiss(&mut self, _: &Dismiss, cx: &mut ViewContext) { diff --git a/crates/contacts_panel/src/contacts_panel.rs b/crates/contacts_panel/src/contacts_panel.rs index 3a8a9605f31620f233f8b0b2d9071754b04f87b6..e26e64f9f6ee18353dd00163fe1008d52b384b92 100644 --- a/crates/contacts_panel/src/contacts_panel.rs +++ b/crates/contacts_panel/src/contacts_panel.rs @@ -344,7 +344,7 @@ impl ContactsPanel { is_incoming: bool, cx: &mut LayoutContext, ) -> ElementBox { - enum Reject {} + enum Decline {} enum Accept {} enum Cancel {} @@ -373,13 +373,13 @@ impl ContactsPanel { if is_incoming { row.add_children([ - MouseEventHandler::new::(user.id as usize, cx, |mouse_state, _| { + MouseEventHandler::new::(user.id as usize, cx, |mouse_state, _| { let button_style = if is_contact_request_pending { &theme.disabled_contact_button } else { &theme.contact_button.style_for(mouse_state, false) }; - render_icon_button(button_style, "icons/reject.svg") + render_icon_button(button_style, "icons/decline.svg") .aligned() .flex_float() .boxed() @@ -421,7 +421,7 @@ impl ContactsPanel { } else { &theme.contact_button.style_for(mouse_state, false) }; - render_icon_button(button_style, "icons/reject.svg") + render_icon_button(button_style, "icons/decline.svg") .aligned() .flex_float() .boxed() diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 43467bb61ae8f3e0faac373c014eba1315d65dc1..12ff05c7575ec53b1102ab253d4a9db08790b69a 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -564,7 +564,7 @@ message RespondToContactRequest { enum ContactRequestResponse { Accept = 0; - Reject = 1; + Decline = 1; Block = 2; Dismiss = 3; } diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 1907bb16934cf31d66bc3f71735cc57d3f1a4f53..9875f974983706204b0287913cc2eb15402123ab 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -362,8 +362,8 @@ pub struct ContactNotification { pub header_message: ContainedText, pub header_height: f32, pub body_message: ContainedText, - pub button: ContainedText, - pub dismiss_button: IconButton, + pub button: Interactive, + pub dismiss_button: Interactive, } #[derive(Clone, Deserialize, Default)] diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 68ecfa8903638eb26f180c6f10c1536aeaad9977..21d5581640d8654f7192bb3d7b07d771fcf8ff2f 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1769,7 +1769,7 @@ impl Workspace { .boxed() })) .constrained() - .with_width(250.) + .with_width(theme.notifications.width) .contained() .with_style(theme.notifications.container) .aligned() diff --git a/styles/src/styleTree/contactNotification.ts b/styles/src/styleTree/contactNotification.ts index 13e19df90bc07cdb28d79153f9dcf5d056856741..09360f2f9118876070a0700392f6fc2756b9e5c4 100644 --- a/styles/src/styleTree/contactNotification.ts +++ b/styles/src/styleTree/contactNotification.ts @@ -1,21 +1,24 @@ import Theme from "../themes/theme"; import { backgroundColor, iconColor, text } from "./components"; +const avatarSize = 12; +const headerPadding = 8; + export default function contactNotification(theme: Theme): Object { return { headerAvatar: { - height: 12, - width: 12, + height: avatarSize, + width: avatarSize, cornerRadius: 6, }, headerMessage: { ...text(theme, "sans", "primary", { size: "xs" }), - margin: { left: 4 } + margin: { left: headerPadding, right: headerPadding } }, headerHeight: 18, bodyMessage: { ...text(theme, "sans", "secondary", { size: "xs" }), - margin: { top: 6, bottom: 6 }, + margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 }, }, button: { ...text(theme, "sans", "primary", { size: "xs" }), @@ -23,6 +26,9 @@ export default function contactNotification(theme: Theme): Object { padding: 4, cornerRadius: 6, margin: { left: 6 }, + hover: { + background: backgroundColor(theme, "on300", "hovered") + } }, dismissButton: { color: iconColor(theme, "secondary"), @@ -30,6 +36,9 @@ export default function contactNotification(theme: Theme): Object { iconHeight: 8, buttonWidth: 8, buttonHeight: 8, + hover: { + color: iconColor(theme, "primary") + } } } } \ No newline at end of file diff --git a/styles/src/styleTree/workspace.ts b/styles/src/styleTree/workspace.ts index 326b07b9eef4eed9ba98b116d56eaeb422ff3f54..65564f5cbc35299fd49e39656e97370798312084 100644 --- a/styles/src/styleTree/workspace.ts +++ b/styles/src/styleTree/workspace.ts @@ -159,7 +159,7 @@ export default function workspace(theme: Theme) { shadow: shadow(theme), }, notifications: { - width: 256, + width: 380, margin: { right: 10, bottom: 10 }, } };