/** * TASKMATE - Keyboard Shortcuts Module * ===================================== * Global keyboard shortcuts (only non-browser-conflicting) */ import store from './store.js'; import { $ } from './utils.js'; class ShortcutsManager { constructor() { this.shortcuts = new Map(); this.isEnabled = true; this.registerDefaultShortcuts(); this.bindEvents(); } bindEvents() { document.addEventListener('keydown', (e) => this.handleKeydown(e)); } handleKeydown(e) { // Don't handle shortcuts when typing in inputs if (this.isInputFocused()) return; // Don't handle when modals are open (except escape) if (store.get('openModals').length > 0 && e.key !== 'Escape') return; // Don't handle when disabled if (!this.isEnabled) return; const combo = this.getKeyCombo(e); const handler = this.shortcuts.get(combo); if (handler) { e.preventDefault(); handler(e); } } getKeyCombo(e) { const parts = []; if (e.ctrlKey || e.metaKey) parts.push('Ctrl'); if (e.altKey) parts.push('Alt'); if (e.shiftKey) parts.push('Shift'); // Get the key let key = e.key; if (key === ' ') key = 'Space'; if (key.length === 1) key = key.toUpperCase(); parts.push(key); return parts.join('+'); } isInputFocused() { const activeElement = document.activeElement; const tagName = activeElement?.tagName.toLowerCase(); const isContentEditable = activeElement?.contentEditable === 'true'; return ['input', 'textarea', 'select'].includes(tagName) || isContentEditable; } // ===================== // SHORTCUT REGISTRATION // ===================== register(combo, handler, description = '') { this.shortcuts.set(combo, handler); // Store description for help display handler.description = description; } unregister(combo) { this.shortcuts.delete(combo); } enable() { this.isEnabled = true; } disable() { this.isEnabled = false; } // ===================== // DEFAULT SHORTCUTS // ===================== registerDefaultShortcuts() { // Only Escape - close modals (doesn't conflict with browser) this.register('Escape', () => this.handleEscape(), 'Schließen / Abbrechen'); } // ===================== // SHORTCUT HANDLERS // ===================== handleEscape() { const openModals = store.get('openModals'); if (openModals.length > 0) { // Close the topmost modal const topModal = openModals[openModals.length - 1]; window.dispatchEvent(new CustomEvent('modal:close', { detail: { modalId: topModal } })); } else { // Clear selection store.clearSelection(); } } showHelp() { // No longer needed - shortcuts removed } // ===================== // HELP DISPLAY // ===================== getShortcutsList() { // Minimal shortcuts that don't conflict with browser return { actions: { title: 'Aktionen', shortcuts: [ { combo: 'Escape', description: 'Dialog schließen / Auswahl aufheben' } ] } }; } } // Create and export singleton const shortcutsManager = new ShortcutsManager(); export default shortcutsManager;