Fix some alignment issues, add reading time estimates
This commit is contained in:
parent
5e8eb94d6b
commit
25f07fd9bb
24
package-lock.json
generated
24
package-lock.json
generated
|
@ -8,11 +8,13 @@
|
|||
"name": "bgenc.net-new",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@sveltejs/adapter-static": "^2.0.3"
|
||||
"@sveltejs/adapter-static": "^2.0.3",
|
||||
"reading-time-estimator": "^1.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/kit": "^1.27.6",
|
||||
"@types/lodash": "^4.14.201",
|
||||
"@types/node": "^20.12.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"date-fns": "^2.30.0",
|
||||
|
@ -360,6 +362,15 @@
|
|||
"integrity": "sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.12.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz",
|
||||
"integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==",
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pug": {
|
||||
"version": "2.0.9",
|
||||
"dev": true,
|
||||
|
@ -2356,6 +2367,11 @@
|
|||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reading-time-estimator": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/reading-time-estimator/-/reading-time-estimator-1.11.0.tgz",
|
||||
"integrity": "sha512-2813WXSxCPsDvgrYq+cPBI4gGqgmtKlo62rpI0mwnhrMfZJIqbDfOeidr9Y36OruDesQGmYA9DkVRmvsBbv2DA=="
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
||||
|
@ -2966,6 +2982,12 @@
|
|||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/unist-util-stringify-position": {
|
||||
"version": "2.0.3",
|
||||
"dev": true,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"devDependencies": {
|
||||
"@sveltejs/kit": "^1.27.6",
|
||||
"@types/lodash": "^4.14.201",
|
||||
"@types/node": "^20.12.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"date-fns": "^2.30.0",
|
||||
|
@ -34,6 +35,7 @@
|
|||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@sveltejs/adapter-static": "^2.0.3"
|
||||
"@sveltejs/adapter-static": "^2.0.3",
|
||||
"reading-time-estimator": "^1.11.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
<style>
|
||||
a,
|
||||
button {
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
color: hsl(var(--color-text-h), var(--color-text-s), calc(100% - var(--color-text-l)));
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
</script>
|
||||
|
||||
<header>
|
||||
<a href="/">
|
||||
<picture class="logo">
|
||||
<a class="logo" href="/">
|
||||
<picture>
|
||||
<source srcset={Avif} type="image/avif" />
|
||||
<source srcset={WebP} type="image/webp" />
|
||||
<img
|
||||
|
@ -31,9 +31,11 @@
|
|||
align-items: center;
|
||||
margin-right: 4rem;
|
||||
gap: 2rem;
|
||||
margin-bottom: -3rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 12rem;
|
||||
align-self: flex-start;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import _ from 'lodash';
|
||||
import { readingTime } from 'reading-time-estimator';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { readFile } from 'fs/promises';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
|
@ -7,15 +13,18 @@ export async function load({ params }) {
|
|||
const iterablePostFiles = Object.entries(allPostFiles);
|
||||
|
||||
const posts = await Promise.all(
|
||||
iterablePostFiles.map(async ([path, resolver]) => {
|
||||
iterablePostFiles.map(async ([filePath, resolver]) => {
|
||||
const { metadata } = await resolver();
|
||||
|
||||
const slug = /[/]([^/]*)[.]md$/.exec(path)?.[1];
|
||||
if (!slug) throw new Error(`Could not parse slug from path: ${path}`);
|
||||
const slug = /[/]([^/]*)[.]md$/.exec(filePath)?.[1];
|
||||
if (!slug) throw new Error(`Could not parse slug from path: ${filePath}`);
|
||||
|
||||
const contents = await readFile(path.join(__dirname, '..', `${slug}.md`), 'utf8');
|
||||
|
||||
return {
|
||||
meta: metadata,
|
||||
path: slug,
|
||||
readingTime: readingTime(contents),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
@ -33,3 +42,4 @@ export async function load({ params }) {
|
|||
pageCount: Math.ceil(posts.length / PAGE_SIZE),
|
||||
};
|
||||
}
|
||||
export type Post = Awaited<ReturnType<typeof load>>['posts'][number];
|
|
@ -1,11 +1,13 @@
|
|||
<script lang="ts">
|
||||
import Button from '$lib/Button.svelte';
|
||||
import { ArrowLeft, ArrowLineLeft, ArrowLineRight, ArrowRight } from 'phosphor-svelte';
|
||||
import { format } from 'date-fns';
|
||||
import type { Post } from './+page.server';
|
||||
|
||||
export let data;
|
||||
|
||||
function groupPosts(posts: any[]) {
|
||||
const postsByYear = new Map<string, any[]>();
|
||||
function groupPosts(posts: Post[]) {
|
||||
const postsByYear = new Map<string, Post[]>();
|
||||
posts.forEach((post) => {
|
||||
const year = format(new Date(post.meta.date), 'yyyy');
|
||||
if (!postsByYear.has(year)) {
|
||||
|
@ -31,6 +33,7 @@
|
|||
<time datetime={post.meta.date}>
|
||||
{format(new Date(post.meta.date), 'MMMM d')}
|
||||
</time>
|
||||
<span>about {post.readingTime.text}</span>
|
||||
</li>
|
||||
</a>
|
||||
{/each}
|
||||
|
@ -40,16 +43,14 @@
|
|||
</ul>
|
||||
|
||||
<div class="pagination-controls">
|
||||
<Button disabled={data.page < 3} href={'/posts/'}>{data.page < 3 ? '_' : data.page - 1}</Button>
|
||||
<Button disabled={data.page < 3} href={'/posts/'}><ArrowLineLeft /></Button>
|
||||
<Button disabled={data.page === 1} href={data.page === 2 ? '/posts/' : `/posts/${data.page - 1}`}
|
||||
>{data.page === 1 ? '_' : data.page - 1}</Button
|
||||
><ArrowLeft /></Button
|
||||
>
|
||||
<span class="current-page">{data.page}</span>
|
||||
<Button disabled={!data.hasMore} href="/posts/{data.page + 1}"
|
||||
>{data.hasMore ? data.page + 1 : '_'}</Button
|
||||
>
|
||||
<Button disabled={!data.hasMore} href="/posts/{data.page + 1}"><ArrowRight /></Button>
|
||||
<Button disabled={data.page > data.pageCount - 2} href="/posts/{data.pageCount}"
|
||||
>{data.page > data.pageCount - 2 ? '_' : data.pageCount}</Button
|
||||
><ArrowLineRight /></Button
|
||||
>
|
||||
</div>
|
||||
|
||||
|
@ -65,25 +66,14 @@
|
|||
gap: 0.2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
:global(.pagination-controls > :first-child) {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
:global(.pagination-controls > :last-child) {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.current-page {
|
||||
display: inline-block;
|
||||
color: hsl(var(--color-text-h), var(--color-text-s), calc(100% - var(--color-text-l)));
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
opacity: 0.6;
|
||||
font-weight: bolder;
|
||||
color: var(--color-primary);
|
||||
cursor: unset;
|
||||
user-select: none;
|
||||
background-color: var(--color-primary);
|
||||
padding: 0.5rem 1rem;
|
||||
clip-path: var(--clip-path-button);
|
||||
transition: all var(--animation-speed) var(--animation-type);
|
||||
}
|
||||
.post-title {
|
||||
margin-bottom: 0.3rem;
|
||||
|
|
Loading…
Reference in a new issue