2020-03-04 07:14:38 +00:00
import SwiftUI
import SecretKit
2020-09-22 06:12:50 +00:00
struct CreateSecretView < StoreType : SecretStoreModifiable > : View {
2022-02-28 00:29:09 +00:00
2020-09-22 06:12:50 +00:00
@ ObservedObject var store : StoreType
@ Binding var showing : Bool
2022-02-28 00:29:09 +00:00
2020-09-22 06:12:50 +00:00
@ State private var name = " "
@ State private var requiresAuthentication = true
2022-02-28 00:29:09 +00:00
@ State private var test : ThumbnailPickerView . Item = ThumbnailPickerView . Item ( name : " Test " , description : " Hello " , thumbnail : Text ( " Hello " ) )
2020-03-04 07:14:38 +00:00
var body : some View {
2020-03-07 08:00:09 +00:00
VStack {
HStack {
VStack {
HStack {
2022-02-27 23:08:25 +00:00
Text ( " Create a New Secret " )
. font ( . largeTitle )
2020-03-07 08:00:09 +00:00
Spacer ( )
}
HStack {
Text ( " Name: " )
2022-02-27 23:08:25 +00:00
TextField ( " Shhhhh " , text : $ name )
. focusable ( )
2020-03-07 08:00:09 +00:00
}
2022-02-28 00:29:09 +00:00
if #available ( macOS 12.0 , * ) {
ThumbnailPickerView ( items : [
ThumbnailPickerView . Item ( name : " Requires Authentication Before Use " , description : " You will be required to authenticate using Touch ID, Apple Watch, or password before each use. " , thumbnail : AuthenticationView ( ) ) ,
ThumbnailPickerView . Item ( name : " Notify on Use " ,
description : " No authentication is required while your Mac is unlocked. " ,
thumbnail : NotificationView ( ) )
] , selection : $ test )
} else {
// H S t a c k {
// V S t a c k ( s p a c i n g : 2 0 ) {
// P i c k e r ( " " , s e l e c t i o n : $ r e q u i r e s A u t h e n t i c a t i o n ) {
// T e x t ( " R e q u i r e s A u t h e n t i c a t i o n ( B i o m e t r i c s o r P a s s w o r d ) b e f o r e e a c h u s e " ) . t a g ( t r u e )
// T e x t ( " A u t h e n t i c a t i o n n o t r e q u i r e d w h e n M a c i s u n l o c k e d " ) . t a g ( f a l s e )
// }
// . p i c k e r S t y l e ( S e g m e n t e d P i c k e r S t y l e ( ) )
// }
// S p a c e r ( )
// }
}
2020-03-04 07:14:38 +00:00
}
}
2020-03-07 08:00:09 +00:00
HStack {
Spacer ( )
2020-09-22 06:12:50 +00:00
Button ( " Cancel " ) {
showing = false
2020-03-04 07:14:38 +00:00
}
2020-09-22 06:12:50 +00:00
. keyboardShortcut ( . cancelAction )
Button ( " Create " , action : save )
. disabled ( name . isEmpty )
. keyboardShortcut ( . defaultAction )
2020-03-04 07:14:38 +00:00
}
2020-03-07 08:00:09 +00:00
} . padding ( )
2020-03-04 07:14:38 +00:00
}
2022-02-28 00:29:09 +00:00
2020-03-04 07:14:38 +00:00
func save ( ) {
try ! store . create ( name : name , requiresAuthentication : requiresAuthentication )
2020-09-22 06:12:50 +00:00
showing = false
2020-03-04 07:14:38 +00:00
}
}
2022-02-27 21:30:18 +00:00
2022-02-27 23:08:25 +00:00
struct ThumbnailPickerView : View {
2022-02-28 00:29:09 +00:00
2022-02-27 23:08:25 +00:00
let items : [ Item ]
2022-02-28 00:29:09 +00:00
@ Binding var selection : Item
2022-02-27 23:08:25 +00:00
var body : some View {
HStack {
ForEach ( items ) { item in
2022-02-28 00:29:09 +00:00
VStack {
item . thumbnail
. clipShape ( RoundedRectangle ( cornerRadius : 10 ) )
. overlay ( RoundedRectangle ( cornerRadius : 10 )
. stroke ( lineWidth : item . id = = selection . id ? 5 : 0 ) )
. foregroundColor ( . accentColor )
Text ( item . name )
. bold ( )
Text ( item . description )
} . onTapGesture {
selection = item
}
2022-02-27 23:08:25 +00:00
}
2022-02-28 00:29:09 +00:00
} . onAppear {
selection = items . first !
2022-02-27 23:08:25 +00:00
}
}
2022-02-28 00:29:09 +00:00
2022-02-27 23:08:25 +00:00
}
extension ThumbnailPickerView {
2022-02-28 00:29:09 +00:00
2022-02-27 23:08:25 +00:00
struct Item : Identifiable {
let id = UUID ( )
let name : String
2022-02-28 00:29:09 +00:00
let description : String
2022-02-27 23:08:25 +00:00
let thumbnail : AnyView
2022-02-28 00:29:09 +00:00
init < ViewType : View > ( name : String , description : String , thumbnail : ViewType ) {
2022-02-27 23:08:25 +00:00
self . name = name
2022-02-28 00:29:09 +00:00
self . description = description
2022-02-27 23:08:25 +00:00
self . thumbnail = AnyView ( thumbnail )
}
}
2022-02-28 00:29:09 +00:00
2022-02-27 23:08:25 +00:00
}
@ available ( macOS 12.0 , * )
2022-02-28 00:29:09 +00:00
struct SystemBackgroundView : View {
let anchor : UnitPoint
2022-02-27 23:08:25 +00:00
var body : some View {
2022-02-28 00:29:09 +00:00
if let mainScreen = NSScreen . main , let imageURL = NSWorkspace . shared . desktopImageURL ( for : mainScreen ) {
AsyncImage ( url : imageURL ) { phase in
switch phase {
case . empty , . failure :
Rectangle ( )
. foregroundColor ( Color ( . systemPurple ) )
case . success ( let image ) :
image
. resizable ( )
. scaleEffect ( 3 , anchor : anchor )
. clipped ( )
@ unknown default :
Rectangle ( )
. foregroundColor ( Color ( . systemPurple ) )
2022-02-27 23:08:25 +00:00
}
}
2022-02-28 00:29:09 +00:00
} else {
Rectangle ( )
. foregroundColor ( Color ( . systemPurple ) )
}
}
}
@ available ( macOS 12.0 , * )
struct AuthenticationView : View {
var body : some View {
ZStack {
SystemBackgroundView ( anchor : . center )
2022-02-27 23:08:25 +00:00
VStack {
Spacer ( )
Image ( systemName : " touchid " )
. resizable ( )
. aspectRatio ( contentMode : . fit )
. frame ( width : 100 )
. foregroundColor ( Color ( . systemRed ) )
Spacer ( )
Text ( " Touch ID Prompt " )
. font ( . largeTitle )
2022-02-28 00:29:09 +00:00
. foregroundColor ( . primary )
2022-02-27 23:08:25 +00:00
. redacted ( reason : . placeholder )
Spacer ( )
VStack {
Text ( " Touch ID Detail prompt.Detail two. " )
. font ( . title3 )
2022-02-28 00:29:09 +00:00
. foregroundColor ( . primary )
2022-02-27 23:08:25 +00:00
Text ( " Touch ID Detail prompt.Detail two. " )
. font ( . title3 )
2022-02-28 00:29:09 +00:00
. foregroundColor ( . primary )
2022-02-27 23:08:25 +00:00
}
. redacted ( reason : . placeholder )
Spacer ( )
RoundedRectangle ( cornerRadius : 10 )
. frame ( width : 275 , height : 40 , alignment : . center )
2022-02-28 00:29:09 +00:00
. foregroundColor ( . accentColor )
2022-02-27 23:08:25 +00:00
RoundedRectangle ( cornerRadius : 10 )
. frame ( width : 275 , height : 40 , alignment : . center )
. foregroundColor ( Color ( . unemphasizedSelectedContentBackgroundColor ) )
2022-02-28 00:29:09 +00:00
}
. padding ( )
. background (
RoundedRectangle ( cornerRadius : 15 )
. foregroundStyle ( . ultraThickMaterial )
)
. padding ( )
}
}
}
@ available ( macOS 12.0 , * )
struct NotificationView : View {
var body : some View {
ZStack {
SystemBackgroundView ( anchor : . topTrailing )
VStack {
Rectangle ( )
. background ( Color . clear )
. foregroundStyle ( . thinMaterial )
. frame ( height : 35 )
VStack {
HStack {
Spacer ( )
HStack {
Image ( nsImage : NSApplication . shared . applicationIconImage )
. resizable ( )
. frame ( width : 64 , height : 64 )
. foregroundColor ( . primary )
. padding ( )
VStack ( alignment : . leading ) {
Text ( " Secretive " )
. font ( . largeTitle )
. foregroundColor ( . primary )
Text ( " Secretive wants to sign some request " )
. font ( . title3 )
. foregroundColor ( . primary )
Text ( " Secretive wants to sign some request " )
. font ( . title3 )
. foregroundColor ( . primary )
}
. padding ( )
}
. redacted ( reason : . placeholder )
. background (
RoundedRectangle ( cornerRadius : 15 )
. foregroundStyle ( . ultraThickMaterial )
)
}
Spacer ( )
}
. padding ( )
}
2022-02-27 23:08:25 +00:00
}
}
2022-02-28 00:29:09 +00:00
2022-02-27 23:08:25 +00:00
}
2022-02-27 21:30:18 +00:00
#if DEBUG
struct CreateSecretView_Previews : PreviewProvider {
2022-02-28 00:29:09 +00:00
2022-02-27 21:30:18 +00:00
static var previews : some View {
Group {
CreateSecretView ( store : Preview . StoreModifiable ( ) , showing : . constant ( true ) )
2022-02-27 23:08:25 +00:00
if #available ( macOS 12.0 , * ) {
AuthenticationView ( ) . environment ( \ . colorScheme , . dark )
AuthenticationView ( ) . environment ( \ . colorScheme , . light )
2022-02-28 00:29:09 +00:00
NotificationView ( ) . environment ( \ . colorScheme , . dark )
NotificationView ( ) . environment ( \ . colorScheme , . light )
2022-02-27 23:08:25 +00:00
} else {
// F a l l b a c k o n e a r l i e r v e r s i o n s
}
2022-02-27 21:30:18 +00:00
}
}
}
#endif