add posts and things
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
ChronosXYZ 2024-09-19 02:47:22 +03:00
parent 9a3add3f50
commit a49603e539
Signed by: ChronosXYZ
GPG Key ID: 189BF50EBD342791
45 changed files with 344 additions and 527 deletions

22
.drone.yml Normal file
View File

@ -0,0 +1,22 @@
kind: pipeline
name: default
steps:
- name: build
image: node:20
commands:
- npm install
- npm run build
- name: rsync
image: drillster/drone-rsync
settings:
hosts:
- nexusnest.link
port:
from_secret: rsync_port
target: /srv/nginx/nginx/www/pigeoncatcher.site
source: dist/*
user:
from_secret: rsync_user
key:
from_secret: rsync_key

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.gif filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text

View File

@ -1,7 +1,6 @@
// @ts-check
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
// https://astro.build/config

View File

@ -10,11 +10,12 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.9.3",
"@astrojs/mdx": "^3.1.6",
"@astrojs/rss": "^4.0.7",
"@astrojs/sitemap": "^3.1.6",
"astro": "^4.15.7",
"@astrojs/check": "^0.9.3",
"sharp": "^0.33.5",
"typescript": "^5.6.2"
}
}

View File

@ -20,6 +20,9 @@ dependencies:
astro:
specifier: ^4.15.7
version: 4.15.7(typescript@5.6.2)
sharp:
specifier: ^0.33.5
version: 0.33.5
typescript:
specifier: ^5.6.2
version: 5.6.2
@ -1620,7 +1623,6 @@ packages:
color-name: 1.1.4
simple-swizzle: 0.2.2
dev: false
optional: true
/color@4.2.3:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
@ -1630,7 +1632,6 @@ packages:
color-convert: 2.0.1
color-string: 1.9.1
dev: false
optional: true
/comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
@ -1683,7 +1684,6 @@ packages:
engines: {node: '>=8'}
requiresBuild: true
dev: false
optional: true
/deterministic-object-hash@2.0.2:
resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==}
@ -2176,7 +2176,6 @@ packages:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
requiresBuild: true
dev: false
optional: true
/is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
@ -3421,7 +3420,6 @@ packages:
'@img/sharp-win32-ia32': 0.33.5
'@img/sharp-win32-x64': 0.33.5
dev: false
optional: true
/shiki@1.17.7:
resolution: {integrity: sha512-Zf6hNtWhFyF4XP5OOsXkBTEx9JFPiN0TQx4wSe+Vqeuczewgk2vT4IZhF4gka55uelm052BD5BaHavNqUNZd+A==}
@ -3445,7 +3443,6 @@ packages:
dependencies:
is-arrayish: 0.3.2
dev: false
optional: true
/sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}

View File

1
public/discord.svg Normal file
View File

@ -0,0 +1 @@
<svg fill="#FFFFFF" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 41.625 10.769531 C 37.644531 7.566406 31.347656 7.023438 31.078125 7.003906 C 30.660156 6.96875 30.261719 7.203125 30.089844 7.589844 C 30.074219 7.613281 29.9375 7.929688 29.785156 8.421875 C 32.417969 8.867188 35.652344 9.761719 38.578125 11.578125 C 39.046875 11.867188 39.191406 12.484375 38.902344 12.953125 C 38.710938 13.261719 38.386719 13.429688 38.050781 13.429688 C 37.871094 13.429688 37.6875 13.378906 37.523438 13.277344 C 32.492188 10.15625 26.210938 10 25 10 C 23.789063 10 17.503906 10.15625 12.476563 13.277344 C 12.007813 13.570313 11.390625 13.425781 11.101563 12.957031 C 10.808594 12.484375 10.953125 11.871094 11.421875 11.578125 C 14.347656 9.765625 17.582031 8.867188 20.214844 8.425781 C 20.0625 7.929688 19.925781 7.617188 19.914063 7.589844 C 19.738281 7.203125 19.34375 6.960938 18.921875 7.003906 C 18.652344 7.023438 12.355469 7.566406 8.320313 10.8125 C 6.214844 12.761719 2 24.152344 2 34 C 2 34.175781 2.046875 34.34375 2.132813 34.496094 C 5.039063 39.605469 12.972656 40.941406 14.78125 41 C 14.789063 41 14.800781 41 14.8125 41 C 15.132813 41 15.433594 40.847656 15.621094 40.589844 L 17.449219 38.074219 C 12.515625 36.800781 9.996094 34.636719 9.851563 34.507813 C 9.4375 34.144531 9.398438 33.511719 9.765625 33.097656 C 10.128906 32.683594 10.761719 32.644531 11.175781 33.007813 C 11.234375 33.0625 15.875 37 25 37 C 34.140625 37 38.78125 33.046875 38.828125 33.007813 C 39.242188 32.648438 39.871094 32.683594 40.238281 33.101563 C 40.601563 33.515625 40.5625 34.144531 40.148438 34.507813 C 40.003906 34.636719 37.484375 36.800781 32.550781 38.074219 L 34.378906 40.589844 C 34.566406 40.847656 34.867188 41 35.1875 41 C 35.199219 41 35.210938 41 35.21875 41 C 37.027344 40.941406 44.960938 39.605469 47.867188 34.496094 C 47.953125 34.34375 48 34.175781 48 34 C 48 24.152344 43.785156 12.761719 41.625 10.769531 Z M 18.5 30 C 16.566406 30 15 28.210938 15 26 C 15 23.789063 16.566406 22 18.5 22 C 20.433594 22 22 23.789063 22 26 C 22 28.210938 20.433594 30 18.5 30 Z M 31.5 30 C 29.566406 30 28 28.210938 28 26 C 28 23.789063 29.566406 22 31.5 22 C 33.433594 22 35 23.789063 35 26 C 35 28.210938 33.433594 30 31.5 30 Z"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
public/earth.gif (Stored with Git LFS) Normal file

Binary file not shown.

1
public/email.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z"/></svg>

After

Width:  |  Height:  |  Size: 274 B

1
public/github.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0"?><svg fill="#FFFFFF" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30px" height="30px"> <path d="M15,3C8.373,3,3,8.373,3,15c0,5.623,3.872,10.328,9.092,11.63C12.036,26.468,12,26.28,12,26.047v-2.051 c-0.487,0-1.303,0-1.508,0c-0.821,0-1.551-0.353-1.905-1.009c-0.393-0.729-0.461-1.844-1.435-2.526 c-0.289-0.227-0.069-0.486,0.264-0.451c0.615,0.174,1.125,0.596,1.605,1.222c0.478,0.627,0.703,0.769,1.596,0.769 c0.433,0,1.081-0.025,1.691-0.121c0.328-0.833,0.895-1.6,1.588-1.962c-3.996-0.411-5.903-2.399-5.903-5.098 c0-1.162,0.495-2.286,1.336-3.233C9.053,10.647,8.706,8.73,9.435,8c1.798,0,2.885,1.166,3.146,1.481C13.477,9.174,14.461,9,15.495,9 c1.036,0,2.024,0.174,2.922,0.483C18.675,9.17,19.763,8,21.565,8c0.732,0.731,0.381,2.656,0.102,3.594 c0.836,0.945,1.328,2.066,1.328,3.226c0,2.697-1.904,4.684-5.894,5.097C18.199,20.49,19,22.1,19,23.313v2.734 c0,0.104-0.023,0.179-0.035,0.268C23.641,24.676,27,20.236,27,15C27,8.373,21.627,3,15,3z"/></svg>

After

Width:  |  Height:  |  Size: 975 B

1
public/instagram.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><radialGradient id="yOrnnhliCrdS2gy~4tD8ma" cx="19.38" cy="42.035" r="44.899" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fd5"/><stop offset=".328" stop-color="#ff543f"/><stop offset=".348" stop-color="#fc5245"/><stop offset=".504" stop-color="#e64771"/><stop offset=".643" stop-color="#d53e91"/><stop offset=".761" stop-color="#cc39a4"/><stop offset=".841" stop-color="#c837ab"/></radialGradient><path fill="url(#yOrnnhliCrdS2gy~4tD8ma)" d="M34.017,41.99l-20,0.019c-4.4,0.004-8.003-3.592-8.008-7.992l-0.019-20 c-0.004-4.4,3.592-8.003,7.992-8.008l20-0.019c4.4-0.004,8.003,3.592,8.008,7.992l0.019,20 C42.014,38.383,38.417,41.986,34.017,41.99z"/><radialGradient id="yOrnnhliCrdS2gy~4tD8mb" cx="11.786" cy="5.54" r="29.813" gradientTransform="matrix(1 0 0 .6663 0 1.849)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#4168c9"/><stop offset=".999" stop-color="#4168c9" stop-opacity="0"/></radialGradient><path fill="url(#yOrnnhliCrdS2gy~4tD8mb)" d="M34.017,41.99l-20,0.019c-4.4,0.004-8.003-3.592-8.008-7.992l-0.019-20 c-0.004-4.4,3.592-8.003,7.992-8.008l20-0.019c4.4-0.004,8.003,3.592,8.008,7.992l0.019,20 C42.014,38.383,38.417,41.986,34.017,41.99z"/><path fill="#fff" d="M24,31c-3.859,0-7-3.14-7-7s3.141-7,7-7s7,3.14,7,7S27.859,31,24,31z M24,19c-2.757,0-5,2.243-5,5 s2.243,5,5,5s5-2.243,5-5S26.757,19,24,19z"/><circle cx="31.5" cy="16.5" r="1.5" fill="#fff"/><path fill="#fff" d="M30,37H18c-3.859,0-7-3.14-7-7V18c0-3.86,3.141-7,7-7h12c3.859,0,7,3.14,7,7v12 C37,33.86,33.859,37,30,37z M18,13c-2.757,0-5,2.243-5,5v12c0,2.757,2.243,5,5,5h12c2.757,0,5-2.243,5-5V18c0-2.757-2.243-5-5-5H18z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

1
public/linkedin.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#0078d4" d="M42,37c0,2.762-2.238,5-5,5H11c-2.761,0-5-2.238-5-5V11c0-2.762,2.239-5,5-5h26c2.762,0,5,2.238,5,5 V37z"/><path d="M30,37V26.901c0-1.689-0.819-2.698-2.192-2.698c-0.815,0-1.414,0.459-1.779,1.364 c-0.017,0.064-0.041,0.325-0.031,1.114L26,37h-7V18h7v1.061C27.022,18.356,28.275,18,29.738,18c4.547,0,7.261,3.093,7.261,8.274 L37,37H30z M11,37V18h3.457C12.454,18,11,16.528,11,14.499C11,12.472,12.478,11,14.514,11c2.012,0,3.445,1.431,3.486,3.479 C18,16.523,16.521,18,14.485,18H18v19H11z" opacity=".05"/><path d="M30.5,36.5v-9.599c0-1.973-1.031-3.198-2.692-3.198c-1.295,0-1.935,0.912-2.243,1.677 c-0.082,0.199-0.071,0.989-0.067,1.326L25.5,36.5h-6v-18h6v1.638c0.795-0.823,2.075-1.638,4.238-1.638 c4.233,0,6.761,2.906,6.761,7.774L36.5,36.5H30.5z M11.5,36.5v-18h6v18H11.5z M14.457,17.5c-1.713,0-2.957-1.262-2.957-3.001 c0-1.738,1.268-2.999,3.014-2.999c1.724,0,2.951,1.229,2.986,2.989c0,1.749-1.268,3.011-3.015,3.011H14.457z" opacity=".07"/><path fill="#fff" d="M12,19h5v17h-5V19z M14.485,17h-0.028C12.965,17,12,15.888,12,14.499C12,13.08,12.995,12,14.514,12 c1.521,0,2.458,1.08,2.486,2.499C17,15.887,16.035,17,14.485,17z M36,36h-5v-9.099c0-2.198-1.225-3.698-3.192-3.698 c-1.501,0-2.313,1.012-2.707,1.99C24.957,25.543,25,26.511,25,27v9h-5V19h5v2.616C25.721,20.5,26.85,19,29.738,19 c3.578,0,6.261,2.25,6.261,7.274L36,36L36,36z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

4
public/mastodon.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="61.076954mm" height="65.47831mm" viewBox="0 0 216.4144 232.00976">
<path fill="#2b90d9" d="M211.80734 139.0875c-3.18125 16.36625-28.4925 34.2775-57.5625 37.74875-15.15875 1.80875-30.08375 3.47125-45.99875 2.74125-26.0275-1.1925-46.565-6.2125-46.565-6.2125 0 2.53375.15625 4.94625.46875 7.2025 3.38375 25.68625 25.47 27.225 46.39125 27.9425 21.11625.7225 39.91875-5.20625 39.91875-5.20625l.8675 19.09s-14.77 7.93125-41.08125 9.39c-14.50875.7975-32.52375-.365-53.50625-5.91875C9.23234 213.82 1.40609 165.31125.20859 116.09125c-.365-14.61375-.14-28.39375-.14-39.91875 0-50.33 32.97625-65.0825 32.97625-65.0825C49.67234 3.45375 78.20359.2425 107.86484 0h.72875c29.66125.2425 58.21125 3.45375 74.8375 11.09 0 0 32.975 14.7525 32.975 65.0825 0 0 .41375 37.13375-4.59875 62.915"/>
<path fill="#fff" d="M177.50984 80.077v60.94125h-24.14375v-59.15c0-12.46875-5.24625-18.7975-15.74-18.7975-11.6025 0-17.4175 7.5075-17.4175 22.3525v32.37625H96.20734V85.42325c0-14.845-5.81625-22.3525-17.41875-22.3525-10.49375 0-15.74 6.32875-15.74 18.7975v59.15H38.90484V80.077c0-12.455 3.17125-22.3525 9.54125-29.675 6.56875-7.3225 15.17125-11.07625 25.85-11.07625 12.355 0 21.71125 4.74875 27.8975 14.2475l6.01375 10.08125 6.015-10.08125c6.185-9.49875 15.54125-14.2475 27.8975-14.2475 10.6775 0 19.28 3.75375 25.85 11.07625 6.36875 7.3225 9.54 17.22 9.54 29.675"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
public/matrix.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="50px" height="50px"><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M5,5c-0.55226,0.00006 -0.99994,0.44774 -1,1v38c0.00006,0.55226 0.44774,0.99994 1,1h3c0.36064,0.0051 0.69608,-0.18438 0.87789,-0.49587c0.18181,-0.3115 0.18181,-0.69676 0,-1.00825c-0.18181,-0.3115 -0.51725,-0.50097 -0.87789,-0.49587h-2v-36h2c0.36064,0.0051 0.69608,-0.18438 0.87789,-0.49587c0.18181,-0.3115 0.18181,-0.69676 0,-1.00825c-0.18181,-0.3115 -0.51725,-0.50097 -0.87789,-0.49587zM42,5c-0.36064,-0.0051 -0.69608,0.18438 -0.87789,0.49587c-0.18181,0.3115 -0.18181,0.69676 0,1.00825c0.18181,0.3115 0.51725,0.50097 0.87789,0.49587h2v36h-2c-0.36064,-0.0051 -0.69608,0.18438 -0.87789,0.49587c-0.18181,0.3115 -0.18181,0.69676 0,1.00825c0.18181,0.3115 0.51725,0.50097 0.87789,0.49587h3c0.55226,-0.00006 0.99994,-0.44774 1,-1v-38c-0.00006,-0.55226 -0.44774,-0.99994 -1,-1zM31.07422,17.50977c-1.09848,-0.02226 -2.20583,0.25053 -3.0957,0.86328c-0.571,0.394 -1.06291,0.89977 -1.62891,1.38477c-0.861,-1.718 -2.42027,-2.17703 -4.19727,-2.20703c-1.801,-0.031 -3.23142,0.79102 -4.48242,2.29102v-1.8418h-3.66992v14h3.66406c0,0 -0.00609,-5.23398 0.00391,-7.83398c0.002,-0.462 0.02123,-0.93377 0.11523,-1.38477c0.29,-1.389 1.75483,-2.24681 3.17383,-2.13281c1.352,0.109 2.14298,0.84722 2.20898,2.44922c0.011,0.279 0,8.90234 0,8.90234h3.66602v-7.77148c0.006,-0.599 0.06984,-1.21102 0.21484,-1.79102c0.326,-1.3 1.54366,-1.93925 2.97266,-1.78125c1.26,0.139 2.2195,0.81836 2.3125,2.19336v9.15039h3.66797v-10c0,-1 -0.25364,-1.50914 -0.55664,-2.11914c-0.7325,-1.47563 -2.53835,-2.33399 -4.36914,-2.37109z"></path></g></g></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

9
public/telegram.svg Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 240.1 240.1">
<linearGradient id="Oval_1_" gradientUnits="userSpaceOnUse" x1="-838.041" y1="660.581" x2="-838.041" y2="660.3427" gradientTransform="matrix(1000 0 0 -1000 838161 660581)">
<stop offset="0" style="stop-color:#2AABEE"/>
<stop offset="1" style="stop-color:#229ED9"/>
</linearGradient>
<circle fill-rule="evenodd" clip-rule="evenodd" fill="url(#Oval_1_)" cx="120.1" cy="120.1" r="120.1"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M54.3,118.8c35-15.2,58.3-25.3,70-30.2 c33.3-13.9,40.3-16.3,44.8-16.4c1,0,3.2,0.2,4.7,1.4c1.2,1,1.5,2.3,1.7,3.3s0.4,3.1,0.2,4.7c-1.8,19-9.6,65.1-13.6,86.3 c-1.7,9-5,12-8.2,12.3c-7,0.6-12.3-4.6-19-9c-10.6-6.9-16.5-11.2-26.8-18c-11.9-7.8-4.2-12.1,2.6-19.1c1.8-1.8,32.5-29.8,33.1-32.3 c0.1-0.3,0.1-1.5-0.6-2.1c-0.7-0.6-1.7-0.4-2.5-0.2c-1.1,0.2-17.9,11.4-50.6,33.5c-4.8,3.3-9.1,4.9-13,4.8 c-4.3-0.1-12.5-2.4-18.7-4.4c-7.5-2.4-13.5-3.7-13-7.9C45.7,123.3,48.7,121.1,54.3,118.8z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

1
public/xmpp.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#f57f17" d="M13,37l1.9,1.9C27.33,37.74,40,25.32,40,12l-1.98-0.85L32,13C32,13,31,36,13,37z"/><path fill="#e65100" d="M38.99,10.85C38.55,33.15,20.9,39,13,39v-2c10.7,0,23.29-8.19,23.97-25.53L38.99,10.85z"/><path fill="#0288d1" d="M45,9c0,10.06-9.3,21.16-19.73,26.6c6.9-3.8,13.46-11.27,13.72-24.75L45,9z"/><path fill="#9ccc65" d="M35,37l-1.9,1.9C20.67,37.74,8,25.32,8,12l1.98-0.85L16,13C16,13,17,36,35,37z"/><path fill="#689f38" d="M9.01,10.85C9.45,33.15,27.1,39,35,39v-2c-10.7,0-23.29-8.19-23.97-25.53L9.01,10.85z"/><path fill="#0288d1" d="M3,9c0,10.06,9.3,21.16,19.73,26.6c-6.9-3.8-13.46-11.27-13.72-24.75L3,9z"/></svg>

After

Width:  |  Height:  |  Size: 717 B

View File

@ -5,43 +5,29 @@ import '../styles/global.css';
interface Props {
title: string;
description: string;
image?: string;
}
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props;
const { title } = Astro.props;
---
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<!-- <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> -->
<meta name="generator" content={Astro.generator} />
<!-- Font preloads -->
<link rel="preload" href="/fonts/atkinson-regular.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/atkinson-bold.woff" as="font" type="font/woff" crossorigin />
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />
<!-- <meta property="og:image" content={new URL(image, Astro.url)} /> -->

View File

@ -0,0 +1,66 @@
---
import type { CollectionEntry } from 'astro:content'
import FormattedDate from './FormattedDate.astro';
import { Image } from 'astro:assets';
interface Props {
post: CollectionEntry<'blog'>
showSeparator: boolean
}
const { post, showSeparator } = Astro.props;
---
<div class="entry-box">
<div class="entry-body">
<div class="entry-title">
<h2><a href={`/blog/${post.slug}`}>{post.data.title}</a></h2>
<span><FormattedDate date={post.data.pubDate} /></span>
</div>
{post.data.cover && <Image class="entry-img" src={post.data.cover} alt={post.data.coverAlt || ""}/> }
</div>
{showSeparator && <span class="entry-separator" /> }
</div>
<style>
.entry-box {
display: flex;
flex-direction: column;
height: 7m;
padding: 0 0 1em;
}
.entry-title {
display: flex;
flex-direction: column;
}
.entry-body {
display: flex;
}
.entry-img {
border-radius: var(--image-radius);
margin-left: auto;
/* width: ; */
aspect-ratio: 1;
/* height: 100%; */
height: 96px;
width: 96px;
}
.entry-separator {
/* width: 1em; */
margin-top: 1em;
border-bottom: 1px dotted white;
}
h2 {
margin: 0;
}
@media only screen and (max-width: 768px) {
.entry-body {
gap: 2em;
}
}
</style>

