This commit is contained in:
Max Goedjen
2025-08-10 14:23:57 -07:00
parent bab76da2ab
commit 998f4b9bf4
14 changed files with 99 additions and 81 deletions

View File

@@ -10,7 +10,7 @@ struct ContentView: View {
@Binding var runningSetup: Bool
@Binding var hasRunSetup: Bool
@State var showingAgentInfo = false
@State var activeSecret: AnySecret.ID?
@State var activeSecret: AnySecret?
@Environment(\.colorScheme) var colorScheme
@Environment(\.secretStoreList) private var storeList: SecretStoreList
@@ -106,7 +106,7 @@ extension ContentView {
if let modifiable = storeList.modifiableStore {
CreateSecretView(store: modifiable, showing: $showingCreation)
.onDisappear {
guard let newest = modifiable.secrets.last?.id else { return }
guard let newest = modifiable.secrets.last else { return }
activeSecret = newest
}
}

View File

@@ -3,31 +3,17 @@ import SecretKit
struct EmptyStoreView: View {
@State var store: AnySecretStore
@Binding var activeSecret: AnySecret.ID?
@State var store: AnySecretStore?
var body: some View {
if store is AnySecretStoreModifiable {
NavigationLink(destination: EmptyStoreModifiableView(), tag: Constants.emptyStoreModifiableTag, selection: $activeSecret) {
Text("empty_store_modifiable_title")
}
EmptyStoreModifiableView()
} else {
NavigationLink(destination: EmptyStoreImmutableView(), tag: Constants.emptyStoreTag, selection: $activeSecret) {
Text("empty_store_nonmodifiable_title")
}
EmptyStoreImmutableView()
}
}
}
extension EmptyStoreView {
enum Constants {
static let emptyStoreModifiableTag = "emptyStoreModifiableTag"
static let emptyStoreTag = "emptyStoreTag"
}
}
struct EmptyStoreImmutableView: View {
var body: some View {

View File

@@ -3,7 +3,7 @@ import SecretKit
struct SecretDetailView<SecretType: Secret>: View {
@State var secret: SecretType
let secret: SecretType
private let keyWriter = OpenSSHKeyWriter()
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: NSHomeDirectory().replacingOccurrences(of: Bundle.main.hostBundleID, with: Bundle.main.agentBundleID))
@@ -47,12 +47,12 @@ struct SecretDetailView<SecretType: Secret>: View {
}
//#if DEBUG
//
//struct SecretDetailView_Previews: PreviewProvider {
// static var previews: some View {
// SecretDetailView(secret: Preview.Store(numberOfRandomSecrets: 1).secrets[0])
// }
//}
//
//#endif
#if DEBUG
struct SecretDetailView_Previews: PreviewProvider {
static var previews: some View {
SecretDetailView(secret: Preview.Store(numberOfRandomSecrets: 1).secrets[0])
}
}
#endif

View File

@@ -2,24 +2,30 @@ import SwiftUI
import SecretKit
struct SecretListItemView: View {
@State var store: AnySecretStore
var secret: AnySecret
@Binding var activeSecret: AnySecret.ID?
@State var isDeleting: Bool = false
@State var isRenaming: Bool = false
var deletedSecret: (AnySecret) -> Void
var renamedSecret: (AnySecret) -> Void
var body: some View {
let showingPopupWrapped = Binding(
private var showingPopup: Binding<Bool> {
Binding(
get: { isDeleting || isRenaming },
set: { if $0 == false { isDeleting = false; isRenaming = false } }
set: {
if $0 == false {
isDeleting = false
isRenaming = false
}
}
)
return NavigationLink(destination: SecretDetailView(secret: secret), tag: secret.id, selection: $activeSecret) {
}
var body: some View {
NavigationLink(value: secret) {
if secret.requiresAuthentication {
HStack {
Text(secret.name)
@@ -40,7 +46,7 @@ struct SecretListItemView: View {
}
}
}
.popover(isPresented: showingPopupWrapped) {
.popover(isPresented: showingPopup) {
if let modifiable = store as? AnySecretStoreModifiable {
if isDeleting {
DeleteSecretView(store: modifiable, secret: secret) { deleted in

View File

@@ -55,7 +55,7 @@ struct StepView: View {
.foregroundColor(.green)
.frame(width: max(0, ((width - (Constants.padding * 2)) / Double(numberOfSteps - 1)) * Double(currentStep) - (Constants.circleWidth / 2)), height: 5)
HStack {
ForEach(0..<numberOfSteps) { index in
ForEach(Array(0..<numberOfSteps), id: \.self) { index in
ZStack {
if currentStep > index {
Circle()

View File

@@ -4,8 +4,8 @@ import SecretKit
struct StoreListView: View {
@Binding var activeSecret: AnySecret.ID?
@Binding var activeSecret: AnySecret?
@Environment(SecretStoreList.self) private var storeList: SecretStoreList
private func secretDeleted(secret: AnySecret) {
@@ -13,25 +13,24 @@ struct StoreListView: View {
}
private func secretRenamed(secret: AnySecret) {
activeSecret = secret.id
activeSecret = secret
}
var body: some View {
NavigationView {
NavigationSplitView {
List(selection: $activeSecret) {
ForEach(storeList.stores) { store in
if store.isAvailable {
Section(header: Text(store.name)) {
if store.secrets.isEmpty {
EmptyStoreView(store: store, activeSecret: $activeSecret)
EmptyStoreView(store: store)
} else {
ForEach(store.secrets) { secret in
SecretListItemView(
store: store,
secret: secret,
activeSecret: $activeSecret,
deletedSecret: self.secretDeleted,
renamedSecret: self.secretRenamed
deletedSecret: secretDeleted,
renamedSecret: secretRenamed
)
}
}
@@ -39,25 +38,26 @@ struct StoreListView: View {
}
}
}
.listStyle(SidebarListStyle())
.onAppear {
activeSecret = nextDefaultSecret
} detail: {
if let activeSecret {
SecretDetailView(secret: activeSecret)
} else {
EmptyStoreView(store: storeList.stores.first)
}
.frame(minWidth: 100, idealWidth: 240)
}
.navigationSplitViewStyle(.balanced)
.onAppear {
activeSecret = nextDefaultSecret
}
.frame(minWidth: 100, idealWidth: 240)
}
}
extension StoreListView {
var nextDefaultSecret: AnyHashable? {
let fallback: AnyHashable
if storeList.modifiableStore?.isAvailable ?? false {
fallback = EmptyStoreView.Constants.emptyStoreModifiableTag
} else {
fallback = EmptyStoreView.Constants.emptyStoreTag
}
return storeList.stores.compactMap(\.secrets.first).first?.id ?? fallback
private var nextDefaultSecret: AnySecret? {
return storeList.stores.compactMap(\.secrets.first).first
}
}