diff --git a/crates/workspace/src/notifications.rs b/crates/workspace/src/notifications.rs index 4437a960ef..1060227d4a 100644 --- a/crates/workspace/src/notifications.rs +++ b/crates/workspace/src/notifications.rs @@ -33,7 +33,7 @@ impl From<&dyn NotificationHandle> for AnyViewHandle { } } -struct NotificationTracker { +pub(crate) struct NotificationTracker { notifications_sent: HashMap>, } @@ -65,8 +65,7 @@ impl Workspace { id: usize, cx: &ViewContext, ) -> bool { - cx - .global::() + cx.global::() .get(&TypeId::of::()) .map(|ids| ids.contains(&id)) .unwrap_or(false) @@ -78,8 +77,7 @@ impl Workspace { cx: &mut ViewContext, build_notification: impl FnOnce(&mut ViewContext) -> ViewHandle, ) { - if !self.has_shown_notification_once::(id, cx) - { + if !self.has_shown_notification_once::(id, cx) { cx.update_global::(|tracker, _| { let entry = tracker.entry(TypeId::of::()).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), + } + pub struct MessageNotification { - message: Cow<'static, str>, + message: NotificationMessage, on_click: Option)>>, click_message: Option>, } @@ -215,7 +218,16 @@ pub mod simple_message_notification { S: Into>, { 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 + { + 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() diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 292ec28abc..823c9c9294 100644 --- a/crates/workspace/src/workspace.rs +++ b/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, 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, cx: &mut AsyncAppCo { return true; } - workspace.has_shown_notification_once::(2, cx) + workspace.has_shown_notification_once::(MESSAGE_ID, cx) }) .unwrap_or(false) { @@ -3218,6 +3219,24 @@ fn notify_of_new_dock(workspace: &WeakViewHandle, cx: &mut AsyncAppCo .flatten() .is_some() { + if !workspace + .read_with(cx, |workspace, cx| { + workspace.has_shown_notification_once::(MESSAGE_ID, cx) + }) + .unwrap_or(false) + { + cx.update(|cx| { + cx.update_global::(|tracker, _| { + let entry = tracker + .entry(TypeId::of::()) + .or_default(); + if !entry.contains(&MESSAGE_ID) { + entry.push(MESSAGE_ID); + } + }); + }); + } + return; } @@ -3232,11 +3251,33 @@ fn notify_of_new_dock(workspace: &WeakViewHandle, 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::(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)) }) })