Browse Source

feat: Further Lighthouse compliance

develop
Dale 1 year ago
parent
commit
a25978473b
Signed by: Deiru GPG Key ID: AA250C0277B927E1
  1. 1
      package.json
  2. 18
      shell.nix
  3. 405
      src/domains/landing/components/Landing.tsx
  4. 27
      src/domains/landing/index.tsx
  5. 21
      src/domains/status/index.tsx
  6. 7
      src/lib/styles.ts
  7. 246
      src/styles/landing.css
  8. 5
      static/landing/styles/style.css
  9. 5
      yarn.lock

1
package.json

@ -23,6 +23,7 @@
"express": "^4.17.1",
"gamedig": "^2.0.14",
"mumble-ping": "^1.0.0",
"prettier": "^2.2.0",
"ramda": "^0.26.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",

18
shell.nix

@ -0,0 +1,18 @@
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
let
nodePkg = pkgs.nodejs-12_x;
yarnPkg = pkgs.yarn.override { nodejs = nodePkg; };
tslPkg = pkgs.nodePackages.typescript-language-server.override { nodejs = nodePkg; };
src = ./.;
in mkShell {
shellHook = ''
export PATH=$PATH:${src}/node_modules/.bin
'';
buildInputs = [
yarnPkg nodePkg tslPkg
yarn2nix
];
}

405
src/domains/landing/components/Landing.tsx

