get poetry stuff workin

This commit is contained in:
Silas 2024-05-29 18:33:13 -04:00
parent 3d22344e7f
commit 251620863c
Failed to generate hash of commit
42 changed files with 632 additions and 299 deletions

7
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"recommendations": [
"svelte.svelte-vscode",
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint"
]
}

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}

86
package-lock.json generated
View File

@ -20,6 +20,7 @@
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tailwindcss/typography": "^0.5.13",
"@theatre/core": "^0.7.1",
"@theatre/studio": "^0.7.1",
"@threlte/theatre": "^2.1.7",
@ -28,6 +29,7 @@
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"autoprefixer": "^10.4.19",
"daisyui": "^4.11.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.35.1",
@ -1811,6 +1813,34 @@
"vite": "^5.0.0"
}
},
"node_modules/@tailwindcss/typography": {
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz",
"integrity": "sha512-ADGcJ8dX21dVVHIwTRgzrcunY6YY9uSlAHHGVKvkA+vLc5qLwEszvKts40lx7z0qc4clpjclwLeK5rVCV2P/uw==",
"dev": true,
"dependencies": {
"lodash.castarray": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.merge": "^4.6.2",
"postcss-selector-parser": "6.0.10"
},
"peerDependencies": {
"tailwindcss": ">=3.0.0 || insiders"
}
},
"node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
"version": "6.0.10",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@theatre/core": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/@theatre/core/-/core-0.7.1.tgz",
@ -2966,6 +2996,16 @@
"node": ">= 8"
}
},
"node_modules/css-selector-tokenizer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz",
"integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
"fastparse": "^1.1.2"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
@ -3019,6 +3059,34 @@
"resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz",
"integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A=="
},
"node_modules/culori": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz",
"integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/daisyui": {
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.11.1.tgz",
"integrity": "sha512-obT9CUbQdW6eoHwSeT5VwaRrWlwrM4OT5qlfdJ0oQlSIEYhwnEl2+L2fwu5PioLbitwuMdYC2X8I1cyy8Pf6LQ==",
"dev": true,
"dependencies": {
"css-selector-tokenizer": "^0.8",
"culori": "^3",
"picocolors": "^1",
"postcss-js": "^4"
},
"engines": {
"node": ">=16.9.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/daisyui"
}
},
"node_modules/data-view-buffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
@ -3846,6 +3914,12 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
"node_modules/fastparse": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
"dev": true
},
"node_modules/fastq": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
@ -4970,6 +5044,18 @@
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"dev": true
},
"node_modules/lodash.castarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
"dev": true
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
"dev": true
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",

View File

@ -17,6 +17,7 @@
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tailwindcss/typography": "^0.5.13",
"@theatre/core": "^0.7.1",
"@theatre/studio": "^0.7.1",
"@threlte/theatre": "^2.1.7",
@ -25,6 +26,7 @@
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"autoprefixer": "^10.4.19",
"daisyui": "^4.11.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.35.1",

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<body data-sveltekit-preload-data="hover" data-theme="forest">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@ -0,0 +1,19 @@
<script context="module">
import { onMount } from 'svelte';
import Headline from './poetry/h1.svelte';
import p from './poetry/p.svelte';
export { Headline as h1, p };
</script>
<script lang="ts">
export let title;
export let date;
export let categories;
export let tags;
export let year;
export let layout;
</script>
<main>
<slot />
</main>

View File

@ -41,7 +41,7 @@ export const fetchMarkdownPosts = async (
section: SectionKey,
limit: number,
offset: number
): Promise<Post[]> => {
): Promise<{posts: Post[], total: number}> => {
let posts: Record<string, () => Promise<unknown>>;
switch (section) {
case 'poetry':
@ -74,7 +74,9 @@ export const fetchMarkdownPosts = async (
})
);
const paginatedPosts = allPosts.slice(offset, offset + limit);
const sortedPosts = allPosts.sort((a, b) => new Date(a.meta.date).getTime() - new Date(b.meta.date).getTime() );
return paginatedPosts;
const paginatedPosts = sortedPosts.slice(offset, offset + limit);
return {posts: paginatedPosts, total: allPosts.length};
};

View File

