frontend: added webcam capture with device picker and robust error handling#567
frontend: added webcam capture with device picker and robust error handling#567Pritom2357 wants to merge 5 commits intoAOSSIE-Org:mainfrom
Conversation
… the class in body light propagates to the whole html
Removed commented-out theme context and effect code.
Removed commented-out useEffect for theme handling.
…/landing-dark-mode-class
|
|
WalkthroughThe PR updates Tauri package versions and adds a new dependency (react-webcam). It introduces a webcam-based face search flow in FaceSearchDialog, including device enumeration, device selection, webcam capture, file saving via Tauri FS, and triggering the existing search flow with enhanced error handling and additional dialogs. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant D as FaceSearchDialog
participant M as MediaDevices API
participant W as react-webcam
participant FS as Tauri FS
participant S as SearchMutation
participant R as Router
rect rgb(235,245,255)
note over U,D: Start face search via webcam
U->>D: Open Device Picker
D->>M: enumerateDevices()
M-->>D: video input devices
U->>D: Select camera (deviceId)
D->>D: Set selectedDeviceId, open Webcam dialog
end
rect rgb(240,255,240)
U->>W: Click Capture
D->>W: getScreenshot()
W-->>D: image data (base64)
D->>D: Convert to Blob
D->>FS: writeFile(tempPath, blob)
FS-->>D: OK
D->>S: mutate({ file: tempPath })
S-->>D: success
D->>R: navigate("/")
end
rect rgb(255,240,240)
alt Permission/No device
M-->>D: error/empty list
D-->>U: Show webcamError
else Capture/FS error
FS-->>D: error
D-->>U: Show error feedback
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/src/components/Dialog/FaceSearchDialog.tsx (1)
1-284: Prettier check is failingCI reports a Prettier formatting failure for this file. Please run
pnpm prettier --write frontend/src/components/Dialog/FaceSearchDialog.tsx(or the repo’s equivalent script) and commit the formatted result so the PR check passes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
frontend/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (2)
frontend/package.json(2 hunks)frontend/src/components/Dialog/FaceSearchDialog.tsx(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/src/components/Dialog/FaceSearchDialog.tsx (5)
frontend/src/features/infoDialogSlice.ts (1)
showInfoDialog(16-30)frontend/src/constants/routes.ts (1)
ROUTES(1-11)frontend/src/features/searchSlice.ts (1)
startSearch(20-23)frontend/src/features/loaderSlice.ts (1)
showLoader(17-20)frontend/src/components/ui/dialog.tsx (6)
Dialog(131-131)DialogTrigger(140-140)DialogContent(133-133)DialogHeader(136-136)DialogTitle(139-139)DialogDescription(134-134)
🪛 GitHub Actions: PR Check
frontend/src/components/Dialog/FaceSearchDialog.tsx
[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues in this file.
| useEffect(() => { | ||
| if (isDevicePickerOpen) { | ||
| navigator.mediaDevices.enumerateDevices().then((mediaDevices) => { | ||
| const videoDevices = mediaDevices.filter(({ kind }) => kind === 'videoinput'); | ||
| setDevices(videoDevices); | ||
| }); | ||
| } | ||
| }, [isDevicePickerOpen]); |
There was a problem hiding this comment.
Handle enumerateDevices rejections
navigator.mediaDevices.enumerateDevices() rejects whenever camera access isn’t allowed (permission denied, insecure context, unsupported WebView). Right now that rejection propagates as an unhandled promise, leaving the picker empty with no feedback. Add a guard for navigator.mediaDevices and catch the rejection so you can surface a friendly error and avoid the unhandled rejection.
useEffect(() => {
- if (isDevicePickerOpen) {
- navigator.mediaDevices.enumerateDevices().then((mediaDevices) => {
- const videoDevices = mediaDevices.filter(({ kind }) => kind === 'videoinput');
- setDevices(videoDevices);
- });
- }
+ if (!isDevicePickerOpen) {
+ return;
+ }
+ if (!navigator.mediaDevices?.enumerateDevices) {
+ setWebcamError(
+ 'Webcam access is not supported in this environment.',
+ );
+ setDevices([]);
+ return;
+ }
+ navigator.mediaDevices
+ .enumerateDevices()
+ .then(mediaDevices => {
+ const videoDevices = mediaDevices.filter(({ kind }) => kind === 'videoinput');
+ setDevices(videoDevices);
+ })
+ .catch(error => {
+ console.error('Unable to enumerate camera devices:', error);
+ setWebcamError(
+ 'Could not list camera devices. Please check permissions and try again.',
+ );
+ setDevices([]);
+ });
}, [isDevicePickerOpen]);Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In frontend/src/components/Dialog/FaceSearchDialog.tsx around lines 80 to 87,
the call to navigator.mediaDevices.enumerateDevices() is unguarded and its
rejection is unhandled; add a guard to check navigator.mediaDevices exists
before calling enumerateDevices, call enumerateDevices inside a try/catch or
attach .catch to handle rejections, and on error set a local error state (or
clear devices and set an error message) so the picker shows a friendly message
instead of leaving the promise unhandled; ensure to still setDevices([]) on
error and avoid swallowing the error so downstream UI can react.
|
This work is already under progress by @tushar1977 |
Summary
Implements webcam face-search with a device picker:
navigator.mediaDevices.enumerateDevicesreact-webcamwithdeviceId: { exact: ... }plugin-fs+@tauri-apps/api/path(currently commented out as not needed now)UI
How it works
videoConstraints.deviceId: { exact: selectedDeviceId }Why
Files Changed
Testing
GIF
Known limitations
Checklist
Note ⭐⭐:
I added the picker because I had multiple media devices in my laptop, and each time, when I used the webcam picker, it chose the first device (which is my tablet's camera), and it showed misery for me. So, I used this method. The camera pickers can be removed later.
Summary by CodeRabbit
New Features
Improvements
Chores