Skip to content

Commit 35d012a

Browse files
author
Eric Wheeler
committed
fix: copy task button retrieves content from backend
This change modifies the copy button in task history to retrieve the task content from the backend storage using getHistoryItem before copying it to the clipboard. This ensures the most up-to-date content is copied. Fixes: #3648 Signed-off-by: Eric Wheeler <[email protected]>
1 parent 73a276b commit 35d012a

File tree

6 files changed

+43
-21
lines changed

6 files changed

+43
-21
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,19 @@ export class ClineProvider
11761176
await downloadTask(historyItem.ts, apiConversationHistory)
11771177
}
11781178

1179+
async copyTaskToClipboard(id: string) {
1180+
try {
1181+
const historyItem = await getHistoryItem(id)
1182+
if (historyItem) {
1183+
await vscode.env.clipboard.writeText(historyItem.task)
1184+
vscode.window.showInformationMessage(t("common:info.clipboard_copy"))
1185+
}
1186+
} catch (error) {
1187+
this.log(`Error copying task: ${error}`)
1188+
vscode.window.showErrorMessage(t("common:errors.copy_task_failed"))
1189+
}
1190+
}
1191+
11791192
/* Condenses a task's message history to use fewer tokens. */
11801193
async condenseTaskContext(taskId: string) {
11811194
let task: Task | undefined

src/core/webview/webviewMessageHandler.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,11 @@ export const webviewMessageHandler = async (
441441
case "showTaskWithId":
442442
provider.showTaskWithId(message.text!)
443443
break
444+
case "copyTask":
445+
if (message.text) {
446+
provider.copyTaskToClipboard(message.text)
447+
}
448+
break
444449
case "condenseTaskContextRequest":
445450
provider.condenseTaskContext(message.text!)
446451
break

src/shared/WebviewMessage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ export interface WebviewMessage {
5959
| "shareCurrentTask"
6060
| "showTaskWithId"
6161
| "deleteTaskWithId"
62+
| "taskDeletedConfirmation"
63+
| "copyTask"
6264
| "exportTaskWithId"
6365
| "importSettings"
6466
| "exportSettings"

webview-ui/src/components/history/CopyButton.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
1-
import { useCallback } from "react"
1+
import { useCallback, useState } from "react"
22

3-
import { useClipboard } from "@/components/ui/hooks"
43
import { Button, StandardTooltip } from "@/components/ui"
54
import { useAppTranslation } from "@/i18n/TranslationContext"
65
import { cn } from "@/lib/utils"
6+
import { vscode } from "@/utils/vscode"
77

88
type CopyButtonProps = {
9-
itemTask: string
9+
itemId: string
1010
}
1111

12-
export const CopyButton = ({ itemTask }: CopyButtonProps) => {
13-
const { isCopied, copy } = useClipboard()
12+
export const CopyButton = ({ itemId }: CopyButtonProps) => {
13+
const [isCopied, setIsCopied] = useState(false)
1414
const { t } = useAppTranslation()
1515

1616
const onCopy = useCallback(
1717
(e: React.MouseEvent) => {
1818
e.stopPropagation()
1919

2020
if (!isCopied) {
21-
copy(itemTask)
21+
vscode.postMessage({ type: "copyTask", text: itemId })
22+
setIsCopied(true)
23+
setTimeout(() => setIsCopied(false), 2000)
2224
}
2325
},
24-
[isCopied, copy, itemTask],
26+
[isCopied, itemId],
2527
)
2628

2729
return (

webview-ui/src/components/history/TaskItemFooter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const TaskItemFooter: React.FC<TaskItemFooterProps> = ({ item, variant, isSelect
5252
{/* Action Buttons for non-compact view */}
5353
{!isSelectionMode && (
5454
<div className="flex flex-row gap-0 items-center opacity-50 hover:opacity-100">
55-
<CopyButton itemTask={item.task} />
55+
<CopyButton itemId={item.id} />
5656
{variant === "full" && <ExportButton itemId={item.id} />}
5757
</div>
5858
)}
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
import { render, screen, fireEvent } from "@/utils/test-utils"
2-
3-
import { useClipboard } from "@/components/ui/hooks"
4-
52
import { CopyButton } from "../CopyButton"
3+
import { vscode } from "@/utils/vscode"
4+
5+
vi.mock("@/utils/vscode", () => ({
6+
vscode: {
7+
postMessage: vi.fn(),
8+
},
9+
}))
610

7-
vi.mock("@/components/ui/hooks")
811
vi.mock("@src/i18n/TranslationContext", () => ({
912
useAppTranslation: () => ({
1013
t: (key: string) => key,
1114
}),
1215
}))
1316

1417
describe("CopyButton", () => {
15-
const mockCopy = vi.fn()
16-
1718
beforeEach(() => {
1819
vi.clearAllMocks()
19-
;(useClipboard as any).mockReturnValue({
20-
isCopied: false,
21-
copy: mockCopy,
22-
})
2320
})
2421

25-
it("copies task content when clicked", () => {
26-
render(<CopyButton itemTask="Test task content" />)
22+
it("sends copy message with task ID when clicked", () => {
23+
render(<CopyButton itemId="test-task-id" />)
2724

2825
const copyButton = screen.getByRole("button")
2926
fireEvent.click(copyButton)
3027

31-
expect(mockCopy).toHaveBeenCalledWith("Test task content")
28+
expect(vscode.postMessage).toHaveBeenCalledWith({
29+
type: "copyTask",
30+
text: "test-task-id",
31+
})
3232
})
3333
})

0 commit comments

Comments
 (0)