View File

@ -3,5 +3,14 @@ const today = new Date();
---
<footer>
<p>Made with ❤️ in 🇷🇺</p>
<p>&copy; {today.getFullYear()} Denis Davydov / Made with ❤️ in 🇷🇺 using <a href="https://astro.build">Astro</a></p>
</footer>
<style>
footer {
text-align: center;
}
/* footer p {
margin: 0.5rem;
} */
</style>

View File

@ -15,3 +15,11 @@ const { date } = Astro.props;
})
}
</time>
<style>
time {
text-transform: uppercase;
letter-spacing: .2px;
font-size: 11pt;
}
}

View File

@ -1,11 +1,13 @@
---
import HeaderLink from './HeaderLink.astro';
import { MENU, SITE_TITLE } from '../consts';
import { SITE_TITLE } from '../consts';
---
<header>
<h1 id="title">{SITE_TITLE}</h1>
<nav>
{MENU.map((data, index) => <HeaderLink href={data.path} showSeparator={index < MENU.length - 1}>{data.name}</HeaderLink>)}
<HeaderLink href="/" showSeparator={true}>Home</HeaderLink>
<HeaderLink href="/blog" showSeparator={true}>Posts</HeaderLink>
<HeaderLink href="/rss.xml" showSeparator={false}>RSS</HeaderLink>
</nav>
</header>

