Cargo.lock 🔗
@@ -17772,7 +17772,6 @@ dependencies = [
"client",
"cloud_api_types",
"db",
- "feature_flags",
"git_ui",
"gpui",
"icons",
Danilo Leal created
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Cargo.lock | 1
crates/platform_title_bar/src/platform_title_bar.rs | 15 ---
crates/sidebar/src/sidebar.rs | 39 ++++----
crates/title_bar/Cargo.toml | 1
crates/title_bar/src/title_bar.rs | 62 +-------------
crates/workspace/src/multi_workspace.rs | 30 ++++++
crates/workspace/src/status_bar.rs | 54 +++++++++++-
crates/workspace/src/workspace.rs | 10 ++
crates/zed/src/visual_test_runner.rs | 8
crates/zed/src/zed.rs | 4
10 files changed, 113 insertions(+), 111 deletions(-)
@@ -17772,7 +17772,6 @@ dependencies = [
"client",
"cloud_api_types",
"db",
- "feature_flags",
"git_ui",
"gpui",
"icons",
@@ -32,7 +32,6 @@ pub struct PlatformTitleBar {
should_move: bool,
system_window_tabs: Entity<SystemWindowTabs>,
workspace_sidebar_open: bool,
- sidebar_has_notifications: bool,
}
impl PlatformTitleBar {
@@ -47,7 +46,6 @@ impl PlatformTitleBar {
should_move: false,
system_window_tabs,
workspace_sidebar_open: false,
- sidebar_has_notifications: false,
}
}
@@ -83,19 +81,6 @@ impl PlatformTitleBar {
cx.notify();
}
- pub fn sidebar_has_notifications(&self) -> bool {
- self.sidebar_has_notifications
- }
-
- pub fn set_sidebar_has_notifications(
- &mut self,
- has_notifications: bool,
- cx: &mut Context<Self>,
- ) {
- self.sidebar_has_notifications = has_notifications;
- cx.notify();
- }
-
pub fn is_multi_workspace_enabled(cx: &App) -> bool {
cx.has_flag::<AgentV2FeatureFlag>() && !DisableAiSettings::get_global(cx).disable_ai
}
@@ -2551,23 +2551,19 @@ impl Sidebar {
this.pl(px(ui::utils::TRAFFIC_LIGHT_PADDING))
})
.pr_1p5()
+ .gap_1()
.border_b_1()
.border_color(cx.theme().colors().border)
- .justify_between()
- .child(self.render_sidebar_toggle_button(cx))
+ .justify_end()
.child(
- h_flex()
- .gap_0p5()
- .child(
- IconButton::new("archive", IconName::Archive)
- .icon_size(IconSize::Small)
- .tooltip(Tooltip::text("View Archived Threads"))
- .on_click(cx.listener(|this, _, window, cx| {
- this.show_archive(window, cx);
- })),
- )
- .child(self.render_recent_projects_button(cx)),
- ),
+ IconButton::new("archive", IconName::Archive)
+ .icon_size(IconSize::Small)
+ .tooltip(Tooltip::text("View Archived Threads"))
+ .on_click(cx.listener(|this, _, window, cx| {
+ this.show_archive(window, cx);
+ })),
+ )
+ .child(self.render_recent_projects_button(cx)),
)
.when(!empty_state, |this| {
this.child(
@@ -2612,9 +2608,7 @@ impl Sidebar {
}
fn render_sidebar_toggle_button(&self, _cx: &mut Context<Self>) -> impl IntoElement {
- let icon = IconName::ThreadsSidebarLeftOpen;
-
- IconButton::new("sidebar-close-toggle", icon)
+ IconButton::new("sidebar-close-toggle", IconName::ThreadsSidebarLeftOpen)
.icon_size(IconSize::Small)
.tooltip(Tooltip::element(move |_window, cx| {
v_flex()
@@ -2816,6 +2810,13 @@ impl Render for Sidebar {
}),
SidebarView::Archive(archive_view) => this.child(archive_view.clone()),
})
+ .child(
+ h_flex()
+ .p_1()
+ .border_t_1()
+ .border_color(cx.theme().colors().border_variant)
+ .child(self.render_sidebar_toggle_button(cx)),
+ )
}
}
@@ -2874,8 +2875,8 @@ mod tests {
let multi_workspace = multi_workspace.clone();
let sidebar =
cx.update(|window, cx| cx.new(|cx| Sidebar::new(multi_workspace.clone(), window, cx)));
- multi_workspace.update(cx, |mw, _cx| {
- mw.register_sidebar(sidebar.clone());
+ multi_workspace.update(cx, |mw, cx| {
+ mw.register_sidebar(sidebar.clone(), cx);
});
cx.run_until_parked();
sidebar
@@ -38,7 +38,6 @@ chrono.workspace = true
client.workspace = true
cloud_api_types.workspace = true
db.workspace = true
-feature_flags.workspace = true
git_ui.workspace = true
gpui = { workspace = true, features = ["screen-capture"] }
icons.workspace = true
@@ -25,16 +25,14 @@ use auto_update::AutoUpdateStatus;
use call::ActiveCall;
use client::{Client, UserStore, zed_urls};
use cloud_api_types::Plan;
-use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt};
+
use gpui::{
Action, AnyElement, App, Context, Corner, Element, Empty, Entity, Focusable,
InteractiveElement, IntoElement, MouseButton, ParentElement, Render,
StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window, actions, div,
};
use onboarding_banner::OnboardingBanner;
-use project::{
- DisableAiSettings, Project, git_store::GitStoreEvent, trusted_worktrees::TrustedWorktrees,
-};
+use project::{Project, git_store::GitStoreEvent, trusted_worktrees::TrustedWorktrees};
use remote::RemoteConnectionOptions;
use settings::Settings;
use settings::WorktreeId;
@@ -43,14 +41,13 @@ use std::sync::Arc;
use theme::ActiveTheme;
use title_bar_settings::TitleBarSettings;
use ui::{
- Avatar, ButtonLike, ContextMenu, Divider, IconWithIndicator, Indicator, PopoverMenu,
- PopoverMenuHandle, TintColor, Tooltip, prelude::*, utils::platform_title_bar_height,
+ Avatar, ButtonLike, ContextMenu, IconWithIndicator, Indicator, PopoverMenu, PopoverMenuHandle,
+ TintColor, Tooltip, prelude::*, utils::platform_title_bar_height,
};
use update_version::UpdateVersion;
use util::ResultExt;
use workspace::{
- MultiWorkspace, ToggleWorkspaceSidebar, ToggleWorktreeSecurity, Workspace, WorkspaceId,
- notifications::NotifyResultExt,
+ MultiWorkspace, ToggleWorktreeSecurity, Workspace, WorkspaceId, notifications::NotifyResultExt,
};
use zed_actions::OpenRemote;
@@ -198,7 +195,6 @@ impl Render for TitleBar {
let mut render_project_items = title_bar_settings.show_branch_name
|| title_bar_settings.show_project_items;
title_bar
- .children(self.render_workspace_sidebar_toggle(window, cx))
.when_some(
self.application_menu.clone().filter(|_| !show_menus),
|title_bar, menu| {
@@ -402,19 +398,15 @@ impl TitleBar {
};
let is_open = multi_workspace.read(cx).sidebar_open();
- let has_notifications = multi_workspace.read(cx).sidebar_has_notifications(cx);
platform_titlebar.update(cx, |titlebar, cx| {
titlebar.set_workspace_sidebar_open(is_open, cx);
- titlebar.set_sidebar_has_notifications(has_notifications, cx);
});
let platform_titlebar = platform_titlebar.clone();
let subscription = cx.observe(&multi_workspace, move |mw, cx| {
let is_open = mw.read(cx).sidebar_open();
- let has_notifications = mw.read(cx).sidebar_has_notifications(cx);
platform_titlebar.update(cx, |titlebar, cx| {
titlebar.set_workspace_sidebar_open(is_open, cx);
- titlebar.set_sidebar_has_notifications(has_notifications, cx);
});
});
@@ -723,50 +715,6 @@ impl TitleBar {
)
}
- fn render_workspace_sidebar_toggle(
- &self,
- _window: &mut Window,
- cx: &mut Context<Self>,
- ) -> Option<AnyElement> {
- if !cx.has_flag::<AgentV2FeatureFlag>() || DisableAiSettings::get_global(cx).disable_ai {
- return None;
- }
-
- let is_sidebar_open = self.platform_titlebar.read(cx).is_workspace_sidebar_open();
-
- if is_sidebar_open {
- return None;
- }
-
- let has_notifications = self.platform_titlebar.read(cx).sidebar_has_notifications();
-
- Some(
- h_flex()
- .h_full()
- .gap_0p5()
- .child(
- IconButton::new(
- "toggle-workspace-sidebar",
- IconName::ThreadsSidebarLeftClosed,
- )
- .icon_size(IconSize::Small)
- .when(has_notifications, |button| {
- button
- .indicator(Indicator::dot().color(Color::Accent))
- .indicator_border_color(Some(cx.theme().colors().title_bar_background))
- })
- .tooltip(move |_, cx| {
- Tooltip::for_action("Open Threads Sidebar", &ToggleWorkspaceSidebar, cx)
- })
- .on_click(|_, window, cx| {
- window.dispatch_action(ToggleWorkspaceSidebar.boxed_clone(), cx);
- }),
- )
- .child(Divider::vertical().color(ui::DividerColor::Border))
- .into_any_element(),
- )
- }
-
fn render_project_name(
&self,
name: Option<SharedString>,
@@ -169,7 +169,23 @@ impl MultiWorkspace {
}
}
- pub fn register_sidebar<T: Sidebar>(&mut self, sidebar: Entity<T>) {
+ pub fn register_sidebar<T: Sidebar>(&mut self, sidebar: Entity<T>, cx: &mut Context<Self>) {
+ self._subscriptions
+ .push(cx.observe(&sidebar, |this, _, cx| {
+ let has_notifications = this.sidebar_has_notifications(cx);
+ let is_open = this.sidebar_open;
+ let show_toggle = this.multi_workspace_enabled(cx);
+ for workspace in &this.workspaces {
+ workspace.update(cx, |workspace, cx| {
+ workspace.set_workspace_sidebar_open(
+ is_open,
+ has_notifications,
+ show_toggle,
+ cx,
+ );
+ });
+ }
+ }));
self.sidebar = Some(Box::new(sidebar));
}
@@ -256,9 +272,11 @@ impl MultiWorkspace {
pub fn open_sidebar(&mut self, cx: &mut Context<Self>) {
self.sidebar_open = true;
let sidebar_focus_handle = self.sidebar.as_ref().map(|s| s.focus_handle(cx));
+ let has_notifications = self.sidebar_has_notifications(cx);
+ let show_toggle = self.multi_workspace_enabled(cx);
for workspace in &self.workspaces {
workspace.update(cx, |workspace, cx| {
- workspace.set_workspace_sidebar_open(true, cx);
+ workspace.set_workspace_sidebar_open(true, has_notifications, show_toggle, cx);
workspace.set_sidebar_focus_handle(sidebar_focus_handle.clone());
});
}
@@ -268,9 +286,11 @@ impl MultiWorkspace {
fn close_sidebar(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.sidebar_open = false;
+ let has_notifications = self.sidebar_has_notifications(cx);
+ let show_toggle = self.multi_workspace_enabled(cx);
for workspace in &self.workspaces {
workspace.update(cx, |workspace, cx| {
- workspace.set_workspace_sidebar_open(false, cx);
+ workspace.set_workspace_sidebar_open(false, has_notifications, show_toggle, cx);
workspace.set_sidebar_focus_handle(None);
});
}
@@ -367,8 +387,10 @@ impl MultiWorkspace {
} else {
if self.sidebar_open {
let sidebar_focus_handle = self.sidebar.as_ref().map(|s| s.focus_handle(cx));
+ let has_notifications = self.sidebar_has_notifications(cx);
+ let show_toggle = self.multi_workspace_enabled(cx);
workspace.update(cx, |workspace, cx| {
- workspace.set_workspace_sidebar_open(true, cx);
+ workspace.set_workspace_sidebar_open(true, has_notifications, show_toggle, cx);
workspace.set_sidebar_focus_handle(sidebar_focus_handle);
});
}
@@ -1,11 +1,11 @@
-use crate::{ItemHandle, Pane};
+use crate::{ItemHandle, Pane, ToggleWorkspaceSidebar};
use gpui::{
- AnyView, App, Context, Decorations, Entity, IntoElement, ParentElement, Render, Styled,
+ Action, AnyView, App, Context, Decorations, Entity, IntoElement, ParentElement, Render, Styled,
Subscription, Window,
};
use std::any::TypeId;
use theme::CLIENT_SIDE_DECORATION_ROUNDING;
-use ui::{h_flex, prelude::*};
+use ui::{Divider, Indicator, Tooltip, prelude::*};
use util::ResultExt;
pub trait StatusItemView: Render {
@@ -35,6 +35,8 @@ pub struct StatusBar {
active_pane: Entity<Pane>,
_observe_active_pane: Subscription,
workspace_sidebar_open: bool,
+ sidebar_has_notifications: bool,
+ show_sidebar_toggle: bool,
}
impl Render for StatusBar {
@@ -43,8 +45,7 @@ impl Render for StatusBar {
.w_full()
.justify_between()
.gap(DynamicSpacing::Base08.rems(cx))
- .py(DynamicSpacing::Base04.rems(cx))
- .px(DynamicSpacing::Base06.rems(cx))
+ .p(DynamicSpacing::Base04.rems(cx))
.bg(cx.theme().colors().status_bar_background)
.map(|el| match window.window_decorations() {
Decorations::Server => el,
@@ -61,17 +62,21 @@ impl Render for StatusBar {
.border_b(px(1.0))
.border_color(cx.theme().colors().status_bar_background),
})
- .child(self.render_left_tools())
+ .child(self.render_left_tools(cx))
.child(self.render_right_tools())
}
}
impl StatusBar {
- fn render_left_tools(&self) -> impl IntoElement {
+ fn render_left_tools(&self, cx: &mut Context<Self>) -> impl IntoElement {
h_flex()
.gap_1()
.min_w_0()
.overflow_x_hidden()
+ .when(
+ self.show_sidebar_toggle && !self.workspace_sidebar_open,
+ |this| this.child(self.render_sidebar_toggle(cx)),
+ )
.children(self.left_items.iter().map(|item| item.to_any()))
}
@@ -82,6 +87,29 @@ impl StatusBar {
.overflow_x_hidden()
.children(self.right_items.iter().rev().map(|item| item.to_any()))
}
+
+ fn render_sidebar_toggle(&self, cx: &mut Context<Self>) -> impl IntoElement {
+ h_flex()
+ .gap_0p5()
+ .child(
+ IconButton::new(
+ "toggle-workspace-sidebar",
+ IconName::ThreadsSidebarLeftClosed,
+ )
+ .icon_size(IconSize::Small)
+ .when(self.sidebar_has_notifications, |this| {
+ this.indicator(Indicator::dot().color(Color::Accent))
+ .indicator_border_color(Some(cx.theme().colors().status_bar_background))
+ })
+ .tooltip(move |_, cx| {
+ Tooltip::for_action("Open Threads Sidebar", &ToggleWorkspaceSidebar, cx)
+ })
+ .on_click(|_, window, cx| {
+ window.dispatch_action(ToggleWorkspaceSidebar.boxed_clone(), cx);
+ }),
+ )
+ .child(Divider::vertical().color(ui::DividerColor::Border))
+ }
}
impl StatusBar {
@@ -94,6 +122,8 @@ impl StatusBar {
this.update_active_pane_item(window, cx)
}),
workspace_sidebar_open: false,
+ sidebar_has_notifications: false,
+ show_sidebar_toggle: false,
};
this.update_active_pane_item(window, cx);
this
@@ -104,6 +134,16 @@ impl StatusBar {
cx.notify();
}
+ pub fn set_sidebar_has_notifications(&mut self, has: bool, cx: &mut Context<Self>) {
+ self.sidebar_has_notifications = has;
+ cx.notify();
+ }
+
+ pub fn set_show_sidebar_toggle(&mut self, show: bool, cx: &mut Context<Self>) {
+ self.show_sidebar_toggle = show;
+ cx.notify();
+ }
+
pub fn add_left_item<T>(&mut self, item: Entity<T>, window: &mut Window, cx: &mut Context<Self>)
where
T: 'static + StatusItemView,
@@ -2160,9 +2160,17 @@ impl Workspace {
&self.status_bar
}
- pub fn set_workspace_sidebar_open(&self, open: bool, cx: &mut App) {
+ pub fn set_workspace_sidebar_open(
+ &self,
+ open: bool,
+ has_notifications: bool,
+ show_toggle: bool,
+ cx: &mut App,
+ ) {
self.status_bar.update(cx, |status_bar, cx| {
status_bar.set_workspace_sidebar_open(open, cx);
+ status_bar.set_sidebar_has_notifications(has_notifications, cx);
+ status_bar.set_show_sidebar_toggle(show_toggle, cx);
});
}
@@ -2659,8 +2659,8 @@ fn run_multi_workspace_sidebar_visual_tests(
.context("Failed to create sidebar")?;
multi_workspace_window
- .update(cx, |multi_workspace, _window, _cx| {
- multi_workspace.register_sidebar(sidebar.clone());
+ .update(cx, |multi_workspace, _window, cx| {
+ multi_workspace.register_sidebar(sidebar.clone(), cx);
})
.context("Failed to register sidebar")?;
@@ -3191,8 +3191,8 @@ edition = "2021"
.context("Failed to create sidebar")?;
workspace_window
- .update(cx, |multi_workspace, _window, _cx| {
- multi_workspace.register_sidebar(sidebar.clone());
+ .update(cx, |multi_workspace, _window, cx| {
+ multi_workspace.register_sidebar(sidebar.clone(), cx);
})
.context("Failed to register sidebar")?;
@@ -397,8 +397,8 @@ pub fn initialize_workspace(
.update(cx, |_, window, cx| {
let sidebar =
cx.new(|cx| Sidebar::new(multi_workspace_handle.clone(), window, cx));
- multi_workspace_handle.update(cx, |multi_workspace, _cx| {
- multi_workspace.register_sidebar(sidebar);
+ multi_workspace_handle.update(cx, |multi_workspace, cx| {
+ multi_workspace.register_sidebar(sidebar, cx);
});
})
.ok();