@ -0,0 +1,3 @@
<h1 class="poetry-headline">
<slot></slot>
</h1>

View File

@ -0,0 +1,3 @@
<p class="whitespace-pre">
<slot></slot>
</p>

View File

@ -1,13 +1,13 @@
---
categories:
- Poetry
- Poetry
date: 2013-01-10 00:00:00 +0000
tags:
- Humor
- Muffins
- Humor
- Muffins
title: Breakfast Blues
---
Lost my reason to wake in the morning
Ever since you left me without warning.
We've always seemed to have gotten along

View File

@ -6,6 +6,7 @@ tags:
- Christian
title: Djinn
year: 2019
layout: poetry
---
"Jesus dropped by."

View File

@ -1,14 +1,14 @@
---
categories:
- Poetry
- Poetry
date: 2018-04-28 12:00:00 +0000
tags:
- Wisdom
- Lessons
- Wisdom
- Lessons
title: I've Seen
year: 2018
---
I've seen tears fall
From the face of a giant,
A hint of desperation

View File

@ -1,12 +1,12 @@
---
categories:
- Poetry
- Poetry
date: 2019-02-02 12:00:00 +0000
tags:
- Love
- Lovers
- Relationships
- Introspective
- Love
- Lovers
- Relationships
- Introspective
title: Infrared Homing
---
@ -40,4 +40,3 @@ A candle
Can't replace it,
But any fire
Is better than none.

View File

@ -1,12 +1,11 @@
---
categories:
- Poetry
- Poetry
date: 2020-10-01 20:00:00 +0000
tags:
- Neuroscience
- Wisdom
- Neuroscience
- Wisdom
title: Judge Judy
---
With each passing moment,
@ -28,4 +27,3 @@ The neurons are dismissed
Then return to jury duty
For another microcosm case
In their show of Judge Judy.

View File

@ -1,10 +1,10 @@
---
categories:
- Poetry
- Poetry
date: 2018-06-25 20:00:00 +0000
tags:
- Chess
- Lessons
- Chess
- Lessons
title: King's Pin
year: 2018
---
@ -24,4 +24,3 @@ Synonymous to beginner.
A satisfying poach
Awarded to the winner.

View File

@ -1,12 +1,12 @@
---
categories:
- Poetry
- Poetry
date: 2014-10-27 00:00:00 +0000
tags:
- Humor
- Humor
title: Klepto Couches
---
My home houses countless couches.
Klepto-couches with pickpocket pouches
That swiftly swipe your cellular phone

View File

@ -1,13 +1,13 @@
---
categories:
- Poetry
- Poetry
date: 2012-02-25 00:00:00 +0000
tags:
- Grounds
- Covenant
- Grounds
- Covenant
title: Leafblower
---
You're the girl sitting on the park bench.
I'm the guy with a leaf blower.
I've gotta do my job,

View File

@ -1,9 +1,9 @@
---
categories:
- Poetry
- Poetry
date: 2019-10-26 12:00:00 +0000
tags:
- Wisdom
- Wisdom
title: Of Molecules And Men
---
@ -49,4 +49,3 @@ To cease to be
Is to become
Every friend
And alleged foe.

View File

@ -1,13 +1,13 @@
---
categories:
- Poetry
- Poetry
date: 2012-03-01 00:00:00 +0000
tags:
- Grounds
- Covenant
- Grounds
- Covenant
title: Monday Morning Shift
---
These plants look beautiful, but not at this location.
They must be eradicated according to administration.
I brought out my tools; Some gloves and a spade,

View File

@ -1,13 +1,12 @@
---
categories:
- Poetry
- Poetry
date: 2016-05-10 00:00:00 +0000
tags:
- Work
- Worry
- Self-conscious
- Work
- Worry
- Self-conscious
title: Morning Commute
---
A few minutes into my morning commute
@ -24,4 +23,3 @@ So I ditched the car and snuck into work,
Though I knew my hopes and dreams would be seen
Swirled amidst my self-doubt and worries
Like creamer mixed in bitter cups of caffeine.

View File

