From 306e26da464a3de363c478e683ce0a08fe5f79ff Mon Sep 17 00:00:00 2001 From: lew Date: Thu, 26 Mar 2026 19:07:37 +0000 Subject: [PATCH] feat: manpage, ?compact, and some changes to formatting --- www/db/seed.ts | 46 +++++++++++++++++++++++++++++++++------ www/public/config.yaml | 6 +++++ www/public/js/params.js | 2 ++ www/public/man.txt | 46 +++++++++++++++++++++++++++++++++++++++ www/src/lib/format.ts | 11 +--------- www/src/lib/txt.ts | 4 ++++ www/src/pages/index.astro | 14 ++++++++---- www/src/styles/global.css | 12 ++++++++++ 8 files changed, 120 insertions(+), 21 deletions(-) create mode 100644 www/public/man.txt diff --git a/www/db/seed.ts b/www/db/seed.ts index ec0eced..40fad5f 100644 --- a/www/db/seed.ts +++ b/www/db/seed.ts @@ -4,18 +4,50 @@ export default async function seed() { await db.insert(Guestbook).values([ { id: 1, - name: 'alice', - message: 'love the site!', - url: 'https://example.com', - createdAt: new Date('2026-01-20'), + name: 'lisek', + message: ':)', + url: null, + createdAt: new Date('2026-03-23'), approved: true, }, { id: 2, - name: 'bob', - message: 'great blog posts', + name: 'stripes', + message: 'yay signing', url: null, - createdAt: new Date('2026-01-18'), + createdAt: new Date('2026-03-21'), + approved: true, + }, +{ + id: 4, + name: 'Evan', + message: 'Queue has four silent letters o_O', + url: null, + createdAt: new Date('2026-01-23'), + approved: true, + }, + { + id: 5, + name: 'your good pal chev', + message: 'howdy howdy', + url: 'https://youtu.be/dQw4w9WgXcQ?si=lmJDP_U9yTySGD-_', + createdAt: new Date('2025-11-19'), + approved: true, + }, + { + id: 6, + name: 'Farofa', + message: 'Thinking on what to write holdon', + url: null, + createdAt: new Date('2025-11-03'), + approved: true, + }, +{ + id: 10, + name: 'luna', + message: 'we love lewis from primal gaming', + url: null, + createdAt: new Date('2025-08-23'), approved: true, }, ]); diff --git a/www/public/config.yaml b/www/public/config.yaml index a83350b..7aa7cfe 100644 --- a/www/public/config.yaml +++ b/www/public/config.yaml @@ -1,2 +1,8 @@ pinned: - none +descriptions: + cv.txt: curriculum vitae + now.txt: what i'm doing now + man.txt: manual page + changelog.txt: site changelog + stats.txt: site statistics diff --git a/www/public/js/params.js b/www/public/js/params.js index 12de2e1..518658c 100644 --- a/www/public/js/params.js +++ b/www/public/js/params.js @@ -24,6 +24,8 @@ location.replace('/admin'); } + if (p.has('compact')) document.documentElement.dataset.compact = ''; + var has = p.get('has'); if (has) { document.documentElement.dataset.has = has; diff --git a/www/public/man.txt b/www/public/man.txt new file mode 100644 index 0000000..86ce23f --- /dev/null +++ b/www/public/man.txt @@ -0,0 +1,46 @@ +WYNNE.RS(7) Personal Sites Manual WYNNE.RS(7) + +NAME + wynne.rs — personal website of lewis m.w. + +SYNOPSIS + wynne.rs [?just=SECTION] [?has=TERM] [?do=ACTION] [?compact] + +DESCRIPTION + A personal website limited to some made-up, arbitrary design + principles to keep things minimal. An experiment in doing as + much as possible with as few distinct routes as I can. As it + stands there is an index page with a list of all the content + on the site, and a [slug]. Anything interesting is done with + search parameters. Rather than a search page or an index for + content categories, the queries below can be used. They tend + to all modify data classes to show/hide content on the index. + +OPTIONS + ?just=SECTION + Display only the named section. + + ?has=TERM + Filter entries to those containing TERM. + + ?do=random + Redirect to a random entry. + + ?do=newest + Redirect to the most recent entry. + + ?compact + Hide section labels and dates. + +PUBLIC FILES + cv.txt Curriculum vitae. + now.txt What I'm doing now. + changelog.txt Site changelog. I forget to update this often. + stats.txt Site statistics. Generated at build-time. + man.txt This man page. + +SEE ALSO + source https://github.com/llywelwyn/wynne.rs + +AUTHOR + lewis m.w. diff --git a/www/src/lib/format.ts b/www/src/lib/format.ts index 5a00731..e82cca5 100644 --- a/www/src/lib/format.ts +++ b/www/src/lib/format.ts @@ -5,15 +5,6 @@ export function formatDate(date: Date): string { return `${d}/${m}/${y}`; } -export function extractDomain(url: string): string { - try { - const parsed = new URL(url); - return parsed.hostname.replace(/^www\./, ''); - } catch { - return url; - } -} - export function formatListItem( date: Date, url: string, @@ -23,7 +14,7 @@ export function formatListItem( const pinnedBadge = options?.pinned ? ' [pinned]' : ''; const suffix = options?.suffix ? ` ${options.suffix}` : ''; const prefix = options?.prefix ?? ''; - return `${prefix}${formatDate(date)} ${title}${pinnedBadge}${suffix}`; + return `${prefix}${formatDate(date)} ${title}${pinnedBadge}${suffix}`; } interface Sortable { diff --git a/www/src/lib/txt.ts b/www/src/lib/txt.ts index b8f12be..b5475a6 100644 --- a/www/src/lib/txt.ts +++ b/www/src/lib/txt.ts @@ -8,10 +8,12 @@ export interface TxtFile { name: string; date: Date; pinned: boolean; + description?: string; } export interface TxtConfig { pinned?: string[]; + descriptions?: Record; } export function getTxtDir(): string { @@ -32,12 +34,14 @@ export function getTxtFiles(): TxtFile[] { const config = loadTxtConfig(); const pinnedSet = new Set(config.pinned || []); + const descriptions = config.descriptions || {}; const files = fs.readdirSync(txtDir) .filter(file => file.endsWith('.txt')) .map(name => ({ name, date: getGitLastModifiedDate(path.join(txtDir, name)), pinned: pinnedSet.has(name), + description: descriptions[name], })); return sortByPinnedThenDate(files); } diff --git a/www/src/pages/index.astro b/www/src/pages/index.astro index 11741be..b78acb2 100644 --- a/www/src/pages/index.astro +++ b/www/src/pages/index.astro @@ -2,7 +2,7 @@ import { getCollection } from 'astro:content'; import Layout from '../layouts/Layout.astro'; import { getApprovedEntries, type GuestbookEntry } from '../lib/db'; -import { formatDate, extractDomain, formatListItem } from '../lib/format'; +import { formatDate, formatListItem } from '../lib/format'; import { organizePostsByCategory, getSlug, enrichPostsWithDates } from '../lib/md'; import { getTxtFiles } from '../lib/txt'; import { DEFAULT_CATEGORY, SECTIONS, SUBDOMAINS } from '../lib/consts'; @@ -16,6 +16,7 @@ const bookmarks = bookmarksCollection .sort((a, b) => b.data.date.getTime() - a.data.date.getTime()); const txtFiles = getTxtFiles(); +const txtMaxNameLen = Math.max(...txtFiles.map(f => f.name.replace(/\.txt$/, '').length)); const visibleLabels = [...sortedCategories.filter(c => c !== DEFAULT_CATEGORY), ...Object.values(SECTIONS)]; const labelWidth = Math.max(...visibleLabels.map(l => l.length)); @@ -48,18 +49,23 @@ const urls = [ })}
-
 formatListItem(f.date, `/${f.name}`, f.name, { pinned: f.pinned, prefix: i === 0 ? labelPrefix(SECTIONS.plaintext, `?just=${SECTIONS.plaintext}`) : blankPrefix })).join('\n')} />
