better/more comments and focus bugfix

This commit is contained in:
Baipyrus 2023-02-08 15:30:06 +01:00
parent b542343fd9
commit 1ee17099e2
3 changed files with 70 additions and 27 deletions

View File

@ -4,13 +4,15 @@ function runCommand(input) {
if (input === "") if (input === "")
return ""; return "";
// Exit current level // Get current mode
const modeSplit = chatMode.split(' '); const modeSplit = chatMode.split(' ');
if (modeSplit[0] !== "default") { if (modeSplit[0] !== "default") {
const lowerIn = input.toLowerCase(); const lowerIn = input.toLowerCase();
// Run exit command in other mode
if (lowerIn.startsWith("exit")) { if (lowerIn.startsWith("exit")) {
cmd_exit(); cmd_exit();
return ""; return "";
// Run clear command in other modes
} else if (lowerIn.startsWith("clear")) { } else if (lowerIn.startsWith("clear")) {
cmd_clear(); cmd_clear();
return ""; return "";
@ -20,12 +22,16 @@ function runCommand(input) {
// Handle different chat modes // Handle different chat modes
switch (modeSplit[0]) { switch (modeSplit[0]) {
case "msg": case "msg":
// Send direct message, rename previous pretext to own name
directMessage(modeSplit[1].split(','), input); directMessage(modeSplit[1].split(','), input);
renameToSelf(); renameToSelf();
// Return without message
return ""; return "";
case "chat": case "chat":
// Send group message, rename previous pretext to own name
groupMessage(modeSplit[1].split(','), input); groupMessage(modeSplit[1].split(','), input);
renameToSelf(); renameToSelf();
// Return without message
return ""; return "";
} }
@ -88,24 +94,31 @@ function cmd_about() {
// Reload page // Reload page
function cmd_reload() { function cmd_reload() {
window.location.reload(); window.location.reload();
// Return without message
return null;
} }
// Clear terminal window // Clear terminal window
function cmd_clear() { function cmd_clear() {
setTimeout(() => { setTimeout(() => {
// Remove all children except core elements and banner
const tbc = tbDiv.children; const tbc = tbDiv.children;
for (let i = tbc.length-3; i > 1; i--) for (let i = tbc.length-3; i > 1; i--)
tbDiv.removeChild(tbc[i]); tbDiv.removeChild(tbc[i]);
// Replace last child with new (current) pretext
const prelink = document.createElement("a"); const prelink = document.createElement("a");
prelink.innerHTML = pretext.current; prelink.innerHTML = pretext.current;
tbDiv.replaceChild(prelink, tbc[1]); tbDiv.replaceChild(prelink, tbc[1]);
// Reset cursor position
cursorPosition = 0; cursorPosition = 0;
cursorYOffset = 7; cursorYOffset = 7;
updateCursor(); updateCursor();
}, 50); }, 50);
// Return without message
return null; return null;
} }
@ -113,12 +126,15 @@ function cmd_clear() {
function cmd_history() { function cmd_history() {
let output = ""; let output = "";
// Get history
const hl = history.list; const hl = history.list;
for (let i = 0; i < hl.length; i++) { for (let i = 0; i < hl.length; i++) {
// Add line break on every command except last
const lineBreak = (i !== hl.length - 1) ? "<br>" : ""; const lineBreak = (i !== hl.length - 1) ? "<br>" : "";
output += `${i+1} ${hl[i]}${lineBreak}`; output += `${i+1} ${hl[i]}${lineBreak}`;
} }
// Return output list
return output; return output;
} }
@ -159,8 +175,10 @@ function cmd_echo(input) {
function cmd_nick(input) { function cmd_nick(input) {
if (input === undefined) if (input === undefined)
return "No nickname was given!"; return "No nickname was given!";
// Rename user
if (!!window.localStorage.getItem("connected")) if (!!window.localStorage.getItem("connected"))
sendNickname(input[0]); sendNickname(input[0]);
// Connect with given name
else else
connect(input[0]); connect(input[0]);
return null; return null;

View File

@ -33,81 +33,83 @@ textIn.oninput = () => {
textIn.value = ""; textIn.value = "";
updateCursor(); updateCursor();
}; };
// Auto focus on start
textIn.focus(); textIn.focus();
// If no ranged selection was made, focus on input field // Key Listener
document.addEventListener("selectionchange", e => {
if (e.target !== textIn) {
const selection = window.getSelection();
if (selection.type === "Caret")
textIn.focus();
}
});
document.addEventListener("keydown", e => { document.addEventListener("keydown", e => {
const text = textCur.textContent; const text = textCur.textContent;
switch (e.key) { switch (e.key) {
case "Backspace": case "Backspace":
// Ein Zeichen nach links löschen // Delete one character to the left
if (cursorPosition === 0) if (cursorPosition === 0)
return; return;
// Cursor is in the middle of the input
if (cursorPosition <= textCur.textContent.length-1) { if (cursorPosition <= textCur.textContent.length-1) {
const a = text.substring(0, cursorPosition-1); const a = text.substring(0, cursorPosition-1);
const b = text.substring(cursorPosition, text.length); const b = text.substring(cursorPosition, text.length);
textCur.textContent=a+b; textCur.textContent=a+b;
// Cursor is at the end of input
} else } else
textCur.textContent = text.substring(0,text.length-1); textCur.textContent = text.substring(0,text.length-1);
// Update cursor visuals
cursorPosition--; cursorPosition--;
updateCursor(); updateCursor();
break; break;
case "ArrowLeft": case "ArrowLeft":
// Ein Zeichen nach links // Go one cursor position to the left
if (cursorPosition > 0) { if (cursorPosition > 0) {
cursorPosition--; cursorPosition--;
updateCursor(); updateCursor();
} }
break; break;
case "ArrowRight": case "ArrowRight":
// Ein Zeichen nach reckts // Go one cursor position to the right
if (cursorPosition < textCur.textContent.length) { if (cursorPosition < textCur.textContent.length) {
cursorPosition++; cursorPosition++;
updateCursor(); updateCursor();
} }
break; break;
case "Delete": case "Delete":
// Ein Zeichen nach rechts löschen // Delete one character to the left
if (cursorPosition >= textCur.textContent.length) if (cursorPosition >= textCur.textContent.length)
return; return;
if (cursorPosition === 0 && textCur.textContent.length === 0) // No input given yet
if (textCur.textContent.length === 0)
return; return;
const a = text.substring(0, cursorPosition); const a = text.substring(0, cursorPosition);
const b = text.substring(cursorPosition+1, text.length); const b = text.substring(cursorPosition+1, text.length);
textCur.textContent = a+b; textCur.textContent = a+b;
break; break;
case "Enter": case "Enter":
// Befehl absenden / Zeilenumbruch // Send out command / line break
outputText({user: text}); outputText({user: text});
// Refocus
textIn.focus();
break; break;
case "ArrowUp": case "ArrowUp":
// Einen Befehl zurück in der History // Go back one command in the history
if (history.index > 0) { if (history.index > 0) {
history.index--; history.index--;
textCur.textContent = history.list[history.index]; textCur.textContent = history.list[history.index];
cursorPosition = textCur.textContent.length; cursorPosition = textCur.textContent.length;
} }
// Update cursor position
updateCursor(); updateCursor();
break; break;
case "ArrowDown": case "ArrowDown":
// Einen Befehl nach vorne in der History // Go forward one command in the history
if (history.index < history.list.length-1) { if (history.index < history.list.length-1) {
history.index++; history.index++;
textCur.textContent = history.list[history.index]; textCur.textContent = history.list[history.index];
cursorPosition = textCur.textContent.length; cursorPosition = textCur.textContent.length;
// Reached end of history
} else if (history.index < history.list.length) { } else if (history.index < history.list.length) {
history.index++; history.index++;
textCur.textContent = ""; textCur.textContent = "";
cursorPosition = 0; cursorPosition = 0;
} }
// Update cursor position
updateCursor(); updateCursor();
break; break;
case "Tab": case "Tab":
@ -116,9 +118,12 @@ document.addEventListener("keydown", e => {
} }
}); });
// Text output or user input handler
function outputText(params) { function outputText(params) {
// Unpack parameters
const { user, output, preNext } = params; const { user, output, preNext } = params;
// Temporarily remove core elements
tbDiv.removeChild(textIn); tbDiv.removeChild(textIn);
tbDiv.removeChild(textCur); tbDiv.removeChild(textCur);
@ -132,18 +137,19 @@ function outputText(params) {
history.index = history.list.length; history.index = history.list.length;
} }
// Fix current input to page // Fixate current input to page
tbDiv.appendChild(createText(user)); tbDiv.appendChild(createText(user));
tbDiv.innerHTML += `<br>`; tbDiv.innerHTML += `<br>`;
cursorYOffset++; cursorYOffset++;
} }
// Replace text on last pretext
if (preNext !== undefined) { if (preNext !== undefined) {
const tbc = tbDiv.children; const tbc = tbDiv.children;
tbc[tbc.length - 1].innerHTML = preNext; tbc[tbc.length - 1].innerHTML = preNext;
} }
// Run command and return output // Run as command if it's user input and display output
const isUserInput = output === undefined && user !== undefined; const isUserInput = output === undefined && user !== undefined;
let commandOutput = (isUserInput && !whitespaceOnly) ? runCommand(user) : (output ? output : ""); let commandOutput = (isUserInput && !whitespaceOnly) ? runCommand(user) : (output ? output : "");
if (commandOutput !== "" && commandOutput !== null) { if (commandOutput !== "" && commandOutput !== null) {
@ -153,16 +159,19 @@ function outputText(params) {
// Offset cursor by at least one line, and as many more as there are line breaks // Offset cursor by at least one line, and as many more as there are line breaks
cursorYOffset += commandOutput.split("<br>").length; cursorYOffset += commandOutput.split("<br>").length;
} }
// Add new pretext to terminal // Add new pretext to terminal
if (commandOutput !== null) { if (commandOutput !== null) {
const prelink = document.createElement('a'); const prelink = document.createElement('a');
prelink.innerHTML = pretext.current; prelink.innerHTML = pretext.current;
tbDiv.appendChild(prelink); tbDiv.appendChild(prelink);
} }
// Add elements on top of div
// Add core elements back on top of div
tbDiv.appendChild(textCur); tbDiv.appendChild(textCur);
tbDiv.appendChild(textIn); tbDiv.appendChild(textIn);
// Reset variables
// Reset variables and position cursor
if (isUserInput) { if (isUserInput) {
textCur.textContent = ""; textCur.textContent = "";
cursorPosition = 0; cursorPosition = 0;

View File

@ -7,6 +7,8 @@ const pretext = {
const userData = { history: [], chatPull: null }; const userData = { history: [], chatPull: null };
let chatMode = "default", activityNotify; let chatMode = "default", activityNotify;
// If no user data exists, initialize it
if (window.localStorage.getItem("id") === null) if (window.localStorage.getItem("id") === null)
window.localStorage.setItem("id", ""); window.localStorage.setItem("id", "");
if (window.localStorage.getItem("name") === null) if (window.localStorage.getItem("name") === null)
@ -14,6 +16,8 @@ if (window.localStorage.getItem("name") === null)
if (window.localStorage.getItem("connected") === null) if (window.localStorage.getItem("connected") === null)
window.localStorage.setItem("connected", ""); window.localStorage.setItem("connected", "");
// Activity request interval
function setNotification() { function setNotification() {
return setInterval(()=>{ return setInterval(()=>{
fetch('/activity', { fetch('/activity', {
@ -29,6 +33,7 @@ function setNotification() {
}, 60000); }, 60000);
} }
// If user data is found, check for validity
if (window.localStorage.getItem("id") !== "" && window.localStorage.getItem("name") !== "") { if (window.localStorage.getItem("id") !== "" && window.localStorage.getItem("name") !== "") {
pretext.original = pretext.current = `${window.localStorage.getItem("name")}@baipyr.us:~# `; pretext.original = pretext.current = `${window.localStorage.getItem("name")}@baipyr.us:~# `;
@ -43,13 +48,16 @@ if (window.localStorage.getItem("id") !== "" && window.localStorage.getItem("nam
id: window.localStorage.getItem("id") id: window.localStorage.getItem("id")
}) })
}).then(res => { }).then(res => {
// Return JSON if status is OK
if (res.status === 200) if (res.status === 200)
return res.json(); return res.json();
}).then(res => { }).then(res => {
if (res === undefined) if (res === undefined)
return; return;
// Regularly send activity
if (res.success) if (res.success)
activityNotify = setNotification(); activityNotify = setNotification();
// Delete user data
else { else {
window.localStorage.setItem("id", ""); window.localStorage.setItem("id", "");
window.localStorage.setItem("name", ""); window.localStorage.setItem("name", "");
@ -64,6 +72,7 @@ if (window.localStorage.getItem("id") !== "" && window.localStorage.getItem("nam
// Tell server to disconnect // Tell server to disconnect
function disconnect() { function disconnect() {
if (!!window.localStorage.getItem("connected")) { if (!!window.localStorage.getItem("connected")) {
// Send disconnect request
fetch('/disconnect', { fetch('/disconnect', {
method: 'POST', method: 'POST',
headers: { headers: {
@ -74,9 +83,11 @@ function disconnect() {
id: window.localStorage.getItem("id") id: window.localStorage.getItem("id")
}) })
}).then(res => {}); }).then(res => {});
// Delete user data
window.localStorage.setItem("id", ""); window.localStorage.setItem("id", "");
window.localStorage.setItem("name", ""); window.localStorage.setItem("name", "");
window.localStorage.setItem("connected", ""); window.localStorage.setItem("connected", "");
// Reset pretext
pretext.original = pretext.current = "root@baipyr.us:~# "; pretext.original = pretext.current = "root@baipyr.us:~# ";
} }
} }
@ -93,6 +104,7 @@ function connect(name) {
body: JSON.stringify({ name }) body: JSON.stringify({ name })
}).then(res => { }).then(res => {
if (res.status === 200) { if (res.status === 200) {
// Regularly send activity
activityNotify = setNotification(); activityNotify = setNotification();
window.localStorage.setItem("connected", "1"); window.localStorage.setItem("connected", "1");
return res.json(); return res.json();
@ -102,7 +114,7 @@ function connect(name) {
}).then(res => { }).then(res => {
if (res === undefined) if (res === undefined)
return; return;
// Save provided id // Save provided id, set pretext, output confirmation
const { id } = res; const { id } = res;
window.localStorage.setItem("id", id); window.localStorage.setItem("id", id);
pretext.original = pretext.current = `${name}@baipyr.us:~# `; pretext.original = pretext.current = `${name}@baipyr.us:~# `;
@ -127,6 +139,7 @@ function sendNickname(name) {
name name
}) })
}).then(res => { }).then(res => {
// Return JSON if status is OK
if (res.status === 200) if (res.status === 200)
return res.json(); return res.json();
}).then(res => { }).then(res => {
@ -217,11 +230,13 @@ function requestUsernames() {
'Accept': 'application/json', 'Accept': 'application/json',
} }
}).then(res => { }).then(res => {
// Return JSON if status is OK
if (res.status === 200) if (res.status === 200)
return res.json(); return res.json();
}).then(res => { }).then(res => {
if (res === undefined) if (res === undefined)
return; return;
// Output usernames
let output = ""; let output = "";
for (const u of res) for (const u of res)
output += `${u.name}#${u.id} `; output += `${u.name}#${u.id} `;
@ -240,6 +255,7 @@ function requestPing() {
}).then(res => { }).then(res => {
if (res.status !== 200) if (res.status !== 200)
return; return;
// Output measured ping time
const diff = new Date() - startTime; const diff = new Date() - startTime;
const output = `Host responded after ${diff}ms.`; const output = `Host responded after ${diff}ms.`;
outputText({output}) outputText({output})