From fdd8ecc79ddc302c9579d2260faac1a4f1e2f44e Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Thu, 3 Aug 2023 20:46:03 -0400 Subject: [PATCH] Add find and replace hooks for desktop app --- app/components/Input.tsx | 1 + app/editor/components/FindAndReplace.tsx | 44 +++++++++++++++++++++--- app/typings/window.d.ts | 10 ++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/app/components/Input.tsx b/app/components/Input.tsx index 6483a0ca9..251d0830e 100644 --- a/app/components/Input.tsx +++ b/app/components/Input.tsx @@ -177,6 +177,7 @@ function Input( labelHidden, onFocus, onBlur, + onRequestSubmit, children, ...rest } = props; diff --git a/app/editor/components/FindAndReplace.tsx b/app/editor/components/FindAndReplace.tsx index f2b8032f9..fe944fdec 100644 --- a/app/editor/components/FindAndReplace.tsx +++ b/app/editor/components/FindAndReplace.tsx @@ -20,6 +20,7 @@ import { ResizingHeightContainer } from "~/components/ResizingHeightContainer"; import Tooltip from "~/components/Tooltip"; import useKeyDown from "~/hooks/useKeyDown"; import useOnClickOutside from "~/hooks/useOnClickOutside"; +import Desktop from "~/utils/Desktop"; import { altDisplay, isModKey, metaDisplay } from "~/utils/keyboard"; import { useEditor } from "./EditorContext"; @@ -39,14 +40,40 @@ export default function FindAndReplace({ readOnly }: Props) { const [regexEnabled, setRegex] = React.useState(false); const [searchTerm, setSearchTerm] = React.useState(""); const [replaceTerm, setReplaceTerm] = React.useState(""); - const popover = usePopoverState(); + const { show } = popover; + // Hooks for desktop app menu items + React.useEffect(() => { + if (!Desktop.bridge) { + return; + } + if ("onFindInPage" in Desktop.bridge) { + Desktop.bridge.onFindInPage(() => { + selectionRef.current = window.getSelection()?.toString(); + show(); + }); + } + if ("onReplaceInPage" in Desktop.bridge) { + Desktop.bridge.onReplaceInPage(() => { + setShowReplace(true); + show(); + }); + } + }, [show]); + + // Close handlers useKeyDown("Escape", popover.hide); useOnClickOutside(popover.unstable_referenceRef, popover.hide); + // Keyboard shortcuts useKeyDown( - (ev) => isModKey(ev) && !popover.visible && ev.code === "KeyF", + (ev) => + isModKey(ev) && + !popover.visible && + ev.code === "KeyF" && + // Handler is through AppMenu on desktop app + !Desktop.isElectron(), (ev) => { ev.preventDefault(); selectionRef.current = window.getSelection()?.toString(); @@ -72,6 +99,7 @@ export default function FindAndReplace({ readOnly }: Props) { { allowInInput: true } ); + // Callbacks const handleMore = React.useCallback( () => setShowReplace((state) => !state), [] @@ -122,18 +150,24 @@ export default function FindAndReplace({ readOnly }: Props) { const handleReplace = React.useCallback( (ev) => { + if (readOnly) { + return; + } ev.preventDefault(); editor.commands.replace({ text: replaceTerm }); }, - [editor.commands, replaceTerm] + [editor.commands, readOnly, replaceTerm] ); const handleReplaceAll = React.useCallback( (ev) => { + if (readOnly) { + return; + } ev.preventDefault(); editor.commands.replaceAll({ text: replaceTerm }); }, - [editor.commands, replaceTerm] + [editor.commands, readOnly, replaceTerm] ); const handleChangeFind = React.useCallback( @@ -281,7 +315,7 @@ export default function FindAndReplace({ readOnly }: Props) { )} - {showReplace && ( + {showReplace && !readOnly && ( void; + + /** + * Registers a callback to be called when the application wants to open the find in page dialog. + */ + onFindInPage: (callback: () => void) => void; + + /** + * Registers a callback to be called when the application wants to open the replace in page dialog. + */ + onReplaceInPage: (callback: () => void) => void; }; } }