Initial commit: Socktop WebTerm with k3s deployment
- Multi-architecture Docker image (ARM64 + AMD64) - Kubernetes manifests for 3-replica deployment - Traefik ingress configuration - NGINX Proxy Manager integration - ConfigMap-based configuration - Automated build and deployment scripts - Session monitoring tools
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
// Terminal Initialization Script for socktop webterm
|
||||
// Catppuccin Frappe theme with transparency
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Catppuccin Frappe theme for xterm
|
||||
var term = new Terminal({
|
||||
allowTransparency: true,
|
||||
fontFamily:
|
||||
'"JetBrains Mono", "Fira Code", "Cascadia Code", Consolas, monospace',
|
||||
fontSize: 14,
|
||||
lineHeight: 1.2,
|
||||
cursorBlink: true,
|
||||
cursorStyle: "block",
|
||||
theme: {
|
||||
background: "rgba(48, 52, 70, 0.75)",
|
||||
foreground: "#c6d0f5",
|
||||
cursor: "#f2d5cf",
|
||||
cursorAccent: "#303446",
|
||||
selectionBackground: "rgba(202, 158, 230, 0.3)",
|
||||
|
||||
// ANSI colors
|
||||
black: "#51576d",
|
||||
red: "#e78284",
|
||||
green: "#a6d189",
|
||||
yellow: "#e5c890",
|
||||
blue: "#8caaee",
|
||||
magenta: "#f4b8e4",
|
||||
cyan: "#81c8be",
|
||||
white: "#b5bfe2",
|
||||
|
||||
// Bright ANSI colors
|
||||
brightBlack: "#626880",
|
||||
brightRed: "#e78284",
|
||||
brightGreen: "#a6d189",
|
||||
brightYellow: "#e5c890",
|
||||
brightBlue: "#8caaee",
|
||||
brightMagenta: "#f4b8e4",
|
||||
brightCyan: "#81c8be",
|
||||
brightWhite: "#a5adce",
|
||||
},
|
||||
});
|
||||
|
||||
// Create and load the FitAddon
|
||||
var fitAddon = new FitAddon.FitAddon();
|
||||
term.loadAddon(fitAddon);
|
||||
|
||||
// Create and load the TerminadoAddon
|
||||
var terminadoAddon = new TerminadoAddon();
|
||||
term.loadAddon(terminadoAddon);
|
||||
|
||||
// Open terminal in the container
|
||||
var terminalContainer = document.getElementById("terminal");
|
||||
term.open(terminalContainer);
|
||||
|
||||
// Build websocket URL
|
||||
var protocol = location.protocol === "https:" ? "wss://" : "ws://";
|
||||
var socketURL =
|
||||
protocol +
|
||||
location.hostname +
|
||||
(location.port ? ":" + location.port : "") +
|
||||
window.WEBSOCKET_PATH;
|
||||
var sock = new WebSocket(socketURL);
|
||||
|
||||
// Fit-once strategy
|
||||
var fitDone = false;
|
||||
function fitOnceIfReady() {
|
||||
if (fitDone) return;
|
||||
if (!terminalContainer) return;
|
||||
var w = terminalContainer.clientWidth;
|
||||
var h = terminalContainer.clientHeight;
|
||||
if (!w || !h) return;
|
||||
|
||||
try {
|
||||
fitAddon.fit();
|
||||
fitDone = true;
|
||||
} catch (e) {
|
||||
console.error("Fit error:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule fit
|
||||
if (
|
||||
document.readyState === "complete" ||
|
||||
document.readyState === "interactive"
|
||||
) {
|
||||
requestAnimationFrame(fitOnceIfReady);
|
||||
} else {
|
||||
window.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
function () {
|
||||
requestAnimationFrame(fitOnceIfReady);
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
}
|
||||
window.addEventListener(
|
||||
"load",
|
||||
function () {
|
||||
requestAnimationFrame(fitOnceIfReady);
|
||||
setTimeout(fitOnceIfReady, 150);
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
|
||||
// Send size and auto-launch command
|
||||
var autoSent = false;
|
||||
function sendSizeAndCommandOnce() {
|
||||
if (autoSent) return;
|
||||
if (!sock || sock.readyState !== WebSocket.OPEN) return;
|
||||
if (!fitDone) return;
|
||||
|
||||
var rows = term.rows || 0;
|
||||
var cols = term.cols || 0;
|
||||
|
||||
if (!rows || !cols) {
|
||||
var approxCharW = 9;
|
||||
var approxCharH = 18;
|
||||
cols = Math.max(
|
||||
1,
|
||||
Math.floor(terminalContainer.clientWidth / approxCharW),
|
||||
);
|
||||
rows = Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
terminalContainer.clientHeight / approxCharH,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (rows > 0 && cols > 0) {
|
||||
try {
|
||||
terminadoAddon.sendSize(rows, cols);
|
||||
terminadoAddon.sendCommand("socktop -P local\r");
|
||||
autoSent = true;
|
||||
} catch (e) {
|
||||
console.error("Failed to send initial commands:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WebSocket event handlers
|
||||
sock.addEventListener("open", function () {
|
||||
terminadoAddon.attach(sock, true, true);
|
||||
requestAnimationFrame(function () {
|
||||
fitOnceIfReady();
|
||||
setTimeout(sendSizeAndCommandOnce, 120);
|
||||
});
|
||||
});
|
||||
|
||||
function onFirstMessage() {
|
||||
fitOnceIfReady();
|
||||
try {
|
||||
sock.removeEventListener("message", onFirstMessage);
|
||||
} catch (e) {}
|
||||
setTimeout(sendSizeAndCommandOnce, 40);
|
||||
}
|
||||
sock.addEventListener("message", onFirstMessage);
|
||||
|
||||
// Handle window resize
|
||||
window.addEventListener("resize", function () {
|
||||
try {
|
||||
fitAddon.fit();
|
||||
} catch (e) {
|
||||
console.error("Resize fit error:", e);
|
||||
}
|
||||
});
|
||||
|
||||
sock.addEventListener("error", function (err) {
|
||||
console.error("WebSocket error:", err);
|
||||
});
|
||||
|
||||
sock.addEventListener("close", function () {
|
||||
console.log("WebSocket closed");
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user