diff --git a/pixstrip-core/src/config.rs b/pixstrip-core/src/config.rs index cb9c38d..f859827 100644 --- a/pixstrip-core/src/config.rs +++ b/pixstrip-core/src/config.rs @@ -17,6 +17,8 @@ pub struct AppConfig { pub high_contrast: bool, pub large_text: bool, pub reduced_motion: bool, + pub history_max_entries: usize, + pub history_max_days: u32, } impl Default for AppConfig { @@ -36,6 +38,8 @@ impl Default for AppConfig { high_contrast: false, large_text: false, reduced_motion: false, + history_max_entries: 50, + history_max_days: 30, } } } diff --git a/pixstrip-core/src/storage.rs b/pixstrip-core/src/storage.rs index 997ded0..6fd49d5 100644 --- a/pixstrip-core/src/storage.rs +++ b/pixstrip-core/src/storage.rs @@ -272,6 +272,32 @@ impl HistoryStore { self.write_all(&entries) } + pub fn prune(&self, max_entries: usize, max_days: u32) -> Result<()> { + let mut entries = self.list()?; + if entries.is_empty() { + return Ok(()); + } + + let now_secs = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + let cutoff_secs = now_secs.saturating_sub(max_days as u64 * 86400); + + // Remove entries older than max_days + entries.retain(|e| { + e.timestamp.parse::().unwrap_or(0) >= cutoff_secs + }); + + // Trim to max_entries (keep the most recent) + if entries.len() > max_entries { + let start = entries.len() - max_entries; + entries = entries.split_off(start); + } + + self.write_all(&entries) + } + pub fn list(&self) -> Result> { if !self.history_path.exists() { return Ok(Vec::new()); diff --git a/pixstrip-gtk/src/app.rs b/pixstrip-gtk/src/app.rs index 95cb256..3591dd7 100644 --- a/pixstrip-gtk/src/app.rs +++ b/pixstrip-gtk/src/app.rs @@ -1629,6 +1629,11 @@ fn show_results( output_files, }); + // Prune old history entries + let config_store = pixstrip_core::storage::ConfigStore::new(); + let app_config = config_store.load().unwrap_or_default(); + let _ = history.prune(app_config.history_max_entries, app_config.history_max_days); + // Show toast let savings = if result.total_input_bytes > 0 { let pct = diff --git a/pixstrip-gtk/src/settings.rs b/pixstrip-gtk/src/settings.rs index 7b569c4..0e9df98 100644 --- a/pixstrip-gtk/src/settings.rs +++ b/pixstrip-gtk/src/settings.rs @@ -271,6 +271,10 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog { }); } + // Preserve history settings from current config (not exposed in UI yet) + let hist_max_entries = config.history_max_entries; + let hist_max_days = config.history_max_days; + // Save settings when the dialog closes dialog.connect_closed(move |_| { let new_config = AppConfig { @@ -305,6 +309,8 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog { high_contrast: contrast_row.is_active(), large_text: large_text_row.is_active(), reduced_motion: motion_row.is_active(), + history_max_entries: hist_max_entries, + history_max_days: hist_max_days, }; let store = ConfigStore::new();