Refactor: Vite

This commit is contained in:
wont-stream 2025-04-08 16:22:07 -04:00
parent 69f8f74182
commit 7fd41cd78c
22 changed files with 569 additions and 413 deletions

0
src/components/app.css Normal file
View file

13
src/components/app.tsx Normal file
View file

@ -0,0 +1,13 @@
import Navbar from './navbar';
import Container from './container';
import './app.css';
export default () => {
return (
<>
<Navbar />
<Container />
</>
)
}

View file

@ -0,0 +1,44 @@
import { useState } from 'preact/hooks';
import Heart from '../heart';
const api = "lanyard.creations.works"
const statusMap = {
online: "border-success-subtle",
idle: "border-warning-subtle",
dnd: "border-danger-subtle",
offline: "border-light-subtle",
}
export default () => {
const [status, setStatus] = useState<keyof typeof statusMap>('offline');
fetch(`https://${api}/v1/users/1273447359417942128`)
.then(req => req.json())
.then((res) => {
if (res.data.discord_status) {
setStatus(res.data.discord_status);
} else {
setStatus('offline');
}
})
return (
<>
<div class="container bg-body-tertiary shadow text-center position-absolute top-50 start-50 translate-middle mx-auto py-4">
<img src="favicon.svg" class={`img-thumbnail rounded-circle border border-4 ${statusMap[status]}`} alt="..." width="100" />
<br />
<h1>Seth</h1>
<h6 class="lead">Dedicated Backend Developer
<br />
<br />
<small class="text-body-secondary">
With a passsion for high-fidelity audio, gaming, and web development
</small>
</h6>
<Heart />
</div>
</>
)
}

View file

@ -0,0 +1,18 @@
:root {
--bpm: 0;
}
@keyframes pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.heart {
animation: pulse calc(60s / var(--bpm)) infinite ease;
}

View file

@ -0,0 +1,68 @@
import { useState } from 'preact/hooks';
import './index.css';
export default () => {
const [heartrate, setHeartrate] = useState(0);
const ws = new WebSocket("wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9");
let hrTimeout: ReturnType<typeof setTimeout>;
const setHrInterval = () => {
hrTimeout = setTimeout(() => {
return setHeartrate(0);
}, 6000);
};
ws.onopen = () => {
ws.send(
JSON.stringify({
topic: "hr:0BCA",
event: "phx_join",
payload: {},
ref: 0,
}),
);
setInterval(() => {
ws.send(
JSON.stringify({
topic: "phoenix",
event: "heartbeat",
payload: {},
ref: 0,
}),
);
}, 10000);
return setHrInterval();
};
ws.onmessage = ({ data }) => {
const { event, payload } = JSON.parse(data);
switch (event) {
case "hr_update": {
clearTimeout(hrTimeout);
setHrInterval();
setHeartrate(payload.hr);
break;
}
default: {
break;
}
}
};
return (
<>
<div style={heartrate == 0 ? "display:none" : `--bpm: ${heartrate};`} class="heart">
<br />
<span>{heartrate} BPM</span>
</div>
</>
)
}

View file

@ -0,0 +1,22 @@
export default () => {
return (
<>
<nav class="navbar shadow fixed-top" style="background-color: var(--bs-content-bg); border-bottom: var(--bs-border-width) solid var(--bs-content-border-color);">
<div class="container-fluid">
<div class="navbar-brand">
<img src="favicon.svg" alt="Logo" width="24" height="24" class="d-inline-block align-text-top" />
Seth
</div>
<span class="navbar-text">
IPv4 dot Army
</span>
<div class="d-flex hstack gap-2" role="search">
<button type="button" class="btn btn-outline-success btn-sm">🗕</button>
<button type="button" class="btn btn-outline-warning btn-sm">🗖</button>
<button type="button" class="btn btn-outline-danger btn-sm">🗙</button>
</div>
</div>
</nav>
</>
)
}

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="none"><g filter="url(#a)"><g clip-path="url(#b)"><rect width="256" height="256" fill="#1a1a1a" rx="128"/><path stroke="#787878" stroke-width="10" d="m150.035 192 142 1"/><ellipse cx="87" cy="120" fill="#e8e8e8" rx="13" ry="8"/><path fill="#e8e8e8" fill-rule="evenodd" d="M101.139 38.263c-1.6764-7.0088-9.9916-9.9969-15.7458-5.6584L52.0779 57.7231c-.9878.7448-2.2162 1.0925-3.4501 1.0038-2.8433-.2042-5.7211-.3084-8.6278-.3084-52.5128 0-97 34.4995-97 79.1815 0 22.093 11.0445 44.911 28.4288 62.117C-11.1382 216.973 13.0784 229 40 229c9.3865 0 18.4441-1.462 27-4.098V251c0 2.762 2.2386 5 5 5h20.0132c2.5448 0 4.6836-1.911 4.9686-4.44l2.9543-26.219c.2799-2.489 2.3799-4.324 4.8249-4.861.724-.159 1.436-.353 2.132-.583 2.205-.729 4.208-1.797 5.895-3.144 1.688-1.346 3.027-2.945 3.94-4.704.377-.727.679-1.647.903-2.61.51-2.192 1.987-4.165 4.164-4.733l2.084-.544c.412-.107.837-.162 1.262-.162h10.218c.425 0 .85.055 1.262.162l10.258 2.676c.412.108.837.162 1.262.162H154c2.761 0 5-2.238 5-5v-18c0-2.761-2.239-5-5-5h-29.191C132.533 165.993 137 151.65 137 137.6c0-19.979-9.03-38.0624-23.615-51.8194-.73-.6885-1.255-1.5689-1.489-2.5447L101.139 38.263Zm11.793 140.755c.045-.012.092-.018.138-.018h11.739c-4.421 7.446-9.909 14.453-16.238 20.717C97.2163 210.956 82.9836 219.978 67 224.902v-10.524c13.1215-4.569 24.9171-12.247 34.536-21.768 4.28-4.235 8.099-8.806 11.396-13.592Zm0 0-22.3113 5.82c-.4121.108-.8363.162-1.2621.162H72c-2.7614 0-5 2.239-5 5v24.378C58.4813 217.344 49.4038 219 40 219c-23.8886 0-45.67204-10.687-61.5365-26.39C-37.4496 176.859-47 156.477-47 137.6c0-37.256 37.89237-69.1815 87-69.1815 3.8926 0 7.7237.2036 11.4777.5979 1.2591.1323 2.5215-.218 3.5324-.9802l30.3067-22.8501c2.8771-2.1693 7.0347-.6752 7.8729 2.8292l9.7033 40.5664c.241 1.0061.788 1.9129 1.565 2.5952C118.617 103.6 127 119.919 127 137.6c0 13.801-5.105 28.406-14.068 41.418Zm-11.601 33.945c-.257 2.282 1.628 4.279 3.809 3.558 1.65-.545 3.148-1.344 4.411-2.351 1.262-1.007 2.263-2.203 2.946-3.519.546-1.051.88-2.163.993-3.294.024-.245-.206-.431-.445-.369-.03.008-.061.012-.092.012h-6.482c-2.545 0-4.684 1.912-4.969 4.44l-.171 1.523Z" clip-rule="evenodd"/><g filter="url(#c)" opacity=".25"><path fill="#e8e8e8" fill-rule="evenodd" d="M114.139 38.263c-1.676-7.0088-9.992-9.9969-15.7458-5.6584L63.5434 58.8801c-3.4643-.3052-6.9821-.4616-10.5434-.4616-52.51276 0-97 34.4995-97 79.1815 0 22.093 11.0445 44.911 28.4288 62.117C1.86185 216.973 26.0784 229 53 229c9.3865 0 18.4441-1.462 27-4.098V256h29.481l3.945-35.005c2.22-.047 4.412-.419 6.467-1.098 2.205-.729 4.208-1.797 5.895-3.144 1.688-1.346 3.027-2.945 3.94-4.704.887-1.708 1.356-4.479 1.382-6.382L137.5 204H149l11.5 3H172v-28h-34.191C145.533 165.993 150 151.65 150 137.6c0-20.49-9.497-38.9861-24.745-52.8664L114.139 38.263Zm11.793 140.755L126 179h11.809c-4.421 7.446-9.909 14.453-16.238 20.717-11.355 11.239-25.5874 20.261-41.571 25.185v-10.524c13.1215-4.569 24.917-12.247 34.536-21.768 4.28-4.235 8.099-8.806 11.396-13.592Zm0 0L103 185H80v29.378C71.4813 217.344 62.4038 219 53 219c-23.8886 0-45.67204-10.687-61.53647-26.39C-24.4496 176.859-34 156.477-34 137.6c0-37.256 37.89237-69.1815 87-69.1815 3.8926 0 7.7237.2036 11.4777.5979l1.9593.2058 1.5731-1.186 36.4029-27.4468 11.48 47.9923.37 1.5465 1.195 1.0487C131.617 103.6 140 119.919 140 137.6c0 13.801-5.105 28.406-14.068 41.418Zm-12.092 38.305c1.476-.078 2.929-.349 4.3-.802 1.65-.545 3.148-1.344 4.411-2.351 1.262-1.007 2.263-2.203 2.946-3.519.625-1.204.973-2.487 1.027-3.788L126 207h-10.997l-1.163 10.323Z" clip-rule="evenodd"/></g></g></g><defs><filter id="a" width="276" height="256" x="-20" y="0" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/><feOffset dx="-20"/><feGaussianBlur stdDeviation="10"/><feComposite in2="hardAlpha" k2="-1" k3="1" operator="arithmetic"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/><feBlend in2="shape" result="effect1_innerShadow_1591_192"/></filter><filter id="c" width="256" height="265.418" x="-64" y="10.582" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_1591_192" stdDeviation="10"/></filter><clipPath id="b"><rect width="256" height="256" fill="#fff" rx="128"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -1,20 +0,0 @@
@import "halfmoon/css/halfmoon.css";
:root {
--bpm: 0;
}
@keyframes pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.heart {
animation: pulse calc(60s / var(--bpm)) infinite ease;
}

View file

@ -1,169 +0,0 @@
<!DOCTYPE html>
<html lang="en" data-bs-theme="dark" data-bs-core="default">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Seth @ IPv4 dot Army</title>
<link rel="stylesheet" href="index.css">
</head>
<body class="container-fluid">
<nav class="navbar fixed-top bg-body-secondary">
<div class="container-fluid">
<div class="navbar-brand">
<img src="./favicon.svg" alt="Logo" width="24" height="24" />
Seth
</div>
<div class="d-flex hstack gap-2">
<button type="button" class="btn btn-outline-success btn-sm">🗕︎</button>
<button type="button" class="btn btn-outline-warning btn-sm">🗖︎</button>
<button type="button" class="btn btn-outline-danger btn-sm">🗙︎</button>
</div>
</div>
</nav>
<div class="container vstack gap-5 position-absolute top-50 start-50 translate-middle">
<div class="container bg-body-tertiary shadow pt-4 pb-4 rounded">
<div class="row">
<div class="col-12 text-center">
<img src="./favicon.svg" alt="pfp" width="100rem" height="100rem" id="pfp"
class="border border-4 rounded-circle border-light-subtle">
<h1>Seth</h1>
<p class="lead">A backend developer.</p>
</div>
</div>
<div class="row row-cols-auto justify-content-center">
<div class="col">
<a class="link-underline-opacity-100-hover" href="https://git.creations.works/seth">
Forgejo
</a>
</div>
<div class="col">
<a class="link-secondary link-underline-opacity-100-hover" href="https://github.com/wont-stream">
GitHub
</a>
</div>
<div class="col">
<a class="link-success link-underline-opacity-100-hover" href="https://cash.app/$echoedAway">
Cash App
</a>
</div>
</div>
<div class="row row-cols-auto justify-content-center text-center">
<a id="music"></a>
</div>
<br>
<div class="row row-cols-auto justify-content-center text-center" id="heartrate">
</div>
</div>
</div>
<script>
const pfp = document.getElementById("pfp");
const music = document.getElementById("music");
const heartrate = document.getElementById("heartrate");
const lanyard = new WebSocket("wss://lanyard.creations.works/socket");
lanyard.onopen = () => {
lanyard.send(JSON.stringify({
op: 2,
d: {
subscribe_to_id: "1273447359417942128"
}
}))
}
lanyard.onmessage = ({ data }) => {
const { op, d } = JSON.parse(data)
switch (op) {
case 0: {
pfp.className = `border border-4 rounded-circle ${{
"online": "border-success-subtle",
"idle": "border-warning-subtle",
"dnd": "border-danger-subtle",
"offline": "border-light-subtle"
}[d.discord_status]}`
const tidalData = d.activities.filter((act) => {
return act?.application_id === "1130698654987067493";
})[0];
if (tidalData) {
const [color, trackId] = tidalData?.assets?.small_text.split("|");
music.style.color = color;
music.href = `https://tidal.com/browse/track/${trackId}/u`
music.innerHTML = `Listening to<br>${tidalData?.name.replace(
/\s?[\(\[].*?[\)\]]/g,
"",
)} by ${tidalData?.state}`
}
break
}
case 1: {
setInterval(async () => {
lanyard.send(JSON.stringify({
op: 3,
}))
}, d.heartbeat_interval)
}
}
}
const hyperate = new WebSocket("wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9",);
let hrTimeout;
const setHrInterval = async () => {
hrTimeout = setTimeout(async () => {
heartrate.innerHTML = "";
}, 6000);
};
hyperate.onopen = async () => {
hyperate.send(
JSON.stringify({
topic: "hr:0BCA",
event: "phx_join",
payload: {},
ref: 0,
}),
);
setInterval(async () => {
hyperate.send(
JSON.stringify({
topic: "phoenix",
event: "heartbeat",
payload: {},
ref: 0,
}),
);
}, 10000);
return await setHrInterval();
};
hyperate.onmessage = async ({ data }) => {
const { event, payload } = JSON.parse(data);
switch (event) {
case "hr_update": {
clearTimeout(hrTimeout);
await setHrInterval();
document.documentElement.style.setProperty("--bpm", payload.hr);
heartrate.innerHTML = `<div class="heart">♥️<br /><span>${payload.hr} BPM</span></div>`;
break;
}
default: {
break;
}
}
};
</script>
</body>
</html>

