From a02236acb5798c47632cad4a761b0c535e329f74 Mon Sep 17 00:00:00 2001
From: Johan Nyman
Date: Tue, 13 Aug 2024 07:56:09 +0200
Subject: [PATCH] chore: update webhid demo to support multiple connected
devices
---
packages/webhid-demo/public/index.html | 3 +-
packages/webhid-demo/src/app.ts | 148 +++++++++++++++----------
2 files changed, 93 insertions(+), 58 deletions(-)
diff --git a/packages/webhid-demo/public/index.html b/packages/webhid-demo/public/index.html
index f49cbe7..e7af962 100644
--- a/packages/webhid-demo/public/index.html
+++ b/packages/webhid-demo/public/index.html
@@ -26,7 +26,8 @@
-
+
Connected Devices:
+
diff --git a/packages/webhid-demo/src/app.ts b/packages/webhid-demo/src/app.ts
index 7897bd3..1b740a7 100644
--- a/packages/webhid-demo/src/app.ts
+++ b/packages/webhid-demo/src/app.ts
@@ -1,5 +1,7 @@
import { getOpenedXKeysPanels, requestXkeysPanels, setupXkeysPanel, XKeys } from 'xkeys-webhid'
+const connectedXkeys = new Set()
+
function appendLog(str: string) {
const logElm = document.getElementById('log')
if (logElm) {
@@ -7,88 +9,120 @@ function appendLog(str: string) {
}
}
-let currentXkeys: XKeys | null = null
-
async function openDevice(device: HIDDevice): Promise {
const xkeys = await setupXkeysPanel(device)
- currentXkeys = xkeys
+ connectedXkeys.add(xkeys)
+
+ const id = xkeys.info.name
- appendLog(`Connected to "${xkeys.info.name}"`)
+ appendLog(`${id}: Connected`)
xkeys.on('disconnected', () => {
- appendLog(`${xkeys.info.name} was disconnected`)
+ appendLog(`${id}: Disconnected`)
// Clean up stuff:
xkeys.removeAllListeners()
+
+ connectedXkeys.delete(xkeys)
+ updateDeviceList()
})
xkeys.on('error', (...errs) => {
- appendLog('X-keys error:' + errs.join(','))
+ appendLog(`${id}: X-keys error: ${errs.join(',')}`)
})
xkeys.on('down', (keyIndex: number) => {
- appendLog(`Button ${keyIndex} down`)
+ appendLog(`${id}: Button ${keyIndex} down`)
xkeys.setBacklight(keyIndex, 'blue')
})
xkeys.on('up', (keyIndex: number) => {
- appendLog(`Button ${keyIndex} up`)
+ appendLog(`${id}: Button ${keyIndex} up`)
xkeys.setBacklight(keyIndex, null)
})
xkeys.on('jog', (index, value) => {
- appendLog(`Jog #${index}: ${value}`)
+ appendLog(`${id}: Jog #${index}: ${value}`)
})
xkeys.on('joystick', (index, value) => {
- appendLog(`Joystick #${index}: ${JSON.stringify(value)}`)
+ appendLog(`${id}: Joystick #${index}: ${JSON.stringify(value)}`)
})
xkeys.on('shuttle', (index, value) => {
- appendLog(`Shuttle #${index}: ${value}`)
+ appendLog(`${id}: Shuttle #${index}: ${value}`)
})
xkeys.on('tbar', (index, value) => {
- appendLog(`T-bar #${index}: ${value}`)
+ appendLog(`${id}: T-bar #${index}: ${value}`)
})
+
+ updateDeviceList()
}
-window.addEventListener('load', () => {
- appendLog('Page loaded')
- // Attempt to open a previously selected device:
- getOpenedXKeysPanels()
- .then((devices) => {
- if (devices.length > 0) {
- appendLog(`"${devices[0].productName}" already granted in a previous session`)
- console.log(devices[0])
- openDevice(devices[0]).catch(console.error)
- }
- })
- .catch(console.error)
-})
-
-const consentButton = document.getElementById('consent-button')
-consentButton?.addEventListener('click', () => {
- if (currentXkeys) {
- appendLog('Closing device')
- currentXkeys.close().catch(console.error)
- currentXkeys = null
- }
- // Prompt for a device
-
- appendLog('Asking user for permissions...')
- requestXkeysPanels()
- .then((devices) => {
- if (devices.length === 0) {
- appendLog('No device was selected')
- return
- }
- appendLog(`Access granted to "${devices[0].productName}"`)
- openDevice(devices[0]).catch(console.error)
- })
- .catch((error) => {
- appendLog(`No device access granted: ${error}`)
- })
-})
-
-const closeButton = document.getElementById('close-button')
-closeButton?.addEventListener('click', () => {
- if (currentXkeys) {
- appendLog('Closing device')
- currentXkeys.close().catch(console.error)
- currentXkeys = null
+function initialize() {
+ window.addEventListener('load', () => {
+ appendLog('Page loaded')
+
+ if (!navigator.hid) {
+ appendLog('>>>>> WebHID not supported in this browser <<<<<')
+ return
+ }
+
+ // Attempt to open a previously selected device:
+ getOpenedXKeysPanels()
+ .then((devices) => {
+ for (const device of devices) {
+ appendLog(`"${device.productName}" already granted in a previous session`)
+ console.log(device)
+ openDevice(device).catch(appendLog)
+ }
+ })
+ .catch(console.error)
+ })
+
+ const consentButton = document.getElementById('consent-button')
+ consentButton?.addEventListener('click', () => {
+ // Prompt for a device
+
+ appendLog('Asking user for permissions...')
+ requestXkeysPanels()
+ .then((devices) => {
+ if (devices.length === 0) {
+ appendLog('No device was selected')
+ } else {
+ for (const device of devices) {
+ appendLog(`Access granted to "${device.productName}"`)
+ openDevice(device).catch(console.error)
+ }
+ }
+ })
+ .catch((error) => {
+ appendLog(`No device access granted: ${error}`)
+ })
+ })
+}
+
+function updateDeviceList() {
+ // Update the list of connected devices:
+
+ const container = document.getElementById('devices')
+ if (container) {
+ container.innerHTML = ''
+
+ if (connectedXkeys.size === 0) {
+ container.innerHTML = 'No devices connected'
+ } else {
+ connectedXkeys.forEach((xkeys) => {
+ const div = document.createElement('div')
+ div.innerHTML = `
+ ${xkeys.info.name}
+ `
+ const button = document.createElement('button')
+ button.innerText = 'Close device'
+ button.addEventListener('click', () => {
+ appendLog(xkeys.info.name + ' Closing device')
+ xkeys.close().catch(console.error)
+ // currentXkeys = null
+ })
+
+ container.appendChild(div)
+ })
+ }
}
-})
+}
+
+initialize()