@ -1,49 +1,91 @@
import React, { FC } from 'react';
import { MumbleStatus } from 'src/lib/mumble';
import { XMPPStatus } from 'src/lib/xmpp';
import { MastodonStatus } from 'src/lib/mastodon';
import React, { FC } from "react";
import { MumbleStatus } from "src/lib/mumble";
import { XMPPStatus } from "src/lib/xmpp";
import { MastodonStatus } from "src/lib/mastodon";
import cn from 'classnames';
import cn from "classnames";
import embedStyles from "src/lib/styles";
type Props = {
mastodon: MastodonStatus,
mumble: MumbleStatus,
xmpp: XMPPStatus,
staticHost?: string,
}
mastodon: MastodonStatus;
mumble: MumbleStatus;
xmpp: XMPPStatus;
staticHost?: string;
};
const Landing: FC<Props> = ({ mastodon, mumble, xmpp, staticHost = 'http://localhost:8080' }) => (
<html>
<head>
<title>GenSoc Network</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" href={`${staticHost}/static/landing/styles/style-initial.css`} />
</head>
<body>
<div className="grid-container">
<div className="grid-cell">
<div className="yuyuko-cell">
<div className="yuyuko-bg img-bg"></div>
<h3>Gensokyo.social</h3>
<hr className="break" />
<h4>A Free <a href="https://en.wikipedia.org/wiki/Fediverse" target="blank_" rel="noreferrer">Fediverse</a> Node.</h4>
<ul className="feature-list">
<li>Fully-automated Luxury Gay Yokai Communism:</li>
<li>Running Mastodon {mastodon.version}</li>
<li>Providing social network services and more</li>
<li>Operating on <a target="_blank" href="https://nixos.org">NixOS</a> from <a target="_blank" rel="noreferrer" href="https://www.openstreetmap.org/search?query=Limburger%20Str.%2045%2C%2065555%20Limburg%20an%20der%20Lahn#map=19/50.40888/8.06255">Limburg, Germany</a></li>
<li>Proudly using <a href="https://jortage.com" target="_blank" rel="noreferrer">Jortage</a></li>
<li>Serving dinner</li>
</ul>
</div>
</div>
<div className="grid-cell">
<div className="youmu-cell">
<div className="img-bg youmu-bg"></div>
<h3>Mastodon</h3>
<hr className="break" />
<h4>Is it dinner yet?</h4>
{/*<p style={{
const Landing: FC<Props> = ({ mastodon, mumble, xmpp }) => (
<html lang="en">
<head>
<title>GenSoc Network</title>
<meta
name="description"
content="Gensokyo.social - Free Fediverse Node"
/>
<meta name="og:title" content="GenSoc Network" />
<meta
name="og:description"
content="Gensokyo.social - Free Fediverse Node"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style
dangerouslySetInnerHTML={{
__html: embedStyles("landing.css"),
}}
/>
</head>
<body>
<div className="grid-container">
<div className="grid-cell">
<div className="yuyuko-cell">
<div className="yuyuko-bg img-bg"></div>
<h3>Gensokyo.social</h3>
<hr className="break" />
<h4>
A Free&nbsp;
<a
href="https://en.wikipedia.org/wiki/Fediverse"
target="blank_"
rel="noreferrer"
>
Fediverse
</a>{" "}
Node.
</h4>
<ul className="feature-list">
<li>Fully-automated Luxury Gay Yokai Communism:</li>
<li>Running Mastodon {mastodon.version}</li>
<li>Providing social network services and more</li>
<li>
Operating on{" "}
<a target="_blank" rel="noreferrer" href="https://nixos.org">
NixOS
</a>{" "}
from{" "}
<a
target="_blank"
rel="noreferrer"
href="https://www.openstreetmap.org/search?query=Limburger%20Str.%2045%2C%2065555%20Limburg%20an%20der%20Lahn#map=19/50.40888/8.06255"
>
Limburg, Germany
</a>
</li>
<li>
Proudly using{" "}
<a href="https://jortage.com" target="_blank" rel="noreferrer">
Jortage
</a>
</li>
<li>Serving dinner</li>
</ul>
</div>
</div>
<div className="grid-cell">
<div className="youmu-cell">
<div className="img-bg youmu-bg"></div>
<h3>Mastodon</h3>
<hr className="break" />
<h4>Is it dinner yet?</h4>
{/*<p style={{
padding: "10px", backgroundColor: "var(--Warning)",
color: "black", borderRadius: "2px",
marginTop: "10px", display: "inline-block",
@ -51,100 +93,191 @@ const Landing: FC<Props> = ({ mastodon, mumble, xmpp, staticHost = 'http://local
Due to onslaught of bots we have enabled applications. <br />
The only requirement is to sound like an actual human
</p>*/}
<ul className="links">
<li><a href="https://gensokyo.social/auth/sign_up" className="youmu-link">Sign Up</a></li>
<li><a href="https://gensokyo.social/auth/sign_in" className="youmu-link">Log In</a></li>
<li><a href="https://gensokyo.social/web/timelines/home" className="youmu-link">Home</a></li>
{/*<li><a href="https://gensokyo.social/about" className="youmu-link">About Page</a></li>*/}
</ul>
</div>
</div>
<div className="grid-cell">
<div className="yuuka-cell">
<div className="yuuka-bg img-bg"></div>
<h3>New user?</h3>
<hr className="break" />
<h4>Here's the rundown</h4>
<ul className="links">
<li><a href="https://medium.com/@VirtualAdept/a-friendly-introduction-to-the-fediverse-5b4ef3f8ed0e" target="_blank" rel="noreferrer" className="yuuka-link">What's Fediverse?</a></li>
<li><a href="https://blog.joinmastodon.org/2018/08/mastodon-quick-start-guide/" target="_blank" rel="noreferrer" className="yuuka-link">Learn the Ropes</a></li>
<li><a href="https://www.notion.so/deiru/Rules-and-Code-of-Conduct-aa95638c4aa148c1b6139f297ff0318b" target="_blank" rel="noreferrer" className="yuuka-link">Read the Rules</a></li>
<li><a href="https://www.notion.so/Terms-of-Service-5a5782fe41ea4fff86ff85bb074f2046" target="_blank" rel="noreferrer" className="yuuka-link">Study the Terms of Service</a></li>
</ul>
</div>
</div>
<div className="grid-cell">
<div className="byakuren-cell">
<div className="byakuren-bg img-bg"></div>
<h3>Services Status</h3>
<hr className="break" />
<h4>{`See how we're doing.`}</h4>
<table className="services-list">
<tbody>
<tr>
<td>{'<*>'}</td>
<td>Mastodon</td>
<td>{mastodon.online ? 'Online' : 'Offline'}</td>
<td>
<span className={cn({
"text-success": mastodon.online,
"text-fail": !mastodon.online,
})}>
</span>
</td>
</tr>
<tr>
<td>{'<*>'}</td>
<td>Mumble</td>
<td>{mumble.online ? 'Online' : 'Offline'}</td>
<td>
<span className={cn({
"text-success": mumble.online,
"text-fail": !mumble.online,
})}>
</span>
</td>
</tr>
<tr>
<td>{'<*>'}</td>
<td>XMPP</td>
<td>{xmpp.online ? 'Online' : 'Offline'}</td>
<td>
<span className={cn({
"text-success": xmpp.online,
"text-fail": !xmpp.online,
})}>
</span>
</td>
</tr>
</tbody>
</table>
{xmpp.unstable && (
<div style={{
padding: "10px", backgroundColor: "var(--Warning)",
color: "black", borderRadius: "2px",
marginTop: "10px", display: "inline-block",
}}>
XMPP is currently wonky.
Do not rely on status that much
</div>
)}
<div style={{marginTop: "15px"}}>
Refer to <a target="_blank" rel="noreferrer" href="https://status.gensokyo.social">Status page</a> for more details.
</div>
<ul className="bottom-links">
<li><a href="https://code.gensokyo.social/Gensokyo.social/status" target="_blank" rel="noreferrer">Code</a></li>
<li><a href="https://www.notion.so/GenSoc-4ea8d54e1d494d02a6c952492380a87f" target="_blank" rel="noreferrer" className="yuuka-link">GenSoc Central</a></li>
</ul>
</div>
</div>
<ul className="links">
<li>
<a
href="https://gensokyo.social/auth/sign_up"
className="youmu-link"
>
Sign Up
</a>
</li>
<li>
<a
href="https://gensokyo.social/auth/sign_in"
className="youmu-link"
>
Log In
</a>
</li>
<li>
<a
href="https://gensokyo.social/web/timelines/home"
className="youmu-link"
>
Home
</a>
</li>
{/*<li><a href="https://gensokyo.social/about" className="youmu-link">About Page</a></li>*/}
</ul>
</div>
</div>
<div className="grid-cell">
<div className="yuuka-cell">
<div className="yuuka-bg img-bg"></div>
<h3>New user?</h3>
<hr className="break" />
<h4>Here's the rundown</h4>
<ul className="links">
<li>
<a
href="https://medium.com/@VirtualAdept/a-friendly-introduction-to-the-fediverse-5b4ef3f8ed0e"
target="_blank"
rel="noreferrer"
className="yuuka-link"
>
What's Fediverse?
</a>
</li>
<li>
<a
href="https://blog.joinmastodon.org/2018/08/mastodon-quick-start-guide/"
target="_blank"
rel="noreferrer"
className="yuuka-link"
>
Learn the Ropes
</a>
</li>
<li>
<a
href="https://www.notion.so/deiru/Rules-and-Code-of-Conduct-aa95638c4aa148c1b6139f297ff0318b"
target="_blank"
rel="noreferrer"
className="yuuka-link"
>
Read the Rules
</a>
</li>
<li>
<a
href="https://www.notion.so/Terms-of-Service-5a5782fe41ea4fff86ff85bb074f2046"
target="_blank"
rel="noreferrer"
className="yuuka-link"
>
Study the Terms of Service
</a>
</li>
</ul>
</div>
</div>
<div className="grid-cell">
<div className="byakuren-cell">
<div className="byakuren-bg img-bg"></div>
<h3>Services Status</h3>
<hr className="break" />
<h4>{`See how we're doing.`}</h4>
<table className="services-list">
<tbody>
<tr>
<td>{"<*>"}</td>
<td>Mastodon</td>
<td>{mastodon.online ? "Online" : "Offline"}</td>
<td>
<span
className={cn({
"text-success": mastodon.online,
"text-fail": !mastodon.online,
})}
>
</span>
</td>
</tr>
<tr>
<td>{"<*>"}</td>
<td>Mumble</td>
<td>{mumble.online ? "Online" : "Offline"}</td>
<td>
<span
className={cn({
"text-success": mumble.online,
"text-fail": !mumble.online,
})}
>
</span>
</td>
</tr>
<tr>
<td>{"<*>"}</td>
<td>XMPP</td>
<td>{xmpp.online ? "Online" : "Offline"}</td>
<td>
<span
className={cn({
"text-success": xmpp.online,
"text-fail": !xmpp.online,
})}
>
</span>
</td>
</tr>
</tbody>
</table>
{xmpp.unstable && (
<div
style={{
padding: "10px",
backgroundColor: "var(--Warning)",
color: "black",
borderRadius: "2px",
marginTop: "10px",
display: "inline-block",
}}
>
XMPP is currently wonky. Do not rely on status that much
</div>
)}
<div style={{ marginTop: "15px" }}>
Refer to{" "}
<a
target="_blank"
rel="noreferrer"
href="https://status.gensokyo.social"
>
Status page
</a>{" "}
for more details.
</div>
<link rel="stylesheet" type="text/css" href={`${staticHost}/static/landing/styles/style.css?v=1.0`} />
</body>
</html>
<ul className="bottom-links">
<li>
<a
href="https://code.gensokyo.social/Gensokyo.social/status"
target="_blank"
rel="noreferrer"
>
Code
</a>
</li>
<li>
<a
href="https://www.notion.so/GenSoc-4ea8d54e1d494d02a6c952492380a87f"
target="_blank"
rel="noreferrer"
className="yuuka-link"
>
GenSoc Central
</a>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
);
export default Landing
export default Landing;

