Created blog page, many improvements

This commit is contained in:
2024-02-18 11:30:50 +03:00
parent cfbaf56159
commit 3853e8fa20
23 changed files with 4301 additions and 3284 deletions
+92
View File
@@ -0,0 +1,92 @@
<script setup lang="ts">
const config = useAppConfig()
const meta = {
title: 'Page not found',
description:
'The page you are looking for does not exist. It might have been removed, had its name changed, or is temporarily unavailable.',
image: `${config.url}/images/logo.png`,
url: config.url,
}
useSeoMeta({
title: meta.title,
description: meta.description,
ogTitle: meta.title,
ogDescription: meta.description,
ogImage: meta.image,
ogUrl: meta.url,
ogType: 'website',
twitterTitle: meta.title,
twitterDescription: meta.description,
twitterImage: meta.image,
twitterCard: 'summary',
})
useHead({
title: 'Page not found',
htmlAttrs: {
lang: config.locale || 'en',
},
link: [
{
rel: 'icon',
type: 'image/x-icon',
href: '/favicon.ico',
},
],
})
const error = {
http_code: 200,
title: config.title,
url: config.url,
locale: config.locale || 'en',
data: {
path: '/error.vue',
content: {
title: 'Page not found!',
description:
"The page you are looking for does not exist. However, no 404 error has occurred, as you're browsing through a web application loaded into memory and HTTP error codes make no sense here.",
},
},
slug: useRoute().params.slug,
build: config.build,
}
const errorString = JSON.stringify(error, null, 2)
const buffer = ref('')
const startTime = Date.now()
const dt = 20
let i = 0
function type() {
if (Date.now() > startTime + dt * i) buffer.value += errorString[i++]
if (i < errorString.length) requestAnimationFrame(type)
}
onMounted(() => setTimeout(type, 1500))
</script>
<template>
<div>
<h3 class="alex">Page not found!</h3>
<pre class="pre-wrap">{{ buffer }}<span class="blinker">&#9610;</span></pre>
</div>
</template>
<style scoped lang="scss">
.blinker {
animation: blinker 1s steps(2, start) infinite;
}
@keyframes blinker {
from {
visibility: visible;
}
to {
visibility: hidden;
}
}
</style>
+14 -3
View File
@@ -1,4 +1,5 @@
<script setup lang="ts">
const config = useAppConfig()
const age =
new Date(Number(new Date()) - Number(new Date('2003-09-18'))).getFullYear() -
1970
@@ -6,8 +7,8 @@ const age =
const meta = {
title: 'About Me',
description: `Nice to meet you!~ I'm Andrew, a ${age}-year-old developer from Kaluga, Russia.`,
image: 'https://enderman.ch/images/logo.png',
url: 'https://enderman.ch/about',
image: `${config.url}/images/logo.png`,
url: `${config.url}/about`,
}
useSeoMeta({
@@ -27,7 +28,7 @@ useSeoMeta({
useHead({
title: 'About',
htmlAttrs: {
lang: 'en',
lang: config.locale || 'en',
},
link: [
{
@@ -82,6 +83,16 @@ useHead({
thinking for quite some time, and then concluded that adding «ch» at the
end sounded pretty good. I was 14 at the time of making that decision.
</li>
<li>
<strong
>When will you make a new video? What happened to your
schedule?</strong
>
</li>
<li>
One day. Haven't been particularly motivated lately, but life's busy. 🙁
I'm alive and well, though.
</li>
</ul>
</section>
</template>
+38
View File
@@ -0,0 +1,38 @@
<script setup lang="ts">
const { slug } = useRoute().params
</script>
<template>
<article
class="scrollbar fade-mask-sm d-flex flex-column gap-3 flex-grow-1 overflow-x-hidden overflow-y-auto py-sm-4 pe-sm-3"
>
<ContentDoc :path="`/blog/${slug}`">
<template #default="{ doc }">
<div class="post-preamble">
<h3 class="alex">{{ doc.title }}</h3>
<img
draggable="false"
:src="doc.thumbnail"
:alt="doc.title"
class="post-preamble-thumb rounded-4"
/>
</div>
<div class="post-content">
<ContentRenderer :value="doc" />
</div>
</template>
<template #not-found>
<div
class="d-flex flex-column justify-content-center align-items-center gap-3"
>
<span>Blog post not found 🙁</span>
<NuxtLink to="/blog" class="link-hi">Back to blog</NuxtLink>
</div>
</template>
</ContentDoc>
</article>
</template>
<style scoped lang="scss"></style>
+80
View File
@@ -0,0 +1,80 @@
<script setup lang="ts">
import { formatDate } from 'date-fns'
</script>
<template>
<section>
<h3 class="alex">Recent posts</h3>
<ContentList
:query="{
path: '/blog',
where: [{ draft: false }],
limit: 3,
sort: [{ created: -1 }],
}"
>
<template #default="{ list }">
<div class="d-grid gap-3">
<NuxtLink
v-for="post in list"
:key="post._path"
:to="post._path"
class="no-decoration"
>
<article
class="post-box d-flex flex-column flex-md-row gap-3 rounded-4 h-100"
>
<div class="post-thumb">
<img
draggable="false"
:src="post.thumbnail"
:alt="post.title"
class="rounded-4"
/>
</div>
<div>
<h3 class="post-title alex">{{ post.title }}</h3>
<p class="post-description">{{ post.description }}</p>
<div class="row">
<div class="col-6 d-flex flex-row gap-1 align-items-center">
<iconify-icon icon="mdi:calendar" />
<small class="nobr">
{{ formatDate(post.created, 'LLLL do, y &ndash; HH:mm') }}
</small>
</div>
</div>
<div v-if="post.updated" class="row">
<div class="col-12 d-flex flex-row gap-1 align-items-center">
<iconify-icon icon="mdi:pencil" />
<small class="nobr">
{{ formatDate(post.updated, 'LLLL do, y &ndash; HH:mm') }}
</small>
</div>
</div>
</div>
<div class="post-pocket d-flex flex-row gap-1 align-items-center">
<iconify-icon icon="mdi:clock-outline" />
<small class="nobr font-monospace font-small">
{{ post.readingTime.text }}
</small>
</div>
</article>
</NuxtLink>
</div>
</template>
<template #not-found>
<div
class="d-flex flex-column justify-content-center align-items-center gap-3"
>
<span>No posts found 🙁</span>
<NuxtLink to="/" class="link-hi">Back to index</NuxtLink>
</div>
</template>
</ContentList>
</section>
</template>
<style scoped lang="scss"></style>
+6 -6
View File
@@ -3,7 +3,7 @@ const config = useAppConfig()
const meta = {
title: 'Enderman',
description: config.description,
image: 'https://enderman.ch/images/logo.png',
image: `${config.url}/images/logo.png`,
url: config.url,
}
@@ -43,9 +43,9 @@ useHead({
I'm <strong>Enderman</strong> &ndash; a software engineer, a malware
enthusiast and most importantly, a weird tall creature. I have over 300K
subscribers on
<a class="link-hi" href="https://go.enderman.ch/youtube">YouTube</a> and
<a class="link-hi" :href="`${config.shortener}/youtube`">YouTube</a> and
over 20K followers on
<a class="link-hi" href="https://go.enderman.ch/twitter">Twitter</a>.
<a class="link-hi" :href="`${config.shortener}/twitter`">Twitter</a>.
Sometimes I wish there were 48 hours in a day.
</p>
<div class="row g-3">
@@ -57,7 +57,7 @@ useHead({
<strong>C/C++</strong> for desktop applications and any common
backend stack with framework-loaded TypeScript for web. You can take
a look at my code on
<a class="link-hi" href="https://go.enderman.ch/github">GitHub</a>.
<a class="link-hi" :href="`${config.shortener}/github`">GitHub</a>.
</li>
<li>
I have the most unnecessary, yet fascinating knowledge about
@@ -70,7 +70,7 @@ useHead({
<li>
I research and analyze modern malware, educate computer users about
it and preserve history. The repository can be found
<a class="link-hi" href="https://go.enderman.ch/repository">here</a
<a class="link-hi" :href="`${config.shortener}/repository`">here</a
>.
</li>
<li>I make videos for you to enjoy!</li>
@@ -86,7 +86,7 @@ useHead({
<li>Philosophy</li>
<li>Geopolitics</li>
<li>
<a class="link-hi" href="https://go.enderman.ch/chess">Chess</a>
<a class="link-hi" :href="`${config.shortener}/chess`">Chess</a>
</li>
<li>Solitude</li>
</ul>
+5 -5
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
// AI-Generated test data.
const config = useAppConfig()
const projects = [
{
name: 'MalwareWatch',
@@ -25,7 +25,7 @@ const projects = [
{
name: 'Windows XP Keygen / UMSKT',
description: 'A key generator for Windows XP.',
url: 'https://go.enderman.ch/xpkeygen',
url: `${config.shortener}/xpkeygen`,
},
]
@@ -33,8 +33,8 @@ const meta = {
title: "Enderman's Projects",
description:
"A display of my largest projects. Some of them aren't published on YouTube.",
image: 'https://enderman.ch/images/logo.png',
url: 'https://enderman.ch/projects',
image: `${config.url}/images/logo.png`,
url: `${config.url}/projects`,
}
useSeoMeta({
@@ -54,7 +54,7 @@ useSeoMeta({
useHead({
title: 'Projects',
htmlAttrs: {
lang: 'en',
lang: config.locale || 'en',
},
link: [
{
+18 -15
View File
@@ -1,8 +1,11 @@
<script setup lang="ts">
const config = useAppConfig()
const fqdn = config.url.split('//')[1]
const socials = [
{
name: 'YouTube',
url: 'https://go.enderman.ch/youtube',
url: `${config.shortener}/youtube`,
icon: {
name: 'logos:youtube-icon',
color: 'white',
@@ -10,7 +13,7 @@ const socials = [
},
{
name: 'Andrew',
url: 'https://go.enderman.ch/andrew',
url: `${config.shortener}/andrew`,
icon: {
name: 'logos:youtube-icon',
color: 'white',
@@ -18,7 +21,7 @@ const socials = [
},
{
name: 'Twitch',
url: 'https://go.enderman.ch/twitch',
url: `${config.shortener}/twitch`,
icon: {
name: 'fa:twitch',
color: '#B68CFF',
@@ -26,7 +29,7 @@ const socials = [
},
{
name: 'TikTok',
url: 'https://go.enderman.ch/tiktok',
url: `${config.shortener}/tiktok`,
icon: {
name: 'logos:tiktok-icon',
color: 'white',
@@ -34,7 +37,7 @@ const socials = [
},
{
name: 'Twitter',
url: 'https://go.enderman.ch/twitter',
url: `${config.shortener}/twitter`,
icon: {
name: 'logos:twitter',
color: 'white',
@@ -42,7 +45,7 @@ const socials = [
},
{
name: 'Telegram',
url: 'https://go.enderman.ch/telegram',
url: `${config.shortener}/telegram`,
icon: {
name: 'logos:telegram',
color: 'white',
@@ -50,7 +53,7 @@ const socials = [
},
{
name: 'Discord',
url: 'https://go.enderman.ch/discord',
url: `${config.shortener}/discord`,
icon: {
name: 'logos:discord-icon',
color: 'white',
@@ -58,7 +61,7 @@ const socials = [
},
{
name: 'GitHub',
url: 'https://go.enderman.ch/github',
url: `${config.shortener}/github`,
icon: {
name: 'fa:github',
color: 'white',
@@ -66,7 +69,7 @@ const socials = [
},
{
name: 'Steam',
url: 'https://go.enderman.ch/steam',
url: `${config.shortener}/steam`,
icon: {
name: 'fa:steam',
color: 'white',
@@ -78,8 +81,8 @@ const meta = {
title: 'Enderman Online',
description:
'Discover me on your favorite social media and find ways to contact me here.',
image: 'https://enderman.ch/images/logo.png',
url: 'https://enderman.ch/projects',
image: `${config.url}/images/logo.png`,
url: `${config.url}/projects`,
}
useSeoMeta({
@@ -99,7 +102,7 @@ useSeoMeta({
useHead({
title: 'Socials',
htmlAttrs: {
lang: 'en',
lang: config.locale || 'en',
},
link: [
{
@@ -140,11 +143,11 @@ useHead({
Personal:
<EMail
class="link-hi"
address="contact@enderman.ch"
:address="`contact@${fqdn}`"
subject="Hey Enderman!"
/><br />
Manager: <EMail class="link-hi" address="manager@enderman.ch" /><br />
Abuse: <EMail class="link-hi" address="abuse@enderman.ch" />
Manager: <EMail class="link-hi" :address="`manager@${fqdn}`" /><br />
Abuse: <EMail class="link-hi" :address="`abuse@${fqdn}`" />
</p>
</div>
</div>