This commit is contained in:
parent
ad23ab1907
commit
a65ee6fe67
15 changed files with 564 additions and 466 deletions
44
biome.json
Normal file
44
biome.json
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||||
|
"vcs": {
|
||||||
|
"enabled": true,
|
||||||
|
"clientKind": "git",
|
||||||
|
"useIgnoreFile": false
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"ignoreUnknown": true,
|
||||||
|
"ignore": []
|
||||||
|
},
|
||||||
|
"formatter": {
|
||||||
|
"enabled": true,
|
||||||
|
"indentStyle": "tab",
|
||||||
|
"lineEnding": "lf"
|
||||||
|
},
|
||||||
|
"organizeImports": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"css": {
|
||||||
|
"formatter": {
|
||||||
|
"indentStyle": "tab",
|
||||||
|
"lineEnding": "lf"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"linter": {
|
||||||
|
"enabled": true,
|
||||||
|
"rules": {
|
||||||
|
"recommended": true,
|
||||||
|
"correctness": {
|
||||||
|
"noUnusedImports": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"javascript": {
|
||||||
|
"formatter": {
|
||||||
|
"quoteStyle": "double",
|
||||||
|
"indentStyle": "tab",
|
||||||
|
"lineEnding": "lf",
|
||||||
|
"jsxQuoteStyle": "double",
|
||||||
|
"semicolons": "always"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
bun.lock
2
bun.lock
|
@ -9,7 +9,7 @@
|
||||||
"tsx-dom": "latest",
|
"tsx-dom": "latest",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "^1.9.4",
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|
60
index.ts
60
index.ts
|
@ -1,19 +1,20 @@
|
||||||
import { build, serve, gzipSync, file, gc } from "bun";
|
import { file, gc, serve } from "bun";
|
||||||
|
|
||||||
import Backend from "./src/back"
|
import Backend from "./src/back";
|
||||||
|
|
||||||
import pkg from "./package.json";
|
import pkg from "./package.json";
|
||||||
|
|
||||||
|
|
||||||
let heartrate = 0;
|
let heartrate = 0;
|
||||||
let lanyard = {};
|
let lanyard = {};
|
||||||
|
|
||||||
require("node:fs/promises").rm("./dist", { recursive: true, force: true }).catch(() => {
|
require("node:fs/promises")
|
||||||
|
.rm("./dist", { recursive: true, force: true })
|
||||||
|
.catch(() => {
|
||||||
// ignore
|
// ignore
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!Backend.development) {
|
if (!Backend.development) {
|
||||||
await Backend.build()
|
await Backend.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = serve({
|
const server = serve({
|
||||||
|
@ -22,7 +23,7 @@ const server = serve({
|
||||||
await Backend.postAnalytics(req, server);
|
await Backend.postAnalytics(req, server);
|
||||||
|
|
||||||
if (Backend.development) {
|
if (Backend.development) {
|
||||||
await Backend.build()
|
await Backend.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Backend.Responses.file(file("./dist/index.html"));
|
return await Backend.Responses.file(file("./dist/index.html"));
|
||||||
|
@ -37,18 +38,18 @@ const server = serve({
|
||||||
},
|
},
|
||||||
|
|
||||||
"/api/server": () => {
|
"/api/server": () => {
|
||||||
const string = JSON.stringify(process)
|
const string = JSON.stringify(process);
|
||||||
const data = JSON.parse(string)
|
const data = JSON.parse(string);
|
||||||
|
|
||||||
// clear possibly data that could be sensitive
|
// clear possibly data that could be sensitive
|
||||||
data.env = {}
|
data.env = {};
|
||||||
|
|
||||||
data.availableMemory = process.availableMemory()
|
data.availableMemory = process.availableMemory();
|
||||||
data.constrainedMemory = process.constrainedMemory()
|
data.constrainedMemory = process.constrainedMemory();
|
||||||
data.cpuUsage = process.cpuUsage()
|
data.cpuUsage = process.cpuUsage();
|
||||||
data.memoryUsage = process.memoryUsage()
|
data.memoryUsage = process.memoryUsage();
|
||||||
data.uptime = process.uptime()
|
data.uptime = process.uptime();
|
||||||
data.package = pkg
|
data.package = pkg;
|
||||||
|
|
||||||
return Backend.Responses.json({ data });
|
return Backend.Responses.json({ data });
|
||||||
},
|
},
|
||||||
|
@ -64,13 +65,13 @@ const server = serve({
|
||||||
return Response.redirect("/");
|
return Response.redirect("/");
|
||||||
},
|
},
|
||||||
"/api/gc": async () => {
|
"/api/gc": async () => {
|
||||||
gc(true)
|
gc(true);
|
||||||
|
|
||||||
return Backend.Responses.ok();
|
return Backend.Responses.ok();
|
||||||
},
|
},
|
||||||
"/api/headers": async (req) => {
|
"/api/headers": async (req) => {
|
||||||
return Backend.Responses.json({ ...req.headers.toJSON() });
|
return Backend.Responses.json({ ...req.headers.toJSON() });
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
fetch: async (request, server) => {
|
fetch: async (request, server) => {
|
||||||
|
@ -86,22 +87,33 @@ const server = serve({
|
||||||
ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true);
|
ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true);
|
||||||
|
|
||||||
ws.subscribe("hyperate");
|
ws.subscribe("hyperate");
|
||||||
ws.send(JSON.stringify({ type: "hyperate", data: { hr: heartrate } }), true);
|
ws.send(
|
||||||
|
JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
|
||||||
|
true,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
message: async (ws, message) => {
|
message: async (ws, message) => {
|
||||||
ws.send(JSON.stringify({ type: "echo", data: message }), true)
|
ws.send(JSON.stringify({ type: "echo", data: message }), true);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
development: Backend.development,
|
development: Backend.development,
|
||||||
port: 2056
|
port: 2056,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Backend.Sockets.Hyperate((data) => {
|
new Backend.Sockets.Hyperate((data) => {
|
||||||
heartrate = data;
|
heartrate = data;
|
||||||
server.publish("hyperate", JSON.stringify({ type: "hyperate", data: { hr: heartrate } }), true);
|
server.publish(
|
||||||
})
|
"hyperate",
|
||||||
|
JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
new Backend.Sockets.Lanyard((data) => {
|
new Backend.Sockets.Lanyard((data) => {
|
||||||
lanyard = data;
|
lanyard = data;
|
||||||
server.publish("lanyard", JSON.stringify({ type: "lanyard", data: lanyard }), true);
|
server.publish(
|
||||||
|
"lanyard",
|
||||||
|
JSON.stringify({ type: "lanyard", data: lanyard }),
|
||||||
|
true,
|
||||||
|
);
|
||||||
});
|
});
|
|
@ -3,10 +3,12 @@
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_ENV=development bun run --hot . --watch",
|
"dev": "NODE_ENV=development bun run --hot . --watch",
|
||||||
"start": "bun run ."
|
"start": "bun run .",
|
||||||
|
"lint": "bunx biome ci . --verbose",
|
||||||
|
"lint:fix": "bunx biome check --fix"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "^1.9.4",
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
import ReconnectingWebSocket from "reconnecting-websocket";
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
private _socket: ReconnectingWebSocket;
|
private _socket: ReconnectingWebSocket;
|
||||||
|
@ -7,7 +7,9 @@ export default class {
|
||||||
private _callback: (data: number) => void;
|
private _callback: (data: number) => void;
|
||||||
|
|
||||||
constructor(callback: (data: number) => void) {
|
constructor(callback: (data: number) => void) {
|
||||||
this._socket = new ReconnectingWebSocket("wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9")
|
this._socket = new ReconnectingWebSocket(
|
||||||
|
"wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9",
|
||||||
|
);
|
||||||
this._keepAlive = null;
|
this._keepAlive = null;
|
||||||
this._interval = null;
|
this._interval = null;
|
||||||
this._callback = callback;
|
this._callback = callback;
|
||||||
|
@ -15,7 +17,7 @@ export default class {
|
||||||
this._socket.binaryType = "arraybuffer";
|
this._socket.binaryType = "arraybuffer";
|
||||||
|
|
||||||
this._socket.onopen = () => {
|
this._socket.onopen = () => {
|
||||||
console.log("Hyperate socket opened")
|
console.log("Hyperate socket opened");
|
||||||
|
|
||||||
this._socket.send(
|
this._socket.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
|
@ -36,7 +38,7 @@ export default class {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}, 10000);
|
}, 10000);
|
||||||
}
|
};
|
||||||
|
|
||||||
this._socket.onmessage = ({ data }: MessageEvent) => {
|
this._socket.onmessage = ({ data }: MessageEvent) => {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
@ -48,7 +50,7 @@ export default class {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
this._socket.onerror = () => {
|
this._socket.onerror = () => {
|
||||||
console.error("Hyperate socket error");
|
console.error("Hyperate socket error");
|
||||||
|
@ -60,7 +62,7 @@ export default class {
|
||||||
clearInterval(this._interval);
|
clearInterval(this._interval);
|
||||||
this._interval = null;
|
this._interval = null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
this._socket.onclose = () => {
|
this._socket.onclose = () => {
|
||||||
console.log("Hyperate socket closed");
|
console.log("Hyperate socket closed");
|
||||||
|
@ -72,8 +74,7 @@ export default class {
|
||||||
clearInterval(this._interval);
|
clearInterval(this._interval);
|
||||||
this._interval = null;
|
this._interval = null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private heartbeat() {
|
private heartbeat() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
import ReconnectingWebSocket from "reconnecting-websocket";
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
private _socket: ReconnectingWebSocket;
|
private _socket: ReconnectingWebSocket;
|
||||||
|
@ -6,40 +6,46 @@ export default class {
|
||||||
private _callback: (data: { [key: string]: string }) => void;
|
private _callback: (data: { [key: string]: string }) => void;
|
||||||
|
|
||||||
constructor(callback: (data: { [key: string]: string }) => void) {
|
constructor(callback: (data: { [key: string]: string }) => void) {
|
||||||
this._socket = new ReconnectingWebSocket("wss://lanyard.creations.works/socket")
|
this._socket = new ReconnectingWebSocket(
|
||||||
|
"wss://lanyard.creations.works/socket",
|
||||||
|
);
|
||||||
this._keepAlive = null;
|
this._keepAlive = null;
|
||||||
this._callback = callback;
|
this._callback = callback;
|
||||||
|
|
||||||
this._socket.binaryType = "arraybuffer";
|
this._socket.binaryType = "arraybuffer";
|
||||||
|
|
||||||
this._socket.onopen = () => {
|
this._socket.onopen = () => {
|
||||||
console.log("Lanyard socket opened")
|
console.log("Lanyard socket opened");
|
||||||
}
|
};
|
||||||
|
|
||||||
this._socket.onmessage = ({ data }: MessageEvent) => {
|
this._socket.onmessage = ({ data }: MessageEvent) => {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
|
||||||
switch (data.op) {
|
switch (data.op) {
|
||||||
case 0: {
|
case 0: {
|
||||||
this._callback(data.d)
|
this._callback(data.d);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
this._socket.send(JSON.stringify({
|
this._socket.send(
|
||||||
|
JSON.stringify({
|
||||||
op: 2,
|
op: 2,
|
||||||
d: {
|
d: {
|
||||||
subscribe_to_id: "1273447359417942128"
|
subscribe_to_id: "1273447359417942128",
|
||||||
}
|
},
|
||||||
}))
|
}),
|
||||||
|
);
|
||||||
this._keepAlive = setInterval(() => {
|
this._keepAlive = setInterval(() => {
|
||||||
this._socket.send(JSON.stringify({
|
this._socket.send(
|
||||||
op: 3
|
JSON.stringify({
|
||||||
}))
|
op: 3,
|
||||||
}, data.d.heartbeat_interval)
|
}),
|
||||||
|
);
|
||||||
|
}, data.d.heartbeat_interval);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
this._socket.onerror = () => {
|
this._socket.onerror = () => {
|
||||||
console.error("Lanyard socket error");
|
console.error("Lanyard socket error");
|
||||||
|
@ -47,7 +53,7 @@ export default class {
|
||||||
clearInterval(this._keepAlive);
|
clearInterval(this._keepAlive);
|
||||||
this._keepAlive = null;
|
this._keepAlive = null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
this._socket.onclose = () => {
|
this._socket.onclose = () => {
|
||||||
console.log("Lanyard socket closed");
|
console.log("Lanyard socket closed");
|
||||||
|
@ -55,7 +61,6 @@ export default class {
|
||||||
clearInterval(this._keepAlive);
|
clearInterval(this._keepAlive);
|
||||||
this._keepAlive = null;
|
this._keepAlive = null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,23 +5,26 @@ const development = process.env.NODE_ENV === "development";
|
||||||
|
|
||||||
const build = async () => {
|
const build = async () => {
|
||||||
return await Bun.build({
|
return await Bun.build({
|
||||||
entrypoints: ['./src/front/index.html'],
|
entrypoints: ["./src/front/index.html"],
|
||||||
outdir: './dist',
|
outdir: "./dist",
|
||||||
minify: !development,
|
minify: !development,
|
||||||
sourcemap: (development ? "inline" : "none"),
|
sourcemap: development ? "inline" : "none",
|
||||||
splitting: true,
|
splitting: true,
|
||||||
publicPath: "/assets/",
|
publicPath: "/assets/",
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const respOptions = {
|
const respOptions = {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Cache-Control": "no-cache",
|
"Cache-Control": "no-cache",
|
||||||
"Content-Encoding": "gzip",
|
"Content-Encoding": "gzip",
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
const okResp = new Response(Bun.gzipSync(JSON.stringify({ data: "ok" })), respOptions)
|
const okResp = new Response(
|
||||||
|
Bun.gzipSync(JSON.stringify({ data: "ok" })),
|
||||||
|
respOptions,
|
||||||
|
);
|
||||||
const Responses = {
|
const Responses = {
|
||||||
ok: () => {
|
ok: () => {
|
||||||
return okResp.clone();
|
return okResp.clone();
|
||||||
|
@ -35,12 +38,15 @@ const Responses = {
|
||||||
"Content-Type": file.type,
|
"Content-Type": file.type,
|
||||||
"Cache-Control": "public, max-age=31536000",
|
"Cache-Control": "public, max-age=31536000",
|
||||||
"Content-Encoding": "gzip",
|
"Content-Encoding": "gzip",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const postAnalytics = async (req: Request | Bun.BunRequest, server: Bun.Server) => {
|
const postAnalytics = async (
|
||||||
|
req: Request | Bun.BunRequest,
|
||||||
|
server: Bun.Server,
|
||||||
|
) => {
|
||||||
return await fetch("https://plausible.creations.works/api/event", {
|
return await fetch("https://plausible.creations.works/api/event", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -50,7 +56,9 @@ const postAnalytics = async (req: Request | Bun.BunRequest, server: Bun.Server)
|
||||||
req.headers.get("CF-Connecting-IP") ||
|
req.headers.get("CF-Connecting-IP") ||
|
||||||
req.headers.get("X-Real-IP") ||
|
req.headers.get("X-Real-IP") ||
|
||||||
req.headers.get("X-Forwarded-For")?.split(",")[0] ||
|
req.headers.get("X-Forwarded-For")?.split(",")[0] ||
|
||||||
(typeof server.requestIP(req) === "string" ? server.requestIP(req) : (server.requestIP(req)?.address || ""))
|
(typeof server.requestIP(req) === "string"
|
||||||
|
? server.requestIP(req)
|
||||||
|
: server.requestIP(req)?.address || ""),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
@ -58,14 +66,14 @@ const postAnalytics = async (req: Request | Bun.BunRequest, server: Bun.Server)
|
||||||
name: "pageview",
|
name: "pageview",
|
||||||
url: req.url,
|
url: req.url,
|
||||||
referrer: req.headers.get("referer") || "",
|
referrer: req.headers.get("referer") || "",
|
||||||
})
|
}),
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Sockets: {
|
Sockets: {
|
||||||
Hyperate,
|
Hyperate,
|
||||||
Lanyard
|
Lanyard,
|
||||||
},
|
},
|
||||||
Responses,
|
Responses,
|
||||||
build,
|
build,
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 2147483648;
|
z-index: 2147483648;
|
||||||
background: linear-gradient(to bottom,
|
background: linear-gradient(
|
||||||
|
to bottom,
|
||||||
transparent 50%,
|
transparent 50%,
|
||||||
rgba(0, 0, 0, 0.3) 51%);
|
rgba(0, 0, 0, 0.3) 51%
|
||||||
|
);
|
||||||
background-size: 100% 6px;
|
background-size: 100% 6px;
|
||||||
animation: scanlines 2s steps(30) infinite;
|
animation: scanlines 2s steps(30) infinite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,27 @@
|
||||||
import Lanyard from './components/Lanyard';
|
import Hyperate from "./components/Hyperate";
|
||||||
import Hyperate from './components/Hyperate';
|
import Lanyard from "./components/Lanyard";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
return <div class="app">
|
return (
|
||||||
|
<div class="app">
|
||||||
<p>seth> cat ./about.txt</p>
|
<p>seth> cat ./about.txt</p>
|
||||||
<p>A Dedicated Backend Developer,<br />with a passion for high-fidelity audio,<br />gaming, and web development.</p>
|
<p>
|
||||||
|
A Dedicated Backend Developer,
|
||||||
|
<br />
|
||||||
|
with a passion for high-fidelity audio,
|
||||||
|
<br />
|
||||||
|
gaming, and web development.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>seth> curl /tmp/discord-ipc</p>
|
<p>seth> curl /tmp/discord-ipc</p>
|
||||||
<p><Lanyard /></p>
|
<p>
|
||||||
|
<Lanyard />
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>seth> cat /tmp/heartrate</p>
|
<p>seth> cat /tmp/heartrate</p>
|
||||||
<p><Hyperate /></p>
|
<p>
|
||||||
|
<Hyperate />
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -40,10 +40,10 @@ class Socket extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
emitLanyard(lanyard: object) {
|
emitLanyard(lanyard: object) {
|
||||||
this.dispatchEvent(new CustomEvent('lanyard', { detail: lanyard }));
|
this.dispatchEvent(new CustomEvent("lanyard", { detail: lanyard }));
|
||||||
}
|
}
|
||||||
emitHyperate(heartRate: number) {
|
emitHyperate(heartRate: number) {
|
||||||
this.dispatchEvent(new CustomEvent('hyperate', { detail: heartRate }));
|
this.dispatchEvent(new CustomEvent("hyperate", { detail: heartRate }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,15 @@ import socket from "../../Socket";
|
||||||
export default () => {
|
export default () => {
|
||||||
const paragraph = createRef<HTMLParagraphElement>();
|
const paragraph = createRef<HTMLParagraphElement>();
|
||||||
|
|
||||||
socket.addEventListener('hyperate', (event: Event) => {
|
socket.addEventListener("hyperate", (event: Event) => {
|
||||||
const heartRate = (event as CustomEvent).detail;
|
const heartRate = (event as CustomEvent).detail;
|
||||||
if (paragraph.current) {
|
if (paragraph.current) {
|
||||||
paragraph.current.innerText = `${heartRate} BPM`;
|
paragraph.current.innerText = `${heartRate} BPM`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return <div>
|
return (
|
||||||
|
<div>
|
||||||
<p ref={paragraph}>0 BPM</p>
|
<p ref={paragraph}>0 BPM</p>
|
||||||
</div>;
|
</div>
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createRef } from "tsx-dom";
|
|
||||||
import { highlightAll } from "@speed-highlight/core";
|
import { highlightAll } from "@speed-highlight/core";
|
||||||
|
import { createRef } from "tsx-dom";
|
||||||
|
|
||||||
import socket from "../../Socket";
|
import socket from "../../Socket";
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@ const statusTypes: { [key: string]: string } = {
|
||||||
idle: "rgb(150, 150, 0)",
|
idle: "rgb(150, 150, 0)",
|
||||||
dnd: "rgb(150, 0, 0)",
|
dnd: "rgb(150, 0, 0)",
|
||||||
offline: "rgb(150, 150, 150)",
|
offline: "rgb(150, 150, 150)",
|
||||||
}
|
};
|
||||||
|
|
||||||
const gradientTypes: { [key: string]: string } = {
|
const gradientTypes: { [key: string]: string } = {
|
||||||
online: "rgba(0, 150, 0, 0.1)",
|
online: "rgba(0, 150, 0, 0.1)",
|
||||||
idle: "rgba(150, 150, 0, 0.1)",
|
idle: "rgba(150, 150, 0, 0.1)",
|
||||||
dnd: "rgba(150, 0, 0, 0.1)",
|
dnd: "rgba(150, 0, 0, 0.1)",
|
||||||
offline: "rgba(150, 150, 150, 0.1)",
|
offline: "rgba(150, 150, 150, 0.1)",
|
||||||
}
|
};
|
||||||
const activityTypes: { [key: number]: string } = {
|
const activityTypes: { [key: number]: string } = {
|
||||||
0: "Playing",
|
0: "Playing",
|
||||||
1: "Streaming",
|
1: "Streaming",
|
||||||
|
@ -23,37 +23,46 @@ const activityTypes: { [key: number]: string } = {
|
||||||
3: "Watching",
|
3: "Watching",
|
||||||
4: "Custom Status",
|
4: "Custom Status",
|
||||||
5: "Competing in",
|
5: "Competing in",
|
||||||
}
|
};
|
||||||
|
|
||||||
const stringify = (data: { [key: string]: string }) => {
|
const stringify = (data: { [key: string]: string }) => {
|
||||||
return JSON.stringify(data, null, 2)
|
return JSON.stringify(data, null, 2);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const code = createRef<HTMLDivElement>();
|
const code = createRef<HTMLDivElement>();
|
||||||
|
|
||||||
socket.addEventListener('lanyard', (event: Event) => {
|
socket.addEventListener("lanyard", (event: Event) => {
|
||||||
const lanyard = (event as CustomEvent).detail;
|
const lanyard = (event as CustomEvent).detail;
|
||||||
document.body.style = `--status-color: ${statusTypes[lanyard.discord_status]}; --gradient-color: ${gradientTypes[lanyard.discord_status]};`;
|
document.body.style = `--status-color: ${statusTypes[lanyard.discord_status]}; --gradient-color: ${gradientTypes[lanyard.discord_status]};`;
|
||||||
if (code.current) {
|
if (code.current) {
|
||||||
code.current.innerHTML = stringify({
|
code.current.innerHTML = stringify({
|
||||||
status: lanyard.discord_status,
|
status: lanyard.discord_status,
|
||||||
activities: lanyard.activities.map((act: {
|
activities: lanyard.activities.map(
|
||||||
type: number, name: string, details: string, state: string
|
(act: {
|
||||||
|
type: number;
|
||||||
|
name: string;
|
||||||
|
details: string;
|
||||||
|
state: string;
|
||||||
}) => {
|
}) => {
|
||||||
return [
|
return [
|
||||||
...new Set([
|
...new Set([
|
||||||
activityTypes[act.type],
|
activityTypes[act.type],
|
||||||
act.name,
|
act.name,
|
||||||
act.details,
|
act.details,
|
||||||
act.state
|
act.state,
|
||||||
])
|
]),
|
||||||
].filter(n => n)
|
].filter((n) => n);
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
highlightAll();
|
highlightAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
return <div class="shj-lang-json" ref={code}>{"{}"}</div>
|
return (
|
||||||
}
|
<div class="shj-lang-json" ref={code}>
|
||||||
|
{"{}"}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -13,8 +13,12 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: #DEDEDE;
|
color: #dedede;
|
||||||
text-shadow: 0 0 5px #C8C8C8;
|
text-shadow: 0 0 5px #c8c8c8;
|
||||||
background: radial-gradient(at bottom right, var(--gradient-color, rgba(150, 150, 150, 0.1)) 0%, rgba(0, 0, 0, 1) 100%);
|
background: radial-gradient(
|
||||||
|
at bottom right,
|
||||||
|
var(--gradient-color, rgba(150, 150, 150, 0.1)) 0%,
|
||||||
|
rgba(0, 0, 0, 1) 100%
|
||||||
|
);
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
import "tsx-dom";
|
import "tsx-dom";
|
||||||
|
|
||||||
import App from './App';
|
import App from "./App";
|
||||||
|
|
||||||
document.body.appendChild(<App />);
|
document.body.appendChild(<App />);
|
||||||
|
|
||||||
// You're garbage, let me collect you.
|
// You're garbage, let me collect you.
|
||||||
fetch("/api/gc")
|
fetch("/api/gc");
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
// Environment setup & latest features
|
// Environment setup & latest features
|
||||||
"lib": [
|
"lib": ["ESNext", "DOM"],
|
||||||
"ESNext",
|
|
||||||
"DOM",
|
|
||||||
],
|
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
|
|
Loading…
Add table
Reference in a new issue