feat: some formatting changes to reduce vertical whitespace
This commit is contained in:
parent
58747658a8
commit
3b0bba0353
6 changed files with 36 additions and 33 deletions
7
www/src/lib/consts.ts
Normal file
7
www/src/lib/consts.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
export const DEFAULT_CATEGORY = 'none';
|
||||||
|
|
||||||
|
export const SECTIONS = {
|
||||||
|
plaintext: 'plaintext',
|
||||||
|
bookmarks: 'bookmarks',
|
||||||
|
guestbook: 'guestbook',
|
||||||
|
} as const;
|
||||||
|
|
@ -18,11 +18,12 @@ export function formatListItem(
|
||||||
date: Date,
|
date: Date,
|
||||||
url: string,
|
url: string,
|
||||||
title: string,
|
title: string,
|
||||||
options?: { pinned?: boolean; suffix?: string }
|
options?: { pinned?: boolean; suffix?: string; prefix?: string }
|
||||||
): string {
|
): string {
|
||||||
const pinnedBadge = options?.pinned ? ' [pinned]' : '';
|
const pinnedBadge = options?.pinned ? ' [pinned]' : '';
|
||||||
const suffix = options?.suffix ? ` ${options.suffix}` : '';
|
const suffix = options?.suffix ? ` ${options.suffix}` : '';
|
||||||
return `<span class="muted">${formatDate(date)}</span> <a href="${url}">${title}</a>${pinnedBadge}${suffix}`;
|
const prefix = options?.prefix ?? '';
|
||||||
|
return `${prefix}<span class="muted">${formatDate(date)}</span> <a href="${url}">${title}</a>${pinnedBadge}${suffix}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Sortable {
|
interface Sortable {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import type { CollectionEntry } from 'astro:content';
|
import type { CollectionEntry } from 'astro:content';
|
||||||
import { getGitDates, type GitDates } from './git';
|
import { getGitDates, type GitDates } from './git';
|
||||||
|
import { DEFAULT_CATEGORY } from './consts';
|
||||||
|
|
||||||
type Post = CollectionEntry<'md'>;
|
type Post = CollectionEntry<'md'>;
|
||||||
|
|
||||||
|
|
@ -55,15 +56,15 @@ export function organizePostsByCategory(posts: PostWithDates[], { sortAlphabetic
|
||||||
categories: string[];
|
categories: string[];
|
||||||
} {
|
} {
|
||||||
const grouped = posts.reduce((acc, post) => {
|
const grouped = posts.reduce((acc, post) => {
|
||||||
const category = post.data.category ?? 'md';
|
const category = post.data.category ?? DEFAULT_CATEGORY;
|
||||||
if (!acc[category]) acc[category] = [];
|
if (!acc[category]) acc[category] = [];
|
||||||
acc[category].push(post);
|
acc[category].push(post);
|
||||||
return acc;
|
return acc;
|
||||||
}, {} as Record<string, PostWithDates[]>);
|
}, {} as Record<string, PostWithDates[]>);
|
||||||
|
|
||||||
const categories = Object.keys(grouped).sort((a, b) => {
|
const categories = Object.keys(grouped).sort((a, b) => {
|
||||||
if (a === 'md') return -1;
|
if (a === DEFAULT_CATEGORY) return -1;
|
||||||
if (b === 'md') return 1;
|
if (b === DEFAULT_CATEGORY) return 1;
|
||||||
return a.localeCompare(b);
|
return a.localeCompare(b);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { getApprovedEntries, type GuestbookEntry } from '../lib/db';
|
||||||
import { formatDate, extractDomain, formatListItem } from '../lib/format';
|
import { formatDate, extractDomain, formatListItem } from '../lib/format';
|
||||||
import { organizePostsByCategory, getSlug, enrichPostsWithDates } from '../lib/md';
|
import { organizePostsByCategory, getSlug, enrichPostsWithDates } from '../lib/md';
|
||||||
import { getTxtFiles } from '../lib/txt';
|
import { getTxtFiles } from '../lib/txt';
|
||||||
|
import { DEFAULT_CATEGORY, SECTIONS } from '../lib/consts';
|
||||||
|
|
||||||
const rawPosts = await getCollection('md');
|
const rawPosts = await getCollection('md');
|
||||||
const posts = enrichPostsWithDates(rawPosts);
|
const posts = enrichPostsWithDates(rawPosts);
|
||||||
|
|
@ -16,6 +17,12 @@ const bookmarks = bookmarksCollection
|
||||||
|
|
||||||
const txtFiles = getTxtFiles();
|
const txtFiles = getTxtFiles();
|
||||||
|
|
||||||
|
const visibleLabels = [...sortedCategories.filter(c => c !== DEFAULT_CATEGORY), ...Object.values(SECTIONS)];
|
||||||
|
const labelWidth = Math.max(...visibleLabels.map(l => l.length));
|
||||||
|
const labelPrefix = (label: string, href: string) =>
|
||||||
|
`${' '.repeat(labelWidth - label.length)}<a class="section-label" href="${href}">${label}</a> `;
|
||||||
|
const blankPrefix = ' '.repeat(labelWidth + 2);
|
||||||
|
|
||||||
let guestbookEntries: GuestbookEntry[] = [];
|
let guestbookEntries: GuestbookEntry[] = [];
|
||||||
try {
|
try {
|
||||||
guestbookEntries = await getApprovedEntries();
|
guestbookEntries = await getApprovedEntries();
|
||||||
|
|
@ -33,35 +40,29 @@ const urls = [
|
||||||
|
|
||||||
{sortedCategories.map(category => {
|
{sortedCategories.map(category => {
|
||||||
const categoryPosts = grouped[category];
|
const categoryPosts = grouped[category];
|
||||||
|
const isDefault = category === DEFAULT_CATEGORY;
|
||||||
return (
|
return (
|
||||||
<section data-section={category}>
|
<section data-section={category}>
|
||||||
<a class="section-label" href={`?just=${category}`}>{category}</a>
|
<pre set:html={categoryPosts.map((post, i) => formatListItem(post.dates.created, `/${getSlug(post.id)}`, post.data.title, { pinned: post.data.pinned, prefix: (!isDefault && i === 0) ? labelPrefix(category, `?just=${category}`) : blankPrefix })).join('\n')} />
|
||||||
<pre set:html={categoryPosts.map(post => formatListItem(post.dates.created, `/${getSlug(post.id)}`, post.data.title, { pinned: post.data.pinned })).join('\n')} />
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<section data-section="txt">
|
<section data-section={SECTIONS.plaintext}>
|
||||||
<a class="section-label" href="?just=txt">txt</a>
|
<pre set:html={txtFiles.map((f, i) => formatListItem(f.date, `/${f.name}`, f.name, { pinned: f.pinned, prefix: i === 0 ? labelPrefix(SECTIONS.plaintext, `?just=${SECTIONS.plaintext}`) : blankPrefix })).join('\n')} />
|
||||||
<pre set:html={txtFiles.map(f => formatListItem(f.date, `/${f.name}`, f.name, { pinned: f.pinned })).join('\n')} />
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-section="bookmarks">
|
<section data-section={SECTIONS.bookmarks}>
|
||||||
<a class="section-label" href="?just=bookmarks">bookmarks</a>
|
<pre set:html={bookmarks.map((b, i) => formatListItem(b.data.date, b.data.url, b.data.title, { suffix: `<span class="muted">(${extractDomain(b.data.url)})</span>`, prefix: i === 0 ? labelPrefix(SECTIONS.bookmarks, `?just=${SECTIONS.bookmarks}`) : blankPrefix })).join('\n')} />
|
||||||
<pre set:html={bookmarks.map(b => formatListItem(b.data.date, b.data.url, b.data.title, { suffix: `<span class="muted">(${extractDomain(b.data.url)})</span>` })).join('\n')} />
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-section="guestbook">
|
<section data-section={SECTIONS.guestbook}>
|
||||||
<a class="section-label" href="?just=guestbook">guestbook</a>
|
<pre class="guestbook-entries" set:html={guestbookEntries.map((e, i) => {
|
||||||
<div class="guestbook-entries">
|
const prefix = i === 0 ? labelPrefix(SECTIONS.guestbook, `?just=${SECTIONS.guestbook}`) : blankPrefix;
|
||||||
{guestbookEntries.map(e => (
|
const nameHtml = e.url ? `<a href="${e.url}"><b>${e.name}</b></a>` : `<b>${e.name}</b>`;
|
||||||
<div class="guestbook-entry">
|
return `${prefix}<span class="muted">${formatDate(e.createdAt)}</span> ${nameHtml} ${e.message}`;
|
||||||
<span class="muted">{formatDate(e.createdAt)}</span>
|
}).join('\n')} />
|
||||||
<span><b set:html={e.url ? `<a href="${e.url}">${e.name}</a>` : e.name} /> {e.message}</span>
|
<form id="guestbook-form" class="guestbook-form" style={`margin-left: ${labelWidth + 12}ch`}>
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<form id="guestbook-form" class="guestbook-form">
|
|
||||||
<input type="text" name="name" placeholder="name" required maxlength="100" /><br />
|
<input type="text" name="name" placeholder="name" required maxlength="100" /><br />
|
||||||
<input type="text" name="message" placeholder="message" required maxlength="500" /><br />
|
<input type="text" name="message" placeholder="message" required maxlength="500" /><br />
|
||||||
<input type="url" name="url" placeholder="url (optional)" maxlength="200" /><br />
|
<input type="url" name="url" placeholder="url (optional)" maxlength="200" /><br />
|
||||||
|
|
|
||||||
|
|
@ -101,17 +101,10 @@ section pre {
|
||||||
}
|
}
|
||||||
|
|
||||||
.guestbook-entries {
|
.guestbook-entries {
|
||||||
font-family: monospace;
|
white-space: pre-wrap;
|
||||||
}
|
|
||||||
|
|
||||||
.guestbook-entry {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 8ch 1fr;
|
|
||||||
gap: 0 4ch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.guestbook-form {
|
.guestbook-form {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
margin-left: 12ch;
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue