NERDDISCO commited on
Commit
66cb510
Β·
1 Parent(s): 69bcf09

fix: trigger WebSerial and WebUSB with the same user gesture

Browse files
.changeset/wide-animals-notice.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ ---
2
+ "@lerobot/web": patch
3
+ ---
4
+
5
+ fix: trigger WebSerial and WebUSB with the same user gesture
packages/web/src/find_port.ts CHANGED
@@ -175,26 +175,50 @@ async function findPortInteractive(
175
  ): Promise<RobotConnection[]> {
176
  const { onMessage } = options;
177
 
178
- onMessage?.("Opening port selection dialog...");
179
 
180
  try {
181
- // Step 1: Request Web Serial port
182
- const port = await navigator.serial.requestPort();
 
 
 
 
 
 
 
 
 
 
 
 
183
  await port.open({ baudRate: 1000000 });
184
 
185
  const portName = getPortDisplayName(port);
186
  onMessage?.(`βœ… Connected to ${portName}`);
187
 
188
- // Step 2: Request WebUSB device for metadata (if supported)
189
  let serialNumber: string;
190
  let usbMetadata: RobotConnection["usbMetadata"];
191
 
192
- if (isWebUSBSupported()) {
193
- onMessage?.("πŸ“± Requesting device identification...");
194
- const usbData = await requestUSBDeviceMetadata();
195
- serialNumber = usbData.serialNumber;
196
- usbMetadata = usbData.usbMetadata;
197
- onMessage?.(`πŸ†” Device ID: ${serialNumber}`);
 
 
 
 
 
 
 
 
 
 
 
 
198
  } else {
199
  onMessage?.("⚠️ WebUSB not supported, using fallback ID");
200
  const fallbackId = `no-usb-${Date.now()}`;
 
175
  ): Promise<RobotConnection[]> {
176
  const { onMessage } = options;
177
 
178
+ onMessage?.("Opening device selection dialogs...");
179
 
180
  try {
181
+ // Step 1: Request both permissions simultaneously to preserve user gesture
182
+ let serialPortPromise = navigator.serial.requestPort();
183
+ let usbDevicePromise: Promise<{
184
+ serialNumber: string;
185
+ usbMetadata: RobotConnection["usbMetadata"];
186
+ }> | null = null;
187
+
188
+ if (isWebUSBSupported()) {
189
+ onMessage?.("πŸ“± Requesting device access permissions...");
190
+ usbDevicePromise = requestUSBDeviceMetadata();
191
+ }
192
+
193
+ // Wait for serial port
194
+ const port = await serialPortPromise;
195
  await port.open({ baudRate: 1000000 });
196
 
197
  const portName = getPortDisplayName(port);
198
  onMessage?.(`βœ… Connected to ${portName}`);
199
 
200
+ // Get USB metadata
201
  let serialNumber: string;
202
  let usbMetadata: RobotConnection["usbMetadata"];
203
 
204
+ if (usbDevicePromise) {
205
+ try {
206
+ const usbData = await usbDevicePromise;
207
+ serialNumber = usbData.serialNumber;
208
+ usbMetadata = usbData.usbMetadata;
209
+ onMessage?.(`πŸ†” Device ID: ${serialNumber}`);
210
+ } catch (usbError) {
211
+ onMessage?.("⚠️ Device identification failed, using fallback ID");
212
+ const fallbackId = `fallback-${Date.now()}`;
213
+ serialNumber = fallbackId;
214
+ usbMetadata = {
215
+ vendorId: "Unknown",
216
+ productId: "Unknown",
217
+ serialNumber: fallbackId,
218
+ manufacturerName: "USB Dialog Cancelled",
219
+ productName: "User cancelled device selection",
220
+ };
221
+ }
222
  } else {
223
  onMessage?.("⚠️ WebUSB not supported, using fallback ID");
224
  const fallbackId = `no-usb-${Date.now()}`;