Z ZPI 文档 v0.3.8
介绍页

源码

packages/desktop/src/renderer/use-overlay-shortcut.ts

typescript56 行查看原文
import { useEffect, useRef } from "react";
import { type ShortcutCommand, shortcutForEvent } from "../shared/shortcuts.ts";
import { hasVisibleShortcutBlocker } from "./shortcut-context.ts";
import { useStore } from "./store.ts";

/** An open layer owns only its own shortcut, including keys from portalled submenus. */
export function useOverlayShortcut(command: ShortcutCommand, open: boolean, close: () => void) {
  const callback = useRef(close);
  callback.current = close;
  useEffect(() => {
    if (!open) return;
    let composing = false;
    const begin = () => {
      composing = true;
    };
    const end = () => {
      composing = false;
    };
    const keydown = (event: KeyboardEvent) => {
      const settings = useStore.getState().settings?.shortcuts;
      if (!settings || event.defaultPrevented || composing || event.isComposing || event.keyCode === 229)
        return;
      if (!(event.target instanceof Element) || !event.target.closest(`[data-shortcut-owner="${command}"]`))
        return;
      if (hasVisibleShortcutBlocker('.settings-screen, [data-shortcut-recording="true"]')) return;
      if (
        shortcutForEvent(
          {
            key: event.key,
            code: event.code,
            ctrlKey: event.ctrlKey,
            metaKey: event.metaKey,
            altKey: event.altKey,
            shiftKey: event.shiftKey,
            repeat: false,
          },
          window.zpi.platform,
          settings,
        ) !== command
      )
        return;
      event.preventDefault();
      event.stopPropagation();
      if (!event.repeat) callback.current();
    };
    window.addEventListener("keydown", keydown, true);
    window.addEventListener("compositionstart", begin, true);
    window.addEventListener("compositionend", end, true);
    return () => {
      window.removeEventListener("keydown", keydown, true);
      window.removeEventListener("compositionstart", begin, true);
      window.removeEventListener("compositionend", end, true);
    };
  }, [command, open]);
}