Prompts for empty stores (#31)

* Preview content

* Empty views.

* Cleanup

* Better sizing
This commit is contained in:
Max Goedjen
2020-03-11 00:02:17 -07:00
committed by GitHub
parent 8a6e72e73c
commit e4178d35d8
4 changed files with 118 additions and 21 deletions

View File

@@ -4,10 +4,10 @@ import SecretKit
struct ContentView: View {
@ObservedObject var storeList: SecretStoreList
@State var active: AnySecret.ID?
@State var showingDeletion = false
@State var deletingSecret: AnySecret?
@State fileprivate var active: AnySecret.ID?
@State fileprivate var showingDeletion = false
@State fileprivate var deletingSecret: AnySecret?
var body: some View {
NavigationView {
@@ -15,13 +15,25 @@ struct ContentView: View {
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 store.secrets.isEmpty {
if store is AnySecretStoreModifiable {
NavigationLink(destination: EmptyStoreModifiableView()) {
Text("No Secrets")
}
} else {
NavigationLink(destination: EmptyStoreView()) {
Text("No Secrets")
}
}
} else {
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")
}
}
}
}
@@ -53,9 +65,14 @@ struct ContentView: View {
}
}
//
//struct ContentView_Previews: PreviewProvider {
// static var previews: some View {
// ContentView(store: Preview.Store(numberOfRandomSecrets: 10))
// }
//}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView(storeList: Preview.storeList(stores: [Preview.Store(numberOfRandomSecrets: 0)], modifiableStores: [Preview.StoreModifiable(numberOfRandomSecrets: 0)]))
ContentView(storeList: Preview.storeList(stores: [Preview.Store()], modifiableStores: [Preview.StoreModifiable()]))
ContentView(storeList: Preview.storeList(stores: [Preview.Store()]))
ContentView(storeList: Preview.storeList(modifiableStores: [Preview.StoreModifiable()]))
}
}
}

View File

@@ -0,0 +1,53 @@
import SwiftUI
struct EmptyStoreView: View {
var body: some View {
VStack {
Text("No Secrets").bold()
Text("Use your Smart Card's management tool to create a secret.")
Text("Secretive only supports Elliptic Curve keys.")
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
struct EmptyStoreModifiableView: View {
var body: some View {
GeometryReader { windowGeometry in
VStack {
GeometryReader { g in
Path { path in
path.move(to: CGPoint(x: g.size.width / 2, y: g.size.height))
path.addCurve(to:
CGPoint(x: g.size.width * (3/4), y: g.size.height * (1/2)), control1:
CGPoint(x: g.size.width / 2, y: g.size.height * (1/2)), control2:
CGPoint(x: g.size.width * (3/4), y: g.size.height * (1/2)))
path.addCurve(to:
CGPoint(x: g.size.width, y: 0), control1:
CGPoint(x: g.size.width, y: g.size.height * (1/2)), control2:
CGPoint(x: g.size.width, y: 0))
}.stroke(style: StrokeStyle(lineWidth: 5, lineCap: .round))
Path { path in
path.move(to: CGPoint(x: g.size.width - 10, y: 0))
path.addLine(to: CGPoint(x: g.size.width, y: -10))
path.addLine(to: CGPoint(x: g.size.width + 10, y: 0))
}.fill()
}.frame(height: (windowGeometry.size.height/2) - 20).padding()
Text("No Secrets").bold()
Text("Create a new one by clicking here.")
Spacer()
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
struct EmptyStoreModifiableView_Previews: PreviewProvider {
static var previews: some View {
Group {
EmptyStoreView()
EmptyStoreModifiableView()
}
}
}

View File

@@ -23,15 +23,15 @@ extension Preview {
let isAvailable = true
let id = UUID()
let name = "Preview Store"
var name: String { "Preview Store" }
@Published var secrets: [Secret] = []
init(secrets: [Secret]) {
self.secrets.append(contentsOf: secrets)
}
init(numberOfRandomSecrets: Int) {
let new = (0...numberOfRandomSecrets).map { Secret(name: String(describing: $0)) }
init(numberOfRandomSecrets: Int = 5) {
let new = (0..<numberOfRandomSecrets).map { Secret(name: String(describing: $0)) }
self.secrets.append(contentsOf: new)
}
@@ -39,9 +39,32 @@ extension Preview {
return data
}
func delete(secret: Preview.Secret) throws {
}
class StoreModifiable: Store, SecretStoreModifiable {
override var name: String { "Modifiable Preview Store" }
func create(name: String, requiresAuthentication: Bool) throws {
}
func delete(secret: Preview.Secret) throws {
}
}
}
extension Preview {
static func storeList(stores: [Store] = [], modifiableStores: [StoreModifiable] = []) -> SecretStoreList {
let list = SecretStoreList()
for store in stores {
list.add(store: store)
}
for storeModifiable in modifiableStores {
list.add(store: storeModifiable)
}
return list
}
}