i had to stop becuz online lesson
This commit is contained in:
116
httpdocs/public/css/styles.css
Normal file
116
httpdocs/public/css/styles.css
Normal file
@@ -0,0 +1,116 @@
|
||||
* {
|
||||
margin:0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#main {
|
||||
background: black;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#terminal {
|
||||
--padding: 30px;
|
||||
width: calc(100% - (2 * var(--padding)));
|
||||
height: calc(100% - (2 * var(--padding)));
|
||||
padding: var(--padding);
|
||||
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#terminal::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
#terminal::-webkit-scrollbar-thumb {
|
||||
background-color: #222;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#terminal::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
#terminal::-webkit-scrollbar-track {
|
||||
background: none;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
#terminal::-webkit-scrollbar-track:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.terminalLine {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
|
||||
.pathText {
|
||||
color: limegreen;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
}
|
||||
.pathColon {
|
||||
color: white;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
}
|
||||
.pathPath {
|
||||
color: limegreen;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
}
|
||||
.pathDollar {
|
||||
color: white;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
}
|
||||
|
||||
.pathBlinky {
|
||||
width: 10px;
|
||||
height: 20px;
|
||||
background: lime;
|
||||
animation: blinky infinite 1s;
|
||||
}
|
||||
@keyframes blinky {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.terminalInput {
|
||||
margin-left: 5px;
|
||||
background: none;
|
||||
outline:none;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
color: white;
|
||||
}
|
||||
.terminalInput:disabled {
|
||||
margin-left: 5px;
|
||||
background: none;
|
||||
outline:none;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.responseText {
|
||||
font-size: 16px;
|
||||
margin-left: 5px;
|
||||
background: none;
|
||||
outline:none;
|
||||
border: none;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
color: white;
|
||||
}
|
||||
207
httpdocs/public/js/terminal.js
Normal file
207
httpdocs/public/js/terminal.js
Normal file
@@ -0,0 +1,207 @@
|
||||
const terminalContainer = document.getElementById("terminal");
|
||||
const hostname = `192.168.${Math.floor(Math.random() * 100)}.${Math.floor(Math.random() * 255)}`;
|
||||
let currentFolder = "~/";
|
||||
|
||||
|
||||
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
document.querySelector(".pathText").innerHTML = `guest@${hostname}`;
|
||||
|
||||
addInputEventListeners();
|
||||
|
||||
});
|
||||
|
||||
async function sendCommand(e){
|
||||
const command = e.target.value;
|
||||
// e.target.value = "";
|
||||
// resizeInput();
|
||||
deactivateAllStuff();
|
||||
|
||||
console.log("COMMAND SENT: "+command);
|
||||
|
||||
try {
|
||||
// Construct the URL with the command parameter in the query string
|
||||
const url = "/execute?command=" + encodeURIComponent(command) + "¤tDir=" + encodeURIComponent(currentFolder);
|
||||
|
||||
// Make a GET request using the fetch API
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error: ${response.status} - ${response.statusText}`);
|
||||
}
|
||||
|
||||
// Parse the JSON response
|
||||
const files = await response.json();
|
||||
|
||||
// Handle the execution response
|
||||
handleExecutionResponse(files);
|
||||
} catch (error) {
|
||||
console.error("Error:", error.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function deactivateAllStuff() {
|
||||
const blinkies = document.querySelectorAll(".pathBlinky");
|
||||
for (let i = 0; i < blinkies.length; i++){
|
||||
blinkies[i].remove();
|
||||
}
|
||||
|
||||
const actives = document.querySelectorAll(".activeLine");
|
||||
for (let i = 0; i < actives.length; i++){
|
||||
actives[i].classList.remove("activeLine");
|
||||
}
|
||||
|
||||
let input = document.getElementById("terminalInput");
|
||||
input.disabled = true;
|
||||
input.setAttribute("id", "");
|
||||
|
||||
console.log("deactivated inputs");
|
||||
}
|
||||
|
||||
|
||||
function handleExecutionResponse(response) {
|
||||
if (response.command === "cd"){
|
||||
currentFolder = response.directory
|
||||
}
|
||||
|
||||
|
||||
//Show Response
|
||||
let commandResponse = document.createElement("div")
|
||||
commandResponse.classList.add("terminalLine");
|
||||
|
||||
let textElement = document.createElement("span");
|
||||
textElement.classList.add("responseText");
|
||||
textElement.innerHTML = response.response;
|
||||
|
||||
commandResponse.appendChild(textElement)
|
||||
terminalContainer.appendChild(commandResponse);
|
||||
console.log("created response element")
|
||||
|
||||
|
||||
//create new terminal line.
|
||||
createNewTerminalLine();
|
||||
|
||||
addInputEventListeners();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function createNewTerminalLine(){
|
||||
let newTerminalLine = document.createElement("div");
|
||||
newTerminalLine.classList.add("terminalLine");
|
||||
newTerminalLine.classList.add("activeLine");
|
||||
|
||||
let pathText = document.createElement("h4")
|
||||
pathText.innerHTML=`guest@${hostname}`;
|
||||
pathText.classList.add("pathText");
|
||||
|
||||
let pathColon = document.createElement("h4")
|
||||
pathColon.innerHTML = ":";
|
||||
pathColon.classList.add("pathColon");
|
||||
|
||||
|
||||
let pathPath = document.createElement("h4");
|
||||
pathPath.innerHTML = currentFolder;
|
||||
pathPath.classList.add("pathPath");
|
||||
|
||||
|
||||
let pathDollar = document.createElement("h4");
|
||||
pathDollar.innerHTML = "$";
|
||||
pathDollar.classList.add("pathDollar");
|
||||
|
||||
|
||||
let newTerminalInput = document.createElement("input");
|
||||
newTerminalInput.setAttribute("type", "text");
|
||||
newTerminalInput.setAttribute("value", "");
|
||||
newTerminalInput.setAttribute("id", "terminalInput");
|
||||
newTerminalInput.classList.add("terminalInput");
|
||||
|
||||
let blinky = document.createElement("div");
|
||||
blinky.classList.add("pathBlinky");
|
||||
|
||||
newTerminalLine.appendChild(pathText);
|
||||
newTerminalLine.appendChild(pathColon);
|
||||
newTerminalLine.appendChild(pathPath);
|
||||
newTerminalLine.appendChild(pathDollar);
|
||||
newTerminalLine.appendChild(newTerminalInput);
|
||||
newTerminalLine.appendChild(blinky);
|
||||
|
||||
terminalContainer.appendChild(newTerminalLine)
|
||||
}
|
||||
|
||||
|
||||
function resizeInput() {
|
||||
const inputText = terminalInput.value;
|
||||
const inputWidth = measureTextWidth(inputText);
|
||||
const maxWidth = 300; // Set your desired maximum width
|
||||
|
||||
if (inputWidth <= maxWidth) {
|
||||
terminalInput.style.width = inputWidth + "px";
|
||||
} else {
|
||||
terminalInput.style.width = maxWidth + "px";
|
||||
terminalInput.value = inputText.slice(0, -1); // Remove the last character
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function measureTextWidth(text) {
|
||||
const nonBreakingSpace = '\u00A0';
|
||||
const sanitizedText = text.replace(/ /g, nonBreakingSpace);
|
||||
|
||||
const fakeElement = document.createElement("div");
|
||||
fakeElement.style.visibility = "hidden";
|
||||
fakeElement.style.position = "absolute";
|
||||
fakeElement.style.top = "0";
|
||||
fakeElement.style.left = "0";
|
||||
fakeElement.style.width = "auto";
|
||||
fakeElement.style.fontFamily = "Source Code Pro";
|
||||
fakeElement.style.fontSize = "16px";
|
||||
fakeElement.style.whiteSpace = "nowrap";
|
||||
fakeElement.innerHTML = sanitizedText;
|
||||
|
||||
document.body.appendChild(fakeElement);
|
||||
const width = fakeElement.offsetWidth;
|
||||
document.body.removeChild(fakeElement);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
function addInputEventListeners() {
|
||||
const terminalInput = document.getElementById("terminalInput");
|
||||
|
||||
terminalInput.addEventListener("input", function (e) {
|
||||
resizeInput();
|
||||
});
|
||||
resizeInput()
|
||||
|
||||
terminalInput.addEventListener('blur', function(e) {
|
||||
e.preventDefault();
|
||||
setTimeout(() => {
|
||||
terminalInput.focus();
|
||||
}, 0);
|
||||
}, false);
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
setTimeout(() => {
|
||||
terminalInput.focus();
|
||||
}, 0);
|
||||
}, false);
|
||||
terminalInput.focus();
|
||||
|
||||
terminalInput.addEventListener("keydown", async function (e) {
|
||||
if (e.key === "Enter"){
|
||||
await sendCommand(e);
|
||||
}
|
||||
})
|
||||
|
||||
return;
|
||||
}
|
||||
Reference in New Issue
Block a user