From 23400a5a70a700c318aabed1053faa8fce4d60c5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sun, 22 Oct 2023 16:03:33 +0200 Subject: [PATCH] Start styling notification panel --- crates/collab_ui/src/chat_panel.rs | 3 +- crates/collab_ui/src/collab_ui.rs | 13 +++-- crates/collab_ui/src/notification_panel.rs | 62 ++++++++++++--------- crates/theme/src/theme.rs | 3 + styles/src/style_tree/notification_panel.ts | 39 ++++++++++--- 5 files changed, 81 insertions(+), 39 deletions(-) diff --git a/crates/collab_ui/src/chat_panel.rs b/crates/collab_ui/src/chat_panel.rs index 3661d1ae0e2e5385f1bb2d528ba573fa28a6e210..051b44f9d3ee3f61924a67925a417d66939036e5 100644 --- a/crates/collab_ui/src/chat_panel.rs +++ b/crates/collab_ui/src/chat_panel.rs @@ -443,7 +443,8 @@ impl ChatPanel { Flex::row() .with_child(render_avatar( message.sender.avatar.clone(), - &theme, + &theme.chat_panel.avatar, + theme.chat_panel.avatar_container, )) .with_child( Label::new( diff --git a/crates/collab_ui/src/collab_ui.rs b/crates/collab_ui/src/collab_ui.rs index 4f1b5b8d4e60772e0372925dd948c7da88c2754a..6c9ba94865ed24d9e82f9a2051691ca15cb6548a 100644 --- a/crates/collab_ui/src/collab_ui.rs +++ b/crates/collab_ui/src/collab_ui.rs @@ -11,7 +11,7 @@ use call::{report_call_event_for_room, ActiveCall, Room}; use feature_flags::{ChannelsAlpha, FeatureFlagAppExt}; use gpui::{ actions, - elements::{Empty, Image}, + elements::{ContainerStyle, Empty, Image}, geometry::{ rect::RectF, vector::{vec2f, Vector2F}, @@ -20,7 +20,7 @@ use gpui::{ AnyElement, AppContext, Element, ImageData, Task, }; use std::{rc::Rc, sync::Arc}; -use theme::Theme; +use theme::AvatarStyle; use time::{OffsetDateTime, UtcOffset}; use util::ResultExt; use workspace::AppState; @@ -133,8 +133,11 @@ fn notification_window_options( } } -fn render_avatar(avatar: Option>, theme: &Arc) -> AnyElement { - let avatar_style = theme.chat_panel.avatar; +fn render_avatar( + avatar: Option>, + avatar_style: &AvatarStyle, + container: ContainerStyle, +) -> AnyElement { avatar .map(|avatar| { Image::from_data(avatar) @@ -154,7 +157,7 @@ fn render_avatar(avatar: Option>, theme: &Arc) .into_any() }) .contained() - .with_style(theme.chat_panel.avatar_container) + .with_style(container) .into_any() } diff --git a/crates/collab_ui/src/notification_panel.rs b/crates/collab_ui/src/notification_panel.rs index fb0b393a42b7edc064d09ddd20aa1e8e79f8529e..8efdcf03e14f0a3bf89a03c177bc86610c07812d 100644 --- a/crates/collab_ui/src/notification_panel.rs +++ b/crates/collab_ui/src/notification_panel.rs @@ -21,7 +21,7 @@ use rpc::proto; use serde::{Deserialize, Serialize}; use settings::SettingsStore; use std::{sync::Arc, time::Duration}; -use theme::{IconButton, Theme}; +use theme::{ui, Theme}; use time::{OffsetDateTime, UtcOffset}; use util::{ResultExt, TryFutureExt}; use workspace::{ @@ -197,9 +197,9 @@ impl NotificationPanel { let NotificationPresenter { actor, text, - icon, needs_response, can_navigate, + .. } = self.present_notification(entry, cx)?; let theme = theme::current(cx); @@ -227,17 +227,21 @@ impl NotificationPanel { Flex::column() .with_child( Flex::row() - .with_children( - actor.map(|actor| render_avatar(actor.avatar.clone(), &theme)), - ) - .with_child(render_icon_button(&theme.chat_panel.icon_button, icon)) + .with_children(actor.map(|actor| { + render_avatar( + actor.avatar.clone(), + &style.avatar, + style.avatar_container, + ) + })) .with_child( Label::new( format_timestamp(timestamp, now, self.local_timezone), style.timestamp.text.clone(), ) .contained() - .with_style(style.timestamp.container), + .with_style(style.timestamp.container) + .flex_float(), ) .align_children_center(), ) @@ -245,8 +249,12 @@ impl NotificationPanel { .with_children(if let Some(is_accepted) = response { Some( Label::new( - if is_accepted { "Accepted" } else { "Declined" }, - style.button.text.clone(), + if is_accepted { + "You Accepted" + } else { + "You Declined" + }, + style.read_text.text.clone(), ) .into_any(), ) @@ -573,19 +581,34 @@ impl View for NotificationPanel { fn render(&mut self, cx: &mut ViewContext) -> AnyElement { let theme = theme::current(cx); + let style = &theme.notification_panel; let element = if self.client.user_id().is_none() { self.render_sign_in_prompt(&theme, cx) } else if self.notification_list.item_count() == 0 { self.render_empty_state(&theme, cx) } else { - List::new(self.notification_list.clone()) - .contained() - .with_style(theme.chat_panel.list) + Flex::column() + .with_child( + Flex::row() + .with_child(Label::new("Notifications", style.title.text.clone())) + .with_child(ui::svg(&style.title_icon).flex_float()) + .align_children_center() + .contained() + .with_style(style.title.container) + .constrained() + .with_height(style.title_height), + ) + .with_child( + List::new(self.notification_list.clone()) + .contained() + .with_style(style.list) + .flex(1., true), + ) .into_any() }; element .contained() - .with_style(theme.chat_panel.container) + .with_style(style.container) .constrained() .with_min_width(150.) .into_any() @@ -675,19 +698,6 @@ impl Panel for NotificationPanel { } } -fn render_icon_button(style: &IconButton, svg_path: &'static str) -> impl Element { - Svg::new(svg_path) - .with_color(style.color) - .constrained() - .with_width(style.icon_width) - .aligned() - .constrained() - .with_width(style.button_width) - .with_height(style.button_width) - .contained() - .with_style(style.container) -} - pub struct NotificationToast { notification_id: u64, actor: Option>, diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 7bedb263401ffe0eb4dc59915ea1c0377bcac820..3bcbaec7aa06f226e7845f552feeb2222e536c72 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -653,6 +653,9 @@ pub struct ChatPanel { pub struct NotificationPanel { #[serde(flatten)] pub container: ContainerStyle, + pub title: ContainedText, + pub title_icon: SvgStyle, + pub title_height: f32, pub list: ContainerStyle, pub avatar: AvatarStyle, pub avatar_container: ContainerStyle, diff --git a/styles/src/style_tree/notification_panel.ts b/styles/src/style_tree/notification_panel.ts index 996f05398b634849ff77ca5256ce2acb145827b6..3b6a87946a38b6d072daacc46ed6fa9dd76eea4b 100644 --- a/styles/src/style_tree/notification_panel.ts +++ b/styles/src/style_tree/notification_panel.ts @@ -1,9 +1,9 @@ -import { background, text } from "./components" +import { background, border, text } from "./components" import { icon_button } from "../component/icon_button" import { useTheme } from "../theme" import { interactive } from "../element" -export default function chat_panel(): any { +export default function (): any { const theme = useTheme() const layer = theme.middle @@ -12,12 +12,32 @@ export default function chat_panel(): any { avatar: { icon_width: 24, icon_height: 24, - corner_radius: 4, + corner_radius: 12, outer_width: 24, - outer_corner_radius: 16, + outer_corner_radius: 24, + }, + title: { + ...text(layer, "sans", "default"), + padding: { left: 8, right: 8 }, + border: border(layer, { bottom: true }), + }, + title_height: 32, + title_icon: { + asset: "icons/feedback.svg", + color: text(theme.lowest, "sans", "default").color, + dimensions: { + width: 16, + height: 16, + }, + }, + read_text: { + padding: { top: 4, bottom: 4 }, + ...text(layer, "sans", "disabled"), + }, + unread_text: { + padding: { top: 4, bottom: 4 }, + ...text(layer, "sans", "base"), }, - read_text: text(layer, "sans", "disabled"), - unread_text: text(layer, "sans", "base"), button: interactive({ base: { ...text(theme.lowest, "sans", "on", { size: "xs" }), @@ -42,7 +62,12 @@ export default function chat_panel(): any { bottom: 2, }, }, - list: {}, + list: { + padding: { + left: 8, + right: 8, + }, + }, icon_button: icon_button({ variant: "ghost", color: "variant",