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/octosentryApp.swift | |
| parent | 8e6d29f1806cc569b48d913564c7d80a1c2f2355 (diff) | |
| download | octosentry-277e2a7209047ed1514ea7b34034c510a4e51a4f.tar.gz octosentry-277e2a7209047ed1514ea7b34034c510a4e51a4f.tar.bz2 octosentry-277e2a7209047ed1514ea7b34034c510a4e51a4f.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/octosentryApp.swift')
| -rw-r--r-- | octosentry/octosentryApp.swift | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/octosentry/octosentryApp.swift b/octosentry/octosentryApp.swift index cf7522d..e80c4a0 100644 --- a/octosentry/octosentryApp.swift +++ b/octosentry/octosentryApp.swift @@ -7,15 +7,46 @@ import SwiftUI +enum SecurityEventWindow { + static let id = "security-events-window" +} + @main struct octosentryApp: App { @State private var store = SecurityEventStore() @State private var authStore = AuthStore() var body: some Scene { - MenuBarExtra("OctoSentry", systemImage: "shield.lefthalf.filled") { + MenuBarExtra { SecurityEventListView(store: store, authStore: authStore) + .frame(width: 380, height: 420) + } label: { + MenuBarIconView(criticalCount: store.unseenCriticalCount) } .menuBarExtraStyle(.window) + + Window("Security Events", id: SecurityEventWindow.id) { + SecurityEventListView(store: store, authStore: authStore, isStandaloneWindow: true) + .frame(minWidth: 420, minHeight: 480) + } + } +} + +private struct MenuBarIconView: View { + let criticalCount: Int + + var body: some View { + ZStack(alignment: .topTrailing) { + Image(systemName: criticalCount > 0 ? "exclamationmark.shield.fill" : "shield.lefthalf.filled") + + if criticalCount > 0 { + Text(criticalCount > 9 ? "9+" : "\(criticalCount)") + .font(.system(size: 8, weight: .bold)) + .foregroundStyle(.white) + .padding(2) + .background(Circle().fill(.red)) + .offset(x: 8, y: -6) + } + } } } |
