Facelift for detail view.

This commit is contained in:
Max Goedjen 2020-09-19 16:10:10 -07:00
parent e92a813cae
commit 3b093379b8
No known key found for this signature in database
GPG Key ID: E58C21DD77B9B8E8
1 changed files with 117 additions and 30 deletions

View File

@ -4,40 +4,16 @@ import SecretKit
struct SecretDetailView<SecretType: Secret>: View {
@State var secret: SecretType
private let keyWriter = OpenSSHKeyWriter()
var body: some View {
Form {
Section {
GroupBox(label: Text("Fingerprint")) {
HStack {
Text(keyWriter.openSSHFingerprint(secret: secret))
Spacer()
}
.frame(minWidth: 150, maxWidth: .infinity)
.padding()
}.onDrag {
return NSItemProvider(item: NSData(data: keyWriter.openSSHFingerprint(secret: secret).data(using: .utf8)!), typeIdentifier: kUTTypeUTF8PlainText as String)
}
Spacer().frame(height: 10)
GroupBox(label: Text("Public Key")) {
VStack(alignment: .leading) {
Text(keyWriter.openSSHString(secret: secret))
.multilineTextAlignment(.leading)
HStack {
Spacer()
Button(action: copy) {
Text("Copy")
}
}
}
.frame(minWidth: 150, maxWidth: .infinity)
.padding()
}
.onDrag {
return NSItemProvider(item: NSData(data: keyString.data(using: .utf8)!), typeIdentifier: kUTTypeUTF8PlainText as String)
}
CopyableView(title: "Fingerprint", image: Image(systemName: "touchid"), text: keyWriter.openSSHFingerprint(secret: secret))
Spacer()
.frame(height: 20)
CopyableView(title: "Public Key", image: Image(systemName: "key"), text: keyWriter.openSSHString(secret: secret))
Spacer()
}
}
@ -55,7 +31,6 @@ struct SecretDetailView<SecretType: Secret>: View {
NSPasteboard.general.setString(keyString, forType: .string)
}
}
struct SecretDetailView_Previews: PreviewProvider {
@ -63,3 +38,115 @@ struct SecretDetailView_Previews: PreviewProvider {
SecretDetailView(secret: Preview.Store(numberOfRandomSecrets: 1).secrets[0])
}
}
struct CopyableView: View {
var title: String
var image: Image
var text: String
@State private var interactionState: InteractionState = .normal
var body: some View {
VStack(alignment: .leading) {
HStack {
image
.renderingMode(.template)
.foregroundColor(primaryTextColor)
Text(title)
.font(.headline)
.foregroundColor(primaryTextColor)
Spacer()
Text(hoverText)
.bold()
.textCase(.uppercase)
.foregroundColor(secondaryTextColor)
.transition(.opacity)
}
.padding(EdgeInsets(top: 20, leading: 20, bottom: 10, trailing: 20))
Divider()
Text(text)
.foregroundColor(primaryTextColor)
.padding(EdgeInsets(top: 10, leading: 20, bottom: 20, trailing: 20))
.multilineTextAlignment(.leading)
.font(.system(.body, design: .monospaced))
}
.frame(minWidth: 150, maxWidth: .infinity)
.background(backgroundColor)
.cornerRadius(10)
.onHover { hovering in
interactionState = hovering ? .hovering : .normal
}
.onDrag {
NSItemProvider(item: NSData(data: text.data(using: .utf8)!), typeIdentifier: kUTTypeUTF8PlainText as String)
}
.animation(.spring())
.onTapGesture {
copy()
interactionState = .clicking
}
.gesture(
TapGesture()
.onEnded {
interactionState = .normal
}
)
}
var hoverText: String {
switch interactionState {
case .hovering:
return "Click to Copy"
case .clicking:
return "Copied!"
case .normal:
return ""
}
}
var backgroundColor: Color {
let color: NSColor
switch interactionState {
case .normal:
color = .windowBackgroundColor
case .hovering:
color = .unemphasizedSelectedContentBackgroundColor
case .clicking:
color = .selectedContentBackgroundColor
}
return Color(color)
}
var primaryTextColor: Color {
let color: NSColor
switch interactionState {
case .normal, .hovering:
color = .textColor
case .clicking:
color = .white
}
return Color(color)
}
var secondaryTextColor: Color {
let color: NSColor
switch interactionState {
case .normal, .hovering:
color = .secondaryLabelColor
case .clicking:
color = .white
}
return Color(color)
}
func copy() {
NSPasteboard.general.declareTypes([.string], owner: nil)
NSPasteboard.general.setString(text, forType: .string)
}
private enum InteractionState {
case normal, hovering, clicking
}
}