Add find and replace hooks for desktop app

This commit is contained in:
Tom Moor
2023-08-03 20:46:03 -04:00
parent 7c15d03b50
commit fdd8ecc79d
3 changed files with 50 additions and 5 deletions

View File

@@ -177,6 +177,7 @@ function Input(
labelHidden,
onFocus,
onBlur,
onRequestSubmit,
children,
...rest
} = props;

View File

@@ -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) {
)}
</Flex>
<ResizingHeightContainer>
{showReplace && (
{showReplace && !readOnly && (
<Flex gap={8}>
<StyledInput
maxLength={255}

View File

@@ -96,6 +96,16 @@ declare global {
* Go forward in history, if possible
*/
goForward: () => 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;
};
}
}