From 3fe2346305d7c30d04ef387889f14491e1d4f1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Fri, 8 May 2026 09:25:25 -0400 Subject: [PATCH] Add space default profile control --- .../src/shell/internal_pages/profiles.rs | 45 ++++++++++++++++++- crates/ely_app/src/shell/spaces.rs | 14 +++++- crates/ely_browser_core/src/state.rs | 8 ++++ crates/ely_browser_core/tests/spaces.rs | 16 +++++++ 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/crates/ely_app/src/shell/internal_pages/profiles.rs b/crates/ely_app/src/shell/internal_pages/profiles.rs index 07807a0..e02e6ad 100644 --- a/crates/ely_app/src/shell/internal_pages/profiles.rs +++ b/crates/ely_app/src/shell/internal_pages/profiles.rs @@ -62,6 +62,8 @@ fn render_profiles_header(snapshot: &BrowserSnapshot) -> AnyElement { } fn render_profile_list(snapshot: &BrowserSnapshot, cx: &mut Context) -> AnyElement { + let active_space = snapshot.spaces.iter().find(|space| space.id() == &snapshot.active_space_id); + div() .flex_1() .min_h_0() @@ -71,7 +73,13 @@ fn render_profile_list(snapshot: &BrowserSnapshot, cx: &mut Context) - .border_t_1() .border_color(rgb(colors::HAIRLINE)) .children(snapshot.profiles.iter().enumerate().map(|(index, profile)| { - render_profile_row(index, profile, profile.id() == &snapshot.active_profile_id, cx) + render_profile_row( + index, + profile, + profile.id() == &snapshot.active_profile_id, + active_space.is_some_and(|space| space.default_profile_id() == profile.id()), + cx, + ) })) .into_any_element() } @@ -80,9 +88,11 @@ fn render_profile_row( index: usize, profile: &Profile, active: bool, + default_for_active_space: bool, cx: &mut Context, ) -> AnyElement { let profile_id = profile.id().clone(); + let default_profile_id = profile.id().clone(); let sync_profile_id = profile.id().clone(); let sync_policy = profile.sync_policy(); @@ -130,6 +140,12 @@ fn render_profile_row( .flex() .items_center() .gap_3() + .child(render_profile_default_action( + index, + default_profile_id, + default_for_active_space, + cx, + )) .child(render_profile_sync_action(index, sync_profile_id, sync_policy, cx)) .child(render_profile_action(index, profile_id, active, cx)), ) @@ -147,6 +163,33 @@ fn profile_color_swatch(color_hex: u32) -> AnyElement { .into_any_element() } +fn render_profile_default_action( + index: usize, + profile_id: ProfileId, + default_for_active_space: bool, + cx: &mut Context, +) -> AnyElement { + if default_for_active_space { + return div() + .text_xs() + .font_semibold() + .text_color(rgb(colors::SUCCESS)) + .child("Default") + .into_any_element(); + } + + Button::new(("default-profile", index)) + .ghost() + .xsmall() + .icon(IconName::CircleCheck) + .label("Set Default") + .tooltip("Use for New Tabs in Active Space") + .on_click(cx.listener(move |shell, _, _, cx| { + shell.set_active_space_default_profile(&profile_id, cx); + })) + .into_any_element() +} + fn render_profile_action( index: usize, profile_id: ProfileId, diff --git a/crates/ely_app/src/shell/spaces.rs b/crates/ely_app/src/shell/spaces.rs index 21bc3f5..55bce4d 100644 --- a/crates/ely_app/src/shell/spaces.rs +++ b/crates/ely_app/src/shell/spaces.rs @@ -1,10 +1,22 @@ -use ely_domain::SpaceId; +use ely_domain::{ProfileId, SpaceId}; use gpui::{Context, Window}; use super::{ElyShell, ShellState}; use crate::{SelectNextSpace, SelectPreviousSpace}; impl ElyShell { + pub(super) fn set_active_space_default_profile( + &mut self, + profile_id: &ProfileId, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state + && core.set_active_space_default_profile(profile_id).is_ok() + { + cx.notify(); + } + } + pub(super) fn move_space_up(&mut self, space_id: &SpaceId, cx: &mut Context) { if let ShellState::Ready(core) = &mut self.state && core.move_space_up(space_id).is_ok_and(|moved| moved) diff --git a/crates/ely_browser_core/src/state.rs b/crates/ely_browser_core/src/state.rs index 75e3a4b..a230e1c 100644 --- a/crates/ely_browser_core/src/state.rs +++ b/crates/ely_browser_core/src/state.rs @@ -300,6 +300,14 @@ impl BrowserCore { Ok(()) } + pub fn set_active_space_default_profile( + &mut self, + profile_id: &ProfileId, + ) -> Result<(), CoreError> { + let active_space_id = self.active_space_id.clone(); + self.set_space_default_profile(&active_space_id, profile_id) + } + pub fn set_space_sidebar_width( &mut self, space_id: &SpaceId, diff --git a/crates/ely_browser_core/tests/spaces.rs b/crates/ely_browser_core/tests/spaces.rs index 81dbdc3..8a66885 100644 --- a/crates/ely_browser_core/tests/spaces.rs +++ b/crates/ely_browser_core/tests/spaces.rs @@ -233,6 +233,22 @@ fn space_default_profile_updates_with_profile_validation() -> Result<(), Box Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let work_space_id = core.snapshot()?.active_space_id; + let research_profile_id = core.create_profile("Research", 0x9fc9a2, ProfileKind::Standard)?; + + core.set_active_space_default_profile(&research_profile_id)?; + let snapshot = core.snapshot()?; + let Some(work_space) = snapshot.spaces.iter().find(|space| space.id() == &work_space_id) else { + return Err("missing work space".into()); + }; + + assert_eq!(work_space.default_profile_id(), &research_profile_id); + Ok(()) +} + #[test] fn space_settings_refresh_updated_at() -> Result<(), Box> { let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;