diff --git a/crates/ely_app/src/shell/internal_pages/profiles.rs b/crates/ely_app/src/shell/internal_pages/profiles.rs index e02e6ad..6816c5b 100644 --- a/crates/ely_app/src/shell/internal_pages/profiles.rs +++ b/crates/ely_app/src/shell/internal_pages/profiles.rs @@ -8,7 +8,7 @@ use gpui::{ px, rgb, }; use gpui_component::{ - IconName, Selectable, Sizable, StyledExt, + Disableable, IconName, Selectable, Sizable, StyledExt, button::{Button, ButtonVariants}, scroll::ScrollableElement, }; @@ -146,7 +146,13 @@ fn render_profile_row( default_for_active_space, cx, )) - .child(render_profile_sync_action(index, sync_profile_id, sync_policy, cx)) + .child(render_profile_sync_action( + index, + sync_profile_id, + profile.allows_sync(), + sync_policy, + cx, + )) .child(render_profile_action(index, profile_id, active, cx)), ) .into_any_element() @@ -220,9 +226,21 @@ fn render_profile_action( fn render_profile_sync_action( index: usize, profile_id: ProfileId, + allows_sync: bool, sync_policy: ProfileSyncPolicy, cx: &mut Context, ) -> AnyElement { + if !allows_sync { + return Button::new(("profile-sync-policy", index)) + .ghost() + .xsmall() + .selected(true) + .disabled(true) + .label("Sync Paused") + .tooltip("Private Profiles keep Sync paused") + .into_any_element(); + } + let next_policy = sync_policy.toggled(); let paused = sync_policy == ProfileSyncPolicy::Paused; diff --git a/crates/ely_browser_core/src/error.rs b/crates/ely_browser_core/src/error.rs index f1fa5e2..5361b6f 100644 --- a/crates/ely_browser_core/src/error.rs +++ b/crates/ely_browser_core/src/error.rs @@ -36,6 +36,9 @@ pub enum CoreError { #[error("profile not found: {id}")] ProfileNotFound { id: ProfileId }, + #[error("private profile keeps sync paused: {id}")] + PrivateProfileSyncLocked { id: ProfileId }, + #[error("download not found: {id}")] DownloadNotFound { id: DownloadId }, diff --git a/crates/ely_browser_core/src/state/profiles.rs b/crates/ely_browser_core/src/state/profiles.rs index cdb89dd..a537bcb 100644 --- a/crates/ely_browser_core/src/state/profiles.rs +++ b/crates/ely_browser_core/src/state/profiles.rs @@ -100,6 +100,9 @@ impl BrowserCore { .iter_mut() .find(|profile| profile.id() == profile_id) .ok_or_else(|| CoreError::ProfileNotFound { id: profile_id.clone() })?; + if sync_policy == ProfileSyncPolicy::Enabled && !profile.allows_sync() { + return Err(CoreError::PrivateProfileSyncLocked { id: profile_id.clone() }); + } profile.set_sync_policy(sync_policy); Ok(()) diff --git a/crates/ely_browser_core/tests/profiles.rs b/crates/ely_browser_core/tests/profiles.rs index dc85334..025abcf 100644 --- a/crates/ely_browser_core/tests/profiles.rs +++ b/crates/ely_browser_core/tests/profiles.rs @@ -1,6 +1,6 @@ use std::error::Error; -use ely_browser_core::{BrowserCore, InitialBrowserConfig}; +use ely_browser_core::{BrowserCore, CoreError, InitialBrowserConfig}; use ely_domain::{CommandIntent, ProfileKind, ProfileSyncPolicy, UrlText}; #[test] @@ -85,3 +85,25 @@ fn profile_sync_policy_can_pause_one_profile() -> Result<(), Box> { assert_eq!(research_profile.sync_policy(), ProfileSyncPolicy::Paused); Ok(()) } + +#[test] +fn private_profile_sync_policy_stays_paused() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let private_profile_id = core.create_profile("Private", 0x807d72, ProfileKind::Private)?; + + let result = core.set_profile_sync_policy(&private_profile_id, ProfileSyncPolicy::Enabled); + let error = match result { + Ok(()) => return Err("private profile sync enabled".into()), + Err(error) => error, + }; + + assert_eq!(error, CoreError::PrivateProfileSyncLocked { id: private_profile_id.clone() }); + let snapshot = core.snapshot()?; + let Some(private_profile) = + snapshot.profiles.iter().find(|profile| profile.id() == &private_profile_id) + else { + return Err("missing private profile".into()); + }; + assert_eq!(private_profile.sync_policy(), ProfileSyncPolicy::Paused); + Ok(()) +} diff --git a/crates/ely_domain/src/profile.rs b/crates/ely_domain/src/profile.rs index c69e752..a2fcc5e 100644 --- a/crates/ely_domain/src/profile.rs +++ b/crates/ely_domain/src/profile.rs @@ -97,11 +97,19 @@ impl Profile { self.sync_policy } + #[must_use] + pub fn allows_sync(&self) -> bool { + self.kind == ProfileKind::Standard + } + pub fn set_download_policy(&mut self, download_policy: DownloadPolicy) { self.download_policy = download_policy; } pub fn set_sync_policy(&mut self, sync_policy: ProfileSyncPolicy) { - self.sync_policy = sync_policy; + self.sync_policy = match self.kind { + ProfileKind::Standard => sync_policy, + ProfileKind::Private => ProfileSyncPolicy::Paused, + }; } }