View File

@ -1,5 +1,9 @@
---
const { href, ...props } = Astro.props;
interface Props {
href: string;
showSeparator: boolean;
}
const { href, showSeparator } = Astro.props;
// const { pathname } = Astro.url;
// const subpath = pathname.match(/[^\/]+/g);
@ -10,7 +14,7 @@ const { href, ...props } = Astro.props;
<a href={href} class="header-link">
<slot />
</a>
<span class="menu-separator" style={{visibility: props.showSeparator ? 'visible' : 'hidden'}}>|</span>
<span class="menu-separator" style={{visibility: showSeparator ? 'visible' : 'hidden'}}>|</span>
</div>
<style>
.header-link {

View File

@ -2,8 +2,3 @@
// You can import this data from anywhere in your site by using the `import` keyword.
export const SITE_TITLE = 'pigeon.catcher@home';
export const MENU = [
{ name: 'Home', path: '/' },
{name: 'Posts', path: '/posts'},
{name: 'RSS', path: '/rss'},
];

BIN
src/content/blog/banners/12.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/content/blog/banners/oasis.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/content/blog/covers/oasis-cover.jpg (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,47 @@
---
title: 'Development of Oasis SA:MP Server #1'
description: ''
cover: './covers/oasis-cover.jpg'
banner: './banners/oasis.jpg'
# coverAlt: ''
pubDate: 2024-05-18
---
Hi there!
I am developing a [GTA SA-MP](## "Grand Theft Auto: San Andreas Multiplayer") server called Oasis. Despite being an older game from 2004, it still has small community around it. Creating a server for it has been a longtime dream of mine, as Ive been playing SAMP since childhood. Recently, some members from the open.mp Discord server reached out for help with their server development, and I decided to join in.
The server is entertainment-themed, featuring several game modes. I decided to develop the server in an unconventional way, using the C++ language instead
of the internal scripting language Pawn to improve my skills and for more flexibility in development. Since I am honing my skills, I am more motivated to work on this. I am using the open.mp component system for game mode development.
I plan to release a series of posts in the format of a developer diary about the development of this project where I discuss issues I've encountered while developing or to share experience I've received.
I designed the architecture of the game mode, which includes several components: a core manager, a textdraw manager (to draw custom UI), and a command manager. A lot of attention was given to the command manager (processor). First, I created a command and argument parser using a hashmap and C++ metaprogramming features. Command arguments are converted into the appropriate data types and then passed to command handlers that define the behavior of different commands. When creating a command, I include the command's help information in the command manager to automatically generate the help dialog. In the future, I plan to implement a role system in the command manager to more conveniently restrict access to commands (for example, for admins). I developed a callback verifier to ensure compliance with a specific callback format using a C++ metaprogramming feature called concepts. This is a new feature with little documentation, so [I had to go to Stack Overflow](https://stackoverflow.com/questions/77890544/how-to-infer-types-of-arguments-from-function-type-to-check-against-list-of-allo), where some guy helped me solve the problem I had.
The server has localization support, so players speaking languages such as English, Russian and Portuguese can play the server together! I used library called [tinygettext](https://github.com/tinygettext/tinygettext/). It supports standard GNU Gettext PO translation files, so it's pretty easy to translate the project in any language. I made the localization system capable of macros expanding to enable support for human-readable colors, for example.
![](./images/oasis-multilang.png)
Currently, the server has two modes - freeroam mode and DM mode. In freeroam mode, not much has been implemented yet, but you can spawn a car and just drive around the world. For now, I'm focusing on developing the DM mode, where you can enter one of three server-generated rooms with different weapon sets and maps to compete with friends in shooting. In the future, there will be the ability to create custom rooms with flexible map settings, round time, HP, armor, and weapons.
![](./images/oasis-modes.png)
![Oasis DM Rooms](./images/oasis-dm-rooms.png)
![Oasis DM](./images/oasis-dm.png)
I am planning to develop other modes, such as PTP (Protect the President, more on it later), Cops & Robbers, Race and Derby.
I have also implemented a minimalist speedometer.
![Oasis Speedometer](./images/oasis-speedometer.png)
After the DM mode, I plan to move on to the PTP (Protect the President) mode. This is a popular mode on another server called UIF, where you play in one of three teams (secret service, police, and terrorists). Your goal is to save the president and vice president, or to kill them, depending on which team you play. It's simple but fun game, and old GTA physics makes it more funny. In Oasis we plan to extend this mode further, making it even more interesting.
To simplify project deployment for developers, I integrated a VSCode feature called Dev Containers for quickly setting up the development environment using Docker. I've always been annoyed by the long setup time required to start developing, so I implemented this first. I am also in the process of integrating Nix into the project, but I have encountered [cross-compilation issue](https://discourse.nixos.org/t/multistdenv-x86-libgcc-linkage-issue/45419) that I haven't been able to resolve yet. Nix allows for more reproducible and predictable builds than Docker. The project also includes a CI/CD system, which further speeds up development and testing on the dev server.
Join the development team by contacting me, if you love making games!
Also please join the project's [Discord server](https://discord.gg/88Nqr7N4Mz).
Stay tuned!

View File

@ -1,16 +0,0 @@
---
title: 'First post'
description: 'Lorem ipsum dolor sit amet'
pubDate: 'Jul 08 2022'
heroImage: '/blog-placeholder-3.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.

BIN
src/content/blog/images/oasis-dm-rooms.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/content/blog/images/oasis-dm.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/content/blog/images/oasis-modes.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/content/blog/images/oasis-multilang.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/content/blog/images/oasis-speedometer.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,214 +0,0 @@
---
title: 'Markdown Style Guide'
description: 'Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.'
pubDate: 'Jun 19 2024'
heroImage: '/blog-placeholder-1.jpg'
---
Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.
## Headings
The following HTML `<h1>`—`<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
# H1
## H2
### H3
#### H4
##### H5
###### H6
## Paragraph
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
## Images
### Syntax
```markdown
![Alt text](./full/or/relative/path/of/image)
```
### Output
![blog placeholder](/blog-placeholder-about.jpg)
## Blockquotes
The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
### Blockquote without attribution
#### Syntax
```markdown
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
> **Note** that you can use _Markdown syntax_ within a blockquote.
```
#### Output
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
> **Note** that you can use _Markdown syntax_ within a blockquote.
### Blockquote with attribution
#### Syntax
```markdown
> Don't communicate by sharing memory, share memory by communicating.<br>
> — <cite>Rob Pike[^1]</cite>
```
#### Output
> Don't communicate by sharing memory, share memory by communicating.<br>
> — <cite>Rob Pike[^1]</cite>
[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
## Tables
### Syntax
```markdown
| Italics | Bold | Code |
| --------- | -------- | ------ |
| _italics_ | **bold** | `code` |
```
### Output
| Italics | Bold | Code |
| --------- | -------- | ------ |
| _italics_ | **bold** | `code` |
## Code Blocks
### Syntax
we can use 3 backticks ``` in new line and write snippet and close with 3 backticks on new line and to highlight language specific syntax, write one word of language name after first 3 backticks, for eg. html, javascript, css, markdown, typescript, txt, bash
````markdown
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
```
````
### Output
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
```
## List Types
### Ordered List
#### Syntax
```markdown
1. First item
2. Second item
3. Third item
```
#### Output
1. First item
2. Second item
3. Third item
### Unordered List
#### Syntax
```markdown
- List item
- Another item
- And another item
```
#### Output
- List item
- Another item
- And another item
### Nested list
#### Syntax
```markdown
- Fruit
- Apple
- Orange
- Banana
- Dairy
- Milk
- Cheese
```
#### Output
- Fruit
- Apple
- Orange
- Banana
- Dairy
- Milk
- Cheese
## Other Elements — abbr, sub, sup, kbd, mark
### Syntax
```markdown
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
H<sub>2</sub>O
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
```
### Output
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
H<sub>2</sub>O
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.

View File

@ -1,16 +0,0 @@
---
title: 'Second post'
description: 'Lorem ipsum dolor sit amet'
pubDate: 'Jul 15 2022'
heroImage: '/blog-placeholder-4.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.

View File

@ -1,16 +0,0 @@
---
title: 'Third post'
description: 'Lorem ipsum dolor sit amet'
pubDate: 'Jul 22 2022'
heroImage: '/blog-placeholder-2.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.

View File

@ -1,31 +0,0 @@
---
title: 'Using MDX'
description: 'Lorem ipsum dolor sit amet'
pubDate: 'Jun 01 2024'
heroImage: '/blog-placeholder-5.jpg'
---
This theme comes with the [@astrojs/mdx](https://docs.astro.build/en/guides/integrations-guide/mdx/) integration installed and configured in your `astro.config.mjs` config file. If you prefer not to use MDX, you can disable support by removing the integration from your config file.
## Why MDX?
MDX is a special flavor of Markdown that supports embedded JavaScript & JSX syntax. This unlocks the ability to [mix JavaScript and UI Components into your Markdown content](https://docs.astro.build/en/guides/markdown-content/#mdx-features) for things like interactive charts or alerts.
If you have existing content authored in MDX, this integration will hopefully make migrating to Astro a breeze.
## Example
Here is how you import and use a UI component inside of MDX.
When you open this page in the browser, you should see the clickable button below.
import HeaderLink from '../../components/HeaderLink.astro';
<HeaderLink href="#" onclick="alert('clicked!')">
Embedded component in MDX
</HeaderLink>
## More Links
- [MDX Syntax Documentation](https://mdxjs.com/docs/what-is-mdx)
- [Astro Usage Documentation](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages)
- **Note:** [Client Directives](https://docs.astro.build/en/reference/directives-reference/#client-directives) are still required to create interactive components. Otherwise, all components in your MDX will render as static HTML (no JavaScript) by default.

View File

@ -3,13 +3,16 @@ import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
// Type-check frontmatter using a schema
schema: z.object({
schema: ({image}) => z.object({
title: z.string(),
description: z.string(),
// Transform string to Date object
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: z.string().optional(),
banner: image().optional(),
bannerAlt: z.string().optional(),
cover: image().optional(),
coverAlt: z.string().optional(),
}),
});

View File

@ -4,77 +4,32 @@ import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import FormattedDate from '../components/FormattedDate.astro';
import { Image } from 'astro:assets';
type Props = CollectionEntry<'blog'>['data'];
const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
const { title, pubDate, banner: cover, bannerAlt: coverAlt } = Astro.props;
---
<html lang="en">
<head>
<BaseHead title={title} description={description} />
<style>
main {
width: calc(100% - 2em);
max-width: 100%;
margin: 0;
}
.hero-image {
width: 100%;
}
.hero-image img {
display: block;
margin: 0 auto;
border-radius: 12px;
box-shadow: var(--box-shadow);
}
.prose {
width: 720px;
max-width: calc(100% - 2em);
margin: auto;
padding: 1em;
color: rgb(var(--gray-dark));
}
.title {
margin-bottom: 1em;
padding: 1em 0;
text-align: center;
line-height: 1;
}
.title h1 {
margin: 0 0 0.5em 0;
}
.date {
margin-bottom: 0.5em;
color: rgb(var(--gray));
}
.last-updated-on {
font-style: italic;
}
</style>
<BaseHead title={title} />
</head>
<body>
<Header />
<main>
<article>
<div class="hero-image">
{heroImage && <img width={1020} height={510} src={heroImage} alt="" />}
<div class="cover-box">
{cover && <Image class="cover-image" src={cover} alt={coverAlt || ""} />}
</div>
<div class="prose">
<div class="title">
<div class="date">
<FormattedDate date={pubDate} />
{
updatedDate && (
<div class="last-updated-on">
Last updated on <FormattedDate date={updatedDate} />
</div>
)
}
</div>
<h1>{title}</h1>
<hr />
<span class="hr" />
</div>
<slot />
</div>
@ -82,4 +37,30 @@ const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
</main>
<Footer />
</body>
<style>
.title {
display: flex;
flex-direction: column;
}
.hr {
border-bottom: 1px dotted white;
}
.cover-box {
padding-top: 1em;
}
.cover-image {
border-radius: var(--image-radius);
margin-left: auto;
height: 100%;
width: 100%;
}
</style>
<style is:global>
.prose img {
width: 100%;
height: auto;
}
</style>
</html>

View File

@ -0,0 +1,19 @@
---
import BaseHead from "../components/BaseHead.astro";
import Footer from "../components/Footer.astro";
import Header from "../components/Header.astro";
import { SITE_TITLE } from "../consts";
---
<html lang="en">
<head>
<BaseHead title={SITE_TITLE} />
</head>
<body>
<Header />
<main>
<slot />
</main>
<Footer />
</body>
</html>

View File

@ -4,7 +4,7 @@ import Header from '../../components/Header.astro';
import Footer from '../../components/Footer.astro';
import { SITE_TITLE } from '../../consts';
import { getCollection } from 'astro:content';
import FormattedDate from '../../components/FormattedDate.astro';
import BlogEntry from '../../components/BlogEntry.astro';
const posts = (await getCollection('blog')).sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
@ -14,98 +14,37 @@ const posts = (await getCollection('blog')).sort(
<!doctype html>
<html lang="en">
<head>
<!-- <BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} /> -->
<style>
main {
width: 960px;
}
ul {
display: flex;
flex-wrap: wrap;
gap: 2rem;
list-style-type: none;
margin: 0;
padding: 0;
}
ul li {
width: calc(50% - 1rem);
}
ul li * {
text-decoration: none;
transition: 0.2s ease;
}
ul li:first-child {
width: 100%;
margin-bottom: 1rem;
text-align: center;
}
ul li:first-child img {
width: 100%;
}
ul li:first-child .title {
font-size: 2.369rem;
}
ul li img {
margin-bottom: 0.5rem;
border-radius: 12px;
}
ul li a {
display: block;
}
.title {
margin: 0;
color: rgb(var(--black));
line-height: 1;
}
.date {
margin: 0;
color: rgb(var(--gray));
}
ul li a:hover h4,
ul li a:hover .date {
color: rgb(var(--accent));
}
ul a:hover img {
box-shadow: var(--box-shadow);
}
@media (max-width: 720px) {
ul {
gap: 0.5em;
}
ul li {
width: 100%;
text-align: center;
}
ul li:first-child {
margin-bottom: 0;
}
ul li:first-child .title {
font-size: 1.563em;
}
}
</style>
</head>
<BaseHead title={SITE_TITLE} />
<body>
<Header />
<main>
<section>
<ul>
{
posts.map((post) => (
<li>
<a href={`/blog/${post.slug}/`}>
<img width={720} height={360} src={post.data.heroImage} alt="" />
<h4 class="title">{post.data.title}</h4>
<p class="date">
<FormattedDate date={post.data.pubDate} />
</p>
</a>
</li>
))
}
</ul>
</section>
<h1>Posts</h1>
<!-- <ul class="blog-posts"> -->
{
posts.map((post, index) => (
<BlogEntry post={post} showSeparator={index < posts.length - 1}></BlogEntry>
))
}
<!-- </ul> -->
</main>
<Footer />
</body>
</html>
<style>
main {
all: unset;
width: 40vw;
}
.blog-entry:not(:last-child) {
border-bottom: 1px solid rgb(var(--gray-light));
}
@media only screen and (max-width: 768px) {
/* For mobile phones: */
main {
min-width: 100%;
}
}
}
</style>

View File

@ -1,50 +0,0 @@
---
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
---
<!doctype html>
<html lang="en">
<head>
<BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
</head>
<body>
<Header />
<main>
<h1>🧑‍🚀 Hello, Astronaut!</h1>
<p>
Welcome to the official <a href="https://astro.build/">Astro</a> blog starter template. This
template serves as a lightweight, minimally-styled starting point for anyone looking to build
a personal website, blog, or portfolio with Astro.
</p>
<p>
This template comes with a few integrations already configured in your
<code>astro.config.mjs</code> file. You can customize your setup with
<a href="https://astro.build/integrations">Astro Integrations</a> to add tools like Tailwind,
React, or Vue to your project.
</p>
<p>Here are a few ideas on how to get started with the template:</p>
<ul>
<li>Edit this page in <code>src/pages/index.astro</code></li>
<li>Edit the site header items in <code>src/components/Header.astro</code></li>
<li>Add your name to the footer in <code>src/components/Footer.astro</code></li>
<li>Check out the included blog posts in <code>src/content/blog/</code></li>
<li>Customize the blog post page layout in <code>src/layouts/BlogPost.astro</code></li>
</ul>
<p>
Have fun! If you get stuck, remember to <a href="https://docs.astro.build/"
>read the docs
</a> or <a href="https://astro.build/chat">join us on Discord</a> to ask questions.
</p>
<p>
Looking for a blog template with a bit more personality? Check out <a
href="https://github.com/Charca/astro-blog-template"
>astro-blog-template
</a> by <a href="https://twitter.com/Charca">Maxi Ferreira</a>.
</p>
</main>
<Footer />
</body>
</html>

19
src/pages/index.mdx Normal file
View File

@ -0,0 +1,19 @@
---
layout: '../layouts/DefaultLayout.astro'
---
# <img src="earth.gif" width="33px"/> Hello, World!
My name is Denis Davydov. I am software engineer. This is my personal website, where I blog about things (tech included), share my experience, and more!
## Contacts
- <img src="email.svg" width="20px"/> **Email**: `pigeon.catcher [at] antiope [dot] link`
- <img src="github.svg" width="20px"/> **GitHub**: [@ChronosXYZ](https://github.com/ChronosXYZ)
- <img src="telegram.svg" width="20px"/> **Telegram**: [@und3f1n3d0](https://t.me/und3f1n3d0)
- <img src="discord.svg" width="20px"/> **Discord**: [@chronosxyz](https://discordapp.com/users/612009225681371136)
- <img src="matrix.svg" width="20px"/> **Matrix**: [@chronosxyz:tchncs.de](https://matrix.to/#/@chronosxyz:tchncs.de)
- <img src="xmpp.svg" width="20px"/> **XMPP**: [chronosx88@antiope.link](xmpp:chronosx88@antiope.link)
- <img src="mastodon.svg" width="20px"/> **Mastodon**: [@ChronosX88@lor.sh](https://lor.sh/@ChronosX88)
- <img src="instagram.svg" width="20px"/> **Instagram**: [@pigeon.catcher](https://instagram.com/pigeon.catcher)
- <img src="linkedin.svg" width="20px"/> **LinkedIn**: [@pigeoncatcher](https://linkedin.com/in/pigeoncatcher)

View File

@ -1,13 +1,13 @@
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
import { SITE_TITLE } from '../consts';
export async function GET(context) {
const posts = await getCollection('blog');
return rss({
title: SITE_TITLE,
description: SITE_DESCRIPTION,
site: context.site,
description: '',
items: posts.map((post) => ({
...post.data,
link: `/blog/${post.slug}/`,

View File

@ -1,5 +1,6 @@
:root {
--accent-color: #efefef;
--image-radius: 7px;
}
body {
@ -44,18 +45,30 @@ main {
max-width: 67%;
}
/* img {
width: 100%;
height: auto;
} */
.blog-posts {
list-style-type: none;
padding: unset;
li {
display: flex;
padding-bottom: 4px;
padding-top: 2px;
/* padding-bottom: 4px; */
/* padding-top: 2px; */
flex-direction: column;
span {
/* span {
flex: 0 0 115px
}
} */
}
li:not(:last-child) {
padding: 1em 0 1em;
border-bottom: 1px dotted white;
}
}