Skip to content

Turn history retention into a discrete slider with named presets - #89

Closed
alvst wants to merge 1 commit into
momenbasel:mainfrom
alvst:alvie/pr-retention-slider
Closed

alvst wants to merge 1 commit into
momenbasel:mainfrom
alvst:alvie/pr-retention-slider

Conversation

@alvst

@alvst alvst commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

The "remove clips older than" day picker offered a handful of choices and no way to say "keep everything". This replaces it with a 10-stop slider of named presets, adding 3 Weeks, 2 Months, and Forever.

What changed

  • A new HistoryRetentionPreset drives a 10-stop slider from 1 Day through Forever, replacing the day-choice Picker.
  • Forever is stored as historyRetentionDays == 0 — no automatic pruning by age; the existing safety cap still applies.
  • The confirm-before-apply dialog for destructive changes is kept exactly as it was: only the presentation of the choice changes, not the safety UX around it.
  • Layout fix at the call site: Form(.formStyle(.grouped)) puts every row in a Section's body onto a shared label/control NSGridView, which clamps and right-shifts a bare control regardless of SwiftUI frame modifiers. The slider block moved into the Section's footer, which is plain full-width content.

Screenshots

Before:
00-baseline screenshots bar.png

After:
08-retention-slider screenshots after.png

Notes for review

  • Stored-value migration is safe: every previously stored day count remains a valid stop, so existing installs land on their current setting.
  • The confirm dialog still covers every destructive direction — mode switch, tighter preset, and Forever → short.
  • No dependencies; merges in any order.

This feature should be bundled into v2.

Part of #80.

Replaces the "remove clips older than" day-choice Picker with a
10-stop slider (1 Day through Forever) matching Alvie's Pesty's
granularity, via a new HistoryRetentionPreset enum. Adds three new
stops baseline didn't have (3 Weeks, 2 Months, Forever) - Forever is
represented as historyRetentionDays == 0, meaning "no automatic
pruning by age", with only the existing safety cap still applying.

Keeps the confirm-before-apply destructive-change dialog baseline
already had; only the presentation of the choice changes, not the
safety UX around it.

The slider itself needed a fix unrelated to its content: on macOS,
Form(.formStyle(.grouped)) lays out every row in a Section's body on
a shared label/control NSGridView, which clamps and right-shifts any
bare control placed there regardless of SwiftUI-side frame modifiers.
Moving the slider block into the Section's footer (plain full-width
content, never part of that grid) fixes it - see the comment at the
call site for how this was confirmed.
@momenbasel

Copy link
Copy Markdown
Owner

Landed as 3488572 through #104 with a follow-up (d84964d). The slider wrote the draft at every stop it crossed and each write ran the removal check: dragging from 1 Year toward 1 Day committed 6 Months on the way past it, put up the confirm alert for 3 Months while the mouse was still down, and Cancel restored 6 Months instead of 1 Year. It now moves a local value and applies it once editing ends (or on a keyboard step), so Cancel returns to the value the drag started from; the stop under the thumb is still shown live. retentionCutoff returns nil for 0 days instead of treating it as 1, so Forever cannot regress through a new caller. Thanks @alvst.

@momenbasel momenbasel closed this Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants