more/better comments, splitting up functions and fixing chat output

This commit is contained in:
Baipyrus 2023-01-19 12:57:43 +01:00
parent 20c6a9330e
commit 4e2aeca765
3 changed files with 136 additions and 78 deletions

View File

@ -4,21 +4,25 @@ function runCommand(input) {
if (input === "") if (input === "")
return ""; return "";
// Exit current level
if (input.toLowerCase().startsWith("exit")) { if (input.toLowerCase().startsWith("exit")) {
cmd_exit(); cmd_exit();
return ""; return "";
} }
// Handle different chat modes
const modeSplit = chatMode.split(' '); const modeSplit = chatMode.split(' ');
switch (modeSplit[0]) { switch (modeSplit[0]) {
case "msg": case "msg":
directMessage(modeSplit[1], input) directMessage(modeSplit[1], input);
renameToSelf();
return ""; return "";
// case "chat": // case "chat":
// // Global messages // renameToSelf();
// return ""; // return "";
} }
// Default chat mode:
let output = ""; let output = "";
const lowerIn = input.toLowerCase(); const lowerIn = input.toLowerCase();
@ -53,24 +57,6 @@ function runCommand(input) {
return output; return output;
} }
function directMessage(name, message) {
// Direct message
fetch('/message', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: user.id,
message,
name
})
}).then(res => {});
}
// function globalMessage(message) {}
function cmd_help() { function cmd_help() {
// Display 'help' message // Display 'help' message
return "Commands list:<br>" + return "Commands list:<br>" +
@ -131,42 +117,23 @@ function cmd_exec(input) {
return eval(str).toString(); return eval(str).toString();
} }
// Echo out any given text
function cmd_echo(input) { function cmd_echo(input) {
if (input === undefined) if (input === undefined)
return " "; return " ";
return input.join(' '); return input.join(' ');
} }
// Set users' name
function cmd_nick(input) { function cmd_nick(input) {
if (input === undefined) if (input === undefined)
return "No nickname was given!"; return "No nickname was given!";
user.name = input[0]; user.name = input[0];
fetch('/nickname', { sendNickname();
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: user.name,
id: user.id
})
}).then(res => {
if (res.status === 200)
return res.json();
}).then(res => {
if (res === undefined)
return;
if (res.success)
outputText({output: `Applied name '${user.name}'.`});
else {
outputText({output: `Name '${user.name}' is already taken!`});
user.name = "";
}
});
return null; return null;
} }
// Initialize direct chat
function cmd_msg(input) { function cmd_msg(input) {
if (input === undefined) if (input === undefined)
return "No recipient was given!"; return "No recipient was given!";
@ -174,47 +141,33 @@ function cmd_msg(input) {
return "You are not connected!"; return "You are not connected!";
if (user.name === "") if (user.name === "")
return "You do not have a name!"; return "You do not have a name!";
// Get recipient username without spaces and pretext
const username = input[0]; const username = input[0];
pretext.current = `Chat (${username})> `; pretext.current = `Chat (${username})> `;
// Set chat mode to direct messages and start pulling
chatMode = `msg ${username}`; chatMode = `msg ${username}`;
user.chatPull = setInterval(() => { user.chatPull = setInterval(getChatMessages, 500);
fetch('/getChat', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: user.id
})
}).then(res => {
if (res.status === 200)
return res.json();
else if (res.status === 204)
return;
cmd_exit();
outputText({output: "Error occurred while fetching messages!"});
}).then(res => {
if (res === undefined)
return;
for (const user in res)
for (const msg of res[user])
outputText({output: msg});
});
}, 500);
} }
function cmd_exit() { // Exit current level (example: chat -> main)
function cmd_exit(error) {
const level = chatMode.split(' ')[0]; const level = chatMode.split(' ')[0];
if (level === "default") if (level === "default")
return "Already at top-level!"; return "Already at top-level!";
// Set mode to default and reset pretext
chatMode = "default"; chatMode = "default";
pretext.current = pretext.original; pretext.current = pretext.original;
// Do individual resets
switch (level) { switch (level) {
// case "chat": // case "chat":
case "msg": case "msg":
// Stop chat pulling
clearInterval(user.chatPull); clearInterval(user.chatPull);
break; break;
} }
// Exit was called automatically. Print error.
if (error)
outputText({output: error});
} }

View File

