mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-04-18 05:22:11 +00:00
Facelift for detail view.
This commit is contained in:
parent
e92a813cae
commit
3b093379b8
@ -4,40 +4,16 @@ import SecretKit
|
|||||||
struct SecretDetailView<SecretType: Secret>: View {
|
struct SecretDetailView<SecretType: Secret>: View {
|
||||||
|
|
||||||
@State var secret: SecretType
|
@State var secret: SecretType
|
||||||
|
|
||||||
private let keyWriter = OpenSSHKeyWriter()
|
private let keyWriter = OpenSSHKeyWriter()
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
GroupBox(label: Text("Fingerprint")) {
|
CopyableView(title: "Fingerprint", image: Image(systemName: "touchid"), text: keyWriter.openSSHFingerprint(secret: secret))
|
||||||
HStack {
|
Spacer()
|
||||||
Text(keyWriter.openSSHFingerprint(secret: secret))
|
.frame(height: 20)
|
||||||
Spacer()
|
CopyableView(title: "Public Key", image: Image(systemName: "key"), text: keyWriter.openSSHString(secret: secret))
|
||||||
}
|
|
||||||
.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)
|
|
||||||
}
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,7 +31,6 @@ struct SecretDetailView<SecretType: Secret>: View {
|
|||||||
NSPasteboard.general.setString(keyString, forType: .string)
|
NSPasteboard.general.setString(keyString, forType: .string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SecretDetailView_Previews: PreviewProvider {
|
struct SecretDetailView_Previews: PreviewProvider {
|
||||||
@ -63,3 +38,115 @@ struct SecretDetailView_Previews: PreviewProvider {
|
|||||||
SecretDetailView(secret: Preview.Store(numberOfRandomSecrets: 1).secrets[0])
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user