Context
The Recordings window (⌘L) is a plain list with small 128×80 thumbnails, no search, and newest-first order only. Once you have dozens of recordings, finding one is slow. There are also two small issues worth fixing along the way:
- The window reloads on
NSWindow.didBecomeKeyNotification from any window, re-reading every project.json each time an editor or Settings window gets focus.
- The empty state always says "Recordings are saved to ~/Movies/Recordings", even when a custom folder is set in Settings.
Where to look
Sources/Snapcap/Views/LibraryView.swift: LibraryView, LibraryRow, loadThumbnail(for:) (which uses AVAssetImageGenerator at min(1, duration / 2)), the context menu and the trash confirmation.
Sources/SnapcapCore/Model/RecordingLibrary.swift: entries() (sorted newest first), Entry.exportURL and rootURL.
Sources/Snapcap/Views/EditorView.swift: EditorModel.rename(to:), if you want to offer Rename from the grid too.
Sources/Snapcap/App/AppDelegate.swift: showLibrary() creates the window (760×560, minimum 520×360).
Sources/Snapcap/Views/Components.swift: formatDuration and the Brand colors.
Proposal
- Show a grid of cards in a
LazyVGrid with adaptive columns of about 220 pt. Each card has a 16:10 thumbnail, name, duration, date and export status. Keep a list mode behind a toggle stored in @AppStorage.
- Add
.searchable filtering by name and source title, case- and diacritic-insensitive.
- Add a sort menu (newest, oldest, longest, name), and remember the choice.
- Cache thumbnails in an
NSCache keyed by folder and lastExport.date, so scrolling and reloads don't regenerate them.
- Keep every existing context-menu action. Double-click and Return open a recording, and ⌘⌫ moves it to the Trash with the existing confirmation.
- Reload only when the Recordings window itself becomes key, or watch the folder with a
DispatchSource.
- Put the filter and sort logic in a small pure function in
SnapcapCore so it can be unit tested.
Acceptance criteria
Context
The Recordings window (⌘L) is a plain list with small 128×80 thumbnails, no search, and newest-first order only. Once you have dozens of recordings, finding one is slow. There are also two small issues worth fixing along the way:
NSWindow.didBecomeKeyNotificationfrom any window, re-reading everyproject.jsoneach time an editor or Settings window gets focus.Where to look
Sources/Snapcap/Views/LibraryView.swift:LibraryView,LibraryRow,loadThumbnail(for:)(which usesAVAssetImageGeneratoratmin(1, duration / 2)), the context menu and the trash confirmation.Sources/SnapcapCore/Model/RecordingLibrary.swift:entries()(sorted newest first),Entry.exportURLandrootURL.Sources/Snapcap/Views/EditorView.swift:EditorModel.rename(to:), if you want to offer Rename from the grid too.Sources/Snapcap/App/AppDelegate.swift:showLibrary()creates the window (760×560, minimum 520×360).Sources/Snapcap/Views/Components.swift:formatDurationand theBrandcolors.Proposal
LazyVGridwith adaptive columns of about 220 pt. Each card has a 16:10 thumbnail, name, duration, date and export status. Keep a list mode behind a toggle stored in@AppStorage..searchablefiltering by name and source title, case- and diacritic-insensitive.NSCachekeyed by folder andlastExport.date, so scrolling and reloads don't regenerate them.DispatchSource.SnapcapCoreso it can be unit tested.Acceptance criteria
for i in $(seq 1 120); do snapcap-cli fixture /tmp/snapcap-lib/Sessions/fixture-$i --seconds 2; done, then launch withSNAPCAP_LIBRARY=/tmp/snapcap-lib.