big style update
This commit is contained in:
@@ -17,9 +17,10 @@ const tooltipStyles = css`
|
||||
opacity: 0;
|
||||
display: block;
|
||||
pointer-events: none;
|
||||
background-color: black;
|
||||
border: white solid 1px;
|
||||
color: white;
|
||||
background-color: var(--dj-bgpalette1);
|
||||
box-shadow: 0 0 12px 1px rgb(10 12 15 / 70%);
|
||||
border: var(--dj-palette3) solid 1px;
|
||||
color: var(--dj-palette3);
|
||||
padding: 10px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
14
app/api.ts
14
app/api.ts
@@ -1,4 +1,15 @@
|
||||
export type DjAPIEndpoint = "/rp-articles";
|
||||
export type DjAPIEndpoint =
|
||||
| "/rp-articles"
|
||||
| "/blog-entries"
|
||||
;
|
||||
|
||||
type BlogEntry = {
|
||||
title: string,
|
||||
slug: string;
|
||||
createdAt: string,
|
||||
updatedAt: string,
|
||||
tags?: string[],
|
||||
};
|
||||
|
||||
type RPArticle = {
|
||||
title: string,
|
||||
@@ -11,6 +22,7 @@ type RPArticle = {
|
||||
|
||||
export interface DjAPIResultMap extends Record<DjAPIEndpoint, unknown> {
|
||||
"/rp-articles": RPArticle[];
|
||||
"/blog-entries": BlogEntry[];
|
||||
}
|
||||
|
||||
export type DjAPIResult = DjAPIResultMap[DjAPIEndpoint];
|
||||
|
||||
98
app/blog/DjBlogEntry.tsx
Normal file
98
app/blog/DjBlogEntry.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { computed, createTextVNode, defineComponent, h, type VNode } from "vue";
|
||||
import useHead from "@/useHead.ts";
|
||||
import useAsyncState from "@/useAsyncState.ts";
|
||||
import getDjAPI from "@/api.ts";
|
||||
import getDomParser from "@/domParse.ts";
|
||||
import { addCSS, css } from "../util.ts";
|
||||
|
||||
const style = css`
|
||||
.byline {
|
||||
font-style: italic;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--dj-palette1);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
`;
|
||||
|
||||
export default defineComponent({
|
||||
name: "DjBlogEntry",
|
||||
props: {
|
||||
slug: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
async setup(props) {
|
||||
addCSS('DjBlogEntry', style);
|
||||
|
||||
const parseDom = getDomParser();
|
||||
|
||||
const blogpostContent = useAsyncState(
|
||||
`dj-blog-article-content-${ props.slug }`,
|
||||
async ({ hostUrl }) => {
|
||||
const blogpostResponse = await fetch(`${hostUrl}/blog/content/${ props.slug }.html`);
|
||||
const result = await blogpostResponse.text();
|
||||
return result;
|
||||
},
|
||||
);
|
||||
|
||||
const blogpostsMetadata = useAsyncState('article-metadata', ({ hostUrl }) => getDjAPI(hostUrl, '/blog-entries'));
|
||||
|
||||
const blogpostMetadata = computed(() => blogpostsMetadata.result.value?.find(_ => _.slug === props.slug));
|
||||
|
||||
useHead({
|
||||
title: () => blogpostMetadata.value?.title ?? '',
|
||||
metatags: () => blogpostMetadata.value ? [
|
||||
{ name: 'title', content: blogpostMetadata.value.title },
|
||||
{ name: 'author', content: 'Daniel Ledda' },
|
||||
] : [],
|
||||
});
|
||||
|
||||
function transformPostNode(node: Node): VNode | string {
|
||||
if (node.nodeType === node.ELEMENT_NODE) {
|
||||
const el = node as Element;
|
||||
const attrs: Record<string, string> = {};
|
||||
const children = [...node.childNodes].map((_) => transformPostNode(_));
|
||||
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
const item = el.attributes.item(i);
|
||||
if (item) {
|
||||
attrs[item.name] = item.value;
|
||||
}
|
||||
}
|
||||
|
||||
return h((node as Element).tagName, attrs, children);
|
||||
} else {
|
||||
return createTextVNode(node.textContent ?? "");
|
||||
}
|
||||
}
|
||||
|
||||
function PostContentTransformed() {
|
||||
if (blogpostContent.result.value) {
|
||||
const dom = parseDom(blogpostContent.result.value);
|
||||
return h("div", {}, [...dom.children].map((_) => transformPostNode(_)));
|
||||
}
|
||||
return <div>Blog post loading...</div>;
|
||||
}
|
||||
|
||||
await Promise.allSettled([ blogpostContent.done, blogpostsMetadata.done ]);
|
||||
|
||||
return () => <>
|
||||
{ blogpostMetadata.value
|
||||
? <>
|
||||
<h1>{ blogpostMetadata.value.title }</h1>
|
||||
<div class="byline">by Daniel Ledda, first published { new Date(blogpostMetadata.value.createdAt).toLocaleDateString() }</div>
|
||||
<PostContentTransformed />
|
||||
</>
|
||||
: "Sorry, this blog post doesn't seem to exist."
|
||||
}
|
||||
</>;
|
||||
}
|
||||
});
|
||||
|
||||
42
app/blog/DjBlogMain.tsx
Normal file
42
app/blog/DjBlogMain.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import { defineComponent } from "vue";
|
||||
import useAsyncState from "@/useAsyncState.ts";
|
||||
import getDjAPI from "@/api.ts";
|
||||
import { RouterLink } from "vue-router";
|
||||
import { addCSS, css } from "@/util.ts";
|
||||
|
||||
const style = css`
|
||||
.entry {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
export default defineComponent({
|
||||
name: "DjBlogMain",
|
||||
async setup() {
|
||||
addCSS('DjBlogMain', style);
|
||||
|
||||
const blogEntries = useAsyncState('blog-entries-meta', ({ hostUrl }) => getDjAPI(hostUrl, "/blog-entries"));
|
||||
|
||||
await blogEntries.done;
|
||||
|
||||
return () => <>
|
||||
<main>
|
||||
<h2>Entries</h2>
|
||||
<ul>
|
||||
{blogEntries.result.value?.map(_ => (
|
||||
<li key={_.slug}>
|
||||
<div class="entry">
|
||||
<RouterLink to={{ name: 'DjBlogEntry', params: { slug: _.slug }}}>{ _.title }</RouterLink>
|
||||
<span>-</span>
|
||||
<time datetime={ _.createdAt }>{ new Date(_.createdAt).toLocaleDateString() }</time>
|
||||
</div>
|
||||
</li>
|
||||
)) ?? <li>Blog posts loading...</li>}
|
||||
</ul>
|
||||
</main>
|
||||
</>;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
import { defineComponent, ref } from "vue";
|
||||
import useHead from "@/useHead.ts";
|
||||
import { defineComponent, ref, type VNode, Suspense } from "vue";
|
||||
import { type RouteRecordRaw, RouterLink, RouterView } from "vue-router";
|
||||
import DjTooltip, { setupTooltip } from "@/DjTooltip.tsx";
|
||||
import DjBlogEntry from "@/blog/DjBlogEntry.tsx";
|
||||
import DjBlogMain from "@/blog/DjBlogMain.tsx";
|
||||
import DjEmail from "@/DjEmail.tsx";
|
||||
import { addCSS, css } from "@/util.ts";
|
||||
import useHead from "@/useHead.ts";
|
||||
|
||||
export const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: "/",
|
||||
name: "DjBlogMain",
|
||||
component: DjBlogMain,
|
||||
},
|
||||
{
|
||||
path: "/post/:slug",
|
||||
name: "DjBlogEntry",
|
||||
component: DjBlogEntry,
|
||||
props: ({ params }) => {
|
||||
if ("slug" in params) {
|
||||
return { slug: params.slug };
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const styles = css`
|
||||
.supercontainer {
|
||||
@@ -9,31 +33,85 @@ const styles = css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
footer {
|
||||
color: gray;
|
||||
font-style: italic;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--dj-palette3);
|
||||
text-decoration: solid line;
|
||||
|
||||
&:visited {
|
||||
color: var(--dj-visited);
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
font-size: 40px;
|
||||
margin-bottom: 40px;
|
||||
text-decoration: none;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
|
||||
a, a:visited {
|
||||
color: var(--dj-palette3);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default defineComponent({
|
||||
name: "app-root",
|
||||
name: "DjBlogRoot",
|
||||
setup() {
|
||||
addCSS('dj-blog-root', styles);
|
||||
const carrier = ref<HTMLDivElement | null>(null);
|
||||
setupTooltip({ carrier });
|
||||
|
||||
addCSS('dj-blog-root', styles);
|
||||
useHead({ title: "djblog Home" });
|
||||
|
||||
const tooltipCarrier = ref<HTMLDivElement | null>(null);
|
||||
setupTooltip({ carrier: tooltipCarrier });
|
||||
|
||||
return () => <>
|
||||
<div ref={tooltipCarrier} class="tooltip-carrier" />
|
||||
return () => (
|
||||
<>
|
||||
<div ref={carrier} class="tooltip-carrier" />
|
||||
<div class="supercontainer">
|
||||
<div class="container">
|
||||
<DjTooltip tooltip="come in and find out...">
|
||||
<h1>dj blog</h1>
|
||||
<nav>
|
||||
<DjTooltip tooltip="flog, clog, bog, frog, cog, log, grog, fog, snog...">
|
||||
<RouterLink to={{ name: 'DjBlogMain' }}>
|
||||
dj blog
|
||||
</RouterLink>
|
||||
</DjTooltip>
|
||||
</nav>
|
||||
<RouterView>
|
||||
{{
|
||||
default: ({ Component }: { Component: VNode }) => (Component &&
|
||||
(
|
||||
<Suspense>
|
||||
{{
|
||||
default: () => Component,
|
||||
fallback: () => <div>Page loading...</div>,
|
||||
}}
|
||||
</Suspense>
|
||||
)),
|
||||
}}
|
||||
</RouterView>
|
||||
<footer>
|
||||
<div class="bottom">
|
||||
<div>
|
||||
<a href="/">djledda.net</a> {new Date().getFullYear()} - <DjEmail>{() => "Contact"}</DjEmail>
|
||||
</div>
|
||||
</div>
|
||||
</>;
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { createSSRApp } from "vue";
|
||||
import DjBlogRoot from "@/blog//DjBlogRoot.tsx";
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import DjBlogRoot, { routes } from "@/blog//DjBlogRoot.tsx";
|
||||
import { cssRegistry } from "@/util.ts";
|
||||
|
||||
createSSRApp(DjBlogRoot)
|
||||
.provide(cssRegistry, new Set())
|
||||
.use(createRouter({
|
||||
routes,
|
||||
history: createWebHistory("/blog"),
|
||||
}))
|
||||
.mount("#app-root");
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { createSSRApp } from "vue";
|
||||
import DjBlogRoot from "@/blog/DjBlogRoot.tsx";
|
||||
import DjBlogRoot, { routes } from "@/blog/DjBlogRoot.tsx";
|
||||
import { createMemoryHistory, createRouter } from "vue-router";
|
||||
|
||||
export default function createApp() {
|
||||
const app = createSSRApp(DjBlogRoot);
|
||||
return { app, router: null };
|
||||
const router = createRouter({
|
||||
routes: routes,
|
||||
history: createMemoryHistory("/blog"),
|
||||
});
|
||||
const app = createSSRApp(DjBlogRoot).use(router);
|
||||
return { app, router };
|
||||
}
|
||||
|
||||
8
app/domParse.ts
Normal file
8
app/domParse.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { inject } from "vue";
|
||||
|
||||
export default function getDomParser() {
|
||||
return inject(
|
||||
"dom-parse",
|
||||
(innerHTML: string) => Object.assign(document.createElement("div"), { innerHTML }),
|
||||
);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ export default defineComponent({
|
||||
return <div>Artikel lädt...</div>;
|
||||
}
|
||||
|
||||
await Promise.all([ articleContent.done, articlesMetadata.done ]);
|
||||
await Promise.allSettled([ articleContent.done, articlesMetadata.done ]);
|
||||
|
||||
return () => (
|
||||
<div class="ge-article">
|
||||
|
||||
@@ -1,63 +1,88 @@
|
||||
import { defineComponent, computed, ref, type Ref } from "vue";
|
||||
import { defineComponent, ref, type Ref } from "vue";
|
||||
import useHead from "@/useHead.ts";
|
||||
import DjTooltip, { setupTooltip } from "@/DjTooltip.tsx";
|
||||
import DjEmail from "@/DjEmail.tsx";
|
||||
import { addCSS, css } from "@/util.ts";
|
||||
|
||||
const styles = css`
|
||||
:root {
|
||||
--subject-spacing: 40px;
|
||||
}
|
||||
|
||||
.resource {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title_name {
|
||||
font-size: 48px;
|
||||
color: var(--dj-palette3);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.supercontainer {
|
||||
padding-top: 3em;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 50em;
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.main {
|
||||
width: 35em;
|
||||
padding: 20px;
|
||||
}
|
||||
:root {
|
||||
--subject-spacing: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.title_name {
|
||||
font-size: 30px;
|
||||
}
|
||||
.main {
|
||||
width: 20em;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--dj-palette3);
|
||||
|
||||
&:visited {
|
||||
color: var(--dj-visited);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default defineComponent({
|
||||
name: "app-root",
|
||||
name: "DjHomeRoot",
|
||||
setup() {
|
||||
useHead({ title: "DJ Ledda's Homepage" });
|
||||
addCSS('DjHomeRoot', styles);
|
||||
useHead({ title: "djledda" });
|
||||
|
||||
const tooltipCarrier = ref<HTMLDivElement | null>(null);
|
||||
setupTooltip({ carrier: tooltipCarrier });
|
||||
|
||||
const dude1Spinning = ref(false);
|
||||
const dude2Spinning = ref(false);
|
||||
|
||||
function toggleDude(event: MouseEvent, dudeRef: Ref<boolean>) {
|
||||
const dude = event.target as HTMLImageElement;
|
||||
if (dudeRef.value) {
|
||||
dude.addEventListener("animationiteration", function listener() {
|
||||
dudeRef.value = false;
|
||||
dude.removeEventListener("animationiteration", listener as EventListenerOrEventListenerObject);
|
||||
});
|
||||
} else {
|
||||
dudeRef.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
const shaking = computed(() => dude1Spinning.value || dude2Spinning.value);
|
||||
|
||||
return () => <>
|
||||
<div ref={tooltipCarrier} class="tooltip-carrier" />
|
||||
<div class="supercontainer">
|
||||
<div class={{ shakeable: true, shakeMe: shaking.value }}>
|
||||
<div class="title_name">
|
||||
<DjTooltip tooltip="I wonder what he's listening to?">
|
||||
<img src="/home/img/dj.gif" alt="dj legt krasse Mucke auf"
|
||||
class={{ dude: true, spinMe: dude1Spinning.value }}
|
||||
onClick={ (e) => toggleDude(e, dude1Spinning)} />
|
||||
</DjTooltip>
|
||||
<div>
|
||||
<div class="dj-title title_name">
|
||||
<DjTooltip tooltip="Easily the coolest guy out there.">
|
||||
<span>DJ Ledda</span>
|
||||
</DjTooltip>
|
||||
<DjTooltip tooltip="I once heard this guy played at revs.">
|
||||
<img src="/home/img/dj.gif" alt="dj laying down some sick beats"
|
||||
class={{ dude: true, spinMe: dude2Spinning.value }}
|
||||
onClick={ (e) => toggleDude(e, dude2Spinning) } />
|
||||
<span>dj ledda</span>
|
||||
</DjTooltip>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="subject">
|
||||
<div class="resourcelist">
|
||||
<a href="https://drum-slayer.com">
|
||||
<DjTooltip class="resource" tooltip="Small app for designing multitrack looped rhythms with local save and multiple files. Originally built using just vanilla TypeScript and CSS, now with Vue.">
|
||||
Drum Slayer
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="/somaesque/index.html">
|
||||
<DjTooltip class="resource" tooltip="Puzzle solver app for puzzle cubes resembling the original Soma Cube puzzle. Save and edit your own puzzles! Built with Svelte, THREE.js and AssemblyScript.">
|
||||
Somaesque
|
||||
<a href="/blog">
|
||||
<DjTooltip class="resource" tooltip="My musings, my losings, my winnings, my thoughts">
|
||||
Blog
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="/generative-energy">
|
||||
@@ -65,6 +90,11 @@ export default defineComponent({
|
||||
Generative Energy - Ray Peat Resources
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="https://git.djledda.net/Ledda">
|
||||
<DjTooltip class="resource" tooltip="Check out what I'm coding!">
|
||||
My git projects
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="/home/muenchen-auf-englisch.html">
|
||||
<DjTooltip class="resource" tooltip="
|
||||
Authentic historically accurate translations of all of Munich's S-Bahn and U-Bahn
|
||||
@@ -74,6 +104,16 @@ export default defineComponent({
|
||||
München auf Englisch - Munich in English
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="https://drum-slayer.com">
|
||||
<DjTooltip class="resource" tooltip="Small app for designing multitrack looped rhythms with local save and multiple files. Originally built using just vanilla TypeScript and CSS, now with Vue.">
|
||||
Drum Slayer
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="/somaesque/index.html">
|
||||
<DjTooltip class="resource" tooltip="Puzzle solver app for puzzle cubes resembling the original Soma Cube puzzle. Save and edit your own puzzles! Built with Svelte, THREE.js and AssemblyScript.">
|
||||
Somaesque
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="/kadi/">
|
||||
<DjTooltip class="resource" tooltip="Make an account and start saving paper and tracking your Yatzy stats with your
|
||||
friends! Make your own rulesets, and more. Built with React, express.js, and
|
||||
@@ -81,11 +121,6 @@ export default defineComponent({
|
||||
K A D I: Online Yatzy Scoresheets
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<a href="https://git.djledda.net/Ledda">
|
||||
<DjTooltip class="resource" tooltip="Check out what I'm coding!">
|
||||
My git projects
|
||||
</DjTooltip>
|
||||
</a>
|
||||
<DjEmail>
|
||||
<DjTooltip class="resource" tooltip="You'll see my address when you click here.">
|
||||
Click here to get in touch
|
||||
@@ -94,7 +129,6 @@ export default defineComponent({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tooltipCarrier"></div>
|
||||
</div>
|
||||
</div>
|
||||
</>;
|
||||
|
||||
39
main.ts
39
main.ts
@@ -100,6 +100,45 @@ async function getAPIResponse(apiReq: Request): Promise<Response> {
|
||||
}
|
||||
result.sort((a, b) => a.titleDe.localeCompare(b.titleDe));
|
||||
jsonResponse = result;
|
||||
} else if (apiPath === "/blog-entries") {
|
||||
const paths: string[] = [];
|
||||
const contentDir = './public/blog/content/';
|
||||
for await (const dirEnt of Deno.readDir(contentDir)) {
|
||||
if (dirEnt.isFile && dirEnt.name.endsWith('.html')) {
|
||||
paths.push(`${contentDir}${dirEnt.name}`);
|
||||
}
|
||||
}
|
||||
const result: DjAPIResultMap['/blog-entries'] = [];
|
||||
for (const filePath of paths) {
|
||||
const [ stat, content ] = await Promise.all([Deno.stat(filePath), Deno.readTextFile(filePath)]);
|
||||
const dom = parser.parseFromString(content, 'text/html');
|
||||
const metadata = {
|
||||
slug: '',
|
||||
tags: [] as string[],
|
||||
title: '',
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
};
|
||||
const metaTags = dom.querySelectorAll('meta') as unknown as NodeListOf<HTMLMetaElement>;
|
||||
for (const metaTag of metaTags) {
|
||||
const name = metaTag.attributes.getNamedItem('name')?.value ?? '';
|
||||
const content = metaTag.attributes.getNamedItem('content')?.value ?? '';
|
||||
if (name === 'title') {
|
||||
metadata.title = content;
|
||||
} else if (name === 'tags') {
|
||||
metadata.tags = content ? content.split(",") : [];
|
||||
} else if (name === 'slug') {
|
||||
metadata.slug = content;
|
||||
} else if (name === 'updatedAt') {
|
||||
metadata.createdAt = content;
|
||||
} else if (name === 'createdAt') {
|
||||
metadata.updatedAt = content;
|
||||
}
|
||||
}
|
||||
result.push(metadata);
|
||||
}
|
||||
result.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
||||
jsonResponse = result;
|
||||
}
|
||||
|
||||
if (!jsonResponse) {
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<title>Poof, and it's gone</title>
|
||||
|
||||
<article>
|
||||
<p>
|
||||
Since reading Ray Peat's work and drastically improving my wellbeing, something that had been declining for years, I've
|
||||
been thinking more and more often about the phenomenon of learned helpless and its relevance to my life. Sometimes,
|
||||
looking back to past times is useful to help reorient yourself in the present and aim towards a more desirable future.
|
||||
Sometimes, a new perspective or experience might instantly obliterate previous behaviour without any sort of concerted
|
||||
mental or physical grunt to eradicate it.
|
||||
</p>
|
||||
<p>
|
||||
On the flipside, I have sometimes hopelessly tried to forcefully change my behaviour, employing all the en vogue self-help tricks
|
||||
to form long-term habits, only to practically immediately lose them not long afterwards. These kinds of experiences remind me of those
|
||||
hypnosis advertisements that claim to have you give up smoking after just a few sessions; sometimes it's even after just one visit. There's no short
|
||||
supply of stories of miracle cures or sudden, permanent breaks of addiction. Cold-turkey clean cuts that seem to arise with no obvious
|
||||
effort on the part of the addict, no signs of worn willpower.
|
||||
</p>
|
||||
<p>
|
||||
When I was sixteen I spent six weeks abroad in a small town called Marburg in Hesse, Germany. Those six weeks were spent
|
||||
living with a new family along with my exchange student, who had lived six weeks with me and my family just prior to my
|
||||
arrival in Germany. Six weeks of school, new acquaintances, a new language (albeit one I had been "studying" in the
|
||||
Australian school system) and unfamiliar cultural quirks.
|
||||
</p>
|
||||
<p>
|
||||
It was a barrage of stimulation, I came home every day from school and would collapse, totally exhausted, onto my
|
||||
exchange student's bed, which was mine for the duration of the stay. It's not like I was actually expected to
|
||||
<i>learn</i> anything or do any homework whilst I was at school here—I was basically on holidays and could really
|
||||
have just treated it as such. Plenty of my own friends who had taken a similar trip certainly did. I'm not manyt of them
|
||||
learnt or used much German beyond <i>Wo ist McDonalds?</i>. But I had been gradually becoming more fascinated with the
|
||||
structure of German before arriving. Once there, especially at that age I presume, the Deutsch on the blackboard in
|
||||
biology class looked more like a sophisticated puzzle game than a complete drag of a memorisation task. Each day was a
|
||||
new game of deductive guesswork, and better still, I got to play with new ideas about how the language works every day
|
||||
in the schoolyard with new friends I was making. New ways to describe how things are situated and move in relation to
|
||||
one another, mysterious new prefixes and other linguistic building blocks, and the insane backwards word order of German
|
||||
provided unlimited entertainment to see if I was up to the challenge.
|
||||
</p>
|
||||
<p>
|
||||
On top of this, I was in the grade just above mine back home in Australia. Whilst that really shouldn't have made much
|
||||
difference, the amount of responsibility and independece these kids were allowed to exercise at sixteen or seventeen was
|
||||
nothing short of amazing to my adolescent self. I had never seen anything like it. Some of my classmates would stand out
|
||||
the front of school during lunchtime and smoke a couple of cigarettes with their own teachers, something that still to
|
||||
this day I find kind of insane. It certainly would never have been acceptable back at home. Starting in the senior
|
||||
school, you were allowed to just leave and go home if you didn't have class on, as long as you were back in time. And we
|
||||
did. School uniforms simply weren't part of the culture either. For everyone else perhaps stressful and another target
|
||||
of the cruel status games of teenagerhood, but for me it was like every day was casual dress day back home. To top it
|
||||
all off, the legal drinking age in Germany is sixteen, at least for wine, beer, and other weaker drinks.
|
||||
</p>
|
||||
<p>
|
||||
These classmates of mine were running their own meetings headed by the <i>Klassensprecher</i>, the class representatives, and they actually seemed cool, like people I would like to hang out and befriend. They were
|
||||
|
||||
</article>
|
||||
105
public/blog/content/poof-and-its-gone.html
Normal file
105
public/blog/content/poof-and-its-gone.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<meta name="title" content="Poof, and it's gone">
|
||||
<meta name="slug" content="poof-and-its-gone">
|
||||
<meta name="createdAt" content="2025-12-20T17:54:05.000Z">
|
||||
<meta name="updatedAt" content="2025-12-20T17:54:05.000Z">
|
||||
<meta name="tags" content="">
|
||||
|
||||
<article>
|
||||
<p>
|
||||
Since reading Ray Peat's work and drastically improving my wellbeing—something that had been declining for years—I've
|
||||
been thinking more and more often about the phenomenon of learned helplessness and its relevance in my own life. Sometimes,
|
||||
looking back to past times can be useful to help reorient yourself in the present. In doing so you're better equipped to
|
||||
aim towards a more desirable future. Sometimes, a new perspective or experience might instantly obliterate previous
|
||||
behaviour without any sort of concerted mental or physical grunt to eradicate it.
|
||||
</p>
|
||||
<p>
|
||||
On the flipside, I have sometimes hopelessly tried to forcefully change my behaviour, employing all the en vogue
|
||||
self-help tricks to form long-term habits, only to lose them just as quickly as they formed in the months that would
|
||||
follow. These kinds of experiences remind me of those hypnosis advertisements that claim to have you give up smoking
|
||||
after just a few sessions; sometimes it's even after just one visit. There's no short supply <i>miracle cure</i> stories
|
||||
or reports of sudden, permanent breaks in addiction. Cold-turkey clean cuts that seem to arise with no obvious effort on
|
||||
the part of the addict, no signs of worn willpower.
|
||||
</p>
|
||||
<p>
|
||||
When I was sixteen I spent six weeks abroad in a small town called Marburg in Hesse, Germany. Those six weeks were spent
|
||||
living with a new family along with my exchange student, Arne, who had been staying with my family for the six weeks
|
||||
prior. Those were six exciting weeks of school, new acquaintances, a new language (albeit one I had been "studying" in
|
||||
the Australian school system) and unfamiliar cultural quirks.
|
||||
</p>
|
||||
<p>
|
||||
It was a barrage of stimulation, I came home every day from school and would collapse, totally exhausted, onto my
|
||||
exchange student's bed, which was graciously mine to use for the duration of the stay. It's not like I was actually expected to
|
||||
<i>learn</i> anything or do any homework whilst I was at school here—I was basically on holidays and could really
|
||||
have just treated it as such. Plenty of my own classmates who had been on a very similar trip certainly did. I'm not sure many of them
|
||||
learnt or used much German beyond <i>"Wo ist McDonalds?"</i> I, on the other hand, thanks to a romantic summer fling,
|
||||
had been gradually becoming more fascinated with the structure of German before arriving. Once there, especially at that
|
||||
age I presume, the Deutsch on the blackboard looked more like a sophisticated puzzle game than a
|
||||
complete drag of a memorisation task. Each day was a new game of deductive guesswork, and better still, I got to play
|
||||
with new ideas about how the language works every day in the schoolyard with the new friends I was making. New ways to
|
||||
describe how things are situated in space, adverbs for how they move in relation to one another, mysterious new prefixes and other quaint linguistic
|
||||
quirks, like the insane backwards word order of German, provided unlimited entertainment to see if I was up to
|
||||
the challenge. I practically spent all my time in class ogling the immaculate chalk handwriting of the various teachers,
|
||||
trying to work out what on Earth was going on. For some strange reason, it was a kind of bliss.
|
||||
</p>
|
||||
<p>
|
||||
On top of this, I was in the grade just above mine back home in Australia. Whilst that really shouldn't have made much
|
||||
difference, the amount of responsibility and independence these kids were allowed to exercise at sixteen or seventeen was
|
||||
nothing short of amazing to my adolescent self. I had never seen anything like it. Some of my classmates would stand out
|
||||
the front of school during lunchtime and smoke a couple of cigarettes with their own teachers, something I find kind of insane
|
||||
still to this day; it certainly would never have been acceptable back at home. Starting in the senior
|
||||
school, you were allowed to just leave and go home if you didn't have anywhere to be, so long as you were back in time
|
||||
for class. And we did. School uniforms simply weren't part of the culture either. For everyone else this perhaps just meant stressful decision making,
|
||||
another way to play the oft cruel status games of teenagerhood, but for me it was like every day was casual dress day back
|
||||
home. To top it all off, the legal drinking age in Germany is sixteen, at least for wine, beer, and other weaker drinks.
|
||||
</p>
|
||||
<p>
|
||||
These classmates of mine were running their own meetings headed by the <i>Klassensprecher</i>, the class
|
||||
representatives, and much unlike similar candidates back home, they actually seemed cool, they seemed like people I
|
||||
might like to hang out with and befriend. Alongside making decision making about general school organisation, they would
|
||||
organise class bus trips, we saw a local band comprised of kids from the local schools, and for the first time I drank
|
||||
alcohol with everybody, just hanging out and left to our own devices. It was a sense of freedom and self-responsibility
|
||||
that wasn't afforded to me by the school system back home. Increasingly Australia, and especially Victoria, from which I
|
||||
hail, is branded as a "nanny state", and my experiences in Germany reinforce that.
|
||||
</p>
|
||||
<p>
|
||||
I really felt like I was in the midst of some sort of Hollywood production, an atmosphere that didn't quite seem tangible in
|
||||
Australia. The intersection in the Venn diagram of taking on of responsibility and having free reign was
|
||||
vanishingly small amongst teenagers. Either you wagged class and/or did drugs, or obediently followed the rules. As the
|
||||
years went by, the fine line between the two seemed to vanish further and further, at least from where I was standing.
|
||||
</p>
|
||||
<p>
|
||||
Back in Australia, a routine had begun to solidify itself leading up to this trip. It was a routine of coming home,
|
||||
maybe doing homework, and then browsing Reddit and playing hours of Team Fortress 2. I had racked up an impressive 2000
|
||||
hours in-game. It seemed fairly inconsequential to me, and my high school friends, unlike primary school, were mostly
|
||||
fragmented, and so on weeknights I didn't find myself hanging out with many people regularly. I did try to get Team Fortress
|
||||
working on the old computer my host family had in Germany, just for fun, but to no avail. However, even whilst
|
||||
attempting to get it set up, something about it began to seem like an entirely futile endeavour.
|
||||
</p>
|
||||
<p>
|
||||
When I arrived back in Australia, it was as if a switch had been flipped. I all but stopped playing Team
|
||||
Fortress, a regular staple of my free time. Practically overnight it seemed to have turned from being an incredibly
|
||||
seductive way to pass the time to being a colossal <i>waste</i> of it. I just stopped playing cold turkey, and as far as I could tell, no
|
||||
effort went in to the dissolution of that habit whatsoever.
|
||||
</p>
|
||||
<p>
|
||||
I'm not exactly sure what facet of my overseas trip pushed me to change my behaviour so effortlessly, but I think it was
|
||||
the culmination of the incredibly enriched environment. As I have looked back on those times over the past few years, especially since
|
||||
discovering Ray, I can't help but think that I found myself in a "rat park" experiment during that time. Or I perhaps I was one of the rats
|
||||
looking on, watching as others were freed from certain death by drowning. My habits in Australia suddenly seemed dull and useless, like I was stuck in
|
||||
what the Germans call a <i>goldener Käfig</i> or <i>gilded cage</i>; basically trapped in a environment forged by
|
||||
my own riches and good intentions. Participating in the foreign exchange program widened my horizons. I could see that, indeed, what
|
||||
I was missing out on <i>was</i> possible, and I had the power to change my lifestyle.
|
||||
</p>
|
||||
<p>
|
||||
It would be nice if I could now say that I've since enjoyed a deeply enriched life and everything has been hunky dory, but alas
|
||||
I wouldn't be a fan of Ray's if I didn't encounter a struggle or two along the way. But I seems to have profoundly changed the course of my
|
||||
life for the better. Ever since then, I've found it extremely difficult to waste my days away without having a
|
||||
sense of direction in my life. Though this has, some times more than others, been a source of anxiety. I certainly don't think I
|
||||
would have found it so simple to move abroad and continue to learn German whilst living, studying, and working in Munich for
|
||||
several years like I have been if I had never gone on that trip.
|
||||
</p>
|
||||
<p>
|
||||
So I guess, in that respect, watching your fellow rats have a good time, in real life, might just get you to settle for
|
||||
no less. One look at those old menial habits and—<i>poof</i>—they're gone. And for that I'm grateful.
|
||||
</p>
|
||||
</article>
|
||||
@@ -4,14 +4,8 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" href="/blog/styles.css">
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab:wght@600&display=swap"
|
||||
rel="stylesheet">
|
||||
<!-- <link rel="icon" href="/generative-energy/favicon.ico" sizes="any" /> -->
|
||||
|
||||
<meta name="description" content="Generative Energy - A page dedicated to Dr. Raymond Peat">
|
||||
<meta property="og:image" content="icecream.png">
|
||||
<link rel="stylesheet" href="/theme.css">
|
||||
<meta name="description" content="dj blog - djledda's blog">
|
||||
|
||||
<!-- SSR HEAD OUTLET -->
|
||||
</head>
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
:root {
|
||||
--subject-spacing: 40px;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #292929;
|
||||
font-family: "Roboto", serif;
|
||||
}
|
||||
|
||||
.title_name {
|
||||
font-size: 50px;
|
||||
color: floralwhite;
|
||||
font-family: "Roboto Slab", "Times New Roman", Times, serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title_name img {
|
||||
margin: 20px;
|
||||
height: 100px;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.spinMe {
|
||||
animation: spin 1s infinite linear;
|
||||
}
|
||||
|
||||
.shakeMe {
|
||||
animation: shake 0.2s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0% {
|
||||
transform: scale(1) translate(1px, 1px) rotate(0deg);
|
||||
}
|
||||
25% {
|
||||
transform: scale(0.95) translate(-1px, -2px) rotate(-1deg);
|
||||
}
|
||||
50% {
|
||||
transform: scale(0.9) translate(-3px, 0px) rotate(1deg);
|
||||
}
|
||||
75% {
|
||||
transform: scale(0.95) translate(3px, 2px) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) translate(-1px, 2px) rotate(-1deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg) scale(1);
|
||||
filter: hue-rotate(0deg) saturate(5);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(90deg) scale(2);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(180deg) scale(1);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(270deg) scale(2);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg) scale(1);
|
||||
filter: hue-rotate(360deg) saturate(5);
|
||||
}
|
||||
}
|
||||
|
||||
.supercontainer {
|
||||
padding-top: 3em;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 50em;
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.main {
|
||||
width: 35em;
|
||||
padding: 20px;
|
||||
}
|
||||
:root {
|
||||
--subject-spacing: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.title_name img {
|
||||
margin: 10px;
|
||||
height: 60px;
|
||||
width: auto;
|
||||
}
|
||||
.title_name {
|
||||
font-size: 30px;
|
||||
}
|
||||
.main {
|
||||
width: 20em;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
span.subjecttitle {
|
||||
height: 100%;
|
||||
font-family: "Roboto Slab", "Times New Roman", Times, serif;
|
||||
font-size: 20px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.subject:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.subject:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.subject {
|
||||
margin-top: var(--subject-spacing);
|
||||
margin-bottom: var(--subject-spacing);
|
||||
}
|
||||
|
||||
.resourcelist {
|
||||
margin-top: 2px;
|
||||
background-color: white;
|
||||
border-style: solid;
|
||||
border-color: #292929;
|
||||
border-width: 1px;
|
||||
border-radius: 5px;
|
||||
|
||||
a:first-of-type {
|
||||
.resource {
|
||||
padding: 15px 20px 10px 20px;
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
a:last-of-type {
|
||||
.resource {
|
||||
padding: 10px 20px 15px 20px;
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
a:only-of-type {
|
||||
.resource {
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resource {
|
||||
position: relative;
|
||||
background-color: white;
|
||||
padding: 10px 20px 10px 20px;
|
||||
display: block;
|
||||
color: #333333;
|
||||
text-decorAtion: none;
|
||||
transition: background-color 200ms;
|
||||
}
|
||||
|
||||
.resource:hover {
|
||||
background-color: #bde4ff;
|
||||
}
|
||||
|
||||
.resource:active {
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.50) inset;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -2,13 +2,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="/home/icon.webp" />
|
||||
<link rel="stylesheet" href="/home/main.css" />
|
||||
<link rel="stylesheet" href="/theme.css" />
|
||||
<link rel="icon" href="/home/img/dj.gif" />
|
||||
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab:wght@600&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<!-- SSR HEAD OUTLET -->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
59
public/theme.css
Normal file
59
public/theme.css
Normal file
@@ -0,0 +1,59 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Quattrocento:wght@400;700&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Laila:wght@300;400;500;600;700&family=Quattrocento:wght@400;700&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Laila:wght@300;400;500;600;700&family=Quattrocento:wght@400;700&family=Roboto+Slab:wght@100..900&display=swap');
|
||||
|
||||
:root {
|
||||
--dj-palette1: #83a6bf;
|
||||
--dj-palette2: #5e81ac;
|
||||
--dj-palette3: #8fbcbb;
|
||||
--dj-visited: #8d8bd5;
|
||||
--dj-bgpalette1: #2e3440;
|
||||
}
|
||||
|
||||
html, body {
|
||||
background-color: var(--dj-bgpalette1);
|
||||
color: var(--dj-palette1);
|
||||
|
||||
font-family: "Quattrocento", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 400; /* bold 700 */
|
||||
font-style: normal;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, nav, .dj-title, .roboto-slab {
|
||||
font-family: "Roboto Slab", serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.laila-light {
|
||||
font-family: "Laila", serif;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.laila-regular, body {
|
||||
font-family: "Laila", serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.laila-medium {
|
||||
font-family: "Laila", serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.laila-semibold {
|
||||
font-family: "Laila", serif;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.laila-bold {
|
||||
font-family: "Laila", serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
Reference in New Issue
Block a user