UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

193 lines 6.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeyboardHandler = void 0; class KeyboardHandler { constructor() { this.shortcuts = new Map(); this.keySequences = new Map(); this.currentSequence = []; this.SEQUENCE_TIMEOUT_MS = 1000; } static normalizeKeyEvent(rawKey, rawCh) { if (!rawKey) { return { key: '', shift: false, ctrl: false, alt: false, meta: false, ch: rawCh || '', }; } return { key: rawKey.name || rawKey.key || '', shift: !!rawKey.shift, ctrl: !!rawKey.ctrl, alt: !!rawKey.meta || !!rawKey.alt, meta: !!rawKey.meta, full: rawKey.full || '', ch: rawCh || rawKey.ch || '', }; } static buildShortcutKey(event) { const parts = []; if (event.ctrl) parts.push('ctrl'); if (event.alt) parts.push('alt'); if (event.shift) parts.push('shift'); if (event.meta) parts.push('meta'); if (event.key) { parts.push(event.key.toLowerCase()); } return parts.join('+'); } static parseShortcutKey(shortcut) { const parts = shortcut.toLowerCase().split('+'); const key = parts[parts.length - 1] || ''; return { ctrl: parts.includes('ctrl') || parts.includes('c'), alt: parts.includes('alt') || parts.includes('a'), shift: parts.includes('shift') || parts.includes('s'), meta: parts.includes('meta') || parts.includes('m'), key, }; } static matchesShortcut(event, shortcut) { const expected = KeyboardHandler.parseShortcutKey(shortcut); const actual = KeyboardHandler.buildShortcutKey(event); const expectedKey = KeyboardHandler.buildShortcutKey({ key: expected.key, ctrl: expected.ctrl, alt: expected.alt, shift: expected.shift, meta: expected.meta, }); return actual === expectedKey; } registerShortcut(config) { const key = config.key.toLowerCase(); this.shortcuts.set(key, config); } unregisterShortcut(key) { this.shortcuts.delete(key.toLowerCase()); } findMatchingShortcut(event) { for (const [key, config] of this.shortcuts) { if (KeyboardHandler.matchesShortcut(event, key)) { return config; } } return this.checkSequenceMatch(event); } registerKeySequence(sequence, action) { const key = sequence.join(' '); this.keySequences.set(key, sequence); this.registerShortcut({ key, description: `Key sequence: ${sequence.join(' ')}`, action, global: true, }); } checkSequenceMatch(event) { const eventKey = event.key.toLowerCase(); this.currentSequence.push(eventKey); if (this.sequenceTimeout) { clearTimeout(this.sequenceTimeout); } this.sequenceTimeout = setTimeout(() => { this.currentSequence = []; }, this.SEQUENCE_TIMEOUT_MS); const currentSequenceKey = this.currentSequence.join(' '); for (const [sequenceKey, _sequence] of this.keySequences) { if (sequenceKey === currentSequenceKey) { this.currentSequence = []; if (this.sequenceTimeout) { clearTimeout(this.sequenceTimeout); } return this.shortcuts.get(sequenceKey); } else if (sequenceKey.startsWith(currentSequenceKey + ' ')) { return undefined; } } this.currentSequence = []; if (this.sequenceTimeout) { clearTimeout(this.sequenceTimeout); } return undefined; } static isNavigationKey(key) { const navigationKeys = [ 'up', 'down', 'left', 'right', 'home', 'end', 'pageup', 'pagedown', 'tab', 'enter', 'escape', 'space', ]; return navigationKeys.includes(key.toLowerCase()); } static isFunctionKey(key) { return /^f\d+$/.test(key.toLowerCase()); } static isPrintableKey(event) { if (KeyboardHandler.isFunctionKey(event.key) || KeyboardHandler.isNavigationKey(event.key) || event.ctrl || event.alt || event.meta) { return false; } return event.ch !== undefined && event.ch.length === 1; } static getKeyDescription(event) { const parts = []; if (event.ctrl) parts.push('Ctrl'); if (event.alt) parts.push('Alt'); if (event.shift) parts.push('Shift'); if (event.meta) parts.push('Meta'); let keyName = event.key; if (keyName) { keyName = keyName.charAt(0).toUpperCase() + keyName.slice(1); const keyMappings = { 'Escape': 'Esc', 'Enter': '↵', 'Tab': '⇥', 'Space': '␣', 'Up': '↑', 'Down': '↓', 'Left': '←', 'Right': '→', 'Pageup': 'PgUp', 'Pagedown': 'PgDn', }; keyName = keyMappings[keyName] || keyName; } parts.push(keyName); return parts.join('+'); } getShortcuts() { return Array.from(this.shortcuts.values()); } getShortcutsByContext(context) { return Array.from(this.shortcuts.values()) .filter(shortcut => shortcut.context === context || shortcut.global); } clear() { this.shortcuts.clear(); this.keySequences.clear(); this.currentSequence = []; if (this.sequenceTimeout) { clearTimeout(this.sequenceTimeout); this.sequenceTimeout = undefined; } } destroy() { this.clear(); } } exports.KeyboardHandler = KeyboardHandler; //# sourceMappingURL=keyboard-handler.js.map