Skip to content

Commit e230bab

Browse files
committed
Solves race condition where QR code wouldn't be generated
1 parent dcb86a3 commit e230bab

File tree

1 file changed

+49
-17
lines changed

1 file changed

+49
-17
lines changed

webview-ui/src/components/chat/CloudTaskButton.tsx

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect, useRef } from "react"
1+
import { useState, useEffect, useCallback } from "react"
22
import { useTranslation } from "react-i18next"
33
import { CloudUpload, Copy, Check } from "lucide-react"
44
import QRCode from "qrcode"
@@ -20,16 +20,22 @@ export const CloudTaskButton = ({ item, disabled = false }: CloudTaskButtonProps
2020
const { t } = useTranslation()
2121
const { cloudUserInfo, cloudApiUrl } = useExtensionState()
2222
const { copyWithFeedback, showCopyFeedback } = useCopyToClipboard()
23-
const qrCodeRef = useRef<HTMLCanvasElement>(null)
23+
const [canvasElement, setCanvasElement] = useState<HTMLCanvasElement | null>(null)
2424

2525
// Generate the cloud URL for the task
2626
const cloudTaskUrl = item?.id ? `${cloudApiUrl}/task/${item.id}` : ""
2727

28-
// Generate QR code when dialog opens
29-
useEffect(() => {
30-
if (dialogOpen && qrCodeRef.current && cloudTaskUrl) {
28+
// Helper function to generate QR code
29+
const generateQRCode = useCallback(
30+
(canvas: HTMLCanvasElement, context: string) => {
31+
if (!cloudTaskUrl) {
32+
console.log(`Skipping QR generation (${context}): No URL available`)
33+
return
34+
}
35+
36+
console.log(`Generating QR code (${context})`)
3137
QRCode.toCanvas(
32-
qrCodeRef.current,
38+
canvas,
3339
cloudTaskUrl,
3440
{
3541
width: 140,
@@ -41,12 +47,40 @@ export const CloudTaskButton = ({ item, disabled = false }: CloudTaskButtonProps
4147
},
4248
(error: Error | null | undefined) => {
4349
if (error) {
44-
console.error("Error generating QR code:", error)
50+
console.error(`Error generating QR code (${context}):`, error)
51+
} else {
52+
console.log(`QR code generated successfully (${context})`)
4553
}
4654
},
4755
)
56+
},
57+
[cloudTaskUrl],
58+
)
59+
60+
// Callback ref to capture canvas element when it mounts
61+
const canvasRef = useCallback(
62+
(node: HTMLCanvasElement | null) => {
63+
console.log("Canvas ref callback called with:", node)
64+
if (node) {
65+
setCanvasElement(node)
66+
67+
// Try to generate QR code immediately when canvas is available
68+
if (dialogOpen) {
69+
generateQRCode(node, "on mount")
70+
}
71+
} else {
72+
setCanvasElement(null)
73+
}
74+
},
75+
[dialogOpen, generateQRCode],
76+
)
77+
78+
// Also generate QR code when dialog opens after canvas is available
79+
useEffect(() => {
80+
if (dialogOpen && canvasElement) {
81+
generateQRCode(canvasElement, "in useEffect")
4882
}
49-
}, [dialogOpen, cloudTaskUrl])
83+
}, [dialogOpen, canvasElement, generateQRCode])
5084

5185
// Check if the button should be shown
5286
if (!cloudUserInfo?.extensionBridgeEnabled || !item?.id) {
@@ -75,16 +109,14 @@ export const CloudTaskButton = ({ item, disabled = false }: CloudTaskButtonProps
75109
</DialogHeader>
76110

77111
<div className="flex flex-col space-y-4 text-center">
78-
{qrCodeRef && (
79-
<div className="flex justify-center">
80-
<div
81-
className="w-[170px] h-[170px] bg-white rounded-lg border-border cursor-pointer hover:opacity-70 transition-opacity"
82-
onClick={() => vscode.postMessage({ type: "openExternal", url: cloudTaskUrl })}
83-
title={t("chat:task.openInCloud")}>
84-
<canvas ref={qrCodeRef} className="m-[15px]" />
85-
</div>
112+
<div className="flex justify-center">
113+
<div
114+
className="w-[170px] h-[170px] bg-white rounded-lg border-border cursor-pointer hover:opacity-70 transition-opacity"
115+
onClick={() => vscode.postMessage({ type: "openExternal", url: cloudTaskUrl })}
116+
title={t("chat:task.openInCloud")}>
117+
<canvas ref={canvasRef} className="m-[15px]" />
86118
</div>
87-
)}
119+
</div>
88120

89121
<div className="flex items-center space-x-2">
90122
<Input value={cloudTaskUrl} disabled className="flex-1 font-mono text-sm" readOnly />

0 commit comments

Comments
 (0)