mirror of
https://github.com/ION606/web-to-fish.git
synced 2026-05-14 18:36:53 +00:00
138 lines
2.9 KiB
HTML
138 lines
2.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Shell</title>
|
|
<style>
|
|
body {
|
|
font-family: monospace;
|
|
background: #000000;
|
|
color: #ffffff;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100vh;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.terminal-container {
|
|
background: #000000;
|
|
border-radius: 5px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
gap: 1rem;
|
|
width: 100%;
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.terminal-header {
|
|
font-size: 1.5rem;
|
|
text-transform: uppercase;
|
|
color: #00ff00;
|
|
margin: 0;
|
|
}
|
|
|
|
.output {
|
|
flex-grow: 1;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
background: #000000;
|
|
border-radius: 5px;
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
::-webkit-scrollbar {
|
|
width: 10px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: #555;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: #777;
|
|
}
|
|
</style>
|
|
<link rel="stylesheet" href="node_modules/@xterm/xterm/css/xterm.css" />
|
|
<script src="node_modules/@xterm/xterm/lib/xterm.js"></script>
|
|
<script src="node_modules/@xterm/addon-fit/lib/addon-fit.js"></script>
|
|
</head>
|
|
<body>
|
|
<div class="terminal-container">
|
|
<div class="output" id="output"></div>
|
|
</div>
|
|
<script>
|
|
const sessionId =
|
|
sessionStorage.getItem("sessionId") || crypto.randomUUID();
|
|
sessionStorage.setItem("sessionId", sessionId);
|
|
|
|
function connect() {
|
|
const protocol =
|
|
location.protocol === "https:" ? "wss://" : "ws://";
|
|
const ws = new WebSocket(
|
|
`${protocol}${location.host}/shell-ws?id=${sessionId}`
|
|
);
|
|
|
|
term.onData((data) => ws.send(data));
|
|
|
|
ws.addEventListener("message", (event) => {
|
|
const data = JSON.parse(event.data);
|
|
if (data.event) {
|
|
switch (data.event) {
|
|
case "exit":
|
|
term.write(
|
|
"\r\nConnection closed. Refreshing...\r\n"
|
|
);
|
|
setTimeout(
|
|
() => window.location.reload(),
|
|
2000
|
|
);
|
|
break;
|
|
default:
|
|
term.write(
|
|
`\r\nUnknown event: ${data.event}\r\n`
|
|
);
|
|
break;
|
|
}
|
|
} else {
|
|
term.write(data.data);
|
|
}
|
|
});
|
|
|
|
ws.addEventListener("close", () => {
|
|
setTimeout(connect, 1000);
|
|
});
|
|
}
|
|
|
|
const term = new Terminal({
|
|
cursorBlink: true,
|
|
theme: {
|
|
background: "#000000",
|
|
foreground: "#ffffff",
|
|
cursor: "#00ff00",
|
|
},
|
|
});
|
|
const outputContainer = document.querySelector("#output");
|
|
term.open(outputContainer);
|
|
|
|
const fitAddon = new FitAddon.FitAddon();
|
|
term.loadAddon(fitAddon);
|
|
fitAddon.fit();
|
|
connect();
|
|
|
|
window.addEventListener("beforeunload", () => {
|
|
navigator.sendBeacon(`/kill-session?id=${sessionId}`);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|