forked from seth/ipv4.army
send help
This commit is contained in:
parent
8c000ba0b7
commit
b76e879350
104 changed files with 4260 additions and 142 deletions
|
@ -1,61 +0,0 @@
|
|||
.scanlines {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scanlines:before,
|
||||
.scanlines:after {
|
||||
display: inherit;
|
||||
pointer-events: none;
|
||||
content: "";
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.scanlines:before {
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
z-index: 2147483649;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
opacity: 0.75;
|
||||
animation: scanline 6s linear infinite;
|
||||
}
|
||||
|
||||
.scanlines:after {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 2147483648;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent 50%,
|
||||
rgba(0, 0, 0, 0.3) 51%
|
||||
);
|
||||
background-size: 100% 6px;
|
||||
animation: scanlines 2s steps(30) infinite;
|
||||
}
|
||||
|
||||
/* ANIMATE UNIQUE SCANLINE */
|
||||
@keyframes scanline {
|
||||
0% {
|
||||
transform: translate3d(0, 200000%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scanlines {
|
||||
0% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
}
|
||||
|
||||
span.shj-syn-str:nth-child(2) {
|
||||
color: var(--status-color, rgba(150, 150, 150, 0.1));
|
||||
}
|
||||
|
||||
.shj-numbers {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.shj-lang-json {
|
||||
padding: 0px;
|
||||
background-color: transparent;
|
||||
}
|
|
@ -1,27 +1,40 @@
|
|||
import "mdui/components/layout";
|
||||
import "mdui/components/layout-main";
|
||||
|
||||
import Hyperate from "./components/Hyperate";
|
||||
import Lanyard from "./components/Lanyard";
|
||||
import NavigationBar from "./components/NavigationBar";
|
||||
import TopAppBar from "./components/TopAppBar";
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<div class="app terminal">
|
||||
<p>[seth@ipv4 ~]$ cat ./about.txt</p>
|
||||
<p>
|
||||
A Dedicated Backend Developer,
|
||||
<br />
|
||||
with a passion for high-fidelity audio,
|
||||
<br />
|
||||
gaming, and web development.
|
||||
</p>
|
||||
<div>
|
||||
<TopAppBar />
|
||||
<mdui-layout>
|
||||
<mdui-layout-main>
|
||||
<div class="app terminal">
|
||||
<p>[seth@ipv4 ~]$ cat ./about.txt</p>
|
||||
<p>
|
||||
A Dedicated Backend Developer,
|
||||
<br />
|
||||
with a passion for high-fidelity audio,
|
||||
<br />
|
||||
gaming, and web development.
|
||||
</p>
|
||||
|
||||
<p>[seth@ipv4 ~]$ cat /tmp/discord-ipc</p>
|
||||
<p>
|
||||
<Lanyard />
|
||||
</p>
|
||||
<p>[seth@ipv4 ~]$ cat /tmp/discord-ipc</p>
|
||||
<p>
|
||||
<Lanyard />
|
||||
</p>
|
||||
|
||||
<p>[seth@ipv4 ~]$ cat /tmp/heartrate</p>
|
||||
<p>
|
||||
<Hyperate />
|
||||
</p>
|
||||
<p>[seth@ipv4 ~]$ cat /tmp/heartrate</p>
|
||||
<p>
|
||||
<Hyperate />
|
||||
</p>
|
||||
</div>
|
||||
</mdui-layout-main>
|
||||
</mdui-layout>
|
||||
<NavigationBar />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createRef } from "tsx-dom";
|
||||
|
||||
import socket from "../../Socket";
|
||||
import socket from "../../utilities/socket";
|
||||
|
||||
export default () => {
|
||||
const paragraph = createRef<HTMLParagraphElement>();
|
||||
|
|
|
@ -1,20 +1,6 @@
|
|||
import { highlightElement } from "@speed-highlight/core";
|
||||
import { createRef } from "tsx-dom";
|
||||
import socket from "../../Socket";
|
||||
|
||||
const statusTypes = {
|
||||
online: "0, 150, 0",
|
||||
idle: "150, 150, 0",
|
||||
dnd: "150, 0, 0",
|
||||
offline: "150, 150, 150",
|
||||
};
|
||||
|
||||
const gradientTypes = {
|
||||
online: "0, 150, 0",
|
||||
idle: "150, 150, 0",
|
||||
dnd: "150, 0, 0",
|
||||
offline: "150, 150, 150",
|
||||
};
|
||||
import socket from "../../utilities/socket";
|
||||
|
||||
const activityTypes: Record<number, string> = {
|
||||
0: "Playing",
|
||||
|
@ -31,8 +17,6 @@ export default () => {
|
|||
socket.addEventListener("lanyard", (event: Event) => {
|
||||
const lanyard = (event as CustomEvent<LanyardData>).detail;
|
||||
|
||||
document.body.style = `--status-color: rgb(${statusTypes[lanyard.discord_status]}); --gradient-color: rgba(${gradientTypes[lanyard.discord_status]}, 0.1);`;
|
||||
|
||||
if (container.current) {
|
||||
container.current.textContent = JSON.stringify(
|
||||
{
|
||||
|
|
29
src/front/components/NavigationBar/index.tsx
Normal file
29
src/front/components/NavigationBar/index.tsx
Normal file
|
@ -0,0 +1,29 @@
|
|||
import "mdui/components/navigation-bar";
|
||||
import "mdui/components/navigation-bar-item";
|
||||
import "mdui/components/button-icon";
|
||||
|
||||
import "@mdui/icons/person--outlined";
|
||||
import "@mdui/icons/person--rounded";
|
||||
|
||||
import "@mdui/icons/more-vert--rounded";
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<mdui-navigation-bar value="item-1">
|
||||
<mdui-navigation-bar-item value="item-1">
|
||||
<mdui-icon-person--outlined slot="icon" />
|
||||
<mdui-icon-person--rounded slot="active-icon" />
|
||||
Item 1
|
||||
</mdui-navigation-bar-item>
|
||||
<mdui-navigation-bar-item value="item-2">
|
||||
<mdui-icon-more-vert--rounded slot="icon" /> Item 2
|
||||
</mdui-navigation-bar-item>
|
||||
<mdui-navigation-bar-item value="item-3">
|
||||
<mdui-icon-more-vert--rounded slot="icon" /> Item 3
|
||||
</mdui-navigation-bar-item>
|
||||
<mdui-navigation-bar-item value="item-4">
|
||||
<mdui-icon-more-vert--rounded slot="icon" /> Item 4
|
||||
</mdui-navigation-bar-item>
|
||||
</mdui-navigation-bar>
|
||||
);
|
||||
};
|
11
src/front/components/TopAppBar/index.tsx
Normal file
11
src/front/components/TopAppBar/index.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import "mdui/components/top-app-bar";
|
||||
import "mdui/components/top-app-bar-title";
|
||||
import "mdui/components/button-icon";
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<mdui-top-app-bar variant="center-aligned" scroll-behavior="elevate">
|
||||
<mdui-top-app-bar-title>Seth @ IPv4.ARMY</mdui-top-app-bar-title>
|
||||
</mdui-top-app-bar>
|
||||
);
|
||||
};
|
|
@ -1,44 +1,167 @@
|
|||
@import "../../node_modules/@speed-highlight/core/dist/themes/dark.css";
|
||||
@import "./App.css";
|
||||
@import "../../node_modules/@fontsource/roboto/latin-400.css";
|
||||
@import "../../node_modules/@fontsource/roboto-mono/latin-400.css";
|
||||
|
||||
@import "../../node_modules/mdui/mdui.css";
|
||||
|
||||
html,
|
||||
head,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 2vh monospace;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
font-family: "Roboto", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #dedede;
|
||||
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%
|
||||
);
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.terminal {
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
[class*="shj-lang-"] {
|
||||
white-space: pre;
|
||||
color: #112;
|
||||
text-shadow: none;
|
||||
box-sizing: border-box;
|
||||
gap: 0.4em;
|
||||
background: #dedede;
|
||||
border-radius: 10px;
|
||||
max-width: min(100%, 100vw);
|
||||
margin: 10px 0;
|
||||
padding: 30px 20px;
|
||||
font:
|
||||
18px / 24px "Roboto Mono",
|
||||
monospace;
|
||||
box-shadow: 0 0 5px #0001;
|
||||
}
|
||||
|
||||
.shj-inline {
|
||||
border-radius: 5px;
|
||||
margin: 0;
|
||||
padding: 2px 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
[class*="shj-lang-"]::selection {
|
||||
background: #bdf5;
|
||||
}
|
||||
|
||||
[class*="shj-lang-"] ::selection {
|
||||
background: #bdf5;
|
||||
}
|
||||
|
||||
[class*="shj-lang-"] > div {
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
[class*="shj-lang-"] > div :last-child {
|
||||
outline: none;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.shj-numbers {
|
||||
counter-reset: line;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.shj-numbers div {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.shj-numbers div:before {
|
||||
color: #999;
|
||||
content: counter(line);
|
||||
opacity: 0.5;
|
||||
text-align: right;
|
||||
counter-increment: line;
|
||||
margin-right: 5px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.shj-syn-cmnt {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.shj-syn-err,
|
||||
.shj-syn-kwd {
|
||||
color: #e16;
|
||||
}
|
||||
|
||||
.shj-syn-num,
|
||||
.shj-syn-class {
|
||||
color: #f60;
|
||||
}
|
||||
|
||||
.shj-syn-insert,
|
||||
.shj-syn-str {
|
||||
color: #7d8;
|
||||
}
|
||||
|
||||
.shj-syn-bool {
|
||||
color: #3bf;
|
||||
}
|
||||
|
||||
.shj-syn-type,
|
||||
.shj-syn-oper {
|
||||
color: #5af;
|
||||
}
|
||||
|
||||
.shj-syn-section,
|
||||
.shj-syn-func {
|
||||
color: #84f;
|
||||
}
|
||||
|
||||
.shj-syn-deleted,
|
||||
.shj-syn-var {
|
||||
color: #f44;
|
||||
}
|
||||
|
||||
.shj-oneline {
|
||||
padding: 12px 10px;
|
||||
}
|
||||
|
||||
.shj-lang-http.shj-oneline .shj-syn-kwd {
|
||||
color: #fff;
|
||||
background: #25f;
|
||||
border-radius: 5px;
|
||||
padding: 5px 7px;
|
||||
}
|
||||
|
||||
[class*="shj-lang-"] {
|
||||
color: #f8f8f2;
|
||||
background: var(--mdui-color-secondary-container);
|
||||
}
|
||||
|
||||
[class*="shj-lang-"]:before {
|
||||
color: #6f9aff;
|
||||
}
|
||||
|
||||
.shj-syn-deleted,
|
||||
.shj-syn-err,
|
||||
.shj-syn-var {
|
||||
color: #ff5261;
|
||||
}
|
||||
|
||||
.shj-syn-section,
|
||||
.shj-syn-kwd {
|
||||
color: #ff7cc6;
|
||||
}
|
||||
|
||||
.shj-syn-class {
|
||||
color: #eab07c;
|
||||
}
|
||||
|
||||
.shj-numbers,
|
||||
.shj-syn-cmnt {
|
||||
color: #7d828b;
|
||||
}
|
||||
|
||||
.shj-syn-insert,
|
||||
.shj-syn-type,
|
||||
.shj-syn-func,
|
||||
.shj-syn-bool {
|
||||
color: #71d58a;
|
||||
}
|
||||
|
||||
.shj-syn-num {
|
||||
color: #b581fd;
|
||||
}
|
||||
|
||||
.shj-syn-oper {
|
||||
color: #80c6ff;
|
||||
}
|
||||
|
||||
.shj-syn-str {
|
||||
color: #4dacfa;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="mdui-theme-dark">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no" />
|
||||
<meta name="renderer" content="webkit" />
|
||||
<meta name="theme-color" content="#000000">
|
||||
<meta name="description"
|
||||
content="A Dedicated Backend Developer, with a passion for high-fidelity audio, gaming, and web development.">
|
||||
|
@ -15,8 +16,8 @@
|
|||
<link rel="stylesheet" href="index.css" />
|
||||
</head>
|
||||
|
||||
<body class="scanlines">
|
||||
<script src="index.tsx"></script>
|
||||
<body>
|
||||
<script src="index.tsx" type="module"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,5 +1,7 @@
|
|||
import "tsx-dom";
|
||||
|
||||
import "./utilities/clicker";
|
||||
|
||||
import App from "./App";
|
||||
|
||||
document.body.appendChild(<App />);
|
||||
|
|
21
src/front/utilities/clicker/index.ts
Normal file
21
src/front/utilities/clicker/index.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
const effectTick = new Audio("https://no.ipv4.army/u/Effect_Tick.ogg");
|
||||
|
||||
effectTick.volume = 0.1;
|
||||
|
||||
const whitelistedTags = ["mdui-button", "mdui-icon"];
|
||||
|
||||
document.onclick = (event: MouseEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
|
||||
if (!target) return;
|
||||
|
||||
const tagName = target.tagName.toLowerCase();
|
||||
const isWhitelisted = whitelistedTags.some((tag) => tagName.startsWith(tag));
|
||||
|
||||
console.log(tagName, isWhitelisted);
|
||||
|
||||
if (!isWhitelisted) return;
|
||||
|
||||
effectTick.currentTime = 0;
|
||||
effectTick.play();
|
||||
};
|
108
src/front/utilities/snackbar/index.ts
Normal file
108
src/front/utilities/snackbar/index.ts
Normal file
|
@ -0,0 +1,108 @@
|
|||
import type { Snackbar } from "mdui";
|
||||
import { snackbar } from "mdui";
|
||||
|
||||
interface Options {
|
||||
/**
|
||||
* The text to display in the snackbar.
|
||||
*/
|
||||
message: string;
|
||||
/**
|
||||
* The position of the snackbar. Defaults to `bottom`. Possible values are:
|
||||
* * `top`: Aligned to the top, centered
|
||||
* * `top-start`: Aligned to the top, left
|
||||
* * `top-end`: Aligned to the top, right
|
||||
* * `bottom`: Aligned to the bottom, centered
|
||||
* * `bottom-start`: Aligned to the bottom, left
|
||||
* * `bottom-end`: Aligned to the bottom, right
|
||||
*/
|
||||
placement?:
|
||||
| "top"
|
||||
| "top-start"
|
||||
| "top-end"
|
||||
| "bottom"
|
||||
| "bottom-start"
|
||||
| "bottom-end";
|
||||
/**
|
||||
* The text for the action button.
|
||||
*/
|
||||
action?: string;
|
||||
/**
|
||||
* Whether to show a close button on the right.
|
||||
*/
|
||||
closeable?: boolean;
|
||||
/**
|
||||
* The maximum number of lines to display for the message text. Defaults to no limit. Possible values are:
|
||||
* * `1`: The message text will be displayed on one line at most.
|
||||
* * `2`: The message text will be displayed on two lines at most.
|
||||
*/
|
||||
messageLine?: 1 | 2;
|
||||
/**
|
||||
* The duration (in milliseconds) after which the snackbar will automatically close. If set to 0, it will not close automatically. Defaults to 5 seconds.
|
||||
*/
|
||||
autoCloseDelay?: number;
|
||||
/**
|
||||
* Whether to close the snackbar when clicking or touching outside of it.
|
||||
*/
|
||||
closeOnOutsideClick?: boolean;
|
||||
/**
|
||||
* The name of the queue.
|
||||
* By default, queues are not enabled. When calling this function multiple times, multiple snackbars will be displayed simultaneously.
|
||||
* You can pass a queue name as an argument. Snackbar functions with the same queue name will only open after the previous snackbar has closed.
|
||||
*/
|
||||
queue?: string;
|
||||
/**
|
||||
* The callback function to be executed when the snackbar is clicked.
|
||||
* The function parameter is the snackbar instance, and `this` also points to the snackbar instance.
|
||||
* @param snackbar
|
||||
*/
|
||||
onClick?: (snackbar: Snackbar) => void;
|
||||
/**
|
||||
* The callback function to be executed when the action button is clicked.
|
||||
* The function parameter is the snackbar instance, and `this` also points to the snackbar instance.
|
||||
* By default, clicking the action button will close the snackbar. If the return value is false, the snackbar will not close. If the return value is a promise, the snackbar will close after the promise is resolved.
|
||||
* @param snackbar
|
||||
*/
|
||||
onActionClick?: (snackbar: Snackbar) => void | boolean | Promise<void>;
|
||||
/**
|
||||
* The callback function to be executed when the snackbar is opened.
|
||||
* The function parameter is the snackbar instance, and `this` also points to the snackbar instance.
|
||||
* @param snackbar
|
||||
*/
|
||||
onOpen?: (snackbar: Snackbar) => void;
|
||||
/**
|
||||
* The callback function to be executed when the snackbar's show animation is complete.
|
||||
* The function parameter is the snackbar instance, and `this` also points to the snackbar instance.
|
||||
* @param snackbar
|
||||
*/
|
||||
onOpened?: (snackbar: Snackbar) => void;
|
||||
/**
|
||||
* The callback function to be executed when the snackbar is about to be closed.
|
||||
* The function parameter is the snackbar instance, and `this` also points to the snackbar instance.
|
||||
* @param snackbar
|
||||
*/
|
||||
onClose?: (snackbar: Snackbar) => void;
|
||||
/**
|
||||
* The callback function to be executed when the snackbar's hide animation is complete.
|
||||
* The function parameter is the snackbar instance, and `this` also points to the snackbar instance.
|
||||
* @param snackbar
|
||||
*/
|
||||
onClosed?: (snackbar: Snackbar) => void;
|
||||
}
|
||||
|
||||
const popcorn = new Audio("https://no.ipv4.army/u/Popcorn.ogg");
|
||||
|
||||
popcorn.volume = 0.1;
|
||||
|
||||
export const snacker = (opts: Options) => {
|
||||
snackbar({
|
||||
closeable: true,
|
||||
messageLine: 2,
|
||||
queue: "snacker",
|
||||
onOpen: () => {
|
||||
popcorn.currentTime = 0;
|
||||
popcorn.play();
|
||||
},
|
||||
|
||||
...opts,
|
||||
});
|
||||
};
|
|
@ -8,6 +8,9 @@ class Socket extends EventTarget {
|
|||
|
||||
this._socket = new WebSocket(url);
|
||||
this._socket.onmessage = (event) => {
|
||||
if (event.data === "ping") return;
|
||||
if (event.data === "pong") return;
|
||||
|
||||
const { type, data } = JSON.parse(event.data);
|
||||
|
||||
switch (type) {
|
||||
|
@ -20,7 +23,7 @@ class Socket extends EventTarget {
|
|||
break;
|
||||
}
|
||||
case "echo": {
|
||||
console.log("Echo: ", data);
|
||||
//console.log("Echo: ", data);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -36,7 +39,7 @@ class Socket extends EventTarget {
|
|||
|
||||
setInterval(() => {
|
||||
this._socket.send("ping");
|
||||
}, 30 * 1000);
|
||||
}, 10 * 1000);
|
||||
}
|
||||
|
||||
emitLanyard(lanyard: LanyardData) {
|
12
src/index.ts
12
src/index.ts
|
@ -30,10 +30,12 @@ const server = serve({
|
|||
"/assets/:file": async (req) =>
|
||||
Backend.Responses.file(file(`./dist/${req.params.file}`)),
|
||||
|
||||
"/public/*": async (req) => {
|
||||
return Backend.Responses.file(file(`.${new URL(req.url).pathname}`));
|
||||
},
|
||||
|
||||
"/robots.txt": async () =>
|
||||
Backend.Responses.file(file("./public/robots.txt")),
|
||||
"/favicon.svg": async () =>
|
||||
Backend.Responses.file(file("./public/favicon.svg")),
|
||||
|
||||
"/api/server": () => {
|
||||
const safeProcess = JSON.parse(JSON.stringify(process));
|
||||
|
@ -71,7 +73,7 @@ const server = serve({
|
|||
},
|
||||
|
||||
websocket: {
|
||||
idleTimeout: 1,
|
||||
idleTimeout: 60,
|
||||
open: (ws) => {
|
||||
ws.subscribe("lanyard");
|
||||
ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true);
|
||||
|
@ -83,7 +85,9 @@ const server = serve({
|
|||
);
|
||||
},
|
||||
message: (ws, msg) => {
|
||||
ws.send(JSON.stringify({ type: "echo", data: msg }), true);
|
||||
if (msg === "ping") ws.send("pong", true);
|
||||
if (msg === "pong") ws.send("ping", true);
|
||||
return;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue