From d193f5a400fe0ae40022b6ff0713eba411c0ea67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sat, 9 May 2026 01:14:15 -0400 Subject: [PATCH] Add settings reset defaults --- .../shell/internal_pages/download_settings.rs | 32 +++- .../src/shell/internal_pages/general.rs | 30 +++- .../shell/internal_pages/privacy_security.rs | 25 ++- .../src/shell/internal_pages/profiles.rs | 29 +++- .../src/shell/internal_pages/search.rs | 27 ++- .../src/shell/internal_pages/sidebar_tabs.rs | 45 +++-- .../ely_app/src/shell/internal_pages/sync.rs | 39 ++++- crates/ely_app/src/shell/mod.rs | 95 +---------- crates/ely_app/src/shell/settings_actions.rs | 161 ++++++++++++++++++ crates/ely_browser_core/src/state.rs | 26 ++- crates/ely_browser_core/src/state/profiles.rs | 10 ++ crates/ely_browser_core/src/state/sync.rs | 4 + .../tests/settings_defaults.rs | 78 +++++++++ 13 files changed, 465 insertions(+), 136 deletions(-) create mode 100644 crates/ely_app/src/shell/settings_actions.rs create mode 100644 crates/ely_browser_core/tests/settings_defaults.rs diff --git a/crates/ely_app/src/shell/internal_pages/download_settings.rs b/crates/ely_app/src/shell/internal_pages/download_settings.rs index d5f3e6d..44150d2 100644 --- a/crates/ely_app/src/shell/internal_pages/download_settings.rs +++ b/crates/ely_app/src/shell/internal_pages/download_settings.rs @@ -37,7 +37,7 @@ impl ElyShell { .flex_col() .gap_5() .child(render_download_settings_header(snapshot)) - .child(render_download_policy_summary(snapshot)) + .child(render_download_policy_summary(snapshot, cx)) .child(render_download_policy_rows(&snapshot.active_download_policy, &options, cx)), ) } @@ -78,7 +78,10 @@ fn render_download_settings_header(snapshot: &BrowserSnapshot) -> AnyElement { .into_any_element() } -fn render_download_policy_summary(snapshot: &BrowserSnapshot) -> AnyElement { +fn render_download_policy_summary( + snapshot: &BrowserSnapshot, + cx: &mut Context, +) -> AnyElement { div() .rounded_md() .border_1() @@ -121,10 +124,27 @@ fn render_download_policy_summary(snapshot: &BrowserSnapshot) -> AnyElement { ) .child( div() - .text_xs() - .font_semibold() - .text_color(rgb(colors::MUTED)) - .child(format!("{} entries", snapshot.download_entries.len())), + .flex() + .items_center() + .gap_2() + .child( + div() + .text_xs() + .font_semibold() + .text_color(rgb(colors::MUTED)) + .child(format!("{} entries", snapshot.download_entries.len())), + ) + .child( + Button::new("reset-download-settings") + .ghost() + .xsmall() + .icon(IconName::Undo2) + .label("Reset") + .tooltip("Restore Download Defaults") + .on_click(cx.listener(|shell, _, _, cx| { + shell.reset_active_profile_download_settings(cx); + })), + ), ) .into_any_element() } diff --git a/crates/ely_app/src/shell/internal_pages/general.rs b/crates/ely_app/src/shell/internal_pages/general.rs index ec79bd8..62cd5c8 100644 --- a/crates/ely_app/src/shell/internal_pages/general.rs +++ b/crates/ely_app/src/shell/internal_pages/general.rs @@ -24,7 +24,7 @@ impl ElyShell { .flex_col() .gap_5() .child(render_general_header(snapshot)) - .child(render_general_summary(snapshot.new_tab_destination)) + .child(render_general_summary(snapshot.new_tab_destination, cx)) .child(render_new_tab_destinations(snapshot.new_tab_destination, cx)), ) } @@ -65,7 +65,10 @@ fn render_general_header(snapshot: &BrowserSnapshot) -> AnyElement { .into_any_element() } -fn render_general_summary(destination: NewTabDestination) -> AnyElement { +fn render_general_summary( + destination: NewTabDestination, + cx: &mut Context, +) -> AnyElement { div() .rounded_md() .border_1() @@ -107,7 +110,28 @@ fn render_general_summary(destination: NewTabDestination) -> AnyElement { ), ) .child( - div().text_xs().font_semibold().text_color(rgb(colors::SUCCESS)).child("Saved locally"), + div() + .flex() + .items_center() + .gap_2() + .child( + div() + .text_xs() + .font_semibold() + .text_color(rgb(colors::SUCCESS)) + .child("Saved locally"), + ) + .child( + Button::new("reset-general-settings") + .ghost() + .xsmall() + .icon(IconName::Undo2) + .label("Reset") + .tooltip("Restore General Defaults") + .on_click(cx.listener(|shell, _, _, cx| { + shell.reset_general_settings(cx); + })), + ), ) .into_any_element() } diff --git a/crates/ely_app/src/shell/internal_pages/privacy_security.rs b/crates/ely_app/src/shell/internal_pages/privacy_security.rs index 96e92ea..d997341 100644 --- a/crates/ely_app/src/shell/internal_pages/privacy_security.rs +++ b/crates/ely_app/src/shell/internal_pages/privacy_security.rs @@ -28,7 +28,7 @@ impl ElyShell { .flex_col() .gap_5() .child(render_privacy_header(snapshot)) - .child(render_history_summary(snapshot)) + .child(render_history_summary(snapshot, cx)) .when(snapshot.active_profile_history_entry_count > 0, |this| { this.child(render_history_clear_controls(confirming_clear, cx)) }) @@ -77,7 +77,7 @@ fn render_privacy_header(snapshot: &BrowserSnapshot) -> AnyElement { .into_any_element() } -fn render_history_summary(snapshot: &BrowserSnapshot) -> AnyElement { +fn render_history_summary(snapshot: &BrowserSnapshot, cx: &mut Context) -> AnyElement { div() .rounded_md() .border_1() @@ -124,10 +124,23 @@ fn render_history_summary(snapshot: &BrowserSnapshot) -> AnyElement { ) .child( div() - .text_xs() - .font_semibold() - .text_color(rgb(colors::MUTED)) - .child(format!("{} Profile entries", snapshot.active_profile_history_entry_count)), + .flex() + .items_center() + .gap_2() + .child(div().text_xs().font_semibold().text_color(rgb(colors::MUTED)).child( + format!("{} Profile entries", snapshot.active_profile_history_entry_count), + )) + .child( + Button::new("reset-privacy-settings") + .ghost() + .xsmall() + .icon(IconName::Undo2) + .label("Reset") + .tooltip("Restore Privacy Defaults") + .on_click(cx.listener(|shell, _, _, cx| { + shell.reset_privacy_settings(cx); + })), + ), ) .into_any_element() } diff --git a/crates/ely_app/src/shell/internal_pages/profiles.rs b/crates/ely_app/src/shell/internal_pages/profiles.rs index 57d941e..23107b5 100644 --- a/crates/ely_app/src/shell/internal_pages/profiles.rs +++ b/crates/ely_app/src/shell/internal_pages/profiles.rs @@ -28,19 +28,21 @@ impl ElyShell { .flex() .flex_col() .gap_5() - .child(render_profiles_header(snapshot)) + .child(render_profiles_header(snapshot, cx)) .child(render_profile_list(snapshot, cx)), ) } } -fn render_profiles_header(snapshot: &BrowserSnapshot) -> AnyElement { +fn render_profiles_header(snapshot: &BrowserSnapshot, cx: &mut Context) -> AnyElement { div() .flex() .items_end() .justify_between() + .gap_4() .child( div() + .min_w_0() .flex() .flex_col() .gap_2() @@ -54,9 +56,26 @@ fn render_profiles_header(snapshot: &BrowserSnapshot) -> AnyElement { ) .child( div() - .text_xs() - .text_color(rgb(colors::MUTED)) - .child(format!("{} profiles", snapshot.profiles.len())), + .flex() + .items_center() + .gap_2() + .child( + div() + .text_xs() + .text_color(rgb(colors::MUTED)) + .child(format!("{} profiles", snapshot.profiles.len())), + ) + .child( + Button::new("reset-profile-sync-settings") + .ghost() + .xsmall() + .icon(IconName::Undo2) + .label("Reset Sync") + .tooltip("Restore Profile Sync Defaults") + .on_click(cx.listener(|shell, _, _, cx| { + shell.reset_profile_sync_settings(cx); + })), + ), ) .into_any_element() } diff --git a/crates/ely_app/src/shell/internal_pages/search.rs b/crates/ely_app/src/shell/internal_pages/search.rs index d64a22e..65885bf 100644 --- a/crates/ely_app/src/shell/internal_pages/search.rs +++ b/crates/ely_app/src/shell/internal_pages/search.rs @@ -24,7 +24,7 @@ impl ElyShell { .flex_col() .gap_5() .child(render_search_header(snapshot)) - .child(render_search_summary(snapshot.search_engine)) + .child(render_search_summary(snapshot.search_engine, cx)) .child(render_search_engines(snapshot.search_engine, cx)), ) } @@ -65,7 +65,7 @@ fn render_search_header(snapshot: &BrowserSnapshot) -> AnyElement { .into_any_element() } -fn render_search_summary(search_engine: SearchEngine) -> AnyElement { +fn render_search_summary(search_engine: SearchEngine, cx: &mut Context) -> AnyElement { div() .rounded_md() .border_1() @@ -107,7 +107,28 @@ fn render_search_summary(search_engine: SearchEngine) -> AnyElement { ), ) .child( - div().text_xs().font_semibold().text_color(rgb(colors::SUCCESS)).child("Saved locally"), + div() + .flex() + .items_center() + .gap_2() + .child( + div() + .text_xs() + .font_semibold() + .text_color(rgb(colors::SUCCESS)) + .child("Saved locally"), + ) + .child( + Button::new("reset-search-settings") + .ghost() + .xsmall() + .icon(IconName::Undo2) + .label("Reset") + .tooltip("Restore Search Defaults") + .on_click(cx.listener(|shell, _, _, cx| { + shell.reset_search_settings(cx); + })), + ), ) .into_any_element() } diff --git a/crates/ely_app/src/shell/internal_pages/sidebar_tabs.rs b/crates/ely_app/src/shell/internal_pages/sidebar_tabs.rs index 5900c02..8b8a151 100644 --- a/crates/ely_app/src/shell/internal_pages/sidebar_tabs.rs +++ b/crates/ely_app/src/shell/internal_pages/sidebar_tabs.rs @@ -64,13 +64,17 @@ impl ElyShell { .flex() .flex_col() .gap_5() - .child(render_sidebar_tabs_header(snapshot, active_space)) + .child(render_sidebar_tabs_header(snapshot, active_space, cx)) .child(render_sidebar_tabs_settings(snapshot, active_space, cx)), ) } } -fn render_sidebar_tabs_header(snapshot: &BrowserSnapshot, active_space: &Space) -> AnyElement { +fn render_sidebar_tabs_header( + snapshot: &BrowserSnapshot, + active_space: &Space, + cx: &mut Context, +) -> AnyElement { div() .flex() .items_end() @@ -98,16 +102,33 @@ fn render_sidebar_tabs_header(snapshot: &BrowserSnapshot, active_space: &Space) .flex() .items_center() .gap_2() - .text_xs() - .font_semibold() - .text_color(rgb(colors::MUTED)) - .child(IconName::LayoutDashboard) - .child(format!( - "{} / {} / {}", - sidebar_width_label(active_space), - archive_policy_label(active_space.archive_policy()), - snapshot.favorite_limit.label() - )), + .child( + div() + .flex() + .items_center() + .gap_2() + .text_xs() + .font_semibold() + .text_color(rgb(colors::MUTED)) + .child(IconName::LayoutDashboard) + .child(format!( + "{} / {} / {}", + sidebar_width_label(active_space), + archive_policy_label(active_space.archive_policy()), + snapshot.favorite_limit.label() + )), + ) + .child( + Button::new("reset-sidebar-tabs-settings") + .ghost() + .xsmall() + .icon(IconName::Undo2) + .label("Reset") + .tooltip("Restore Sidebar & Tabs Defaults") + .on_click(cx.listener(|shell, _, _, cx| { + shell.reset_sidebar_tabs_settings(cx); + })), + ), ) .into_any_element() } diff --git a/crates/ely_app/src/shell/internal_pages/sync.rs b/crates/ely_app/src/shell/internal_pages/sync.rs index d6aa855..d9796f5 100644 --- a/crates/ely_app/src/shell/internal_pages/sync.rs +++ b/crates/ely_app/src/shell/internal_pages/sync.rs @@ -8,7 +8,11 @@ use gpui::{ px, rgb, }; use gpui::{StatefulInteractiveElement, prelude::FluentBuilder}; -use gpui_component::{IconName, StyledExt, scroll::ScrollableElement}; +use gpui_component::{ + IconName, Sizable, StyledExt, + button::{Button, ButtonVariants}, + scroll::ScrollableElement, +}; use super::{ElyShell, render_canvas_surface}; @@ -26,7 +30,7 @@ impl ElyShell { .flex_col() .gap_5() .child(render_sync_header(snapshot)) - .child(render_sync_queue(snapshot)) + .child(render_sync_queue(snapshot, cx)) .child(render_sync_objects(snapshot, cx)), ) } @@ -64,7 +68,7 @@ fn render_sync_header(snapshot: &BrowserSnapshot) -> AnyElement { .into_any_element() } -fn render_sync_queue(snapshot: &BrowserSnapshot) -> AnyElement { +fn render_sync_queue(snapshot: &BrowserSnapshot, cx: &mut Context) -> AnyElement { div() .rounded_md() .border_1() @@ -76,8 +80,33 @@ fn render_sync_queue(snapshot: &BrowserSnapshot) -> AnyElement { .items_center() .justify_between() .gap_4() - .child(metric_block("Pending objects", snapshot.sync_status.pending_objects(), colors::INK)) - .child(metric_block("Failed objects", snapshot.sync_status.failed_objects(), colors::ERROR)) + .child( + div() + .flex() + .items_center() + .gap_4() + .child(metric_block( + "Pending objects", + snapshot.sync_status.pending_objects(), + colors::INK, + )) + .child(metric_block( + "Failed objects", + snapshot.sync_status.failed_objects(), + colors::ERROR, + )), + ) + .child( + Button::new("reset-sync-settings") + .ghost() + .xsmall() + .icon(IconName::Undo2) + .label("Reset") + .tooltip("Restore Sync Defaults") + .on_click(cx.listener(|shell, _, _, cx| { + shell.reset_sync_settings(cx); + })), + ) .into_any_element() } diff --git a/crates/ely_app/src/shell/mod.rs b/crates/ely_app/src/shell/mod.rs index b2099a8..15a042f 100644 --- a/crates/ely_app/src/shell/mod.rs +++ b/crates/ely_app/src/shell/mod.rs @@ -10,6 +10,7 @@ mod notes; mod plugins; mod reading_list; mod render; +mod settings_actions; mod sidebar; mod site_permissions; mod space_files; @@ -28,10 +29,7 @@ mod web_surface_state; mod web_surface_view; use ely_browser_core::{BrowserCore, InitialBrowserConfig}; -use ely_domain::{ - ArchivePolicy, DownloadPolicy, FavoriteLimit, HistoryRecordingPolicy, NewTabDestination, - ProfileId, ProfileSyncPolicy, SearchEngine, SpaceId, SyncObjectKind, SyncObjectPolicy, TabId, -}; +use ely_domain::{ProfileId, SpaceId, TabId}; use gpui::{AppContext, Context, Entity, FocusHandle, Subscription, Window}; use gpui_component::input::{InputEvent, InputState}; @@ -268,95 +266,6 @@ impl ElyShell { } } - fn set_active_space_archive_policy( - &mut self, - archive_policy: ArchivePolicy, - cx: &mut Context, - ) { - if let ShellState::Ready(core) = &mut self.state - && core.set_active_space_archive_policy(archive_policy).is_ok() - { - cx.notify(); - } - } - - fn set_search_engine(&mut self, search_engine: SearchEngine, cx: &mut Context) { - if let ShellState::Ready(core) = &mut self.state { - core.set_search_engine(search_engine); - cx.notify(); - } - } - - fn set_new_tab_destination(&mut self, destination: NewTabDestination, cx: &mut Context) { - if let ShellState::Ready(core) = &mut self.state { - core.set_new_tab_destination(destination); - cx.notify(); - } - } - - fn set_history_recording_policy( - &mut self, - policy: HistoryRecordingPolicy, - cx: &mut Context, - ) { - if let ShellState::Ready(core) = &mut self.state { - core.set_history_recording_policy(policy); - cx.notify(); - } - } - - fn set_active_profile_download_policy( - &mut self, - policy: DownloadPolicy, - cx: &mut Context, - ) { - if let ShellState::Ready(core) = &mut self.state - && core.set_active_profile_download_policy(policy).is_ok() - { - cx.notify(); - } - } - - fn set_profile_sync_policy( - &mut self, - profile_id: &ProfileId, - sync_policy: ProfileSyncPolicy, - cx: &mut Context, - ) { - if let ShellState::Ready(core) = &mut self.state - && core.set_profile_sync_policy(profile_id, sync_policy).is_ok() - { - cx.notify(); - } - } - - fn set_favorite_limit(&mut self, favorite_limit: FavoriteLimit, cx: &mut Context) { - if let ShellState::Ready(core) = &mut self.state { - core.set_favorite_limit(favorite_limit); - cx.notify(); - } - } - - fn set_sync_object_policy( - &mut self, - kind: SyncObjectKind, - policy: SyncObjectPolicy, - cx: &mut Context, - ) { - if let ShellState::Ready(core) = &mut self.state { - core.set_sync_object_policy(kind, policy); - cx.notify(); - } - } - - fn archive_idle_tabs_now(&mut self, cx: &mut Context) { - if let ShellState::Ready(core) = &mut self.state - && core.archive_idle_tabs(std::time::SystemTime::now()).is_ok() - { - cx.notify(); - } - } - fn on_close_current_tab( &mut self, _: &CloseCurrentTab, diff --git a/crates/ely_app/src/shell/settings_actions.rs b/crates/ely_app/src/shell/settings_actions.rs new file mode 100644 index 0000000..7c9540e --- /dev/null +++ b/crates/ely_app/src/shell/settings_actions.rs @@ -0,0 +1,161 @@ +use ely_domain::{ + ArchivePolicy, DownloadPolicy, FavoriteLimit, HistoryRecordingPolicy, NewTabDestination, + ProfileId, ProfileSyncPolicy, SearchEngine, SyncObjectKind, SyncObjectPolicy, +}; +use gpui::Context; + +use super::{ElyShell, ShellState}; + +impl ElyShell { + pub(super) fn set_active_space_archive_policy( + &mut self, + archive_policy: ArchivePolicy, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state + && core.set_active_space_archive_policy(archive_policy).is_ok() + { + cx.notify(); + } + } + + pub(super) fn set_search_engine( + &mut self, + search_engine: SearchEngine, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state { + core.set_search_engine(search_engine); + cx.notify(); + } + } + + pub(super) fn reset_search_settings(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state { + core.reset_search_settings(); + cx.notify(); + } + } + + pub(super) fn set_new_tab_destination( + &mut self, + destination: NewTabDestination, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state { + core.set_new_tab_destination(destination); + cx.notify(); + } + } + + pub(super) fn reset_general_settings(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state { + core.reset_general_settings(); + cx.notify(); + } + } + + pub(super) fn set_history_recording_policy( + &mut self, + policy: HistoryRecordingPolicy, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state { + core.set_history_recording_policy(policy); + cx.notify(); + } + } + + pub(super) fn reset_privacy_settings(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state { + core.reset_privacy_settings(); + cx.notify(); + } + } + + pub(super) fn set_active_profile_download_policy( + &mut self, + policy: DownloadPolicy, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state + && core.set_active_profile_download_policy(policy).is_ok() + { + cx.notify(); + } + } + + pub(super) fn reset_active_profile_download_settings(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state + && core.reset_active_profile_download_settings().is_ok() + { + cx.notify(); + } + } + + pub(super) fn set_profile_sync_policy( + &mut self, + profile_id: &ProfileId, + sync_policy: ProfileSyncPolicy, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state + && core.set_profile_sync_policy(profile_id, sync_policy).is_ok() + { + cx.notify(); + } + } + + pub(super) fn reset_profile_sync_settings(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state { + core.reset_profile_sync_settings(); + cx.notify(); + } + } + + pub(super) fn set_favorite_limit( + &mut self, + favorite_limit: FavoriteLimit, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state { + core.set_favorite_limit(favorite_limit); + cx.notify(); + } + } + + pub(super) fn reset_sidebar_tabs_settings(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state + && core.reset_sidebar_tabs_settings().is_ok() + { + cx.notify(); + } + } + + pub(super) fn set_sync_object_policy( + &mut self, + kind: SyncObjectKind, + policy: SyncObjectPolicy, + cx: &mut Context, + ) { + if let ShellState::Ready(core) = &mut self.state { + core.set_sync_object_policy(kind, policy); + cx.notify(); + } + } + + pub(super) fn reset_sync_settings(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state { + core.reset_sync_settings(); + cx.notify(); + } + } + + pub(super) fn archive_idle_tabs_now(&mut self, cx: &mut Context) { + if let ShellState::Ready(core) = &mut self.state + && core.archive_idle_tabs(std::time::SystemTime::now()).is_ok() + { + cx.notify(); + } + } +} diff --git a/crates/ely_browser_core/src/state.rs b/crates/ely_browser_core/src/state.rs index 06f2b06..9011a23 100644 --- a/crates/ely_browser_core/src/state.rs +++ b/crates/ely_browser_core/src/state.rs @@ -1,9 +1,9 @@ use std::{collections::BTreeMap, time::SystemTime}; use ely_domain::{ - ArchivePolicy, ArchivedTab, BookmarkEntry, BrowserTab, DomainError, DownloadEntry, - DownloadPolicy, FavoriteLimit, HistoryEntry, HistoryRecordingPolicy, NewTabDestination, - NoteEntry, Profile, ProfileId, ProfileKind, ReadingListEntry, SearchEngine, + ArchivePolicy, ArchivedTab, BookmarkEntry, BrowserTab, DEFAULT_SIDEBAR_WIDTH_PX, DomainError, + DownloadEntry, DownloadPolicy, FavoriteLimit, HistoryEntry, HistoryRecordingPolicy, + NewTabDestination, NoteEntry, Profile, ProfileId, ProfileKind, ReadingListEntry, SearchEngine, SitePermissionAuditEvent, SitePermissionEntry, Space, SpaceId, SplitLayout, SyncStatus, TabGroup, TabId, UrlText, }; @@ -292,6 +292,10 @@ impl BrowserCore { self.search_engine = search_engine; } + pub fn reset_search_settings(&mut self) { + self.set_search_engine(SearchEngine::default()); + } + #[must_use] pub fn search_engine(&self) -> SearchEngine { self.search_engine @@ -301,6 +305,10 @@ impl BrowserCore { self.new_tab_destination = destination; } + pub fn reset_general_settings(&mut self) { + self.set_new_tab_destination(NewTabDestination::default()); + } + #[must_use] pub fn new_tab_destination(&self) -> NewTabDestination { self.new_tab_destination @@ -310,6 +318,10 @@ impl BrowserCore { self.history_recording_policy = policy; } + pub fn reset_privacy_settings(&mut self) { + self.set_history_recording_policy(HistoryRecordingPolicy::default()); + } + #[must_use] pub fn history_recording_policy(&self) -> HistoryRecordingPolicy { self.history_recording_policy @@ -319,6 +331,14 @@ impl BrowserCore { self.favorite_limit = favorite_limit; } + pub fn reset_sidebar_tabs_settings(&mut self) -> Result<(), CoreError> { + let active_space_id = self.active_space_id.clone(); + self.set_space_archive_policy(&active_space_id, ArchivePolicy::Manual)?; + self.set_space_sidebar_width(&active_space_id, DEFAULT_SIDEBAR_WIDTH_PX)?; + self.set_favorite_limit(FavoriteLimit::default()); + Ok(()) + } + #[must_use] pub fn favorite_limit(&self) -> FavoriteLimit { self.favorite_limit diff --git a/crates/ely_browser_core/src/state/profiles.rs b/crates/ely_browser_core/src/state/profiles.rs index ae3ab33..8d61c6f 100644 --- a/crates/ely_browser_core/src/state/profiles.rs +++ b/crates/ely_browser_core/src/state/profiles.rs @@ -90,6 +90,10 @@ impl BrowserCore { self.set_profile_download_policy(&profile_id, download_policy) } + pub fn reset_active_profile_download_settings(&mut self) -> Result<(), CoreError> { + self.set_active_profile_download_policy(DownloadPolicy::ask_every_time()) + } + pub fn set_profile_sync_policy( &mut self, profile_id: &ProfileId, @@ -108,6 +112,12 @@ impl BrowserCore { Ok(()) } + pub fn reset_profile_sync_settings(&mut self) { + for profile in &mut self.profiles { + profile.set_sync_policy(ProfileSyncPolicy::default()); + } + } + pub(super) fn cleanup_private_profile_session_data(&mut self, profile_id: &ProfileId) { if self .profiles diff --git a/crates/ely_browser_core/src/state/sync.rs b/crates/ely_browser_core/src/state/sync.rs index 4d22cd3..65519eb 100644 --- a/crates/ely_browser_core/src/state/sync.rs +++ b/crates/ely_browser_core/src/state/sync.rs @@ -66,6 +66,10 @@ impl BrowserCore { self.sync_object_policies.set(kind, policy); } + pub fn reset_sync_settings(&mut self) { + self.sync_object_policies = SyncObjectPolicies::default(); + } + #[must_use] pub fn sync_object_policy(&self, kind: SyncObjectKind) -> SyncObjectPolicy { self.sync_object_policies.get(kind) diff --git a/crates/ely_browser_core/tests/settings_defaults.rs b/crates/ely_browser_core/tests/settings_defaults.rs new file mode 100644 index 0000000..92744e3 --- /dev/null +++ b/crates/ely_browser_core/tests/settings_defaults.rs @@ -0,0 +1,78 @@ +use std::{error::Error, path::PathBuf}; + +use ely_browser_core::{BrowserCore, InitialBrowserConfig}; +use ely_domain::{ + ArchivePolicy, DEFAULT_SIDEBAR_WIDTH_PX, DownloadPolicy, FavoriteLimit, HistoryRecordingPolicy, + NewTabDestination, ProfileKind, ProfileSyncPolicy, SearchEngine, SyncObjectKind, + SyncObjectPolicy, +}; + +#[test] +fn section_resets_restore_settings_defaults() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + + core.set_new_tab_destination(NewTabDestination::Bookmarks); + core.reset_general_settings(); + assert_eq!(core.snapshot()?.new_tab_destination, NewTabDestination::ElyNewTab); + + core.set_search_engine(SearchEngine::Google); + core.reset_search_settings(); + assert_eq!(core.snapshot()?.search_engine, SearchEngine::DuckDuckGo); + + core.set_history_recording_policy(HistoryRecordingPolicy::Pause); + core.reset_privacy_settings(); + assert_eq!(core.snapshot()?.history_recording_policy, HistoryRecordingPolicy::Record); + + let active_space_id = core.snapshot()?.active_space_id; + core.set_active_space_archive_policy(ArchivePolicy::IdleDays(30))?; + core.set_space_sidebar_width(&active_space_id, 56)?; + core.set_favorite_limit(FavoriteLimit::Six); + core.reset_sidebar_tabs_settings()?; + + let snapshot = core.snapshot()?; + let Some(active_space) = snapshot.spaces.iter().find(|space| space.id() == &active_space_id) + else { + return Err("missing active space".into()); + }; + assert_eq!(active_space.archive_policy(), &ArchivePolicy::Manual); + assert_eq!(active_space.sidebar_width_px(), DEFAULT_SIDEBAR_WIDTH_PX); + assert_eq!(snapshot.favorite_limit, FavoriteLimit::Twelve); + + core.set_active_profile_download_policy(DownloadPolicy::fixed_directory(PathBuf::from( + "/tmp", + ))?)?; + core.reset_active_profile_download_settings()?; + assert_eq!(core.snapshot()?.active_download_policy, DownloadPolicy::ask_every_time()); + + core.set_sync_object_policy(SyncObjectKind::Tabs, SyncObjectPolicy::Paused); + core.reset_sync_settings(); + assert_eq!(core.sync_object_policy(SyncObjectKind::Tabs), SyncObjectPolicy::Enabled); + Ok(()) +} + +#[test] +fn profile_sync_reset_restores_profile_kind_defaults() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let standard_profile_id = core.snapshot()?.active_profile_id; + let private_profile_id = core.create_profile("Private", 0x807d72, ProfileKind::Private)?; + + core.select_profile(&standard_profile_id)?; + core.set_profile_sync_policy(&standard_profile_id, ProfileSyncPolicy::Paused)?; + core.reset_profile_sync_settings(); + + let snapshot = core.snapshot()?; + let Some(standard_profile) = + snapshot.profiles.iter().find(|profile| profile.id() == &standard_profile_id) + else { + return Err("missing standard profile".into()); + }; + let Some(private_profile) = + snapshot.profiles.iter().find(|profile| profile.id() == &private_profile_id) + else { + return Err("missing private profile".into()); + }; + + assert_eq!(standard_profile.sync_policy(), ProfileSyncPolicy::Enabled); + assert_eq!(private_profile.sync_policy(), ProfileSyncPolicy::Paused); + Ok(()) +}