2022-08-16 21:11:16 +00:00
|
|
|
|
"use babel";
|
|
|
|
|
|
|
|
|
|
import React, { useEffect, useCallback, useRef, useLayoutEffect } from "react";
|
2022-08-22 12:20:24 +00:00
|
|
|
|
import Option from "./command.js";
|
2022-08-23 03:40:41 +00:00
|
|
|
|
import Application from "../commands/application.js";
|
|
|
|
|
import Core from "../commands/core.js";
|
|
|
|
|
import NoteTags from "../commands/notetagsbar.js";
|
|
|
|
|
import Formatting from "../commands/formatting.js";
|
2022-08-16 21:11:16 +00:00
|
|
|
|
import { logger, useModal } from "inkdrop";
|
2022-08-22 12:20:24 +00:00
|
|
|
|
import useArrowKeyNavigation from "../navigation/hook.js";
|
2022-08-16 21:11:16 +00:00
|
|
|
|
|
|
|
|
|
const CommandPalette = (props) => {
|
2022-08-23 03:40:41 +00:00
|
|
|
|
const Commands = [...Formatting, ...Application, ...Core, ...NoteTags];
|
|
|
|
|
|
2022-08-16 21:11:16 +00:00
|
|
|
|
const modal = useModal();
|
|
|
|
|
const { Dialog } = inkdrop.components.classes;
|
2022-08-22 12:20:24 +00:00
|
|
|
|
|
|
|
|
|
const inputRef = useRef(null);
|
|
|
|
|
const [searchQuery, setSearchQuery] = React.useState("");
|
2022-08-16 21:11:16 +00:00
|
|
|
|
|
|
|
|
|
const toggle = useCallback(() => {
|
|
|
|
|
modal.show();
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const sub = inkdrop.commands.add(document.body, {
|
|
|
|
|
"commandpalette:toggle": toggle,
|
|
|
|
|
});
|
2022-08-23 01:49:14 +00:00
|
|
|
|
console.log("useeffect triggered");
|
2022-08-16 21:11:16 +00:00
|
|
|
|
return () => sub.dispose();
|
|
|
|
|
}, [toggle]);
|
|
|
|
|
|
2022-08-22 07:17:43 +00:00
|
|
|
|
// focus text box when dialog is shown
|
2022-08-16 21:11:16 +00:00
|
|
|
|
useLayoutEffect(() => {
|
2022-08-22 07:17:43 +00:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
const textbox = document.getElementById("cpInput");
|
|
|
|
|
textbox.focus();
|
|
|
|
|
}, 50);
|
2022-08-22 12:20:24 +00:00
|
|
|
|
console.log("use layout effect triggered");
|
2022-08-16 21:11:16 +00:00
|
|
|
|
});
|
|
|
|
|
|
2022-08-22 12:20:24 +00:00
|
|
|
|
const filter = (commands, query) => {
|
|
|
|
|
if (!query) return commands;
|
|
|
|
|
return commands.filter((command) => {
|
|
|
|
|
const commandText = command.name.toLowerCase();
|
|
|
|
|
const commandCat = command.category.toLowerCase();
|
|
|
|
|
let textFilter = commandText.includes(query.toLowerCase());
|
|
|
|
|
let categoryFilter = commandCat.includes(query.toLowerCase());
|
|
|
|
|
return textFilter || categoryFilter;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const changeHandler = (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
setSearchQuery(e.currentTarget.value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const filteredResults = filter(Commands, searchQuery);
|
|
|
|
|
|
2022-08-16 21:11:16 +00:00
|
|
|
|
return (
|
2022-08-22 12:20:24 +00:00
|
|
|
|
<Dialog
|
|
|
|
|
{...modal.state}
|
|
|
|
|
onBackdropClick={modal.close}
|
|
|
|
|
className="commandpalette flex-col"
|
|
|
|
|
>
|
2022-08-16 21:11:16 +00:00
|
|
|
|
<Dialog.Content className="commandpalette">
|
2022-08-23 01:49:14 +00:00
|
|
|
|
<div
|
|
|
|
|
className="commandpalettewrapper flex-col"
|
|
|
|
|
ref={useArrowKeyNavigation({
|
|
|
|
|
selectors: "a,input",
|
|
|
|
|
modal: modal.close,
|
|
|
|
|
})}
|
|
|
|
|
>
|
2022-08-22 12:20:24 +00:00
|
|
|
|
<div className="flex-col contents">
|
2022-08-16 21:11:16 +00:00
|
|
|
|
<div className="ui small input">
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
placeholder="Search files by name (append > for actions or ! for formatting)"
|
|
|
|
|
spellCheck="false"
|
|
|
|
|
className="cpInput"
|
|
|
|
|
id="cpInput"
|
2022-08-22 12:20:24 +00:00
|
|
|
|
ref={inputRef}
|
|
|
|
|
onChange={changeHandler}
|
2022-08-16 21:11:16 +00:00
|
|
|
|
/>
|
|
|
|
|
</div>
|
2022-08-22 12:20:24 +00:00
|
|
|
|
<div className="cpContents">
|
|
|
|
|
{filteredResults.length === 0 ? (
|
|
|
|
|
<div className="nomatch">
|
|
|
|
|
<p className="nomatchemoji">{"(。>﹏<)"}</p>
|
|
|
|
|
<p className="nomatchtext">no matching commands</p>
|
|
|
|
|
<p className="nomatchtext">
|
|
|
|
|
try searching for a different term
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
|
|
|
|
{filteredResults.map((Command, index) => {
|
|
|
|
|
return (
|
|
|
|
|
<Option idx={index} key={index} {...Command} modal={modal} />
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
2022-08-16 21:11:16 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Dialog.Content>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default CommandPalette;
|