Fix notification styling, minimize database reads

Mikayla Maki created

Change summary

crates/workspace/src/notifications.rs | 38 +++++++++++++-----
crates/workspace/src/workspace.rs     | 57 ++++++++++++++++++++++++----
2 files changed, 76 insertions(+), 19 deletions(-)

Detailed changes

crates/workspace/src/notifications.rs 🔗

@@ -33,7 +33,7 @@ impl From<&dyn NotificationHandle> for AnyViewHandle {
     }
 }
 
-struct NotificationTracker {
+pub(crate) struct NotificationTracker {
     notifications_sent: HashMap<TypeId, Vec<usize>>,
 }
 
@@ -65,8 +65,7 @@ impl Workspace {
         id: usize,
         cx: &ViewContext<Self>,
     ) -> bool {
-        cx
-            .global::<NotificationTracker>()
+        cx.global::<NotificationTracker>()
             .get(&TypeId::of::<V>())
             .map(|ids| ids.contains(&id))
             .unwrap_or(false)
@@ -78,8 +77,7 @@ impl Workspace {
         cx: &mut ViewContext<Self>,
         build_notification: impl FnOnce(&mut ViewContext<Self>) -> ViewHandle<V>,
     ) {
-        if !self.has_shown_notification_once::<V>(id, cx)
-        {
+        if !self.has_shown_notification_once::<V>(id, cx) {
             cx.update_global::<NotificationTracker, _, _>(|tracker, _| {
                 let entry = tracker.entry(TypeId::of::<V>()).or_default();
                 entry.push(id);
@@ -167,7 +165,7 @@ pub mod simple_message_notification {
         elements::{Flex, MouseEventHandler, Padding, ParentElement, Svg, Text},
         impl_actions,
         platform::{CursorStyle, MouseButton},
-        AppContext, Element, Entity, View, ViewContext,
+        AnyElement, AppContext, Element, Entity, View, ViewContext, fonts::TextStyle,
     };
     use menu::Cancel;
     use serde::Deserialize;
@@ -195,8 +193,13 @@ pub mod simple_message_notification {
         )
     }
 
+    enum NotificationMessage {
+        Text(Cow<'static, str>),
+        Element(fn(TextStyle, &AppContext) -> AnyElement<MessageNotification>),
+    }
+
     pub struct MessageNotification {
-        message: Cow<'static, str>,
+        message: NotificationMessage,
         on_click: Option<Arc<dyn Fn(&mut ViewContext<Self>)>>,
         click_message: Option<Cow<'static, str>>,
     }
@@ -215,7 +218,16 @@ pub mod simple_message_notification {
             S: Into<Cow<'static, str>>,
         {
             Self {
-                message: message.into(),
+                message: NotificationMessage::Text(message.into()),
+                on_click: None,
+                click_message: None,
+            }
+        }
+
+        pub fn new_element(message: fn(TextStyle, &AppContext) -> AnyElement<MessageNotification>) -> MessageNotification
+        {
+            Self {
+                message: NotificationMessage::Element(message),
                 on_click: None,
                 click_message: None,
             }
@@ -254,7 +266,12 @@ pub mod simple_message_notification {
             enum MessageNotificationTag {}
 
             let click_message = self.click_message.clone();
-            let message = self.message.clone();
+            let message = match &self.message {
+                NotificationMessage::Text(text) => {
+                    Text::new(text.to_owned(), theme.message.text.clone()).into_any()
+                }
+                NotificationMessage::Element(e) => e(theme.message.text.clone(), cx),
+            };
             let on_click = self.on_click.clone();
             let has_click_action = on_click.is_some();
 
@@ -262,8 +279,7 @@ pub mod simple_message_notification {
                 .with_child(
                     Flex::row()
                         .with_child(
-                            Text::new(message, theme.message.text.clone())
-                                .contained()
+                            message.contained()
                                 .with_style(theme.message.container)
                                 .aligned()
                                 .top()

crates/workspace/src/workspace.rs 🔗

@@ -19,7 +19,7 @@ use assets::Assets;
 use call::ActiveCall;
 use client::{
     proto::{self, PeerId},
-    Client, TypedEnvelope, UserStore, ZED_APP_VERSION,
+    Client, TypedEnvelope, UserStore,
 };
 use collections::{hash_map, HashMap, HashSet};
 use drag_and_drop::DragAndDrop;
@@ -60,7 +60,7 @@ use std::{
 };
 
 use crate::{
-    notifications::simple_message_notification::MessageNotification,
+    notifications::{simple_message_notification::MessageNotification, NotificationTracker},
     persistence::model::{
         DockData, DockStructure, SerializedPane, SerializedPaneGroup, SerializedWorkspace,
     },
@@ -81,7 +81,7 @@ use serde::Deserialize;
 use shared_screen::SharedScreen;
 use status_bar::StatusBar;
 pub use status_bar::StatusItemView;
-use theme::Theme;
+use theme::{Theme, ThemeSettings};
 pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
 use util::{async_iife, channel::ZedVersion, paths, ResultExt};
 pub use workspace_settings::{AutosaveSetting, GitGutterSetting, WorkspaceSettings};
@@ -3193,6 +3193,7 @@ async fn open_items(
 fn notify_of_new_dock(workspace: &WeakViewHandle<Workspace>, cx: &mut AsyncAppContext) {
     const NEW_PANEL_BLOG_POST: &str = "https://zed.dev/blog/new-panel-system";
     const NEW_DOCK_HINT_KEY: &str = "show_new_dock_key";
+    const MESSAGE_ID: usize = 2;
 
     if workspace
         .read_with(cx, |workspace, cx| {
@@ -3205,7 +3206,7 @@ fn notify_of_new_dock(workspace: &WeakViewHandle<Workspace>, cx: &mut AsyncAppCo
             {
                 return true;
             }
-            workspace.has_shown_notification_once::<MessageNotification>(2, cx)
+            workspace.has_shown_notification_once::<MessageNotification>(MESSAGE_ID, cx)
         })
         .unwrap_or(false)
     {
@@ -3218,6 +3219,24 @@ fn notify_of_new_dock(workspace: &WeakViewHandle<Workspace>, cx: &mut AsyncAppCo
         .flatten()
         .is_some()
     {
+        if !workspace
+            .read_with(cx, |workspace, cx| {
+                workspace.has_shown_notification_once::<MessageNotification>(MESSAGE_ID, cx)
+            })
+            .unwrap_or(false)
+        {
+            cx.update(|cx| {
+                cx.update_global::<NotificationTracker, _, _>(|tracker, _| {
+                    let entry = tracker
+                        .entry(TypeId::of::<MessageNotification>())
+                        .or_default();
+                    if !entry.contains(&MESSAGE_ID) {
+                        entry.push(MESSAGE_ID);
+                    }
+                });
+            });
+        }
+
         return;
     }
 
@@ -3232,11 +3251,33 @@ fn notify_of_new_dock(workspace: &WeakViewHandle<Workspace>, cx: &mut AsyncAppCo
     workspace
         .update(cx, |workspace, cx| {
             workspace.show_notification_once(2, cx, |cx| {
+
+
                 cx.add_view(|_| {
-                    MessageNotification::new(
-                        "Looking for the dock? Try 'ctrl-`'!\n'shift-escape' now zooms your pane",
-                    )
-                    .with_click_message("Click to read more about the new panel system")
+                    MessageNotification::new_element(|text, _| {
+                        Text::new(
+                            "Looking for the dock? Try ctrl-`!\nshift-escape now zooms your pane.",
+                            text,
+                        )
+                        .with_custom_runs(vec![26..32, 34..46], |_, bounds, scene, cx| {
+                            let code_span_background_color = settings::get::<ThemeSettings>(cx)
+                                .theme
+                                .editor
+                                .document_highlight_read_background;
+
+                            scene.push_quad(gpui::Quad {
+                                bounds,
+                                background: Some(code_span_background_color),
+                                border: Default::default(),
+                                corner_radius: 2.0,
+                            })
+                        })
+                        .into_any()
+                    })
+                    // MessageNotification::new_(
+                    //     "Looking for the dock? Try 'ctrl-`'!\n'shift-escape' now zooms your pane",
+                    // )
+                    .with_click_message("Read more about the new panel system")
                     .on_click(|cx| cx.platform().open_url(NEW_PANEL_BLOG_POST))
                 })
             })