Files
AIHostingTycoon/apps/web/src/hooks/useKeyboardShortcuts.ts
T
josh c1cc70eeb9
Balance Check / balance-simulation (pull_request) Successful in 38s
Balance Check / multi-run-balance (pull_request) Successful in 13m44s
Rename AI Tycoon to Token Empire across entire codebase
Full rebrand: UI display text, package scope (@ai-tycoon/* -> @token-empire/*),
localStorage keys, Docker/CI image paths, database names, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 21:04:07 -04:00

71 lines
1.8 KiB
TypeScript

import { useEffect } from 'react';
import { useGameStore, type ActivePage } from '@/store';
import type { GameSpeed } from '@token-empire/shared';
const PAGE_SHORTCUTS: Record<string, ActivePage> = {
d: 'dashboard',
i: 'infrastructure',
r: 'research',
m: 'models',
k: 'market',
f: 'finance',
t: 'talent',
s: 'settings',
};
export function useKeyboardShortcuts() {
useEffect(() => {
let gPressed = false;
let gTimer: ReturnType<typeof setTimeout>;
const handler = (e: KeyboardEvent) => {
if (e.ctrlKey && e.key === 'd') {
e.preventDefault();
window.dispatchEvent(new Event('toggle-dev-menu'));
return;
}
const target = e.target as HTMLElement;
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT') return;
const store = useGameStore.getState();
if (gPressed) {
gPressed = false;
clearTimeout(gTimer);
const page = PAGE_SHORTCUTS[e.key];
if (page) {
e.preventDefault();
store.setActivePage(page);
}
return;
}
switch (e.key) {
case ' ':
e.preventDefault();
store.togglePause();
break;
case '1':
store.setGameSpeed(1 as GameSpeed);
break;
case '2':
store.setGameSpeed(2 as GameSpeed);
break;
case '3':
store.setGameSpeed(5 as GameSpeed);
break;
case 'g':
gPressed = true;
gTimer = setTimeout(() => { gPressed = false; }, 500);
break;
}
};
window.addEventListener('keydown', handler);
return () => {
window.removeEventListener('keydown', handler);
clearTimeout(gTimer);
};
}, []);
}