mirror of
https://codeberg.org/vlw/victorwesterlund.com.git
synced 2025-09-14 03:23:41 +02:00
80 lines
No EOL
1.8 KiB
JavaScript
80 lines
No EOL
1.8 KiB
JavaScript
export default class Search {
|
|
constructor(input,results) {
|
|
const self = this;
|
|
|
|
this.endpoint = new URL("api/search",window.location.href);
|
|
|
|
this.lastQuery = "";
|
|
this.throttle = null;
|
|
|
|
this.results = results;
|
|
this.input = input;
|
|
this.input?.addEventListener("keyup",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 = new Promise(reject => setTimeout(() => reject("Request timed out"),3000));
|
|
const api = fetch(url);
|
|
|
|
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.throttle);
|
|
this.throttle = setTimeout(() => this.search(query),500);
|
|
}
|
|
|
|
async keyEvent(event) {
|
|
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.lastQuery = query;
|
|
this.status("searching..");
|
|
this.queue(query);
|
|
}
|
|
} |