1+ import AppKit
12import MarkdownUI
23import SwiftUI
34
@@ -151,36 +152,45 @@ struct ChatPanelMessages: View {
151152 }
152153 }
153154 } else {
154- Markdown ( text)
155- . textSelection ( . enabled)
156- . markdownTheme ( . gitHub. text {
157- BackgroundColor ( Color . clear)
158- } )
159- . markdownCodeSyntaxHighlighter (
160- ChatCodeSyntaxHighlighter ( brightMode: colorScheme != . dark)
161- )
162- . frame ( alignment: . leading)
163- . padding ( )
164- . background {
165- RoundedCorners ( tl: r, tr: r, bl: 0 , br: r)
166- . fill ( Color . contentBackground)
167- }
168- . overlay {
169- RoundedCorners ( tl: r, tr: r, bl: 0 , br: r)
170- . stroke ( Color ( nsColor: . separatorColor) , lineWidth: 1 )
155+ HStack ( alignment: . bottom, spacing: 2 ) {
156+ Markdown ( text)
157+ . textSelection ( . enabled)
158+ . markdownTheme ( . gitHub. text {
159+ BackgroundColor ( Color . clear)
160+ } )
161+ . markdownCodeSyntaxHighlighter (
162+ ChatCodeSyntaxHighlighter ( brightMode: colorScheme != . dark)
163+ )
164+ . frame ( alignment: . leading)
165+ . padding ( )
166+ . background {
167+ RoundedCorners ( tl: r, tr: r, bl: 0 , br: r)
168+ . fill ( Color . contentBackground)
169+ }
170+ . overlay {
171+ RoundedCorners ( tl: r, tr: r, bl: 0 , br: r)
172+ . stroke ( Color ( nsColor: . separatorColor) , lineWidth: 1 )
173+ }
174+ . padding ( . leading, 8 )
175+ . rotationEffect ( Angle ( degrees: 180 ) )
176+ . scaleEffect ( x: - 1 , y: 1 , anchor: . center)
177+ . shadow ( color: . black. opacity ( 0.1 ) , radius: 2 )
178+ . contextMenu {
179+ Button ( " Copy " ) {
180+ NSPasteboard . general. clearContents ( )
181+ NSPasteboard . general. setString ( text, forType: . string)
182+ }
183+ }
184+
185+ CopyButton {
186+ NSPasteboard . general. clearContents ( )
187+ NSPasteboard . general. setString ( text, forType: . string)
171188 }
172- . padding ( . leading, 8 )
173- . padding ( . trailing)
174189 . rotationEffect ( Angle ( degrees: 180 ) )
175190 . scaleEffect ( x: - 1 , y: 1 , anchor: . center)
176- . shadow ( color: . black. opacity ( 0.1 ) , radius: 2 )
177- . frame ( maxWidth: . infinity, alignment: . leading)
178- . contextMenu {
179- Button ( " Copy " ) {
180- NSPasteboard . general. clearContents ( )
181- NSPasteboard . general. setString ( text, forType: . string)
182- }
183- }
191+ }
192+ . frame ( maxWidth: . infinity, alignment: . leading)
193+ . padding ( . trailing, 2 )
184194 }
185195 }
186196
@@ -253,7 +263,7 @@ struct ChatPanelInputArea: View {
253263 Image ( systemName: " paperplane.fill " )
254264 . padding ( 8 )
255265 }
256- . buttonStyle ( . plain)
266+ . buttonStyle ( . plain)
257267 . disabled ( chat. isReceivingMessage)
258268 }
259269 . frame ( maxWidth: . infinity)
@@ -352,20 +362,51 @@ struct GlobalChatSwitchToggleStyle: ToggleStyle {
352362 )
353363 . offset ( x: configuration. isOn ? 5 : - 5 , y: 0 )
354364 . animation ( . linear( duration: 0.1 ) , value: configuration. isOn)
355-
356365 )
357366 . onTapGesture { configuration. isOn. toggle ( ) }
358367 . overlay {
359368 RoundedRectangle ( cornerRadius: 10 , style: . circular)
360369 . stroke ( . black. opacity ( 0.2 ) , lineWidth: 1 )
361370 }
362-
371+
363372 Text ( configuration. isOn ? " Global Chat " : " File Chat " )
364373 . foregroundStyle ( . tertiary)
365374 }
366375 }
367376}
368377
378+ struct CopyButton : View {
379+ var copy : ( ) -> Void
380+ @State var isCopied = false
381+ var body : some View {
382+ Button ( action: {
383+ withAnimation ( . linear( duration: 0.1 ) ) {
384+ isCopied = true
385+ }
386+ copy ( )
387+ Task {
388+ try await Task . sleep ( nanoseconds: 1_000_000_000 )
389+ withAnimation ( . linear( duration: 0.1 ) ) {
390+ isCopied = false
391+ }
392+ }
393+ } ) {
394+ Image ( systemName: isCopied ? " checkmark.circle " : " doc.on.doc " )
395+ . resizable ( )
396+ . aspectRatio ( contentMode: . fit)
397+ . frame ( width: 14 , height: 14 )
398+ . frame ( width: 20 , height: 20 , alignment: . center)
399+ . foregroundColor ( . secondary)
400+ . background (
401+ . regularMaterial,
402+ in: RoundedRectangle ( cornerRadius: 4 , style: . circular)
403+ )
404+ . padding ( 4 )
405+ }
406+ . buttonStyle ( . plain)
407+ }
408+ }
409+
369410// MARK: - Previews
370411
371412struct ChatPanel_Preview : PreviewProvider {
@@ -375,7 +416,11 @@ struct ChatPanel_Preview: PreviewProvider {
375416 isUser: true ,
376417 text: " **Hello** "
377418 ) ,
378- . init( id: " 2 " , isUser: false , text: " **Hey**! What can I do for you? " ) ,
419+ . init(
420+ id: " 2 " ,
421+ isUser: false ,
422+ text: " **Hey**! What can I do for you?**Hey**! What can I do for you?**Hey**! What can I do for you?**Hey**! What can I do for you? "
423+ ) ,
379424 . init( id: " 5 " , isUser: false , text: " Yooo " ) ,
380425 . init( id: " 4 " , isUser: true , text: " Yeeeehh " ) ,
381426 . init(
@@ -403,7 +448,7 @@ struct ChatPanel_Preview: PreviewProvider {
403448 history: ChatPanel_Preview . history,
404449 isReceivingMessage: true
405450 ) )
406- . frame ( width: 450 , height: 500 )
451+ . frame ( width: 450 , height: 700 )
407452 . colorScheme ( . dark)
408453 }
409454}
0 commit comments