Skip to content

Commit 9d829b2

Browse files
committed
Add a copy button in UI
1 parent 3649777 commit 9d829b2

File tree

1 file changed

+77
-32
lines changed

1 file changed

+77
-32
lines changed

Core/Sources/SuggestionWidget/SuggestionPanelContent/ChatPanel.swift

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import AppKit
12
import MarkdownUI
23
import 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

371412
struct 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

Comments
 (0)