From aed3a4154e6e7d8ea1529921143409c58988c41d 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 05:13:20 -0400 Subject: [PATCH] Track tab sync participation --- crates/ely_browser_core/src/state/sync.rs | 6 +++++- crates/ely_browser_core/src/state/tabs.rs | 14 ++++++++++++++ crates/ely_browser_core/tests/sync.rs | 21 +++++++++++++++++++++ crates/ely_domain/src/tab.rs | 11 +++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/crates/ely_browser_core/src/state/sync.rs b/crates/ely_browser_core/src/state/sync.rs index d9171c3..1c0d526 100644 --- a/crates/ely_browser_core/src/state/sync.rs +++ b/crates/ely_browser_core/src/state/sync.rs @@ -76,7 +76,7 @@ impl BrowserCore { ), self.sync_object_status( SyncObjectKind::Tabs, - self.tabs.len(), + self.sync_enabled_tab_count(), SyncObjectState::LocalOnly, ), self.sync_object_status( @@ -126,4 +126,8 @@ impl BrowserCore { SyncObjectStatus::with_policy(kind, local_count, state, policy) } + + fn sync_enabled_tab_count(&self) -> usize { + self.tabs.iter().filter(|tab| tab.sync_enabled()).count() + } } diff --git a/crates/ely_browser_core/src/state/tabs.rs b/crates/ely_browser_core/src/state/tabs.rs index dde3720..ce3f9cf 100644 --- a/crates/ely_browser_core/src/state/tabs.rs +++ b/crates/ely_browser_core/src/state/tabs.rs @@ -243,6 +243,20 @@ impl BrowserCore { Ok(next_pinned) } + pub fn set_tab_sync_enabled( + &mut self, + tab_id: &TabId, + sync_enabled: bool, + ) -> Result<(), CoreError> { + let tab = self + .tabs + .iter_mut() + .find(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + tab.set_sync_enabled(sync_enabled); + Ok(()) + } + pub fn active_tab(&self) -> Result<&BrowserTab, CoreError> { self.tabs .iter() diff --git a/crates/ely_browser_core/tests/sync.rs b/crates/ely_browser_core/tests/sync.rs index 94ba7ac..938566a 100644 --- a/crates/ely_browser_core/tests/sync.rs +++ b/crates/ely_browser_core/tests/sync.rs @@ -63,3 +63,24 @@ fn sync_object_policy_pauses_object_kind() -> Result<(), Box> { assert_eq!(spaces_status.state(), SyncObjectState::LocalOnly); Ok(()) } + +#[test] +fn tab_sync_status_counts_sync_enabled_tabs() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let unsynced_tab_id = core.open_tab(UrlText::parse("https://example.com/local-only")?); + + core.set_tab_sync_enabled(&unsynced_tab_id, false)?; + let snapshot = core.snapshot()?; + let Some(tabs_status) = + snapshot.sync_status.objects().iter().find(|status| status.kind() == SyncObjectKind::Tabs) + else { + return Err("missing tabs sync status".into()); + }; + let Some(unsynced_tab) = snapshot.tabs.iter().find(|tab| tab.id() == &unsynced_tab_id) else { + return Err("missing unsynced tab".into()); + }; + + assert!(!unsynced_tab.sync_enabled()); + assert_eq!(tabs_status.local_count(), 1); + Ok(()) +} diff --git a/crates/ely_domain/src/tab.rs b/crates/ely_domain/src/tab.rs index 3621770..1172725 100644 --- a/crates/ely_domain/src/tab.rs +++ b/crates/ely_domain/src/tab.rs @@ -30,6 +30,7 @@ pub struct BrowserTab { state: TabState, flags: TabFlags, split_id: Option, + sync_enabled: bool, created_at: SystemTime, last_active_at: SystemTime, } @@ -54,6 +55,7 @@ impl BrowserTab { state: TabState::Ready, flags: TabFlags::default(), split_id: None, + sync_enabled: true, created_at, last_active_at: created_at, } @@ -149,6 +151,11 @@ impl BrowserTab { self.split_id.as_ref() } + #[must_use] + pub fn sync_enabled(&self) -> bool { + self.sync_enabled + } + pub fn set_split_id(&mut self, split_id: SplitId) { self.split_id = Some(split_id); } @@ -156,4 +163,8 @@ impl BrowserTab { pub fn clear_split_id(&mut self) { self.split_id = None; } + + pub fn set_sync_enabled(&mut self, sync_enabled: bool) { + self.sync_enabled = sync_enabled; + } }