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">
<input class="search" type="text" id="search" placeholder="Go to ... (Try typing `help` or `?`)">
<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>
<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.

View File

@ -1,7 +1,10 @@
[
["Pages", "/pages/"],
["Resources", "/pages/resources"],
["Recommended", "/pages/recommended"],
["Grade Calculator", "/pages/grade-calc/"],
["GitHub", "https://github.com/lambdapaul"]
{"title":"Pages", "link": "/pages/"},
{"title":"Resources", "link": "/pages/resources"},
{"title":"Recommended", "link": "/pages/recommended"},
{"title":"Grade Calculator", "link": "/pages/grade-calc/"},
{"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
(function () {
var client = new XMLHttpRequest();
setTimeout(() => {
let searchField = document.querySelector("#search");
if (searchField === null)
return;
let client = new XMLHttpRequest();
client.open("GET", "/pages.json");
client.onreadystatechange = () => {
if (client.readyState === 4)
fuzzyInit(client.responseText);
}
client.send();
document.querySelector("#search").focus();
})();
searchField.focus();
}, 50);
function fuzzyInit(pagesFileName) {
if (pagesFileName == "")
return;
let searchField = document.querySelector("#search");
let resultBlock = document.querySelector("#results");
if (searchField === null || resultBlock === null)
return;
var pages;
try {
pages = JSON.parse(pagesFileName);
@ -25,66 +33,97 @@ function fuzzyInit(pagesFileName) {
pages.sort();
document.querySelector("#search")
.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;
}
searchField.addEventListener("keyup", (e) => {
// help
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."
let searchValue = searchField.value ? searchField.value.toLowerCase() : "";
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;
}
// if (document.querySelector("#search").value === ""){
// document.querySelector("#results").innerHTML = "Try entering something into the input field...";
// return;
// }
// help
if (searchValue === "?" || searchValue === "help") {
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;
}
let results = [];
for (const [i, [title, page]] of pages.entries()) {
ret = fuzzySearch(title, document.querySelector("#search").value);
for (const [i, page] of pages.entries()) {
ret = fuzzySearch(page.title, searchValue);
if (ret === null)
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 = "";
for (const [hfRet, rlink] of results) {
output += `<a class="hyperlink" href="${rlink}"><div class="name">${hfRet.first}</div><div class="link">${rlink}</div></a>`;
resultBlock.innerHTML = "";
for (const res of results) {
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 == "")
output = "No matches found."
document.querySelector("#results").innerHTML = output;
if (results.length <= 0)
resultBlock.innerHTML = "Unknown command or no matching pages found."
}
);
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) {
let search = input.replace(/\s/g, "");
function fuzzySearch(findIn, find) {
let search = find.replace(/\s/g, "");
search = search.toLowerCase();
let tokens = list.split('');
let tokens = findIn.split('');
let pc = 0;
let score = 0;
for (const [i, ch] of tokens.entries()) {
if (ch.toLowerCase() == search[pc]) {
if (ch.toLowerCase() === search[pc]) {
score += i - pc;
tokens[i] = `<span class="highlight">${ch}</span>`;
pc++;
@ -92,8 +131,9 @@ function fuzzySearch(list, input) {
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;
}