initial commit

This commit is contained in:
remi 2022-06-07 00:18:05 +02:00
commit 5fc1858e75
5 changed files with 322 additions and 0 deletions

BIN
font.otf Normal file

Binary file not shown.

61
index.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>heonian web dictionary</title>
<meta name="description" content="now with 50% less unix requirement">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./main.css">
<link rel="preload" href="./wordlist.json" as="fetch">
</head>
<body>
<!--
entry screen, centered {
hisho
[search box, has a button to click to toggle heonian IME]
[show all words] [other resource links, idk link to google doc, heonian-conversation, github]
}
click search box or show all words, screen animates search box and. title and all that to top of screen
and. results appear n stuff,
Vewy Cool Fancy Totally Not Waste Of Resources
RUBY TAGS HOLY SHIT
um,
results layout would kinda look like,,,
[words - 420 found / expressions - 69 found / wahtever else - ygettheidea] (click one to filter to just those)
word {
word [word in latin, in ruby]
[tags like. common word, slang, formal???, type, etc]
[maybe formal and non-formal versions of word could be shown]
[show inflections button (steal from jisho)]
[play audio clip would also be cool....]
short english translation, followed by . long description/explanation of word
maybe an example? usage?
and. source/who made it/etc
repeat for all meanings of word,
}
-->
<header class="fullscreen">
<span class="heonian"></span>
<div id="search">
<input type="text" placeholder="loading...">
<button>
H
</button>
</div>
<div>
<a href="#">show all words</a> <a href="#">uh. something else</a>
</div>
<noscript>turn on js doofus</noscript>
</header>
<main>
</main>
<script src="./main.js"></script>
</body>
</html>

128
main.css Normal file
View File

@ -0,0 +1,128 @@
@font-face {
font-family: "heonian";
src: url("./font.otf");
}
@keyframes clearly-cheating {
0% {
opacity: 1;
transform: translateY(0);
}
50% {
opacity: 0;
transform: translateY(-20px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
:root {
--font: "Helvetica Neue", Helvetica, Arial, sans-serif;
--font-h: "heonian", "Helvatica Neue", Helvetica, Arial, sans-serif;
--nice-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
--grey: rgb(226, 226, 226);
--darkgrey: rgb(150, 150, 150);
}
body {
margin: 0;
padding: 0;
font-family: var(--font);
}
a {
color: rgb(119, 205, 233);
text-decoration: none;
}
a:hover {
text-decoration: underline;
cursor: pointer;
}
.heonian {
font-family: "heonian";
}
header {
display: flex;
justify-content: space-around;
align-items: center;
flex-flow: row wrap;
padding-bottom: 8px;
border-bottom: 1px solid var(--grey);
}
header * {
margin: 8px;
}
header #search {
flex-grow: 1;
white-space: nowrap;
overflow-x: hidden;
}
header #search button {
all: unset;
position: relative;
left: -64px;
top: -2px;
width: 48px;
text-align: center;
height: 2rem;
border-left: 1px solid var(--grey);
}
header input {
height: 2rem;
font-size: 1.5rem;
font-family: var(--font-h);
padding: 4px;
padding-right: calc(4px + 48px); /* space for heonian ime button */
border: 1px solid var(--grey);
border-radius: 4px;
font-weight: 100;
transition: border-color 0.3s;
width: calc(100% - 52px - 24px);
}
header input:focus {
outline: none;
border: 1px solid var(--darkgrey);
}
header span.heonian {
font-size: 1.5rem;
}
header.fullscreen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
flex-flow: column;
justify-content: center;
padding-bottom: 0px;
border-bottom: none;
}
header.fullscreen span.heonian {
font-size: 8rem;
}
header.fullscreen #search {
flex-grow: 0;
max-width: 500px;
}
.header-animation {
animation: clearly-cheating 1s ease-in-out;
}
.header-animation-reverse {
animation: clearly-cheating 1s ease-in-out reverse;
}

118
main.js Normal file
View File

@ -0,0 +1,118 @@
let json = null;
let searchDictionary = {};
let header = null;
let main = null;
function animateHeader(inout = false) {
//todo: debounce this
if (inout) {
header.classList.add("header-animation-reverse");
header.classList.remove("header-animation");
setTimeout(() => {
header.classList.add("fullscreen");
},500);
setTimeout(() => {
header.classList.remove("header-animation-reverse");
},1000);
} else {
header.classList.add("header-animation");
header.classList.remove("header-animation-reverse");
setTimeout(() => {
header.classList.remove("fullscreen");
},500);
setTimeout(() => {
header.classList.remove("header-animation");
},1000);
}
//somewhere here we animate in the actual page too, but it.. doesnt exist yet
}
// on space animateHeader()
document.addEventListener("keydown", (e) => {
//on / key press
if (e.keyCode === 191) {
e.preventDefault();
header.querySelector("input").focus();
}
if (e.keyCode === 27) {
//if search box not focused, and if we're not on the home page, go back to home page
if (!header.querySelector("input").matches(":focus") && !header.classList.contains("fullscreen")) {
e.preventDefault();
animateHeader(true);
}
}
if (e.keyCode === 13) {
if (header.querySelector("input").matches(":focus")) {
//search
e.preventDefault();
animateHeader(); //just in case
doSearch();
}
}
});
function stripWord(word) {
return word.replace(/[^a-zA-Z]/g, "");
}
function loadDictionary() {
fetch("/wordlist.json").then((e) => {
if (e.status === 200) {
//convert to json lmao
e.json().then((e) => {
json = e;
let values = Object.values(json);
let keys = Object.keys(json);
//prepare search. maybe async this if we're loading a specific word?
for (let i = 0; i < keys.length; i++) {
//create array
searchDictionary[keys[i]] = [];
//add: base word (obvious, will always exist)
searchDictionary[keys[i]].push(stripWord(keys[i]));
//add: base word, but in heonian (todo, needs translator)
//add: translation (will always exist, i hope)
searchDictionary[keys[i]].push(stripWord(values[i].translation));
}
//ok, we're all ready!
document.querySelector("header input").placeholder = "search";
});
} else {
alert("yeah something went horribly wrong loading the wordlist so uh,,, certified ike moment");
return;
}
});
}
function search(word) {
word = stripWord(word);
let result = [];
for (let key in searchDictionary) {
for (let value in searchDictionary[key]) {
if (searchDictionary[key][value].includes(word)) {
result.push(key);
}
}
}
return result;
}
function doSearch() {
let results = search(header.querySelector("input").value);
if (results.length == 0) {
main.innerHTML = "no results lulw";
} else {
//actually render results or w/e
}
}
window.onload = () => {
header = document.querySelector("header");
main = document.querySelector("main");
loadDictionary();
}

15
wordlist.json Normal file
View File

@ -0,0 +1,15 @@
{
"a.bae": {
"translation": "young",
"type": "modifier"
},
"a.e mo?": {
"translation": "isn't it right?",
"type": "expression"
},
"a.ga.ka": {
"translation": "at, towards, for",
"type": "marker",
"notes": "also used like"
}
}