13 Commits

Author SHA1 Message Date
35aa3b076f add iocaine blog post 2025-08-25 21:26:10 +00:00
2e397c5be3 finish blog
 add first blog entry
🎨 rework ui+ux
 add freemono
2025-08-24 03:46:08 +00:00
f1c471839f readd btns
🐛 fixed some blog stuff
2025-08-21 02:19:36 +00:00
bfd8c187c6 🔥 rm bulma
 rework ui+ux
 update shader
 update profile.avif
 update 404
2025-08-20 08:38:03 +00:00
510897d94b push changes 2025-08-14 15:19:35 +02:00
078634b664 sloppy blog impl from example 2025-08-10 18:28:27 +02:00
6a5176caab 🐛 fix layout
🍱 update 88x31s
🔥 rm landing
2025-08-07 02:27:39 +02:00
i0uring
282c67b1fc update bg.frag 2025-07-30 15:24:38 +02:00
74224bd648 🐛 fix btn sizes 2025-05-08 22:12:02 +02:00
8f217ec82b 🐛 fix scrollbar
🔥 rm disclaimer in footer
2025-05-08 00:19:54 +02:00
0e1055b1a6 📝 change text
 add buttons
🔥 rm socials
2025-05-07 05:31:46 +02:00
94c56d7405 update justfile
🐛 fix theming
📝 change some wording
2025-04-23 21:23:33 +02:00
Lucielle Rosalia Hoerner
0a203fdb65 Merge pull request 'rust rewrite' (#4) from rewrite/rust into develop
Reviewed-on: https://git.gay/luciel/web_luciel/pulls/4
2025-03-19 01:07:42 +00:00
48 changed files with 1567 additions and 643 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ dist/
pkg/ pkg/
target/ target/
Cargo.lock Cargo.lock
static/

View File

@@ -1,29 +1,37 @@
[package] [package]
name = "web_luciel" name = "web_iouring"
version = "0.0.0-develop" version = "0.0.0-develop"
authors = ["luciel"] authors = ["iouring"]
license = "Apache-2.0" license = "Apache-2.0"
edition = "2024" edition = "2024"
rust-version = "1.85" rust-version = "1.91"
publish = false publish = false
[dependencies] [dependencies]
js-sys = "0.3" js-sys = "0.3"
yew = { git = "https://github.com/yewstack/yew.git", rev = "910efcc", features = ["csr"] } yew = { git = "https://github.com/yewstack/yew.git", rev = "21f373b", features = [
yew-router = { git = "https://github.com/yewstack/yew.git", rev = "910efcc" } "csr",
] }
yew-router = { git = "https://github.com/yewstack/yew.git", rev = "21f373b" }
wasm-bindgen = { version = "0.2" } wasm-bindgen = { version = "0.2" }
log = { version = "0.4" } log = { version = "0.4" }
wasm-logger = { version = "0.2" } wasm-logger = { version = "0.2" }
serde = { version = "1.0" }
wasm-bindgen-futures = "0.4.50"
serde_json = "1.0.143"
lsp-types = "0.97"
chrono = "0.4"
yew-markdown = { git = "https://git.celesteflare.cc/i0uring/page_md.git", rev = "1e9840" }
yew-hooks = "0.3"
[patch.crates-io]
yew = { git = "https://github.com/yewstack/yew.git", rev = "21f373b", features = [
"csr",
], optional = false }
[dependencies.web-sys] [dependencies.web-sys]
version = "0.3" version = "0.3"
features = [ features = ["HtmlCanvasElement", "WebGlBuffer", "WebGlProgram", "WebGlRenderingContext", "WebGl2RenderingContext", "WebGlShader", "WebGlUniformLocation", "Navigator", "Clipboard"]
'HtmlCanvasElement',
'WebGlBuffer',
'WebGlProgram',
'WebGlRenderingContext',
'WebGl2RenderingContext',
'WebGlShader',
'WebGlUniformLocation',
]

View File

@@ -1,6 +0,0 @@
version: '3'
services:
web:
build: ./
ports:
- "8080:8080"

View File

@@ -1,31 +1,41 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" /> <meta content="width=device-width, initial-scale=1.0" name="viewport" />
<title>celesteflare.cc ~ lunary</title> <title>i0ur.ing ~ welcome</title>
<link data-trunk rel="copy-file" href="public/misc/favicon.ico" /> <link data-trunk rel="copy-file" href="public/misc/favicon.ico" />
<link data-trunk rel="copy-file" href="public/misc/404.png" />
<link data-trunk rel="copy-file" href="public/misc/profile.avif" /> <link data-trunk rel="copy-file" href="public/misc/profile.avif" />
<link data-trunk rel="copy-file" href="public/misc/oneko.gif" /> <link data-trunk rel="copy-file" href="public/misc/oneko.gif" />
<link data-trunk rel="copy-file" href="public/misc/freemono.ttf" />
<link data-trunk rel="copy-file" href="public/misc/monocraft.ttf" /> <link data-trunk rel="copy-file" href="public/misc/monocraft.ttf" />
<link data-trunk rel="copy-file" href="public/blog/testimage.jpg" />
<link data-trunk rel="copy-file" href="public/shaders/post.bloom.svg" /> <link data-trunk rel="copy-file" href="public/shaders/post.bloom.svg" />
<link data-trunk rel="copy-file" href="public/buttons/luciel.png"/> <link data-trunk rel="copy-file" href="public/buttons/iouring.png" />
<link data-trunk rel="copy-file" href="public/buttons/servfail.png"/>
<link data-trunk rel="copy-file" href="public/buttons/wasm.png" /> <link data-trunk rel="copy-file" href="public/buttons/wasm.png" />
<link data-trunk rel="copy-file" href="public/buttons/dataforest.png" />
<link data-trunk rel="copy-file" href="public/buttons/servfail.png" />
<link data-trunk rel="copy-file" href="public/buttons/rust.png" /> <link data-trunk rel="copy-file" href="public/buttons/rust.png" />
<link data-trunk rel="copy-file" href="public/buttons/csharp.png" />
<link data-trunk rel="copy-file" href="public/buttons/kotlin.png" />
<link data-trunk rel="copy-file" href="public/buttons/java.png" />
<link data-trunk rel="copy-file" href="public/buttons/fedora.png" /> <link data-trunk rel="copy-file" href="public/buttons/fedora.png" />
<link data-trunk rel="copy-file" href="public/buttons/artix.png" />
<link data-trunk rel="copy-file" href="public/socials/fedi.svg"/> <link data-trunk rel="copy-file" href="public/buttons/nixos.png" />
<link data-trunk rel="copy-file" href="public/socials/git.svg"/> <link data-trunk rel="copy-file" href="public/buttons/chimera.png" />
<link data-trunk rel="copy-file" href="public/socials/lastfm.svg"/> <link data-trunk rel="copy-file" href="public/buttons/void.png" />
<link data-trunk rel="copy-file" href="public/buttons/aqueer.png" />
<link data-trunk rel="sass" href="main.scss" /> <link data-trunk rel="sass" href="main.scss" />
<link data-trunk rel="rust" /> <link data-trunk rel="rust" />
<base data-trunk-public-url /> <base data-trunk-public-url />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma/css/bulma.min.css"/>
</head> </head>
</html> </html>

View File

@@ -1,25 +1,13 @@
#!/usr/bin/env just --justfile #!/usr/bin/env just --justfile
install-wasm-pack: setup:
cargo install wasm-pack rustup target add wasm32-unknown-unknown
install-tauri: install:
cargo install tauri-cli cargo install --locked wasm-pack trunk --force
trunk-serve: debug:
trunk serve trunk serve
build: build:
trunk build trunk build --release
tauri-dev:
cargo tauri dev
tauri-build:
cargo tauri build
create-yew-app:
npx create-yew-app web_luciel
serve-app:
cd web_luciel && trunk serve

View File

@@ -1,46 +1,49 @@
@charset "UTF-8";
@font-face {
font-family: freemono;
src: url("freemono.ttf");
}
@font-face { @font-face {
font-family: monocraft; font-family: monocraft;
src: url("monocraft.ttf"); src: url("monocraft.ttf");
} }
html * { html * {
font-family: monocraft, monospace !important; font-family: freemono, monocraft, monospace !important;
scrollbar-color: hsla(232, 97%, 85%, 0.5) hsla(240, 21.05%, 14.9%, 0.7) !important;
scrollbar-width: thin !important;
scroll-behavior: smooth !important;
}
::-webkit-scrollbar {
display: none;
}
.textarea {
-ms-overflow-style: none !important;
scrollbar-width: none !important;
}
.textarea::-webkit-scrollbar {
display: none !important;
} }
.box { .box {
backdrop-filter: blur(4px) !important; backdrop-filter: blur(4px) !important;
--bulma-box-background-color: #1E1E2E80 !important;
--bulma-shadow-h: 232 !important;
--bulma-shadow-s: 97% !important;
--bulma-shadow-l: 85% !important;
--bulma-shadow: 0 0.5em 1em -0.125em hsla(
var(--bulma-shadow-h),
var(--bulma-shadow-s),
var(--bulma-shadow-l),
0.3
), 0 0px 0 1px hsla(
var(--bulma-shadow-h),
var(--bulma-shadow-s),
var(--bulma-shadow-l),
0.02
) !important;
} }
.input, .select select, .textarea { .card {
backdrop-filter: blur(4px) !important;
}
.input,
.select select,
.textarea {
backdrop-filter: blur(4px); backdrop-filter: blur(4px);
--bulma-input-h: 232 !important; background-color: white, 0.213125 !important;
--bulma-input-s: 97% !important; border-color: white !important;
--bulma-input-l: 85% !important;
--bulma-input-background-h: var(--bulma-input-h) !important;
--bulma-input-background-s: var(--bulma-input-s) !important;
--bulma-input-background-l: var(--bulma-input-l) !important;
background-color: hsla(
var(--bulma-input-h),
var(--bulma-input-s),
var(--bulma-input-background-l),
0.213125
) !important;
border-color: hsl(var(--bulma-input-h), var(--bulma-input-s), var(--bulma-input-l)) !important;
} }
a.navbar-item, a.navbar-item,
@@ -49,14 +52,30 @@ a.navbar-item:hover {
} }
::-moz-selection { ::-moz-selection {
background: hsla(232, 97%, 85%, 0.4125) !important; background: #F5C2E740 !important;
} }
::selection { ::selection {
background: hsla(232, 97%, 85%, 0.4125) !important; background: #F5C2E740 !important;
}
a {
color: #F5C2E7FF !important;
text-decoration: none !important;
} }
a:hover { a:hover {
text-decoration: underline; text-decoration: underline !important;
filter: url("post.bloom.svg#process") filter: url("post.bloom.svg#process") !important;
}
button {
background-color: transparent !important;
border-color: transparent !important;
color: white !important;
}
button:hover {
text-decoration: underline !important;
filter: url("post.bloom.svg#process") !important;
} }

BIN
public/blog/testimage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

BIN
public/buttons/aqueer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
public/buttons/artix.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/buttons/chimera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/buttons/csharp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/buttons/iouring.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/buttons/java.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/buttons/kotlin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

BIN
public/buttons/nixos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
public/buttons/void.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/misc/404.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/misc/freemono.ttf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 224 KiB

View File