27
src/domains/landing/index.tsx

@ -1,15 +1,17 @@
import React from 'react';
import { Router } from 'express';
import React from "react";
import { Router } from "express";
import { getFromCache } from 'src/lib/status';
import Landing from './components/Landing';
import { renderToString } from 'react-dom/server';
import { getFromCache } from "src/lib/status";
import Landing from "./components/Landing";
import { renderToString } from "react-dom/server";
const development = process.env.NODE_ENV === 'development';
const STATIC_HOST = development ? 'http://localhost:8080' : 'https://gensokyo.network';
const development = process.env.NODE_ENV === "development";
const STATIC_HOST = development
? "http://localhost:8080"
: "https://gensokyo.network";
const router = Router();
router.get('/', (_, res) => {
router.get("/", (_, res) => {
getFromCache().then(([mastodonStatus, mumbleStatus, XMPPStatus]) => {
const statusPage = (
<Landing
@ -18,10 +20,13 @@ router.get('/', (_, res) => {
xmpp={XMPPStatus}
staticHost={STATIC_HOST}
/>
)
const page = renderToString(statusPage);
);
const page = `
<!DOCTYPE html>
${renderToString(statusPage)}
`;
res.status(200).send(page);
})
});
});
export default router;

21
src/domains/status/index.tsx

@ -3,15 +3,17 @@ import React from "react";
import { Router } from "express";
import { renderToString } from "react-dom/server";
import Status from './components/Status';
import Status from "./components/Status";
import { getFromCache } from 'src/lib/status';
import { getFromCache } from "src/lib/status";
const development = process.env.NODE_ENV === 'development';
const STATIC_HOST = development ? 'http://localhost:8080' : 'https://gensokyo.network';
const development = process.env.NODE_ENV === "development";
const STATIC_HOST = development
? "http://localhost:8080"
: "https://gensokyo.network";
const router = Router();
router.get('/', (_, res) => {
router.get("/", (_, res) => {
getFromCache().then(([mastodonStatus, mumbleStatus, XMPPStatus]) => {
const statusPage = (
<Status
@ -20,10 +22,13 @@ router.get('/', (_, res) => {
xmpp={XMPPStatus}
staticHost={STATIC_HOST}
/>
)
const page = renderToString(statusPage);
);
const page = `
<!DOCTYPE html>
${renderToString(statusPage)}
`;
res.status(200).send(page);
})
});
});
export default router;

7
src/lib/styles.ts

@ -0,0 +1,7 @@
import path from 'path';
import fs from 'fs';
export default function embedStyles(filename: string) {
const file = fs.readFileSync(path.resolve('src/styles', filename), 'utf-8');
return file;
}

246
src/styles/landing.css

@ -0,0 +1,246 @@
@font-face {
font-family: FiraCode;
src: url('https://gensokyo.network/static/landing/fonts/FiraCode-Retina.woff2');
font-display: swap;
}
.grid-container {
width: 100vw;
height: 100%;
display: flex;
flex-wrap: wrap;
}
.grid-cell {
height: 50vh;
flex: 0 0 50vw;
box-sizing: border-box;
/* width: 50vw; */
}
.grid-cell > * > h2 {
margin-bottom: 15px;
}
.grid-cell > div {
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.5);
padding: 20px;
height: 100%;
width: 100%;
}
html, body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
body {
font-family: FiraCode;
}
.links {
list-style: none;
padding-left: 0;
}
.links > li {
margin-top: 10px;
}
.cell-text {
white-space: pre-line;
}
.dinner {
color: lightgray;
}
.feature-list {
list-style: none;
padding-left: 0;
}
.feature-list > li {
margin-top: 10px;
}
.feature-list > li:before {
content: '<*>';
margin-right: 5px;}
.yuyuko-bg {
background-image: url('https://gensokyo.network/static/landing/images/yuyuko.webp');
background-color: var(--YuyukoBackground);
}
.youmu-bg {
background-image: url('https://gensokyo.network/static/landing/images/youmu.webp');
background-color: var(--YoumuBackground);
}
.yuuka-bg {
background-image: url('https://gensokyo.network/static/landing/images/yuuka.webp');
background-color: var(--YuukaBackground);
}
.byakuren-bg {
background-image: url('https://gensokyo.network/static/landing/images/byakuren.webp');
background-color: var(--ByakurenBackground);
}
.img-bg {
z-index: -1;
content: '';
background-size: 200px;
background-repeat: no-repeat;
/* background-position-x: left; */
background-position: bottom right;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.yuyuko-cell {
color: var(--YuyukoText);
position: relative;
}
.youmu-cell {
background-color: var(--YoumuBackground);
color: var(--YoumuText);
position: relative;
}
.yuuka-cell {
background-color: var(--YuukaBackground);
color: var(--YuukaText);
position: relative;
}
.byakuren-cell {
background-color: var(--ByakurenBackground);
color: var(--ByakurenText);
position: relative;
}
a {
color: #B6FBFD;
text-decoration: none;
transition: border-color 0.5s ease;
border: 1px solid rgba(0, 0, 0, 0);
}
a:before {
content: ">=";
color: white;
margin-right: 5px;
}
a:hover {
transition: border-color 0.5s ease;
border-bottom: 1px solid #B6FBFD !important;
}
.services-list {
margin-top: 15px;
}
.services-list > tbody > tr > td {
padding: 5px;
color: var(--ByakurenText);
}
.services-list > tbody > tr > td:first-of-type {
padding-left: 0;
}
.under-construction {
position: relative;
}
.under-construction > * > a {
color: #9b1719;
}
.under-construction:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('/images/warning.png');
background-position: center;
background-size: contain;
background-repeat: no-repeat;
}
ul.bottom-links {
list-style: none;
padding-left: 0;
position: absolute;
bottom: 15px;
left: 20px;
}
ul.bottom-links > li {
display: inline-block;
margin-right: 5px;
}
.break {
margin: 0;
color: white;
}
.text-success {
color: var(--Success);
}
.success {
color: white;
background-color: var(--Success);
}
.text-fail {
color: var(--Fail);
}
.fail {
color: white;
background-color: var(--Fail);
}
.text-warning {
color: var(--Success);
}
.warning {
color: white;
background-color: var(--Fail);
}
@media (max-width: 820px) {
.grid-cell {
flex: 0 0 100vw;
height: 65vh;
}
}
:root {
--Test: #000000;
--Success: #32c900;
--Fail: #c90000;
--Warning: #D9DB40;
--YuyukoBackground: #FF6FB7;
--YuyukoText: white;
--YoumuBackground: #30AA2A;
--YoumuText: white;
--YuukaBackground: #FF0005;
--YuukaText: white;
--ByakurenBackground: #8918D2;
--ByakurenText: white;
}

5
static/landing/styles/style.css

@ -1,6 +1,6 @@
@font-face {
font-family: FiraCode;
src: url('https://gensokyo.network/static/landing/fonts/FiraCode-Retina.woff2');
src: url("https://gensokyo.network/static/landing/fonts/FiraCode-Retina.woff2");
}
html, body {
@ -42,7 +42,8 @@ body {
}
.feature-list > li:before {
content: '<*>';
margin-right: 5px;}
margin-right: 5px;
}
.yuyuko-bg {
background-image: url('https://gensokyo.network/static/landing/images/yuyuko.webp');
background-color: var(--YuyukoBackground);

5
yarn.lock

@ -3712,6 +3712,11 @@ prepend-http@^1.0.1:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
prettier@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.0.tgz#8a03c7777883b29b37fb2c4348c66a78e980418b"
integrity sha512-yYerpkvseM4iKD/BXLYUkQV5aKt4tQPqaGW6EsZjzyu0r7sVZZNPJW4Y8MyKmicp6t42XUPcBVA+H6sB3gqndw==
process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"

Loading…
Cancel
Save