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

@ -7,29 +7,29 @@ tags:
title: Autumn Synesthesia
---
The trees branch out their reds and yellows.
Their last battle cry before the frost.
The further north, the more pronounced
As they recall the life they lost.
Shouting in color upon deaf ears,
The trees branch out their reds and yellows.
Their last battle cry before the frost.
The further north, the more pronounced
As they recall the life they lost.
Shouting in color upon deaf ears,
Such beauty produced at a deadly cost.
The reds rage on
With blistering hate.
"Is there no escape
The reds rage on
With blistering hate.
"Is there no escape
From our inevitable fate?"
The orange reminisce
On the seasons before.
"Winter is knocking,
The orange reminisce
On the seasons before.
"Winter is knocking,
But Spring is next door."
The yellows enjoy
The weather while it lasts.
"Best to live in the present
The yellows enjoy
The weather while it lasts.
"Best to live in the present
Than the future or past."
The browns mutter softly
The last lesson to learn.
"From dust I arose,
So to dust I return."
The browns mutter softly
The last lesson to learn.
"From dust I arose,
So to dust I return."

View File

@ -10,22 +10,22 @@ tags:
title: Breakfast Blue Pt. 2
---
Oh, my good friend, I didn't mean to leave.
It wasn't your fault, so no longer grieve!
If I could, I would run back to your side.
Oh, my good friend, I didn't mean to leave.
It wasn't your fault, so no longer grieve!
If I could, I would run back to your side.
But, alas, a lack of legs slows my stride.
It's been over a year since I've last seen
Your serious face and Chartwell's cuisine.
Often I think this is for the better
It's been over a year since I've last seen
Your serious face and Chartwell's cuisine.
Often I think this is for the better
\'Til I shed tears as I read your letter.
Fake tears, that is, for I also lack eyes.
In fact, let me unveil my disguise:
I'm an object lacking animation,
Fake tears, that is, for I also lack eyes.
In fact, let me unveil my disguise:
I'm an object lacking animation,
Given life through personification.
What words can I say to help you move on
And accept the fact that I am now gone?
Know that I too will miss your sweet lovin'
For I'll always be your chocolate muffin.
What words can I say to help you move on
And accept the fact that I am now gone?
Know that I too will miss your sweet lovin'
For I'll always be your chocolate muffin.

View File

@ -1,29 +1,29 @@
---
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
Lost my reason to wake in the morning
Ever since you left me without warning.
We've always seemed to have gotten along
Now I'm wondering if I did you wrong.
Lost my reason to give you thanks and praise.
Each day that passes passes in a daze.
The life I live is a life of decay.
Lost my reason to give you thanks and praise.
Each day that passes passes in a daze.
The life I live is a life of decay.
My happiness happens to never stay.
I would have treated you so much better,
Or perhaps branded a scarlet letter
Across my chest and openly confess
I would have treated you so much better,
Or perhaps branded a scarlet letter
Across my chest and openly confess
That I'm impressed by a snack I love best.
Oh chocolate muffin, why'd you have to leave?
I've learned not to wear my heart on my sleeve.
Instead my love will always be suppressed
As I keep it locked in a chocolate chest.
Oh chocolate muffin, why'd you have to leave?
I've learned not to wear my heart on my sleeve.
Instead my love will always be suppressed
As I keep it locked in a chocolate chest.

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,36 +1,36 @@
---
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
My home houses countless couches.
Klepto-couches with pickpocket pouches
That swiftly swipe your cellular phone
Between the cushions of their comfy unknown.
Then your change jingles and jangles
Until they're untangled
From your Wrangler jeans pocket
Then your change jingles and jangles
Until they're untangled
From your Wrangler jeans pocket
As you wonder where your socks went.
But your socks and shoes
Were swept under your feet
But your socks and shoes
Were swept under your feet
Right under your nose.
So discreet are these deceitful seats
As they watch you search
So discreet are these deceitful seats
As they watch you search
For the keys they stole.
At last your quest
Leads you straight to the crook.
"I should have guessed
At last your quest
Leads you straight to the crook.
"I should have guessed
The klepto-couches had took!"
But still your lesson
Has yet to be learned.
These klepto-couches
Deserve to be burned.
But still your lesson
Has yet to be learned.
These klepto-couches
Deserve to be burned.

