title bar: Adjust the onboarding banner component API (#27455)
This PR encapsulates the layout building of the Onboarding Banner component inside of it, allowing to, at the call site, just pass an icon, title, and subtitle. The `subtitle` parameter, by default, uses the `Introducing:` label, which I think will be the one we'll use most of the time for this specific component. Release Notes: - N/A
This commit is contained in:
parent
5953c6167b
commit
152432f1d9
2 changed files with 51 additions and 37 deletions
|
@ -1,9 +1,9 @@
|
||||||
use gpui::{Action, Entity, Global, Render};
|
use gpui::{Action, Entity, Global, Render, SharedString};
|
||||||
use ui::{prelude::*, ButtonLike, Tooltip};
|
use ui::{prelude::*, ButtonLike, Tooltip};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
/// Prompts the user to try Zed's features
|
/// Prompts the user to try newly released Zed's features
|
||||||
pub struct Banner {
|
pub struct OnboardingBanner {
|
||||||
dismissed: bool,
|
dismissed: bool,
|
||||||
source: String,
|
source: String,
|
||||||
details: BannerDetails,
|
details: BannerDetails,
|
||||||
|
@ -11,23 +11,37 @@ pub struct Banner {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct BannerGlobal {
|
struct BannerGlobal {
|
||||||
entity: Entity<Banner>,
|
entity: Entity<OnboardingBanner>,
|
||||||
}
|
}
|
||||||
impl Global for BannerGlobal {}
|
impl Global for BannerGlobal {}
|
||||||
|
|
||||||
pub struct BannerDetails {
|
pub struct BannerDetails {
|
||||||
pub action: Box<dyn Action>,
|
pub action: Box<dyn Action>,
|
||||||
pub banner_label: Box<dyn Fn(&Window, &mut Context<Banner>) -> AnyElement>,
|
pub icon_name: IconName,
|
||||||
|
pub label: SharedString,
|
||||||
|
pub subtitle: Option<SharedString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Banner {
|
impl OnboardingBanner {
|
||||||
pub fn new(source: &str, details: BannerDetails, cx: &mut Context<Self>) -> Self {
|
pub fn new(
|
||||||
|
source: &str,
|
||||||
|
icon_name: IconName,
|
||||||
|
label: impl Into<SharedString>,
|
||||||
|
subtitle: Option<SharedString>,
|
||||||
|
action: Box<dyn Action>,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) -> Self {
|
||||||
cx.set_global(BannerGlobal {
|
cx.set_global(BannerGlobal {
|
||||||
entity: cx.entity(),
|
entity: cx.entity(),
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
source: source.to_string(),
|
source: source.to_string(),
|
||||||
details,
|
details: BannerDetails {
|
||||||
|
action,
|
||||||
|
icon_name,
|
||||||
|
label: label.into(),
|
||||||
|
subtitle: subtitle.or(Some(SharedString::from("Introducing:"))),
|
||||||
|
},
|
||||||
dismissed: get_dismissed(source),
|
dismissed: get_dismissed(source),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,8 +104,8 @@ pub fn restore_banner(cx: &mut App) {
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for Banner {
|
impl Render for OnboardingBanner {
|
||||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
if !self.should_show(cx) {
|
if !self.should_show(cx) {
|
||||||
return div();
|
return div();
|
||||||
}
|
}
|
||||||
|
@ -103,7 +117,24 @@ impl Render for Banner {
|
||||||
.border_color(border_color)
|
.border_color(border_color)
|
||||||
.child(
|
.child(
|
||||||
ButtonLike::new("try-a-feature")
|
ButtonLike::new("try-a-feature")
|
||||||
.child((self.details.banner_label)(window, cx))
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.h_full()
|
||||||
|
.gap_1()
|
||||||
|
.child(Icon::new(self.details.icon_name).size(IconSize::Small))
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_0p5()
|
||||||
|
.when_some(self.details.subtitle.as_ref(), |this, subtitle| {
|
||||||
|
this.child(
|
||||||
|
Label::new(subtitle)
|
||||||
|
.size(LabelSize::Small)
|
||||||
|
.color(Color::Muted),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.child(Label::new(&self.details.label).size(LabelSize::Small)),
|
||||||
|
),
|
||||||
|
)
|
||||||
.on_click(cx.listener(|this, _, window, cx| {
|
.on_click(cx.listener(|this, _, window, cx| {
|
||||||
telemetry::event!("Banner Clicked", source = this.source);
|
telemetry::event!("Banner Clicked", source = this.source);
|
||||||
this.dismiss(cx);
|
this.dismiss(cx);
|
|
@ -1,6 +1,6 @@
|
||||||
mod application_menu;
|
mod application_menu;
|
||||||
mod banner;
|
|
||||||
mod collab;
|
mod collab;
|
||||||
|
mod onboarding_banner;
|
||||||
mod platforms;
|
mod platforms;
|
||||||
mod window_controls;
|
mod window_controls;
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ use crate::application_menu::{
|
||||||
|
|
||||||
use crate::platforms::{platform_linux, platform_mac, platform_windows};
|
use crate::platforms::{platform_linux, platform_mac, platform_windows};
|
||||||
use auto_update::AutoUpdateStatus;
|
use auto_update::AutoUpdateStatus;
|
||||||
use banner::{Banner, BannerDetails};
|
|
||||||
use call::ActiveCall;
|
use call::ActiveCall;
|
||||||
use client::{Client, UserStore};
|
use client::{Client, UserStore};
|
||||||
use feature_flags::{FeatureFlagAppExt, ZedPro};
|
use feature_flags::{FeatureFlagAppExt, ZedPro};
|
||||||
|
@ -25,6 +24,7 @@ use gpui::{
|
||||||
InteractiveElement, Interactivity, IntoElement, MouseButton, ParentElement, Render, Stateful,
|
InteractiveElement, Interactivity, IntoElement, MouseButton, ParentElement, Render, Stateful,
|
||||||
StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window,
|
StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window,
|
||||||
};
|
};
|
||||||
|
use onboarding_banner::OnboardingBanner;
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use rpc::proto;
|
use rpc::proto;
|
||||||
use settings::Settings as _;
|
use settings::Settings as _;
|
||||||
|
@ -39,7 +39,7 @@ use util::ResultExt;
|
||||||
use workspace::{notifications::NotifyResultExt, Workspace};
|
use workspace::{notifications::NotifyResultExt, Workspace};
|
||||||
use zed_actions::{OpenBrowser, OpenRecent, OpenRemote};
|
use zed_actions::{OpenBrowser, OpenRecent, OpenRemote};
|
||||||
|
|
||||||
pub use banner::restore_banner;
|
pub use onboarding_banner::restore_banner;
|
||||||
|
|
||||||
#[cfg(feature = "stories")]
|
#[cfg(feature = "stories")]
|
||||||
pub use stories::*;
|
pub use stories::*;
|
||||||
|
@ -128,7 +128,7 @@ pub struct TitleBar {
|
||||||
should_move: bool,
|
should_move: bool,
|
||||||
application_menu: Option<Entity<ApplicationMenu>>,
|
application_menu: Option<Entity<ApplicationMenu>>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
banner: Entity<Banner>,
|
banner: Entity<OnboardingBanner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for TitleBar {
|
impl Render for TitleBar {
|
||||||
|
@ -316,29 +316,12 @@ impl TitleBar {
|
||||||
subscriptions.push(cx.observe(&user_store, |_, _, cx| cx.notify()));
|
subscriptions.push(cx.observe(&user_store, |_, _, cx| cx.notify()));
|
||||||
|
|
||||||
let banner = cx.new(|cx| {
|
let banner = cx.new(|cx| {
|
||||||
Banner::new(
|
OnboardingBanner::new(
|
||||||
"Git Onboarding",
|
"Git Onboarding",
|
||||||
BannerDetails {
|
IconName::GitBranchSmall,
|
||||||
action: zed_actions::OpenGitIntegrationOnboarding.boxed_clone(),
|
"Git Support",
|
||||||
banner_label: Box::new(|_, _| {
|
None,
|
||||||
h_flex()
|
zed_actions::OpenGitIntegrationOnboarding.boxed_clone(),
|
||||||
.h_full()
|
|
||||||
.items_center()
|
|
||||||
.gap_1()
|
|
||||||
.child(Icon::new(IconName::GitBranchSmall).size(IconSize::Small))
|
|
||||||
.child(
|
|
||||||
h_flex()
|
|
||||||
.gap_0p5()
|
|
||||||
.child(
|
|
||||||
Label::new("Introducing:")
|
|
||||||
.size(LabelSize::Small)
|
|
||||||
.color(Color::Muted),
|
|
||||||
)
|
|
||||||
.child(Label::new("Git Support").size(LabelSize::Small)),
|
|
||||||
)
|
|
||||||
.into_any_element()
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue