2020-09-22 06:12:50 +00:00
import SwiftUI
2021-12-12 02:07:10 +00:00
import UniformTypeIdentifiers
2020-09-22 06:12:50 +00:00
struct CopyableView : View {
2024-01-05 02:45:55 +00:00
var title : LocalizedStringKey
2020-09-22 06:12:50 +00:00
var image : Image
var text : String
@ State private var interactionState : InteractionState = . normal
2022-12-18 23:16:08 +00:00
@ Environment ( \ . colorScheme ) private var colorScheme
2020-09-22 06:12:50 +00:00
var body : some View {
VStack ( alignment : . leading ) {
HStack {
image
. renderingMode ( . template )
. imageScale ( . large )
. foregroundColor ( primaryTextColor )
Text ( title )
. font ( . headline )
. foregroundColor ( primaryTextColor )
Spacer ( )
if interactionState != . normal {
Text ( hoverText )
. bold ( )
. textCase ( . uppercase )
. foregroundColor ( secondaryTextColor )
. transition ( . opacity )
}
}
. padding ( EdgeInsets ( top : 20 , leading : 20 , bottom : 10 , trailing : 20 ) )
Divider ( )
Text ( text )
. fixedSize ( horizontal : false , vertical : true )
. foregroundColor ( primaryTextColor )
. padding ( EdgeInsets ( top : 10 , leading : 20 , bottom : 20 , trailing : 20 ) )
. multilineTextAlignment ( . leading )
. font ( . system ( . body , design : . monospaced ) )
}
. background ( backgroundColor )
. frame ( minWidth : 150 , maxWidth : . infinity )
. cornerRadius ( 10 )
. onHover { hovering in
withAnimation {
interactionState = hovering ? . hovering : . normal
}
}
. onDrag {
2021-12-12 02:07:10 +00:00
NSItemProvider ( item : NSData ( data : text . data ( using : . utf8 ) ! ) , typeIdentifier : UTType . utf8PlainText . identifier )
2020-09-22 06:12:50 +00:00
}
. onTapGesture {
copy ( )
withAnimation {
interactionState = . clicking
}
}
. gesture (
TapGesture ( )
. onEnded {
withAnimation {
interactionState = . normal
}
}
)
}
2024-01-05 20:37:59 +00:00
var hoverText : LocalizedStringKey {
2020-09-22 06:12:50 +00:00
switch interactionState {
case . hovering :
2024-01-05 20:37:59 +00:00
return " copyable_click_to_copy_button "
2020-09-22 06:12:50 +00:00
case . clicking :
2024-01-05 20:37:59 +00:00
return " copyable_copied "
2020-09-22 06:12:50 +00:00
case . normal :
fatalError ( )
}
}
var backgroundColor : Color {
switch interactionState {
case . normal :
2022-12-18 23:16:08 +00:00
return colorScheme = = . dark ? Color ( white : 0.2 ) : Color ( white : 0.885 )
2020-09-22 06:12:50 +00:00
case . hovering :
2022-12-18 23:16:08 +00:00
return colorScheme = = . dark ? Color ( white : 0.275 ) : Color ( white : 0.82 )
2020-09-22 06:12:50 +00:00
case . clicking :
2022-12-18 23:16:08 +00:00
return . accentColor
2020-09-22 06:12:50 +00:00
}
}
var primaryTextColor : Color {
switch interactionState {
case . normal , . hovering :
2022-12-18 23:16:08 +00:00
return Color ( . textColor )
2020-09-22 06:12:50 +00:00
case . clicking :
2022-12-18 23:16:08 +00:00
return . white
2020-09-22 06:12:50 +00:00
}
}
var secondaryTextColor : Color {
switch interactionState {
case . normal , . hovering :
2022-12-18 23:16:08 +00:00
return Color ( . secondaryLabelColor )
2020-09-22 06:12:50 +00:00
case . clicking :
2022-12-18 23:16:08 +00:00
return . white
2020-09-22 06:12:50 +00:00
}
}
func copy ( ) {
NSPasteboard . general . declareTypes ( [ . string ] , owner : nil )
NSPasteboard . general . setString ( text , forType : . string )
}
private enum InteractionState {
case normal , hovering , clicking
}
}
#if DEBUG
struct CopyableView_Previews : PreviewProvider {
static var previews : some View {
Group {
2024-01-05 02:45:55 +00:00
CopyableView ( title : " secret_detail_sha256_fingerprint_label " , image : Image ( systemName : " figure.wave " ) , text : " Hello world. " )
2022-12-18 23:16:08 +00:00
. padding ( )
2024-01-05 02:45:55 +00:00
CopyableView ( title : " secret_detail_sha256_fingerprint_label " , image : Image ( systemName : " figure.wave " ) , text : " Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. Long text. " )
2022-12-18 23:16:08 +00:00
. padding ( )
2020-09-22 06:12:50 +00:00
}
}
}
#endif