mirror of
https://codeberg.org/vlw/victorwesterlund.com.git
synced 2025-09-14 11:33:41 +02:00
dev21w42b
This commit is contained in:
parent
b8960d61ad
commit
7cd3bdb6f4
4 changed files with 99 additions and 47 deletions
|
@ -60,6 +60,19 @@ header h1 {
|
||||||
gap: var(--padding);
|
gap: var(--padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#results > p {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#results > p.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#results > p.error::before {
|
||||||
|
content: "oh crap, ";
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
--padding-multiplier: 1.2;
|
--padding-multiplier: 1.2;
|
||||||
flex: none;
|
flex: none;
|
||||||
|
@ -130,6 +143,30 @@ header h1 {
|
||||||
#search input:focus {
|
#search input:focus {
|
||||||
outline: solid 5px rgba(var(--palette-contrast),.2);
|
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) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
|
@ -5,36 +5,76 @@ export default class Search {
|
||||||
this.endpoint = new URL("api/search",window.location.href);
|
this.endpoint = new URL("api/search",window.location.href);
|
||||||
|
|
||||||
this.lastQuery = "";
|
this.lastQuery = "";
|
||||||
this.timeout = null;
|
this.throttle = null;
|
||||||
|
|
||||||
this.results = {
|
this.results = results;
|
||||||
element: results,
|
this.input = input;
|
||||||
set content(html) {
|
this.input?.addEventListener("keyup",event => this.keyEvent(event)) ?? false;
|
||||||
this.results?.insertAdjacentHTML("beforeend",html);
|
}
|
||||||
}
|
|
||||||
};
|
clearResults() {
|
||||||
input?.addEventListener("keydown",event => this.keyEvent(event)) ?? false;
|
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) {
|
async search(query) {
|
||||||
const url = new URL(this.endpoint);
|
const url = new URL(this.endpoint);
|
||||||
url.searchParams.set("q",query);
|
url.searchParams.set("q",query);
|
||||||
|
|
||||||
const timeout = setTimeout(() => this.showSpinner(),1000);
|
const timeout = new Promise(reject => setTimeout(() => reject("Request timed out"),3000));
|
||||||
const api = await fetch(url);
|
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) {
|
queue(query) {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.throttle);
|
||||||
this.timeout = setTimeout(() => this.search(query),500);
|
this.throttle = setTimeout(() => this.search(query),500);
|
||||||
}
|
}
|
||||||
|
|
||||||
async keyEvent(event) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
this.queue(event.target.value);
|
|
||||||
|
this.lastQuery = query;
|
||||||
|
this.status("searching..");
|
||||||
|
this.queue(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,7 @@
|
||||||
import { default as Search } from "./modules/Search.mjs";
|
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 resultsContainer = document.getElementById("results");
|
||||||
|
|
||||||
const search = new Search(searchField,resultsContainer);
|
new Search(searchBox,resultsContainer);
|
||||||
window.addEventListener("keydown",() => searchField.focus());
|
window.addEventListener("keydown",() => searchBox.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());
|
|
||||||
*/
|
|
|
@ -18,22 +18,15 @@
|
||||||
<input type="text" placeholder="start typing to search..">
|
<input type="text" placeholder="start typing to search..">
|
||||||
</div>
|
</div>
|
||||||
<div id="results">
|
<div id="results">
|
||||||
<div class="card">
|
<!--<div class="card">
|
||||||
<div>
|
<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>
|
<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>
|
<p>github/​victorwesterlund.com</p>
|
||||||
</div>
|
</div>
|
||||||
<p>Lorem ipsum</p>
|
<p>Lorem ipsum</p>
|
||||||
<p class="button">read more</p>
|
<p class="button">read more</p>
|
||||||
</div>
|
</div>-->
|
||||||
<div class="card">
|
<p>search results will appear here as you type</p>
|
||||||
<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>
|
</div>
|
||||||
<script type="module" src="assets/js/search.js"></script>
|
<script type="module" src="assets/js/search.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Add table
Reference in a new issue