@ -1,14 +1,13 @@
---
categories:
- Poetry
- Poetry
date: 2015-07-15 00:00:00 +0000
tags:
- Relationships
- Love
- Drinking
- Humor
- Relationships
- Love
- Drinking
- Humor
title: Perfect Situation
---
When I'm hammered,
@ -32,5 +31,3 @@ And I speculate the odds
Given a perfect situation
In a parallel universe
If I'd rise to the occasion.

View File

@ -1,12 +1,11 @@
---
categories:
- Poetry
- Poetry
date: 2016-12-20 00:00:00 +0000
tags:
- Introspective
- Silence
- Introspective
- Silence
title: Silent Silas
---
The windows to my soul
@ -24,4 +23,3 @@ But if it's any consolation,
I am striving to get better
At voicing my own thoughts
Without resorting to writing letters.

View File

@ -1,18 +1,15 @@
---
categories:
- Poetry
- Poetry
date: 2014-07-20 00:00:00 +0000
tags:
- Love
- Relationships
- Realtalk
- Love
- Relationships
- Realtalk
title: Thought Experiment
---
Love is a free fall
And I'm afraid of the ground.
If I jump and no one's there,
Will my body make a sound?

View File

@ -1,13 +1,12 @@
---
categories:
- Poetry
- Poetry
date: 2017-10-10 00:00:00 +0000
tags:
- Wisdom
- Speech
- Verbal Abuse
- Wisdom
- Speech
- Verbal Abuse
title: Unintentional Internalization
---
Our skin's as thick
@ -29,4 +28,3 @@ For each one we've endured,
We've dealt so many more
For the most innocuous remark
Still can pierce like a sword.

View File

@ -1,12 +1,12 @@
---
categories:
- Poetry
- Poetry
date: 2013-05-10 00:00:00 +0000
tags:
- Realtalk
- Realtalk
title: Who Am I?
---
Am I the clothes on my back
And the hair on my head?
Am I the people I'm with

View File

@ -1,7 +1,52 @@
<script lang="ts">
import App from '$lib/components/scenes/app/App.svelte';
<script>
import '../../app.css';
</script>
<App>
<div class="flex flex-col h-screen">
<div class="navbar bg-base-300 sticky top-0 z-50">
<div class="navbar-start">
<div class="dropdown">
<div tabindex="-1" class="btn btn-ghost lg:hidden">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h8m-8 6h16"
/>
</svg>
</div>
<ul
tabindex="-1"
class="menu menu-sm dropdown-content mt-3 z-10 p-2 shadow bg-base-300 rounded-box w-52"
>
<li><a href="/thoughts">Thoughts</a></li>
<li><a href="/poetry">Poetry</a></li>
<li><a href="/projects">Projects</a></li>
<li><a href="/experiments">Experiments</a></li>
<li><a href="/services">Services</a></li>
</ul>
</div>
<a class="btn btn-outline btn-primary text-xl" href="/">silentsilas</a>
</div>
<div class="navbar-end hidden lg:flex">
<ul class="menu menu-horizontal px-1">
<li><a href="/thoughts">Thoughts</a></li>
<li><a href="/poetry">Poetry</a></li>
<li><a href="/projects">Projects</a></li>
<li><a href="/experiments">Experiments</a></li>
<li><a href="/services">Services</a></li>
</ul>
</div>
</div>
<div class="flex flex-col items-center flex-1 overflow-auto">
<slot />
</App>
</div>
</div>

View File

