mirror of https://codeberg.org/pzp/pzp-hub.git
init
This commit is contained in:
commit
854e376a6a
|
@ -0,0 +1,5 @@
|
|||
node_modules
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
TODO
|
|
@ -0,0 +1,13 @@
|
|||
# My Hub
|
||||
|
||||
Welcome to this hub!
|
||||
|
||||
> Blockquote
|
||||
|
||||
This is **bold** while this is _italic_.
|
||||
|
||||
This is a [link](https://staltz.com).
|
||||
|
||||
- This is a list
|
||||
- With items
|
||||
- And more items
|
|
@ -0,0 +1,44 @@
|
|||
const fastify = require('fastify');
|
||||
const fastifyView = require('@fastify/view');
|
||||
const fastifyMarkdown = require('fastify-markdown');
|
||||
const fastifyStatic = require('@fastify/static');
|
||||
const ejs = require('ejs');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const staticsPath = path.join(__dirname, 'public');
|
||||
const viewsPath = path.join(__dirname, 'views');
|
||||
const homepagePath = path.join(__dirname, '..', 'HOMEPAGE.md');
|
||||
const homepageMD = fs.readFileSync(homepagePath, 'utf8');
|
||||
|
||||
const app = fastify({logger: true});
|
||||
|
||||
app.register(fastifyView, {
|
||||
engine: {ejs},
|
||||
root: viewsPath,
|
||||
});
|
||||
|
||||
app.register(fastifyMarkdown, {
|
||||
src: false,
|
||||
});
|
||||
|
||||
app.register(fastifyStatic, {
|
||||
root: staticsPath,
|
||||
});
|
||||
|
||||
app.get('/', (req, reply) => {
|
||||
const markdown = reply.markdown().parse(homepageMD);
|
||||
reply.view('index.ejs', {markdown});
|
||||
});
|
||||
|
||||
app.get('/invite', (req, reply) => {
|
||||
reply.view('invite.ejs');
|
||||
});
|
||||
|
||||
app.listen({port: 3000}, (err, address) => {
|
||||
app.log.info(`server listening on ${address}`);
|
||||
if (err) {
|
||||
app.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
let hasFocus = true;
|
||||
window.addEventListener('blur', () => {
|
||||
hasFocus = false;
|
||||
});
|
||||
window.addEventListener('focus', () => {
|
||||
hasFocus = true;
|
||||
});
|
||||
|
||||
const inviteLinkElem = document.getElementById('invite');
|
||||
const failureElem = document.getElementById('failure');
|
||||
|
||||
const hash = window.location.hash;
|
||||
if (hash) {
|
||||
let uri = decodeURIComponent(hash.slice(1));
|
||||
if (!uri.startsWith('ppppp:')) uri = 'ppppp://invite' + uri;
|
||||
inviteLinkElem.href = uri;
|
||||
|
||||
// Autoredirect to the PPPPP URI as soon as possible
|
||||
setTimeout(() => {
|
||||
console.log(uri);
|
||||
// window.location.replace(uri);
|
||||
}, 100);
|
||||
|
||||
// Redirect to uri or show failure state
|
||||
// FIXME:
|
||||
// inviteLinkElem.onclick = function handleURI(ev) {
|
||||
// ev.preventDefault();
|
||||
// const uri = inviteLinkElem.href;
|
||||
// inviteLinkElem.classList.remove('hidden');
|
||||
// setTimeout(function () {
|
||||
// if (hasFocus) {
|
||||
// inviteLinkElem.classList.add('hidden');
|
||||
// failureElem.classList.remove('hidden');
|
||||
// }
|
||||
// }, 5000);
|
||||
// window.location.replace(uri);
|
||||
// };
|
||||
} else {
|
||||
inviteLinkElem.classList.add('hidden');
|
||||
failureElem.classList.remove('hidden');
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
:root {
|
||||
--color-bg-void: #f6f5f5;
|
||||
--color-bg-text: #fff;
|
||||
--color-bg-text-border: #e8e8e8;
|
||||
--color-text: #111;
|
||||
--color-text-weak: #777;
|
||||
--color-text-very-weak: #ddd;
|
||||
--color-button: hsl(350, 87%, 65%);
|
||||
--color-button-hover: hsl(350, 87%, 70%);
|
||||
--color-link: hsl(350, 87%, 55%);
|
||||
|
||||
--space-tiny: 4px;
|
||||
--space-small: 10px;
|
||||
--space-normal: 20px;
|
||||
--space-big: 32px;
|
||||
|
||||
color-scheme: light dark;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
/* Colors */
|
||||
--color-bg-void: #111114;
|
||||
--color-bg-text: #333337;
|
||||
--color-bg-text-border: #414145;
|
||||
--color-text: #f3f3f3;
|
||||
--color-text-weak: #ababab;
|
||||
--color-text-very-weak: #666;
|
||||
--color-button: hsl(350, 87%, 65%);
|
||||
--color-button-hover: hsl(350, 87%, 70%);
|
||||
--color-link: hsl(350, 87%, 70%);
|
||||
|
||||
color-scheme: light dark;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-bg-void);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
article {
|
||||
max-width: 600px;
|
||||
margin: var(--space-normal) auto;
|
||||
background-color: var(--color-bg-text);
|
||||
padding: var(--space-normal);
|
||||
border-radius: var(--space-small);
|
||||
box-shadow: 0 var(--space-normal) var(--space-big) rgba(0, 0, 0, 0.03);
|
||||
border: 1px solid var(--color-bg-text-border);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--space-small);
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 20px;
|
||||
}
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--space-small);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 var(--space-small);
|
||||
padding: 0 var(--space-small);
|
||||
color: var(--color-text-weak);
|
||||
border-left: var(--space-tiny) solid var(--color-text-very-weak);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 4px;
|
||||
padding: 0;
|
||||
margin: 20px 0;
|
||||
background-color: #ddd;
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: var(--space-normal);
|
||||
}
|
||||
|
||||
a.btn {
|
||||
background: var(--color-button);
|
||||
border-radius: 999px;
|
||||
box-shadow: var(--color-button) 0 10px 20px -10px;
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 24px;
|
||||
opacity: 1;
|
||||
outline: 0 solid transparent;
|
||||
padding: 8px 18px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
touch-action: manipulation;
|
||||
width: fit-content;
|
||||
word-break: break-word;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
a.btn:hover {
|
||||
text-decoration: none;
|
||||
background: var(--color-button-hover);
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<article><%- markdown %></article>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<article>
|
||||
<h1>Join PPPPP</h1>
|
||||
<a id="invite" class="btn" href="#">Claim invite</a>
|
||||
<p id="failure" class="hidden">
|
||||
Sorry, it seems like you have no actual invite code in the link you
|
||||
opened.
|
||||
</p>
|
||||
</article>
|
||||
<script src="/invite.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"name": "ppppp-hub",
|
||||
"version": "0.0.1",
|
||||
"description": "PPPPP hub server",
|
||||
"author": "Andre Staltz <contact@staltz.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/staltz/ppppp-hub",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:staltz/ppppp-hub.git"
|
||||
},
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"*.js",
|
||||
"lib/*.js"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./lib/index.js"
|
||||
}
|
||||
},
|
||||
"type": "commonjs",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/static": "6.10.2",
|
||||
"@fastify/view": "7.4.1",
|
||||
"ejs": "3.1.9",
|
||||
"fastify": "4.17.0",
|
||||
"fastify-markdown": "0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"c8": "7",
|
||||
"prettier": "^2.6.2",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"tap-arc": "^0.3.5",
|
||||
"tape": "^5.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js | tap-arc --bail",
|
||||
"format-code": "prettier --write \"(lib|test)/**/*.js\"",
|
||||
"format-code-staged": "pretty-quick --staged --pattern \"(lib|test)/**/*.js\"",
|
||||
"coverage": "c8 --reporter=lcov npm run test"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "npm run format-code-staged"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue