mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-07-01 09:43:37 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
12b920b0af | |||
bfb4f80b8c | |||
d661b9002b | |||
9daae8957a | |||
bde9085d31 | |||
84521cf8d6 | |||
4a6e8c0b11 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
tag_name: ${{ github.ref }}
|
tag_name: ${{ github.ref }}
|
||||||
release_name: ${{ github.ref }}
|
release_name: ${{ github.ref }}
|
||||||
body: ''
|
body: "Build: https://github.com/maxgoedjen/secretive/actions/runs/${{ github.run_id }}"
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: false
|
prerelease: false
|
||||||
- name: Setup Signing
|
- name: Setup Signing
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
50731666241DF8660023809E /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731665241DF8660023809E /* Updater.swift */; };
|
50731666241DF8660023809E /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731665241DF8660023809E /* Updater.swift */; };
|
||||||
50731669241E00C20023809E /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731668241E00C20023809E /* NoticeView.swift */; };
|
50731669241E00C20023809E /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731668241E00C20023809E /* NoticeView.swift */; };
|
||||||
508A58AA241E06B40069DC07 /* PreviewUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58A9241E06B40069DC07 /* PreviewUpdater.swift */; };
|
508A58AA241E06B40069DC07 /* PreviewUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58A9241E06B40069DC07 /* PreviewUpdater.swift */; };
|
||||||
|
508A58B3241ED2180069DC07 /* AgentStatusChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */; };
|
||||||
|
508A58B5241ED48F0069DC07 /* PreviewAgentStatusChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58B4241ED48F0069DC07 /* PreviewAgentStatusChecker.swift */; };
|
||||||
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */; };
|
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */; };
|
||||||
5099A02723FE34FA0062B6F2 /* SmartCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02623FE34FA0062B6F2 /* SmartCard.swift */; };
|
5099A02723FE34FA0062B6F2 /* SmartCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02623FE34FA0062B6F2 /* SmartCard.swift */; };
|
||||||
5099A02923FE35240062B6F2 /* SmartCardStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02823FE35240062B6F2 /* SmartCardStore.swift */; };
|
5099A02923FE35240062B6F2 /* SmartCardStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02823FE35240062B6F2 /* SmartCardStore.swift */; };
|
||||||
@ -186,6 +188,8 @@
|
|||||||
50731668241E00C20023809E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = "<group>"; };
|
50731668241E00C20023809E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = "<group>"; };
|
||||||
508A58A9241E06B40069DC07 /* PreviewUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewUpdater.swift; sourceTree = "<group>"; };
|
508A58A9241E06B40069DC07 /* PreviewUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewUpdater.swift; sourceTree = "<group>"; };
|
||||||
508A58AB241E121B0069DC07 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
|
508A58AB241E121B0069DC07 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
|
||||||
|
508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgentStatusChecker.swift; sourceTree = "<group>"; };
|
||||||
|
508A58B4241ED48F0069DC07 /* PreviewAgentStatusChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewAgentStatusChecker.swift; sourceTree = "<group>"; };
|
||||||
5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateSecretView.swift; sourceTree = "<group>"; };
|
5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateSecretView.swift; sourceTree = "<group>"; };
|
||||||
5099A02623FE34FA0062B6F2 /* SmartCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartCard.swift; sourceTree = "<group>"; };
|
5099A02623FE34FA0062B6F2 /* SmartCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartCard.swift; sourceTree = "<group>"; };
|
||||||
5099A02823FE35240062B6F2 /* SmartCardStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartCardStore.swift; sourceTree = "<group>"; };
|
5099A02823FE35240062B6F2 /* SmartCardStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartCardStore.swift; sourceTree = "<group>"; };
|
||||||
@ -305,14 +309,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
50617D8223FCE48E0099B055 /* AppDelegate.swift */,
|
50617D8223FCE48E0099B055 /* AppDelegate.swift */,
|
||||||
50617D8423FCE48E0099B055 /* ContentView.swift */,
|
508A58B0241ED1C40069DC07 /* Views */,
|
||||||
50731668241E00C20023809E /* NoticeView.swift */,
|
508A58B1241ED1EA0069DC07 /* Controllers */,
|
||||||
50C385A42407A76D00AF2719 /* SecretDetailView.swift */,
|
|
||||||
5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */,
|
|
||||||
50B8550C24138C4F009958AC /* DeleteSecretView.swift */,
|
|
||||||
50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */,
|
|
||||||
50C385A8240B636500AF2719 /* SetupView.swift */,
|
|
||||||
50731665241DF8660023809E /* Updater.swift */,
|
|
||||||
50617D8623FCE48E0099B055 /* Assets.xcassets */,
|
50617D8623FCE48E0099B055 /* Assets.xcassets */,
|
||||||
50617D8B23FCE48E0099B055 /* Main.storyboard */,
|
50617D8B23FCE48E0099B055 /* Main.storyboard */,
|
||||||
50617D8E23FCE48E0099B055 /* Info.plist */,
|
50617D8E23FCE48E0099B055 /* Info.plist */,
|
||||||
@ -328,6 +326,7 @@
|
|||||||
50617D8923FCE48E0099B055 /* Preview Assets.xcassets */,
|
50617D8923FCE48E0099B055 /* Preview Assets.xcassets */,
|
||||||
50617DD123FCEFA90099B055 /* PreviewStore.swift */,
|
50617DD123FCEFA90099B055 /* PreviewStore.swift */,
|
||||||
508A58A9241E06B40069DC07 /* PreviewUpdater.swift */,
|
508A58A9241E06B40069DC07 /* PreviewUpdater.swift */,
|
||||||
|
508A58B4241ED48F0069DC07 /* PreviewAgentStatusChecker.swift */,
|
||||||
);
|
);
|
||||||
path = "Preview Content";
|
path = "Preview Content";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -400,6 +399,29 @@
|
|||||||
path = Config;
|
path = Config;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
508A58B0241ED1C40069DC07 /* Views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
50617D8423FCE48E0099B055 /* ContentView.swift */,
|
||||||
|
50731668241E00C20023809E /* NoticeView.swift */,
|
||||||
|
50C385A42407A76D00AF2719 /* SecretDetailView.swift */,
|
||||||
|
5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */,
|
||||||
|
50B8550C24138C4F009958AC /* DeleteSecretView.swift */,
|
||||||
|
50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */,
|
||||||
|
50C385A8240B636500AF2719 /* SetupView.swift */,
|
||||||
|
);
|
||||||
|
path = Views;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
508A58B1241ED1EA0069DC07 /* Controllers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
50731665241DF8660023809E /* Updater.swift */,
|
||||||
|
508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */,
|
||||||
|
);
|
||||||
|
path = Controllers;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
5099A02523FE34DE0062B6F2 /* SmartCard */ = {
|
5099A02523FE34DE0062B6F2 /* SmartCard */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -752,6 +774,7 @@
|
|||||||
50C385A9240B636500AF2719 /* SetupView.swift in Sources */,
|
50C385A9240B636500AF2719 /* SetupView.swift in Sources */,
|
||||||
50617D8523FCE48E0099B055 /* ContentView.swift in Sources */,
|
50617D8523FCE48E0099B055 /* ContentView.swift in Sources */,
|
||||||
50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */,
|
50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */,
|
||||||
|
508A58B3241ED2180069DC07 /* AgentStatusChecker.swift in Sources */,
|
||||||
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */,
|
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */,
|
||||||
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */,
|
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */,
|
||||||
50731666241DF8660023809E /* Updater.swift in Sources */,
|
50731666241DF8660023809E /* Updater.swift in Sources */,
|
||||||
@ -759,6 +782,7 @@
|
|||||||
50BB046B2418AAAE00D6E079 /* EmptyStoreView.swift in Sources */,
|
50BB046B2418AAAE00D6E079 /* EmptyStoreView.swift in Sources */,
|
||||||
50731669241E00C20023809E /* NoticeView.swift in Sources */,
|
50731669241E00C20023809E /* NoticeView.swift in Sources */,
|
||||||
50617D8323FCE48E0099B055 /* AppDelegate.swift in Sources */,
|
50617D8323FCE48E0099B055 /* AppDelegate.swift in Sources */,
|
||||||
|
508A58B5241ED48F0069DC07 /* PreviewAgentStatusChecker.swift in Sources */,
|
||||||
508A58AA241E06B40069DC07 /* PreviewUpdater.swift in Sources */,
|
508A58AA241E06B40069DC07 /* PreviewUpdater.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -14,10 +14,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
return list
|
return list
|
||||||
}()
|
}()
|
||||||
let updater = Updater()
|
let updater = Updater()
|
||||||
|
let agentStatusChecker = AgentStatusChecker()
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||||
|
let contentView = ContentView(storeList: storeList, updater: updater, agentStatusChecker: agentStatusChecker, runSetupBlock: { self.runSetup(sender: nil) })
|
||||||
let contentView = ContentView(storeList: storeList, updater: updater)
|
|
||||||
// Create the window and set the content view.
|
// Create the window and set the content view.
|
||||||
window = NSWindow(
|
window = NSWindow(
|
||||||
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
|
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
|
||||||
@ -29,6 +29,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
window.makeKeyAndOrderFront(nil)
|
window.makeKeyAndOrderFront(nil)
|
||||||
window.titleVisibility = .hidden
|
window.titleVisibility = .hidden
|
||||||
window.toolbar = toolbar
|
window.toolbar = toolbar
|
||||||
|
window.isReleasedWhenClosed = false
|
||||||
if storeList.modifiableStore?.isAvailable ?? false {
|
if storeList.modifiableStore?.isAvailable ?? false {
|
||||||
let plus = NSTitlebarAccessoryViewController()
|
let plus = NSTitlebarAccessoryViewController()
|
||||||
plus.view = NSButton(image: NSImage(named: NSImage.addTemplateName)!, target: self, action: #selector(add(sender:)))
|
plus.view = NSButton(image: NSImage(named: NSImage.addTemplateName)!, target: self, action: #selector(add(sender:)))
|
||||||
@ -38,6 +39,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
runSetupIfNeeded()
|
runSetupIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applicationDidBecomeActive(_ notification: Notification) {
|
||||||
|
agentStatusChecker.check()
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
|
||||||
|
guard !flag else { return false }
|
||||||
|
window.makeKeyAndOrderFront(self)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
@IBAction func add(sender: AnyObject?) {
|
@IBAction func add(sender: AnyObject?) {
|
||||||
var addWindow: NSWindow!
|
var addWindow: NSWindow!
|
||||||
let addView = CreateSecretView(store: storeList.modifiableStore!) {
|
let addView = CreateSecretView(store: storeList.modifiableStore!) {
|
||||||
@ -58,6 +69,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
backing: .buffered, defer: false)
|
backing: .buffered, defer: false)
|
||||||
let setupView = SetupView() { success in
|
let setupView = SetupView() { success in
|
||||||
self.window.endSheet(setupWindow)
|
self.window.endSheet(setupWindow)
|
||||||
|
self.agentStatusChecker.check()
|
||||||
}
|
}
|
||||||
setupWindow.contentView = NSHostingView(rootView: setupView)
|
setupWindow.contentView = NSHostingView(rootView: setupView)
|
||||||
window.beginSheet(setupWindow, completionHandler: nil)
|
window.beginSheet(setupWindow, completionHandler: nil)
|
||||||
|
33
Secretive/Controllers/AgentStatusChecker.swift
Normal file
33
Secretive/Controllers/AgentStatusChecker.swift
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
import AppKit
|
||||||
|
|
||||||
|
protocol AgentStatusCheckerProtocol: ObservableObject {
|
||||||
|
var running: Bool { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
class AgentStatusChecker: ObservableObject, AgentStatusCheckerProtocol {
|
||||||
|
|
||||||
|
@Published var running: Bool = false
|
||||||
|
|
||||||
|
init() {
|
||||||
|
check()
|
||||||
|
}
|
||||||
|
|
||||||
|
func check() {
|
||||||
|
running = secretAgentProcess != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var secretAgentProcess: NSRunningApplication? {
|
||||||
|
NSRunningApplication.runningApplications(withBundleIdentifier: Constants.secretAgentAppID).first
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AgentStatusChecker {
|
||||||
|
|
||||||
|
enum Constants {
|
||||||
|
static let secretAgentAppID = "com.maxgoedjen.Secretive.SecretAgent"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
Secretive/Preview Content/PreviewAgentStatusChecker.swift
Normal file
12
Secretive/Preview Content/PreviewAgentStatusChecker.swift
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
class PreviewAgentStatusChecker: AgentStatusCheckerProtocol {
|
||||||
|
|
||||||
|
let running: Bool
|
||||||
|
|
||||||
|
init(running: Bool = true) {
|
||||||
|
self.running = running
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SecretKit
|
import SecretKit
|
||||||
|
|
||||||
struct ContentView<UpdaterType: UpdaterProtocol>: View {
|
struct ContentView<UpdaterType: UpdaterProtocol, AgentStatusCheckerType: AgentStatusCheckerProtocol>: View {
|
||||||
|
|
||||||
@ObservedObject var storeList: SecretStoreList
|
@ObservedObject var storeList: SecretStoreList
|
||||||
@ObservedObject var updater: UpdaterType
|
@ObservedObject var updater: UpdaterType
|
||||||
|
@ObservedObject var agentStatusChecker: AgentStatusCheckerType
|
||||||
|
var runSetupBlock: (() -> Void)?
|
||||||
|
|
||||||
@State fileprivate var active: AnySecret.ID?
|
@State fileprivate var active: AnySecret.ID?
|
||||||
@State fileprivate var showingDeletion = false
|
@State fileprivate var showingDeletion = false
|
||||||
@ -15,6 +17,9 @@ struct ContentView<UpdaterType: UpdaterProtocol>: View {
|
|||||||
if updater.update != nil {
|
if updater.update != nil {
|
||||||
updateNotice()
|
updateNotice()
|
||||||
}
|
}
|
||||||
|
if !agentStatusChecker.running {
|
||||||
|
agentNotice()
|
||||||
|
}
|
||||||
NavigationView {
|
NavigationView {
|
||||||
List(selection: $active) {
|
List(selection: $active) {
|
||||||
ForEach(storeList.stores) { store in
|
ForEach(storeList.stores) { store in
|
||||||
@ -47,13 +52,7 @@ struct ContentView<UpdaterType: UpdaterProtocol>: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.onAppear {
|
}.onAppear {
|
||||||
let fallback: AnyHashable
|
self.active = self.nextDefaultSecret
|
||||||
if self.storeList.modifiableStore?.isAvailable ?? false {
|
|
||||||
fallback = Constants.emptyStoreModifiableTag
|
|
||||||
} else {
|
|
||||||
fallback = Constants.emptyStoreTag
|
|
||||||
}
|
|
||||||
self.active = self.storeList.stores.compactMap { $0.secrets.first }.first?.id ?? fallback
|
|
||||||
}
|
}
|
||||||
.listStyle(SidebarListStyle())
|
.listStyle(SidebarListStyle())
|
||||||
.frame(minWidth: 100, idealWidth: 240)
|
.frame(minWidth: 100, idealWidth: 240)
|
||||||
@ -61,8 +60,11 @@ struct ContentView<UpdaterType: UpdaterProtocol>: View {
|
|||||||
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||||
.sheet(isPresented: $showingDeletion) {
|
.sheet(isPresented: $showingDeletion) {
|
||||||
if self.storeList.modifiableStore != nil {
|
if self.storeList.modifiableStore != nil {
|
||||||
DeleteSecretView(secret: self.deletingSecret!, store: self.storeList.modifiableStore!) {
|
DeleteSecretView(secret: self.deletingSecret!, store: self.storeList.modifiableStore!) { deleted in
|
||||||
self.showingDeletion = false
|
self.showingDeletion = false
|
||||||
|
if deleted {
|
||||||
|
self.active = self.nextDefaultSecret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,10 +87,26 @@ struct ContentView<UpdaterType: UpdaterProtocol>: View {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func agentNotice() -> some View {
|
||||||
|
NoticeView(text: "Secret Agent isn't running. Run setup again to fix.", severity: .advisory, actionTitle: "Run Setup") {
|
||||||
|
self.runSetupBlock?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func delete<SecretType: Secret>(secret: SecretType) {
|
func delete<SecretType: Secret>(secret: SecretType) {
|
||||||
deletingSecret = AnySecret(secret)
|
deletingSecret = AnySecret(secret)
|
||||||
self.showingDeletion = true
|
self.showingDeletion = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nextDefaultSecret: AnyHashable? {
|
||||||
|
let fallback: AnyHashable
|
||||||
|
if self.storeList.modifiableStore?.isAvailable ?? false {
|
||||||
|
fallback = Constants.emptyStoreModifiableTag
|
||||||
|
} else {
|
||||||
|
fallback = Constants.emptyStoreTag
|
||||||
|
}
|
||||||
|
return self.storeList.stores.compactMap { $0.secrets.first }.first?.id ?? fallback
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,12 +121,22 @@ fileprivate enum Constants {
|
|||||||
struct ContentView_Previews: PreviewProvider {
|
struct ContentView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
Group {
|
Group {
|
||||||
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)], modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]), updater: PreviewUpdater())
|
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)],
|
||||||
ContentView(storeList: Preview.storeList(stores: [Preview.Store()], modifiableStores: [Preview.StoreModifiable()]), updater: PreviewUpdater())
|
modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]),
|
||||||
ContentView(storeList: Preview.storeList(stores: [Preview.Store()]), updater: PreviewUpdater())
|
updater: PreviewUpdater(),
|
||||||
ContentView(storeList: Preview.storeList(modifiableStores: [Preview.StoreModifiable()]), updater: PreviewUpdater())
|
agentStatusChecker: PreviewAgentStatusChecker())
|
||||||
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)], modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]), updater: PreviewUpdater(update: .advisory))
|
ContentView(storeList: Preview.storeList(stores: [Preview.Store()], modifiableStores: [Preview.StoreModifiable()]), updater: PreviewUpdater(),
|
||||||
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)], modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]), updater: PreviewUpdater(update: .critical))
|
agentStatusChecker: PreviewAgentStatusChecker())
|
||||||
|
ContentView(storeList: Preview.storeList(stores: [Preview.Store()]), updater: PreviewUpdater(),
|
||||||
|
agentStatusChecker: PreviewAgentStatusChecker())
|
||||||
|
ContentView(storeList: Preview.storeList(modifiableStores: [Preview.StoreModifiable()]), updater: PreviewUpdater(),
|
||||||
|
agentStatusChecker: PreviewAgentStatusChecker())
|
||||||
|
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)], modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]), updater: PreviewUpdater(update: .advisory),
|
||||||
|
agentStatusChecker: PreviewAgentStatusChecker())
|
||||||
|
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)], modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]), updater: PreviewUpdater(update: .critical),
|
||||||
|
agentStatusChecker: PreviewAgentStatusChecker())
|
||||||
|
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)], modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]), updater: PreviewUpdater(update: .critical),
|
||||||
|
agentStatusChecker: PreviewAgentStatusChecker(running: false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,9 +8,9 @@ struct DeleteSecretView<StoreType: SecretStoreModifiable>: View {
|
|||||||
|
|
||||||
@State var confirm = ""
|
@State var confirm = ""
|
||||||
|
|
||||||
fileprivate var dismissalBlock: () -> ()
|
fileprivate var dismissalBlock: (Bool) -> ()
|
||||||
|
|
||||||
init(secret: StoreType.SecretType, store: StoreType, dismissalBlock: @escaping () -> ()) {
|
init(secret: StoreType.SecretType, store: StoreType, dismissalBlock: @escaping (Bool) -> ()) {
|
||||||
self.secret = secret
|
self.secret = secret
|
||||||
self.store = store
|
self.store = store
|
||||||
self.dismissalBlock = dismissalBlock
|
self.dismissalBlock = dismissalBlock
|
||||||
@ -37,14 +37,16 @@ struct DeleteSecretView<StoreType: SecretStoreModifiable>: View {
|
|||||||
TextField(secret.name, text: $confirm)
|
TextField(secret.name, text: $confirm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onExitCommand(perform: dismissalBlock)
|
.onExitCommand {
|
||||||
|
self.dismissalBlock(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
Button(action: delete) {
|
Button(action: delete) {
|
||||||
Text("Delete")
|
Text("Delete")
|
||||||
}.disabled(confirm != secret.name)
|
}.disabled(confirm != secret.name)
|
||||||
Button(action: dismissalBlock) {
|
Button(action: { self.dismissalBlock(false) }) {
|
||||||
Text("Don't Delete")
|
Text("Don't Delete")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,6 +55,6 @@ struct DeleteSecretView<StoreType: SecretStoreModifiable>: View {
|
|||||||
|
|
||||||
func delete() {
|
func delete() {
|
||||||
try! store.delete(secret: secret)
|
try! store.delete(secret: secret)
|
||||||
dismissalBlock()
|
self.dismissalBlock(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user