@@ -1,11 +1,9 @@
#version 300 es #version 300 es
precision lowp float; precision highp float;
const float CAM_FAR = 20.0; const float CAM_FAR = 20.0;
const vec3 BACKGROUND = vec3(0.0, 0.0, 0.0); const vec3 BACKGROUND = vec3(0.0, 0.0, 0.0);
const float PI = radians(180.0);
uniform float time; uniform float time;
uniform vec2 resolution; uniform vec2 resolution;
uniform bool layer_snow; uniform bool layer_snow;
@@ -19,48 +17,42 @@ vec3 artifactAxis;
vec3 camFwd; vec3 camFwd;
vec3 camUp; vec3 camUp;
float smootherstep(float edge0, float edge1, float x) {
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
}
float rand(float n) { float rand(float n) {
n = fract(n * 43758.5453); return fract(sin(n) * 43758.5453);
n *= n;
return fract(n * 43758.5453);
}
float hash(float n) {
return fract(abs(fract(n) * 43758.5453));
} }
float noise(float x) { float noise(float x) {
float i = floor(x); float i = floor(x);
float f = fract(x); float f = fract(x);
float u = f * f * (3.0 - 2.0 * f); return mix(rand(i), rand(i + 1.0), f * f * (3.0 - 2.0 * f));
return mix(hash(i), hash(i + 1.0), u);
} }
mat4 viewMatrix(vec3 dir, vec3 up) { mat4 viewMatrix(vec3 dir, vec3 up) {
vec3 f = normalize(dir); vec3 f = normalize(dir);
vec3 s = normalize(cross(f, up)); vec3 s = normalize(cross(f, up));
return mat4(vec4(s, 0.0), vec4(cross(s, f), 0.0), vec4(-f, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); vec3 u = cross(s, f);
return mat4(
vec4(s, 0.0),
vec4(u, 0.0),
vec4(-f, 0.0),
vec4(0.0, 0.0, 0.0, 1.0)
);
} }
mat3 rotationAlign(vec3 d, vec3 z) { mat3 rotationAlign(vec3 d, vec3 z) {
vec3 v = cross(z, d); vec3 v = cross(z, d);
float c = dot(z, d); float c = dot(z, d);
float k = 1.0 / (1.0 + c); float k = 1.0 / (1.0 + c);
float k_vx = v.x * k;
float k_vy = v.y * k;
float k_vz = v.z * k;
return mat3( return mat3(
v.x * v.x * k + c, k_vx * v.x + c, k_vx * v.y - v.z, k_vx * v.z + v.y,
v.y * v.x * k - v.z, k_vy * v.x + v.z, k_vy * v.y + c, k_vy * v.z - v.x,
v.z * v.x * k + v.y, k_vz * v.x - v.y, k_vz * v.y + v.x, k_vz * v.z + c
v.x * v.y * k + v.z,
v.y * v.y * k + c,
v.z * v.y * k - v.x,
v.x * v.z * k - v.y,
v.y * v.z * k + v.x,
v.z * v.z * k + c
); );
} }
@@ -74,48 +66,10 @@ vec3 calcRay(vec2 uv, float fov, float aspect) {
return normalize(vec3(aspect * uv.x, uv.y, d)); return normalize(vec3(aspect * uv.x, uv.y, d));
} }
vec2 getWave(vec2 position, vec2 dir, float speed, float frequency, float iTimeshift) {
float x = dot(dir, position) * frequency + iTimeshift * speed;
float wave = exp(sin(x) - 1.0);
float dist = wave * cos(x);
return vec2(wave, -dist);
}
float heightmap(vec2 worldPos) {
const float scale = 0.06;
vec2 p = worldPos * scale;
vec2 p2 = (artifactOffset.xz - vec2(0.0, 1.0)) * scale;
float d = (1.0 - smootherstep(0.0, 1.0, clamp(length(p2 - p) * 1.25, 0.0, 1.0))) * 0.87;
float angle = 0.0;
float freq = 5.0;
float speed = 2.0;
float weight = 1.9;
float wave = 0.0;
float waveScale = 0.0;
vec2 dir;
vec2 res;
for (int i = 0; i < 5; i++) {
dir = vec2(cos(angle), sin(angle));
res = getWave(p, dir, speed, freq, time);
p += dir * res.y * weight * 0.05;
wave += res.x * weight - d;
angle += 12.0;
waveScale += weight;
weight = mix(weight, 0.0, 0.2);
freq *= 1.18;
speed *= 1.06;
}
return wave * (1.0 / waveScale);
}
float octahedron(vec3 p, float s) { float octahedron(vec3 p, float s) {
const float factor = 0.57735027;
p = abs(p); p = abs(p);
return (p.x + p.y + p.z - s) * 0.57735027; return (p.x + p.y + p.z - s) * factor;
} }
void artifact(vec3 p, inout float currDist, inout vec3 glowColor, inout int id) { void artifact(vec3 p, inout float currDist, inout vec3 glowColor, inout int id) {
@@ -145,10 +99,6 @@ float artifactDist(vec3 p) {
return octahedron(p, 1.2); return octahedron(p, 1.2);
} }
float objectsDist(vec3 p) {
return artifactDist(p);
}
vec3 objectsNormal(vec3 p, float eps) { vec3 objectsNormal(vec3 p, float eps) {
vec2 h = vec2(eps, 0); vec2 h = vec2(eps, 0);
return normalize(vec3(artifactDist(p + h.xyy) - artifactDist(p - h.xyy), eps * 2.0, artifactDist(p + h.yyx) - artifactDist(p - h.yyx))); return normalize(vec3(artifactDist(p + h.xyy) - artifactDist(p - h.xyy), eps * 2.0, artifactDist(p + h.yyx) - artifactDist(p - h.yyx)));
@@ -174,96 +124,41 @@ void marchObjects(vec3 eye, vec3 ray, float wDepth, inout vec4 color) {
color = dist < 0.01 ? vec4(objectsColor(id, objectsNormal(rayPos, 0.01), ray), depth) : color; color = dist < 0.01 ? vec4(objectsColor(id, objectsNormal(rayPos, 0.01), ray), depth) : color;
} }
vec3 waterColor(vec3 ray, vec3 normal, vec3 p) {
vec3 color = vec3(0.0);
float fogDist = length(p - vec3(0.0, 0.0, -6.0));
float dist = 0.0;
int objId = 0;
vec3 refl = reflect(ray, normal);
vec3 rayPos = p + refl * dist;
if (length(p.xz - artifactOffset.xz) < 8.5 && dot(refl, normalize(artifactOffset - p)) > -0.25) {
for (int i = 0; i < 40; i++) {
dist = objects(rayPos, color, objId);
if (dist < 0.01) {
color = objectsColor(objId, objectsNormal(rayPos, 0.001), rayPos);
break;
}
rayPos += refl * dist;
}
}
float fresnel = 0.04 + 0.9 * pow(1.0 - max(0.0, dot(-normal, ray)), 7.0);
float d = length(artifactOffset - p);
const float r = 14.0;
float atten = clamp(1.0 - (d * d) / (r * r), 0.0, 1.0);
atten *= atten;
vec3 point = vec3(0.75, 0.55, 0.45) * atten * (1.0 + fresnel) * 0.07;
vec3 ambient = dot(normal, normalize(vec3(0.0, 1.0, 0.5))) * max(fresnel, 0.06) * vec3(0.1, 0.5, 1.0) * 0.85;
float fog = smootherstep(25.0, 6.0, fogDist) * (1.0 / (fogDist * 0.1));
return color + (point + ambient) * fog;
}
vec3 waterNormal(vec2 p, float eps) {
vec2 h = vec2(eps, 0.0);
return normalize(vec3(heightmap(p - h.xy) - heightmap(p + h.xy), eps * 2.0, heightmap(p - h.yx) - heightmap(p + h.yx)));
}
void marchWater(vec3 eye, vec3 ray, inout vec4 color) {
const vec3 planeNorm = vec3(0.0, 1.0, 0.0);
const float depth = 3.0;
float ceilDist = intersectPlane(eye, ray, vec3(0.0, 0.0, 0.0), planeNorm);
vec3 normal = vec3(0.0);
if (dot(planeNorm, ray) > -0.05) {
color = vec4(vec3(0.0), CAM_FAR);
return;
}
float height = 0.0;
vec3 rayPos = eye + ray * ceilDist;
for (int i = 0; i < 30; i++) {
height = heightmap(rayPos.xz) * depth - depth;
if (rayPos.y - height < 0.1) {
color.w = distance(rayPos, eye);
vec3 normPos = (eye + ray * color.w);
color.rgb = waterColor(ray, waterNormal(normPos.xz, 0.005), normPos);
return;
}
rayPos += ray * max(rayPos.y - height, 0.1);
}
color = vec4(vec3(0.0), CAM_FAR);
}
vec3 march(vec2 uv, vec3 camPos) { vec3 march(vec2 uv, vec3 camPos) {
mat4 vm = viewMatrix(camFwd, camUp); mat4 vm = viewMatrix(camFwd, camUp);
vec3 ray = (vm * vec4(calcRay(uv, 80.0, resolution.x / resolution.y), 1.0)).xyz; vec3 ray = (vm * vec4(calcRay(uv, 80.0, resolution.x / resolution.y), 1.0)).xyz;
vec4 color = vec4(BACKGROUND, CAM_FAR); vec4 color = vec4(BACKGROUND, CAM_FAR);
vec3 waterColor;
marchWater(camPos, ray, color);
marchObjects(camPos, ray, color.w, color); marchObjects(camPos, ray, color.w, color);
return color.rgb; return color.rgb;
} }
float snow(vec2 uv, float scale) { float snow(vec2 uv, float scale) {
float w = smootherstep(1.0, 0.0, -uv.y * (scale * 0.01)); float w = smoothstep(1.0, 0.0, -uv.y * (scale * 0.01));
if (w < 0.1) return 0.0; if (w < 0.1) return 0.0;
uv += time / scale;
uv.y += time / scale; float timeScale = time / scale;
uv += vec2(timeScale, timeScale);
uv.x += sin(uv.y + time * 0.125) / scale; uv.x += sin(uv.y + time * 0.125) / scale;
uv *= scale; uv *= scale;
vec2 s = floor(uv), f = fract(uv);
return smootherstep(0.0, min(length(0.5 + 0.5 * sin(11.0 * fract(sin((s + scale) * mat2(7.0, 3.0, 6.0, 5.0)) * 5.0)) - f), 3.0), sin(f.x + f.y) * 0.01) * w; vec2 s = floor(uv);
vec2 f = fract(uv);
float sinValueX = sin((s.x + scale) * 7.0) * 5.0;
float sinValueY = sin((s.y + scale) * 5.0) * 5.0;
float combinedSinValue = sinValueX + sinValueY;
float lengthValue = length(0.5 + 0.5 * sin(11.0 * fract(combinedSinValue)) - f);
return smoothstep(0.0, min(lengthValue, 3.0), sin(f.x + f.y) * 0.01) * w;
} }
void mainImage(out vec4 fragColor, in vec2 fragCoord) { void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord * (vec2(1.0) / resolution.xy); vec2 uv = fragCoord / resolution.xy;
float s = sin(time); float s = sin(time);
float c = cos(time); float c = cos(time);
artifactRotation = mat3(c, 0, s, 0, 1, 0, -s, 0, c) * rotationAlign(vec3(0.0, 1.0, 0.0), vec3(s * 0.2, 1.0, c * 0.2 + 0.3)); artifactRotation = mat3(c, 0, s, 0, 1, 0, -s, 0, c) * rotationAlign(vec3(0.0, 1.0, 0.0), vec3(s * 0.2, 1.0, c * 0.2 + 0.3));
artifactOffset = vec3(s * 0.4, c * 0.3 - 1.7, -6.0); artifactOffset = vec3(s * 0.4, c * 0.3 - 1.7, -6.0);
@@ -273,9 +168,8 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) {
fragColor = vec4(march(uv, vec3(0.0, 1.9, 1.0)) - (length(uv - 0.5) - 0.3) * 0.05, 1.0); fragColor = vec4(march(uv, vec3(0.0, 1.9, 1.0)) - (length(uv - 0.5) - 0.3) * 0.05, 1.0);
if (layer_snow) { if (layer_snow) {
vec2 p = fragCoord.xy / resolution.xy; vec2 uvSnow = (fragCoord * 2.0 - resolution.xy) / min(resolution.x, resolution.y);
vec2 uvSnow = (fragCoord.xy * 2.0 - resolution.xy) / min(resolution.x, resolution.y); fragColor += vec4(vec3(snow(uvSnow, 4.0)), 0.5) * 0.7;
fragColor += mix(vec4(vec3(snow(uvSnow, 4.0)), 0.5) + vec4(vec3(snow(uvSnow, 3.0)), 0.5), vec4(0.0), vec4(0.7));
} }
} }

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="196.52mm" height="196.52mm" viewBox="0 0 196.52 196.52" version="1.1" id="svg8" inkscape:version="0.92.2 2405546, 2018-03-11" sodipodi:docname="Logo_penta_connectat-imbrincat_BiN.svg" inkscape:export-filename="/home/nestor/Pictures/Fediversal/Logo_penta_connectat-imbrincat_mono-512x.png" inkscape:export-xdpi="66.175453" inkscape:export-ydpi="66.175453">
<defs id="defs2"/>
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.35646619" inkscape:cx="-324.56885" inkscape:cy="378.80956" inkscape:document-units="mm" inkscape:current-layer="layer2" showgrid="false" inkscape:snap-smooth-nodes="true" inkscape:snap-midpoints="true" inkscape:snap-global="false" inkscape:window-width="1366" inkscape:window-height="736" inkscape:window-x="0" inkscape:window-y="32" inkscape:window-maximized="1" fit-margin-top="5" fit-margin-left="5" fit-margin-right="5" fit-margin-bottom="5"/>
<metadata id="metadata5">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g inkscape:label="Hexagons" inkscape:groupmode="layer" id="layer1" style="display:none" transform="translate(6.6789703,-32.495842)">
<circle style="fill:#00a3ff;fill-opacity:0.99596773;fill-rule:nonzero;stroke:#d79611;stroke-width:11;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="path830" cx="91.581032" cy="130.75584" r="87.760002"/>
<path sodipodi:type="star" style="display:inline;fill:#0000d4;fill-opacity:1;fill-rule:nonzero;stroke:#4b4b40;stroke-width:9.88948536;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="path1669" sodipodi:sides="5" sodipodi:cx="103.97202" sodipodi:cy="134.41467" sodipodi:r1="98.801643" sodipodi:r2="79.932205" sodipodi:arg1="1.0471976" sodipodi:arg2="1.6755161" inkscape:flatsided="true" inkscape:rounded="0" inkscape:randomized="0" d="M 153.37284,219.97941 37.860816,207.8386 13.712232,94.22842 114.29961,36.154276 l 86.315,77.718384 z" inkscape:transform-center-x="-2.409305" inkscape:transform-center-y="-4.7910078" transform="matrix(0.75493711,0,0,0.75474706,13.251553,29.556024)"/>
</g>
<g inkscape:groupmode="layer" id="layer4" inkscape:label="Linies_originals" style="display:none">
<path transform="translate(6.6789702,-32.495842)" sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path1690" d="M 165.18127,119.35405 38.636939,183.48684" style="display:inline;fill:none;stroke:#5496be;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
<path transform="translate(6.6789702,-32.495842)" style="display:inline;fill:none;stroke:#a730b8;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 25.096981,96.875251 125.21379,197.3795" id="path1684" inkscape:connector-curvature="0" sodipodi:nodetypes="cc"/>
<path transform="translate(6.6789702,-32.495842)" sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path1686" d="M 38.636939,183.48684 103.30568,57.239007" style="display:inline;fill:none;stroke:#ce3d1a;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
<path transform="translate(6.6789702,-32.495842)" style="display:inline;fill:none;stroke:#46ae3a;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 125.21379,197.3795 103.30568,57.239007" id="path1688" inkscape:connector-curvature="0" sodipodi:nodetypes="cc"/>
<path transform="translate(6.6789702,-32.495842)" sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path1682" d="m 25.096981,106.16365 140.084289,22.4788" style="display:inline;fill:none;stroke:#d79611;stroke-width:11;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
</g>
<g inkscape:groupmode="layer" id="layer2" inkscape:label="Linies" style="display:inline" transform="translate(6.6789703,-32.495842)">
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 181.13086 275.13672 A 68.892408 68.892408 0 0 1 151.66602 304.46484 L 313.42383 466.85352 L 352.42188 447.08984 L 181.13086 275.13672 z M 394.49414 489.32422 L 355.49609 509.08789 L 437.45898 591.37109 A 68.892409 68.892409 0 0 1 466.92969 562.03906 L 394.49414 489.32422 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9722"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 581.64648 339.39062 L 490.07031 385.80078 L 496.82227 428.99023 L 600.4375 376.47656 A 68.892409 68.892409 0 0 1 581.64648 339.39062 z M 436.9082 412.74219 L 220.38281 522.47656 A 68.892408 68.892408 0 0 1 239.17773 559.56641 L 443.66016 455.93359 L 436.9082 412.74219 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9729"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 367.27539 142.4375 L 262.79492 346.4082 L 293.64258 377.375 L 404.26562 161.41797 A 68.892408 68.892408 0 0 1 367.27539 142.4375 z M 235.62109 399.45898 L 182.69922 502.77344 A 68.892409 68.892409 0 0 1 219.68555 521.75195 L 266.4668 430.42383 L 235.62109 399.45898 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9713"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 150.76758 304.91797 A 68.892408 68.892408 0 0 1 116.35156 312.11328 A 68.892408 68.892408 0 0 1 109.70117 311.41797 L 140.60352 509.08008 A 68.892409 68.892409 0 0 1 175.01953 501.88477 A 68.892409 68.892409 0 0 1 181.66602 502.58008 L 150.76758 304.91797 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1015"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 239.3418 560.54492 A 68.892408 68.892408 0 0 1 240.0625 574.42188 A 68.892408 68.892408 0 0 1 232.79492 601.60156 L 430.42383 633.31445 A 68.892409 68.892409 0 0 1 429.70117 619.43555 A 68.892409 68.892409 0 0 1 436.9707 592.25781 L 239.3418 560.54492 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1674"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 601.13281 377.19922 L 509.91406 555.28125 A 68.892408 68.892408 0 0 1 546.9082 574.26367 L 638.125 396.18359 A 68.892409 68.892409 0 0 1 601.13281 377.19922 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1676"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 476.72266 125.33008 A 68.892408 68.892408 0 0 1 447.25195 154.66211 L 588.51758 296.47266 A 68.892409 68.892409 0 0 1 617.98633 267.14062 L 476.72266 125.33008 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1678"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 347.78711 104.63086 L 169.21094 195.12891 A 68.892409 68.892409 0 0 1 188.00391 232.21484 L 366.57812 141.71289 A 68.892408 68.892408 0 0 1 347.78711 104.63086 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path1680"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 446.92578 154.82617 A 68.892408 68.892408 0 0 1 411.94336 162.30859 A 68.892408 68.892408 0 0 1 405.91406 161.67578 L 421.73242 262.9668 L 464.89453 269.89258 L 446.92578 154.82617 z M 430.92578 321.85352 L 468.32617 561.33594 A 68.892409 68.892409 0 0 1 502.24023 554.39258 A 68.892409 68.892409 0 0 1 509.44727 555.18359 L 474.08984 328.77734 L 430.92578 321.85352 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9758"/>
<path style="color:#ffffff;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#ffffff;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#ffffff;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:41.5748024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 188.13086 232.97461 A 68.892408 68.892408 0 0 1 188.88867 247.07031 A 68.892408 68.892408 0 0 1 181.72852 274.05273 L 283.09766 290.33398 L 303.02148 251.42578 L 188.13086 232.97461 z M 361.86719 260.875 L 341.94141 299.78711 L 581.45508 338.25391 A 68.892409 68.892409 0 0 1 580.75977 324.53516 A 68.892409 68.892409 0 0 1 588.10938 297.21094 L 361.86719 260.875 z " transform="matrix(0.26458333,0,0,0.26458333,-6.6789703,32.495842)" id="path9760"/>
</g>
<g inkscape:groupmode="layer" id="layer3" inkscape:label="Nodes" style="display:inline;opacity:1" transform="translate(6.6789703,-32.495842)">
<circle style="fill:#ffffff;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" id="path817" cx="106.26596" cy="51.535553" r="16.570711" transform="rotate(3.1178174)"/>
<circle id="path819" style="fill:#ffffff;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" cx="171.42836" cy="110.19328" r="16.570711" transform="rotate(3.1178174)"/>
<circle id="path823" style="fill:#ffffff;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" cx="135.76379" cy="190.27704" r="16.570711" transform="rotate(3.1178174)"/>
<circle style="fill:#ffffff;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" id="path825" cx="48.559471" cy="181.1138" r="16.570711" transform="rotate(3.1178174)"/>
<circle id="path827" style="fill:#ffffff;fill-opacity:0.99596773;stroke:none;stroke-width:0.26458332;stroke-opacity:0.96078431" cx="30.328812" cy="95.366837" r="16.570711" transform="rotate(3.1178174)"/>
</g>
<script xmlns=""/></svg>

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="92pt" height="92pt" viewBox="0 0 92 92"><script xmlns=""/><defs><clipPath id="a"><path d="M0 .113h91.887V92H0Zm0 0"/></clipPath></defs><g clip-path="url(#a)"><path style="stroke:none;fill-rule:nonzero;fill:#fff;fill-opacity:1" d="M90.156 41.965 50.036 1.848a5.918 5.918 0 0 0-8.372 0l-8.328 8.332 10.566 10.566a7.03 7.03 0 0 1 7.23 1.684 7.034 7.034 0 0 1 1.669 7.277l10.187 10.184a7.028 7.028 0 0 1 7.278 1.672 7.04 7.04 0 0 1 0 9.957 7.05 7.05 0 0 1-9.965 0 7.044 7.044 0 0 1-1.528-7.66l-9.5-9.497V59.36a7.04 7.04 0 0 1 1.86 11.29 7.04 7.04 0 0 1-9.957 0 7.04 7.04 0 0 1 0-9.958 7.06 7.06 0 0 1 2.304-1.539V33.926a7.049 7.049 0 0 1-3.82-9.234L29.242 14.272 1.73 41.777a5.925 5.925 0 0 0 0 8.371L41.852 90.27a5.925 5.925 0 0 0 8.37 0l39.934-39.934a5.925 5.925 0 0 0 0-8.371"/></g></svg>

Before

Width:  |  Height:  |  Size: 834 B

View File

@@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"
image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 512" fill="white">
<path
d="M256 0c141.385 0 256 114.615 256 256S397.385 512 256 512 0 397.385 0 256 114.615 0 256 0zm-17.22 317.056l-10.725-29.064s-17.374 19.388-43.412 19.388c-23.092 0-39.444-20.057-39.444-52.135 0-41.08 20.728-55.778 41.081-55.778 29.392 0 38.744 19.037 46.787 43.421l10.725 33.387c10.72 32.418 30.781 58.465 88.546 58.465 41.426 0 69.53-12.711 69.53-46.105 0-27.059-15.388-41.08-44.112-47.803l-21.364-4.669c-14.705-3.354-19.039-9.35-19.039-19.388 0-11.344 9.008-18.07 23.713-18.07 16.06 0 24.724 6.035 26.033 20.406l33.391-3.99c-2.681-30.093-23.41-42.454-57.486-42.454-30.092 0-59.488 11.344-59.488 47.81 0 22.736 11.048 37.085 38.748 43.761l22.737 5.357c17.024 3.996 22.732 11.049 22.732 20.736 0 12.362-12.023 17.374-34.754 17.374-33.737 0-47.811-17.724-55.786-42.104l-11.048-33.385c-13.965-43.475-36.358-59.497-80.792-59.497-49.13 0-75.221 31.055-75.221 83.877 0 50.766 26.038 78.177 72.884 78.177 37.722 0 55.779-17.724 55.779-17.724l-.015.005v.002z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,29 +1,46 @@
#![feature(iter_intersperse)]
extern crate core;
use js_sys::Float32Array; use js_sys::Float32Array;
use log::{info, warn}; use log::{info, warn};
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::Arc; use std::sync::Arc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use web_sys::{window, HtmlCanvasElement, WebGl2RenderingContext as GL2}; use wasm_bindgen::prelude::*;
use web_sys::{HtmlCanvasElement, WebGl2RenderingContext as GL2, window};
use yew::prelude::*; use yew::prelude::*;
use yew_router::prelude::*; use yew_router::prelude::*;
mod pages; mod pages;
use crate::pages::about::About; use crate::pages::about::About;
use crate::pages::landing::Landing; use crate::pages::blog::author::Author;
use crate::pages::projects::Projects; use crate::pages::blog::authors::Authors;
use crate::pages::blog::entries::Entries;
use crate::pages::blog::entry::Entry;
use crate::pages::findme::FindMe;
use crate::pages::projects::projects::Projects;
use pages::not_found::PageNotFound; use pages::not_found::PageNotFound;
#[derive(Routable, PartialEq, Eq, Clone, Debug)] #[derive(Routable, PartialEq, Eq, Clone, Debug)]
pub enum Route { pub enum Route {
#[at("/")] #[at("/")]
Landing,
#[at("/about")]
About, About,
#[at("/blog/entries/:id")]
Entry { id: u8 },
#[at("/blog/entries")]
Entries,
#[at("/blog/authors/:id")]
Author { id: u8 },
#[at("/blog/authors")]
Authors,
#[at("/projects")] #[at("/projects")]
Projects, Projects,
#[at("/findme")]
FindMe,
#[not_found] #[not_found]
#[at("/404")] #[at("/404")]
NotFound, NotFound,
@@ -31,172 +48,274 @@ pub enum Route {
pub struct App { pub struct App {
node_ref: NodeRef, node_ref: NodeRef,
navbar_active: bool,
}
pub enum Msg {
ToggleNavbar,
} }
impl Component for App { impl Component for App {
type Message = Msg; type Message = ();
type Properties = (); type Properties = ();
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::ToggleNavbar => {
self.navbar_active = !self.navbar_active;
true
}
}
}
fn create(_ctx: &Context<Self>) -> Self { fn create(_ctx: &Context<Self>) -> Self {
Self { node_ref: NodeRef::default(), navbar_active: false } Self {
node_ref: NodeRef::default(),
}
} }
fn view(&self, _ctx: &Context<Self>) -> Html { fn view(&self, _ctx: &Context<Self>) -> Html {
html! { html! {
<> <>
<BrowserRouter> <canvas width="100%" height="100%" style="
<header>{ self.view_header(_ctx) }</header>
<main style="z-index: 1 !important;">
<canvas style="
background-color: black !important; background-color: black !important;
position: fixed !important; position: fixed !important;
left: 0 !important; left: 0 !important;
top: 0 !important; top: 0 !important;
width: 100vw !important;
height: 100vh !important;
z-index: 0 !important; z-index: 0 !important;
" ref={self.node_ref.clone()} /> " ref={self.node_ref.clone()} />
<div style=" <BrowserRouter>
overflow: scroll !important; <header style="
left: 0 !important; z-index: 2 !important;
margin-top: var(--bulma-navbar-height) !important; display: flex !important;
width: 100% !important; color: white !important;
height: 100% !important; flex-direction: row !important;
align-items: center !important;
justify-content: center !important;
max-width: 100vw !important;
min-height: 20px !important;
height: 20px !important;
max-height: 20px !important;
filter: url(post.bloom.svg) !important;
"> ">
<Switch<Route> render={switch} /> <h3>{r"»[ "}</h3>
<h3><Link<Route> to={Route::About}>{r"about"}</Link<Route>></h3>
<h3>{r"|"}</h3>
<h3><Link<Route> to={Route::Entries}>{r"blog"}</Link<Route>></h3>
<h3>{r"|"}</h3>
<h3><Link<Route> to={Route::FindMe}>{r"findme"}</Link<Route>></h3>
<h3>{r"|"}</h3>
<h3><Link<Route> to={Route::Projects}>{r"projects"}</Link<Route>></h3>
<h3>{r" ]«"}</h3>
</header>
<main style="
z-index: 1 !important;
background-color: transparent !important;
color: white !important;
display: flex !important;
flex-direction: column !important;
min-width: fit-content !important;
width: calc(100vw - 18 px) !important;
flex-wrap: nowrap !important;
justify-content: space-between !important;
align-items: center !important;
justify-content: center !important;
align-self: center !important;
margin-left: auto !important;
margin-right: auto !important;
overflow-x: hidden !important;
overflow-y: auto !important;
height: fit-content !important;
max-height: calc(100vh - 42px) !important;
">
/*
min-height: 70vh !important;
height: 80vw !important;
*/
<div style="
background-color: rgba(0, 0, 0, 0.3125) !important;
backdrop-filter: blur(6px) !important;
padding: 4px 0px 0px 4px !important;
border-radius: 1.0rem !important;
border-style: solid !important;
border-color: black !important;
border-width: 1px !important;
z-index: 1 !important;
overflow-x: hidden !important;
overflow-y: auto !important;
min-width: 70vw !important;
width: 70vh !important;
max-width: calc(100vw - 18px) !important;
height: 100% !important;
margin-top: auto !important;
margin-bottom: auto !important;
scrollbar-width: thin !important;
scrollbar-color: transparent transparent !important;
"><Switch<Route> render={switch} />
{self.view_buttons()}
</div> </div>
</main> </main>
</BrowserRouter> </BrowserRouter>
<div class="tile is-parent container is-centered is-multiline" style="margin-bottom: var(--bulma-navbar-height) !important;">
<div class="columns is-size-3 ml-3 mr-3" style="margin-top: var(--bulma-block-spacing) !important;">
<div class="box mr-1 mb-5 pl-1 pr-1 pt-1 pb-1">
<p class="subtitle ml-2 mb-1 is-size-6" style="text-align: center !important;">{r#"cool buttons you should click on:"#}</p>
<div class="column is-full mb-0 mt-0 ml-0 mr-1 is-flex">
<a class="mr-1" href="https://beta.servfail.network/"><img loading="eager" alt="servfail" class="image has-text-centered" src="servfail.png" /></a>
<a class="mr-1" href="https://webassembly.org/"><img loading="eager" alt="wasm" class="image has-text-centered" src="wasm.png" /></a>
<a class="mr-1" href="https://www.rust-lang.org/"><img loading="eager" alt="rust" class="image has-text-centered" src="rust.png" /></a>
<a class="" href="https://fedoraproject.org/"><img loading="eager" alt="fedora" class="image has-text-centered" src="fedora.png" /></a>
</div>
</div>
<div class="box ml-1 mb-5 pl-1 pr-1 pt-1 pb-1">
<p class="subtitle ml-2 mb-1 is-size-6" style="text-align: center !important;">{r#"hotlink my button:"#}</p>
<div class="column mb-0 mr-1 is-flex is-flex-direction-row is-flex-wrap-nowrap">
<a href="https://celesteflare.cc/" class="mr-2"><img loading="eager" alt="luciel" class="image" src="luciel.png" style="width: 88px !important; height: 31px !important; max-width: 100vw !important;" /></a>
<textarea class="textarea is-size-7" placeholder="" rows="1" readonly=true style="max-height: 31px !important; resize: none !important; min-width: 0px !important;" value="<a href=\"https://celesteflare.cc/\"><img loading=\"eager\" alt=\"luciel\" class=\"image has-text-centered\" src=\"https://celesteflare.cc/luciel.png\" /></a>"/>
</div>
</div>
</div>
</div>
<footer class="footer" style="
--bulma-footer-background-color: #1E1E2E80 !important;
z-index: 1 !important;
position: fixed !important;
left: 0px !important;
bottom: 0px !important;
margin-bottom: 0 !important;
min-height: 31px !important;
width: 100% !important;
padding: 0 !important;
">{ self.view_footer() }</footer>
</> </>
} }
} }
fn rendered(&mut self, _ctx: &Context<Self>, first_render: bool) { fn rendered(&mut self, _ctx: &Context<Self>, first_render: bool) {
if first_render { self.view_canvas(); } if first_render {
self.view_canvas();
}
} }
} }
fn switch(routes: Route) -> Html { fn switch(routes: Route) -> Html {
match routes { match routes {
Route::Landing => { html! { <Landing /> } } Route::About => {
html! { <About /> }
}
Route::About => { html! { <About /> } } Route::Entries => {
Route::Projects => { html! { <Projects /> } } html! { <Entries /> }
}
Route::Entry { id } => {
html! { <Entry id={id as u8} /> }
}
Route::Authors => {
html! { <Authors /> }
}
Route::Author { id } => {
html! { <Author id={id as u8} /> }
}
Route::NotFound => { html! { <PageNotFound /> } } Route::FindMe => {
html! { <FindMe /> }
}
Route::Projects => {
html! { <Projects /> }
}
Route::NotFound => {
html! { <PageNotFound /> }
}
} }
} }
impl App { impl App {
fn view_header(&self, _ctx: &Context<Self>) -> Html { fn view_buttons(&self) -> Html {
let active_class = if self.navbar_active { "is-active" } else { "" };
html! { html! {
<nav class="navbar" style=" <div style="
z-index: 1 !important; z-index: 1 !important;
position: fixed !important; display: flex !important;
top: 0px !important; flex-wrap: wrap !important;
left: 0px !important; flex-direction: row !important;
width: 100% !important; justify-content: center !important;
padding: 0 !important; min-width: 70vw !important;
--bulma-navbar-background-color: #1E1E2E80 !important; width: 70vh !important;
backdrop-filter: blur(4px) !important; max-width: calc(100vw - 18px) !important;
height: fit-content !important;
overflow: hidden !important;
margin-right: auto !important;
margin-left: auto !important;
"> ">
<div class="navbar-brand"> <a style="
<img loading="eager" alt="icowon" class="image pl-2 pr-2 pt-2 pb-2" style="width: var(--bulma-navbar-height) !important; height: var(--bulma-navbar-height) !important;" src="favicon.ico" /> width: 88px !important;
<button class={classes!("navbar-burger", "burger", active_class)} aria-label="menu" aria-expanded="false" onclick={_ctx.link().callback(|_| Msg::ToggleNavbar)}> height: 31px !important;
<span aria-hidden="true"></span> margin-right: 0.2rem !important;
<span aria-hidden="true"></span> image-rendering: pixelated !important;
<span aria-hidden="true"></span> image-resolution: from-image !important;
</button> image-orientation: from-image !important;
" href="https://i0ur.ing/"><img loading="eager" alt="iouring" src="iouring.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://webassembly.org/"><img loading="eager" alt="wasm" src="wasm.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://beta.servfail.network/"><img loading="eager" alt="servfail" src="servfail.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://www.dataforest.net/en/"><img loading="eager" alt="dataforest" src="dataforest.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://fedoraproject.org/"><img loading="eager" alt="fedora" src="fedora.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://artixlinux.org/"><img loading="eager" alt="artix" src="artix.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://nixos.org/"><img loading="eager" alt="nixos" src="nixos.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://chimera-linux.org/"><img loading="eager" alt="void" src="chimera.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://voidlinux.org/"><img loading="eager" alt="void" src="void.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://www.rust-lang.org/"><img loading="eager" alt="rust" src="rust.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://dotnet.microsoft.com/en-us/"><img loading="eager" alt="csharp" src="csharp.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://kotlinlang.org/"><img loading="eager" alt="kotlin" src="kotlin.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
margin-right: 0.2rem !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
" href="https://www.java.com/"><img loading="eager" alt="java" src="java.png" /></a>
<a style="
width: 88px !important;
height: 31px !important;
image-rendering: pixelated !important;
image-resolution: from-image !important;
image-orientation: from-image !important;
"><img loading="eager" alt="aqueer" src="aqueer.png" /></a>
</div> </div>
<div class={classes!("navbar-menu", active_class)}>
<div class="navbar-start">
<Link<Route> classes={classes!("navbar-item")} to={Route::About}>{r"about"}</Link<Route>>
<Link<Route> classes={classes!("navbar-item")} to={Route::Projects}>{r"projects"}</Link<Route>>
</div>
/*
<div class="navbar-end">
<div class="navbar-item">
<div class="field is-grouped">
<p class="control">
</p>
</div>
</div>
</div>
*/
</div>
</nav>
}
}
fn view_footer(&self) -> Html {
html! {
<>
<div class="is-flex is-flex-direction-row is-flex-wrap-wrap is-justify-content-space-between" style="backdrop-filter: blur(4px);">
<p class="is-align-content-center is-size-7 mb-1 ml-0" style="
width: 50% !important;
text-align: left !important;
vertical-align: middle !important;
min-height: 31px !important;
">
{r#"✨ built with "#}
<a href="https://yew.rs/">{r#"yew"#}</a>
{r#" and "#}
<a href="https://bulma.io/">{r#"bulma"#}</a>
{r#" in rust"#}
</p>
<div class="is-align-content-center is-inline-block mt-1 mr-0" style="width: 50% !important; text-align: right !important; vertical-align: middle !important;">
<a class="is-inline-block" href="https://donotsta.re/lunary"><img loading="eager" alt="fedi" class="image is-24x24 has-text-centered pl-1 pr-1 pt-1 pb-1" src="fedi.svg" /></a>
<a class="is-inline-block" href="https://git.gay/luciel/"><img loading="eager" alt="git" class="image is-24x24 has-text-centered pl-1 pr-1 pt-1 pb-1" src="git.svg" /></a>
<a class="is-inline-block" href="https://www.last.fm/user/lumii500pg"><img loading="eager" alt="lastfm" class="image is-24x24 has-text-centered pl-1 pr-1 pt-1 pb-1" src="lastfm.svg" /></a>
</div>
</div>
</>
} }
} }
@@ -206,25 +325,35 @@ impl App {
let gl = canvas let gl = canvas
.get_context("webgl2") .get_context("webgl2")
.unwrap_or(canvas.get_context("webgl").unwrap()) .unwrap_or(canvas.get_context("webgl").unwrap())
.unwrap().dyn_into::<GL2>().unwrap(); .unwrap()
.dyn_into::<GL2>()
.unwrap();
let vertex_buffer = gl.create_buffer().unwrap(); let vertex_buffer = gl.create_buffer().unwrap();
gl.bind_buffer(GL2::ARRAY_BUFFER, Some(&vertex_buffer)); gl.bind_buffer(GL2::ARRAY_BUFFER, Some(&vertex_buffer));
gl.buffer_data_with_array_buffer_view(GL2::ARRAY_BUFFER, &Float32Array::from(vec![ gl.buffer_data_with_array_buffer_view(
-1.0, 1.0, 0.0, GL2::ARRAY_BUFFER,
-1.0, -1.0, 0.0, &Float32Array::from(
1.0, -1.0, 0.0, vec![
1.0, 1.0, 0.0 -1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0,
].as_slice()), GL2::STATIC_DRAW); ]
.as_slice(),
),
GL2::STATIC_DRAW,
);
let color_buffer = gl.create_buffer().unwrap(); let color_buffer = gl.create_buffer().unwrap();
gl.bind_buffer(GL2::ARRAY_BUFFER, Some(&color_buffer)); gl.bind_buffer(GL2::ARRAY_BUFFER, Some(&color_buffer));
gl.buffer_data_with_array_buffer_view(GL2::ARRAY_BUFFER, &Float32Array::from(vec![ gl.buffer_data_with_array_buffer_view(
1.0, 0.0, 0.0, 1.0, GL2::ARRAY_BUFFER,
0.0, 1.0, 0.0, 1.0, &Float32Array::from(
0.0, 0.0, 1.0, 1.0, vec![
1.0, 1.0, 0.0, 1.0 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
].as_slice()), GL2::STATIC_DRAW); ]
.as_slice(),
),
GL2::STATIC_DRAW,
);
let element_buffer = gl.create_buffer().unwrap(); let element_buffer = gl.create_buffer().unwrap();
gl.bind_buffer(GL2::ELEMENT_ARRAY_BUFFER, Some(&element_buffer)); gl.bind_buffer(GL2::ELEMENT_ARRAY_BUFFER, Some(&element_buffer));
@@ -260,7 +389,11 @@ impl App {
gl.attach_shader(&shader_program, &fragment_shader); gl.attach_shader(&shader_program, &fragment_shader);
gl.link_program(&shader_program); gl.link_program(&shader_program);
if !gl.get_program_parameter(&shader_program, GL2::LINK_STATUS).as_bool().unwrap() { if !gl
.get_program_parameter(&shader_program, GL2::LINK_STATUS)
.as_bool()
.unwrap()
{
warn!("shader couldn't be linked!"); warn!("shader couldn't be linked!");
} }
gl.use_program(Some(&shader_program)); gl.use_program(Some(&shader_program));
@@ -281,7 +414,9 @@ impl App {
gl.clear_color(0.0, 0.0, 0.0, 1.0); gl.clear_color(0.0, 0.0, 0.0, 1.0);
gl.clear(GL2::COLOR_BUFFER_BIT | GL2::DEPTH_BUFFER_BIT); gl.clear(GL2::COLOR_BUFFER_BIT | GL2::DEPTH_BUFFER_BIT);
let default_matrix = vec![1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]; let default_matrix = vec![
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
];
let unim_matrix = gl.get_uniform_location(&shader_program, "model"); let unim_matrix = gl.get_uniform_location(&shader_program, "model");
let unim_time = gl.get_uniform_location(&shader_program, "time"); let unim_time = gl.get_uniform_location(&shader_program, "time");
let unim_res = gl.get_uniform_location(&shader_program, "resolution"); let unim_res = gl.get_uniform_location(&shader_program, "resolution");
@@ -289,10 +424,17 @@ impl App {
let mut timestamp = 0.0; let mut timestamp = 0.0;
gl.uniform1f(unim_time.as_ref(), timestamp / 2000.0); gl.uniform1f(unim_time.as_ref(), timestamp / 2000.0);
gl.draw_elements_with_i32(GL2::TRIANGLES, element_indices.len() as i32, GL2::UNSIGNED_SHORT, 0); gl.draw_elements_with_i32(
GL2::TRIANGLES,
element_indices.len() as i32,
GL2::UNSIGNED_SHORT,
0,
);
fn request_animation_frame(f: &Closure<dyn FnMut()>) { fn request_animation_frame(f: &Closure<dyn FnMut()>) {
window().unwrap().request_animation_frame(f.as_ref().unchecked_ref()) window()
.unwrap()
.request_animation_frame(f.as_ref().unchecked_ref())
.expect("should register `requestAnimationFrame` OK"); .expect("should register `requestAnimationFrame` OK");
} }
@@ -308,13 +450,21 @@ impl App {
gl.uniform_matrix4fv_with_f32_array(unim_matrix.as_ref(), false, default_matrix.as_slice()); gl.uniform_matrix4fv_with_f32_array(unim_matrix.as_ref(), false, default_matrix.as_slice());
gl.uniform1f(unim_time.as_ref(), timestamp / 2000.0); gl.uniform1f(unim_time.as_ref(), timestamp / 2000.0);
gl.uniform2fv_with_f32_array(unim_res.as_ref(), vec![canvas.width() as f32, canvas.height() as f32].as_slice()); gl.uniform2fv_with_f32_array(
unim_res.as_ref(),
vec![canvas.width() as f32, canvas.height() as f32].as_slice(),
);
gl.uniform1i(unim_overlay_time.as_ref(), 0); // TODO: ... | add is xmas check gl.uniform1i(unim_overlay_time.as_ref(), 0); // TODO: ... | add is xmas check
gl.viewport(0, 0, canvas.width() as i32, canvas.height() as i32); gl.viewport(0, 0, canvas.width() as i32, canvas.height() as i32);
gl.clear(GL2::COLOR_BUFFER_BIT | GL2::DEPTH_BUFFER_BIT); gl.clear(GL2::COLOR_BUFFER_BIT | GL2::DEPTH_BUFFER_BIT);
gl.draw_elements_with_i32(GL2::TRIANGLES, element_indices.len() as i32, GL2::UNSIGNED_SHORT, 0); gl.draw_elements_with_i32(
GL2::TRIANGLES,
element_indices.len() as i32,
GL2::UNSIGNED_SHORT,
0,
);
request_animation_frame(cb.borrow().as_ref().unwrap()); request_animation_frame(cb.borrow().as_ref().unwrap());
} }

View File

@@ -12,40 +12,82 @@ impl Component for About {
fn view(&self, _ctx: &Context<Self>) -> Html { fn view(&self, _ctx: &Context<Self>) -> Html {
html! { html! {
<> <>
<div class="tile is-parent container"> <div>
{ self.view_info_card() } <img alt="insert pfp here" style="
</div> float: left !important;
</> margin-right: 10px !important;
} border-radius: 0.5rem !important;
} " loading="eager" width="96px" height="96px" src="profile.avif" />
} <div style="
impl About { display: flex !important;
fn view_info_card(&self) -> Html { flex-direction: column !important;
html! { max-height: 96px !important;
<> ">
<div class="box is-small is-flex-shrink-5 mb-5 mt-5"> <p style="
<img alt="insert pfp here" loading="eager" class="image is-128x128 is-square is-inline-block mg-small" src="profile.avif" /> display: flex !important;
<div class="columns is-narrow ml-3 is-inline-block is-vcentered is-centered is-gapless is-multiline is-0 mt-4" style="vertical-align: top !important;"> color: transparent !important;
<p class="column is-narrow" style="filter: url(post.bloom.svg#process) !important; color: #B4BEFE !important;"><img loading="eager" alt="ket" class="image is-24x24 is-square is-inline-block mg-small" src="oneko.gif" />{r" Lucielle R. Hoerner"}</p> flex-direction: row !important;
<p class="column is-narrow" style="background-clip: text !important; background-image: linear-gradient(45deg, #5BCEFAFF, #F5A9B8FF, #FFFFFFFF) !important;"> align-items: center !important;
<p>{r"she/they · transfem and poly"}</p> width: fit-content !important;
<p>{r"programmer and freelancer"}</p> background-clip: text !important;
<p>{r"certified catgirl™"}</p> background-image: linear-gradient(45deg, #5BCEFAFF, #F5A9B8FF, #FFFFFFFF) !important;
-webkit-background-clip: text !important;
margin: unset !important;
filter: url(post.bloom.svg#process) !important;
">
<img loading="eager" alt="ket" src="oneko.gif" />{r" lia · they/she · transfemby"}</p>
<p style="margin: unset !important;">
<p style="margin: unset !important;">{r"certified catgirl™"}</p>
<p style="margin: unset !important;">{r"software engineer"}</p>
<p style="margin: unset !important;">{r"professional yapper"}</p>
<p style="margin: unset !important;">{r"neurospicy and disabled"}</p>
</p> </p>
</div> </div>
<hr style="background-color: #B4BEFE60 !important;" /> <p style="
<p class="subtitle">{r#"about me"#}</p> font-weight: bold !important;
<div class="content is-size-7">{r#" font-style: italic !important;
hellow there! i'm lunary but you can also just call me luciel, luci or luni. font-size: xx-large !important;
personal preference is ordered. ">{r">intro_"}<br /><p style="
thing's i'm interested in are gamedev, devsecops, exploits, hacking, music and cooking. font-weight: normal !important;
in my free-time i mostly work on my private projects or spent time with my partners or online friends. font-style: normal !important;
my knowledge is based on autodidactics and experiences with (former) friends. font-size: medium !important;
looking for a job/internship at the moment because i wasn't able to finish my previous internship due to some financial circumstances. ">{r#"
you can find projects i work on somewhere in the header. name's lia or lucy. we are creating.
i may or may not update information stated here but that's it for now. trying to provide a safe space in the internet.
"#} our goal's to make this world a better ~ less trashy ~ place.
</div> may sound naive as fuck but fuck it we ball.
audhd (certified) and probably bpd or ptsd. i'm not a psychologist tho.
interact with caution, may bite.
political view's prolly very obvious. should be enough to mention i'm social.
figure it yourself. use your brain.
"#}</p>{r">hobbies_"}<br /><p style="
font-weight: normal !important;
font-style: normal !important;
font-size: medium !important;
">{r#"
watching anime, designing something kewl, playing games, starting a new project or just yapping with friends, nearly everything's included.
i especially enjoy cooking or even baking if enough spoons are to avail.
which anime? has to be very specific, i'm really picky and judgy regarding them.
i uh - design stuff when enough creativity is there. nothing specific. maybe just a button, banner, icon or just anything.
has to be something i can somewhat imagine in my fucky-wucky head.
gaymes? gay! no uhh - i play ranging from minecraft and stardew, to puzzly metroidvanias like hollow knight and pseudoregalia, or challenging platformers like celeste, nearly anything.
i also enjoy playing rhythm games like osu! or muse dash. returning to terraria sometimes and also some old-ish games.
projects? you can find public ones in my projects tab.
"#}/*</p>{r"hobbies"}<br /><p style="
font-weight: normal !important;
font-style: normal !important;
font-size: medium !important;
">{r#"
watching anime, designing something kewl, playing games, starting a new project or just yapping/meeting up with friends, nearly everything's included.
i especially enjoy cooking or even baking if enough spoons are to avail.
which anime? has to be very specific, i'm really picky and judgy regarding them.
i uh - design stuff when enough creativity is there. nothing specific. maybe just a button, banner, icon or just anything.
has to be something i can somewhat imagine in my fucky-wucky head.
gaymes? gay! no uhh - i play ranging from minecraft and stardew, to puzzly metroidvanias like hollow knight and pseudoregalia, or challenging platformers like celeste, nearly anything.
i also enjoy playing rhythm games like osu! or muse dash. returning to terraria sometimes and also some old-ish games.
projects? you can find public ones in my projects tab.
"#}*/</p>
</p>
</div> </div>
</> </>
} }

71
src/pages/blog/author.rs Normal file
View File

@@ -0,0 +1,71 @@
use crate::pages::blog::content;
use crate::pages::blog::content::{BlogEntry, Post};
use yew::prelude::*;
use crate::pages::blog::authorcard::AuthorCard;
use crate::pages::blog::entrycard::EntryCard;
#[derive(Clone, Debug, Eq, PartialEq, Properties)]
pub struct Props {
pub id: u8,
}
pub struct Author {
author: content::Author,
}
impl Component for Author {
type Message = ();
type Properties = Props;
fn create(ctx: &Context<Self>) -> Self {
Self {
author: content::Author::from_id(ctx.props().id),
}
}
fn changed(&mut self, ctx: &Context<Self>, _old_props: &Self::Properties) -> bool {
self.author = content::Author::from_id(ctx.props().id);
true
}
fn view(&self, _ctx: &Context<Self>) -> Html {
let Self { author } = self;
let id = author.id;
let cards: Vec<_> = (0..Post::POSTS.len()) // TODO: ... | add var
.filter(|&id_offset| {
Post::from_id(id_offset as u8)
.authors
.iter()
.any(|id1| *id1 == id)
})
.map(|id_offset| html! {<EntryCard id={id_offset as u8} />})
.collect();
html! {
<div style="
display: flex !important;
width: 100% !important;
flex-direction: column !important;
flex-wrap: wrap !important;
justify-content: center !important;
margin-bottom: 2rem !important;
">
<h2 style="text-align: center !important;">{ "about me" }</h2>
<div style="
display: flex !important;
width: 100% !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: center !important;
margin-bottom: 1rem !important;
"><AuthorCard {id} /></div>
<h2 style="text-align: center !important;">{ "my posts" }</h2>
<div style="
display: flex !important;
width: 100% !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: center !important;
">{ for cards }</div>
</div>
}
}
}

View File

@@ -0,0 +1,72 @@
use yew::prelude::*;
use yew_router::components::Link;
use crate::pages::blog::content::Author;
use crate::pages::blog::content::BlogEntry;
use crate::Route;
#[derive(Clone, Debug, PartialEq, Eq, Properties)]
pub struct PropsAuthorCard {
pub id: u8,
}
pub struct AuthorCard {
author: Author,
}
impl Component for AuthorCard {
type Message = ();
type Properties = PropsAuthorCard;
fn create(ctx: &Context<Self>) -> Self {
Self {
author: Author::from_id(ctx.props().id),
}
}
fn changed(&mut self, ctx: &Context<Self>, _old_props: &Self::Properties) -> bool {
self.author = Author::from_id(ctx.props().id);
true
}
fn view(&self, _ctx: &Context<Self>) -> Html {
let Self { author } = self;
let keywords = author.keywords.iter().map(|keyword| html! {
<p style="margin: unset !important;">{*keyword}</p>
}).collect::<Html>();
html! {
<div style="
display: flex !important;
flex-direction: row !important;
flex-wrap: wrap !important;
background-color: #ECBEE130 !important;
border-radius: 0.5rem !important;
width: fit-content !important;
height: fit-content !important;
text-align: left !important;
margin: 1rem 1rem 0 0 !important;
">
<img style="
float: left !important;
margin-right: 0.3rem !important;
border-radius: 0.5rem !important;
" alt="insert pfp here" width="96" height="96" src={author.image_url} />
<div style="
display: flex !important;
flex-direction: column !important;
flex-wrap: wrap !important;
margin-top: 0.3rem !important;
margin-right: 0.3rem !important;
">
<h3 style="margin: unset !important;">
<Link<Route> to={Route::Author { id: author.id }}>
{ &*author.name }
</Link<Route>>
</h3>
{ keywords }
</div>
</div>
}
}
}

31
src/pages/blog/authors.rs Normal file
View File

@@ -0,0 +1,31 @@
use yew::prelude::*;
use crate::pages::blog::authorcard::AuthorCard;
use crate::pages::blog::content::{Author, BlogEntry};
pub struct Authors;
impl Component for Authors {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self
}
fn view(&self, _: &Context<Self>) -> Html {
html! {
<div style="
display: flex !important;
width: 100% !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: center !important;
margin-top: 2rem !important;
margin-bottom: 2rem !important;
">{ for Author::AUTHORS.map(|author| {
let id = author.id;
html! { <AuthorCard {id} /> }
}) }</div>
}
}
}

299
src/pages/blog/content.rs Normal file
View File

@@ -0,0 +1,299 @@
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Author {
pub id: u8,
pub image_url: &'static str,
pub name: &'static str,
pub keywords: &'static [&'static str],
pub about: &'static str,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Post {
pub id: u8,
pub authors: &'static [u8],
pub title: &'static str,
pub utcdate: &'static str,
pub content: &'static str,
}
impl BlogEntry for Author {
fn from_entry(entry: &mut Entry) -> Self {
*Self::AUTHORS
.get(entry.id as usize)
.cloned()
.unwrap_or(&Self {
id: u8::MAX,
image_url: "",
name: "not found",
keywords: [].as_slice(),
about: "",
})
}
}
impl BlogEntry for Post {
fn from_entry(entry: &mut Entry) -> Self {
*Self::POSTS
.get(entry.id as usize)
.cloned()
.unwrap_or(&Self {
id: u8::MAX,
authors: &[u8::MAX],
title: "not found",
utcdate: "1970-01-01",
content: "",
})
}
}
pub struct Entry {
pub id: u8,
}
impl Entry {
pub fn from_id(seed: u8) -> Self {
Self { id: seed }
}
}
pub trait BlogEntry: Sized {
fn from_entry(entry: &mut Entry) -> Self;
fn from_id(id: u8) -> Self {
Self::from_entry(&mut Entry::from_id(id))
}
const AUTHORS: [&'static Author; 2] = [
&Author {
id: 0,
image_url: "profile.avif",
name: "lia",
keywords: &[
"certified catgirl™",
"software engineer",
"professional yapper",
"neurospicy and disabled",
],
about: "",
},
&Author {
id: 1,
image_url: "",
name: "mreowww",
keywords: &["meow", "mrrp", "mew"],
about: "",
},
];
const POSTS: [&'static Post; 2] = [
&Post {
id: 0,
authors: &[0],
title: "haj, world!",
utcdate: "2025-08-24",
content: r#"
### my first blogpost
haj! and welcome to my first blogpost.
this blogpost won't have that much content.
fun fact: this post becomes html from markdown :3
pretty cool, ain't it? we think so too.
it's for including images, formatted text, code and content much easier.
i also added a too overcomplicated blog backend that allows authors and posts by u8::MAX, cause why not.
won't post that much either way, so why bother with higher values.
nonetheless... have a great day, evening, whatever daytime it's for you rn and stay safe. ♡
you may take a look at my other blogposts. this one was basically practially just a test.
"#,
},
&Post {
id: 1,
authors: &[0],
title: "sweet little poison",
utcdate: "2025-08-25",
content: r#"
### > setting up iocaine with docker and caddy. ~
sup, today we're going to give ya a crash course on how to homebrew poison for ai. ^.^
we'll be utilizing docker for containerization and caddy as a reverse-proxy.
#### > preparing docker and files ~
first, we're going to create a new external network and recreate our file struct.
in this example we're going to name it "caddy". very creative, i know.
we achieve this by running following pile of commands:
```sh
docker network create caddy && \
mkdir -p ./caddy/pages/example.com ./iocaine ./socks && \
touch ./docker-compose.yml ./caddy/proxy ./iocaine/config.toml && \
touch ./caddy/pages/example.com/index.html && \
printf '<html><body><h1>hellow body consisting of blood and flesh</h1></body></html>' \
> ./caddy/pages/example.com/index.html
```
after running that we should be set and ready for the next few steps.
if you're curious, this is how it should look like right now:
```sh
Documents/example » tree .
.
├── caddy
│   ├── pages
│   │   └── example.com
│   │   └── index.html
│   └── proxy
├── docker-compose.yml
├── iocaine
│   └── config.toml
└── socks
```
#### > downloading data and configuring iocaine ~
next things next: we're going to download a robots.json, some markov-chain-stuffies and a words.txt.
for now, we will be using the default stuff from the official docs cause why not:
```sh
curl --proto '=https' --tlsv1.3 \
-L https://archive.org/download/GeorgeOrwells1984/1984_djvu.txt \
-o ./iocaine/1984.txt && \
curl --proto '=https' --tlsv1.3 \
-L https://archive.org/download/ost-english-brave_new_world_aldous_huxley/Brave_New_World_Aldous_Huxley_djvu.txt \
-o ./iocaine/brave-new-world.txt && \
curl --proto '=https' --tlsv1.2 \
-L https://git.savannah.gnu.org/cgit/miscfiles.git/plain/web2 \
-o ./iocaine/words.txt && \
curl --proto '=https' --tlsv1.3 \
-L https://github.com/ai-robots-txt/ai.robots.txt/raw/refs/heads/main/robots.json \
-o ./iocaine/robots.json
```
most importantly, we have to scrape nam-shub-of-enki from gergely's git.
here's a way to curl and extract it automatically in the correct folder:
```sh
curl --proto '=https' --tlsv1.3 \
-L https://git.madhouse-project.org/api/packages/iocaine/generic/nam-shub-of-enki/20250711.0/nam-shub-of-enki-20250711.0.tar.zst \
-o ./iocaine/nam-shub-of-enki.tar.zst && \
sudo tar -xvf ./iocaine/nam-shub-of-enki.tar.zst -C ./iocaine
```
now, we're going to prepare our iocaine/config.toml like this:
```sh
cat > ./iocaine/config.toml <<'YAML'
[server]
bind = "/run/iocaine/waow.socket"
unix_listen_access = "everybody"
[server.control]
bind = "/run/iocaine/listen.socket"
unix_listen_access = "owner"
[server.request-handler]
path = "/data"
language = "roto"
[sources]
words = "/data/words.txt"
markov = [ "/data/1984.txt", "/data/brave-new-world.txt" ]
[metrics]
enable = false
YAML
```
#### > cooking up our docker compose file for deployment ~
i have fucked around with docker a little while to make this somehow work.
here's a command which will insert needed content into our docker-compose.yml:
```sh
cat > ./docker-compose.yml <<'YAML'
services:
caddy:
image: caddy:alpine
container_name: proxy.caddy
hostname: proxy.caddy
restart: unless-stopped
cap_add:
- NET_ADMIN
ports:
- "80:80"
- "443:443"
- "443:443/udp"
networks:
- caddy
volumes:
- ./socks:/run/iocaine:ro
- ./caddy/pages:/var/www/html
- ./caddy/data:/data
- ./caddy/config:/config
- ./caddy/proxy:/etc/caddy/Caddyfile:ro
depends_on:
- iocaine
iocaine:
image: git.madhouse-project.org/iocaine/iocaine:2
container_name: proxy.iocaine
hostname: proxy.iocaine
restart: unless-stopped
ports:
- "127.0.0.1:42069:42069"
networks:
- caddy
volumes:
- ./socks:/run/iocaine:rw
- ./iocaine:/data
environment:
- IOCAINE__SERVER__BIND="/run/iocaine/waow.socket"
- IOCAINE__SERVER__UNIX_LISTEN_ACCESS="everybody"
- IOCAINE__SERVER__REQUEST_HANDLER__PATH="/data"
- IOCAINE__SERVER__REQUEST_HANDLER__LANGUAGE="roto"
- IOCAINE__SERVER__CONTROL__BIND="/run/iocaine/listen.socket"
- IOCAINE__SERVER__CONTROL__UNIX_LISTEN_ACCESS="owner"
- IOCAINE__SOURCES__WORDS="/data/words.txt"
- IOCAINE__SOURCES__MARKOV=["/data/1984.txt", "/data/brave-new-world.txt"]
- IOCAINE__METRICS__ENABLE=false
- NSOE__AI_ROBOTS_TXT_PATH=/data/robots.json
command: --config-file /data/config.toml start
networks:
caddy:
external: true
YAML
```
#### > finishing up with caddy and deploying ~
our caddyfile needs some love to work.
here's what i ripped from the official docs:
```sh
cat > ./iocaine/proxy <<'TXT'
(iocaine) {
@read method GET HEAD
@not-read not {
method GET HEAD
}
reverse_proxy @read unix//run/iocaine/waow.socket {
#reverse_proxy @read proxy.iocaine:42069 {
@fallback status 421
handle_response @fallback {
{blocks.handler}
}
}
handle @not-read {
{blocks.default}
}
}
example.com {
import iocaine {
handler {
reverse_proxy http://example:8080
}
default {
# this is the behaviour if neither a GET nor HEAD request comes in
reverse_proxy http://example:8080
}
}
}
TXT
```
now the last thing that's left is a plain and simple:
`docker compose up -d`
and we should be good to go!
i hope this post made it easier/helped you with setting up iocaine on your own server. ♡
it's good to have this set up just to fuck around with fucking parisitic generative ai stealing your things.
gatekeep your stuff from big corpos that are trying to make their business from your experience and skills.
"#,
},
];
}

55
src/pages/blog/entries.rs Normal file
View File

@@ -0,0 +1,55 @@
use yew::prelude::*;
use crate::pages::blog::content::BlogEntry;
use crate::pages::blog::content::Post;
use crate::pages::blog::entrycard::EntryCard;
pub struct Entries {}
impl Component for Entries {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self {}
}
fn view(&self, ctx: &Context<Self>) -> Html {
html! {
<div>
<h1 style="margin: unset !important;">{ "entries" }</h1>
<h2 style="
margin: unset !important;
margin-bottom: 1rem !important;
">{ "here are some things i yapped about" }</h2>
{ self.view_posts(ctx) }
</div>
}
}
}
impl Entries {
fn view_posts(&self, _ctx: &Context<Self>) -> Html {
let cards: Vec<_> = (0..Post::POSTS.len()) // TODO: ... | add var
.filter(|&id_offset| {
Post::from_id(id_offset as u8)
.authors
.iter()
.all(|id| *id != u8::MAX)
})
.map(|id_offset| html! {<EntryCard id={id_offset as u8} />})
.collect();
html! {
<div style="
display: flex !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: center !important;
margin: unset !important;
margin-bottom: 1rem !important;
width: 100% !important;
">
{ for cards }
</div>
}
}
}

77
src/pages/blog/entry.rs Normal file
View File

@@ -0,0 +1,77 @@
use std::rc::Rc;
use yew::prelude::*;
use yew_markdown::Markdown;
use yew_router::prelude::*;
use crate::pages::blog::content;
use crate::pages::blog::content::{Author, BlogEntry};
use crate::Route;
#[derive(Clone, Debug, Eq, PartialEq, Properties)]
pub struct Props {
pub id: u8,
}
#[derive(PartialEq, Eq, Debug)]
pub struct PostState {
pub inner: content::Post,
}
impl Reducible for PostState {
type Action = u8;
fn reduce(self: Rc<Self>, action: u8) -> Rc<Self> {
Self {
inner: content::Post::from_id(action.into()),
}
.into()
}
}
#[function_component]
pub fn Entry(props: &Props) -> Html {
let id = props.id;
let post = use_reducer(|| PostState {
inner: content::Post::from_id(id.into()),
});
{
let post_dispatcher = post.dispatcher();
use_effect_with(id, move |id| {
post_dispatcher.dispatch(*id);
|| {}
});
}
let post = &post.inner;
html! {
<>
<h1 style="
color: #F5C2E7FF !important;
margin: unset !important;
filter: url(post.bloom.svg#process) !important;
">{ &*post.title }</h1>
<div style="flex-direction: column !important;">
<h2 style="margin: unset !important;">
{ "written by " } {
post.authors.iter().map(|id| {
let author = Author::from_id(*id);
html! {
<Link<Route> to={crate::Route::Author { id: author.id }}>
{ &*author.name }
</Link<Route>>
}
}).intersperse(html! { ", " }).collect::<Html>()
} { format!(" on {}", &post.utcdate) }
</h2>
</div>
<Markdown
src={post.content}
hard_line_breaks={true}
send_debug_info={Callback::noop()}
/>
</>
}
}

View File

@@ -0,0 +1,98 @@
use std::rc::Rc;
use yew::prelude::*;
use yew_router::components::Link;
use crate::pages::blog::content::{Author, BlogEntry, Post};
use crate::Route;
#[derive(Clone, Debug, PartialEq, Eq, Properties)]
pub struct PropsEntryCard {
pub id: u8,
}
#[derive(PartialEq, Eq, Debug)]
pub struct PostState {
inner: Post,
}
impl Reducible for PostState {
type Action = u8;
fn reduce(self: Rc<Self>, action: u8) -> Rc<Self> {
Self {
inner: Post::from_id(action.into()),
}
.into()
}
}
#[function_component]
pub fn EntryCard(props: &PropsEntryCard) -> Html {
let id = props.id;
let post = use_reducer_eq(|| PostState {
inner: Post::from_id(id.into()),
});
{
let post_dispatcher = post.dispatcher();
use_effect_with(id, move |id| {
post_dispatcher.dispatch(*id);
|| {}
});
}
let post = &post.inner;
html! {
<div style="
display: flex !important;
flex-direction: column !important;
flex-wrap: wrap !important;
background-color: #ECBEE130 !important;
border-radius: 0.5rem !important;
width: fit-content !important;
height: fit-content !important;
text-align: left !important;
margin: 1rem 1rem 0 0 !important;
">
<Link<Route> to={Route::Entry { id: post.id }}>
<h2 style="
margin: unset !important;
margin-top: 0.3rem !important;
margin-left: 0.3rem !important;
margin-right: 0.3rem !important;
">{ &*post.title }</h2>
</Link<Route>>
<h3 style="
margin: unset !important;
margin-left: 0.3rem !important;
margin-right: 0.3rem !important;
">
{ format!("published {}", post.utcdate) }
</h3>
<div style="flex-direction: column !important;">
<h3 style="
margin: unset !important;
margin-left: 0.3rem !important;
margin-right: 0.3rem !important;
margin-bottom: 0.3rem !important;
">
{ "written by " }
{
post.authors.iter().map(|id| {
let author = Author::from_id(*id);
html! {
<Link<Route> to={crate::Route::Author { id: author.id }}>
{ &*author.name }
</Link<Route>>
}
}).intersperse(html! { ", " }).collect::<Html>()
}
</h3>
</div>
</div>
}
}

7
src/pages/blog/mod.rs Normal file
View File

@@ -0,0 +1,7 @@
pub mod author;
pub mod authorcard;
pub mod authors;
pub mod content;
pub mod entries;
pub mod entry;
pub mod entrycard;

138
src/pages/findme.rs Normal file
View File

@@ -0,0 +1,138 @@
use web_sys::window;
use yew::prelude::*;
pub struct FindMe;
impl Component for FindMe {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self
}
fn view(&self, _ctx: &Context<Self>) -> Html {
let clipboard = window().expect("meow").navigator().clipboard();
let handle_copy_matrix = {
let clipboard = clipboard.clone();
Callback::from(move |_| {
let _ = clipboard.write_text(&*"@iouring:hi.stellaris.fyi".to_string());
})
};
let handle_copy_telegram = {
let clipboard = clipboard.clone();
Callback::from(move |_| {
let _ = clipboard.write_text(&*"@luc1ell3".to_string());
})
};
let handle_copy_discord = {
let clipboard = clipboard.clone();
Callback::from(move |_| {
let _ = clipboard.write_text(&*"@donotusedisc0rdkthxbye".to_string());
})
};
html! {
<div style="
display: flex !important;
flex-direction: row !mportant;
flex-wrap: wrap !important;
justify-content: center !important;
width: 100% !important;
">
<div style="
width: fit-content !important;
height: fit-content !important;
margin: 1rem 1rem 1rem 1rem !important;
">
<p style="
font-weight: bold !important;
font-style: normal !important;
font-size: xx-large !important;
text-align: center !important;
margin: unset !important;
">{r"follow us"}</p>
<p style="
font-weight: normal !important;
font-style: normal !important;
font-size: large !important;
">{" × "}<a style="
color: #F5C2E7FF !important;
" href="https://ice.stellaris.fyi/@iouring">{r"fediverse"}</a><br />
{" × "}<a style="
color: #B4BEFEFF !important;
" href="https://bsky.app/profile/i0ur.ing">{r"bluesky"}</a><br />
</p>
</div>
<div style="
width: fit-content !important;
height: fit-content !important;
margin: 1rem 1rem 1rem 1rem !important;
">
<p style="
font-weight: bold !important;
font-style: normal !important;
font-size: xx-large !important;
text-align: center !important;
margin: unset !important;
">{r"write us"}</p>
<p style="
font-weight: normal !important;
font-style: normal !important;
font-size: large !important;
">
{"× "}
<button style="
color: #94E2D5FF !important;
font-size: large !important;
" onclick={handle_copy_matrix}>{r"matrix"}</button>
<br />
{"× "}
<button style="
color: #B4BEFEFF !important;
font-size: large !important;
" onclick={handle_copy_telegram}>{r"telegr"}</button>
<br />
{"× "}
<button style="
color: #F38BA8FF !important;
font-size: large !important;
" onclick={handle_copy_discord}>{r"ewcord"}</button>
</p>
</div>
<div style="
width: fit-content !important;
height: fit-content !important;
margin: 1rem 1rem 1rem 1rem !important;
">
<p style="
font-weight: bold !important;
font-style: normal !important;
font-size: xx-large !important;
text-align: center !important;
margin: unset !important;
">{r"git gud"}</p>
<p style="
font-weight: normal !important;
font-style: normal !important;
font-size: large !important;
">{" × "}<a style="
color: #F5C2E7FF !important;
" href="https://git.celesteflare.cc/i0uring">{r"my own!!!"}</a><br />
{" × "}<a style="
color: #CBA6F7FF !important;
" href="https://git.gay/luciel">{r"the gay one"}</a><br />
{" × "}<a style="
color: #B4BEFEFF !important;
" href="https://git.rimuru.club/i0uring">{r"git of fren"}</a><br />
{" × "}<a style="
color: #89B4FAFF !important;
" href="https://codeberg.org/i0uring">{r"a mountain what"}</a>
</p>
</div>
</div>
}
}
}

View File

@@ -1,73 +0,0 @@
use crate::Route;
use yew::prelude::*;
use yew_router::prelude::Link;
pub struct Landing;
impl Component for Landing {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self
}
fn view(&self, _ctx: &Context<Self>) -> Html {
html! {
<>
<div class="tile is-parent container" style="
margin: 0 !important;
left: 0 !important;
top: 0 !important;
width: 100% !important;
height: 100% !important;
max-width: 100% !important;
z-index: 2 !important;
">
{ self.view_background() }
{ self.view_text() }
</div>
</>
}
}
}
impl Landing {
fn view_background(&self) -> Html {
html! {
<>
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" style="
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
z-index: 0 !important;
backdrop-filter: blur(24px) !important;
">
<defs>
<@{"linearGradient"} id="trans">
<stop offset="0%" stop-color="#5BCEFA" />
<stop offset="50%" stop-color="#F5A9B8" />
<stop offset="100%" stop-color="#FFFFFF" />
</@>
</defs>
<rect width="100%" height="100%" x="0" y="0" rx="0" ry="0" fill="url(#trans)" fill-opacity="0.2" />
</svg>
</>
}
}
fn view_text(&self) -> Html {
html! {
<>
<Link<Route> classes={classes!("navbar-item")} to={Route::About}><p style="
display: flex !important;
justify-content: center !important;
align-items: center !important;
height: calc(100vh - 16px - (var(--bulma-navbar-height) * 2)) !important;
width: 100% !important;
filter: url(post.bloom.svg#process)
">{r"click to enter"}</p></Link<Route>>
</>
}
}
}

View File

@@ -1,6 +1,6 @@
pub mod landing;
pub mod about; pub mod about;
pub mod blog;
pub mod findme;
pub mod projects; pub mod projects;
pub mod not_found; pub mod not_found;

View File

@@ -11,16 +11,21 @@ impl Component for PageNotFound {
} }
fn view(&self, _ctx: &Context<Self>) -> Html { fn view(&self, _ctx: &Context<Self>) -> Html {
// TODO: ... | personalize
html! { html! {
<section class="hero is-danger is-bold is-large"> <div style="
<div class="hero-body"> display: flex !important;
<div class="container"> text-align: center !important;
<h1 class="title">{ "Page not found" }</h1> flex-direction: row !important;
<h2 class="subtitle">{ "Page page does not seem to exist" }</h2> align-items: center !important;
flex-wrap: wrap !important;
justify-content: center !important;
">
<img loading="eager" alt="huh" style="
width: 96px !important;
height: 96px !important;
" width="96" height="96" src="404.png" />
<h1>{ "what" }</h1>
</div> </div>
</div>
</section>
} }
} }
} }

View File

@@ -1,73 +0,0 @@
use yew::prelude::*;
pub struct Projects;
impl Component for Projects {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self
}
fn view(&self, _ctx: &Context<Self>) -> Html {
html! {
<>
<div class="tile is-parent container mb-5 mt-5">
{ self.view_projects_ongoing() }
{ self.view_projects_finished() }
</div>
</>
}
}
}
impl Projects {
fn view_projects_ongoing(&self) -> Html {
html! {
<>
<p class="title ml-2 is-size-4">{r#"ongoing projects"#}</p>
<div class="columns is-size-7 ml-3 mr-3" style="margin-top: var(--bulma-block-spacing) !important;">
<div class="column box mb-5 mr-1">
<p class="subtitle is-inline-block mb-0"><a href="https://git.gay/luciel/app_catnip">
{r#"catnip"#}
</a></p>
<p class="content">{r#"all-rounder ide in the making"#}</p>
</div>
<div class="column box mb-5 ml-1">
<p class="subtitle is-inline-block mb-0"><a href="https://git.gay/luciel/app_nekochat">
{r#"neko chat"#}
</a></p>
<p class="content">{r#"my planned matrix client"#}</p>
</div>
</div>
</>
}
}
fn view_projects_finished(&self) -> Html {
html! {
<>
<p class="title ml-2 is-size-4">{r#"finished projects"#}</p>
<div class="columns is-size-7 ml-3 mr-3">
<div class="column box mb-5 mr-1">
<p class="subtitle is-inline-block mb-0"><a href="https://git.gay/luciel/lib_tinyevents">
{r#"tiny events"#}
</a></p>
<p class="content">{r#"a java seventeen (and up) event-system that is able to be scaled in large systems."#}</p>
</div>
<div class="column box mb-5 ml-1 mr-2">
<p class="subtitle is-inline-block mb-0"><a href="https://git.gay/luciel/lib_swingify">
{r#"swingify"#}
</a></p>
<p class="content">{r#"my java swing wrapper to simplify window creation for bogus-brains."#}</p>
</div>
<div class="column box mb-5 mr-1">
<p class="subtitle is-inline-block mb-0"><a href="https://git.gay/luciel/mc_mod_mnet">
{r#"modern netty"#}
</a></p>
<p class="content">{r#"fabric mod that adds experimental iouring and kqueue support."#}</p>
</div>
</div>
</>
}
}
}

View File

@@ -0,0 +1,51 @@
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Project {
pub url: &'static str,
pub name: &'static str,
pub desc: &'static str,
}
impl ProjectEntry for Project {}
pub trait ProjectEntry: Sized {
const PROJECTS_ONGOING: [&'static Project; 3] = [
&Project {
url: "https://git.celesteflare.cc/stellaris/mod_headsup",
name: "headsup mod",
desc: "extensible hud mc mod",
},
&Project {
url: "https://git.celesteflare.cc/i0uring/app_catnip",
name: "catnip",
desc: "all-rounder ide in the making",
},
&Project {
url: "https://git.celesteflare.cc/i0uring/app_nekochat",
name: "neko chat",
desc: "my planned matrix client",
},
];
const PROJECTS_FINISHED: [&'static Project; 4] = [
&Project {
url: "https://git.celesteflare.cc/i0uring/lib_tinyevents",
name: "tiny events",
desc: "a java 21+ event-sys",
},
&Project {
url: "https://git.celesteflare.cc/i0uring/dotfiles",
name: "dotfiles",
desc: "personal set of configurations",
},
&Project {
url: "https://git.celesteflare.cc/i0uring/lib_swingify",
name: "tiny events",
desc: "simplifies java swing window creation",
},
&Project {
url: "https://git.celesteflare.cc/i0uring/dotfiles",
name: "modern netty",
desc: "adds experimental netty handlers to mc",
},
];
}

View File

@@ -0,0 +1,3 @@
pub mod content;
pub mod projectcard;
pub mod projects;

View File

@@ -0,0 +1,54 @@
use yew::prelude::*;
use crate::pages::projects::content::Project;
#[derive(Clone, Debug, PartialEq, Eq, Properties)]
pub struct PropsAuthorCard {
pub project: Project,
}
pub struct ProjectCard {
project: Project,
}
impl Component for ProjectCard {
type Message = ();
type Properties = PropsAuthorCard;
fn create(ctx: &Context<Self>) -> Self {
Self {
project: ctx.props().project,
}
}
fn view(&self, _ctx: &Context<Self>) -> Html {
let Self { project } = self;
html! {
<div style="
display: flex !important;
flex-direction: row !important;
flex-wrap: wrap !important;
background-color: #ECBEE130 !important;
border-radius: 0.5rem !important;
width: fit-content !important;
height: fit-content !important;
text-align: left !important;
margin: 1rem 1rem 0 0 !important;
">
<div style="
display: flex !important;
flex-direction: column !important;
flex-wrap: wrap !important;
margin: 0.3rem 0.3rem 0.3rem 0.3rem !important;
">
<h2 style="margin: unset !important;">
<a href={project.url}>{ &*project.name }</a>
</h2>
<h3 style="margin: unset !important;">
{ &*project.desc }
</h3>
</div>
</div>
}
}
}

View File

@@ -0,0 +1,54 @@
use crate::pages::projects::content::{Project, ProjectEntry};
use crate::pages::projects::projectcard::ProjectCard;
use yew::prelude::*;
pub struct Projects;
impl Component for Projects {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self
}
fn view(&self, _ctx: &Context<Self>) -> Html {
let projects_ongoing = Project::PROJECTS_ONGOING.map(|project| {
let project = *project;
html! { <ProjectCard {project} /> }
});
let projects_finished = Project::PROJECTS_FINISHED.map(|project| {
let project = *project;
html! { <ProjectCard {project} /> }
});
html! {
<div style="
display: flex !important;
width: 100% !important;
flex-direction: column !important;
flex-wrap: wrap !important;
justify-content: center !important;
margin-bottom: 2rem !important;
">
<h2 style="text-align: center !important;">{ "ongoing projects" }</h2>
<div style="
display: flex !important;
width: 100% !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: flex-start !important;
margin-bottom: 1rem !important;
">{ for projects_ongoing }</div>
<h2 style="text-align: center !important;">{ "finished projects" }</h2>
<div style="
display: flex !important;
width: 100% !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: flex-start !important;
">{ for projects_finished }</div>
</div>
}
}
}