diff options
| author | Christian Cleberg <[email protected]> | 2026-07-17 17:12:46 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-07-17 17:12:46 -0500 |
| commit | 277e2a7209047ed1514ea7b34034c510a4e51a4f (patch) | |
| tree | 3a0f5ae9c088a14f09831e23f8cb8608210d78cd /octosentry/SecurityEventStore.swift | |
| parent | 8e6d29f1806cc569b48d913564c7d80a1c2f2355 (diff) | |
| download | octosentry-0.5.0.tar.gz octosentry-0.5.0.tar.bz2 octosentry-0.5.0.zip | |
Add mark-seen action, critical-alert badge, and a dedicated window0.5.0
Closes #8-#10 (milestone 0.5.0).
- Mark-seen: each row gets a checkmark button (separate from the
click-to-open button) that persists the event into seenEventIDs and
removes it from the active stream immediately, no API write.
- Menu bar icon switches to a filled exclamation-shield with a red badge
showing the count of unseen critical alerts when any exist.
- Added a dedicated Window (singleton scene, not WindowGroup — avoids
spawning duplicates) opened via a header button, sharing the exact
same store/authStore instances as the popover. The button hides itself
when already viewing the standalone window.
Diffstat (limited to 'octosentry/SecurityEventStore.swift')
| -rw-r--r-- | octosentry/SecurityEventStore.swift | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/octosentry/SecurityEventStore.swift b/octosentry/SecurityEventStore.swift index 65a7280..26dcc16 100644 --- a/octosentry/SecurityEventStore.swift +++ b/octosentry/SecurityEventStore.swift @@ -28,6 +28,10 @@ final class SecurityEventStore { private(set) var watchedRepos: [String] = [] private(set) var watchListErrorMessage: String? + var unseenCriticalCount: Int { + rawEvents.filter { $0.severity == .critical && !$0.seenLocally }.count + } + private let persistenceStore = PersistenceStore() private var rawEvents: [SecurityEvent] = [] private var pollingTask: Task<Void, Never>? @@ -130,6 +134,18 @@ final class SecurityEventStore { await refresh() } + /// Local-only triage state (spec §11) — no API write, no scope beyond + /// read needed. Removes the event from the active stream. + func markSeen(_ eventID: String) async { + var state = await persistenceStore.load() + state.seenEventIDs.insert(eventID) + await persistenceStore.save(state) + + rawEvents.removeAll { $0.id == eventID } + totalFetchedCount = rawEvents.count + applyMinimumSeverityFilter() + } + func removeRepo(_ repoFullName: String) async { var state = await persistenceStore.load() state.watchedRepos.removeAll { $0 == repoFullName } |
