Improve UX and add more page links

This commit is contained in:
Paul 2021-09-24 00:08:37 -04:00
parent e2cfd0f266
commit 7e15316ad6
4 changed files with 183 additions and 53 deletions

87
404.html Normal file
View File

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PaulW.XYZ /</title>
<meta name="description" content="Paul's Homepage. I do things. Sporadically.">
<link rel="stylesheet" href="/stylesheets/persia.css">
</head>
<body>
<svg class="m-icon"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg4546"
version="1.1"
viewBox="0 0 67.733332 67.733331"
height="256"
width="256">
<defs
id="defs4550" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(0,-229.26668)"
id="layer1">
<path
id="rect4524-2"
d="M -3.5234382e-6,249.58668 9.0311079,263.13335 -3.5234382e-6,276.68002 v 13.54667 L 18.06222,263.13335 -3.5234382e-6,236.04001 Z"
style="opacity:1;fill:#ffffff;fill-opacity:0.2;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="rect4524-1-7"
d="M 4.5155513,229.26668 27.093332,263.13335 4.5155524,297.00002 h 9.0311116 l 22.57778,-33.86667 -22.57778,-33.86667 z"
style="opacity:1;fill:#ffffff;fill-opacity:0.73333333;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="rect4524-1-8"
d="m 13.546665,229.26668 22.57778,33.86667 -22.57778,33.86667 h 9.031111 l 18.062225,-27.09334 18.062224,27.09334 h 9.031113 L 45.155557,263.13335 22.577776,229.26668 Z"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:0.73333333;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 36.124444,276.68002 13.546667,20.32 h 9.031113 L 40.64,269.90668 Z"
id="path4779" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:0.46666667;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M -3.5234382e-6,236.04001 18.06222,263.13335 -3.5234382e-6,290.22669 v 6.77333 H 4.5155524 L 27.093333,263.13335 4.5155524,229.26668 H -3.5234382e-6 Z"
id="path4781" />
<path
id="path4783"
d="m 31.608889,283.45335 9.03111,13.54667 h 9.031112 l -13.546667,-20.32 z"
style="opacity:1;fill:#ffffff;fill-opacity:0.46666667;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path4783-1"
d="m 27.093332,290.22669 4.515557,6.77333 H 40.64 l -9.031111,-13.54667 z"
style="opacity:1;fill:#ffffff;fill-opacity:0.2;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>
<nav>
<h1 class="title"><a href="/">PaulW.XYZ</a> / ... ??? </h1>
</nav>
<div class="block">
<h1>Error 404: Not Found</h1>
<p>
<strong>Uh oh! The page you are looking for does not exist...</strong><br>
<strong><a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes">[Wikipedia] Learn more about HTTP status codes.</a></strong>
</p>
</div>
<footer>
<a href="https://github.com/lambdapaul/www">Hosted on GitHub</a>
&copy; 2021 Paul W.
</footer>
</body>
</html>

View File

@ -74,7 +74,7 @@
<div class="fuzzynav"> <div class="fuzzynav">
<input class="search" type="text" id="search" placeholder="Go to ... (Try typing `help` or `?`)"> <input class="search" type="text" id="search" placeholder="Go to ... (Try typing `help` or `?`)">
<div id="results" class="results"> <div id="results" class="results">
<p><strong>Using the search bar will clear this message and list responses based on your query.</strong></p> <p><strong>Press any key to clear this message...</strong></p>
<p>This is a draft of the rationale behind writing pages the way I have. I do not like the traditional web conventions so this is where I experiment the most with interfacing elements. The navigation pane-based design works when they are simple and easy to understand. When they get too complex, people rely on using search bars to get where they want. My goal is to find a method to eliminate the visual noise of the complex navigation panes and find a reasonable alternative them while being easy to use. </p> <p>This is a draft of the rationale behind writing pages the way I have. I do not like the traditional web conventions so this is where I experiment the most with interfacing elements. The navigation pane-based design works when they are simple and easy to understand. When they get too complex, people rely on using search bars to get where they want. My goal is to find a method to eliminate the visual noise of the complex navigation panes and find a reasonable alternative them while being easy to use. </p>
<h2 id="page-categorization">Page Categorization</h2> <h2 id="page-categorization">Page Categorization</h2>
<p>The home page or the index page solely acts as a gateway to all the other pages on the site. <p>The home page or the index page solely acts as a gateway to all the other pages on the site.

View File

@ -1,7 +1,10 @@
[ [
["Pages", "/pages/"], {"title":"Pages", "link": "/pages/"},
["Resources", "/pages/resources"], {"title":"Resources", "link": "/pages/resources"},
["Recommended", "/pages/recommended"], {"title":"Recommended", "link": "/pages/recommended"},
["Grade Calculator", "/pages/grade-calc/"], {"title":"Grade Calculator", "link": "/pages/grade-calc/"},
["GitHub", "https://github.com/lambdapaul"] {"title":"GitHub", "link": "https://github.com/lambdapaul"},
{"title":"GitLab", "link": "https://gitlab.com/lambdapaul"},
{"title":"Mastodon", "link": "https://mastodon.social/@lambdapaul"},
{"title":"Keybase", "link": "https://keybase.io/lambdapaul"}
] ]

View File

