dev21w42b

This commit is contained in:
Victor Westerlund 2021-10-24 09:31:14 +02:00
parent b8960d61ad
commit 7cd3bdb6f4
4 changed files with 99 additions and 47 deletions

View file

@ -60,6 +60,19 @@ header h1 {
gap: var(--padding);
}
#results > p {
text-align: center;
}
#results > p.error {
color: red;
}
#results > p.error::before {
content: "oh crap, ";
font-weight: bold;
}
.card {
--padding-multiplier: 1.2;
flex: none;
@ -130,6 +143,30 @@ header h1 {
#search input:focus {
outline: solid 5px rgba(var(--palette-contrast),.2);
}
/* ---- */
#results::-webkit-scrollbar {
width: 10px;
}
#results::-webkit-scrollbar-track {
background-color: rgba(var(--palette-contrast),.04);
}
#results::-webkit-scrollbar-thumb {
background: var(--swatch-contrast);
}
#results::-webkit-scrollbar-thumb:hover {
background: var(--swatch-background);
outline: solid 2px rgba(var(--palette-contrast),1);
}
#results::-webkit-scrollbar-thumb:active {
background: rgba(var(--palette-contrast),.1);
outline: solid 2px rgba(var(--palette-contrast),1);
}
}
@media (prefers-color-scheme: dark) {

View file

@ -5,36 +5,76 @@ export default class Search {
this.endpoint = new URL("api/search",window.location.href);
this.lastQuery = "";
this.timeout = null;
this.throttle = null;
this.results = {
element: results,
set content(html) {
this.results?.insertAdjacentHTML("beforeend",html);
this.results = results;
this.input = input;
this.input?.addEventListener("keyup",event => this.keyEvent(event)) ?? false;
}
};
input?.addEventListener("keydown",event => this.keyEvent(event)) ?? false;
clearResults() {
while(this.results.firstChild) {
this.results.removeChild(this.results.lastChild);
}
}
output(html) {
this.clearResults();
if(typeof html === "string") {
this.results.insertAdjacentHTML("beforeEnd",html);
return;
}
this.results.appendChild(html);
}
status(text,classList = false) {
const element = document.createElement("p");
if(classList !== false) {
element.classList = classList;
}
element.innerText = text;
this.output(element);
}
async search(query) {
const url = new URL(this.endpoint);
url.searchParams.set("q",query);
const timeout = setTimeout(() => this.showSpinner(),1000);
const api = await fetch(url);
const timeout = new Promise(reject => setTimeout(() => reject("Request timed out"),3000));
const api = fetch(url);
return result;
const result = Promise.race([api,timeout]);
result.then(response => {
if(!response.ok) {
this.status("something went wrong on my side","error");
console.error("Response from server:",response);
return;
}
this.output(response.text);
});
result.catch(error => this.status(error,"error"));
}
// Wait until the user stops typing for a few miliseconds
queue(query) {
clearTimeout(this.timeout);
this.timeout = setTimeout(() => this.search(query),500);
clearTimeout(this.throttle);
this.throttle = setTimeout(() => this.search(query),500);
}
async keyEvent(event) {
if(event.target.value === this.lastQuery) {
const query = event.target.value;
if(query.length < 1) {
this.status("search results will appear here as you type");
return;
}
if(query === this.lastQuery) {
return false;
}
this.queue(event.target.value);
this.lastQuery = query;
this.status("searching..");
this.queue(query);
}
}

View file

@ -1,25 +1,7 @@
import { default as Search } from "./modules/Search.mjs";
// import { default as Monkey } from "./modules/monkeydo/Monkeydo.mjs";
const searchField = document.getElementById("search");
const searchBox = document.getElementById("search")?.children[0] ?? false;
const resultsContainer = document.getElementById("results");
const search = new Search(searchField,resultsContainer);
window.addEventListener("keydown",() => searchField.focus());
/* const monkey = new Monkey({
keyPress: (key) => searchField.dispatchEvent(new KeyboardEvent("keydown",{"key":key})),
log: (message) => console.log(message)
});
monkey.load(JSON.stringify({
tasks: [
[200,"log","hello friend"],
[200,"keyPress","h"],
[400,"keyPress","e"],
[100,"keyPress","l"],
[500,"keyPress","l"],
[700,"keyPress","o"]
]
})).then(() => monkey.do());
*/
new Search(searchBox,resultsContainer);
window.addEventListener("keydown",() => searchBox.focus());

View file

@ -18,22 +18,15 @@
<input type="text" placeholder="start typing to search..">
</div>
<div id="results">
<div class="card">
<!--<div class="card">
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M3 2.75A2.75 2.75 0 0 1 5.75 0h14.5a.75.75 0 0 1 .75.75v20.5a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h5.25v-4H6A1.5 1.5 0 0 0 4.5 18v.75c0 .716.43 1.334 1.05 1.605a.75.75 0 0 1-.6 1.374A3.25 3.25 0 0 1 3 18.75v-16zM19.5 1.5V15H6c-.546 0-1.059.146-1.5.401V2.75c0-.69.56-1.25 1.25-1.25H19.5z" fill="currentColor"/><path d="M7 18.25a.25.25 0 0 1 .25-.25h5a.25.25 0 0 1 .25.25v5.01a.25.25 0 0 1-.397.201l-2.206-1.604a.25.25 0 0 0-.294 0L7.397 23.46a.25.25 0 0 1-.397-.2v-5.01z" fill="currentColor"/></svg>
<p>github/&ZeroWidthSpace;victorwesterlund.com</p>
</div>
<p>Lorem ipsum</p>
<p class="button">read more</p>
</div>
<div class="card">
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M3 2.75A2.75 2.75 0 0 1 5.75 0h14.5a.75.75 0 0 1 .75.75v20.5a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h5.25v-4H6A1.5 1.5 0 0 0 4.5 18v.75c0 .716.43 1.334 1.05 1.605a.75.75 0 0 1-.6 1.374A3.25 3.25 0 0 1 3 18.75v-16zM19.5 1.5V15H6c-.546 0-1.059.146-1.5.401V2.75c0-.69.56-1.25 1.25-1.25H19.5z" fill="currentColor"/><path d="M7 18.25a.25.25 0 0 1 .25-.25h5a.25.25 0 0 1 .25.25v5.01a.25.25 0 0 1-.397.201l-2.206-1.604a.25.25 0 0 0-.294 0L7.397 23.46a.25.25 0 0 1-.397-.2v-5.01z" fill="currentColor"/></svg>
<p>github/victorwesterlund.com</p>
</div>
<p>Lorem ipsum</p>
<p class="button">read more</p>
</div>
</div>-->
<p>search results will appear here as you type</p>
</div>
<script type="module" src="assets/js/search.js"></script>
</body>