git: Add an onboarding and banner flow (#26518)
TODO: - [ ] Hide the reset onboarding action (only useful for development, uncomment: https://github.com/zed-industries/zed/pull/26518/files#diff-f0ce01d9a3df30f60c64b6f9906c54aa0191246a58dbf5297ee321575a180879R96) - [x] Get a designer to replace the modal background (@danilo-leal) Release Notes: - Added a small onboarding banner for the git launch --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com> Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
This commit is contained in:
parent
5f74297576
commit
45b126a977
9 changed files with 352 additions and 10 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -5450,7 +5450,9 @@ dependencies = [
|
|||
"askpass",
|
||||
"assistant_settings",
|
||||
"buffer_diff",
|
||||
"chrono",
|
||||
"collections",
|
||||
"command_palette_hooks",
|
||||
"component",
|
||||
"ctor",
|
||||
"db",
|
||||
|
@ -13984,6 +13986,7 @@ dependencies = [
|
|||
"client",
|
||||
"collections",
|
||||
"feature_flags",
|
||||
"git_ui",
|
||||
"gpui",
|
||||
"http_client",
|
||||
"notifications",
|
||||
|
|
40
assets/icons/git_onboarding_bg.svg
Normal file
40
assets/icons/git_onboarding_bg.svg
Normal file
|
@ -0,0 +1,40 @@
|
|||
<svg width="400" height="120" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="tilePattern" width="124" height="24" patternUnits="userSpaceOnUse">
|
||||
<svg width="124" height="24" viewBox="0 0 124 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.2">
|
||||
<path d="M16.666 12.0013L11.9993 16.668L7.33268 12.0013" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 7.33464L12 16.668" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29 8.33464C29.3682 8.33464 29.6667 8.03616 29.6667 7.66797C29.6667 7.29978 29.3682 7.0013 29 7.0013C28.6318 7.0013 28.3333 7.29978 28.3333 7.66797C28.3333 8.03616 28.6318 8.33464 29 8.33464ZM29 9.66797C30.1046 9.66797 31 8.77254 31 7.66797C31 6.5634 30.1046 5.66797 29 5.66797C27.8954 5.66797 27 6.5634 27 7.66797C27 8.77254 27.8954 9.66797 29 9.66797Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M35 8.33464C35.3682 8.33464 35.6667 8.03616 35.6667 7.66797C35.6667 7.29978 35.3682 7.0013 35 7.0013C34.6318 7.0013 34.3333 7.29978 34.3333 7.66797C34.3333 8.03616 34.6318 8.33464 35 8.33464ZM35 9.66797C36.1046 9.66797 37 8.77254 37 7.66797C37 6.5634 36.1046 5.66797 35 5.66797C33.8954 5.66797 33 6.5634 33 7.66797C33 8.77254 33.8954 9.66797 35 9.66797Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29 16.9987C29.3682 16.9987 29.6667 16.7002 29.6667 16.332C29.6667 15.9638 29.3682 15.6654 29 15.6654C28.6318 15.6654 28.3333 15.9638 28.3333 16.332C28.3333 16.7002 28.6318 16.9987 29 16.9987ZM29 18.332C30.1046 18.332 31 17.4366 31 16.332C31 15.2275 30.1046 14.332 29 14.332C27.8954 14.332 27 15.2275 27 16.332C27 17.4366 27.8954 18.332 29 18.332Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.334 9H29.6673V11.4615C30.2383 11.1443 31.0005 11 32.0007 11H33.6675C34.0356 11 34.334 10.7017 34.334 10.3333V9H35.6673V10.3333C35.6673 11.4378 34.7723 12.3333 33.6675 12.3333H32.0007C30.8614 12.3333 30.3692 12.5484 30.1298 12.7549C29.9016 12.9516 29.7857 13.2347 29.6673 13.742V15H28.334V9Z" fill="white"/>
|
||||
<path d="M48.668 8.66406H55.3346V15.3307" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M48.668 15.3307L55.3346 8.66406" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M76.5871 9.40624C76.8514 9.14195 77 8.78346 77 8.40965C77 8.03583 76.8516 7.67731 76.5873 7.41295C76.323 7.14859 75.9645 7.00005 75.5907 7C75.2169 6.99995 74.8584 7.14841 74.594 7.4127L67.921 14.0874C67.8049 14.2031 67.719 14.3456 67.671 14.5024L67.0105 16.6784C66.9975 16.7217 66.9966 16.7676 67.0076 16.8113C67.0187 16.8551 67.0414 16.895 67.0734 16.9269C67.1053 16.9588 67.1453 16.9815 67.1891 16.9925C67.2328 17.0035 67.2788 17.0024 67.322 16.9894L69.4985 16.3294C69.6551 16.2818 69.7976 16.1964 69.9135 16.0809L76.5871 9.40624Z" stroke="white" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M74 8L76 10" stroke="white" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M70.3877 7.53516V6.53516" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M73.5693 16.6992V17.6992" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M66.3877 10.5352H67.3877" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M77.5693 13.6992H76.5693" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M68.3877 8.53516L67.3877 7.53516" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M75.5693 15.6992L76.5693 16.6992" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M87.334 11.9987L92.0007 7.33203L96.6673 11.9987" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M92 16.6654V7.33203" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M117 12C117 10.6739 116.473 9.40215 115.536 8.46447C114.598 7.52678 113.326 7 112 7C110.602 7.00526 109.261 7.55068 108.256 8.52222L107 9.77778" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M107 7V9.77778H109.778" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M107 12C107 13.3261 107.527 14.5979 108.464 15.5355C109.402 16.4732 110.674 17 112 17C113.398 16.9947 114.739 16.4493 115.744 15.4778L117 14.2222" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M114.223 14.2188H117V16.9965" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
</pattern>
|
||||
<linearGradient id="fade" y2="1" x2="0">
|
||||
<stop offset="0" stop-color="white" stop-opacity=".52"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<mask id="fadeMask" maskContentUnits="objectBoundingBox">
|
||||
<rect width="1" height="1" fill="url(#fade)"/>
|
||||
</mask>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#tilePattern)" mask="url(#fadeMask)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 5.4 KiB |
|
@ -21,7 +21,9 @@ anyhow.workspace = true
|
|||
askpass.workspace = true
|
||||
assistant_settings.workspace = true
|
||||
buffer_diff.workspace = true
|
||||
chrono.workspace = true
|
||||
collections.workspace = true
|
||||
command_palette_hooks.workspace = true
|
||||
component.workspace = true
|
||||
db.workspace = true
|
||||
editor.workspace = true
|
||||
|
|
|
@ -702,7 +702,10 @@ impl GitPanel {
|
|||
let mut dispatch_context = KeyContext::new_with_defaults();
|
||||
dispatch_context.add("GitPanel");
|
||||
|
||||
if self.is_focused(window, cx) {
|
||||
if window
|
||||
.focused(cx)
|
||||
.map_or(false, |focused| self.focus_handle == focused)
|
||||
{
|
||||
dispatch_context.add("menu");
|
||||
dispatch_context.add("ChangesList");
|
||||
}
|
||||
|
@ -714,12 +717,6 @@ impl GitPanel {
|
|||
dispatch_context
|
||||
}
|
||||
|
||||
fn is_focused(&self, window: &Window, cx: &Context<Self>) -> bool {
|
||||
window
|
||||
.focused(cx)
|
||||
.map_or(false, |focused| self.focus_handle == focused)
|
||||
}
|
||||
|
||||
fn close_panel(&mut self, _: &Close, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
cx.emit(PanelEvent::Close);
|
||||
}
|
||||
|
@ -3811,8 +3808,12 @@ impl Render for GitPanel {
|
|||
}
|
||||
|
||||
impl Focusable for GitPanel {
|
||||
fn focus_handle(&self, _: &App) -> gpui::FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
fn focus_handle(&self, cx: &App) -> gpui::FocusHandle {
|
||||
if self.entries.is_empty() {
|
||||
self.commit_editor.focus_handle(cx)
|
||||
} else {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
use std::any::Any;
|
||||
|
||||
use ::settings::Settings;
|
||||
use command_palette_hooks::CommandPaletteFilter;
|
||||
use git::{
|
||||
repository::{Branch, Upstream, UpstreamTracking, UpstreamTrackingStatus},
|
||||
status::{FileStatus, StatusCode, UnmergedStatus, UnmergedStatusCode},
|
||||
};
|
||||
use git_panel_settings::GitPanelSettings;
|
||||
use gpui::{App, Entity, FocusHandle};
|
||||
use gpui::{actions, App, Entity, FocusHandle};
|
||||
use onboarding::{clear_dismissed, GitOnboardingModal};
|
||||
use project::Project;
|
||||
use project_diff::ProjectDiff;
|
||||
use ui::prelude::*;
|
||||
|
@ -15,11 +19,14 @@ pub mod branch_picker;
|
|||
mod commit_modal;
|
||||
pub mod git_panel;
|
||||
mod git_panel_settings;
|
||||
pub mod onboarding;
|
||||
pub mod picker_prompt;
|
||||
pub mod project_diff;
|
||||
pub(crate) mod remote_output;
|
||||
pub mod repository_selector;
|
||||
|
||||
actions!(git, [ResetOnboarding]);
|
||||
|
||||
pub fn init(cx: &mut App) {
|
||||
GitPanelSettings::register(cx);
|
||||
branch_picker::init(cx);
|
||||
|
@ -82,6 +89,21 @@ pub fn init(cx: &mut App) {
|
|||
panel.unstage_all(action, window, cx);
|
||||
});
|
||||
});
|
||||
CommandPaletteFilter::update_global(cx, |filter, _cx| {
|
||||
filter.hide_action_types(&[
|
||||
zed_actions::OpenGitIntegrationOnboarding.type_id(),
|
||||
// ResetOnboarding.type_id(),
|
||||
]);
|
||||
});
|
||||
workspace.register_action(
|
||||
move |workspace, _: &zed_actions::OpenGitIntegrationOnboarding, window, cx| {
|
||||
GitOnboardingModal::toggle(workspace, window, cx)
|
||||
},
|
||||
);
|
||||
workspace.register_action(move |_, _: &ResetOnboarding, window, cx| {
|
||||
clear_dismissed(cx);
|
||||
window.refresh();
|
||||
});
|
||||
workspace.register_action(|workspace, _action: &git::Init, window, cx| {
|
||||
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
||||
return;
|
||||
|
|
267
crates/git_ui/src/onboarding.rs
Normal file
267
crates/git_ui/src/onboarding.rs
Normal file
|
@ -0,0 +1,267 @@
|
|||
use gpui::{
|
||||
svg, ClickEvent, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Global,
|
||||
MouseDownEvent, Render,
|
||||
};
|
||||
use ui::{prelude::*, ButtonLike, TintColor, Tooltip};
|
||||
use util::ResultExt;
|
||||
use workspace::{ModalView, Workspace};
|
||||
|
||||
use crate::git_panel::GitPanel;
|
||||
|
||||
macro_rules! git_onboarding_event {
|
||||
($name:expr) => {
|
||||
telemetry::event!($name, source = "Git Onboarding");
|
||||
};
|
||||
($name:expr, $($key:ident $(= $value:expr)?),+ $(,)?) => {
|
||||
telemetry::event!($name, source = "Git Onboarding", $($key $(= $value)?),+);
|
||||
};
|
||||
}
|
||||
|
||||
/// Introduces user to the Git Panel and overall improved Git support
|
||||
pub struct GitOnboardingModal {
|
||||
focus_handle: FocusHandle,
|
||||
workspace: Entity<Workspace>,
|
||||
}
|
||||
|
||||
impl GitOnboardingModal {
|
||||
pub fn toggle(workspace: &mut Workspace, window: &mut Window, cx: &mut Context<Workspace>) {
|
||||
let workspace_entity = cx.entity();
|
||||
workspace.toggle_modal(window, cx, |_window, cx| Self {
|
||||
workspace: workspace_entity,
|
||||
focus_handle: cx.focus_handle(),
|
||||
});
|
||||
}
|
||||
|
||||
fn open_panel(&mut self, _: &ClickEvent, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.workspace.update(cx, |workspace, cx| {
|
||||
workspace.focus_panel::<GitPanel>(window, cx);
|
||||
});
|
||||
|
||||
cx.emit(DismissEvent);
|
||||
|
||||
git_onboarding_event!("Open Panel Clicked");
|
||||
}
|
||||
|
||||
fn view_blog(&mut self, _: &ClickEvent, _: &mut Window, cx: &mut Context<Self>) {
|
||||
cx.open_url("https://zed.dev/blog/git");
|
||||
cx.notify();
|
||||
|
||||
git_onboarding_event!("Blog Link Clicked");
|
||||
}
|
||||
|
||||
fn cancel(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<DismissEvent> for GitOnboardingModal {}
|
||||
|
||||
impl Focusable for GitOnboardingModal {
|
||||
fn focus_handle(&self, _cx: &App) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalView for GitOnboardingModal {}
|
||||
|
||||
impl Render for GitOnboardingModal {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let window_height = window.viewport_size().height;
|
||||
let max_height = window_height - px(200.);
|
||||
|
||||
let base = v_flex()
|
||||
.id("git-onboarding")
|
||||
.key_context("GitOnboardingModal")
|
||||
.relative()
|
||||
.w(px(450.))
|
||||
.h_full()
|
||||
.max_h(max_height)
|
||||
.p_4()
|
||||
.gap_2()
|
||||
.elevation_3(cx)
|
||||
.track_focus(&self.focus_handle(cx))
|
||||
.overflow_hidden()
|
||||
.on_action(cx.listener(Self::cancel))
|
||||
.on_action(cx.listener(|_, _: &menu::Cancel, _window, cx| {
|
||||
git_onboarding_event!("Cancelled", trigger = "Action");
|
||||
cx.emit(DismissEvent);
|
||||
}))
|
||||
.on_any_mouse_down(cx.listener(|this, _: &MouseDownEvent, window, _cx| {
|
||||
this.focus_handle.focus(window);
|
||||
}))
|
||||
.child(
|
||||
div().p_1p5().absolute().inset_0().h(px(160.)).child(
|
||||
svg()
|
||||
.path("icons/git_onboarding_bg.svg")
|
||||
.text_color(cx.theme().colors().icon_disabled)
|
||||
.w(px(420.))
|
||||
.h(px(128.))
|
||||
.overflow_hidden(),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
.w_full()
|
||||
.gap_1()
|
||||
.child(
|
||||
Label::new("Introducing")
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(Headline::new("Native Git Support").size(HeadlineSize::Large)),
|
||||
)
|
||||
.child(h_flex().absolute().top_2().right_2().child(
|
||||
IconButton::new("cancel", IconName::X).on_click(cx.listener(
|
||||
|_, _: &ClickEvent, _window, cx| {
|
||||
git_onboarding_event!("Cancelled", trigger = "X click");
|
||||
cx.emit(DismissEvent);
|
||||
},
|
||||
)),
|
||||
));
|
||||
|
||||
let open_panel_button = Button::new("open-panel", "Get Started with the Git Panel")
|
||||
.icon_size(IconSize::Indicator)
|
||||
.style(ButtonStyle::Tinted(TintColor::Accent))
|
||||
.full_width()
|
||||
.on_click(cx.listener(Self::open_panel));
|
||||
|
||||
let blog_post_button = Button::new("view-blog", "Check out the Blog Post")
|
||||
.icon(IconName::ArrowUpRight)
|
||||
.icon_size(IconSize::Indicator)
|
||||
.icon_color(Color::Muted)
|
||||
.full_width()
|
||||
.on_click(cx.listener(Self::view_blog));
|
||||
|
||||
let copy = "First-class support for staging, committing, pulling, pushing, viewing diffs, and more. All without leaving Zed.";
|
||||
|
||||
base.child(Label::new(copy).color(Color::Muted)).child(
|
||||
v_flex()
|
||||
.w_full()
|
||||
.mt_2()
|
||||
.gap_2()
|
||||
.child(open_panel_button)
|
||||
.child(blog_post_button),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Prompts the user to try Zed's git features
|
||||
pub struct GitBanner {
|
||||
dismissed: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct GitBannerGlobal(Entity<GitBanner>);
|
||||
impl Global for GitBannerGlobal {}
|
||||
|
||||
impl GitBanner {
|
||||
pub fn new(cx: &mut Context<Self>) -> Self {
|
||||
cx.set_global(GitBannerGlobal(cx.entity()));
|
||||
Self {
|
||||
dismissed: get_dismissed(),
|
||||
}
|
||||
}
|
||||
|
||||
fn should_show(&self, _cx: &mut App) -> bool {
|
||||
!self.dismissed
|
||||
}
|
||||
|
||||
fn dismiss(&mut self, cx: &mut Context<Self>) {
|
||||
git_onboarding_event!("Banner Dismissed");
|
||||
persist_dismissed(cx);
|
||||
self.dismissed = true;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
const DISMISSED_AT_KEY: &str = "zed_git_banner_dismissed_at";
|
||||
|
||||
fn get_dismissed() -> bool {
|
||||
db::kvp::KEY_VALUE_STORE
|
||||
.read_kvp(DISMISSED_AT_KEY)
|
||||
.log_err()
|
||||
.map_or(false, |dismissed| dismissed.is_some())
|
||||
}
|
||||
|
||||
fn persist_dismissed(cx: &mut App) {
|
||||
cx.spawn(|_| {
|
||||
let time = chrono::Utc::now().to_rfc3339();
|
||||
db::kvp::KEY_VALUE_STORE.write_kvp(DISMISSED_AT_KEY.into(), time)
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
pub(crate) fn clear_dismissed(cx: &mut App) {
|
||||
cx.defer(|cx| {
|
||||
cx.global::<GitBannerGlobal>()
|
||||
.clone()
|
||||
.0
|
||||
.update(cx, |this, cx| {
|
||||
this.dismissed = false;
|
||||
cx.notify();
|
||||
});
|
||||
});
|
||||
|
||||
cx.spawn(|_| db::kvp::KEY_VALUE_STORE.delete_kvp(DISMISSED_AT_KEY.into()))
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
impl Render for GitBanner {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
if !self.should_show(cx) {
|
||||
return div();
|
||||
}
|
||||
|
||||
let border_color = cx.theme().colors().editor_foreground.opacity(0.3);
|
||||
let banner = h_flex()
|
||||
.rounded_sm()
|
||||
.border_1()
|
||||
.border_color(border_color)
|
||||
.child(
|
||||
ButtonLike::new("try-git")
|
||||
.child(
|
||||
h_flex()
|
||||
.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)),
|
||||
),
|
||||
)
|
||||
.on_click(cx.listener(|this, _, window, cx| {
|
||||
git_onboarding_event!("Banner Clicked");
|
||||
this.dismiss(cx);
|
||||
window.dispatch_action(
|
||||
Box::new(zed_actions::OpenGitIntegrationOnboarding),
|
||||
cx,
|
||||
)
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
div().border_l_1().border_color(border_color).child(
|
||||
IconButton::new("close", IconName::Close)
|
||||
.icon_size(IconSize::Indicator)
|
||||
.on_click(cx.listener(|this, _, _window, cx| this.dismiss(cx)))
|
||||
.tooltip(|window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Close Announcement Banner",
|
||||
None,
|
||||
"It won't show again for this feature",
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
div().pr_2().child(banner)
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@ util.workspace = true
|
|||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
zeta.workspace = true
|
||||
git_ui.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows.workspace = true
|
||||
|
|
|
@ -18,6 +18,7 @@ use auto_update::AutoUpdateStatus;
|
|||
use call::ActiveCall;
|
||||
use client::{Client, UserStore};
|
||||
use feature_flags::{FeatureFlagAppExt, ZedPro};
|
||||
use git_ui::onboarding::GitBanner;
|
||||
use gpui::{
|
||||
actions, div, px, Action, AnyElement, App, Context, Decorations, Element, Entity,
|
||||
InteractiveElement, Interactivity, IntoElement, MouseButton, ParentElement, Render, Stateful,
|
||||
|
@ -126,6 +127,7 @@ pub struct TitleBar {
|
|||
application_menu: Option<Entity<ApplicationMenu>>,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
zed_predict_banner: Entity<ZedPredictBanner>,
|
||||
git_banner: Entity<GitBanner>,
|
||||
}
|
||||
|
||||
impl Render for TitleBar {
|
||||
|
@ -210,6 +212,7 @@ impl Render for TitleBar {
|
|||
)
|
||||
.child(self.render_collaborator_list(window, cx))
|
||||
.child(self.zed_predict_banner.clone())
|
||||
.child(self.git_banner.clone())
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
|
@ -313,6 +316,7 @@ impl TitleBar {
|
|||
subscriptions.push(cx.observe(&user_store, |_, _, cx| cx.notify()));
|
||||
|
||||
let zed_predict_banner = cx.new(ZedPredictBanner::new);
|
||||
let git_banner = cx.new(GitBanner::new);
|
||||
|
||||
Self {
|
||||
platform_style,
|
||||
|
@ -326,6 +330,7 @@ impl TitleBar {
|
|||
client,
|
||||
_subscriptions: subscriptions,
|
||||
zed_predict_banner,
|
||||
git_banner,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,3 +262,4 @@ pub mod outline {
|
|||
}
|
||||
|
||||
actions!(zed_predict_onboarding, [OpenZedPredictOnboarding]);
|
||||
actions!(git_onboarding, [OpenGitIntegrationOnboarding]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue