Я пишу расширение на основе WebUSB для Scratch3. В конструкторе расширений мне нужно установить соединение с WebUSB. В идеале я хотел бы использовать navigator.usb.getDevices () для проверки доступных / сопряженных устройств, и в случае сбоя я хотел бы попросить пользователя выбрать устройство с помощью navigator.usb.requestDevice ().
Проблема в том, что navigator.usb.requestDevice () должен вызываться из жеста пользователя. В большинстве случаев конструктор расширения scratch3 вызывается из пользовательского действия, и поэтому я могу прекрасно использовать navigator.usb.requestDevice ().
Но navigator.usb.getDevices () возвращает Promise и вызывает navigator.usb.requestDevice () оттуда с ошибкой
«Должен обрабатывать пользовательский жест для отображения запроса на разрешение.»
Итак, работает следующее (но каждый раз открывает диалог запроса):
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(selectedDevice => {
// ...
})
Но из-за отсутствия "пользовательского жеста" происходит следующее:
navigator.usb.getDevices().then(devices => {
if(devices.length == 0) {
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(selectedDevice => {
// ...
})
}
})
Я бы хотел не связываться с ядром Scratch 3 и поэтому не хотел бы добавлять еще один элемент пользовательского интерфейса.
Использование только navigator.usb.requestDevice (), как в первом фрагменте, имеет два основных недостатка:
- Он все время открывает диалог запроса, хотя это необходимо только один раз
- Иногда позже конструктор может быть вызван из неинтерактивной ситуации, и navigator.usb.requestDevice () полностью потерпит неудачу, в то время как navigator.usb.getDevices () завершится успешно
Есть ли способ заставить подход из второго фрагмента кода работать?