Cleanup of presenting.

This commit is contained in:
Max Goedjen 2025-09-13 00:49:23 -07:00
parent 0bff214dfd
commit ee7b367b54
No known key found for this signature in database
8 changed files with 96 additions and 61 deletions

View File

@ -295,7 +295,7 @@
path = Helpers; path = Helpers;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
504788ED2E681EB200B4556F /* Styles */ = { 504788ED2E681EB200B4556F /* Modifiers */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
50E4C4522E73C78900C73783 /* WindowBackgroundStyle.swift */, 50E4C4522E73C78900C73783 /* WindowBackgroundStyle.swift */,
@ -304,7 +304,7 @@
504789222E697DD300B4556F /* BoxBackgroundStyle.swift */, 504789222E697DD300B4556F /* BoxBackgroundStyle.swift */,
5065E312295517C500E16645 /* ToolbarButtonStyle.swift */, 5065E312295517C500E16645 /* ToolbarButtonStyle.swift */,
); );
path = Styles; path = Modifiers;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
504788EE2E681EC300B4556F /* Secrets */ = { 504788EE2E681EC300B4556F /* Secrets */ = {
@ -435,7 +435,7 @@
children = ( children = (
504788EF2E681ED700B4556F /* Configuration */, 504788EF2E681ED700B4556F /* Configuration */,
504788EE2E681EC300B4556F /* Secrets */, 504788EE2E681EC300B4556F /* Secrets */,
504788ED2E681EB200B4556F /* Styles */, 504788ED2E681EB200B4556F /* Modifiers */,
504788F02E681F0100B4556F /* Views */, 504788F02E681F0100B4556F /* Views */,
); );
path = Views; path = Views;

View File

@ -4,54 +4,17 @@ import SecureEnclaveSecretKit
import SmartCardSecretKit import SmartCardSecretKit
import Brief import Brief
extension EnvironmentValues {
// This is injected through .environment modifier below instead of @Entry for performance reasons (basially, restrictions around init/mainactor causing delay in loading secrets/"empty screen" blip).
@MainActor fileprivate static let _secretStoreList: SecretStoreList = {
let list = SecretStoreList()
let cryptoKit = SecureEnclave.Store()
let migrator = SecureEnclave.CryptoKitMigrator()
try? migrator.migrate(to: cryptoKit)
list.add(store: cryptoKit)
list.add(store: SmartCard.Store())
return list
}()
private static let _agentStatusChecker = AgentStatusChecker()
@Entry var agentStatusChecker: any AgentStatusCheckerProtocol = _agentStatusChecker
private static let _updater: any UpdaterProtocol = {
@AppStorage("defaultsHasRunSetup") var hasRunSetup = false
return Updater(checkOnLaunch: hasRunSetup)
}()
@Entry var updater: any UpdaterProtocol = _updater
private static let _justUpdatedChecker = JustUpdatedChecker()
@Entry var justUpdatedChecker: any JustUpdatedCheckerProtocol = _justUpdatedChecker
@MainActor var secretStoreList: SecretStoreList {
EnvironmentValues._secretStoreList
}
}
@main @main
struct Secretive: App { struct Secretive: App {
@Environment(\.agentStatusChecker) var agentStatusChecker @Environment(\.agentStatusChecker) var agentStatusChecker
@Environment(\.justUpdatedChecker) var justUpdatedChecker @Environment(\.justUpdatedChecker) var justUpdatedChecker
@AppStorage("defaultsHasRunSetup") var hasRunSetup = false @AppStorage("defaultsHasRunSetup") var hasRunSetup = false
@State private var showingSetup = false
@State private var showingIntegrations = false
@State private var showingCreation = false
@SceneBuilder var body: some Scene { @SceneBuilder var body: some Scene {
WindowGroup { WindowGroup {
ContentView(showingCreation: $showingCreation, runningSetup: $showingSetup, hasRunSetup: $hasRunSetup) ContentView()
.environment(EnvironmentValues._secretStoreList) .environment(EnvironmentValues._secretStoreList)
.onAppear {
if !hasRunSetup {
showingSetup = true
}
}
.onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)) { _ in .onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)) { _ in
guard hasRunSetup else { return } guard hasRunSetup else { return }
agentStatusChecker.check() agentStatusChecker.check()
@ -62,25 +25,41 @@ struct Secretive: App {
forceLaunchAgent() forceLaunchAgent()
} }
} }
.sheet(isPresented: $showingIntegrations) {
IntegrationsView()
}
} }
.commands { .commands {
AppCommands()
}
WindowGroup(id: String(describing: IntegrationsView.self)) {
IntegrationsView()
}
}
}
extension Secretive {
struct AppCommands: Commands {
@Environment(\.openWindow) var openWindow
@Environment(\.openURL) var openURL
@FocusedValue(\.showCreateSecret) var showCreateSecret
var body: some Commands {
CommandGroup(before: CommandGroupPlacement.appSettings) { CommandGroup(before: CommandGroupPlacement.appSettings) {
Button(.integrationsMenuBarTitle, systemImage: "app.connected.to.app.below.fill") { Button(.integrationsMenuBarTitle, systemImage: "app.connected.to.app.below.fill") {
showingIntegrations = true openWindow(id: String(describing: IntegrationsView.self))
} }
} }
CommandGroup(after: CommandGroupPlacement.newItem) { CommandGroup(after: CommandGroupPlacement.newItem) {
Button(.appMenuNewSecretButton) { Button(.appMenuNewSecretButton, systemImage: "plus") {
showingCreation = true showCreateSecret?()
} }
.keyboardShortcut(KeyboardShortcut(KeyEquivalent("N"), modifiers: [.command, .shift])) .keyboardShortcut(KeyboardShortcut(KeyEquivalent("N"), modifiers: [.command, .shift]))
.disabled(showCreateSecret?.isEnabled == false)
} }
CommandGroup(replacing: .help) { CommandGroup(replacing: .help) {
Button(.appMenuHelpButton) { Button(.appMenuHelpButton) {
NSWorkspace.shared.open(Constants.helpURL) openURL(Constants.helpURL)
} }
} }
SidebarCommands() SidebarCommands()
@ -113,8 +92,56 @@ extension Secretive {
} }
private enum Constants { private enum Constants {
static let helpURL = URL(string: "https://github.com/maxgoedjen/secretive/blob/main/FAQ.md")! static let helpURL = URL(string: "https://github.com/maxgoedjen/secretive/blob/main/FAQ.md")!
} }
extension EnvironmentValues {
// This is injected through .environment modifier below instead of @Entry for performance reasons (basially, restrictions around init/mainactor causing delay in loading secrets/"empty screen" blip).
@MainActor fileprivate static let _secretStoreList: SecretStoreList = {
let list = SecretStoreList()
let cryptoKit = SecureEnclave.Store()
let migrator = SecureEnclave.CryptoKitMigrator()
try? migrator.migrate(to: cryptoKit)
list.add(store: cryptoKit)
list.add(store: SmartCard.Store())
return list
}()
private static let _agentStatusChecker = AgentStatusChecker()
@Entry var agentStatusChecker: any AgentStatusCheckerProtocol = _agentStatusChecker
private static let _updater: any UpdaterProtocol = {
@AppStorage("defaultsHasRunSetup") var hasRunSetup = false
return Updater(checkOnLaunch: hasRunSetup)
}()
@Entry var updater: any UpdaterProtocol = _updater
private static let _justUpdatedChecker = JustUpdatedChecker()
@Entry var justUpdatedChecker: any JustUpdatedCheckerProtocol = _justUpdatedChecker
@MainActor var secretStoreList: SecretStoreList {
EnvironmentValues._secretStoreList
}
}
extension FocusedValues {
@Entry var showCreateSecret: OpenSheet?
}
final class OpenSheet {
let closure: () -> Void
let isEnabled: Bool
init(isEnabled: Bool = true, closure: @escaping () -> Void) {
self.isEnabled = isEnabled
self.closure = closure
}
func callAsFunction() {
closure()
}
}

View File

@ -6,9 +6,9 @@ import Brief
struct ContentView: View { struct ContentView: View {
@Binding var showingCreation: Bool @AppStorage("defaultsHasRunSetup") var hasRunSetup = false
@Binding var runningSetup: Bool @State var showingCreation = false
@Binding var hasRunSetup: Bool @State var runningSetup = true
@State var showingAgentInfo = false @State var showingAgentInfo = false
@State var activeSecret: AnySecret? @State var activeSecret: AnySecret?
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
@ -35,6 +35,23 @@ struct ContentView: View {
toolbarItem(appPathNoticeView, id: "appPath") toolbarItem(appPathNoticeView, id: "appPath")
toolbarItem(newItemView, id: "new") toolbarItem(newItemView, id: "new")
} }
.onAppear {
if !hasRunSetup {
runningSetup = true
}
}
.focusedSceneValue(\.showCreateSecret, .init(isEnabled: !runningSetup) {
showingCreation = true
})
.sheet(isPresented: $showingCreation) {
if let modifiable = storeList.modifiableStore {
CreateSecretView(store: modifiable) { created in
if let created {
activeSecret = created
}
}
}
}
.sheet(isPresented: $runningSetup) { .sheet(isPresented: $runningSetup) {
SetupView(setupComplete: $hasRunSetup) SetupView(setupComplete: $hasRunSetup)
} }
@ -114,15 +131,6 @@ extension ContentView {
showingCreation = true showingCreation = true
} }
.menuButton() .menuButton()
.sheet(isPresented: $showingCreation) {
if let modifiable = storeList.modifiableStore {
CreateSecretView(store: modifiable) { created in
if let created {
activeSecret = created
}
}
}
}
} }
} }