+
 {
+  const name = f.name.replace(/\.txt$/, '');
+  const pad = ' '.repeat(txtMaxNameLen - name.length);
+  const suffix = f.description ? `${pad} (${f.description})` : undefined;
+  return formatListItem(f.date, `/${f.name}`, name, { pinned: f.pinned, suffix, prefix: i === 0 ? labelPrefix(SECTIONS.plaintext, `?just=${SECTIONS.plaintext}`) : blankPrefix });
+}).join('\n')} />
 
-
 formatListItem(b.data.date, b.data.url, b.data.title, { suffix: `(${extractDomain(b.data.url)})`, prefix: i === 0 ? labelPrefix(SECTIONS.bookmarks, `?just=${SECTIONS.bookmarks}`) : blankPrefix })).join('\n')} />
+
 formatListItem(b.data.date, b.data.url, b.data.title, { prefix: i === 0 ? labelPrefix(SECTIONS.bookmarks, `?just=${SECTIONS.bookmarks}`) : blankPrefix })).join('\n')} />
 
 {
   const prefix = i === 0 ? labelPrefix(SECTIONS.guestbook, `?just=${SECTIONS.guestbook}`) : blankPrefix;
   const nameHtml = e.url ? `${e.name}` : `${e.name}`;
-  return `${prefix}${formatDate(e.createdAt)}  ${nameHtml} ${e.message.replace(/\n/g, ' ')}`;
+  return `${prefix}${formatDate(e.createdAt)}  ${nameHtml} ${e.message.replace(/\n/g, ' ')}`;
 }).join('')} />
   

diff --git a/www/src/styles/global.css b/www/src/styles/global.css index c18363d..554de75 100644 --- a/www/src/styles/global.css +++ b/www/src/styles/global.css @@ -1,4 +1,5 @@ body { + box-sizing: border-box; max-width: 38rem; margin: 0 auto; padding: 1rem; @@ -112,3 +113,14 @@ section pre { margin-top: 0.5rem; font-family: monospace; } + +html[data-compact] .list-meta { + display: none; +} +html[data-compact] .guestbook-entry { + padding-left: 0 !important; + text-indent: 0 !important; +} +html[data-compact] .guestbook-form { + margin-left: 0 !important; +}