diff --git a/src/background/index.ts b/src/background/index.ts
index 8de3a75..d93a6bb 100644
--- a/src/background/index.ts
+++ b/src/background/index.ts
@@ -21,7 +21,8 @@ browser.runtime.onInstalled.addListener(async () => {
keyLists.forEach((keyItem, index) => {
const indexKey = index + 1;
browser.storage.sync
- .set({ [indexKey]: { id: indexKey, ...keyItem } })
+ // @ts-ignore
+ .set({ [indexKey]: { id: indexKey, ...keyItem } }) // TODO: Test carefully.
.then(() => browser.runtime.openOptionsPage());
// context menu
diff --git a/src/background/superkey.db.json b/src/background/superkey.db.json
index b70bbd4..de57cf6 100644
--- a/src/background/superkey.db.json
+++ b/src/background/superkey.db.json
@@ -1,232 +1,432 @@
-[
- {
- "key": "gh",
- "separator": "",
- "url": "https://github.com",
- "queryUrl": "https://github.com/search?q",
- "querySeparator": "",
- "subKeys": [
- { "key": "pr", "url": "https://github.com/pulls" },
- {
- "key": "pr-need-review",
- "url": "https://github.com/pulls/review-requested"
- },
- { "key": "pr-mentioned", "url": "https://github.com/pulls/mentioned" },
- { "key": "pr-assigned", "url": "https://github.com/pulls/assigned" },
- { "key": "issues", "url": "https://github.com/issues" },
- { "key": "issues-assigned", "url": "https://github.com/issues/assigned" },
- {
- "key": "issues-mentioned",
- "url": "https://github.com/issues/mentioned"
- },
- { "key": "marketplace", "url": "https://github.com/marketplace" },
- { "key": "explore", "url": "https://github.com/explore" },
- { "key": "trending", "url": "https://github.com/trending" },
- { "key": "setting", "url": "https://github.com/settings/profile" },
- { "key": "gist", "url": "https://gist.github.com/discover" },
- { "key": "notifications", "url": "https://github.com/notifications" }
- ],
- "id": 1
- },
- {
- "key": "so",
- "separator": "",
- "url": "https://stackoverflow.com",
- "queryUrl": "https://stackoverflow.com/search?q",
- "querySeparator": "",
- "subKeys": [],
- "id": 2
- },
- {
- "key": "twt",
- "separator": "",
- "url": "https://twitter.com",
- "queryUrl": "https://twitter.com/search?",
- "querySeparator": "",
- "subKeys": [
- { "key": "new", "url": "https://twitter.com/compose/tweet" },
- { "key": "bookmarks", "url": "https://twitter.com/i/bookmarks" },
- { "key": "messages", "url": "https://twitter.com/messages" },
- { "key": "notifications", "url": "https://twitter.com/notifications" },
- { "key": "explore", "url": "https://twitter.com/explore" },
- { "key": "elon", "url": "https://twitter.com/elonmusk" },
- { "key": "dabit", "url": "https://twitter.com/dabit3" },
- { "key": "binance", "url": "https://twitter.com/binance" },
- { "key": "fireship", "url": "https://twitter.com/fireship_dev" },
- { "key": "", "url": "" }
- ],
- "id": 3
- },
- {
- "key": "jobs",
- "separator": "",
- "url": "https://www.linkedin.com/jobs",
- "queryUrl": "https://www.linkedin.com/jobs/search/?keywords",
- "querySeparator": "",
- "subKeys": [
- { "key": "flexjobs", "url": "https://www.flexjobs.com/" },
- { "key": "indeed", "url": "https://indeed.com" },
- { "key": "arc", "url": "https://arc.dev/remote-jobs" },
- { "key": "remote.co", "url": "https://remote.co" },
- {
- "key": "google",
- "url": "https://www.google.com/search?q=jobs&ibp=htl;jobs"
- },
- { "key": "justremote", "url": "https://justremote.co/" },
- { "key": "weworkremotely", "url": "https://weworkremotely.com/" },
- { "key": "remotive", "url": "https://remotive.com/" },
- { "key": "remoteok", "url": "https://remoteok.com/" },
- { "key": "glassdoor", "url": "https://www.glassdoor.com" },
- { "key": "monster", "url": "https://www.monster.com/" }
- ],
- "id": 4
- },
- {
- "key": "qr",
- "separator": "",
- "url": "https://www.quora.com",
- "queryUrl": "https://www.quora.com/search?q",
- "querySeparator": "",
- "subKeys": [
- { "key": "notifications", "url": "https://www.quora.com/notifications" },
- { "key": "following", "url": "https://www.quora.com/following" },
- { "key": "answer", "url": "https://www.quora.com/answer" },
- { "key": "bookmarks", "url": "https://www.quora.com/bookmarks" },
- { "key": "space", "url": "https://www.quora.com/spaces?discover=true" }
- ],
- "id": 5
- },
- {
- "key": "rd",
- "separator": "",
- "url": "https://www.reddit.com/",
- "queryUrl": "https://www.reddit.com/search/?q",
- "querySeparator": "",
- "subKeys": [
- { "key": "create", "url": "https://www.reddit.com/submit" },
- { "key": "hot", "url": "https://www.reddit.com/hot/" },
- { "key": "new", "url": "https://www.reddit.com/new/" },
- { "key": "top", "url": "https://www.reddit.com/top/" },
- { "key": "chat", "url": "https://www.reddit.com/chat/" },
- { "key": "live", "url": "https://www.reddit.com/rpan/" },
- { "key": "popular", "url": "https://www.reddit.com/r/popular/" },
- { "key": "all", "url": "https://www.reddit.com/r/all/" }
- ],
- "id": 6
- },
- {
- "key": "cd",
- "separator": "",
- "url": "https://www.codegrepper.com/",
- "queryUrl": "https://www.codegrepper.com/search.php?q",
- "querySeparator": "",
- "subKeys": [{ "key": "", "url": "" }],
- "id": 7
- },
- {
- "key": "yt",
- "separator": "",
- "url": "https://www.youtube.com",
- "queryUrl": "https://www.youtube.com/results?search_query",
- "querySeparator": "",
- "subKeys": [
- { "key": "history", "url": "https://www.youtube.com/feed/history" },
- { "key": "gaming", "url": "https://www.youtube.com/gaming" },
- { "key": "live", "url": "https://www.youtube.com/live/featured" },
- { "key": "music", "url": "https://music.youtube.com/tasteprofile" },
- { "key": "artist", "url": "https://artists.youtube/" },
- { "key": "account", "url": "https://www.youtube.com/account" },
- { "key": "premium", "url": "https://www.youtube.com/premium" }
- ],
- "id": 8
- },
- {
- "key": "daily.dev",
- "separator": "",
- "url": "https://app.daily.dev/",
- "queryUrl": "https://app.daily.dev/search?q",
- "querySeparator": "",
- "subKeys": [
- { "key": "popular", "url": "https://app.daily.dev/popular" },
- { "key": "upvoted", "url": "https://app.daily.dev/upvoted" },
- { "key": "bookmarks", "url": "https://app.daily.dev/bookmarks" },
- { "key": "discussed", "url": "https://app.daily.dev/discussed" }
- ],
- "id": 9
- },
- {
- "key": "az",
- "separator": "",
- "url": "https://www.amazon.com",
- "queryUrl": "https://www.amazon.com/s?k",
- "querySeparator": "",
- "subKeys": [{ "key": "", "url": "" }],
- "id": 10
- },
- {
- "key": "whatsapp",
- "separator": "",
- "url": "https://web.whatsapp.com/",
- "queryUrl": "",
- "querySeparator": "",
- "subKeys": [],
- "id": 11,
- "duplicate": false,
- "edited": false
- },
- {
- "key": "gm",
- "separator": "",
- "url": "https://mail.google.com",
- "queryUrl": "https://mail.google.com/mail/u/0/#search/",
- "querySeparator": "",
- "subKeys": [
- { "key": "2", "url": "https://mail.google.com/mail/u/1" },
- { "key": "3", "url": "https://mail.google.com/mail/u/3" }
- ],
- "id": 12
- },
- {
- "key": "meet",
- "separator": "",
- "url": "https://meet.google.com",
- "queryUrl": "https://meet.google.com/?authuser",
- "querySeparator": "",
- "subKeys": [{ "key": "new", "url": "https://meet.google.com/new" }],
- "id": 13
- },
- {
- "key": "cryp",
- "separator": "",
- "url": "https://crypto.com/price",
- "queryUrl": "https://www.coindesk.com/search?s",
- "querySeparator": "",
- "subKeys": [
- {
- "key": "news",
- "url": "https://decrypt.co/?utm_source=cmc&utm_medium=cpc&utm_campaign=search"
- },
- { "key": "btc", "url": "https://coinmarketcap.com/currencies/bitcoin/" },
- { "key": "eth", "url": "https://coinmarketcap.com/currencies/ethereum/" },
- {
- "key": "dogecoin",
- "url": "https://coinmarketcap.com/currencies/dogecoin/"
- },
- {
- "key": "shiba",
- "url": "https://coinmarketcap.com/currencies/shiba-inu/"
- },
- {
- "key": "solana",
- "url": "https://coinmarketcap.com/currencies/solana/"
- },
- { "key": "bnb", "url": "https://coinmarketcap.com/currencies/bnb/" },
- {
- "key": "litecoin",
- "url": "https://coinmarketcap.com/currencies/litecoin/"
- },
- { "key": "tezos", "url": "https://coinmarketcap.com/currencies/tezos/" }
- ],
- "id": 14
- }
-]
+{
+ "keyLists": [
+ {
+ "key": "gh",
+ "separator": "",
+ "url": "https://github.com",
+ "queryUrl": "https://github.com/search?q",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "pr",
+ "url": "https://github.com/pulls"
+ },
+ {
+ "key": "pr-need-review",
+ "url": "https://github.com/pulls/review-requested"
+ },
+ {
+ "key": "pr-mentioned",
+ "url": "https://github.com/pulls/mentioned"
+ },
+ {
+ "key": "pr-assigned",
+ "url": "https://github.com/pulls/assigned"
+ },
+ {
+ "key": "issues",
+ "url": "https://github.com/issues"
+ },
+ {
+ "key": "issues-assigned",
+ "url": "https://github.com/issues/assigned"
+ },
+ {
+ "key": "issues-mentioned",
+ "url": "https://github.com/issues/mentioned"
+ },
+ {
+ "key": "marketplace",
+ "url": "https://github.com/marketplace"
+ },
+ {
+ "key": "explore",
+ "url": "https://github.com/explore"
+ },
+ {
+ "key": "trending",
+ "url": "https://github.com/trending"
+ },
+ {
+ "key": "setting",
+ "url": "https://github.com/settings/profile"
+ },
+ {
+ "key": "gist",
+ "url": "https://gist.github.com/discover"
+ },
+ {
+ "key": "notifications",
+ "url": "https://github.com/notifications"
+ }
+ ],
+ "id": 1
+ },
+ {
+ "key": "so",
+ "separator": "",
+ "url": "https://stackoverflow.com",
+ "queryUrl": "https://stackoverflow.com/search?q",
+ "querySeparator": "",
+ "subKeys": [],
+ "id": 2
+ },
+ {
+ "key": "twt",
+ "separator": "",
+ "url": "https://twitter.com",
+ "queryUrl": "https://twitter.com/search?",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "new",
+ "url": "https://twitter.com/compose/tweet"
+ },
+ {
+ "key": "bookmarks",
+ "url": "https://twitter.com/i/bookmarks"
+ },
+ {
+ "key": "messages",
+ "url": "https://twitter.com/messages"
+ },
+ {
+ "key": "notifications",
+ "url": "https://twitter.com/notifications"
+ },
+ {
+ "key": "explore",
+ "url": "https://twitter.com/explore"
+ },
+ {
+ "key": "elon",
+ "url": "https://twitter.com/elonmusk"
+ },
+ {
+ "key": "dabit",
+ "url": "https://twitter.com/dabit3"
+ },
+ {
+ "key": "binance",
+ "url": "https://twitter.com/binance"
+ },
+ {
+ "key": "fireship",
+ "url": "https://twitter.com/fireship_dev"
+ },
+ {
+ "key": "",
+ "url": ""
+ }
+ ],
+ "id": 3
+ },
+ {
+ "key": "jobs",
+ "separator": "",
+ "url": "https://www.linkedin.com/jobs",
+ "queryUrl": "https://www.linkedin.com/jobs/search/?keywords",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "flexjobs",
+ "url": "https://www.flexjobs.com/"
+ },
+ {
+ "key": "indeed",
+ "url": "https://indeed.com"
+ },
+ {
+ "key": "arc",
+ "url": "https://arc.dev/remote-jobs"
+ },
+ {
+ "key": "remote.co",
+ "url": "https://remote.co"
+ },
+ {
+ "key": "google",
+ "url": "https://www.google.com/search?q=jobs&ibp=htl;jobs"
+ },
+ {
+ "key": "justremote",
+ "url": "https://justremote.co/"
+ },
+ {
+ "key": "weworkremotely",
+ "url": "https://weworkremotely.com/"
+ },
+ {
+ "key": "remotive",
+ "url": "https://remotive.com/"
+ },
+ {
+ "key": "remoteok",
+ "url": "https://remoteok.com/"
+ },
+ {
+ "key": "glassdoor",
+ "url": "https://www.glassdoor.com"
+ },
+ {
+ "key": "monster",
+ "url": "https://www.monster.com/"
+ }
+ ],
+ "id": 4
+ },
+ {
+ "key": "qr",
+ "separator": "",
+ "url": "https://www.quora.com",
+ "queryUrl": "https://www.quora.com/search?q",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "notifications",
+ "url": "https://www.quora.com/notifications"
+ },
+ {
+ "key": "following",
+ "url": "https://www.quora.com/following"
+ },
+ {
+ "key": "answer",
+ "url": "https://www.quora.com/answer"
+ },
+ {
+ "key": "bookmarks",
+ "url": "https://www.quora.com/bookmarks"
+ },
+ {
+ "key": "space",
+ "url": "https://www.quora.com/spaces?discover=true"
+ }
+ ],
+ "id": 5
+ },
+ {
+ "key": "rd",
+ "separator": "",
+ "url": "https://www.reddit.com/",
+ "queryUrl": "https://www.reddit.com/search/?q",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "create",
+ "url": "https://www.reddit.com/submit"
+ },
+ {
+ "key": "hot",
+ "url": "https://www.reddit.com/hot/"
+ },
+ {
+ "key": "new",
+ "url": "https://www.reddit.com/new/"
+ },
+ {
+ "key": "top",
+ "url": "https://www.reddit.com/top/"
+ },
+ {
+ "key": "chat",
+ "url": "https://www.reddit.com/chat/"
+ },
+ {
+ "key": "live",
+ "url": "https://www.reddit.com/rpan/"
+ },
+ {
+ "key": "popular",
+ "url": "https://www.reddit.com/r/popular/"
+ },
+ {
+ "key": "all",
+ "url": "https://www.reddit.com/r/all/"
+ }
+ ],
+ "id": 6
+ },
+ {
+ "key": "cd",
+ "separator": "",
+ "url": "https://www.codegrepper.com/",
+ "queryUrl": "https://www.codegrepper.com/search.php?q",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "",
+ "url": ""
+ }
+ ],
+ "id": 7
+ },
+ {
+ "key": "yt",
+ "separator": "",
+ "url": "https://www.youtube.com",
+ "queryUrl": "https://www.youtube.com/results?search_query",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "history",
+ "url": "https://www.youtube.com/feed/history"
+ },
+ {
+ "key": "gaming",
+ "url": "https://www.youtube.com/gaming"
+ },
+ {
+ "key": "live",
+ "url": "https://www.youtube.com/live/featured"
+ },
+ {
+ "key": "music",
+ "url": "https://music.youtube.com/tasteprofile"
+ },
+ {
+ "key": "artist",
+ "url": "https://artists.youtube/"
+ },
+ {
+ "key": "account",
+ "url": "https://www.youtube.com/account"
+ },
+ {
+ "key": "premium",
+ "url": "https://www.youtube.com/premium"
+ }
+ ],
+ "id": 8
+ },
+ {
+ "key": "daily.dev",
+ "separator": "",
+ "url": "https://app.daily.dev/",
+ "queryUrl": "https://app.daily.dev/search?q",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "popular",
+ "url": "https://app.daily.dev/popular"
+ },
+ {
+ "key": "upvoted",
+ "url": "https://app.daily.dev/upvoted"
+ },
+ {
+ "key": "bookmarks",
+ "url": "https://app.daily.dev/bookmarks"
+ },
+ {
+ "key": "discussed",
+ "url": "https://app.daily.dev/discussed"
+ }
+ ],
+ "id": 9
+ },
+ {
+ "key": "az",
+ "separator": "",
+ "url": "https://www.amazon.com",
+ "queryUrl": "https://www.amazon.com/s?k",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "",
+ "url": ""
+ }
+ ],
+ "id": 10
+ },
+ {
+ "key": "whatsapp",
+ "separator": "",
+ "url": "https://web.whatsapp.com/",
+ "queryUrl": "",
+ "querySeparator": "",
+ "subKeys": [],
+ "id": 11,
+ "duplicate": false,
+ "edited": false
+ },
+ {
+ "key": "gm",
+ "separator": "",
+ "url": "https://mail.google.com",
+ "queryUrl": "https://mail.google.com/mail/u/0/#search/",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "2",
+ "url": "https://mail.google.com/mail/u/1"
+ },
+ {
+ "key": "3",
+ "url": "https://mail.google.com/mail/u/3"
+ }
+ ],
+ "id": 12
+ },
+ {
+ "key": "meet",
+ "separator": "",
+ "url": "https://meet.google.com",
+ "queryUrl": "https://meet.google.com/?authuser",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "new",
+ "url": "https://meet.google.com/new"
+ }
+ ],
+ "id": 13
+ },
+ {
+ "key": "cryp",
+ "separator": "",
+ "url": "https://crypto.com/price",
+ "queryUrl": "https://www.coindesk.com/search?s",
+ "querySeparator": "",
+ "subKeys": [
+ {
+ "key": "news",
+ "url": "https://decrypt.co/?utm_source=cmc&utm_medium=cpc&utm_campaign=search"
+ },
+ {
+ "key": "btc",
+ "url": "https://coinmarketcap.com/currencies/bitcoin/"
+ },
+ {
+ "key": "eth",
+ "url": "https://coinmarketcap.com/currencies/ethereum/"
+ },
+ {
+ "key": "dogecoin",
+ "url": "https://coinmarketcap.com/currencies/dogecoin/"
+ },
+ {
+ "key": "shiba",
+ "url": "https://coinmarketcap.com/currencies/shiba-inu/"
+ },
+ {
+ "key": "solana",
+ "url": "https://coinmarketcap.com/currencies/solana/"
+ },
+ {
+ "key": "bnb",
+ "url": "https://coinmarketcap.com/currencies/bnb/"
+ },
+ {
+ "key": "litecoin",
+ "url": "https://coinmarketcap.com/currencies/litecoin/"
+ },
+ {
+ "key": "tezos",
+ "url": "https://coinmarketcap.com/currencies/tezos/"
+ }
+ ],
+ "id": 14
+ }
+ ]
+}
diff --git a/src/components/autocomplete/helpers.ts b/src/components/autocomplete/helpers.ts
new file mode 100644
index 0000000..d900164
--- /dev/null
+++ b/src/components/autocomplete/helpers.ts
@@ -0,0 +1,16 @@
+export const FIXED_KEYWORDS: { [index: string]: string } = {
+ BOOKMARK: "@",
+ HISTORY: "#",
+};
+
+export const isSearchingHistory = (input: string) =>
+ input[0] === FIXED_KEYWORDS.HISTORY;
+export const isSearchingBookmarks = (input: string) =>
+ input[0] === FIXED_KEYWORDS.BOOKMARK;
+
+export const getSearchType = (input: string) => {
+ if (isSearchingHistory(input)) return "history";
+ if (isSearchingBookmarks(input)) return "bookmark";
+
+ return "key";
+};
diff --git a/src/components/autocomplete/suggestions-item.tsx b/src/components/autocomplete/suggestions-item.tsx
new file mode 100644
index 0000000..f9f6e06
--- /dev/null
+++ b/src/components/autocomplete/suggestions-item.tsx
@@ -0,0 +1,46 @@
+import { FunctionComponent } from "preact";
+import { ISuperKeyOptional } from "../../types";
+
+export const listItemType: {
+ [index: string]: FunctionComponent<{ suggestion: ISuperKeyOptional }>;
+} = {
+ bookmark: ({ suggestion }) => (
+ <>
+ {suggestion.title} {": "}
+
+ {suggestion.url}
+ >
+ ),
+ history: ({ suggestion }) => (
+ <>
+ {suggestion.title} {": "}
+
+ {suggestion.url}
+ >
+ ),
+ key: ({ suggestion }) => (
+ <>
+ {suggestion.key} {": "}
+ {suggestion.url}
+ >
+ ),
+};
+
+export const searchHelperText = {
+ bookmark: (_: any, value: string) => (
+ <>
+ @Bookmarks Search
+
+ {` ${value ? value.substring(1) : ""}`}
+ >
+ ),
+ history: (_: any, value: string) => (
+ <>
+ #History Search
+
+ {` ${value ? value.substring(1) : ""}`}
+ >
+ ),
+ key: (showSearchMessageUrl: any, value: string) =>
+ `${value} Search on ${showSearchMessageUrl}`,
+};
diff --git a/src/components/autocomplete/suggestions.tsx b/src/components/autocomplete/suggestions.tsx
index 282ac7a..3eba186 100644
--- a/src/components/autocomplete/suggestions.tsx
+++ b/src/components/autocomplete/suggestions.tsx
@@ -2,6 +2,8 @@ import { DEFAULT_VALUES } from "./search-handler";
import browser from "webextension-polyfill";
import { FunctionComponent } from "preact";
import { ISuperKeyOptional } from "../../types";
+import { listItemType, searchHelperText } from "./suggestions-item";
+import { getSearchType } from "./helpers";
const style = {
activeItem: "bg-gray-800 text-white",
@@ -40,7 +42,7 @@ const Suggestions: FunctionComponent = ({
: "";
// No sub query found and matched with key with space, can trigger search query
- const showSearchMessageUrl =
+ const showSearchMessageUrl: any =
!filteredSuggestions.length && keyToFind?.queryUrl && keyToFind?.url;
return (
@@ -69,8 +71,10 @@ const Suggestions: FunctionComponent = ({
}
onClick={() => onSuggestionClick(value)}
>
- {value}
- {showSearchMessageUrl ? `Search on ${showSearchMessageUrl}` : ""}
+ {searchHelperText[getSearchType(value)]?.(
+ showSearchMessageUrl,
+ value
+ )}
)}
{filteredSuggestions.map((suggestion, i) => {
@@ -85,13 +89,15 @@ const Suggestions: FunctionComponent = ({
className = style.item;
}
+ const ItemByType = listItemType[suggestion.type || "key"] || <>>;
+
return (
onSuggestionClick(suggestion)}
>
- {suggestion.key} {suggestion.url}
+
);
})}
diff --git a/src/components/autocomplete/use-autocomplete.tsx b/src/components/autocomplete/use-autocomplete.tsx
index 6034b65..66fa93f 100644
--- a/src/components/autocomplete/use-autocomplete.tsx
+++ b/src/components/autocomplete/use-autocomplete.tsx
@@ -3,6 +3,7 @@ import { DEFAULT_VALUES, fireSubmitAction } from "./search-handler";
import browser from "webextension-polyfill";
import { ISuperKeyOptional } from "../../types";
import { ISuggestionsProps } from "./suggestions";
+import { isSearchingBookmarks, isSearchingHistory } from "./helpers";
export const useAutocomplete = () => {
const ref = useRef(null);
@@ -35,7 +36,7 @@ export const useAutocomplete = () => {
});
}, []);
- const [value, setValue] = useState("");
+ const [value, setValue] = useState("");
//close suggestions list when click outside
useEffect(() => {
@@ -49,22 +50,73 @@ export const useAutocomplete = () => {
return () => window.removeEventListener("click", handleOutsideClick);
}, [showSuggestions, ref]);
+ const bookmarkSearch = browser.bookmarks.search;
+ const bookmarkRecent = browser.bookmarks.getRecent;
+ const browserHistorySearch = browser.history.search;
+
const handleChange = useCallback(
- (e: Event) => {
+ async (e: Event) => {
const target = e.currentTarget as HTMLInputElement;
const userInput = target.value;
- const filteredSuggestions: ISuperKeyOptional[] = suggestions?.filter(
- (suggestion: ISuperKeyOptional) =>
- suggestion.key &&
- suggestion.key.toLowerCase().indexOf(userInput.toLowerCase()) > -1
- );
+ let newFilteredSuggestions: ISuperKeyOptional[] = [];
+
+ if (isSearchingBookmarks(userInput)) {
+ const stringWithoutAtKeyword = userInput?.substring(1);
+ let bookmarkResult = [];
+
+ if (stringWithoutAtKeyword)
+ bookmarkResult = await bookmarkSearch(stringWithoutAtKeyword);
+ else bookmarkResult = await bookmarkRecent(10);
+
+ newFilteredSuggestions = bookmarkResult
+ .filter((each) => each.type === "bookmark")
+ .map((each) => {
+ return {
+ key: each.id,
+ url: each.url,
+ type: each.type,
+ title: each.title || "",
+ };
+ });
+ } else if (isSearchingHistory(userInput)) {
+ const stringWithoutHashKeyword = userInput?.substring(1);
+ const historyResult = await browserHistorySearch({
+ text: stringWithoutHashKeyword || " ",
+ maxResults: 20,
+ });
+
+ newFilteredSuggestions = historyResult
+ .sort((a, b) => (a.lastVisitTime || 0) - (b.lastVisitTime || 0))
+ .map((each) => {
+ return {
+ key: each.id,
+ url: each.url,
+ type: "history",
+ title: each.title || "",
+ };
+ });
+ } else
+ newFilteredSuggestions = suggestions
+ ?.filter(
+ (suggestion: ISuperKeyOptional) =>
+ suggestion.key &&
+ suggestion.key.toLowerCase().indexOf(userInput.toLowerCase()) > -1
+ )
+ .map((each: ISuperKeyOptional) => ({ ...each, type: "key" }));
setActiveSuggestion(0);
- setFilteredSuggestions(filteredSuggestions);
+ setFilteredSuggestions(newFilteredSuggestions);
setShowSuggestions(true);
- setValue(target.value);
+ setValue(userInput);
},
- [setValue, suggestions]
+ [
+ setValue,
+ setFilteredSuggestions,
+ bookmarkSearch,
+ bookmarkRecent,
+ browserHistorySearch,
+ suggestions,
+ ]
);
const getByKey = (keyValue: string): ISuperKeyOptional | null => {
diff --git a/src/manifest.ts b/src/manifest.ts
index 1babd20..1db7c84 100644
--- a/src/manifest.ts
+++ b/src/manifest.ts
@@ -82,6 +82,8 @@ export async function getManifest(isFirefox: boolean = false) {
"contextMenus",
"notifications",
"activeTab",
+ "bookmarks",
+ "history",
],
commands: shortCut,
diff --git a/src/types.ts b/src/types.ts
index 60b4bff..b287203 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -26,6 +26,8 @@ export interface ISuperKeyOptional {
searchValue?: string;
duplicate?: boolean;
edited?: boolean;
+ title?: string;
+ type?: string;
}
export interface ISearchHandler {
diff --git a/vite.config.ts b/vite.config.ts
index 2cd5d28..de830dd 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,32 +1,32 @@
-import { resolve } from 'path'
-import { defineConfig } from 'vite'
-import preact from '@preact/preset-vite'
+import { resolve } from "path";
+import { defineConfig } from "vite";
+import preact from "@preact/preset-vite";
-const port = parseInt(process.env.PORT || '') || 3303
-const r = (...args: string[]) => resolve(__dirname, ...args)
+const port = parseInt(process.env.PORT || "") || 3303;
+const r = (...args: string[]) => resolve(__dirname, ...args);
export default defineConfig(({ command }) => {
return {
- root: r('views'),
- base: command === 'serve' ? `http://localhost:${port}/` : undefined,
+ root: r("views"),
+ base: command === "serve" ? `http://localhost:${port}/` : undefined,
resolve: {
alias: {
- '~/': `${r('views')}/`,
+ "~/": `${r("views")}/`,
},
},
server: {
port,
hmr: {
- host: 'localhost',
+ host: "localhost",
},
},
build: {
- outDir: r('extension/dist'),
+ outDir: r("extension/dist"),
emptyOutDir: false,
rollupOptions: {
input: {
- popup: r('views/popup/index.html'),
- options: r('views/options/index.html')
+ popup: r("views/popup/index.html"),
+ options: r("views/options/index.html"),
},
},
},
@@ -34,19 +34,20 @@ export default defineConfig(({ command }) => {
preact(),
// rewrite assets to use relative path
{
- name: 'assets-rewrite',
- enforce: 'post',
- apply: 'build',
+ name: "assets-rewrite",
+ enforce: "post",
+ apply: "build",
transformIndexHtml(html) {
- return html.replace(/"\/assets\//g, '"../assets/')
+ return html.replace(/"\/assets\//g, '"../assets/');
},
},
],
optimizeDeps: {
- include: [
- 'preact',
- ],
+ include: ["preact"],
},
- }
-})
+ esbuild: {
+ logOverride: { "this-is-undefined-in-esm": "silent" },
+ },
+ };
+});