@ -1,23 +1,106 @@
<script lang="ts">
import MenuItem from '$lib/components/scenes/app/MenuItem.svelte';
import { onMount } from 'svelte';
import { fade } from 'svelte/transition';
type Greeting = {
greeting: string;
language: string;
romanisation?: string;
};
const GREETINGS: Greeting[] = [
{ greeting: '你好', language: 'Mandarin', romanisation: 'Nǐ hǎo' },
{ greeting: 'नमस्ते', language: 'Hindi', romanisation: 'Namaste' },
{ greeting: 'Hola', language: 'Spanish' },
{ greeting: 'হ্যালো', language: 'Bengali', romanisation: 'Hyālō' },
{ greeting: 'ہیلو', language: 'Urdu', romanisation: 'Hello' },
{ greeting: 'Oi', language: 'Portuguese' },
{ greeting: 'Здравствуйте', language: 'Russian', romanisation: 'Zdravstvuyte' },
{ greeting: 'こんにちは', language: 'Japanese', romanisation: "Kon'nichiwa" },
{ greeting: 'Merhaba', language: 'Turkish' },
{ greeting: '안녕하세요', language: 'Korean', romanisation: 'Annyeonghaseyo' },
{ greeting: 'Hallo', language: 'German' },
{ greeting: 'สวัสดี', language: 'Thai', romanisation: 'S̄wạs̄dī' },
{ greeting: 'مرحبا', language: 'Arabic', romanisation: 'Marhaba' },
{ greeting: 'היי', language: 'Hebrew', romanisation: 'Hi' },
{ greeting: 'Helo', language: 'Welsh' },
{ greeting: 'Pozdrav', language: 'Croatian' },
{ greeting: 'Hej', language: 'Swedish' },
{ greeting: 'Hyālō', language: 'Bengali' },
{ greeting: 'Salut', language: 'French' },
{ greeting: 'Ciao', language: 'Italian' }
];
let greetings = [...GREETINGS];
let currentGreeting: Greeting = { greeting: 'Hello', language: 'English' };
let visible = false;
onMount(() => {
visible = true;
const interval = setInterval(getRandomGreeting, 3000);
return () => clearInterval(interval);
});
async function getRandomGreeting() {
visible = false;
await new Promise((r) => setTimeout(r, 1000));
if (greetings.length === 0) {
greetings = [...GREETINGS];
}
const greetingIndex = Math.floor(Math.random() * greetings.length);
const greeting = greetings[greetingIndex];
greetings = greetings.filter((_, index) => index !== greetingIndex);
currentGreeting = greeting;
visible = true;
return greeting;
}
</script>
<MenuItem position={[-2.5, 7.5, 0]} htmlContent="Poetry" href="/poetry" />
<MenuItem
position={[2.5, 2.5, -2.5]}
htmlContent="Projects"
clickHandler={() => console.log('clicked!')}
/>
<MenuItem
position={[-2.5, -2.5, -2.5]}
htmlContent="Thoughts"
clickHandler={() => console.log('clicked!')}
/>
<MenuItem
position={[2.5, -7.5, 2.5]}
htmlContent="About"
clickHandler={() => console.log('clicked!')}
/>
<div class="container mx-auto flex flex-col justify-center items-center flex-1">
<div class="justify-center items-center text-center m-10">
{#if visible && currentGreeting}
<div
transition:fade={{ duration: 1200 }}
>
<span class="font-bold">{currentGreeting.greeting}</span>
{#if currentGreeting.romanisation}
<span class="text-gray-500">( {currentGreeting.romanisation} )</span>
{/if}
</div>
<p class="mt-2 text-gray-700" transition:fade={{ delay: 400, duration: 400 }}>
That's {currentGreeting.language} for hello!
</p>
{/if}
</div>
<div class="text-center prose px-4">
<p>
The name's Silas. I write code for a living, and sometimes for fun. I use <a
href="https://elixir-lang.org/"
target="_blank">Elixir</a
>
at my day job, and recently have been messing around with
<a href="https://elixir-lang.org/" target="_blank">Rust</a>,
<a href="https://kit.svelte.dev/" target="_blank">Svelte</a>, and
<a href="https://threejs.org/" target="_blank">three.js</a>
</p>
<p>
Here you can browse my shower <a href="/thoughts" class="link">thoughts</a> and bad
<a href="/poetry" class="link">poetry</a>. Opinions are personally mine and not endorsed by my
employer.
</p>
<p>
I tend to start a lot of <a href="/projects" class="link">projects</a>, but I'm trying to
finish more. I also like to toy with weird web technologies and will host the
<a href="/experiments" class="link">experiments</a> here.
</p>
<p>
I self-host a lot of <a href="/services" class="link">services</a> I find useful. None of them
run any analytics or log your activity, but the software/servers may be outdated, so use at your
own risk.
</p>
<p>Shalom.</p>
</div>
</div>

View File

@ -0,0 +1,15 @@
export const load = async ({ fetch, url }) => {
const limit = 8;
const page = Number(url.searchParams.get('page')) || 1;
const response = await fetch(`/api/poetry?limit=${limit}&page=${page}`);
const { posts, total } = await response.json();
return {
posts,
total,
page,
limit
};
};

View File

@ -1,39 +1,70 @@
<script lang="ts">
import MenuItem from '$lib/components/scenes/app/MenuItem.svelte';
import type { PageData } from './$types';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import type { PageData } from '../poetry/$types';
export let data: PageData;
const xMin = -2.5,
xMax = 2.5;
const yMin = -7.5,
yMax = 7.5;
const zMin = -2.5,
zMax = 2.5;
// Calculate positions
const calculatePositions = (numPosts: number): Array<[number, number, number]> => {
const positions: Array<[number, number, number]> = [];
const numRows = Math.ceil(Math.sqrt(numPosts));
const numCols = Math.ceil(numPosts / numRows);
for (let i = 0; i < numPosts; i++) {
const row = Math.floor(i / numCols);
const col = i % numCols;
const x = xMin + (xMax - xMin) * (col / (numCols - 1));
const y = yMin + (yMax - yMin) * (row / (numRows - 1));
const z = zMin;
positions.push([x, y, z]);
}
return positions;
const formatDate = (date: string) => {
return new Date(date).toLocaleDateString(undefined, {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
// Generate positions based on the number of posts
const positions = calculatePositions(data.posts.length);
let { posts, total } = data;
const limit = 8;
let currentPage = Number($page.url.searchParams.get('page')) || 1;
let totalPages = Math.ceil(total / limit);
$: $page.url.searchParams.get('page'),
(currentPage = Number($page.url.searchParams.get('page')) || 1);
async function fetchData(page: number) {
const response = await fetch(`/api/poetry?limit=${limit}&page=${page}`);
const newData = await response.json();
currentPage = page;
posts = newData.posts;
total = newData.total;
totalPages = Math.ceil(total / limit);
}
function navigate(page: number) {
fetchData(page);
goto(`/poetry/?page=${page}`, { replaceState: true });
}
</script>
{#each data.posts as post, i}
<MenuItem position={positions[i]} htmlContent={post.meta.title} href={post.path} />
{/each}
<div class="container mx-auto flex flex-col items-center py-10">
<div class="prose">
<h1 class="py-6">Poetry</h1>
</div>
<ul>
{#each posts as post}
<li class="py-4">
<h3 class="pb-1">
<a class="link" href={post.path}>
{post.meta.title}
</a>
</h3>
<p class="text-sm">{formatDate(post.meta.date)}</p>
</li>
{/each}
</ul>
</div>
{#if total > 1}
<nav class="join justify-end">
<button
class="join-item btn-primary btn btn-outline"
on:click={() => navigate(currentPage - 1)}
disabled={currentPage === 1}>Prev</button
>
<button class="join-item btn btn-outline">{currentPage} of {totalPages}</button>
<button
class="join-item btn btn-primary btn-outline"
on:click={() => navigate(currentPage + 1)}
disabled={currentPage === totalPages}>Next</button
>
</nav>
{/if}

View File

@ -1,19 +1,16 @@
<script lang="ts">
import MenuItem from '$lib/components/scenes/app/MenuItem.svelte';
import type { PageData } from './$types';
import DomPortal from '$lib/utils/DomPortal.svelte';
export let data: PageData;
const { title, date: _date, Content, categories: _ } = data;
</script>
<MenuItem position={[-2.5, 10, 0]} htmlContent="Back" href="/poetry" />
<DomPortal target="#overlay">
<div class="py-4">
<h1 class="text-xl font-medium text-black pb-2">{title}</h1>
<div>
<div class="container mx-auto flex flex-col items-center py-10">
<div class="prose">
<h1 class="py-6">{title}</h1>
</div>
<div class="prose">
<Content />
</div>
</div>
</DomPortal>
<a href="/poetry" class="link mt-10">Back to Poetry</a>
</div>

View File

@ -13,6 +13,7 @@ export async function load({ params }) {
Content,
title,
date: validDate,
categories
categories,
post
};
}

View File

@ -1,38 +1 @@
<script lang="ts">
import CanvasContainer from '$lib/components/scenes/app/CanvasContainer.svelte';
import '../app.css';
</script>
<CanvasContainer>
<slot />
</CanvasContainer>
<div class="overlay container" id="overlay"></div>
<style>
:global(body) {
margin: 0;
}
.canvas {
width: 100%;
height: 100%;
background: rgb(0, 36, 6);
background: linear-gradient(180deg, rgba(0, 36, 6, 1) 0%, rgba(0, 0, 0, 1) 100%);
position: absolute;
justify-content: center;
align-items: center;
}
.overlay {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: rgba(16, 56, 30, 0.9);
}
</style>
<slot />

View File

@ -1,2 +1,2 @@
export const prerender = true
export const ssr = false
export const ssr = true

View File

@ -2,13 +2,14 @@ import { fetchMarkdownPosts } from '$lib/utils';
import { json } from '@sveltejs/kit';
export const GET = async ({ url }) => {
const limit = Number(url.searchParams.get('limit')) || 6;
const offset = Number(url.searchParams.get('offset')) || 0;
const allPosts = await fetchMarkdownPosts('poetry', limit, offset);
const page = Number(url.searchParams.get('page')) || 1;
const limit = Number(url.searchParams.get('limit')) || 8;
const offset = (page - 1) * limit;
const {posts: allPosts, total: total} = await fetchMarkdownPosts('poetry', limit, offset);
const sortedPosts = allPosts.sort((a, b) => {
return new Date(b.meta.date).getTime() - new Date(a.meta.date).getTime();
});
return json(sortedPosts);
return json({posts: sortedPosts, total: total, page: page});
};

View File

@ -0,0 +1,42 @@
<script lang="ts">
import App from '$lib/components/scenes/app/App.svelte';
import CanvasContainer from '$lib/components/scenes/app/CanvasContainer.svelte';
import '../../app.css'
</script>
<CanvasContainer>
<App>
<slot />
</App>
</CanvasContainer>
<div class="overlay container" id="overlay"></div>
<style>
:global(body) {
margin: 0;
}
.canvas {
width: 100%;
height: 100%;
background: rgb(0, 36, 6);
background: linear-gradient(180deg, rgba(0, 36, 6, 1) 0%, rgba(0, 0, 0, 1) 100%);
position: absolute;
justify-content: center;
align-items: center;
}
.overlay {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: rgba(16, 56, 30, 0.9);
}
</style>

View File

@ -0,0 +1,2 @@
export const prerender = true
export const ssr = false

View File

@ -0,0 +1,37 @@
<script lang="ts">
import MenuItem from '$lib/components/scenes/app/MenuItem.svelte';
import type { PageData } from './$types';
export let data: PageData;
const xMin = -2.5,
xMax = 2.5;
const yMin = -7.5,
yMax = 7.5;
const zMin = -2.5,
zMax = 2.5;
const calculatePositions = (numPosts: number): Array<[number, number, number]> => {
const positions: Array<[number, number, number]> = [];
const numRows = Math.ceil(Math.sqrt(numPosts));
const numCols = Math.ceil(numPosts / numRows);
for (let i = 0; i < numPosts; i++) {
const row = Math.floor(i / numCols);
const col = i % numCols;
const x = xMin + (xMax - xMin) * (col / (numCols - 1));
const y = yMin + (yMax - yMin) * (row / (numRows - 1));
const z = zMin;
positions.push([x, y, z]);
}
return positions;
};
const positions = calculatePositions(data.posts.length);
</script>
{#each data.posts as post, i}
<MenuItem position={positions[i]} htmlContent={post.meta.title} href={post.path} />
{/each}

View File

@ -6,7 +6,10 @@ import { mdsvex } from 'mdsvex';
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: [vitePreprocess(), mdsvex({ extensions: ['.md'] })],
preprocess: [vitePreprocess(), mdsvex({ extensions: ['.md'], layout: {
poetry: './src/lib/utils/PoetryLayout.svelte'
}})],
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.

View File

@ -4,6 +4,10 @@ export default {
theme: {
extend: {},
},
plugins: [],
plugins: [require("@tailwindcss/typography"), require('daisyui')],
daisyui: {
themes: ["light", "forest"],
darkMode: "forest"
},
}