From d94de055d89887883fbe493d15d5dfbf7f7c2b8c Mon Sep 17 00:00:00 2001 From: Paul W <49735521+LambdaPaul@users.noreply.github.com> Date: Tue, 4 Oct 2022 23:41:59 -0400 Subject: [PATCH] Refactor, update UI, and add notes --- .gitignore | 3 +- components/github-profile.tsx | 7 +- components/layout.tsx | 19 +- components/meta.tsx | 8 +- components/recent-notes.tsx | 6 +- components/recent-posts.tsx | 16 +- components/title.tsx | 4 +- {util => lib}/date.ts | 50 +++-- lib/slug.d.ts | 35 +++ {util => lib}/slug.js | 100 +++++---- next.config.js | 2 +- notes/mos-6502.md | 48 ++++- notes/nintendo-switch.md | 20 ++ notes/steam-deck.md | 49 +++++ notes/steam.md | 31 ++- notes/zilog-z80.md | 52 +++-- package-lock.json | 281 +++++++++++++++++++++++++ package.json | 1 + pages/about.tsx | 17 +- pages/index.tsx | 23 +- pages/notes/{[page].tsx => [note].tsx} | 12 +- pages/notes/index.tsx | 31 ++- pages/posts/{[page].tsx => [post].tsx} | 21 +- pages/posts/index.tsx | 54 ++--- public/pages.json | 4 +- styles/global.css | 75 +++++-- styles/post.module.css | 10 +- styles/recent-posts.module.css | 51 ++++- styles/title.module.css | 11 +- tsconfig.json | 2 +- util/slug.d.ts | 35 --- 31 files changed, 813 insertions(+), 265 deletions(-) rename {util => lib}/date.ts (61%) create mode 100644 lib/slug.d.ts rename {util => lib}/slug.js (55%) create mode 100644 notes/nintendo-switch.md create mode 100644 notes/steam-deck.md rename pages/notes/{[page].tsx => [note].tsx} (85%) rename pages/posts/{[page].tsx => [post].tsx} (50%) delete mode 100644 util/slug.d.ts diff --git a/.gitignore b/.gitignore index 85abf00..14c902c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ dist/ .DS_Store .cache/ *.bun -.env \ No newline at end of file +**/*.wip.md +.env diff --git a/components/github-profile.tsx b/components/github-profile.tsx index b5e7f2c..5bc96d7 100644 --- a/components/github-profile.tsx +++ b/components/github-profile.tsx @@ -1,6 +1,6 @@ import Image from 'next/image'; import { parse as URIparse } from 'uri-js'; -import date from '../util/date'; +import date from '../lib/date'; import style from '../styles/github-profile.module.css'; function CardRow({label, children}: {label: string, children: JSX.Element | string}) { @@ -11,6 +11,7 @@ function CardRow({label, children}: {label: string, children: JSX.Element | stri ); } + function GitHubProfile({user}: any) { return (<>
@@ -32,8 +33,8 @@ return (<> } {user.location} {user.bio} - {user.created_at ? date.prettyPrint(user.created_at) : ''} - {user.updated_at && {user.updated_at ? date.prettyPrint(user.updated_at) : ''}} + {user.created_at ? date.toRelativeDate(user.created_at) : ''} + {user.updated_at && {user.updated_at ? date.toRelativeDate(user.updated_at) : ''}} {user.twitter_username && diff --git a/components/layout.tsx b/components/layout.tsx index a5053c1..3abfa3b 100644 --- a/components/layout.tsx +++ b/components/layout.tsx @@ -8,16 +8,23 @@ type LayoutProps = { title?: string, ancestors?: Array<{ name: string, path: string }> children?: ChildrenType, + removeContainer?: boolean, }; -function Layout({ name, title, children, ancestors }: LayoutProps) { +function Container(props: {children?: ChildrenType, ignore?: boolean}) { + if (props.ignore) + return <>{props.children}; + return
+ {props.children} +
; +} + +function Layout(props : LayoutProps) { return ( <> - - - <div className='container'> - {children} - </div> + <Meta name={props.name} ancestors={props.ancestors} /> + <Title title={props.title} name={props.name} ancestors={props.ancestors} /> + <Container ignore={props.removeContainer}>{props.children}</Container> </> ); } diff --git a/components/meta.tsx b/components/meta.tsx index 1ff069d..d452b24 100644 --- a/components/meta.tsx +++ b/components/meta.tsx @@ -2,7 +2,7 @@ import Head from 'next/head'; function Meta({name, ancestors} : {name: string, ancestors?: Array<{ name: string, path: string }> }) { - const path = () => { + function path(): string { if (!ancestors) return name; @@ -11,12 +11,12 @@ function Meta({name, ancestors} path = `${path}${obj.name} /`; }); - return `${path} ${name}`; - }; + return `PaulW.XYZ / ${path} ${name}`; + } return ( <Head> - <title>PaulW.XYZ / {path()} + {path()} ); } diff --git a/components/recent-notes.tsx b/components/recent-notes.tsx index e60209f..b4d07dc 100644 --- a/components/recent-notes.tsx +++ b/components/recent-notes.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; -import { NoteMeta } from "../util/slug"; +import { INoteMeta } from "../lib/slug"; -function RecentNotes({ notesMeta }: { notesMeta: NoteMeta[] }) { +function RecentNotes({ notesMeta }: { notesMeta: INoteMeta[] }) { return (
Recent Notes
@@ -14,7 +14,7 @@ function RecentNotes({ notesMeta }: { notesMeta: NoteMeta[] }) { } { notesMeta.length > 10 && -
+
More... diff --git a/components/recent-posts.tsx b/components/recent-posts.tsx index df192cd..c499b41 100644 --- a/components/recent-posts.tsx +++ b/components/recent-posts.tsx @@ -1,9 +1,9 @@ import Link from "next/link"; -import date from "../util/date"; -import { PostMeta } from "../util/slug"; +import date from "../lib/date"; +import { IPostMeta } from "../lib/slug"; import style from '../styles/recent-posts.module.css'; -function RecentPosts({ postsMeta }: { postsMeta: PostMeta[] }) { +function RecentPosts({ postsMeta }: { postsMeta: IPostMeta[] }) { if (!postsMeta.length) return <>; return ( @@ -13,12 +13,14 @@ function RecentPosts({ postsMeta }: { postsMeta: PostMeta[] }) { {postsMeta?.slice(0, 10) .map((post: any) => { return
- - {post.title} - - {date.prettyPrint(new Date(post.created_at))} + {date.toRelativeDate(new Date(post.created_at))} +
+ + {post.title} + +
})}
diff --git a/components/title.tsx b/components/title.tsx index e63e8e1..8f5a9f2 100644 --- a/components/title.tsx +++ b/components/title.tsx @@ -1,6 +1,7 @@ -import style from '../styles/title.module.css'; import Link from 'next/link'; +import style from '../styles/title.module.css'; + type propsObj = { name: string, title?: string, @@ -32,7 +33,6 @@ function Title({ name, title, ancestors }: propsObj) { {title || name}
-
{name ? <>PaulW.XYZ / {pathElements}{name} diff --git a/util/date.ts b/lib/date.ts similarity index 61% rename from util/date.ts rename to lib/date.ts index 523478b..d2b59f9 100644 --- a/util/date.ts +++ b/lib/date.ts @@ -15,7 +15,27 @@ const months = [ const ordSfx = ['','st','nd','rd','th']; -function prettyPrint(date: Date | string): string { +function toHumanReadableDate(date: Date | string, disable?: {year?: boolean, month?: boolean, day?: boolean}) { + const oDate = (typeof date === 'string')? new Date(date): date; + + const year = oDate.getFullYear(); + const month = months[oDate.getMonth()]; + const day = oDate.getDate(); + + let sfx; + if (day >= 1 && day <= 3) + sfx = ordSfx[day]; + else + sfx = ordSfx[4]; + + let out = !disable?.day ? `${day}${sfx}` : ''; + out = !disable?.month ? `${out} ${month}` : out; + out = !disable?.year ? `${out} ${year}` : out; + + return out; +} + +function toRelativeDate(date: Date | string): string { const oDate = (typeof date === 'string')? new Date(date): date; const now = new Date(); @@ -23,6 +43,10 @@ function prettyPrint(date: Date | string): string { let tdiff = Math.floor(diff/1000); + if (tdiff < 0) { + return toHumanReadableDate(oDate); + } + if (tdiff < 60) { return `${tdiff} seconds ago`; } @@ -40,27 +64,17 @@ function prettyPrint(date: Date | string): string { return `Yesterday`; } - const year = oDate.getFullYear(); - const month = months[oDate.getMonth()]; - const day = oDate.getDate(); - - let sfx; - if (day >= 1 && day <= 3) - sfx = ordSfx[day]; - else - sfx = ordSfx[4]; - if (year != now.getFullYear()) - return `${day}${sfx} ${month} ${year}`; - return `${day}${sfx} ${month}`; + if (oDate.getFullYear() != now.getFullYear()) + return toHumanReadableDate(oDate); + return toHumanReadableDate(oDate, {year: true}); } function isValid(date: any) { return (new Date(date)).toString() === 'Invalid Date'; } - -const d = { - prettyPrint, +const DateTool = { + toRelativeDate, isValid -}; +};; -export default d; \ No newline at end of file +export default DateTool; \ No newline at end of file diff --git a/lib/slug.d.ts b/lib/slug.d.ts new file mode 100644 index 0000000..b474fda --- /dev/null +++ b/lib/slug.d.ts @@ -0,0 +1,35 @@ +interface IPost { + slug: string; + rawslug: string; + content: string; + title: string; +} + +interface INote { + slug: string; + rawslug: string; + content: string; + title: string; +} + +interface INoteMeta { + title: string; + slug: string; + last_updated?: string; +} + +interface IPostMeta { + title: string; + slug: string; + created_at: string; + last_updated?: string; +} + +export function getAllPosts(filter?: Array): IPost[]; +export function getAllNotes(filter?: Array): INote[]; + +export function getPost(rawslug: string, filter?: Array): IPost; +export function getNote(rawslug: string, filter?: Array): INote; + +export function getPostsMeta(): IPostMeta[]; +export function getNotesMeta(): INoteMeta[]; \ No newline at end of file diff --git a/util/slug.js b/lib/slug.js similarity index 55% rename from util/slug.js rename to lib/slug.js index 0d51873..3b5867c 100644 --- a/util/slug.js +++ b/lib/slug.js @@ -2,11 +2,15 @@ const fs = require('fs'); const matter = require('gray-matter'); const { join } = require('path'); -const notesDir = join(process.cwd(), 'notes'); -const postsDir = join(process.cwd(), 'posts'); const cacheDir = join(process.cwd(), '.cache'); -const postsCacheFile = join(cacheDir, 'posts.meta.json'); -const notesCacheFile = join(cacheDir, 'notes.meta.json'); + +function getDir(name) { + return join(process.cwd(), name); +} + +function getCacheFileName(name) { + return join(cacheDir, `${name}.cache.json`) +} function get(dir, rawslug, filter = []) { const slug = rawslug.replace(/\.md$/, ''); @@ -39,13 +43,14 @@ function get(dir, rawslug, filter = []) { } function getAllPosts(filter = []) { - const files = fs.readdirSync(postsDir); + const files = fs.readdirSync(getDir('posts')); return files .filter(c => (!c.match(/^\.]/) && c.match(/\.md$/))) .map(file => { - return get(postsDir, file, filter) + return get(getDir('posts'), file, filter) }) + .filter(c => (c.title && c.slug && c.created_at && (new Date(c.created_at)).toString() !== 'Invalid Date')) .sort((a, b) => { const dA = new Date(a['created_at']); const dB = new Date(b['created_at']); @@ -54,13 +59,14 @@ function getAllPosts(filter = []) { } function getAllNotes(filter = []) { - const files = fs.readdirSync(notesDir); + const files = fs.readdirSync(getDir('notes')); return files .filter(c => (!c.match(/^\.]/) && c.match(/\.md$/))) .map(file => { - return get(notesDir, file, filter) + return get(getDir('notes'), file, filter) }) + .filter(c => (c.title && c.slug && c.last_updated && (new Date(c.last_updated)).toString() !== 'Invalid Date')) .sort((a, b) => { const dA = new Date(a['last_updated']); const dB = new Date(b['last_updated']); @@ -68,69 +74,59 @@ function getAllNotes(filter = []) { }); } -function cachePostsMeta() { // public access cache - const posts = getAllPosts(['title', 'slug', 'created_at', 'last_updated']); +const cats = { + notes: { + name: 'notes', + getAll: getAllNotes, + filter: ['title', 'slug', 'last_updated'], + }, + posts: { + name: 'posts', + getAll: getAllPosts, + filter: ['title', 'slug', 'created_at', 'last_updated'], + } +}; + +function cacheMeta({name, getAll, filter}) { + const items = getAll(filter); if (!fs.existsSync(cacheDir)) { fs.mkdirSync(cacheDir); } - fs.writeFile(postsCacheFile, JSON.stringify(posts), (e) => { + fs.writeFile(getCacheFileName(name), JSON.stringify(items), (e) => { if (e) console.error(e); }); - return posts; + return items; } -function cacheNotesMeta() { - const notes = getAllNotes(['title', 'slug', 'last_updated']); - - if (!fs.existsSync(cacheDir)) { - fs.mkdirSync(cacheDir); - } - - fs.writeFile(notesCacheFile, JSON.stringify(notes), (e) => { - if (e) - console.error(e); - }); - return notes; -} - -function getMetaFromFile(name) { +function getMeta(cat) { try { - const file = fs.readFileSync(name, 'utf-8'); + const file = fs.readFileSync(getCacheFileName(cat.name), 'utf-8'); return JSON.parse(file); } catch (e) { - if (name) - return cachePostsMeta(); + if (cat.name) + return cacheMeta(cat); } } +function getPostsMeta() { + return getMeta(cats.posts); +}; + +function getNotesMeta() { + return getMeta(cats.notes); +}; + function cache() { - cachePostsMeta(); - cacheNotesMeta(); + Object.entries(cats).map(([_, v]) => { + return cacheMeta(v); + }); } -const getPostsMeta = () => { - try { - const file = fs.readFileSync(postsCacheFile, 'utf-8'); - return JSON.parse(file); - } catch (e) { - return cachePostsMeta(); - } -}; - -const getNotesMeta = () => { - try { - const file = fs.readFileSync(notesCacheFile, 'utf-8'); - return JSON.parse(file); - } catch (e) { - return cacheNotesMeta(); - } -}; - -const getPost = (s, f) => {return get(postsDir, s, f)}; -const getNote = (s, f) => {return get(notesDir, s, f)}; +const getPost = (s, f) => {return get(getDir('posts'), s, f)}; +const getNote = (s, f) => {return get(getDir('notes'), s, f)}; module.exports = { getAllPosts, diff --git a/next.config.js b/next.config.js index 5aac596..5775484 100755 --- a/next.config.js +++ b/next.config.js @@ -4,7 +4,7 @@ module.exports = { defaultLocale: 'en-US' }, webpack: (config, _options) => { - const { cache } = require('./util/slug'); + const { cache } = require('./lib/slug'); config.plugins.push( { diff --git a/notes/mos-6502.md b/notes/mos-6502.md index c856a0d..3ef9337 100644 --- a/notes/mos-6502.md +++ b/notes/mos-6502.md @@ -1,17 +1,43 @@ --- title: MOS 6502 Microprocessor -last_updated: '2022-05-16T14:26:03-04:00' +last_updated: '2022-09-29T02:41:26.738Z' --- -Name | 6502 ---- | --- -Introduced | 1975 -Data Width | 8-bit -Address Width | 16-bit -Endianness | Little -Registers | 8-bit A, X, Y, Stack. 16-bit PC -Package | 40-pin DIP -Instruction Count | 56 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name6502
Introduced1975
Data Width8-bit
Address Width16-bit
EndiannessLittle
Registers8-bit A, X, Y, Stack. 16-bit PC
Package40-pin DIP
Instruction Count 56
+ ## Addressing Modes - Implied @@ -25,7 +51,7 @@ Instruction Count | 56 - Indirect, Y ## Docs -- [WDC W65C02S NMOS Variant](https://www.westerndesigncenter.com/wdc/documentation/w65c02s.pdf) +- [westerndesigncenter.com: WDC W65C02S NMOS Variant](https://www.westerndesigncenter.com/wdc/documentation/w65c02s.pdf) - [6502.org: collection of 6502 resources](http://6502.org/) ## Notable Usage (includes variants) diff --git a/notes/nintendo-switch.md b/notes/nintendo-switch.md new file mode 100644 index 0000000..26dfc29 --- /dev/null +++ b/notes/nintendo-switch.md @@ -0,0 +1,20 @@ +--- +title: Nintendo Switch +last_updated: '2022-10-02T23:01:34.000Z' +--- + +Official Website +Developer Portal + +## Third-party Software +- [Atmosphère](https://github.com/Atmosphere-NX/Atmosphere) + - custom firmware + +## Third-party Resources +- [DekuDeals](https://www.dekudeals.com/) + - price tracker for games with support for all major US retailers + + +## High-level Emulators +- [yuzu](https://yuzu-emu.org/) +- [Ryujinx](https://ryujinx.org/) \ No newline at end of file diff --git a/notes/steam-deck.md b/notes/steam-deck.md new file mode 100644 index 0000000..2c51901 --- /dev/null +++ b/notes/steam-deck.md @@ -0,0 +1,49 @@ +--- +title: Steam Deck +last_updated: '2022-09-29T03:55:40.476Z' +--- + +Official Website + +## Access Console-like Youtube in Gaming Mode +- Using Chromium's undocumented command-line options, the user agent can be changed to PlayStation's, Xbox's or Tizen's (Samsung's TV OS) and the application can be launched in full screen by using the `-kiosk` flag. The following XDG Desktop Configuration, for example, can be used and added as a non-Steam game while in Desktop mode for access in gaming mode. +```ini +#!/usr/bin/env xdg-open +[Desktop] +Version=1.0 +Type=Application +Name=YouTube TV +GenericName=Online Video Platform +Comment=An online video-sharing, social media platform +Exec=/usr/bin/flatpak run --branch=master --arch=x86_64 --file-forwarding org.chromium.Chrome @@ %F @@ --user-agent='Mozilla/5.0 (X11; Linux x86_64; Xbox; Xbox One; Valve Steam Gamepad)' --kiosk 'https://www.youtube.com/tv' +Terminal=false +MimeType=text/plain; +Icon=com.youtube.tv # $XDG_PATH contains the paths used to fetch icons, extensions for supported formats are optional + +``` +- Firefox can also be used however the supported command-line options are limited. +- The URL is https://www.youtube.com/tv +- Without the user agent change, the above URL is inaccessible. +- Adblockers like uBlock Origin, AdBlock Plus (both tested) do not remove ads unlike on the desktop site. +- Choosing the Xbox user agent is recommended as button prompts match the Steam Deck's `ABXY` button layout. +- The Electron framework can be used to build a wrapper for the URL. This is the preferrable method as it supports exiting from within the application, while browsers only support manual termination from the Steam menu. E.g. (assuming you can build native linux binaries on a device) +```javascript +const { app, BrowserWindow } = require('electron'); +app.whenReady() + .then(() => { + const win = new BrowserWindow({ + backgroundColor: '#2e2c29', + kiosk: true + }); + win.maximize(); + win.loadURL('https://youtube.com/tv'); + const wc = win.webContents; + wc.userAgent = 'Mozilla/5.0 (X11; Linux x86_64; Xbox; Xbox One; Valve Steam Gamepad)' + }) + .catch((e) => { + console.error(e) + }); +``` + +## Miscellaneous +- When using a dock or a hub to connect to an external display, ensure the display supports the refresh rate set on the device as some TVs and other displays only support refresh rates that are multiples of 30Hz. \ No newline at end of file diff --git a/notes/steam.md b/notes/steam.md index 346c2ba..6d4105f 100644 --- a/notes/steam.md +++ b/notes/steam.md @@ -1,17 +1,20 @@ --- -title: Steam Store Client -last_updated: '2022-05-16T14:20:20-04:00' +title: Steam Store +last_updated: '2022-09-29T03:15:58.777Z' --- +Steam Store +SteamCMD + ## Accessing the Console -- Use the following URLs to enable the console in the GUI client: - - [steam://nav/console](steam://nav/console) - - [steam://open/console](steam://open/console) +- Use the following URIs on a browser or a file manager to open GUI client with the console: + - `steam://nav/console` + - `steam://open/console` - will not work if the Steam client is running in the background - The `-console` flag can be used with the client executable. -- Alternatively, [SteamCMD](https://developer.valvesoftware.com/wiki/SteamCMD), a command-line version of the Steam client, can be used. +- Alternatively, [SteamCMD.zip](https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip), a command-line only version of the Steam client, can be used. -## Console Commands +## Downloading Older Depots Download a single depot (used to download older versions of applications/games): ``` @@ -24,12 +27,20 @@ download_depot [] [] [ + + Name + Z80 + + + Introduced + 1976 + + + Data Width + 8-bit + + + Address Width + 16-bit + + + Binary Comp. + 8080A + + + Endianness + Little + + + Registers + 208 bits (18 × 8-bit + 4 × 16-bit) - Static RAM + + + Package + 40-pin DIP + + + Instruction Count + 158 + + ## Docs -- [User Manual](http://z80.info/zip/z80cpu_um.pdf) +- [z80.info: User Manual](http://z80.info/zip/z80cpu_um.pdf) ## Addressing Modes - Immediate diff --git a/package-lock.json b/package-lock.json index 965c68c..4d2632c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "react-dom": "^18.2.0", "react-markdown": "^8.0.3", "react-syntax-highlighter": "^15.5.0", + "rehype-raw": "^6.1.1", "remark-gfm": "^3.0.1", "uri-js": "^4.4.1" }, @@ -2523,6 +2524,11 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -4489,6 +4495,71 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hast-to-hyperscript": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-10.0.1.tgz", + "integrity": "sha512-dhIVGoKCQVewFi+vz3Vt567E4ejMppS1haBRL6TEmeLeJVB1i/FJIIg/e6s1Bwn0g5qtYojHEKvyGA+OZuyifw==", + "dependencies": { + "@types/unist": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.3.0", + "unist-util-is": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.0.tgz", + "integrity": "sha512-m8yhANIAccpU4K6+121KpPP55sSl9/samzQSQGpb0mTExcNh2WlvjtMwSWFhg6uqD4Rr6Nfa8N6TMypQM51rzQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/hast-util-parse-selector": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.0.tgz", + "integrity": "sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/hastscript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.0.2.tgz", + "integrity": "sha512-uA8ooUY4ipaBvKcMuPehTAB/YfFLSSzCwFSwT6ltJbocFUKH/GDHLN+tflq7lSRf9H86uOuxOFkh1KgIy3Gg2g==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-parse-selector": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", @@ -4498,6 +4569,45 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-raw": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.2.tgz", + "integrity": "sha512-0x3BhhdlBcqRIKyc095lBSDvmQNMY3Eulj2PLsT5XCyKYrxssI5yr3P4Kv/PBo1s/DMkZy2voGkMXECnFCZRLQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.0.0.tgz", + "integrity": "sha512-YHiS6aTaZ3N0Q3nxaY/Tj98D6kM8QX5Q8xqgg8G45zR7PvWnPGPP0vcKCgb/moIydEJ/QWczVrX0JODCVeoV7A==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-to-hyperscript": "^10.0.0", + "property-information": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz", @@ -4561,6 +4671,15 @@ "node": "*" } }, + "node_modules/html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -6252,6 +6371,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6603,6 +6727,20 @@ "jsesc": "bin/jsesc" } }, + "node_modules/rehype-raw": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", + "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-raw": "^7.2.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-gfm": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", @@ -7389,6 +7527,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", @@ -7402,6 +7553,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9152,6 +9312,11 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" + }, "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -10586,11 +10751,93 @@ "has-symbols": "^1.0.2" } }, + "hast-to-hyperscript": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-10.0.1.tgz", + "integrity": "sha512-dhIVGoKCQVewFi+vz3Vt567E4ejMppS1haBRL6TEmeLeJVB1i/FJIIg/e6s1Bwn0g5qtYojHEKvyGA+OZuyifw==", + "requires": { + "@types/unist": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.3.0", + "unist-util-is": "^5.0.0", + "web-namespaces": "^2.0.0" + } + }, + "hast-util-from-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.0.tgz", + "integrity": "sha512-m8yhANIAccpU4K6+121KpPP55sSl9/samzQSQGpb0mTExcNh2WlvjtMwSWFhg6uqD4Rr6Nfa8N6TMypQM51rzQ==", + "requires": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "dependencies": { + "hast-util-parse-selector": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.0.tgz", + "integrity": "sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==", + "requires": { + "@types/hast": "^2.0.0" + } + }, + "hastscript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.0.2.tgz", + "integrity": "sha512-uA8ooUY4ipaBvKcMuPehTAB/YfFLSSzCwFSwT6ltJbocFUKH/GDHLN+tflq7lSRf9H86uOuxOFkh1KgIy3Gg2g==", + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + } + } + } + }, "hast-util-parse-selector": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" }, + "hast-util-raw": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.2.tgz", + "integrity": "sha512-0x3BhhdlBcqRIKyc095lBSDvmQNMY3Eulj2PLsT5XCyKYrxssI5yr3P4Kv/PBo1s/DMkZy2voGkMXECnFCZRLQ==", + "requires": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + } + }, + "hast-util-to-parse5": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.0.0.tgz", + "integrity": "sha512-YHiS6aTaZ3N0Q3nxaY/Tj98D6kM8QX5Q8xqgg8G45zR7PvWnPGPP0vcKCgb/moIydEJ/QWczVrX0JODCVeoV7A==", + "requires": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-to-hyperscript": "^10.0.0", + "property-information": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + } + }, "hast-util-whitespace": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz", @@ -10633,6 +10880,11 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" }, + "html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==" + }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -11745,6 +11997,11 @@ "lines-and-columns": "^1.1.6" } }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11998,6 +12255,16 @@ } } }, + "rehype-raw": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", + "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-raw": "^7.2.0", + "unified": "^10.0.0" + } + }, "remark-gfm": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", @@ -12540,6 +12807,15 @@ "vfile-message": "^3.0.0" } }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, "vfile-message": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", @@ -12549,6 +12825,11 @@ "unist-util-stringify-position": "^3.0.0" } }, + "web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==" + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 375627f..43a3543 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "react-dom": "^18.2.0", "react-markdown": "^8.0.3", "react-syntax-highlighter": "^15.5.0", + "rehype-raw": "^6.1.1", "remark-gfm": "^3.0.1", "uri-js": "^4.4.1" }, diff --git a/pages/about.tsx b/pages/about.tsx index e590f04..a6f8143 100644 --- a/pages/about.tsx +++ b/pages/about.tsx @@ -17,7 +17,7 @@ function AboutPage({usr}: any) {

Got any questions, concerns, or issues? Contact me via email: lambdapaul [at] pm [dot] me.

- + {usr && }

@@ -39,12 +39,15 @@ function AboutPage({usr}: any) { } export async function getStaticProps() { - const res = await fetch('https://api.github.com/users/lambdapaul'); - const usr = await res.json(); - - return { - props: { usr } - }; + try { + const res = await fetch('https://api.github.com/users/lambdapaul'); + const usr = await res.json(); + return { + props: { usr } + }; + } catch (e) { + return {props: {}} + } } export default AboutPage; diff --git a/pages/index.tsx b/pages/index.tsx index 1e56726..0d3460d 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,16 +1,33 @@ import React from 'react'; +import Link from 'next/link'; import Layout from '../components/layout'; import QuickLinks from '../components/quick-links'; import RecentNotes from '../components/recent-notes'; import RecentPosts from '../components/recent-posts'; -import { getNotesMeta, getPostsMeta, NoteMeta, PostMeta } from '../util/slug'; +import { getNotesMeta, getPostsMeta, INoteMeta, IPostMeta } from '../lib/slug'; -function HomePage({ postsMeta, notesMeta }: { postsMeta: PostMeta[], notesMeta: NoteMeta[] }) { +function Nav() { + const nav = {'Posts': '/posts', 'Notes': '/notes', 'About': '/about', }; + return ( +
+ { + Object.entries(nav).map(([k, v]) => { + return + {k} + + }) + } +
+ ) +} + +function HomePage({ postsMeta, notesMeta }: { postsMeta: IPostMeta[], notesMeta: INoteMeta[] }) { return ( +