@ -1,19 +1,27 @@
// good luck reading through this setTimeout(() => {
(function () { let searchField = document.querySelector("#search");
var client = new XMLHttpRequest(); if (searchField === null)
return;
let client = new XMLHttpRequest();
client.open("GET", "/pages.json"); client.open("GET", "/pages.json");
client.onreadystatechange = () => { client.onreadystatechange = () => {
if (client.readyState === 4) if (client.readyState === 4)
fuzzyInit(client.responseText); fuzzyInit(client.responseText);
} }
client.send(); client.send();
document.querySelector("#search").focus(); searchField.focus();
})(); }, 50);
function fuzzyInit(pagesFileName) { function fuzzyInit(pagesFileName) {
if (pagesFileName == "") if (pagesFileName == "")
return; return;
let searchField = document.querySelector("#search");
let resultBlock = document.querySelector("#results");
if (searchField === null || resultBlock === null)
return;
var pages; var pages;
try { try {
pages = JSON.parse(pagesFileName); pages = JSON.parse(pagesFileName);
@ -25,66 +33,97 @@ function fuzzyInit(pagesFileName) {
pages.sort(); pages.sort();
document.querySelector("#search") searchField.addEventListener("keyup", (e) => {
.addEventListener("keyup", (e) => {
switch (e.code) {
case "Enter":
if (document.querySelector("#results").childNodes[0].href === undefined)
return;
window.location = document.querySelector("#results").childNodes[0].href;
break;
case "ArrowDown":
console.log("S");
break;
case "ArrowUp":
console.log("W");
break;
}
// help let searchValue = searchField.value ? searchField.value.toLowerCase() : "";
if (document.querySelector("#search").value === "?" || document.querySelector("#search").value == "help") {
document.querySelector("#results").innerHTML = "Enter a page or directory name. If do not know any, clear the search field to list everything. Using the <code>Enter</code> key would take you to the first page in list, if it is not empty." if (e.code === "Enter") {
if (resultBlock.childNodes === null
|| resultBlock.childNodes[0] === null
|| resultBlock.childNodes[0].href === undefined)
return;
window.location = resultBlock.childNodes[0].href;
return; return;
} }
// help
// if (document.querySelector("#search").value === ""){ if (searchValue === "?" || searchValue === "help") {
// document.querySelector("#results").innerHTML = "Try entering something into the input field..."; resultBlock.innerHTML = "<h2>Help</h2>Enter a page or directory name.<br>If do not know any, clear the search field to list everything.<br> Using the <code>Enter</code> key would take you to the first page in list, if the list is not empty.<br>Alternatively, use the <code>Up</code> and <code>Down</code> arrow keys to select the page you want and use the <code>Enter</code> key."
// return; return;
// } }
let results = []; let results = [];
for (const [i, [title, page]] of pages.entries()) { for (const [i, page] of pages.entries()) {
ret = fuzzySearch(title, document.querySelector("#search").value); ret = fuzzySearch(page.title, searchValue);
if (ret === null) if (ret === null)
continue; continue;
results.push([ret, page]); results.push({formatted: ret.formatted, link: page.link, score: ret.score});
} }
results.sort((x, y) => {return x[0].second - y[0].second}); results.sort((x, y) => {return x.score - y.score});
let output = ""; resultBlock.innerHTML = "";
for (const [hfRet, rlink] of results) { for (const res of results) {
output += `<a class="hyperlink" href="${rlink}"><div class="name">${hfRet.first}</div><div class="link">${rlink}</div></a>`; linkBlock = document.createElement("a");
linkBlock.classList.add("hyperlink");
linkBlock.href = res.link;
linkBlock.innerHTML = `<div class="name">${res.formatted}</div><div class="link">${res.link}</div>`;
resultBlock.appendChild(linkBlock);
} }
if (output == "") if (results.length <= 0)
output = "No matches found." resultBlock.innerHTML = "Unknown command or no matching pages found."
document.querySelector("#results").innerHTML = output;
} }
); );
document.body.addEventListener("keyup", (e) => {
if (e.code === "ArrowDown" || e.code === "ArrowUp") {
if (resultBlock.childNodes === null)
return;
resultNodes = resultBlock.childNodes;
if (resultNodes.length <= 1)
return;
let currNode = document.activeElement;
if (searchField === currNode) {
if (e.code === "ArrowDown")
resultNodes[0].focus();
else
resultNodes[resultNodes.length - 1].focus();
return;
}
if (Array.from(resultNodes).indexOf(currNode) < 0)
return;
if (e.code === "ArrowDown")
if (currNode.nextElementSibling === null)
searchField.focus();
else
currNode.nextElementSibling.focus();
else if (e.code === "ArrowUp")
if (currNode.previousElementSibling === null)
searchField.focus();
else
currNode.previousElementSibling.focus();
return;
}
});
} }
function fuzzySearch(list, input) { function fuzzySearch(findIn, find) {
let search = input.replace(/\s/g, ""); let search = find.replace(/\s/g, "");
search = search.toLowerCase(); search = search.toLowerCase();
let tokens = list.split(''); let tokens = findIn.split('');
let pc = 0; let pc = 0;
let score = 0; let score = 0;
for (const [i, ch] of tokens.entries()) { for (const [i, ch] of tokens.entries()) {
if (ch.toLowerCase() == search[pc]) { if (ch.toLowerCase() === search[pc]) {
score += i - pc; score += i - pc;
tokens[i] = `<span class="highlight">${ch}</span>`; tokens[i] = `<span class="highlight">${ch}</span>`;
pc++; pc++;
@ -92,8 +131,9 @@ function fuzzySearch(list, input) {
return null; return null;
} }
} }
if (search.length != pc)
return null;
return {first: tokens.join(''), second: (score / search.length)}; if (search.length === pc)
return {formatted: tokens.join(''), score: (score / search.length)};
return null;
} }