From 2966804f6575f4f7dd961337cdc3b4a81a280c18 Mon Sep 17 00:00:00 2001 From: Simon <85533298+handsomezhuzhu@users.noreply.github.com> Date: Fri, 16 Jan 2026 01:33:08 +0800 Subject: [PATCH] Fix camera preview mounting for QR scan --- app/page.tsx | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index b1b971e..ecefe9c 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -316,22 +316,43 @@ export default function TwoFactorAuth() { }) streamRef.current = stream - if (videoRef.current) { - videoRef.current.srcObject = stream - // Wait for video to be ready before playing - await new Promise((resolve, reject) => { - const video = videoRef.current! - video.onloadedmetadata = () => { - video - .play() - .then(() => resolve()) - .catch(reject) + setIsCameraOpen(true) + + // Wait for the video element to mount before attaching the stream + await new Promise((resolve, reject) => { + let attempts = 0 + const waitForVideo = () => { + if (videoRef.current) { + resolve() + return } - video.onerror = () => reject(new Error("Video load error")) - }) + attempts += 1 + if (attempts > 10) { + reject(new Error("Video element not available")) + return + } + requestAnimationFrame(waitForVideo) + } + waitForVideo() + }) + + if (!videoRef.current) { + throw new Error("Video element not available") } - setIsCameraOpen(true) + videoRef.current.srcObject = stream + // Wait for video to be ready before playing + await new Promise((resolve, reject) => { + const video = videoRef.current! + video.onloadedmetadata = () => { + video + .play() + .then(() => resolve()) + .catch(reject) + } + video.onerror = () => reject(new Error("Video load error")) + }) + // Start scanning after a short delay to ensure video is rendering setTimeout(() => scanQRCode(), 500) } catch (error) {