Compare commits

...

3 Commits

Author SHA1 Message Date
Nate Butler
c00f5f08bc Merge branch 'main' into fix-agentic-editing-upsell-graphic 2025-05-07 12:43:35 -04:00
Nate Butler
d7a136686c Tidy up onboarding modal graphic 2025-05-07 12:43:02 -04:00
Nate Butler
903529695d add onboarding_banner preview 2025-05-07 12:42:50 -04:00
4 changed files with 90 additions and 4 deletions

2
Cargo.lock generated
View File

@@ -15085,9 +15085,11 @@ dependencies = [
"chrono",
"client",
"collections",
"component",
"db",
"gpui",
"http_client",
"linkme",
"notifications",
"pretty_assertions",
"project",

View File

@@ -1,5 +1,6 @@
use gpui::{
ClickEvent, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, MouseDownEvent, Render,
linear_color_stop, linear_gradient,
};
use ui::{TintColor, Vector, VectorName, prelude::*};
use workspace::{ModalView, Workspace};
@@ -110,6 +111,34 @@ impl Render for AgentOnboardingModal {
.color(ui::Color::Custom(cx.theme().colors().text.alpha(0.32))),
),
)
.child(
div()
.absolute()
.top_0()
.right_0()
.w(px(660.))
.h(px(801.))
.overflow_hidden()
.bg(linear_gradient(
75.,
linear_color_stop(cx.theme().colors().panel_background.alpha(0.01), 1.0),
linear_color_stop(cx.theme().colors().panel_background, 0.45),
)),
)
.child(
div()
.absolute()
.bottom_0()
.right_0()
.w(px(660.))
.h(px(301.))
.overflow_hidden()
.bg(linear_gradient(
0.,
linear_color_stop(cx.theme().colors().panel_background.alpha(0.01), 1.0),
linear_color_stop(cx.theme().colors().panel_background, 0.),
)),
)
.child(
v_flex()
.w_full()

View File

@@ -31,8 +31,10 @@ auto_update.workspace = true
call.workspace = true
chrono.workspace = true
client.workspace = true
component.workspace = true
db.workspace = true
gpui.workspace = true
linkme.workspace = true
notifications.workspace = true
project.workspace = true
remote.workspace = true
@@ -46,9 +48,9 @@ telemetry.workspace = true
theme.workspace = true
ui.workspace = true
util.workspace = true
workspace-hack.workspace = true
workspace.workspace = true
zed_actions.workspace = true
workspace-hack.workspace = true
[target.'cfg(windows)'.dependencies]
windows.workspace = true

View File

@@ -1,12 +1,14 @@
use gpui::{Action, Entity, Global, Render, SharedString};
use ui::{ButtonLike, Tooltip, prelude::*};
use ui::{ButtonLike, Tooltip, component_prelude::*, prelude::*};
use util::ResultExt;
/// Prompts the user to try newly released Zed's features
#[derive(RegisterComponent)]
pub struct OnboardingBanner {
dismissed: bool,
source: String,
details: BannerDetails,
_force_show: bool, // used for previews
}
#[derive(Clone)]
@@ -43,11 +45,12 @@ impl OnboardingBanner {
subtitle: subtitle.or(Some(SharedString::from("Introducing:"))),
},
dismissed: get_dismissed(source),
_force_show: false,
}
}
fn should_show(&self, _cx: &mut App) -> bool {
!self.dismissed
!self.dismissed || self._force_show
}
fn dismiss(&mut self, cx: &mut Context<Self>) {
@@ -56,6 +59,14 @@ impl OnboardingBanner {
self.dismissed = true;
cx.notify();
}
/// Force the banner to show regardless of its dismissal status.
///
/// Used for previews and testing.
fn _force_show(mut self, force: bool) -> Self {
self._force_show = force;
self
}
}
fn dismissed_at_key(source: &str) -> String {
@@ -105,7 +116,7 @@ pub fn restore_banner(cx: &mut App) {
impl Render for OnboardingBanner {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
if !self.should_show(cx) {
if !self.should_show(cx) && !self._force_show {
return div();
}
@@ -160,3 +171,45 @@ impl Render for OnboardingBanner {
div().pr_2().child(banner)
}
}
impl Component for OnboardingBanner {
fn scope() -> ComponentScope {
ComponentScope::Notification
}
fn status() -> ComponentStatus {
ComponentStatus::Live
}
fn description() -> Option<&'static str> {
Some(
"A banner shown in the title bar used for announcing new features. Clicking the banner triggers some action, such as opening a modal. Once dismissed, it won't show again for a given feature.",
)
}
fn preview(_window: &mut Window, cx: &mut App) -> Option<AnyElement> {
let agent_banner = cx.new(|cx| {
OnboardingBanner::new(
"Agentic Onboarding",
IconName::ZedAssistant,
"Agentic Editing",
None,
zed_actions::agent::OpenOnboardingModal.boxed_clone(),
cx,
)
._force_show(true)
});
Some(
v_flex()
.gap_6()
.w_full()
.flex_none()
.children(vec![example_group(vec![single_example(
"Agent Example",
agent_banner.clone().into_any_element(),
)])])
.into_any_element(),
)
}
}