Skip to content

Commit 72e8608

Browse files
committed
fix: camera properly closed
1 parent 56333aa commit 72e8608

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/app/search/page.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default function ProductSearch() {
7272
const [currentCameraIndex, setCurrentCameraIndex] = useState(0);
7373
const [availableCameras, setAvailableCameras] = useState<MediaDeviceInfo[]>([]);
7474
const videoRef = useRef<HTMLVideoElement>(null);
75+
const cameraControlsRef = useRef<{ stop: () => void } | null>(null);
7576
const router = useRouter();
7677
const { setNavigating } = useTopBar();
7778

@@ -126,7 +127,6 @@ export default function ProductSearch() {
126127
if (pageLoading) return; // Don't start camera until page is loaded
127128

128129
let active = true;
129-
let controls: { stop: () => void } | null = null;
130130

131131
const startCamera = async () => {
132132
try {
@@ -136,17 +136,19 @@ export default function ProductSearch() {
136136
if (devices.length > 0 && videoRef.current && active) {
137137
const selectedDevice = devices[currentCameraIndex] || devices[0];
138138
const codeReader = new BrowserMultiFormatReader();
139-
controls = await codeReader.decodeFromVideoDevice(
139+
const controls = await codeReader.decodeFromVideoDevice(
140140
selectedDevice.deviceId,
141141
videoRef.current,
142142
(result, _err, c) => {
143143
if (result && active) {
144144
router.push(`/product/${result.getText()}`);
145145
c.stop();
146+
cameraControlsRef.current = null;
146147
active = false;
147148
}
148149
}
149150
);
151+
cameraControlsRef.current = controls;
150152
}
151153
} catch (error) {
152154
console.error('Failed to start camera:', error);
@@ -159,12 +161,31 @@ export default function ProductSearch() {
159161
return () => {
160162
active = false;
161163
clearTimeout(timer);
162-
if (controls) controls.stop();
164+
if (cameraControlsRef.current) {
165+
cameraControlsRef.current.stop();
166+
cameraControlsRef.current = null;
167+
}
163168
};
164169
}, [router, pageLoading, currentCameraIndex]);
165170

171+
// Cleanup camera when component unmounts
172+
useEffect(() => {
173+
return () => {
174+
if (cameraControlsRef.current) {
175+
cameraControlsRef.current.stop();
176+
cameraControlsRef.current = null;
177+
}
178+
};
179+
}, []);
180+
166181
const flipCamera = () => {
167182
if (availableCameras.length > 1) {
183+
// Stop current camera before switching
184+
if (cameraControlsRef.current) {
185+
cameraControlsRef.current.stop();
186+
cameraControlsRef.current = null;
187+
}
188+
168189
setCurrentCameraIndex((prevIndex) =>
169190
(prevIndex + 1) % availableCameras.length
170191
);

0 commit comments

Comments
 (0)