Skip to content

Commit

Permalink
chore: update webhid demo to support multiple connected devices
Browse files Browse the repository at this point in the history
  • Loading branch information
nytamin committed Aug 13, 2024
1 parent 44179d3 commit a02236a
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 58 deletions.
3 changes: 2 additions & 1 deletion packages/webhid-demo/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ <h3>
<button href="#" id="consent-button">Select device</button>
</p>
<p>
<button href="#" id="close-button">Close device</button>
<p>Connected Devices:</p>
<p id="devices"></p>
</p>

<div id="log" style="white-space: pre; background: #ffffff; border: 1px solid grey;"></div>
Expand Down
148 changes: 91 additions & 57 deletions packages/webhid-demo/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,94 +1,128 @@
import { getOpenedXKeysPanels, requestXkeysPanels, setupXkeysPanel, XKeys } from 'xkeys-webhid'

const connectedXkeys = new Set<XKeys>()

function appendLog(str: string) {
const logElm = document.getElementById('log')
if (logElm) {
logElm.textContent = `${str}\n${logElm.textContent}`
}
}

let currentXkeys: XKeys | null = null

async function openDevice(device: HIDDevice): Promise<void> {
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 = '<i>No devices connected</i>'
} else {
connectedXkeys.forEach((xkeys) => {
const div = document.createElement('div')
div.innerHTML = `
<b>${xkeys.info.name}</b>
`
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()

0 comments on commit a02236a

Please sign in to comment.