// Handle lame OS key input event behavior. See: https://mzl.la/2Ob0WQE // Also "up" all keys on blur. export default function addKeyListener(target, listener) { let keysDown = {}; let keyUpDelays = {}; function setAllKeysUp() { for (const i in keyUpDelays) { clearTimeout(keyUpDelays[i]); } keyUpDelays = {}; for (const key in keysDown) { listener({type: 'keyUp', payload: key}); } keysDown = {}; } function onBlur() { setAllKeysUp(); } function onKeyDown(event) { const {key} = event; if (keysDown[key]) { if (keyUpDelays[key]) { clearTimeout(keyUpDelays[key]); delete keyUpDelays[key]; } return; } keysDown[key] = true; listener({event, type: 'keyDown', payload: key}); } function onKeyUp(event) { const {key} = event; keyUpDelays[key] = setTimeout(() => { delete keyUpDelays[key]; delete keysDown[key]; listener({event, type: 'keyUp', payload: key}); }, 20); } window.addEventListener('blur', onBlur); window.addEventListener('keyup', onKeyUp); target.addEventListener('keydown', onKeyDown); return () => { setAllKeysUp(); target.removeEventListener('keydown', onKeyDown); window.removeEventListener('keyup', onKeyUp); window.removeEventListener('blur', onBlur); }; }