Spaces:
Running
Running
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
|
179 |
|
180 |
try {
|
181 |
-
// Step 1: Request
|
182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
await port.open({ baudRate: 1000000 });
|
184 |
|
185 |
const portName = getPortDisplayName(port);
|
186 |
onMessage?.(`β
Connected to ${portName}`);
|
187 |
|
188 |
-
//
|
189 |
let serialNumber: string;
|
190 |
let usbMetadata: RobotConnection["usbMetadata"];
|
191 |
|
192 |
-
if (
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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()}`;
|