@ -118,12 +118,13 @@ document.addEventListener("keydown", e => {
}); });
function outputText(params) { function outputText(params) {
const { user, output } = params; const { user, output, preNext } = params;
tbDiv.removeChild(textIn); tbDiv.removeChild(textIn);
tbDiv.removeChild(textCur); tbDiv.removeChild(textCur);
if (user !== undefined) { if (user !== undefined) {
// Save input into history if it's not empty
const inputSet = new Set(user.split('')); const inputSet = new Set(user.split(''));
if (user !== "" || inputSet.has(" ") && inputSet.size === 1) { if (user !== "" || inputSet.has(" ") && inputSet.size === 1) {
history.list.push(user); history.list.push(user);
@ -136,8 +137,14 @@ function outputText(params) {
cursorYOffset++; cursorYOffset++;
} }
if (preNext !== undefined) {
const tbc = tbDiv.children;
tbc[tbc.length - 1].innerHTML = preNext;
}
// Run command and return output // Run command and return output
let commandOutput = (output === undefined && user !== undefined) ? runCommand(user) : output; const isUserInput = output === undefined && user !== undefined;
let commandOutput = isUserInput ? runCommand(user) : output;
if (commandOutput !== "" && commandOutput !== null) { if (commandOutput !== "" && commandOutput !== null) {
// If output is given, display it as text with formatting // If output is given, display it as text with formatting
tbDiv.append(createText(commandOutput, false)) tbDiv.append(createText(commandOutput, false))
@ -146,14 +153,19 @@ function outputText(params) {
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) {
tbDiv.innerHTML += pretext.current; const prelink = document.createElement('a');
prelink.innerHTML = pretext.current;
tbDiv.appendChild(prelink);
}
// Add elements on top of div // Add elements on top of div
tbDiv.appendChild(textCur); tbDiv.appendChild(textCur);
tbDiv.appendChild(textIn); tbDiv.appendChild(textIn);
// Reset variables // Reset variables
if (isUserInput) {
textCur.textContent = ""; textCur.textContent = "";
cursorPosition = 0; cursorPosition = 0;
}
updateCursor(); updateCursor();
} }
@ -171,6 +183,12 @@ function createText(str, safe=true) {
return link; return link;
} }
// Rename last-posted pretext to own username
function renameToSelf() {
const tbc = tbDiv.children;
tbc[tbc.length - 3].innerHTML = `${user.name}: `;
}
// Update cursor position based on coordinates // Update cursor position based on coordinates
function updateCursor() { function updateCursor() {
let cursor = document.getElementById("cursor"); let cursor = document.getElementById("cursor");

View File

@ -1,4 +1,9 @@
// Handle server connection // Global networking variables
const user = { id: "", name: "", history: [], connected: false, chatPull: null };
let chatMode = "default";
// Tell server to disconnect
document.body.onunload = document.body.onbeforeunload = () => { document.body.onunload = document.body.onbeforeunload = () => {
if (user.connected) if (user.connected)
fetch('/disconnect', { fetch('/disconnect', {
@ -13,18 +18,100 @@ document.body.onunload = document.body.onbeforeunload = () => {
}).then(res => {}); }).then(res => {});
}; };
// Connect to server
fetch('/connect').then(res => { fetch('/connect').then(res => {
if (res.status === 200) { if (res.status === 200) {
user.connected = true; user.connected = true;
return res.json(); return res.json();
} }
// No valid status code was sent
console.error("Could not connect to server!"); console.error("Could not connect to server!");
}).then(res => { }).then(res => {
if (res === undefined) if (res === undefined)
return; return;
// Save provided id
const { id } = res; const { id } = res;
user.id = id; user.id = id;
}); });
const user = { id: "", name: "", history: [], connected: false, chatPull: null };
let chatMode = "default"; // Send nickname to server, receive verification
function sendNickname() {
fetch('/nickname', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: user.name,
id: user.id
})
}).then(res => {
if (res.status === 200)
return res.json();
}).then(res => {
// No valid status code
if (res === undefined)
return;
// Reply whether name is taken or not
if (res.success)
outputText({output: `Applied name '${user.name}'.`});
else {
outputText({output: `Name '${user.name}' is already taken!`});
user.name = "";
}
});
}
// Pull incoming chat messages
function getChatMessages() {
fetch('/getChat', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: user.id
})
}).then(res => {
// Incoming messages
if (res.status === 200)
return res.json();
// No new messages
else if (res.status === 204)
return;
cmd_exit("Error occurred while fetching messages!");
}).then(res => {
// No messages or invalid status code
if (res === undefined)
return;
// Output all messages by user
for (const user in res)
for (const msg of res[user])
outputText({
preNext: `${user}: `,
output: msg
});
});
}
// Send a direct message, do not look at response
function directMessage(name, message) {
// Direct message
fetch('/message', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: user.id,
message,
name
})
}).then(res => {});
}
// function globalMessage(message) {}