Skip to content

Instantly share code, notes, and snippets.

@briandeheus
Created February 24, 2022 11:56
Show Gist options
  • Save briandeheus/6a524197583191611c8a3e67b12bd6d2 to your computer and use it in GitHub Desktop.
Save briandeheus/6a524197583191611c8a3e67b12bd6d2 to your computer and use it in GitHub Desktop.
const http = require('http');
const QUESTIONS = [
'Have you found happiness?',
'What makes you happy?',
'What would make today better?',
'Are you drinking enough water?',
'Have you eaten two pieces of fruit today?',
'Have you eaten three pieces of vegetables today?',
'Are you reading this?'
]
const EMOJI = [
"😂", "😝", "😁", "😱", "👉", "🙌", "🍻", "🔥", "🌈", "🎈", "😡", "👿",
"🐻", "🐶", "🐬", "🐟", "👌", "😍", "😉", "😳", "💪", "💩", "🍸", "🔑",
"💖", "🌟", "🎉", "🌺", "👠", "🏆", "👽", "💀", "🐵", "🐮", "🐩", "💜",
"💋", "😘", "😜", "😵", "🙏", "👋", "🚽", "💃", "💎", "🚀", "🌙", "🎁",
"⛄", "🌊", "⛵", "🏀", "💰", "🐰", "🐷", "🐍", "🐫", "🔫", "👄", "🍉",
];
const counts = EMOJI.map(_ => 0);
const getTemplate = () => {
return `<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500;700&display=swap" rel="stylesheet">
<style>
html,
body {
background-color: #efebe0;
font-family: 'Montserrat', sans-serif;
}
* {
box-sizing: border;
}
.intro {
width: 100%;
text-align: center;
font-weight: bold;
font-size: 1.2em;
margin: 16px 0;
}
.emojis {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 8px;
}
.emoji-container {
text-align: center;
padding: 8px;
border-radius: 8px;
box-sizing: border-box;
border: 4px solid #fb4570;
background-color: #fb8da0;
color: white;
font-weight: bold;
cursor: pointer;
user-select: none;
overflow: hidden;
}
.emoji {
font-size: 2em;
margin-bottom: 8px;
}
footer {
margin: 16px;
text-align: center;
}
footer a {
color: black;
text-decoration: none;
}
footer a:hover {
color: #fb4570;
}
@media screen and (max-width: 800px) {
.emojis {
grid-template-columns: repeat(4, 1fr);
}
}
</style>
<script>
const setupClick = (e) => {
const counter = e.querySelector(".counter");
const index = e.dataset.index;
e.addEventListener("click", async () => {
const res = await fetch("/api/click", {
method: "POST",
body: index,
});
const body = await res.text();
counter.innerText = body;
});
}
window.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("[data-index]").forEach(setupClick);
});
</script>
</head>
<body>
<header class="intro">
Don't be shy, click on some emoji.
</header>
<content class="emojis">
${EMOJI.map((a, i) => `
<div data-index="${i}" class="emoji-container">
<div class="emoji">${a}</div>
<div class="counter">${counts[i]}</div>
</div>
`).join("")}
</content>
<footer>
<a href="https://twitter.com/briandotjp" target="_blank"> 🐦 @briandotjp</a>
</footer>
</body>
</html>
`
}
const getQuestion = () => {
return QUESTIONS[Math.floor(Math.random() * QUESTIONS.length)];
}
const loadData = async (req, res) => {
return new Promise((resolve, reject) => {
let data;
req.on("data", d => {
if (d.length > 4) {
req.destroy();
}
data = d;
});
req.on("end", () => {
resolve(data);
});
});
}
const getPage = (req, res) => {
const template = getTemplate();
res.writeHead(200, {
'Content-Length': Buffer.byteLength(template),
'Content-Type': 'text/html; charset=utf-8',
'Question': getQuestion()
});
res.end(template);
}
const clickAPI = async (req, res) => {
if (req.method !== "POST") {
boohoo(req, res);
return;
}
try {
const data = await loadData(req, res);
const index = parseInt(data);
if (index < 0 || index >= counts.length) {
boohoo(req, res);
return;
}
counts[index] += 1;
const newCount = counts[index].toString();
res.writeHead(200, {
'Content-Length': Buffer.byteLength(newCount),
'Content-Type': 'text/plain',
'Question': getQuestion()
});
res.end(newCount);
} catch (e) {
console.error(e);
boohoo(req, res);
}
}
const NOOP = (req, res) => {
res.writeHead(404, {
'Content-Length': 0,
'Question': getQuestion()
});
res.end();
}
const boohoo = (req, res) => {
res.writeHead(400, {
'Content-Length': Buffer.byteLength("💩"),
'Question': getQuestion()
});
res.end("💩");
}
const requestListener = (req, res) => {
switch (req.url) {
case "/":
getPage(req, res);
break;
case "/api/click":
clickAPI(req, res);
break;
default:
NOOP(req, res);
break
}
}
const server = http.createServer(requestListener);
server.listen(8080);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment