Compare commits
1 Commits
develop
...
rewrite/ru
| Author | SHA1 | Date | |
|---|---|---|---|
| 54a7bb3975 |
1
.gitignore
vendored
@@ -3,4 +3,3 @@ dist/
|
|||||||
pkg/
|
pkg/
|
||||||
target/
|
target/
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
static/
|
|
||||||
|
|||||||
36
Cargo.toml
@@ -1,37 +1,29 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "web_iouring"
|
name = "web_luciel"
|
||||||
version = "0.0.0-develop"
|
version = "0.0.0-develop"
|
||||||
authors = ["iouring"]
|
authors = ["luciel"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.91"
|
rust-version = "1.85"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
js-sys = "0.3"
|
js-sys = "0.3"
|
||||||
yew = { git = "https://github.com/yewstack/yew.git", rev = "21f373b", features = [
|
yew = { git = "https://github.com/yewstack/yew.git", rev = "910efcc", features = ["csr"] }
|
||||||
"csr",
|
yew-router = { git = "https://github.com/yewstack/yew.git", rev = "910efcc" }
|
||||||
] }
|
|
||||||
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 = ["HtmlCanvasElement", "WebGlBuffer", "WebGlProgram", "WebGlRenderingContext", "WebGl2RenderingContext", "WebGlShader", "WebGlUniformLocation", "Navigator", "Clipboard"]
|
features = [
|
||||||
|
'HtmlCanvasElement',
|
||||||
|
'WebGlBuffer',
|
||||||
|
'WebGlProgram',
|
||||||
|
'WebGlRenderingContext',
|
||||||
|
'WebGl2RenderingContext',
|
||||||
|
'WebGlShader',
|
||||||
|
'WebGlUniformLocation',
|
||||||
|
]
|
||||||
|
|||||||
6
docker-compose.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: ./
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
46
index.html
@@ -1,41 +1,31 @@
|
|||||||
<!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>i0ur.ing ~ welcome</title>
|
<title>celesteflare.cc ~ lunary</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/iouring.png" />
|
<link data-trunk rel="copy-file" href="public/buttons/luciel.png"/>
|
||||||
<link data-trunk rel="copy-file" href="public/buttons/wasm.png" />
|
<link data-trunk rel="copy-file" href="public/buttons/servfail.png"/>
|
||||||
<link data-trunk rel="copy-file" href="public/buttons/dataforest.png" />
|
<link data-trunk rel="copy-file" href="public/buttons/wasm.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/fedora.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/artix.png" />
|
|
||||||
<link data-trunk rel="copy-file" href="public/buttons/nixos.png" />
|
|
||||||
<link data-trunk rel="copy-file" href="public/buttons/chimera.png" />
|
|
||||||
<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="copy-file" href="public/socials/fedi.svg"/>
|
||||||
<link data-trunk rel="rust" />
|
<link data-trunk rel="copy-file" href="public/socials/git.svg"/>
|
||||||
<base data-trunk-public-url />
|
<link data-trunk rel="copy-file" href="public/socials/lastfm.svg"/>
|
||||||
|
|
||||||
|
<link data-trunk rel="sass" href="main.scss"/>
|
||||||
|
<link data-trunk rel="rust"/>
|
||||||
|
<base data-trunk-public-url/>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma/css/bulma.min.css"/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
24
justfile
@@ -1,13 +1,25 @@
|
|||||||
#!/usr/bin/env just --justfile
|
#!/usr/bin/env just --justfile
|
||||||
|
|
||||||
setup:
|
install-wasm-pack:
|
||||||
rustup target add wasm32-unknown-unknown
|
cargo install wasm-pack
|
||||||
|
|
||||||
install:
|
install-tauri:
|
||||||
cargo install --locked wasm-pack trunk --force
|
cargo install tauri-cli
|
||||||
|
|
||||||
debug:
|
trunk-serve:
|
||||||
trunk serve
|
trunk serve
|
||||||
|
|
||||||
build:
|
build:
|
||||||
trunk build --release
|
trunk build
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
87
main.scss
@@ -1,49 +1,46 @@
|
|||||||
@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: freemono, monocraft, monospace !important;
|
font-family: 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.input, .select select, .textarea {
|
||||||
backdrop-filter: blur(4px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input,
|
|
||||||
.select select,
|
|
||||||
.textarea {
|
|
||||||
backdrop-filter: blur(4px);
|
backdrop-filter: blur(4px);
|
||||||
background-color: white, 0.213125 !important;
|
--bulma-input-h: 232 !important;
|
||||||
border-color: white !important;
|
--bulma-input-s: 97% !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,
|
||||||
@@ -52,30 +49,14 @@ a.navbar-item:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-moz-selection {
|
::-moz-selection {
|
||||||
background: #F5C2E740 !important;
|
background: hsla(232, 97%, 85%, 0.4125) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection {
|
::selection {
|
||||||
background: #F5C2E740 !important;
|
background: hsla(232, 97%, 85%, 0.4125) !important;
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #F5C2E7FF !important;
|
|
||||||
text-decoration: none !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: underline !important;
|
text-decoration: underline;
|
||||||
filter: url("post.bloom.svg#process") !important;
|
filter: url("post.bloom.svg#process")
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 4.8 MiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
BIN
public/buttons/luciel.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 31 KiB |
@@ -1,9 +1,11 @@
|
|||||||
#version 300 es
|
#version 300 es
|
||||||
precision highp float;
|
precision lowp 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;
|
||||||
@@ -17,42 +19,48 @@ 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) {
|
||||||
return fract(sin(n) * 43758.5453);
|
n = fract(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);
|
||||||
return mix(rand(i), rand(i + 1.0), f * f * (3.0 - 2.0 * f));
|
float u = 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));
|
||||||
vec3 u = cross(s, f);
|
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));
|
||||||
|
|
||||||
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(
|
||||||
k_vx * v.x + c, k_vx * v.y - v.z, k_vx * v.z + v.y,
|
v.x * v.x * k + c,
|
||||||
k_vy * v.x + v.z, k_vy * v.y + c, k_vy * v.z - v.x,
|
v.y * v.x * k - v.z,
|
||||||
k_vz * v.x - v.y, k_vz * v.y + v.x, k_vz * v.z + c
|
v.z * v.x * k + v.y,
|
||||||
|
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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,10 +74,48 @@ 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) * factor;
|
return (p.x + p.y + p.z - s) * 0.57735027;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@@ -99,6 +145,10 @@ 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)));
|
||||||
@@ -124,41 +174,96 @@ 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 = smoothstep(1.0, 0.0, -uv.y * (scale * 0.01));
|
float w = smootherstep(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;
|
||||||
float timeScale = time / scale;
|
uv.y += 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);
|
||||||
vec2 s = floor(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 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 / resolution.xy;
|
vec2 uv = fragCoord * (vec2(1.0) / 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);
|
||||||
|
|
||||||
@@ -168,8 +273,9 @@ 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 uvSnow = (fragCoord * 2.0 - resolution.xy) / min(resolution.x, resolution.y);
|
vec2 p = fragCoord.xy / resolution.xy;
|
||||||
fragColor += vec4(vec3(snow(uvSnow, 4.0)), 0.5) * 0.7;
|
vec2 uvSnow = (fragCoord.xy * 2.0 - resolution.xy) / min(resolution.x, resolution.y);
|
||||||
|
fragColor += mix(vec4(vec3(snow(uvSnow, 4.0)), 0.5) + vec4(vec3(snow(uvSnow, 3.0)), 0.5), vec4(0.0), vec4(0.7));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
45
public/socials/fedi.svg
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?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>
|
||||||
|
After Width: | Height: | Size: 21 KiB |
1
public/socials/git.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 834 B |
5
public/socials/lastfm.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
452
src/main.rs
@@ -1,46 +1,29 @@
|
|||||||
#![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::JsCast;
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use web_sys::{HtmlCanvasElement, WebGl2RenderingContext as GL2, window};
|
use wasm_bindgen::JsCast;
|
||||||
|
use web_sys::{window, HtmlCanvasElement, WebGl2RenderingContext as GL2};
|
||||||
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::blog::author::Author;
|
use crate::pages::landing::Landing;
|
||||||
use crate::pages::blog::authors::Authors;
|
use crate::pages::projects::Projects;
|
||||||
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,
|
||||||
@@ -48,274 +31,172 @@ 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 = ();
|
type Message = Msg;
|
||||||
type Properties = ();
|
type Properties = ();
|
||||||
|
|
||||||
fn create(_ctx: &Context<Self>) -> Self {
|
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
|
||||||
Self {
|
match msg {
|
||||||
node_ref: NodeRef::default(),
|
Msg::ToggleNavbar => {
|
||||||
|
self.navbar_active = !self.navbar_active;
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create(_ctx: &Context<Self>) -> Self {
|
||||||
|
Self { node_ref: NodeRef::default(), navbar_active: false }
|
||||||
|
}
|
||||||
|
|
||||||
fn view(&self, _ctx: &Context<Self>) -> Html {
|
fn view(&self, _ctx: &Context<Self>) -> Html {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<canvas width="100%" height="100%" style="
|
<BrowserRouter>
|
||||||
|
<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()}/>
|
||||||
<BrowserRouter>
|
|
||||||
<header style="
|
|
||||||
z-index: 2 !important;
|
|
||||||
display: flex !important;
|
|
||||||
color: white !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;
|
|
||||||
">
|
|
||||||
<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="
|
<div style="
|
||||||
background-color: rgba(0, 0, 0, 0.3125) !important;
|
overflow: scroll !important;
|
||||||
backdrop-filter: blur(6px) !important;
|
left: 0 !important;
|
||||||
padding: 4px 0px 0px 4px !important;
|
margin-top: var(--bulma-navbar-height) !important;
|
||||||
border-radius: 1.0rem !important;
|
width: 100% !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;
|
height: 100% !important;
|
||||||
margin-top: auto !important;
|
">
|
||||||
margin-bottom: auto !important;
|
<Switch<Route> render={switch} />
|
||||||
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 {
|
if first_render { self.view_canvas(); }
|
||||||
self.view_canvas();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch(routes: Route) -> Html {
|
fn switch(routes: Route) -> Html {
|
||||||
match routes {
|
match routes {
|
||||||
Route::About => {
|
Route::Landing => { html! { <Landing /> } }
|
||||||
html! { <About /> }
|
|
||||||
}
|
|
||||||
|
|
||||||
Route::Entries => {
|
Route::About => { html! { <About /> } }
|
||||||
html! { <Entries /> }
|
Route::Projects => { html! { <Projects /> } }
|
||||||
}
|
|
||||||
Route::Entry { id } => {
|
|
||||||
html! { <Entry id={id as u8} /> }
|
|
||||||
}
|
|
||||||
Route::Authors => {
|
|
||||||
html! { <Authors /> }
|
|
||||||
}
|
|
||||||
Route::Author { id } => {
|
|
||||||
html! { <Author id={id as u8} /> }
|
|
||||||
}
|
|
||||||
|
|
||||||
Route::FindMe => {
|
Route::NotFound => { html! { <PageNotFound /> } }
|
||||||
html! { <FindMe /> }
|
|
||||||
}
|
|
||||||
|
|
||||||
Route::Projects => {
|
|
||||||
html! { <Projects /> }
|
|
||||||
}
|
|
||||||
Route::NotFound => {
|
|
||||||
html! { <PageNotFound /> }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
fn view_buttons(&self) -> Html {
|
fn view_header(&self, _ctx: &Context<Self>) -> Html {
|
||||||
|
let active_class = if self.navbar_active { "is-active" } else { "" };
|
||||||
html! {
|
html! {
|
||||||
<div style="
|
<nav class="navbar" style="
|
||||||
z-index: 1 !important;
|
z-index: 1 !important;
|
||||||
display: flex !important;
|
position: fixed !important;
|
||||||
flex-wrap: wrap !important;
|
top: 0px !important;
|
||||||
flex-direction: row !important;
|
left: 0px !important;
|
||||||
justify-content: center !important;
|
width: 100% !important;
|
||||||
min-width: 70vw !important;
|
padding: 0 !important;
|
||||||
width: 70vh !important;
|
--bulma-navbar-background-color: #1E1E2E80 !important;
|
||||||
max-width: calc(100vw - 18px) !important;
|
backdrop-filter: blur(4px) !important;
|
||||||
height: fit-content !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
margin-right: auto !important;
|
|
||||||
margin-left: auto !important;
|
|
||||||
">
|
">
|
||||||
<a style="
|
<div class="navbar-brand">
|
||||||
width: 88px !important;
|
<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" />
|
||||||
height: 31px !important;
|
<button class={classes!("navbar-burger", "burger", active_class)} aria-label="menu" aria-expanded="false" onclick={_ctx.link().callback(|_| Msg::ToggleNavbar)}>
|
||||||
margin-right: 0.2rem !important;
|
<span aria-hidden="true"></span>
|
||||||
image-rendering: pixelated !important;
|
<span aria-hidden="true"></span>
|
||||||
image-resolution: from-image !important;
|
<span aria-hidden="true"></span>
|
||||||
image-orientation: from-image !important;
|
</button>
|
||||||
" 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>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,35 +206,25 @@ 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()
|
.unwrap().dyn_into::<GL2>().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(
|
gl.buffer_data_with_array_buffer_view(GL2::ARRAY_BUFFER, &Float32Array::from(vec![
|
||||||
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,
|
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(
|
gl.buffer_data_with_array_buffer_view(GL2::ARRAY_BUFFER, &Float32Array::from(vec![
|
||||||
GL2::ARRAY_BUFFER,
|
1.0, 0.0, 0.0, 1.0,
|
||||||
&Float32Array::from(
|
0.0, 1.0, 0.0, 1.0,
|
||||||
vec![
|
0.0, 0.0, 1.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,
|
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));
|
||||||
@@ -389,11 +260,7 @@ 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
|
if !gl.get_program_parameter(&shader_program, GL2::LINK_STATUS).as_bool().unwrap() {
|
||||||
.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));
|
||||||
@@ -414,9 +281,7 @@ 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![
|
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];
|
||||||
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");
|
||||||
@@ -424,17 +289,10 @@ 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(
|
gl.draw_elements_with_i32(GL2::TRIANGLES, element_indices.len() as i32, GL2::UNSIGNED_SHORT, 0);
|
||||||
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()
|
window().unwrap().request_animation_frame(f.as_ref().unchecked_ref())
|
||||||
.unwrap()
|
|
||||||
.request_animation_frame(f.as_ref().unchecked_ref())
|
|
||||||
.expect("should register `requestAnimationFrame` OK");
|
.expect("should register `requestAnimationFrame` OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,21 +308,13 @@ 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(
|
gl.uniform2fv_with_f32_array(unim_res.as_ref(), vec![canvas.width() as f32, canvas.height() as f32].as_slice());
|
||||||
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(
|
gl.draw_elements_with_i32(GL2::TRIANGLES, element_indices.len() as i32, GL2::UNSIGNED_SHORT, 0);
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,82 +12,40 @@ impl Component for About {
|
|||||||
fn view(&self, _ctx: &Context<Self>) -> Html {
|
fn view(&self, _ctx: &Context<Self>) -> Html {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<div>
|
<div class="tile is-parent container">
|
||||||
<img alt="insert pfp here" style="
|
{ self.view_info_card() }
|
||||||
float: left !important;
|
</div>
|
||||||
margin-right: 10px !important;
|
</>
|
||||||
border-radius: 0.5rem !important;
|
}
|
||||||
" loading="eager" width="96px" height="96px" src="profile.avif" />
|
}
|
||||||
<div style="
|
}
|
||||||
display: flex !important;
|
impl About {
|
||||||
flex-direction: column !important;
|
fn view_info_card(&self) -> Html {
|
||||||
max-height: 96px !important;
|
html! {
|
||||||
">
|
<>
|
||||||
<p style="
|
<div class="box is-small is-flex-shrink-5 mb-5 mt-5">
|
||||||
display: flex !important;
|
<img alt="insert pfp here" loading="eager" class="image is-128x128 is-square is-inline-block mg-small" src="profile.avif" />
|
||||||
color: transparent !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;">
|
||||||
flex-direction: row !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>
|
||||||
align-items: center !important;
|
<p class="column is-narrow" style="background-clip: text !important; background-image: linear-gradient(45deg, #5BCEFAFF, #F5A9B8FF, #FFFFFFFF) !important;">
|
||||||
width: fit-content !important;
|
<p>{r"she/they · transfem and poly"}</p>
|
||||||
background-clip: text !important;
|
<p>{r"programmer and freelancer"}</p>
|
||||||
background-image: linear-gradient(45deg, #5BCEFAFF, #F5A9B8FF, #FFFFFFFF) !important;
|
<p>{r"certified catgirl™"}</p>
|
||||||
-webkit-background-clip: text !important;
|
</p>
|
||||||
margin: unset !important;
|
</div>
|
||||||
filter: url(post.bloom.svg#process) !important;
|
<hr style="background-color: #B4BEFE60 !important;" />
|
||||||
">
|
<p class="subtitle">{r#"about me"#}</p>
|
||||||
<img loading="eager" alt="ket" src="oneko.gif" />{r" lia · they/she · transfemby"}</p>
|
<div class="content is-size-7">{r#"
|
||||||
<p style="margin: unset !important;">
|
hellow there! i'm lunary but you can also just call me luciel, luci or luni.
|
||||||
<p style="margin: unset !important;">{r"certified catgirl™"}</p>
|
personal preference is ordered.
|
||||||
<p style="margin: unset !important;">{r"software engineer"}</p>
|
thing's i'm interested in are gamedev, devsecops, exploits, hacking, music and cooking.
|
||||||
<p style="margin: unset !important;">{r"professional yapper"}</p>
|
in my free-time i mostly work on my private projects or spent time with my partners or online friends.
|
||||||
<p style="margin: unset !important;">{r"neurospicy and disabled"}</p>
|
my knowledge is based on autodidactics and experiences with (former) friends.
|
||||||
</p>
|
looking for a job/internship at the moment because i wasn't able to finish my previous internship due to some financial circumstances.
|
||||||
</div>
|
you can find projects i work on somewhere in the header.
|
||||||
<p style="
|
i may or may not update information stated here but that's it for now.
|
||||||
font-weight: bold !important;
|
"#}
|
||||||
font-style: italic !important;
|
</div>
|
||||||
font-size: xx-large !important;
|
|
||||||
">{r">intro_"}<br /><p style="
|
|
||||||
font-weight: normal !important;
|
|
||||||
font-style: normal !important;
|
|
||||||
font-size: medium !important;
|
|
||||||
">{r#"
|
|
||||||
name's lia or lucy. we are creating.
|
|
||||||
trying to provide a safe space in the internet.
|
|
||||||
our goal's to make this world a better ~ less trashy ~ place.
|
|
||||||
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>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,299 +0,0 @@
|
|||||||
#[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.
|
|
||||||
"#,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
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()}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
pub mod author;
|
|
||||||
pub mod authorcard;
|
|
||||||
pub mod authors;
|
|
||||||
pub mod content;
|
|
||||||
pub mod entries;
|
|
||||||
pub mod entry;
|
|
||||||
pub mod entrycard;
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
73
src/pages/landing.rs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
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>>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -11,21 +11,16 @@ impl Component for PageNotFound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self, _ctx: &Context<Self>) -> Html {
|
fn view(&self, _ctx: &Context<Self>) -> Html {
|
||||||
|
// TODO: ... | personalize
|
||||||
html! {
|
html! {
|
||||||
<div style="
|
<section class="hero is-danger is-bold is-large">
|
||||||
display: flex !important;
|
<div class="hero-body">
|
||||||
text-align: center !important;
|
<div class="container">
|
||||||
flex-direction: row !important;
|
<h1 class="title">{ "Page not found" }</h1>
|
||||||
align-items: center !important;
|
<h2 class="subtitle">{ "Page page does not seem to exist" }</h2>
|
||||||
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>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
73
src/pages/projects.rs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
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>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#[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",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
pub mod content;
|
|
||||||
pub mod projectcard;
|
|
||||||
pub mod projects;
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||