Skip to content

Commit

Permalink
improved performance by avoiding rerenders and duplicated calls to fu…
Browse files Browse the repository at this point in the history
…zzy. Dependency also changed
  • Loading branch information
dbuezas committed Mar 12, 2022
1 parent c3a1fa7 commit e46f5a7
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 140 deletions.
Binary file modified chrome-palette.zip
Binary file not shown.
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"esbuild": "^0.13.4",
"preact": "^10.5.14",
"react": "^17.0.2",
"react-command-palette": "^0.16.2",
"react-command-palette": "github:dbuezas/react-command-palette#npm/push-dist-so-my-project-can-fetch-from-git",
"react-dom": "^17.0.2",
"react-hotkeys-hook": "^3.4.3",
"typescript": "^4.4.2",
Expand All @@ -21,6 +21,7 @@
},
"scripts": {
"start": "node script/build.mjs",
"check-types": "tsc --noEmit",
"build": "NODE_ENV=production node script/build.mjs",
"upgrade": "npx npm-check -u"
},
Expand Down
9 changes: 0 additions & 9 deletions src/App.test.tsx

This file was deleted.

44 changes: 13 additions & 31 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,12 @@ import { sortByUsed, storeLastUsed } from "./last-used";
import usePaletteInput from "./hooks/usePaletteInput";
import { parseInputCommand } from "./hooks/parseInputCommand";

import equal from "fast-deep-equal";

function App() {
const [, forceRender] = useState({});
const commandPalette = useRef<any>(null);
useEffect(() => {
// @TODO: fork and PR original library with fix
// @TODO: Add option to lib to show an empty list when the search query matches nothing (instead of falling back to the full list)
// Command palette LIB HACK
// the library ignores the search string when the commands change.
// this fixes it.
if (!commandPalette.current) return;
commandPalette.current.componentDidUpdate = function (prevProps: any) {
const { commands, open } = this.props;
if (open !== prevProps.open) {
if (open) {
this.handleOpenModal();
} else {
this.handleCloseModal();
}
}

if (!equal(prevProps.commands, commands)) {
const element: HTMLInputElement | undefined =
commandPalette.current.commandPaletteInput?.input;
const value = element?.value || "";
this.fetchData(); // set this.allCommands
this.onSuggestionsFetchRequested({ value }); // updates matching suggestions
}
};
}, [commandPalette.current]);
const input = usePaletteInput(commandPalette);

// @TODO: find a full memoization strategy to keep commands list constant and avoid double fuzzy searching
console.log(input.element);
const commands = sortByUsed([
let commands = sortByUsed([
...useCommandSuggestions(input),
...useAudibleTabSuggestions(input),
...useSwitchTabSuggestions("t", input),
Expand All @@ -64,6 +34,17 @@ function App() {
...useTemplatedSuggestions(input),
]);

const lastCommands = useRef<Command[]>([]);
const areEqual =
commands.length === lastCommands.current.length &&
commands.every((cmd, i) => cmd === lastCommands.current[i]);
if (areEqual) {
commands = lastCommands.current;
} else {
lastCommands.current = commands;
console.log("Commands will rerender and create double search")
}

return (
<CommandPalette
ref={commandPalette}
Expand Down Expand Up @@ -104,6 +85,7 @@ function App() {
placeholder="Search for a command"
renderCommand={SampleAtomCommand}
showSpinnerOnSelect={false}
showAllCommandsWhenNoneMatches={false}
/>
);
}
Expand Down
29 changes: 16 additions & 13 deletions src/hooks/bookmarkSuggestions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef, useState } from "react";
import { useMemo, useRef, useState } from "react";
import { Command } from "./commandsSuggestions";
import { formatDistanceToNow } from "date-fns";
import { parseInputCommand } from "./parseInputCommand";
Expand Down Expand Up @@ -37,7 +37,7 @@ export function useBookmarkSuggestions(
KEYWORD: string,
{ setInputValue, inputValue }: UseSuggestionParam
) {
const shortcut = useShortcut(KEYWORD, { setInputValue, inputValue });
const shortcut = useShortcut(KEYWORD, { setInputValue });
const [commands, setCommands] = useState<Command[]>([]);
const { didMatch, keyword } = parseInputCommand(inputValue);
const myMatch = keyword === KEYWORD;
Expand All @@ -51,17 +51,20 @@ export function useBookmarkSuggestions(
};
fetch();
}

const bookmarkSuggestions = useMemo(
() => [
{
name: "Bookmarked Tabs",
category: "Search",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
},
],
[]
);
if (myMatch) return commands;
if (didMatch) return [];
return [
{
name: "Bookmarked Tabs",
category: "Search",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
},
];
return bookmarkSuggestions;
}
31 changes: 16 additions & 15 deletions src/hooks/bookmarkThisSuggestions.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { useRef, useState } from "react";
import { useMemo, useRef, useState } from "react";
import { Command } from "./commandsSuggestions";
import { formatDistanceToNow } from "date-fns";
import { parseInputCommand } from "./parseInputCommand";
import browser from "webextension-polyfill";
import { UseSuggestionParam } from "./websitesSuggestions";
import niceUrl from "./niceUrl";
import { isDefined } from "./historySuggestions";
import useShortcut from "./useShortcut";

const traverse = (
Expand Down Expand Up @@ -50,7 +48,7 @@ export function useBookmarkThisSuggestions(
KEYWORD: string,
{ setInputValue, inputValue }: UseSuggestionParam
) {
const shortcut = useShortcut(KEYWORD, { setInputValue, inputValue });
const shortcut = useShortcut(KEYWORD, { setInputValue });
const [commands, setCommands] = useState<Command[]>([]);
const { didMatch, keyword } = parseInputCommand(inputValue);
const myMatch = keyword === KEYWORD;
Expand All @@ -64,17 +62,20 @@ export function useBookmarkThisSuggestions(
};
fetch();
}

const bookmarkThis = useMemo(
() => [
{
name: "Bookmark this tab",
category: "Add Bookmark",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
},
],
[]
);
if (myMatch) return commands;
if (didMatch) return [];
return [
{
name: "Bookmark this tab",
category: "Add Bookmark",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
},
];
return bookmarkThis
}
31 changes: 17 additions & 14 deletions src/hooks/historySuggestions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef, useState } from "react";
import { useMemo, useRef, useState } from "react";
import { Command } from "./commandsSuggestions";
import { formatDistanceToNow } from "date-fns";
import { parseInputCommand } from "./parseInputCommand";
Expand All @@ -14,7 +14,7 @@ export function useHistorySuggestions(
KEYWORD: string,
{ setInputValue, inputValue }: UseSuggestionParam
) {
const shortcut = useShortcut(KEYWORD, { setInputValue, inputValue });
const shortcut = useShortcut(KEYWORD, { setInputValue });

const [commands, setCommands] = useState<Command[]>([]);
const { didMatch, keyword } = parseInputCommand(inputValue);
Expand Down Expand Up @@ -48,18 +48,21 @@ export function useHistorySuggestions(
};
fetch();
}

const searchHistory = useMemo(
() => [
{
name: "Search History",
category: "Search",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
shortcut,
},
],
[]
);
if (myMatch) return commands;
if (didMatch) return [];
return [
{
name: "Search History",
category: "Search",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
shortcut,
},
];
return searchHistory;
}
30 changes: 17 additions & 13 deletions src/hooks/tabsSuggestions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef, useState } from "react";
import { useMemo, useRef, useState } from "react";
import { Command } from "./commandsSuggestions";
import { parseInputCommand } from "./parseInputCommand";
import browser from "webextension-polyfill";
Expand All @@ -10,7 +10,7 @@ export function useSwitchTabSuggestions(
KEYWORD: string,
{ setInputValue, inputValue }: UseSuggestionParam
) {
const shortcut = useShortcut(KEYWORD, { setInputValue, inputValue });
const shortcut = useShortcut(KEYWORD, { setInputValue });
const [commands, setCommands] = useState<Command[]>([]);
const { didMatch, keyword } = parseInputCommand(inputValue);
const myMatch = keyword === KEYWORD;
Expand All @@ -37,17 +37,21 @@ export function useSwitchTabSuggestions(
};
fetch();
}
const searchTabs = useMemo(
() => [
{
name: "Search Tabs",
category: "Search",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
shortcut,
},
],
[]
);
if (myMatch) return commands;
if (didMatch) return [];
return [
{
name: "Search Tabs",
category: "Search",
command: async function () {
setInputValue(KEYWORD + ">");
},
keyword: KEYWORD + ">",
shortcut,
},
];
return searchTabs;
}
42 changes: 22 additions & 20 deletions src/hooks/usePaletteInput.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import React, { useMemo } from "react";


