fix: make some changes
Some checks failed
Deploy to SFTP Server / build (push) Failing after 8m2s

This commit is contained in:
Max Richter
2025-10-21 19:38:33 +02:00
parent 06e5126fe0
commit 5ba54fee6e
29 changed files with 153 additions and 45 deletions

View File

@@ -15,13 +15,15 @@ interface Props {
async function checkImage(src: string) {
try {
if (src.startsWith("/@fs") || src.startsWith("/_astro")) return true;
const res = await fetch(src);
if (res.ok) {
return src;
return true;
}
return undefined;
return false;
} catch (err) {
return undefined;
console.log("Failed to fetch: ",src);
return false;
}
}
@@ -35,8 +37,7 @@ const {
} = Astro.props;
let thumbhash = hash && image.fsPath ? await generateThumbHash(image) : "";
const imageSrc = await checkImage(image.src);
const imageOk = await checkImage(image.src);
let exif = await getExifData(image);
@@ -60,9 +61,9 @@ const sizes = [
---
{
imageSrc ? (
imageOk ? (
<AstroImage
src={imageSrc}
src={image}
alt={alt}
data-thumbhash={thumbhash}
data-exif={JSON.stringify(exif)}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -0,0 +1,91 @@
---
date: 2025-10-21
title: "Silvester-Partys: Eine Retrospektive"
draft: true
cover: ./images/cover.png
description: "Eine Übersicht über unsere jährlichen Silvester-Partys, von Gatsby bis Okkult."
tags: ["event", "webdev", "party", "design"]
icon: 🎉
---
import Image from "@components/Image.astro"
import ImageSlider from "@components/ImageSlider.svelte"
import GatsbyPartyScreenshot from "./images/party-placeholder.jpg"
import GatsbyPartyPhoto from "./images/party-placeholder.jpg"
import HarryPotterPartyScreenshot from "./images/party-placeholder.jpg"
import HarryPotterPartyPhoto from "./images/party-placeholder.jpg"
import VenicePartyScreenshot from "./images/party-placeholder.jpg"
import VenicePartyPhoto from "./images/party-placeholder.jpg"
import FashionPartyScreenshot from "./images/party-placeholder.jpg"
import FashionPartyPhoto from "./images/party-placeholder.jpg"
import ImageGallery from "@components/ImageGallery.svelte"
import videoUrl from "./images/eif-teaser.mp4?url"
<ImageGallery client:load/>
Seit 2019 veranstaltet meine WG eine Silvester Party. Dafür haben wir jedes Jahr ein besonderes Motto ausgewählt welches dann die Kostüme und die Dekoration bestimmt.
Ich hab die Parties immer zum Anlass genommen um mich einmal kreativ auszuleben und habe für jede Party mal einfachere mal komplexere Digital Einladungskarten gestaltet.
### 2019-2020: The Great Gatsby
Unsere erste Party stand unter dem Motto "Great Gatsby".
<ImageSlider title="The Great Gatsby" client:load>
<Image src={GatsbyPartyScreenshot} alt="Screenshot der Gatsby Party Visualisierung" />
<Image src={GatsbyPartyPhoto} alt="Foto der Gatsby Party" />
</ImageSlider>
### 2022-2023: Harry Potter und der sprechende Hut
Für den Jahreswechsel 2022-2023 verwandelte sich unsere Wohnung in die Große Halle von Hogwarts. Das Thema war Harry Potter, und wir hatten einen WebGL-basierten sprechenden Hut, der die Gäste interaktiv den Häusern zuordnete. Zusätzlich gab es ein interaktives Harry-Potter-Quiz auf unserer Webseite. Ein visuelles Display zeigte live den Punktestand der einzelnen Häuser an, wobei ein Admin Punkte in Echtzeit hinzufügen oder abziehen konnte.
Seit 2022 nutzen wir ein Google Sheet als Backend für die Partyorganisation. Jeder Gast gibt bei der Anmeldung eine Wahrscheinlichkeit (in Prozent von 0-100) an, wie wahrscheinlich er oder sie teilnehmen wird. Dies ermöglicht uns eine genauere Vorhersage der Gästezahl.
<ImageSlider title="Harry Potter und der sprechende Hut" client:load>
<Image src={HarryPotterPartyScreenshot} alt="Screenshot der Harry Potter Party Webseite" />
<Image src={HarryPotterPartyPhoto} alt="Foto der Harry Potter Party" />
<Image src={import("./images/hp-1-start.png")} alt="Harry Potter Party Start" />
<Image src={import("images/hp-2-start.png")} alt="Harry Potter Party Start 2" />
<Image src={import("images/hp-3-need-name.png")} alt="Harry Potter Party Need Name" />
<Image src={import("images/hp-4-which-house.png")} alt="Harry Potter Party Which House" />
<Image src={import("images/hp-5-select-house.png")} alt="Harry Potter Party Select House" />
<Image src={import("images/hp-6-attendance-probability.png")} alt="Harry Potter Party Attendance Probability" />
<Image src={import("images/hp-7-invitation-card.png")} alt="Harry Potter Party Invitation Card" />
</ImageSlider>
### 2023-2024: Venezianischer Maskenball
Unsere Silvesterparty 2023-2024 entführte unsere Gäste nach Venedig zu einem opulenten Maskenball. Bei der Registrierung auf unserer Webseite erhielt jeder Gast einen einzigartigen Adelstitel und ein passendes Porträt, die dann in einer digitalen Galerie auf der Webseite ausgestellt wurden.
**Organisation:** Auch hier kam unser Google Sheet Backend zum Einsatz, um die Gästeanmeldungen und Wahrscheinlichkeiten zu verwalten.
<ImageSlider title="Venezianischer Maskenball" client:load>
<Image src={VenicePartyScreenshot} alt="Screenshot der Venezianischer Maskenball Galerie" />
<Image src={VenicePartyPhoto} alt="Foto der Venezianischer Maskenball Party" />
<Image src={import("images/venice-1-start.png")} alt="Venice Party Start" />
<Image src={import("images/venice-2-mask.png")} alt="Venice Party Mask" />
<Image src={import("images/venice-3-invitation-test.png")} alt="Venice Party Invitation Test" />
<Image src={import("images/venice-4-generate-portrait.png")} alt="Venice Party Generate Portrait" />
<Image src={import("images/venice-5-portrait.png")} alt="Venice Party Portrait" />
<Image src={import("images/venice-6-gallery.png")} alt="Venice Party Gallery" />
</ImageSlider>
### 2024-2025: Everything is Fashion
Das Motto für 2024-2025 war "Everything is Fashion". Die Party begann mit einem animierten Intro, das die Gäste auf das modische Thema einstimmte.
<video src={videoUrl} controls alt="Fashion Party Teaser Video" />
<ImageSlider title="Everything is Fashion" client:load>
<Image src={FashionPartyScreenshot} alt="Screenshot des Fashion Party Intros" />
<Image src={FashionPartyPhoto} alt="Foto der Fashion Party" />
<Image src={import("images/eif-anim-1.png")} alt="Fashion Party Animation 1" />
<Image src={import("images/eif-anim-2.png")} alt="Fashion Party Animation 2" />
<Image src={import("images/eif-anim-3.png")} alt="Fashion Party Animation 3" />
<Image src={import("images/eif-navigation.png")} alt="Fashion Party Navigation" />
</ImageSlider>
### 2025-2026: Okkult
Für die kommende Silvesterparty 2025-2026 planen wir ein "Okkult"-Thema, das eine mystische und geheimnisvolle Atmosphäre schaffen wird.

View File

@@ -5,7 +5,7 @@ export type MemoriumFile = {
modTime: string;
mime: string;
size: string;
content: unknown;
content: any;
};
export type MemoriumDir = {

View File

@@ -5,39 +5,42 @@ import * as memorium from "@helpers/memorium";
import { resources as resourceTypes } from "../resources.ts";
import markdownToText from "@helpers/markdownToText";
const { resourceType, resourceName } = Astro.params;
const { resourceType, resourceName } = Astro?.params;
const path = useTranslatedPath(Astro.url);
export async function getStaticPaths(props) {
const paths = await Promise.all(resourceTypes.map(async (resourceType: string) => {
const resources = await memorium.listResource(resourceType.id);
return resources.content.map((res: any) => {
return {
params: {
resourceType: resourceType.id,
resourceName: res.name.replace(/\.md$/,"")
},
};
});
}));
export async function getStaticPaths() {
try {
const paths = await Promise.all(
resourceTypes.map(async (resourceType) => {
const resources = await memorium.listResource(resourceType.id);
return resources?.content.map((res: any) => {
return {
params: {
resourceType: resourceType.id,
resourceName: res.name.replace(/\.md$/, ""),
},
};
});
}),
);
const flat = paths.flat();
console.log(flat.map(p => `/resources/${p.params.resourceType}/${p.params.resourceName}`))
return flat;
return paths.flat().filter(Boolean);
}catch(err){
return []
}
}
const resource = await memorium.listResource(
`/${resourceType}/${resourceName}.md`
`/${resourceType}/${resourceName}.md`,
);
---
<Layout title="Max Richter">
<div class="top-info flex items-center place-content-between m-y-2">
<a class="flex items-center gap-1 opacity-50" href={path("/resources/"+resourceType)}>
<a
class="flex items-center gap-1 opacity-50"
href={path("/resources/" + resourceType)}>
<span class="i-tabler-arrow-left"></span> back
</a>
<div class="date opacity-50">
@@ -55,11 +58,19 @@ const resource = await memorium.listResource(
<p>{resource?.content?.description}</p>
<h2>Ingredients</h2>
<ul>
{resource.content.recipeIngredient.map(ingredient => <li>{markdownToText(ingredient)}</li>)}
{
resource.content.recipeIngredient.map((ingredient) => (
<li>{markdownToText(ingredient)}</li>
))
}
</ul>
<h2>Steps</h2>
<ol>
{resource.content.recipeInstructions.map(ingredient => <li>{markdownToText(ingredient)}</li>)}
{
resource.content.recipeInstructions.map((ingredient) => (
<li>{markdownToText(ingredient)}</li>
))
}
</ol>
</Layout>

View File

@@ -8,12 +8,12 @@ const { resourceType } = Astro.params;
const resources = await memorium.listResource(resourceType);
export async function getStaticPaths(): string[] {
export async function getStaticPaths() {
return resourceTypes.map((type: any) => {
return {
params: {
resourceType: type.id,
resourceName: "Recipe"
resourceName: "Recipe",
},
};
});
@@ -21,17 +21,22 @@ export async function getStaticPaths(): string[] {
---
<Layout title="Max Richter">
{ resources.content.filter(res => res && res?.content && res?.content?.name).map((resource: any) => (
<HeroCard
post={{
collection: "resources/"+resourceType,
id: resource.name.replace(/\.md$/,""),
data: {
title: resource.content.name,
cover: {src:`https://marka.max-richter.dev/${resource.content.image}`}
},
}}
/>
))
{
resources.content
.filter((res) => res && res?.content && res?.content?.name)
.map((resource: any) => (
<HeroCard
post={{
collection: "resources/" + resourceType,
id: resource.name.replace(/\.md$/, ""),
data: {
title: resource.content.name,
cover: {
src: `https://marka.max-richter.dev/${resource.content.image}`,
},
},
}}
/>
))
}
</Layout>