Skip to content

Commit

Permalink
Merge pull request #73 from hkamran80/update-search
Browse files Browse the repository at this point in the history
Update search results
  • Loading branch information
Carlgo11 authored Nov 2, 2024
2 parents a853e2a + e4fc1ba commit 684bf98
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 129 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ <h5 class="modal-title">Attention!</h5>
<script type="module" src="/src/components/style.js"></script>
<script type="module" src="/src/components/regions.js"></script>
<script type="module" src="/src/components/category.js"></script>
<script type="module" src="/src/components/search.jsx"></script>
<script type="module" src="/src/components/search.js"></script>
</body>
</html>
136 changes: 136 additions & 0 deletions src/components/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { html } from "htm/preact";
import { render } from "preact";
import algoliasearch from "algoliasearch";
import Table from "./table";

const client = algoliasearch(
import.meta.env.VITE_ALGOLIA_APP_ID,
import.meta.env.VITE_ALGOLIA_API_KEY,
);
const index = client.initIndex(import.meta.env.VITE_ALGOLIA_INDEX_NAME);

const region = window.location.pathname.replace(/\//g, "");

const searchOptions = {
hitsPerPage: 500,
attributesToRetrieve: [
"name",
"category",
"2fa",
"regions",
"contact",
"documentation",
"recovery",
"notes",
"img",
"custom-software",
"custom-hardware",
],
};

function hitToAPI(hit) {
const attributes = { domain: hit.objectID, categories: hit.category };

if (hit["2fa"]) attributes.methods = hit["2fa"];
if (hit["custom-software"])
attributes["custom-software"] = hit["custom-software"];
if (hit["custom-hardware"])
attributes["custom-hardware"] = hit["custom-hardware"];
if (hit.documentation) attributes.documentation = hit.documentation;
if (hit.recovery) attributes.recovery = hit.recovery;
if (hit.notes) attributes.notes = hit.notes;
if (hit.img) attributes.img = hit.img;
if (hit.contact) attributes.contact = hit.contact;
if (hit.regions) attributes.regions = hit.regions;

return [hit.name, attributes];
}

/**
* Send a search query to Algolia
*
* @param {string} query - The query
*/
function sendSearch(query) {
if (
query === undefined ||
query === "" ||
(query.length < 2 && !query.match("^[x|X]$")) ||
query.match("http(s)?://.*") ||
query.match("^2fa(:)?$")
) {
document.getElementById("categories").style.display = "grid";
render(null, document.getElementById("search-categories"));
} else {
if (query.match("^[x|X]$")) query = '"X"';

let filter = [];
let _query = [];
query.split(" ").map((item) => {
// Add word to filter<str> & remove word from _query<str[]>
if (item.match(/\w:\w/g)) {
filter.push(item);
} else {
_query.push(item);
}
});

// Convert back _query<str[]> to query<str>
query = _query.join(" ");

// Add fetched filters to search options array
const options = searchOptions;
if (filter) options["facetFilters"] = filter;

// Execute search
index.search(query, options).then(({ hits }) => {
const entries = hits
.map((hit) => hitToAPI(hit))
.filter(([, entry]) => !entry.regions || entry.regions.includes(region))
.sort(([a], [b]) => a.localeCompare(b));

if (entries.length !== 0) {
const table = html`<${Table}
Category="search"
Title="Search Results"
search=${entries}
/>`;

document.getElementById("categories").style.display = "none";
render(null, document.getElementById("search-categories"));
render(table, document.getElementById("search-categories"));
} else {
render(
<p>No results found.</p>,
document.getElementById("search-categories"),
);
}
});
}
}

function Search() {
let timeout = null;

return html`
<div id="outerSearchBox">
<input
type="search"
class="search"
aria-label="Search the directory"
placeholder="Search websites by name, URL or method (e.g. 2fa:sms)"
autocomplete="off"
spellcheck="false"
aria-keyshortcuts="s"
onInput=${(event) => {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => sendSearch(event.target.value), 1000);
}}
/>
<a href="https://algolia.com/" title="Search by Algolia"></a>
</div>
`;
}

render(html`<${Search} />`, document.getElementById("search"));
128 changes: 0 additions & 128 deletions src/components/search.jsx

This file was deleted.

0 comments on commit 684bf98

Please sign in to comment.