diff --git a/Cargo.lock b/Cargo.lock index 6cf3df6920cb873037639ea37b08275974273bd3..71ebbaf7f18f08adfbd26c432a83866015312cf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3448,7 +3448,6 @@ dependencies = [ "serde_json", "settings", "smallvec", - "story", "telemetry", "theme", "time", @@ -15917,7 +15916,6 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", - "collab_ui", "ctrlc", "dialoguer", "editor", diff --git a/crates/collab_ui/Cargo.toml b/crates/collab_ui/Cargo.toml index 40aa29f9b81cee9e01068925e036991650e1258b..c996e3821fee17dbea99f660304e0b76b6e9bc28 100644 --- a/crates/collab_ui/Cargo.toml +++ b/crates/collab_ui/Cargo.toml @@ -14,7 +14,6 @@ doctest = false [features] default = [] -stories = ["dep:story"] test-support = [ "call/test-support", "client/test-support", @@ -52,7 +51,6 @@ serde.workspace = true serde_json.workspace = true settings.workspace = true smallvec.workspace = true -story = { workspace = true, optional = true } telemetry.workspace = true theme.workspace = true time.workspace = true diff --git a/crates/collab_ui/src/notifications.rs b/crates/collab_ui/src/notifications.rs index f5597895dd62ea3eaa08e537b8d7ce178482ab35..e59477859254418a6e73e275b975289cc98a188d 100644 --- a/crates/collab_ui/src/notifications.rs +++ b/crates/collab_ui/src/notifications.rs @@ -1,17 +1,10 @@ -mod collab_notification; pub mod incoming_call_notification; pub mod project_shared_notification; -#[cfg(feature = "stories")] -mod stories; - use gpui::App; use std::sync::Arc; use workspace::AppState; -#[cfg(feature = "stories")] -pub use stories::*; - pub fn init(app_state: &Arc, cx: &mut App) { incoming_call_notification::init(app_state, cx); project_shared_notification::init(app_state, cx); diff --git a/crates/collab_ui/src/notifications/collab_notification.rs b/crates/collab_ui/src/notifications/collab_notification.rs deleted file mode 100644 index 9d5541d9c20ef49286bb1bd1f40a64874f8eaf13..0000000000000000000000000000000000000000 --- a/crates/collab_ui/src/notifications/collab_notification.rs +++ /dev/null @@ -1,52 +0,0 @@ -use gpui::{AnyElement, SharedUri, img, prelude::*}; -use smallvec::SmallVec; -use ui::prelude::*; - -#[derive(IntoElement)] -pub struct CollabNotification { - avatar_uri: SharedUri, - accept_button: Button, - dismiss_button: Button, - children: SmallVec<[AnyElement; 2]>, -} - -impl CollabNotification { - pub fn new( - avatar_uri: impl Into, - accept_button: Button, - dismiss_button: Button, - ) -> Self { - Self { - avatar_uri: avatar_uri.into(), - accept_button, - dismiss_button, - children: SmallVec::new(), - } - } -} - -impl ParentElement for CollabNotification { - fn extend(&mut self, elements: impl IntoIterator) { - self.children.extend(elements) - } -} - -impl RenderOnce for CollabNotification { - fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { - h_flex() - .text_ui(cx) - .justify_between() - .size_full() - .overflow_hidden() - .elevation_3(cx) - .p_2() - .gap_2() - .child(img(self.avatar_uri).w_12().h_12().rounded_full()) - .child(v_flex().overflow_hidden().children(self.children)) - .child( - v_flex() - .child(self.accept_button) - .child(self.dismiss_button), - ) - } -} diff --git a/crates/collab_ui/src/notifications/incoming_call_notification.rs b/crates/collab_ui/src/notifications/incoming_call_notification.rs index 592f39f67679f94199afb86123ee389336cb9347..aabb477072c97f829ab64971488ab66d2f6a79e4 100644 --- a/crates/collab_ui/src/notifications/incoming_call_notification.rs +++ b/crates/collab_ui/src/notifications/incoming_call_notification.rs @@ -1,11 +1,10 @@ use crate::notification_window_options; -use crate::notifications::collab_notification::CollabNotification; use call::{ActiveCall, IncomingCall}; use futures::StreamExt; use gpui::{App, WindowHandle, prelude::*}; use std::sync::{Arc, Weak}; -use ui::{Button, Label, prelude::*}; +use ui::{CollabNotification, prelude::*}; use util::ResultExt; use workspace::AppState; @@ -118,10 +117,10 @@ impl Render for IncomingCallNotification { move |_, _, cx| state.respond(false, cx) }), ) - .child(v_flex().overflow_hidden().child(Label::new(format!( + .child(Label::new(format!( "{} is sharing a project in Zed", self.state.call.calling_user.github_login - )))), + ))), ) } } diff --git a/crates/collab_ui/src/notifications/project_shared_notification.rs b/crates/collab_ui/src/notifications/project_shared_notification.rs index b21a2dfcb7a73c2e8a483097f9589cc6626fd2ca..165e46458438850f872794d057c17faee86775e2 100644 --- a/crates/collab_ui/src/notifications/project_shared_notification.rs +++ b/crates/collab_ui/src/notifications/project_shared_notification.rs @@ -1,12 +1,11 @@ use crate::notification_window_options; -use crate::notifications::collab_notification::CollabNotification; use call::{ActiveCall, room}; use client::User; use collections::HashMap; use gpui::{App, Size}; use std::sync::{Arc, Weak}; -use ui::{Button, Label, prelude::*}; +use ui::{CollabNotification, prelude::*}; use util::ResultExt; use workspace::AppState; @@ -122,6 +121,14 @@ impl ProjectSharedNotification { impl Render for ProjectSharedNotification { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { let ui_font = theme::setup_ui_font(window, cx); + let no_worktree_root_names = self.worktree_root_names.is_empty(); + + let punctuation = if no_worktree_root_names { "" } else { ":" }; + let main_label = format!( + "{} is sharing a project with you{}", + self.owner.github_login.clone(), + punctuation + ); div().size_full().font(ui_font).child( CollabNotification::new( @@ -135,19 +142,9 @@ impl Render for ProjectSharedNotification { }, )), ) - .child(Label::new(self.owner.github_login.clone())) - .child(Label::new(format!( - "is sharing a project in Zed{}", - if self.worktree_root_names.is_empty() { - "" - } else { - ":" - } - ))) - .children(if self.worktree_root_names.is_empty() { - None - } else { - Some(Label::new(self.worktree_root_names.join(", "))) + .child(Label::new(main_label)) + .when(!no_worktree_root_names, |this| { + this.child(Label::new(self.worktree_root_names.join(", ")).color(Color::Muted)) }), ) } diff --git a/crates/collab_ui/src/notifications/stories/collab_notification.rs b/crates/collab_ui/src/notifications/stories/collab_notification.rs deleted file mode 100644 index 8dc602a3201fa67dca7ad7d9e3efdb5911ae7796..0000000000000000000000000000000000000000 --- a/crates/collab_ui/src/notifications/stories/collab_notification.rs +++ /dev/null @@ -1,48 +0,0 @@ -use gpui::prelude::*; -use story::{Story, StoryItem, StorySection}; -use ui::prelude::*; - -use crate::notifications::collab_notification::CollabNotification; - -pub struct CollabNotificationStory; - -impl Render for CollabNotificationStory { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - let window_container = |width, height| div().w(px(width)).h(px(height)); - - Story::container(cx) - .child(Story::title_for::(cx)) - .child( - StorySection::new().child(StoryItem::new( - "Incoming Call Notification", - window_container(400., 72.).child( - CollabNotification::new( - "https://avatars.githubusercontent.com/u/1486634?v=4", - Button::new("accept", "Accept"), - Button::new("decline", "Decline"), - ) - .child( - v_flex() - .overflow_hidden() - .child(Label::new("maxdeviant is sharing a project in Zed")), - ), - ), - )), - ) - .child( - StorySection::new().child(StoryItem::new( - "Project Shared Notification", - window_container(400., 72.).child( - CollabNotification::new( - "https://avatars.githubusercontent.com/u/1714999?v=4", - Button::new("open", "Open"), - Button::new("dismiss", "Dismiss"), - ) - .child(Label::new("iamnbutler")) - .child(Label::new("is sharing a project in Zed:")) - .child(Label::new("zed")), - ), - )), - ) - } -} diff --git a/crates/storybook/Cargo.toml b/crates/storybook/Cargo.toml index 148f036134a944283d9c07c69641a4fbcd49a134..1c8dc3611e79fc7cd0f10b49cb6d581611a729db 100644 --- a/crates/storybook/Cargo.toml +++ b/crates/storybook/Cargo.toml @@ -15,7 +15,6 @@ path = "src/storybook.rs" [dependencies] anyhow.workspace = true clap = { workspace = true, features = ["derive", "string"] } -collab_ui = { workspace = true, features = ["stories"] } ctrlc = "3.4" dialoguer = { version = "0.11.0", features = ["fuzzy-select"] } editor.workspace = true diff --git a/crates/storybook/src/story_selector.rs b/crates/storybook/src/story_selector.rs index 7f70d58b3b4e5cfb7c23b60c84b17a6a941f0804..4c1113f70f54051bab973595f6f7e7bdbc9c0029 100644 --- a/crates/storybook/src/story_selector.rs +++ b/crates/storybook/src/story_selector.rs @@ -13,7 +13,6 @@ use ui::prelude::*; pub enum ComponentStory { ApplicationMenu, AutoHeightEditor, - CollabNotification, ContextMenu, Cursor, Focus, @@ -33,9 +32,6 @@ impl ComponentStory { .new(|cx| title_bar::ApplicationMenuStory::new(window, cx)) .into(), Self::AutoHeightEditor => AutoHeightEditorStory::new(window, cx).into(), - Self::CollabNotification => cx - .new(|_| collab_ui::notifications::CollabNotificationStory) - .into(), Self::ContextMenu => cx.new(|_| ui::ContextMenuStory).into(), Self::Cursor => cx.new(|_| crate::stories::CursorStory).into(), Self::Focus => FocusStory::model(window, cx).into(), diff --git a/crates/ui/src/components.rs b/crates/ui/src/components.rs index c08e46c5882cf3c9e0a8e205c8b23224d3a7a8e1..60e966e3429e6b72743fd9fdc957b0f2581ca4b7 100644 --- a/crates/ui/src/components.rs +++ b/crates/ui/src/components.rs @@ -4,6 +4,7 @@ mod banner; mod button; mod callout; mod chip; +mod collab; mod content_group; mod context_menu; mod data_table; @@ -50,6 +51,7 @@ pub use banner::*; pub use button::*; pub use callout::*; pub use chip::*; +pub use collab::*; pub use content_group::*; pub use context_menu::*; pub use data_table::*; diff --git a/crates/collab_ui/src/notifications/stories.rs b/crates/ui/src/components/collab.rs similarity index 100% rename from crates/collab_ui/src/notifications/stories.rs rename to crates/ui/src/components/collab.rs diff --git a/crates/ui/src/components/collab/collab_notification.rs b/crates/ui/src/components/collab/collab_notification.rs new file mode 100644 index 0000000000000000000000000000000000000000..0c3fca84e9b9fb3246de20b9b1f077202fa3ebdb --- /dev/null +++ b/crates/ui/src/components/collab/collab_notification.rs @@ -0,0 +1,134 @@ +use gpui::{AnyElement, SharedUri, prelude::*}; +use smallvec::SmallVec; + +use crate::{Avatar, prelude::*}; + +#[derive(IntoElement, RegisterComponent)] +pub struct CollabNotification { + avatar_uri: SharedUri, + accept_button: Button, + dismiss_button: Button, + children: SmallVec<[AnyElement; 2]>, +} + +impl CollabNotification { + pub fn new( + avatar_uri: impl Into, + accept_button: Button, + dismiss_button: Button, + ) -> Self { + Self { + avatar_uri: avatar_uri.into(), + accept_button, + dismiss_button, + children: SmallVec::new(), + } + } +} + +impl ParentElement for CollabNotification { + fn extend(&mut self, elements: impl IntoIterator) { + self.children.extend(elements) + } +} + +impl RenderOnce for CollabNotification { + fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { + h_flex() + .p_2() + .size_full() + .text_ui(cx) + .justify_between() + .overflow_hidden() + .elevation_3(cx) + .gap_1() + .child( + h_flex() + .min_w_0() + .gap_4() + .child(Avatar::new(self.avatar_uri).size(px(40.))) + .child(v_flex().truncate().children(self.children)), + ) + .child( + v_flex() + .items_center() + .child(self.accept_button) + .child(self.dismiss_button), + ) + } +} + +impl Component for CollabNotification { + fn scope() -> ComponentScope { + ComponentScope::Collaboration + } + + fn preview(_window: &mut Window, _cx: &mut App) -> Option { + let avatar = "https://avatars.githubusercontent.com/u/67129314?v=4"; + let container = || div().h(px(72.)).w(px(400.)); // Size of the actual notification window + + let examples = vec![ + single_example( + "Incoming Call", + container() + .child( + CollabNotification::new( + avatar, + Button::new("accept", "Accept"), + Button::new("decline", "Decline"), + ) + .child(Label::new("the user is inviting you to a call")), + ) + .into_any_element(), + ), + single_example( + "Screen Share Request", + container() + .child( + CollabNotification::new( + avatar, + Button::new("accept", "View"), + Button::new("decline", "Ignore"), + ) + .child(Label::new("the user is sharing their screen")), + ) + .into_any_element(), + ), + single_example( + "Project Shared", + container() + .child( + CollabNotification::new( + avatar, + Button::new("accept", "Open"), + Button::new("decline", "Dismiss"), + ) + .child(Label::new("the user is sharing a project")) + .child(Label::new("zed").color(Color::Muted)), + ) + .into_any_element(), + ), + single_example( + "Overflowing Content", + container() + .child( + CollabNotification::new( + avatar, + Button::new("accept", "Accept"), + Button::new("decline", "Decline"), + ) + .child(Label::new( + "a_very_long_username_that_might_overflow is sharing a project in Zed:", + )) + .child( + Label::new("zed-cloud, zed, edit-prediction-bench, zed.dev") + .color(Color::Muted), + ), + ) + .into_any_element(), + ), + ]; + + Some(example_group(examples).vertical().into_any_element()) + } +}