mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 20:03:37 +00:00
refactor(store): Extract utility functions into store/utils/
Move pure utility functions from app-store.ts and type files into dedicated utils modules for better separation of concerns: - theme-utils.ts: Theme and font storage utilities - shortcut-utils.ts: Keyboard shortcut parsing/formatting - usage-utils.ts: Usage limit checking All utilities are re-exported from store/utils/index.ts and app-store.ts maintains backward compatibility for existing imports. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
117
apps/ui/src/store/utils/shortcut-utils.ts
Normal file
117
apps/ui/src/store/utils/shortcut-utils.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import type { ShortcutKey, KeyboardShortcuts } from '../types/ui-types';
|
||||
|
||||
// Helper to parse shortcut string to ShortcutKey object
|
||||
export function parseShortcut(shortcut: string | undefined | null): ShortcutKey {
|
||||
if (!shortcut) return { key: '' };
|
||||
const parts = shortcut.split('+').map((p) => p.trim());
|
||||
const result: ShortcutKey = { key: parts[parts.length - 1] };
|
||||
|
||||
// Normalize common OS-specific modifiers (Cmd/Ctrl/Win/Super symbols) into cmdCtrl
|
||||
for (let i = 0; i < parts.length - 1; i++) {
|
||||
const modifier = parts[i].toLowerCase();
|
||||
if (modifier === 'shift') result.shift = true;
|
||||
else if (
|
||||
modifier === 'cmd' ||
|
||||
modifier === 'ctrl' ||
|
||||
modifier === 'win' ||
|
||||
modifier === 'super' ||
|
||||
modifier === '⌘' ||
|
||||
modifier === '^' ||
|
||||
modifier === '⊞' ||
|
||||
modifier === '◆'
|
||||
)
|
||||
result.cmdCtrl = true;
|
||||
else if (modifier === 'alt' || modifier === 'opt' || modifier === 'option' || modifier === '⌥')
|
||||
result.alt = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Helper to format ShortcutKey to display string
|
||||
export function formatShortcut(shortcut: string | undefined | null, forDisplay = false): string {
|
||||
if (!shortcut) return '';
|
||||
const parsed = parseShortcut(shortcut);
|
||||
const parts: string[] = [];
|
||||
|
||||
// Prefer User-Agent Client Hints when available; fall back to legacy
|
||||
const platform: 'darwin' | 'win32' | 'linux' = (() => {
|
||||
if (typeof navigator === 'undefined') return 'linux';
|
||||
|
||||
const uaPlatform = (
|
||||
navigator as Navigator & { userAgentData?: { platform?: string } }
|
||||
).userAgentData?.platform?.toLowerCase?.();
|
||||
const legacyPlatform = navigator.platform?.toLowerCase?.();
|
||||
const platformString = uaPlatform || legacyPlatform || '';
|
||||
|
||||
if (platformString.includes('mac')) return 'darwin';
|
||||
if (platformString.includes('win')) return 'win32';
|
||||
return 'linux';
|
||||
})();
|
||||
|
||||
// Primary modifier - OS-specific
|
||||
if (parsed.cmdCtrl) {
|
||||
if (forDisplay) {
|
||||
parts.push(platform === 'darwin' ? '⌘' : platform === 'win32' ? '⊞' : '◆');
|
||||
} else {
|
||||
parts.push(platform === 'darwin' ? 'Cmd' : platform === 'win32' ? 'Win' : 'Super');
|
||||
}
|
||||
}
|
||||
|
||||
// Alt/Option
|
||||
if (parsed.alt) {
|
||||
parts.push(
|
||||
forDisplay ? (platform === 'darwin' ? '⌥' : 'Alt') : platform === 'darwin' ? 'Opt' : 'Alt'
|
||||
);
|
||||
}
|
||||
|
||||
// Shift
|
||||
if (parsed.shift) {
|
||||
parts.push(forDisplay ? '⇧' : 'Shift');
|
||||
}
|
||||
|
||||
parts.push(parsed.key.toUpperCase());
|
||||
|
||||
// Add spacing when displaying symbols
|
||||
return parts.join(forDisplay ? ' ' : '+');
|
||||
}
|
||||
|
||||
// Default keyboard shortcuts
|
||||
export const DEFAULT_KEYBOARD_SHORTCUTS: KeyboardShortcuts = {
|
||||
// Navigation
|
||||
board: 'K',
|
||||
graph: 'H',
|
||||
agent: 'A',
|
||||
spec: 'D',
|
||||
context: 'C',
|
||||
memory: 'Y',
|
||||
settings: 'S',
|
||||
projectSettings: 'Shift+S',
|
||||
terminal: 'T',
|
||||
ideation: 'I',
|
||||
notifications: 'X',
|
||||
githubIssues: 'G',
|
||||
githubPrs: 'R',
|
||||
|
||||
// UI
|
||||
toggleSidebar: '`',
|
||||
|
||||
// Actions
|
||||
// Note: Some shortcuts share the same key (e.g., "N" for addFeature, newSession)
|
||||
// This is intentional as they are context-specific and only active in their respective views
|
||||
addFeature: 'N', // Only active in board view
|
||||
addContextFile: 'N', // Only active in context view
|
||||
startNext: 'G', // Only active in board view
|
||||
newSession: 'N', // Only active in agent view
|
||||
openProject: 'O', // Global shortcut
|
||||
projectPicker: 'P', // Global shortcut
|
||||
cyclePrevProject: 'Q', // Global shortcut
|
||||
cycleNextProject: 'E', // Global shortcut
|
||||
|
||||
// Terminal shortcuts (only active in terminal view)
|
||||
// Using Alt modifier to avoid conflicts with both terminal signals AND browser shortcuts
|
||||
splitTerminalRight: 'Alt+D',
|
||||
splitTerminalDown: 'Alt+S',
|
||||
closeTerminal: 'Alt+W',
|
||||
newTerminalTab: 'Alt+T',
|
||||
};
|
||||
Reference in New Issue
Block a user