Skip to content

frontend: added webcam capture with device picker and robust error handling#567

Closed
Pritom2357 wants to merge 5 commits intoAOSSIE-Org:mainfrom
Pritom2357:webcam-device-picker
Closed

frontend: added webcam capture with device picker and robust error handling#567
Pritom2357 wants to merge 5 commits intoAOSSIE-Org:mainfrom
Pritom2357:webcam-device-picker

Conversation

@Pritom2357
Copy link
Contributor

@Pritom2357 Pritom2357 commented Oct 4, 2025

Summary

Implements webcam face-search with a device picker:

  • Device picker dialog using navigator.mediaDevices.enumerateDevices
  • Webcam capture via react-webcam with deviceId: { exact: ... }
  • Saves capture to temp via Tauri plugin-fs + @tauri-apps/api/path (currently commented out as not needed now)

UI

  • Dialog 1: File upload or Use Webcam
  • Dialog 2: Select Camera Device (lists videoinput devices)
  • Dialog 3: Webcam preview with Capture/Cancel

How it works

  • When “Use Webcam” is clicked → open device picker
  • On selection → open webcam dialog with videoConstraints.deviceId: { exact: selectedDeviceId }
  • On capture → convert base64 to Blob → write to temp path → run face search with that path
  • Error state displayed if media access fails

Why

  • Avoids auto-selecting the wrong camera (e.g., tablet/virtual cameras)
  • Fixes infinite loader by surfacing permission/camera errors
  • Keeps backend unchanged by using a real file path

Files Changed

  • FaceSearchDialog.tsx
  • package.json already includes react-webcam and Tauri plugins

Testing

  • OS: Windows 11, Tauri dev build
  • Cameras: Tablet virtual cam, HP laptop webcam, OBS virtual cam
  • Scenarios:
    • Select laptop webcam → capture → search runs
    • Deny camera permission → error message shown
    • Unplug/disable device → picker updates to show available devices

GIF

Animation2

Known limitations

  • Device labels may be empty before permission is granted (browser behavior)
  • If another app is using the camera, access may fail (error shown)

Checklist

  • Lint/format pass
  • Manual test on Windows
  • No breaking changes
  • Added UX copy for errors
  • PR title uses Conventional Commits

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

    • Added webcam-based face search with device selection and live capture.
    • Introduced a device picker to choose from available cameras.
    • Enhanced error messages for camera permissions and availability.
    • Streamlined flow: capture triggers search automatically; upload option remains.
  • Improvements

    • Split the face search into dedicated dialogs for clearer, guided steps.
  • Chores

    • Updated Tauri-related dependencies to newer stable versions.
    • Added react-webcam as a new dependency.

Pritom2357 and others added 5 commits September 27, 2025 03:47
… 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.
@github-actions
Copy link
Contributor

github-actions bot commented Oct 4, 2025

⚠️ No issue was linked in the PR description.
Please make sure to link an issue (e.g., 'Fixes #issue_number')

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 4, 2025

Walkthrough

The 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

Cohort / File(s) Summary
Frontend deps update
frontend/package.json
Bumped @tauri-apps/api to ^2.8.0, @tauri-apps/plugin-dialog to ^2.4.0, @tauri-apps/plugin-fs to ^2.4.2; added react-webcam ^7.2.0.
Face search webcam flow
frontend/src/components/Dialog/FaceSearchDialog.tsx
Added device picker and webcam capture dialogs; enumerates media devices; selects deviceId; captures image via react-webcam; saves blob to temp file using Tauri FS; triggers existing search mutation; added state, refs, handlers, and error handling; preserved upload flow.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Poem

A lens blinks—click!—I twitch my nose,
New cams aligned where data flows.
I hop through dialogs, swift and spry,
Save a snapshot—search will fly.
With Tauri purring, bytes in tow,
I find your face—now off I go! 🐇📸

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely summarizes the primary change by specifying the addition of webcam capture functionality, a device picker, and enhanced error handling in the frontend. It directly corresponds to the implemented features without including extraneous details. The “frontend:” prefix appropriately scopes the change to the UI layer, making the intent immediately clear to reviewers.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 4, 2025

⚠️ No issue was linked in the PR description.
Please make sure to link an issue (e.g., 'Fixes #issue_number')

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 failing

CI 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

📥 Commits

Reviewing files that changed from the base of the PR and between 20d16e5 and 8e2387c.

⛔ Files ignored due to path filters (1)
  • frontend/package-lock.json is 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.

Comment on lines +80 to +87
useEffect(() => {
if (isDevicePickerOpen) {
navigator.mediaDevices.enumerateDevices().then((mediaDevices) => {
const videoDevices = mediaDevices.filter(({ kind }) => kind === 'videoinput');
setDevices(videoDevices);
});
}
}, [isDevicePickerOpen]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

@rahulharpal1603
Copy link
Contributor

This work is already under progress by @tushar1977

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments