Public
Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// core react component for jxnblkio
/** @jsxImportSource https://esm.sh/react */
import { MdContrast } from "https://esm.sh/react-icons/md";
import React from "https://esm.sh/react@18.3.1";
import { useMemo, useState } from "https://esm.sh/react@18.3.1";
import { Avatar } from "https://esm.town/v/jxnblk/avatar";
import { Diagz, Tiled } from "https://esm.town/v/jxnblk/greebles";
import { colors, css } from "https://esm.town/v/jxnblk/JxnblkCSS";
import { GoogleFonts } from "https://esm.town/v/jxnblk/reactGoogleFonts";
import { Vantom } from "https://esm.town/v/jxnblk/vantom";
const OGIMAGE = "https://jxnblk-blogogimage.web.val.run/";
const URL = "https://jxnblk.com";
const DESCRIPTION = "Design engineer and aspiring indie game dev based in Brooklyn, NY";
type PostData = {
path: string;
slug: string;
title: string;
date: Date | string;
excerpt?: string;
html: string;
tags?: string[];
};
const cx = (...cn) => cn.filter(Boolean).join(" ");
export function App(props) {
const cookies: AppCookies = parseCookies(props.cookie || null);
const initColorIndex = cookies.color || 0;
const [colorIndex, setColorIndex] = useState<number>(initColorIndex);
// TODO: add to vanilla
const [baseline, setBaseline] = useState<boolean>(false);
const cycleColor = () => {
const next = (colorIndex + 1) % colors.length;
setColorIndex(next);
setCookie("color", next);
};
const color = useMemo(() => colors[colorIndex], [colorIndex]);
// console.log(props.data.route);
const RouteComponent = props.data?.route ? routes[props.data.route] : routes[Route.Home];
const reverse = colorIndex > 4;
return (
<html lang="en-us">
<Head {...props} />
<body className={cx(color, baseline && "baseline")}>
{props.data?.vanilla && noflash}
<div id="dotgrid" className={cx(baseline && "dotgrid")}>
<Header cycleColor={cycleColor} />
{RouteComponent && <RouteComponent {...props} reverse={reverse} />}
<Footer
reverse={reverse}
toggleBaseline={() => setBaseline(b => !b)}
/>
{props.data?.vanilla && vanilla}
</div>
</body>
</html>
);
}
// TODO: 404
function Head(props) {
const { post } = props.data;
let params = "";
let description = DESCRIPTION;
let title = "Jxnblk | Brent Jackson";
let image = OGIMAGE;
if (post) {
params = `text=${post.title}`;
title = post.title + " | Jxnblk";
image = post.image || (OGIMAGE + params);
}
return (
<head>
<title>{title}</title>
<meta name="description" content={description} />
<style dangerouslySetInnerHTML={{ __html: css }} />
<link rel="icon" href="https://jxnblk-avatar.web.val.run?size=32&color=white&reverse=true&scale=1.375" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:image" content={image} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:url" content={URL + props.pathname} />
<meta property="og:type" content="website" />
<meta property="og:logo" content="https://jxnblk-avatar.web.val.run" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={image} />
<meta name="twitter:site" content="@jxnblk" />
<link rel="preconnect" href="https://esm.town" />
<link rel="preconnect" href="https://esm.sh" />
<link rel="preconnect" href="https://jxnblk.com" />
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
August 14, 2024