mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-28 08:08:02 +00:00
153 lines
6.2 KiB
TypeScript
153 lines
6.2 KiB
TypeScript
import { normalizeShortcutSettings, type ShortcutActionId, type ShortcutSettings } from "@/lib/shortcutRegistry";
|
|
|
|
export interface ShortcutLikeEvent {
|
|
key: string;
|
|
metaKey?: boolean;
|
|
ctrlKey?: boolean;
|
|
altKey?: boolean;
|
|
shiftKey?: boolean;
|
|
isComposing?: boolean;
|
|
}
|
|
|
|
function normalizeKey(key: string): string {
|
|
if (key === " ") return "Space";
|
|
return key.length === 1 ? key.toLowerCase() : key;
|
|
}
|
|
|
|
function shortcutKeyName(key: string): string | null {
|
|
if (key === " ") return "Space";
|
|
if (["Control", "Meta", "Shift", "Alt"].includes(key)) return null;
|
|
if (key.length === 1) return key.toUpperCase();
|
|
return key;
|
|
}
|
|
|
|
export function eventToShortcut(event: ShortcutLikeEvent): string | null {
|
|
if (event.isComposing) return null;
|
|
|
|
const key = shortcutKeyName(event.key);
|
|
if (!key) return null;
|
|
|
|
const hasModifier = !!event.metaKey || !!event.ctrlKey || !!event.altKey || !!event.shiftKey;
|
|
if (!hasModifier && key.length === 1) return null;
|
|
|
|
const parts: string[] = [];
|
|
if (event.shiftKey) parts.push("Shift");
|
|
if (event.metaKey || event.ctrlKey) parts.push("Mod");
|
|
if (event.altKey) parts.push("Alt");
|
|
parts.push(key);
|
|
return parts.join("+");
|
|
}
|
|
|
|
export function matchesShortcut(event: ShortcutLikeEvent, shortcut: string): boolean {
|
|
if (event.isComposing || !shortcut) return false;
|
|
const parts = shortcut.split("+");
|
|
const key = parts[parts.length - 1] ?? "";
|
|
const modifiers = new Set(parts.slice(0, -1));
|
|
const usesMod = modifiers.has("Mod");
|
|
const usesMeta = modifiers.has("Meta");
|
|
const usesCtrl = modifiers.has("Ctrl");
|
|
|
|
if (usesMod) {
|
|
if (!event.metaKey && !event.ctrlKey) return false;
|
|
} else {
|
|
if (!!event.metaKey !== usesMeta) return false;
|
|
if (!!event.ctrlKey !== usesCtrl) return false;
|
|
}
|
|
|
|
if (!!event.altKey !== modifiers.has("Alt")) return false;
|
|
if (!!event.shiftKey !== modifiers.has("Shift")) return false;
|
|
return normalizeKey(event.key) === normalizeKey(key);
|
|
}
|
|
|
|
function actionShortcut(actionId: ShortcutActionId, shortcuts?: Partial<ShortcutSettings>): string {
|
|
return normalizeShortcutSettings(shortcuts)[actionId];
|
|
}
|
|
|
|
export function isExecuteSqlShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("executeSql", shortcuts));
|
|
}
|
|
|
|
export function isCloseTabShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("closeTab", shortcuts));
|
|
}
|
|
|
|
export function isNewQueryShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("newQuery", shortcuts));
|
|
}
|
|
|
|
export function isOpenSettingsShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("openSettings", shortcuts));
|
|
}
|
|
|
|
export function isFocusSearchShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("focusSearch", shortcuts));
|
|
}
|
|
|
|
export function isRefreshDataShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("refreshData", shortcuts));
|
|
}
|
|
|
|
export function isModRShortcut(event: ShortcutLikeEvent): boolean {
|
|
return matchesShortcut(event, "Mod+R");
|
|
}
|
|
|
|
export function isZoomInShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
if (matchesShortcut(event, actionShortcut("zoomInUi", shortcuts))) return true;
|
|
if (event.isComposing || event.altKey) return false;
|
|
if (!event.metaKey && !event.ctrlKey) return false;
|
|
return normalizeKey(event.key) === "NumpadAdd" && !event.shiftKey;
|
|
}
|
|
|
|
export function isZoomOutShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
if (matchesShortcut(event, actionShortcut("zoomOutUi", shortcuts))) return true;
|
|
if (event.isComposing || event.altKey) return false;
|
|
if (!event.metaKey && !event.ctrlKey) return false;
|
|
return normalizeKey(event.key) === "NumpadSubtract" && !event.shiftKey;
|
|
}
|
|
|
|
export function isResetZoomShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
if (matchesShortcut(event, actionShortcut("resetUiZoom", shortcuts))) return true;
|
|
if (event.isComposing || event.altKey || event.shiftKey) return false;
|
|
if (!event.metaKey && !event.ctrlKey) return false;
|
|
return normalizeKey(event.key) === "Numpad0";
|
|
}
|
|
|
|
export function isToggleTransposeShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("toggleTranspose", shortcuts));
|
|
}
|
|
|
|
export function isSaveShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("saveSql", shortcuts));
|
|
}
|
|
|
|
export function isAcceptCompletionShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("acceptCompletion", shortcuts));
|
|
}
|
|
|
|
export function isObjectSourceSaveShortcutTarget(target: { closest(selector: string): unknown } | null | undefined): boolean {
|
|
return !!target?.closest("[data-object-source-editor], [data-object-source-preview]");
|
|
}
|
|
|
|
export function isCopyCurrentRowShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("copyCurrentRow", shortcuts));
|
|
}
|
|
|
|
export function isDeleteCurrentRowShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("deleteCurrentRow", shortcuts));
|
|
}
|
|
|
|
export function isCancelSearchShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("cancelSearch", shortcuts));
|
|
}
|
|
|
|
export function isToggleSidebarShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
|
return matchesShortcut(event, actionShortcut("toggleSidebar", shortcuts));
|
|
}
|
|
|
|
export function isBrowserReloadShortcut(event: ShortcutLikeEvent): boolean {
|
|
if (event.isComposing || event.altKey) return false;
|
|
const key = normalizeKey(event.key);
|
|
if (key === "F5") return true;
|
|
return key === "r" && (!!event.metaKey || !!event.ctrlKey);
|
|
}
|