Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

111 lines
2.8 KiB
TypeScript

import type { KeyboardEvent as ReactKeyboardEvent, RefObject } from "react";
import type { Editor } from "@tiptap/core";
import { isAgentRichTextImeComposing } from "./agentRichTextIme";
import { moveSelectionOverCaretAnchor } from "./agentRichTextEditorSupport";
export function handleAgentRichTextKeyDownCapture(
event: ReactKeyboardEvent<HTMLDivElement>,
input: {
disabled: boolean;
editorRef: RefObject<Editor | null>;
onKeyDownForPaletteRef: RefObject<
((event: KeyboardEvent) => boolean) | undefined
>;
onHistoryNavigationRef: RefObject<
((direction: "older" | "newer") => boolean) | undefined
>;
onSubmitGuidanceRef: RefObject<(() => void) | undefined>;
onSubmitRef: RefObject<() => void>;
submitOnEnter: boolean;
}
): void {
if (isAgentRichTextImeComposing(event.nativeEvent)) {
return;
}
if (input.disabled) {
return;
}
if (input.onKeyDownForPaletteRef.current?.(event.nativeEvent)) {
event.preventDefault();
event.stopPropagation();
return;
}
if (
(event.key === "ArrowUp" || event.key === "ArrowDown") &&
!event.shiftKey &&
!event.metaKey &&
!event.ctrlKey &&
!event.altKey
) {
const currentEditor = input.editorRef.current;
const selection = currentEditor?.state.selection;
const documentSize = currentEditor?.state.doc.content.size ?? 0;
const isAtDocumentBoundary =
Boolean(selection?.empty) &&
(selection?.from === 1 || selection?.to === documentSize - 1);
if (
currentEditor &&
!currentEditor.isDestroyed &&
isAtDocumentBoundary &&
input.onHistoryNavigationRef.current?.(
event.key === "ArrowUp" ? "older" : "newer"
)
) {
event.preventDefault();
event.stopPropagation();
return;
}
}
if (
(event.key === "ArrowLeft" || event.key === "ArrowRight") &&
!event.shiftKey &&
!event.metaKey &&
!event.ctrlKey &&
!event.altKey
) {
const currentEditor = input.editorRef.current;
if (
currentEditor &&
!currentEditor.isDestroyed &&
moveSelectionOverCaretAnchor(
currentEditor.state,
(transaction) => currentEditor.view.dispatch(transaction),
event.key
)
) {
event.preventDefault();
event.stopPropagation();
return;
}
}
if (
event.key === "Enter" &&
(event.metaKey || event.ctrlKey) &&
!event.shiftKey &&
!event.altKey
) {
event.preventDefault();
event.stopPropagation();
if (!input.submitOnEnter) {
return;
}
input.onSubmitGuidanceRef.current?.();
return;
}
if (
event.key !== "Enter" ||
event.shiftKey ||
event.metaKey ||
event.ctrlKey ||
event.altKey
) {
return;
}
event.preventDefault();
event.stopPropagation();
if (!input.submitOnEnter) {
return;
}
input.onSubmitRef.current();
}