commands array -> map & name changes

This commit is contained in:
Cade Scroggins 2022-07-30 13:25:30 -07:00
parent f54caf8405
commit 00a17d4a9f
No known key found for this signature in database
GPG key ID: 6AC5A902158265D0

View file

@ -7,127 +7,107 @@
<script> <script>
const CONFIG = { const CONFIG = {
commands: [ commands: {
{ 0: {
search: '/?q={}',
url: 'https://duckduckgo.com',
},
{
key: '0',
name: 'Local', name: 'Local',
search: ':{}', searchTemplate: ':{}',
url: 'http://localhost:3000', url: 'http://localhost:3000',
}, },
{ a: {
key: 'a',
name: 'AWS', name: 'AWS',
url: 'https://us-west-2.console.aws.amazon.com/console/home', url: 'https://us-west-2.console.aws.amazon.com/console/home',
}, },
{ b: {
key: 'b',
name: 'Dribbble', name: 'Dribbble',
search: '/search/{}', searchTemplate: '/search/{}',
url: 'https://dribbble.com/shots/popular', url: 'https://dribbble.com/shots/popular',
}, },
{ c: {
key: 'c',
name: 'Calendar', name: 'Calendar',
search: '/calendar/u/0/r/search?q={}', searchTemplate: '/calendar/u/0/r/search?q={}',
url: 'https://calendar.google.com/calendar/u/0/r', url: 'https://calendar.google.com/calendar/u/0/r',
}, },
{ d: {
key: 'd',
name: 'Drive', name: 'Drive',
search: '/drive/u/0/search?q={}', searchTemplate: '/drive/u/0/search?q={}',
url: 'https://drive.google.com/drive/u/0/my-drive', url: 'https://drive.google.com/drive/u/0/my-drive',
}, },
{ f: {
key: 'f',
name: 'Figma', name: 'Figma',
url: 'https://www.figma.com/files/recent', url: 'https://www.figma.com/files/recent',
}, },
{ g: {
key: 'g',
name: 'GitHub', name: 'GitHub',
search: '/search?q={}', searchTemplate: '/search?q={}',
url: 'https://github.com', url: 'https://github.com',
}, },
{ h: {
key: 'h',
name: 'Hypem', name: 'Hypem',
search: '/search/{}', searchTemplate: '/search/{}',
url: 'https://hypem.com/latest', url: 'https://hypem.com/latest',
}, },
{ i: {
key: 'i',
name: 'Inbox', name: 'Inbox',
url: 'https://mail.proton.me/u/0/inbox', url: 'https://mail.proton.me/u/0/inbox',
}, },
{ k: {
key: 'k',
name: 'Keep', name: 'Keep',
search: '/u/0/#search/text={}', searchTemplate: '/u/0/#search/text={}',
url: 'https://keep.google.com/u/0', url: 'https://keep.google.com/u/0',
}, },
{ l: {
key: 'l',
name: 'LinkedIn', name: 'LinkedIn',
search: '/search/results/all/?keywords={}', searchTemplate: '/search/results/all/?keywords={}',
url: 'https://www.linkedin.com', url: 'https://www.linkedin.com',
}, },
{ m: {
key: 'm',
name: 'Mail', name: 'Mail',
search: '/mail/u/0/#search/{}', searchTemplate: '/mail/u/0/#search/{}',
url: 'https://mail.google.com/mail/u/0/#inbox', url: 'https://mail.google.com/mail/u/0/#inbox',
}, },
{ n: {
key: 'n',
name: 'Notion', name: 'Notion',
url: 'https://www.notion.so', url: 'https://www.notion.so',
}, },
{ p: {
key: 'p',
name: 'Hunt', name: 'Hunt',
search: '/search?q={}', searchTemplate: '/search?q={}',
url: 'https://www.producthunt.com', url: 'https://www.producthunt.com',
}, },
{ r: {
key: 'r',
name: 'Reddit', name: 'Reddit',
search: '/search?q={}', searchTemplate: '/search?q={}',
url: 'https://www.reddit.com', url: 'https://www.reddit.com',
}, },
{ s: {
key: 's',
name: 'Spotify', name: 'Spotify',
search: '/search/{}', searchTemplate: '/search/{}',
url: 'https://open.spotify.com', url: 'https://open.spotify.com',
}, },
{ t: {
key: 't',
name: 'Twitter', name: 'Twitter',
search: '/search?q={}', searchTemplate: '/search?q={}',
url: 'https://twitter.com/home', url: 'https://twitter.com/home',
}, },
{ v: {
key: 'v',
name: 'Vercel', name: 'Vercel',
url: 'https://vercel.com', url: 'https://vercel.com',
}, },
{ x: {
key: 'x',
name: 'Netflix', name: 'Netflix',
search: '/search?q={}', searchTemplate: '/search?q={}',
url: 'https://www.netflix.com/browse', url: 'https://www.netflix.com/browse',
}, },
{ y: {
key: 'y',
name: 'YouTube', name: 'YouTube',
search: '/results?search_query={}', searchTemplate: '/results?search_query={}',
url: 'https://youtube.com/feed/subscriptions', url: 'https://youtube.com/feed/subscriptions',
}, },
], },
defaultCommand: {
searchTemplate: '/?q={}',
url: 'https://duckduckgo.com',
},
suggestions: { suggestions: {
0: ["0'8000", "0'8080"], 0: ["0'8000", "0'8080"],
a: ['a/cognito/v2/idp/user-pools', 'a/dynamodbv2#item-explorer'], a: ['a/cognito/v2/idp/user-pools', 'a/dynamodbv2#item-explorer'],
@ -256,7 +236,7 @@
</template> </template>
<script type="module"> <script type="module">
class CommandsComponent extends HTMLElement { class Commands extends HTMLElement {
#refs = { #refs = {
commands: null, commands: null,
}; };
@ -272,8 +252,7 @@
} }
#renderCommands() { #renderCommands() {
for (const { key, name, url } of CONFIG.commands) { for (const [key, { name, url }] of Object.entries(CONFIG.commands)) {
if (!name) continue;
const template = document.getElementById('command-template'); const template = document.getElementById('command-template');
const clone = template.content.cloneNode(true); const clone = template.content.cloneNode(true);
clone.querySelector('.command').href = url; clone.querySelector('.command').href = url;
@ -284,7 +263,7 @@
} }
} }
customElements.define('commands-component', CommandsComponent); customElements.define('commands-component', Commands);
</script> </script>
<template id="search-template"> <template id="search-template">
@ -412,7 +391,7 @@
</template> </template>
<script type="module"> <script type="module">
class SearchComponent extends HTMLElement { class Search extends HTMLElement {
static #PATH_DELIMITER = '/'; static #PATH_DELIMITER = '/';
static #SEARCH_DELIMITER = "'"; static #SEARCH_DELIMITER = "'";
static #SUGGESTION_LIMIT = 4; static #SUGGESTION_LIMIT = 4;
@ -468,6 +447,14 @@
}); });
} }
static #formatSearchUrl(url, searchPath, search) {
if (!searchPath) return url;
const baseUrl = Search.#stripUrlPath(url);
const urlQuery = encodeURIComponent(search);
searchPath = searchPath.replace(/{}/g, urlQuery);
return baseUrl + searchPath;
}
static #hasProtocol(s) { static #hasProtocol(s) {
return /^[a-zA-Z]+:\/\//i.test(s); return /^[a-zA-Z]+:\/\//i.test(s);
} }
@ -484,50 +471,35 @@
return { query, url }; return { query, url };
} }
const searchSplit = query.split(SearchComponent.#SEARCH_DELIMITER); if (CONFIG.commands[query]) {
const pathSplit = query.split(SearchComponent.#PATH_DELIMITER); const { key, url } = CONFIG.commands[query];
let defaultSearch = {}; return { key, query, url };
for (const cmd of CONFIG.commands) {
if (query === cmd.key) {
return { key: cmd.key, query, url: cmd.url };
}
if (cmd.search && searchSplit[0] === cmd.key) {
const splitBy = SearchComponent.#SEARCH_DELIMITER;
const search = SearchComponent.#shiftAndTrim(searchSplit, splitBy);
const url = SearchComponent.#prepSearch(cmd.url, cmd.search, search);
return { key: cmd.key, query, search, splitBy, url };
}
if (pathSplit[0] === cmd.key) {
const splitBy = SearchComponent.#PATH_DELIMITER;
const path = SearchComponent.#shiftAndTrim(pathSplit, splitBy);
const url = `${SearchComponent.#stripUrlPath(cmd.url)}/${path}`;
return { key: cmd.key, path, query, splitBy, url };
}
if (!cmd.key) {
const url = SearchComponent.#prepSearch(cmd.url, cmd.search, query);
defaultSearch = { key: cmd.key, query, search: query, url };
}
} }
return defaultSearch; let splitBy = Search.#SEARCH_DELIMITER;
const [searchKey, rawSearch] = query.split(new RegExp(`${splitBy}(.*)`));
if (CONFIG.commands[searchKey]) {
const { searchTemplate, url: base } = CONFIG.commands[searchKey];
const search = rawSearch.trim();
const url = Search.#formatSearchUrl(base, searchTemplate, search);
return { key: searchKey, query, search, splitBy, url };
}
splitBy = Search.#PATH_DELIMITER;
const [pathKey, path] = query.split(new RegExp(`${splitBy}(.*)`));
if (CONFIG.commands[pathKey]) {
const { url: base } = CONFIG.commands[pathKey];
const url = `${Search.#stripUrlPath(base)}/${path}`;
return { key: pathKey, path, query, splitBy, url };
}
const { searchTemplate, url: base } = CONFIG.defaultCommand;
const url = Search.#formatSearchUrl(base, searchTemplate, query);
return { query, search: query, url };
}; };
static #prepSearch(url, searchPath, search) {
if (!searchPath) return url;
const baseUrl = SearchComponent.#stripUrlPath(url);
const urlQuery = encodeURIComponent(search);
searchPath = searchPath.replace(/{}/g, urlQuery);
return baseUrl + searchPath;
}
static #shiftAndTrim(array, delimiter) {
return array.slice(1).join(delimiter).trim();
}
static #stripUrlPath(url) { static #stripUrlPath(url) {
const parser = document.createElement('a'); const parser = document.createElement('a');
parser.href = url; parser.href = url;
@ -542,7 +514,7 @@
} }
#execute(query) { #execute(query) {
const { url } = SearchComponent.#parseQuery(query); const { url } = Search.#parseQuery(query);
window.open(url, '_blank', 'noopener noreferrer'); window.open(url, '_blank', 'noopener noreferrer');
this.#close(); this.#close();
} }
@ -564,7 +536,7 @@
} }
#onInput = async () => { #onInput = async () => {
const q = SearchComponent.#parseQuery(this.#refs.input.value); const q = Search.#parseQuery(this.#refs.input.value);
if (!q.query) { if (!q.query) {
this.#close(); this.#close();
@ -573,9 +545,9 @@
let suggestions = CONFIG.suggestions[q.query] ?? []; let suggestions = CONFIG.suggestions[q.query] ?? [];
if (q.search && suggestions.length < SearchComponent.#SUGGESTION_LIMIT) { if (q.search && suggestions.length < Search.#SUGGESTION_LIMIT) {
const res = await SearchComponent.#fetchDuckDuckGoSuggestions(q.search); const res = await Search.#fetchDuckDuckGoSuggestions(q.search);
const formatted = SearchComponent.#attachSearchPrefix(res, q); const formatted = Search.#attachSearchPrefix(res, q);
suggestions = suggestions.concat(formatted); suggestions = suggestions.concat(formatted);
} }
@ -631,7 +603,7 @@
#renderSuggestions(suggestions, query) { #renderSuggestions(suggestions, query) {
this.#refs.suggestions.innerHTML = ''; this.#refs.suggestions.innerHTML = '';
const sliced = suggestions.slice(0, SearchComponent.#SUGGESTION_LIMIT); const sliced = suggestions.slice(0, Search.#SUGGESTION_LIMIT);
for (const [index, suggestion] of sliced.entries()) { for (const [index, suggestion] of sliced.entries()) {
const template = document.getElementById('suggestion-template'); const template = document.getElementById('suggestion-template');
@ -639,7 +611,7 @@
const ref = clone.querySelector('.suggestion'); const ref = clone.querySelector('.suggestion');
ref.dataset.index = index; ref.dataset.index = index;
ref.dataset.suggestion = suggestion; ref.dataset.suggestion = suggestion;
const escapedQuery = SearchComponent.#escapeRegexCharacters(query); const escapedQuery = Search.#escapeRegexCharacters(query);
const matched = suggestion.match(new RegExp(escapedQuery, 'i')); const matched = suggestion.match(new RegExp(escapedQuery, 'i'));
if (matched) { if (matched) {
@ -661,7 +633,7 @@
} }
} }
customElements.define('search-component', SearchComponent); customElements.define('search-component', Search);
</script> </script>
<style> <style>