View File

@ -1,33 +1,33 @@
---
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,
You're the girl sitting on the park bench.
I'm the guy with a leaf blower.
I've gotta do my job,
So would you kindly please move over?
I'm walking right towards you,
So don't say you didn't notice me.
I'd like to get off work soon,
I'm walking right towards you,
So don't say you didn't notice me.
I'd like to get off work soon,
So I'll give you until the count of three.
One
Two
One
Two
...
Alright, so you've called my bluff.
I'm not really going to do anything.
I just wanted to look real tough,
Alright, so you've called my bluff.
I'm not really going to do anything.
I just wanted to look real tough,
But this little bee ain't got no sting.
I'll just tell my boss that I missed a spot,
And I'll explain my sad situation.
Then we'll both laugh at the thought
Of me writing poetry about my frustration.
I'll just tell my boss that I missed a spot,
And I'll explain my sad situation.
Then we'll both laugh at the thought
Of me writing poetry about my frustration.

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,35 +1,35 @@
---
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,
Then sat down, Indian style, to begin the raid.
The roots, like little fingers, held on to dear life
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,
Then sat down, Indian style, to begin the raid.
The roots, like little fingers, held on to dear life
As I cut through their homes with an oddly-shaped knife.
To justify these cruel killings
I thought of what they've done:
Suffocated the superior plants
To justify these cruel killings
I thought of what they've done:
Suffocated the superior plants
And blocked out the lovely sun.
But what makes one plant superior and the other inferior?
Just the fact that the other has a beautiful exterior?
They are simply trying their best to make a living.
But what makes one plant superior and the other inferior?
Just the fact that the other has a beautiful exterior?
They are simply trying their best to make a living.
We must see past our differences and be more forgiving.
But these thoughts lead down to a dangerous road;
But these thoughts lead down to a dangerous road;
Let's not personify each seed we've sowed.
The sun now rises and heats the ground.
The ice embedded within melts all around,
And now a nice wet spot on my pants is found
Which leaves me thinking of thoughts more profound:
"I really hope no one's looking at me right now."
The sun now rises and heats the ground.
The ice embedded within melts all around,
And now a nice wet spot on my pants is found
Which leaves me thinking of thoughts more profound:
"I really hope no one's looking at me right now."

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,33 +1,33 @@
---
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
Am I the clothes on my back
And the hair on my head?
Am I the people I'm with
And the words I've said?
Am I the field I study
And the school I attend?
Am I the programs I write
Am I the field I study
And the school I attend?
Am I the programs I write
And the poems I've penned?
Am I the music I enjoy
And the guitar I play?
Am I the grade on my test
Am I the music I enjoy
And the guitar I play?
Am I the grade on my test
And my ten page essay?
Am I the habits I've formed
And the phrases I repeat?
Am I the fake smile given
Am I the habits I've formed
And the phrases I repeat?
Am I the fake smile given
To every person I meet?
Am I the religion I follow
And the politician I elect?
Am I every action I carry out
And every thought I reflect?
Am I the religion I follow
And the politician I elect?
Am I every action I carry out
And every thought I reflect?

View File

@ -1,7 +1,52 @@
<script lang="ts">
import App from '$lib/components/scenes/app/App.svelte';
<script>
import '../../app.css';
</script>
<App>
<slot />
</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 />
</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>
<Content />
</div>
<div class="container mx-auto flex flex-col items-center py-10">
<div class="prose">
<h1 class="py-6">{title}</h1>
</div>
</DomPortal>
<div class="prose">
<Content />
</div>
<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"
},
}