mirror of
https://github.com/maxgoedjen/secretive.git
synced 2026-01-24 00:22:52 +01:00
Merge 762edea147 into faa622e379
This commit is contained in:
commit
acd2416e06
@ -364,6 +364,9 @@
|
||||
}
|
||||
},
|
||||
"shouldTranslate" : false
|
||||
},
|
||||
"About Secretive" : {
|
||||
|
||||
},
|
||||
"about_build_log_button" : {
|
||||
"extractionState" : "manual",
|
||||
@ -1289,6 +1292,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Agent Not Running" : {
|
||||
|
||||
},
|
||||
"Agent Running" : {
|
||||
|
||||
},
|
||||
"agent_details_could_not_start_error" : {
|
||||
"extractionState" : "manual",
|
||||
@ -18524,6 +18533,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Integrations..." : {
|
||||
|
||||
},
|
||||
"integrationsGitStepGitconfigSectionNote" : {
|
||||
"extractionState" : "manual",
|
||||
@ -19264,6 +19276,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Open Secretive" : {
|
||||
|
||||
},
|
||||
"persist_authentication_accept_button" : {
|
||||
"comment" : "When the user authorizes an action using a secret that requires unlock, they're shown a notification offering to leave the secret unlocked for a set period of time. This is the title for the notification.",
|
||||
@ -19636,6 +19651,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Quit Secretive" : {
|
||||
|
||||
},
|
||||
"reveal_in_finder_button" : {
|
||||
"extractionState" : "manual",
|
||||
|
||||
@ -74,6 +74,8 @@
|
||||
50E4C4C32E7765DF00C73783 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E4C4C22E7765DF00C73783 /* AboutView.swift */; };
|
||||
50E4C4C82E777E4200C73783 /* AppIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = 50E4C4C72E777E4200C73783 /* AppIcon.icon */; };
|
||||
50E4C4C92E777E4200C73783 /* AppIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = 50E4C4C72E777E4200C73783 /* AppIcon.icon */; };
|
||||
B3AE1BB82F201243007B797C /* DockVisibilityController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3AE1BB72F201243007B797C /* DockVisibilityController.swift */; };
|
||||
B3AE1BBA2F20125C007B797C /* MenuBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3AE1BB92F20125C007B797C /* MenuBarView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -240,6 +242,8 @@
|
||||
50E4C4522E73C78900C73783 /* WindowBackgroundStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowBackgroundStyle.swift; sourceTree = "<group>"; };
|
||||
50E4C4C22E7765DF00C73783 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
|
||||
50E4C4C72E777E4200C73783 /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = AppIcon.icon; sourceTree = "<group>"; };
|
||||
B3AE1BB72F201243007B797C /* DockVisibilityController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DockVisibilityController.swift; sourceTree = "<group>"; };
|
||||
B3AE1BB92F20125C007B797C /* MenuBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBarView.swift; sourceTree = "<group>"; };
|
||||
F418C9A82F0C57F000E9ADF8 /* OpenSource.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = OpenSource.xcconfig; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -333,6 +337,7 @@
|
||||
504788F02E681F0100B4556F /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B3AE1BB92F20125C007B797C /* MenuBarView.swift */,
|
||||
50E4C4C22E7765DF00C73783 /* AboutView.swift */,
|
||||
50BDCB712E63BAF20072D2E7 /* AgentStatusView.swift */,
|
||||
50617D8423FCE48E0099B055 /* ContentView.swift */,
|
||||
@ -441,6 +446,7 @@
|
||||
508A58B1241ED1EA0069DC07 /* Controllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B3AE1BB72F201243007B797C /* DockVisibilityController.swift */,
|
||||
508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */,
|
||||
5091D2BB25183B830049FD9B /* ApplicationDirectoryController.swift */,
|
||||
50571E0224393C2600F76F6C /* JustUpdatedChecker.swift */,
|
||||
@ -688,6 +694,7 @@
|
||||
2C4A9D2F2636FFD3008CC8E2 /* EditSecretView.swift in Sources */,
|
||||
50E4C4532E73C78C00C73783 /* WindowBackgroundStyle.swift in Sources */,
|
||||
5091D2BC25183B830049FD9B /* ApplicationDirectoryController.swift in Sources */,
|
||||
B3AE1BB82F201243007B797C /* DockVisibilityController.swift in Sources */,
|
||||
504789232E697DD300B4556F /* BoxBackgroundStyle.swift in Sources */,
|
||||
5066A6C22516F303004B5A36 /* SetupView.swift in Sources */,
|
||||
5065E313295517C500E16645 /* ToolbarButtonStyle.swift in Sources */,
|
||||
@ -702,6 +709,7 @@
|
||||
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */,
|
||||
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */,
|
||||
50AE97002E5C1A420018C710 /* IntegrationsView.swift in Sources */,
|
||||
B3AE1BBA2F20125C007B797C /* MenuBarView.swift in Sources */,
|
||||
50153E20250AFCB200525160 /* UpdateView.swift in Sources */,
|
||||
5066A6C82516FE6E004B5A36 /* CopyableView.swift in Sources */,
|
||||
50B8550D24138C4F009958AC /* DeleteSecretView.swift in Sources */,
|
||||
|
||||
@ -9,9 +9,10 @@ struct Secretive: App {
|
||||
|
||||
@Environment(\.agentLaunchController) var agentLaunchController
|
||||
@Environment(\.justUpdatedChecker) var justUpdatedChecker
|
||||
@Environment(\.dockVisibilityController) var dockVisibilityController
|
||||
|
||||
@SceneBuilder var body: some Scene {
|
||||
WindowGroup {
|
||||
WindowGroup(id: "main") {
|
||||
ContentView()
|
||||
.environment(EnvironmentValues._secretStoreList)
|
||||
.onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)) { _ in
|
||||
@ -31,6 +32,11 @@ struct Secretive: App {
|
||||
.commands {
|
||||
AppCommands()
|
||||
}
|
||||
MenuBarExtra {
|
||||
MenuBarView()
|
||||
} label: {
|
||||
Image(systemName: "key.fill")
|
||||
}
|
||||
WindowGroup(id: String(describing: IntegrationsView.self)) {
|
||||
IntegrationsView()
|
||||
}
|
||||
@ -110,6 +116,9 @@ extension EnvironmentValues {
|
||||
private static let _justUpdatedChecker = JustUpdatedChecker()
|
||||
@Entry var justUpdatedChecker: any JustUpdatedCheckerProtocol = _justUpdatedChecker
|
||||
|
||||
private static let _dockVisibilityController = DockVisibilityController()
|
||||
@Entry var dockVisibilityController: DockVisibilityController = _dockVisibilityController
|
||||
|
||||
@MainActor var secretStoreList: SecretStoreList {
|
||||
EnvironmentValues._secretStoreList
|
||||
}
|
||||
|
||||
37
Sources/Secretive/Controllers/DockVisibilityController.swift
Normal file
37
Sources/Secretive/Controllers/DockVisibilityController.swift
Normal file
@ -0,0 +1,37 @@
|
||||
import AppKit
|
||||
import Observation
|
||||
|
||||
@MainActor protocol DockVisibilityControllerProtocol: Observable, Sendable {
|
||||
var isDockIconVisible: Bool { get }
|
||||
func showDockIcon()
|
||||
func hideDockIcon()
|
||||
func updateVisibility(hasRunSetup: Bool, hasOpenWindows: Bool)
|
||||
}
|
||||
|
||||
@Observable @MainActor final class DockVisibilityController: DockVisibilityControllerProtocol {
|
||||
|
||||
private(set) var isDockIconVisible: Bool = true
|
||||
|
||||
nonisolated init() {}
|
||||
|
||||
func showDockIcon() {
|
||||
guard !isDockIconVisible else { return }
|
||||
NSApp.setActivationPolicy(.regular)
|
||||
isDockIconVisible = true
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
|
||||
func hideDockIcon() {
|
||||
guard isDockIconVisible else { return }
|
||||
NSApp.setActivationPolicy(.accessory)
|
||||
isDockIconVisible = false
|
||||
}
|
||||
|
||||
func updateVisibility(hasRunSetup: Bool, hasOpenWindows: Bool) {
|
||||
if !hasRunSetup || hasOpenWindows {
|
||||
showDockIcon()
|
||||
} else {
|
||||
hideDockIcon()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,7 @@ struct ContentView: View {
|
||||
@Environment(\.secretStoreList) private var storeList
|
||||
@Environment(\.updater) private var updater
|
||||
@Environment(\.agentLaunchController) private var agentLaunchController
|
||||
@Environment(\.dockVisibilityController) private var dockVisibilityController
|
||||
|
||||
@AppStorage("defaultsHasRunSetup") private var hasRunSetup = false
|
||||
@State private var showingCreation = false
|
||||
@ -41,6 +42,18 @@ struct ContentView: View {
|
||||
if !hasRunSetup {
|
||||
runningSetup = true
|
||||
}
|
||||
dockVisibilityController.showDockIcon()
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: NSWindow.willCloseNotification)) { notification in
|
||||
// When a window closes, check if we should hide the dock icon
|
||||
Task { @MainActor in
|
||||
// Small delay to let the window actually close
|
||||
try? await Task.sleep(for: .milliseconds(100))
|
||||
let hasVisibleWindows = NSApp.windows.contains { window in
|
||||
window.isVisible && window.level == .normal && !window.title.isEmpty
|
||||
}
|
||||
dockVisibilityController.updateVisibility(hasRunSetup: hasRunSetup, hasOpenWindows: hasVisibleWindows)
|
||||
}
|
||||
}
|
||||
.focusedSceneValue(\.showCreateSecret, .init(isEnabled: !runningSetup) {
|
||||
showingCreation = true
|
||||
|
||||
62
Sources/Secretive/Views/Views/MenuBarView.swift
Normal file
62
Sources/Secretive/Views/Views/MenuBarView.swift
Normal file
@ -0,0 +1,62 @@
|
||||
import SwiftUI
|
||||
|
||||
struct MenuBarView: View {
|
||||
|
||||
@Environment(\.openWindow) private var openWindow
|
||||
@Environment(\.agentLaunchController) private var agentLaunchController
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
agentStatusSection
|
||||
Divider()
|
||||
actionsSection
|
||||
Divider()
|
||||
appSection
|
||||
}
|
||||
.padding(.vertical, 4)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var agentStatusSection: some View {
|
||||
HStack(spacing: 6) {
|
||||
Circle()
|
||||
.fill(agentLaunchController.running ? Color.green : Color.red)
|
||||
.frame(width: 8, height: 8)
|
||||
Text(agentLaunchController.running ? "Agent Running" : "Agent Not Running")
|
||||
.font(.caption)
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 4)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var actionsSection: some View {
|
||||
Button("Open Secretive") {
|
||||
openMainWindow()
|
||||
}
|
||||
.keyboardShortcut("O", modifiers: [.command])
|
||||
|
||||
Button("Integrations...") {
|
||||
openWindow(id: String(describing: IntegrationsView.self))
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var appSection: some View {
|
||||
Button("About Secretive") {
|
||||
openWindow(id: String(describing: AboutView.self))
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
|
||||
Button("Quit Secretive") {
|
||||
NSApplication.shared.terminate(nil)
|
||||
}
|
||||
.keyboardShortcut("Q", modifiers: [.command])
|
||||
}
|
||||
|
||||
private func openMainWindow() {
|
||||
openWindow(id: "main")
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user