Cargo.lock 🔗
@@ -12475,6 +12475,7 @@ version = "0.1.0"
dependencies = [
"feature_flags",
"gpui",
+ "project",
"settings",
"smallvec",
"theme",
Anthony Eid created
We don't want to show the sidebar to users if they have `disable_ai`
enabled because it's an AI focused feature. In the future if we add non
AI functionality to the sidebar we'll reenable it.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Cargo.lock | 1
crates/platform_title_bar/Cargo.toml | 1
crates/platform_title_bar/src/platform_title_bar.rs | 4
crates/title_bar/src/title_bar.rs | 6
crates/workspace/src/multi_workspace.rs | 128 +++++++++++++-
5 files changed, 124 insertions(+), 16 deletions(-)
@@ -12475,6 +12475,7 @@ version = "0.1.0"
dependencies = [
"feature_flags",
"gpui",
+ "project",
"settings",
"smallvec",
"theme",
@@ -15,6 +15,7 @@ doctest = false
[dependencies]
feature_flags.workspace = true
gpui.workspace = true
+project.workspace = true
settings.workspace = true
smallvec.workspace = true
theme.workspace = true
@@ -7,6 +7,8 @@ use gpui::{
MouseButton, ParentElement, StatefulInteractiveElement, Styled, Window, WindowControlArea, div,
px,
};
+use project::DisableAiSettings;
+use settings::Settings;
use smallvec::SmallVec;
use std::mem;
use ui::{
@@ -95,7 +97,7 @@ impl PlatformTitleBar {
}
pub fn is_multi_workspace_enabled(cx: &App) -> bool {
- cx.has_flag::<AgentV2FeatureFlag>()
+ cx.has_flag::<AgentV2FeatureFlag>() && !DisableAiSettings::get_global(cx).disable_ai
}
}
@@ -31,7 +31,9 @@ use gpui::{
StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window, actions, div,
};
use onboarding_banner::OnboardingBanner;
-use project::{Project, git_store::GitStoreEvent, trusted_worktrees::TrustedWorktrees};
+use project::{
+ DisableAiSettings, Project, git_store::GitStoreEvent, trusted_worktrees::TrustedWorktrees,
+};
use remote::RemoteConnectionOptions;
use settings::Settings;
use settings::WorktreeId;
@@ -686,7 +688,7 @@ impl TitleBar {
_window: &mut Window,
cx: &mut Context<Self>,
) -> Option<AnyElement> {
- if !cx.has_flag::<AgentV2FeatureFlag>() {
+ if !cx.has_flag::<AgentV2FeatureFlag>() || DisableAiSettings::get_global(cx).disable_ai {
return None;
}
@@ -5,7 +5,8 @@ use gpui::{
ManagedView, MouseButton, Pixels, Render, Subscription, Task, Tiling, Window, WindowId,
actions, deferred, px,
};
-use project::Project;
+use project::{DisableAiSettings, Project};
+use settings::Settings;
use std::future::Future;
use std::path::PathBuf;
use ui::prelude::*;
@@ -122,6 +123,12 @@ impl MultiWorkspace {
}
});
let quit_subscription = cx.on_app_quit(Self::app_will_quit);
+ let settings_subscription =
+ cx.observe_global_in::<settings::SettingsStore>(window, |this, window, cx| {
+ if DisableAiSettings::get_global(cx).disable_ai && this.sidebar_open {
+ this.close_sidebar(window, cx);
+ }
+ });
Self::subscribe_to_workspace(&workspace, cx);
Self {
window_id: window.window_handle().window_id(),
@@ -133,7 +140,11 @@ impl MultiWorkspace {
pending_removal_tasks: Vec::new(),
_serialize_task: None,
_create_task: None,
- _subscriptions: vec![release_subscription, quit_subscription],
+ _subscriptions: vec![
+ release_subscription,
+ quit_subscription,
+ settings_subscription,
+ ],
}
}
@@ -169,7 +180,7 @@ impl MultiWorkspace {
}
pub fn multi_workspace_enabled(&self, cx: &App) -> bool {
- cx.has_flag::<AgentV2FeatureFlag>()
+ cx.has_flag::<AgentV2FeatureFlag>() && !DisableAiSettings::get_global(cx).disable_ai
}
pub fn toggle_sidebar(&mut self, window: &mut Window, cx: &mut Context<Self>) {
@@ -732,16 +743,18 @@ impl Render for MultiWorkspace {
this.activate_previous_workspace(window, cx);
},
))
- .on_action(cx.listener(
- |this: &mut Self, _: &ToggleWorkspaceSidebar, window, cx| {
- this.toggle_sidebar(window, cx);
- },
- ))
- .on_action(
- cx.listener(|this: &mut Self, _: &FocusWorkspaceSidebar, window, cx| {
- this.focus_sidebar(window, cx);
- }),
- )
+ .when(self.multi_workspace_enabled(cx), |this| {
+ this.on_action(cx.listener(
+ |this: &mut Self, _: &ToggleWorkspaceSidebar, window, cx| {
+ this.toggle_sidebar(window, cx);
+ },
+ ))
+ .on_action(cx.listener(
+ |this: &mut Self, _: &FocusWorkspaceSidebar, window, cx| {
+ this.focus_sidebar(window, cx);
+ },
+ ))
+ })
.when(
self.sidebar_open() && self.multi_workspace_enabled(cx),
|this| {
@@ -774,3 +787,92 @@ impl Render for MultiWorkspace {
)
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use fs::FakeFs;
+ use gpui::TestAppContext;
+ use settings::SettingsStore;
+
+ fn init_test(cx: &mut TestAppContext) {
+ cx.update(|cx| {
+ let settings_store = SettingsStore::test(cx);
+ cx.set_global(settings_store);
+ theme::init(theme::LoadThemes::JustBase, cx);
+ DisableAiSettings::register(cx);
+ cx.update_flags(false, vec!["agent-v2".into()]);
+ });
+ }
+
+ #[gpui::test]
+ async fn test_sidebar_disabled_when_disable_ai_is_enabled(cx: &mut TestAppContext) {
+ init_test(cx);
+ let fs = FakeFs::new(cx.executor());
+ let project = Project::test(fs, [], cx).await;
+
+ let (multi_workspace, cx) =
+ cx.add_window_view(|window, cx| MultiWorkspace::test_new(project, window, cx));
+
+ multi_workspace.read_with(cx, |mw, cx| {
+ assert!(mw.multi_workspace_enabled(cx));
+ });
+
+ multi_workspace.update_in(cx, |mw, _window, cx| {
+ mw.open_sidebar(cx);
+ assert!(mw.is_sidebar_open());
+ });
+
+ cx.update(|_window, cx| {
+ DisableAiSettings::override_global(DisableAiSettings { disable_ai: true }, cx);
+ });
+ cx.run_until_parked();
+
+ multi_workspace.read_with(cx, |mw, cx| {
+ assert!(
+ !mw.is_sidebar_open(),
+ "Sidebar should be closed when disable_ai is true"
+ );
+ assert!(
+ !mw.multi_workspace_enabled(cx),
+ "Multi-workspace should be disabled when disable_ai is true"
+ );
+ });
+
+ multi_workspace.update_in(cx, |mw, window, cx| {
+ mw.toggle_sidebar(window, cx);
+ });
+ multi_workspace.read_with(cx, |mw, _cx| {
+ assert!(
+ !mw.is_sidebar_open(),
+ "Sidebar should remain closed when toggled with disable_ai true"
+ );
+ });
+
+ cx.update(|_window, cx| {
+ DisableAiSettings::override_global(DisableAiSettings { disable_ai: false }, cx);
+ });
+ cx.run_until_parked();
+
+ multi_workspace.read_with(cx, |mw, cx| {
+ assert!(
+ mw.multi_workspace_enabled(cx),
+ "Multi-workspace should be enabled after re-enabling AI"
+ );
+ assert!(
+ !mw.is_sidebar_open(),
+ "Sidebar should still be closed after re-enabling AI (not auto-opened)"
+ );
+ });
+
+ multi_workspace.update_in(cx, |mw, window, cx| {
+ mw.toggle_sidebar(window, cx);
+ });
+ multi_workspace.read_with(cx, |mw, _cx| {
+ assert!(
+ mw.is_sidebar_open(),
+ "Sidebar should open when toggled after re-enabling AI"
+ );
+ });
+ }
+}