Various improvements
This commit is contained in:
@@ -18,6 +18,10 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- name: Install node
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install node
|
||||||
- name: Checkout your repository using git
|
- name: Checkout your repository using git
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|||||||
1
package-lock.json
generated
1
package-lock.json
generated
@@ -6315,6 +6315,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
|
||||||
"integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
|
"integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.8"
|
"@types/estree": "1.0.8"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,35 +9,49 @@
|
|||||||
posts: CollectionEntry<"blog">[];
|
posts: CollectionEntry<"blog">[];
|
||||||
}
|
}
|
||||||
let { posts }: Props = $props();
|
let { posts }: Props = $props();
|
||||||
|
|
||||||
let allTags = $derived([...new Set(posts.flatMap(item => item.data.tags))]);
|
let allTags = $derived([...new Set(posts.flatMap((item) => item.data.tags))]);
|
||||||
|
|
||||||
let selectedTags = $state<SvelteMap<string, boolean>>();
|
let selectedTags = $state<SvelteMap<string, boolean>>();
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
const tagsQry = url.searchParams.get('tags');
|
const tagsQry = url.searchParams.get("tags");
|
||||||
const defaultTags = tagsQry ? new Set(decodeURIComponent(tagsQry).split('+')) : new Set();
|
const defaultTags = tagsQry
|
||||||
selectedTags = new SvelteMap(allTags.map(tag => [tag, defaultTags.has(tag)]));
|
? new Set(decodeURIComponent(tagsQry).split("+"))
|
||||||
})
|
: new Set();
|
||||||
|
selectedTags = new SvelteMap(
|
||||||
|
allTags.map((tag) => [tag, defaultTags.has(tag)]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!selectedTags) return;
|
if (!selectedTags) return;
|
||||||
const newTagsQry = encodeURIComponent(
|
const newTagsQry = encodeURIComponent(
|
||||||
[...selectedTags.entries()].filter(([_, v]) => v).map(([k, _]) => k).join('+')
|
[...selectedTags.entries()]
|
||||||
|
.filter(([_, v]) => v)
|
||||||
|
.map(([k, _]) => k)
|
||||||
|
.join("+"),
|
||||||
);
|
);
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
if (newTagsQry == url.searchParams.get("tags")) return;
|
if (newTagsQry == url.searchParams.get("tags")) return;
|
||||||
if (newTagsQry == "") url.searchParams.delete("tags");
|
if (newTagsQry == "") url.searchParams.delete("tags");
|
||||||
else url.searchParams.set("tags", newTagsQry);
|
else url.searchParams.set("tags", newTagsQry);
|
||||||
window.history.pushState(null, "", url.toString());
|
window.history.pushState(null, "", url.toString());
|
||||||
})
|
});
|
||||||
|
|
||||||
let isFiltered = $derived(selectedTags && [...selectedTags.values()].includes(true));
|
let isFiltered = $derived(
|
||||||
let filteredPosts = $derived(isFiltered
|
selectedTags && [...selectedTags.values()].includes(true),
|
||||||
? posts.filter(p => !p.data.unlisted && p.data.tags.some(t => selectedTags!.get(t)))
|
);
|
||||||
: posts.filter(p => !p.data.unlisted));
|
let filteredPosts = $derived(
|
||||||
let shownPosts = $derived(filteredPosts.toReversed())
|
isFiltered
|
||||||
|
? posts.filter(
|
||||||
|
(p) =>
|
||||||
|
!p.data.unlisted && p.data.tags.some((t) => selectedTags!.get(t)),
|
||||||
|
)
|
||||||
|
: posts.filter((p) => !p.data.unlisted),
|
||||||
|
);
|
||||||
|
let shownPosts = $derived(filteredPosts.toReversed());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="lg:flex flex-row-reverse justify-between items-start">
|
<div class="lg:flex flex-row-reverse justify-between items-start">
|
||||||
@@ -46,31 +60,37 @@
|
|||||||
{#each allTags as tag}
|
{#each allTags as tag}
|
||||||
<button
|
<button
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
console.log("TRoggled tag")
|
console.log("TRoggled tag");
|
||||||
selectedTags!.set(tag, !selectedTags!.get(tag))
|
selectedTags!.set(tag, !selectedTags!.get(tag));
|
||||||
}}
|
}}
|
||||||
class={[
|
class={[
|
||||||
"m-0.5 rounded-4xl emph-bg px-2 cursor-pointer border-2 border-solid",
|
"m-0.5 rounded-4xl emph-bg px-2 cursor-pointer border-2 border-solid",
|
||||||
selectedTags?.get(tag) && "border-gray-400"
|
selectedTags?.get(tag) && "border-gray-400",
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{tag}
|
{tag}
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<main class="max-w-[650px]">
|
<main class="max-w-650px">
|
||||||
{#each shownPosts as post}
|
{#each shownPosts as post}
|
||||||
<article>
|
<article>
|
||||||
<a href={`/blog/${post.id}`}>
|
<a href={`/blog/${post.id}`}>
|
||||||
<div class="
|
<div
|
||||||
|
class="
|
||||||
lg:grid grid-cols-[auto_min-content_min-content]
|
lg:grid grid-cols-[auto_min-content_min-content]
|
||||||
m-1 p-2 hover:bg-shade
|
m-1 p-2 hover:bg-shade
|
||||||
">
|
"
|
||||||
|
>
|
||||||
<h2 class="font-bold">{post.data.title}</h2>
|
<h2 class="font-bold">{post.data.title}</h2>
|
||||||
<address class="inline-block post-meta col-start-2 md:ml-3 whitespace-nowrap">
|
<address
|
||||||
|
class="inline-block post-meta col-start-2 md:ml-3 whitespace-nowrap"
|
||||||
|
>
|
||||||
{post.data.author}
|
{post.data.author}
|
||||||
</address>
|
</address>
|
||||||
<div class="inline-block post-meta col-start-3 lg:ml-1 whitespace-nowrap">
|
<div
|
||||||
|
class="inline-block post-meta col-start-3 lg:ml-1 whitespace-nowrap"
|
||||||
|
>
|
||||||
<Time datetime={post.data.pubDate} />
|
<Time datetime={post.data.pubDate} />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-3">{post.data.summary}</div>
|
<div class="col-span-3">{post.data.summary}</div>
|
||||||
@@ -79,4 +99,4 @@
|
|||||||
</article>
|
</article>
|
||||||
{/each}
|
{/each}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const { title, author, summary, pubDate, updatedDate, image } = Astro.props;
|
|||||||
<Main title={title} description={summary} image={image}>
|
<Main title={title} description={summary} image={image}>
|
||||||
<article class="m-5 mt-3">
|
<article class="m-5 mt-3">
|
||||||
<header
|
<header
|
||||||
class="lg:grid grid-cols-[auto_auto_minmax(300px,_1fr)] grid-rows-[auto_auto]"
|
class="lg:grid grid-cols-[auto_auto_minmax(300px,1fr)] grid-rows-[auto_auto]"
|
||||||
>
|
>
|
||||||
<h2 class="font-bold row-span-2 text-2xl m-2 mt-3">{title}</h2>
|
<h2 class="font-bold row-span-2 text-2xl m-2 mt-3">{title}</h2>
|
||||||
<address class="post-meta inline-block col-start-2">{author}</address>
|
<address class="post-meta inline-block col-start-2">{author}</address>
|
||||||
@@ -41,7 +41,7 @@ const { title, author, summary, pubDate, updatedDate, image } = Astro.props;
|
|||||||
</p>
|
</p>
|
||||||
<a href="https://ko-fi.com/D1D4AFWZX" target="_blank">
|
<a href="https://ko-fi.com/D1D4AFWZX" target="_blank">
|
||||||
<img
|
<img
|
||||||
class="inline-block border-0 h-[24px]"
|
class="inline-block border-0 h-6"
|
||||||
src="https://storage.ko-fi.com/cdn/kofi1.png?v=6"
|
src="https://storage.ko-fi.com/cdn/kofi1.png?v=6"
|
||||||
alt="Buy Me a Coffee at ko-fi.com"
|
alt="Buy Me a Coffee at ko-fi.com"
|
||||||
/>
|
/>
|
||||||
@@ -50,7 +50,7 @@ const { title, author, summary, pubDate, updatedDate, image } = Astro.props;
|
|||||||
href="https://patreon.com/lbfalvy?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
href="https://patreon.com/lbfalvy?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
class="inline-block border-0 h-[16px] w-[90px] object-cover ml-3"
|
class="inline-block border-0 h-4 w-22.5 object-cover ml-3"
|
||||||
src={patreonWordmark}
|
src={patreonWordmark}
|
||||||
alt="Support me on Patreon"
|
alt="Support me on Patreon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
---
|
---
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import Main from "../layouts/Main.astro";
|
import Main from "../layouts/Main.astro";
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Main
|
<Main title="About Me" description="Lawrence Bethlenfalvy, software engineer">
|
||||||
title="About Me"
|
|
||||||
description="Lawrence Bethlenfalvy, software engineer"
|
|
||||||
>
|
|
||||||
<div class="max-w-[80ch] m-5">
|
<div class="max-w-[80ch] m-5">
|
||||||
<Image src='https://github.com/lbfalvy.png' loading="eager"
|
<Image
|
||||||
alt="My face" width="120" height="120"
|
src="https://github.com/lbfalvy.png"
|
||||||
class="rounded-full h-30 float-right m-3 [shape-outside:_ellipse()]" />
|
loading="eager"
|
||||||
|
alt="My face"
|
||||||
|
width="120"
|
||||||
|
height="120"
|
||||||
|
class="rounded-full h-30 float-right m-3 [shape-outside:ellipse()]"
|
||||||
|
/>
|
||||||
<p>
|
<p>
|
||||||
My name is Lawrence Bethlenfalvy, I make websites and web-based applications primarily
|
My name is Lawrence Bethlenfalvy, I make websites and web-based
|
||||||
with React. I enjoy seeing the fruit of my labour, which is why I do so much
|
applications primarily with React. I enjoy seeing the fruit of my labour,
|
||||||
frontend development even though I'm not exactly an artistic genius, as finest
|
which is why I do so much frontend development even though I'm not exactly
|
||||||
demonstrated by this website.
|
an artistic genius, as finest demonstrated by this website.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
I really like perfectly designed infrastructure, and in an effort to
|
I really like perfectly designed infrastructure, and in an effort to
|
||||||
@@ -24,19 +25,21 @@ import Main from "../layouts/Main.astro";
|
|||||||
DevOps experience.
|
DevOps experience.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
I studied a lot of advanced mathematical topics in high school, and although
|
I studied a lot of advanced mathematical topics in high school, and
|
||||||
I was never a big fan of solving equations for hours on end the approach and
|
although I was never a big fan of solving equations for hours on end the
|
||||||
some of the concepts stuck with me. I like to draw on mathematical techniques
|
approach and some of the concepts stuck with me. I like to draw on
|
||||||
for day-to-day problem solving, but I also view it as a hobby.
|
mathematical techniques for day-to-day problem solving, but I also view it
|
||||||
|
as a hobby.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
More recently I've been hard at work on my small conceptual language, Orchid,
|
More recently I've been hard at work on my small conceptual language,
|
||||||
which, like anything I do, tries to be unopinionated, minimalistic in design,
|
Orchid, which, like anything I do, tries to be unopinionated, minimalistic
|
||||||
and robust in execution.
|
in design, and robust in execution. Designing a programming language is a
|
||||||
Designing a programming language is a constant goat game against the halting problem
|
constant goat game against the halting problem so realising all these
|
||||||
so realising all these principles at the same time is nigh impossible, and incremental
|
principles at the same time is nigh impossible, and incremental progress
|
||||||
progress is fundamentally incompatible with the optimal, holistic approach to
|
is fundamentally incompatible with the optimal, holistic approach to
|
||||||
issues like type checking, but when I have something to report I do it here.
|
issues like type checking, but when I have something to report I do it
|
||||||
|
here.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Main>
|
</Main>
|
||||||
|
|||||||
@@ -15,16 +15,17 @@ const projReady = await Promise.all(
|
|||||||
projReady.map(([proj, Content]) => (
|
projReady.map(([proj, Content]) => (
|
||||||
<a href={proj.data.url}>
|
<a href={proj.data.url}>
|
||||||
<article class="emph-bg m-3 p-2 text-sm rounded-2xl">
|
<article class="emph-bg m-3 p-2 text-sm rounded-2xl">
|
||||||
{proj.data.image && <Image
|
{proj.data.image && (
|
||||||
src={proj.data.image}
|
<Image
|
||||||
alt=""
|
src={proj.data.image}
|
||||||
loading="eager"
|
alt=""
|
||||||
width="100" height="60"
|
loading="eager"
|
||||||
class="object-center aspect-[16/9] w-full"
|
width="100"
|
||||||
/>}
|
height="60"
|
||||||
<h2 class="font-bold text-xl italic">
|
class="object-center aspect-video w-full"
|
||||||
{proj.data.name}
|
/>
|
||||||
</h2>
|
)}
|
||||||
|
<h2 class="font-bold text-xl italic">{proj.data.name}</h2>
|
||||||
<div>
|
<div>
|
||||||
<Content />
|
<Content />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user