const usePaletteInput = (commandPaletteRef: React.MutableRefObject<any>) => {
const element: HTMLInputElement | undefined =
commandPaletteRef.current?.commandPaletteInput?.input;
const inputValue = element?.value || ""
return useMemo(
() => ({
element,
setInputValue: (value: string) => {
// https://stackoverflow.com/a/46012210
var nativeInputValueSetter = Object!.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
"value"
)!.set!;
nativeInputValueSetter.call(element, value);
var ev2 = new Event("input", { bubbles: true });
element?.dispatchEvent(ev2);
},
inputValue,
}),
[element, inputValue]
);
commandPaletteRef.current?.commandPaletteInput?.input;
const inputValue = element?.value || "";

const setInputValue = useMemo(() => {
return (value: string) => {
const element: HTMLInputElement | undefined =
commandPaletteRef.current?.commandPaletteInput?.input;
if (!element) return;
// https://stackoverflow.com/a/46012210
var nativeInputValueSetter = Object!.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
"value"
)!.set!;
nativeInputValueSetter.call(element, value);
var ev2 = new Event("input", { bubbles: true });
element.dispatchEvent(ev2);
};
}, []);
return {
setInputValue,
inputValue,
};
};
export default usePaletteInput;
2 changes: 1 addition & 1 deletion src/hooks/useShortcut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useHotkeys } from "react-hotkeys-hook";

export default function useShortcut(
KEYWORD: string,
{ setInputValue }: UseSuggestionParam
{ setInputValue }: { setInputValue: UseSuggestionParam["setInputValue"] }
) {
const [shortcut, setShortcut] = useState("unset");
useEffect(() => {
Expand Down
Loading

0 comments on commit e46f5a7

Please sign in to comment.