Files
KGStudio/src/util/osUtil.ts
T
2025-08-11 18:37:21 -07:00

110 lines
3.5 KiB
TypeScript

/**
* OS utility functions for platform detection and keyboard shortcuts
*/
import React from 'react';
/**
* Detects the current operating system platform
* @returns The platform name
*/
export const getPlatform = (): 'mac' | 'windows' | 'linux' | 'unknown' => {
const userAgent = navigator.userAgent.toLowerCase();
const platform = navigator.platform.toLowerCase();
if (platform.includes('mac') || userAgent.includes('mac')) {
return 'mac';
} else if (platform.includes('win') || userAgent.includes('win')) {
return 'windows';
} else if (platform.includes('linux') || userAgent.includes('linux')) {
return 'linux';
}
return 'unknown';
};
/**
* Checks if the appropriate modifier key is pressed based on the current platform
* On Mac: checks for metaKey (CMD)
* On Windows/Linux: checks for ctrlKey (CTRL)
* @param event - The keyboard or mouse event (both native and React events)
* @returns true if the platform-appropriate modifier key is pressed
*/
export const isModifierKeyPressed = (event: KeyboardEvent | MouseEvent | React.KeyboardEvent | React.MouseEvent): boolean => {
const platform = getPlatform();
if (platform === 'mac') {
return event.metaKey;
} else {
// Windows, Linux, or unknown - use Ctrl key
return event.ctrlKey;
}
};
/**
* Gets the display name of the modifier key for the current platform
* @returns The display name (e.g., "Cmd" for Mac, "Ctrl" for others)
*/
export const getModifierKeyDisplayName = (): string => {
const platform = getPlatform();
return platform === 'mac' ? 'Cmd' : 'Ctrl';
};
/**
* Resolves a keyboard shortcut string by replacing 'ctrl' with the appropriate modifier for the current platform
* @param shortcut - The shortcut string (e.g., "ctrl+z", "ctrl+shift+z")
* @returns The resolved shortcut with platform-specific modifiers
*/
export const resolveKeyboardShortcut = (shortcut: string): string => {
const platform = getPlatform();
if (platform === 'mac') {
// Replace 'ctrl' with 'cmd' on Mac
return shortcut.replace(/\bctrl\b/gi, 'cmd');
}
return shortcut;
};
/**
* Checks if a keyboard event matches a given shortcut string
* @param event - The keyboard event
* @param shortcut - The shortcut string (e.g., "ctrl+z", "ctrl+shift+z")
* @returns true if the event matches the shortcut
*/
export const matchesKeyboardShortcut = (event: KeyboardEvent | React.KeyboardEvent, shortcut: string): boolean => {
const normalizedShortcut = shortcut.toLowerCase();
const keys = normalizedShortcut.split('+');
// Extract the main key (last part)
const mainKey = keys[keys.length - 1];
// Handle special key mappings
let eventKey = event.key.toLowerCase();
if (eventKey === ' ') {
eventKey = 'space';
}
if (eventKey !== mainKey) {
return false;
}
// Check modifiers
const hasCtrl = keys.includes('ctrl');
const hasShift = keys.includes('shift');
const hasAlt = keys.includes('alt');
const hasCmd = keys.includes('cmd');
const platform = getPlatform();
// Handle platform-specific modifier checking
let expectedCtrlOrCmd = false;
if (platform === 'mac') {
expectedCtrlOrCmd = hasCmd || hasCtrl; // On Mac, both 'ctrl' and 'cmd' should map to metaKey
} else {
expectedCtrlOrCmd = hasCtrl; // On other platforms, only 'ctrl' maps to ctrlKey
}
const actualCtrlOrCmd = platform === 'mac' ? event.metaKey : event.ctrlKey;
return actualCtrlOrCmd === expectedCtrlOrCmd &&
event.shiftKey === hasShift &&
event.altKey === hasAlt;
};