View file

@ -1,107 +0,0 @@
const pfp = document.getElementById("pfp");
const music = document.getElementById("music");
const heartrate = document.getElementById("heartrate");
const lanyard = new WebSocket("wss://lanyard.creations.works/socket");
lanyard.onopen = () => {
lanyard.send(JSON.stringify({
op: 2,
d: {
subscribe_to_id: "1273447359417942128"
}
}))
}
lanyard.onmessage = ({ data }) => {
const { op, d } = JSON.parse(data)
switch (op) {
case 0: {
pfp.className = `border border-4 rounded-circle ${{
"online": "border-success-subtle",
"idle": "border-warning-subtle",
"dnd": "border-danger-subtle",
"offline": "border-light-subtle"
}[d.discord_status]}`
const tidalData = d.activities.filter((act) => {
return act?.application_id === "1130698654987067493";
})[0];
if (tidalData) {
const [color, trackId] = tidalData?.assets?.small_text.split("|");
music.style.color = color;
music.href = `https://tidal.com/browse/track/${trackId}/u`
music.innerHTML = `Listening to<br>${tidalData?.name.replace(
/\s?[\(\[].*?[\)\]]/g,
"",
)} by ${tidalData?.state}`
}
break
}
case 1: {
setInterval(async () => {
lanyard.send(JSON.stringify({
op: 3,
}))
}, d.heartbeat_interval)
}
}
}
const hyperate = new WebSocket(
// Yes, the token can be hardcoded.
"wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9",
);
let hrTimeout;
const setHrInterval = async () => {
hrTimeout = setTimeout(async () => {
heartrate.innerHTML = "";
}, 6000);
};
hyperate.onopen = async () => {
hyperate.send(
JSON.stringify({
topic: "hr:0BCA",
event: "phx_join",
payload: {},
ref: 0,
}),
);
setInterval(async () => {
hyperate.send(
JSON.stringify({
topic: "phoenix",
event: "heartbeat",
payload: {},
ref: 0,
}),
);
}, 10000);
return await setHrInterval();
};
hyperate.onmessage = async ({ data }) => {
const { event, payload } = JSON.parse(data);
switch (event) {
case "hr_update": {
clearTimeout(hrTimeout);
await setHrInterval();
document.documentElement.style.setProperty("--bpm", payload.hr);
heartrate.innerHTML = `<div class="heart">♥️<br /><span>${payload.hr} BPM</span></div>`;
break;
}
default: {
break;
}
}
};

6
src/main.tsx Normal file
View file

@ -0,0 +1,6 @@
import { render } from 'preact'
import './index.css'
import 'halfmoon/css/halfmoon.min.css';
import App from './components/app.tsx'
render(<App />, document.getElementById('app')!)

1
src/vite-env.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="vite/client" />