Skip to content

fix(calibration): don't open cameras until the user turns them on#21

Merged
nicolas-rabault merged 2 commits into
huggingface:mainfrom
cn0303:fix/calibration-eager-camera-open
Jun 8, 2026
Merged

fix(calibration): don't open cameras until the user turns them on#21
nicolas-rabault merged 2 commits into
huggingface:mainfrom
cn0303:fix/calibration-eager-camera-open

Conversation

@cn0303

@cn0303 cn0303 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Opening or reloading the Calibration page used to switch on the
webcam and any other connected camera without the user doing anything.
This PR gates the camera section behind an explicit On/Off toggle (off by
default), so cameras are only touched once the user opts in.

The bug

The "Attached cameras" section is rendered inline on the calibration page and
mounts on load. On mount, useAvailableCameras fires a
getUserMedia({ video: true }) permission probe to unlock device labels for
enumeration. Because { video: true } lets the browser pick the device, the
probe grabs whatever the OS treats as the default camera independent of the
robot's config. So:

  • just visiting/reloading the page turns a camera on, and
  • a camera can light up even after being removed from the configuration,
    because the probe doesn't care what's configured.

The fix

  • Add an On/Off Switch to the section header, off by default.
  • While off, CameraConfiguration is not mounted, so nothing calls
    getUserMedia and no camera is touched. The panel instead explains that
    turning cameras on will scan connected devices and trigger the browser
    permission prompt ("Nothing is recorded").
  • Turning it on mounts the section (scan + previews); turning it off unmounts
    it and releases every stream via the existing hook cleanups.
  • Adds a Rescan button next to the camera list (a small refresh control,
    spins while scanning) so a newly plugged-in USB camera can be picked up on
    demand instead of waiting for the devicechange auto-refresh. Lives in the
    shared CameraConfiguration, so the recording modal gets it too.

Before / after

Action Before After
Open/reload calibration page camera(s) switch on unprompted nothing turns on
Camera removed from config can still be grabbed by the probe not touched while off
Turn the toggle on n/a scans + previews, asks permission
Plug in a USB camera wait for auto-refresh click Rescan

Before UI

image

After UI

image image

Testing

Frontend only. Verified manually: loaded the calibration page and confirmed no
camera activates until the toggle is switched on; toggling off releases the
streams; Rescan refreshes the list after a hotplug. npm run build passes, and
the changed files pass ESLint directly:

npx eslint src/pages/Calibration.tsx src/components/recording/CameraConfiguration.tsx

cn0303 and others added 2 commits June 8, 2026 13:25
Opening or hard-reloading the calibration page used to switch on the
webcam (and any other connected camera) unprompted. The "Attached
cameras" section mounted on page load and ran getUserMedia immediately:
useAvailableCameras fires a `{ video: true }` permission probe to unlock
device labels, and that probe grabs whatever the OS treats as the default
camera — so a camera could light up even after being removed from the
robot's config, with no user action.

Gate the section behind an explicit On/Off toggle, off by default. While
off, CameraConfiguration is not mounted, so nothing touches a camera; the
panel instead explains that turning cameras on will scan connected
devices and trigger the browser permission prompt. Cameras are only
enumerated and previewed once the user opts in, and toggling off unmounts
the section and releases every stream.

Also add a Rescan button next to the camera list so a newly plugged-in
USB camera can be picked up on demand instead of waiting for the
hotplug auto-refresh.
@nicolas-rabault
nicolas-rabault self-requested a review June 8, 2026 14:24

@nicolas-rabault nicolas-rabault left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Clean, well-scoped fix and the right diagnosis.

Verified on macOS: nothing activates on load, toggle on scans + previews, toggle off releases, Rescan picks up a hotplug.

@nicolas-rabault
nicolas-rabault merged commit a58ba4a into huggingface:main Jun 8, 2026
1 check passed
@cn0303
cn0303 deleted the fix/calibration-eager-camera-open branch June 8, 2026 15:45
cn0303 added a commit to cn0303/leLab that referenced this pull request Jun 8, 2026
The "Rebuild frontend/dist" workflow ran on Node 18, but the repo moved to
Vite 8 (frontend/package.json), which requires Node >=20. Since that bump
`npm run build` failed in CI, so the committed frontend/dist silently
stopped being regenerated and the shipped bundle fell behind the merged
source (e.g. the PR huggingface#21 calibration UI never reached dist, so a plain
install/run showed the old UI).

Bumping to Node 22 fixes the build. This workflow also triggers on changes
to its own file, so merging this re-runs it and rebuilds dist from the
current source on the next push to main.
cn0303 added a commit to cn0303/leLab that referenced this pull request Jun 8, 2026
…ckerfile)

A Dependabot PR bumped the repo to Vite 8 (build(deps-dev): bump vite 5→8),
which requires Node ^20.19.0 || >=22.12.0. Two build pipelines were still
pinned to Node 18, so `npm run build` fails on both:

- .github/workflows/build_frontend.yml — the "Rebuild frontend/dist" workflow.
  Its build failed silently, so the committed frontend/dist stopped being
  regenerated and the shipped bundle fell behind the merged source (e.g. the
  PR huggingface#21 calibration UI never reached dist).
- frontend/Dockerfile — the image the Hugging Face Space builds. Its
  `npm run build` step fails, so the Space shows a build error.

Bump both to Node 22. The rebuild workflow also triggers on changes to its own
file, so merging this re-runs it and regenerates dist from the current source.
nicolas-rabault pushed a commit that referenced this pull request Jun 9, 2026
…ckerfile)

A Dependabot PR bumped the repo to Vite 8 (build(deps-dev): bump vite 5→8),
which requires Node ^20.19.0 || >=22.12.0. Two build pipelines were still
pinned to Node 18, so `npm run build` fails on both:

- .github/workflows/build_frontend.yml — the "Rebuild frontend/dist" workflow.
  Its build failed silently, so the committed frontend/dist stopped being
  regenerated and the shipped bundle fell behind the merged source (e.g. the
  PR #21 calibration UI never reached dist).
- frontend/Dockerfile — the image the Hugging Face Space builds. Its
  `npm run build` step fails, so the Space shows a build error.

Bump both to Node 22. The rebuild workflow also triggers on changes to its own
file, so merging this re-runs it and regenerates dist from the current source.
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