mirror of
https://github.com/maxgoedjen/secretive.git
synced 2026-03-05 09:24:49 +01:00
More progress.
This commit is contained in:
@@ -7,15 +7,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
var window: NSWindow!
|
||||
@IBOutlet var toolbar: NSToolbar!
|
||||
let secureEnclave = SecureEnclave.Store()
|
||||
let smartCard = SmartCard.Store()
|
||||
lazy var allStores: [AnySecretStore] = {
|
||||
[AnySecretStore(secureEnclave), AnySecretStore(smartCard)]
|
||||
let storeList: SecretStoreList = {
|
||||
let list = SecretStoreList()
|
||||
list.add(store: SecureEnclave.Store())
|
||||
list.add(store: SmartCard.Store())
|
||||
return list
|
||||
}()
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
|
||||
let contentView = ContentView(secureEnclave: secureEnclave, smartCard: smartCard)
|
||||
let contentView = ContentView(storeList: storeList)
|
||||
// Create the window and set the content view.
|
||||
window = NSWindow(
|
||||
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
|
||||
@@ -27,7 +28,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
window.titleVisibility = .hidden
|
||||
window.toolbar = toolbar
|
||||
if secureEnclave.isAvailable {
|
||||
if storeList.modifiableStore?.isAvailable ?? false {
|
||||
let plus = NSTitlebarAccessoryViewController()
|
||||
plus.view = NSButton(image: NSImage(named: NSImage.addTemplateName)!, target: self, action: #selector(add(sender:)))
|
||||
plus.layoutAttribute = .right
|
||||
@@ -38,7 +39,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
@IBAction func add(sender: AnyObject?) {
|
||||
var addWindow: NSWindow!
|
||||
let addView = CreateSecretView(store: secureEnclave) {
|
||||
let addView = CreateSecretView(store: storeList.modifiableStore!) {
|
||||
self.window.endSheet(addWindow)
|
||||
}
|
||||
addWindow = NSWindow(
|
||||
|
||||
@@ -3,57 +3,53 @@ import SecretKit
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
@ObservedObject var secureEnclave: SecureEnclave.Store
|
||||
@ObservedObject var smartCard: SmartCard.Store
|
||||
@State var active: Data?
|
||||
@ObservedObject var storeList: SecretStoreList
|
||||
@State var active: AnySecret.ID?
|
||||
|
||||
@State var showingDeletion = false
|
||||
@State var deletingSecret: SecureEnclave.Secret?
|
||||
@State var deletingSecret: AnySecret?
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List(selection: $active) {
|
||||
if secureEnclave.isAvailable {
|
||||
Section(header: Text(secureEnclave.name)) {
|
||||
ForEach(secureEnclave.secrets) { secret in
|
||||
NavigationLink(destination: SecretDetailView(secret: secret), tag: secret.id, selection: self.$active) {
|
||||
Text(secret.name)
|
||||
}.contextMenu {
|
||||
Button(action: { self.delete(secret: secret) }) {
|
||||
Text("Delete")
|
||||
ForEach(storeList.stores) { store in
|
||||
if store.isAvailable {
|
||||
Section(header: Text(store.name)) {
|
||||
ForEach(store.secrets) { secret in
|
||||
NavigationLink(destination: SecretDetailView(secret: secret), tag: secret.id, selection: self.$active) {
|
||||
Text(secret.name)
|
||||
}.contextMenu {
|
||||
if store is AnySecretStoreModifiable {
|
||||
Button(action: { self.delete(secret: secret) }) {
|
||||
Text("Delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if smartCard.isAvailable {
|
||||
Section(header: Text(smartCard.name)) {
|
||||
ForEach(smartCard.secrets) { secret in
|
||||
NavigationLink(destination: SecretDetailView(secret: secret), tag: secret.id, selection: self.$active) {
|
||||
Text(secret.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.onAppear {
|
||||
self.active = self.secureEnclave.secrets.first?.id ?? self.smartCard.secrets.first?.id
|
||||
self.active = self.storeList.stores.compactMap { $0.secrets.first }.first?.id
|
||||
}
|
||||
.listStyle(SidebarListStyle())
|
||||
.frame(minWidth: 100, idealWidth: 240)
|
||||
}
|
||||
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
.sheet(isPresented: $showingDeletion) {
|
||||
DeleteSecretView(secret: self.deletingSecret!, store: self.secureEnclave) {
|
||||
self.showingDeletion = false
|
||||
if self.storeList.modifiableStore != nil {
|
||||
DeleteSecretView(secret: self.deletingSecret!, store: self.storeList.modifiableStore!) {
|
||||
self.showingDeletion = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
func delete(secret: SecureEnclave.Secret) {
|
||||
deletingSecret = secret
|
||||
showingDeletion = true
|
||||
func delete<SecretType: Secret>(secret: SecretType) {
|
||||
deletingSecret = AnySecret(secret)
|
||||
self.showingDeletion = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import SecretKit
|
||||
|
||||
struct CreateSecretView: View {
|
||||
|
||||
@ObservedObject var store: SecureEnclave.Store
|
||||
@ObservedObject var store: AnySecretStoreModifiable
|
||||
|
||||
@State var name = ""
|
||||
@State var requiresAuthentication = true
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import SwiftUI
|
||||
import SecretKit
|
||||
|
||||
struct DeleteSecretView: View {
|
||||
struct DeleteSecretView<StoreType: SecretStoreModifiable>: View {
|
||||
|
||||
let secret: SecureEnclave.Secret
|
||||
@ObservedObject var store: SecureEnclave.Store
|
||||
let secret: StoreType.SecretType
|
||||
@ObservedObject var store: StoreType
|
||||
|
||||
@State var confirm = ""
|
||||
|
||||
fileprivate var dismissalBlock: () -> ()
|
||||
|
||||
init(secret: SecureEnclave.Secret, store: SecureEnclave.Store, dismissalBlock: @escaping () -> ()) {
|
||||
init(secret: StoreType.SecretType, store: StoreType, dismissalBlock: @escaping () -> ()) {
|
||||
self.secret = secret
|
||||
self.store = store
|
||||
self.dismissalBlock = dismissalBlock
|
||||
|
||||
@@ -20,6 +20,7 @@ extension Preview {
|
||||
class Store: SecretStore, ObservableObject {
|
||||
|
||||
let isAvailable = true
|
||||
let id = UUID()
|
||||
let name = "Preview Store"
|
||||
@Published var secrets: [Secret] = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user