#37 Working Joining and Leaving
This commit is contained in:
@@ -1,98 +1,13 @@
|
|||||||
// Modules
|
// Modules
|
||||||
const { SlashCommandBuilder } = require('discord.js');
|
const { SlashCommandBuilder } = require('discord.js');
|
||||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||||
const { getMembersInRole, getAllClientIds, filterAutocompleteValues, getKeyByArrayValue } = require("../utilities/utils");
|
const { filterAutocompleteValues } = require("../utilities/utils");
|
||||||
const { requestOptions, sendHttpRequest } = require("../utilities/httpRequests");
|
const { getOnlineNodes, getAllConnections } = require("../utilities/mysqlHandler");
|
||||||
const { getOnlineNodes, updateNodeInfo, addNodeConnection, getConnectionByNodeId, getAllConnections } = require("../utilities/mysqlHandler");
|
const { joinServerWrapper } = require("../controllers/adminController");
|
||||||
|
|
||||||
// Global Vars
|
// Global Vars
|
||||||
const log = new DebugBuilder("server", "join");
|
const log = new DebugBuilder("server", "join");
|
||||||
|
|
||||||
/**
|
|
||||||
* * This wrapper will check if there is an available node with the requested preset and if so checks for an available client ID to join with
|
|
||||||
*
|
|
||||||
* @param {*} presetName The preset name to listen to on the client
|
|
||||||
* @param {*} channelId The channel ID to join the bot to
|
|
||||||
* @param {*} connections EITHER A collection of clients that are currently connected OR a single discord client ID (NOT dev portal ID) that should be used to join the server with
|
|
||||||
* @param {number} nodeId [OPTIONAL] The node ID to join with (will join with another node if given node is not available)
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async function joinServerWrapper(presetName, channelId, connections, nodeId = 0) {
|
|
||||||
// Get nodes online
|
|
||||||
var onlineNodes = await new Promise((recordResolve, recordReject) => {
|
|
||||||
getOnlineNodes((nodeRows) => {
|
|
||||||
recordResolve(nodeRows);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check which nodes have the selected preset
|
|
||||||
onlineNodes = onlineNodes.filter(node => node.presets.includes(presetName));
|
|
||||||
log.DEBUG("Filtered Online Nodes: ", onlineNodes);
|
|
||||||
|
|
||||||
// Check if any nodes with this preset are available
|
|
||||||
var nodesCurrentlyAvailable = [];
|
|
||||||
for (const node of onlineNodes) {
|
|
||||||
const currentConnection = await getConnectionByNodeId(node.id);
|
|
||||||
log.DEBUG("Checking to see if there is a connection for Node: ", node, currentConnection);
|
|
||||||
if(!currentConnection) nodesCurrentlyAvailable.push(node);
|
|
||||||
}
|
|
||||||
log.DEBUG("Nodes Currently Available: ", nodesCurrentlyAvailable);
|
|
||||||
|
|
||||||
// If not, let the user know
|
|
||||||
if (!nodesCurrentlyAvailable.length > 0) return Error("All nodes with this channel are unavailable, consider swapping one of the currently joined bots.");
|
|
||||||
|
|
||||||
// If so, join with the first node
|
|
||||||
var availableClientIds = await getAllClientIds();
|
|
||||||
log.DEBUG("All clients: ", Object.keys(availableClientIds));
|
|
||||||
|
|
||||||
var selectedClientId;
|
|
||||||
if (typeof connections === 'string') {
|
|
||||||
for (const availableClientId of availableClientIds) {
|
|
||||||
if (availableClientId.discordId != connections ) selectedClientId = availableClientId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.DEBUG("Open connections: ", connections);
|
|
||||||
for (const connection of connections) {
|
|
||||||
log.DEBUG("Used Client ID: ", connection);
|
|
||||||
availableClientIds = availableClientIds.filter(cid => cid.discordId != connection.clientObject.discordId);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.DEBUG("Available Client IDs: ", availableClientIds);
|
|
||||||
|
|
||||||
if (!Object.keys(availableClientIds).length > 0) return log.ERROR("All client ID have been used, consider swapping one of the curretly joined bots or adding more Client IDs to the pool.")
|
|
||||||
selectedClientId = availableClientIds[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
let selectedNode;
|
|
||||||
if (nodeId > 0) selectedNode = getKeyByArrayValue(nodesCurrentlyAvailable, nodeId);
|
|
||||||
|
|
||||||
if (!selectedNode) selectedNode = nodesCurrentlyAvailable[0];
|
|
||||||
|
|
||||||
const reqOptions = new requestOptions("/bot/join", "POST", selectedNode.ip, selectedNode.port);
|
|
||||||
const postObject = {
|
|
||||||
"channelId": channelId,
|
|
||||||
"clientId": selectedClientId.clientId,
|
|
||||||
"presetName": presetName
|
|
||||||
};
|
|
||||||
log.INFO("Post Object: ", postObject);
|
|
||||||
sendHttpRequest(reqOptions, JSON.stringify(postObject), async (responseObj) => {
|
|
||||||
log.VERBOSE("Response Object from node ", selectedNode, responseObj);
|
|
||||||
if (!responseObj || !responseObj.statusCode == 200) return false;
|
|
||||||
// Node has connected to discord
|
|
||||||
// Updating node Object in DB
|
|
||||||
const updatedNode = await updateNodeInfo(selectedNode);
|
|
||||||
log.DEBUG("Updated Node: ", updatedNode);
|
|
||||||
|
|
||||||
// Adding a new node connection
|
|
||||||
const nodeConnection = await addNodeConnection(selectedNode, selectedClientId);
|
|
||||||
log.DEBUG("Node Connection: ", nodeConnection);
|
|
||||||
});
|
|
||||||
|
|
||||||
return selectedClientId;
|
|
||||||
}
|
|
||||||
exports.joinServerWrapper = joinServerWrapper;
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('join')
|
.setName('join')
|
||||||
|
|||||||
@@ -2,41 +2,12 @@
|
|||||||
const { SlashCommandBuilder } = require('discord.js');
|
const { SlashCommandBuilder } = require('discord.js');
|
||||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||||
const { getAllClientIds, getKeyByArrayValue, filterAutocompleteValues } = require("../utilities/utils");
|
const { getAllClientIds, getKeyByArrayValue, filterAutocompleteValues } = require("../utilities/utils");
|
||||||
const { requestOptions, sendHttpRequest } = require("../utilities/httpRequests");
|
const { getAllConnections } = require('../utilities/mysqlHandler');
|
||||||
const { checkNodeConnectionByClientId, removeNodeConnectionByNodeId, getAllConnections } = require('../utilities/mysqlHandler');
|
const { leaveServerWrapper } = require('../controllers/adminController');
|
||||||
|
|
||||||
// Global Vars
|
// Global Vars
|
||||||
const log = new DebugBuilder("server", "leave");
|
const log = new DebugBuilder("server", "leave");
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {*} clientIdObject The client ID object for the node to leave the server. Either 'clientId'||'name' can be set.
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async function leaveServerWrapper(clientIdObject) {
|
|
||||||
if (!clientIdObject.clientId || !clientIdObject.name) return log.ERROR("Tried to leave server without client ID and/or Name");
|
|
||||||
|
|
||||||
const node = await checkNodeConnectionByClientId(clientIdObject);
|
|
||||||
|
|
||||||
reqOptions = new requestOptions("/bot/leave", "POST", node.ip, node.port);
|
|
||||||
|
|
||||||
const responseObj = await new Promise((recordResolve, recordReject) => {
|
|
||||||
sendHttpRequest(reqOptions, JSON.stringify({}), async (responseObj) => {
|
|
||||||
recordResolve(responseObj);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
log.VERBOSE("Response Object from node ", node, responseObj);
|
|
||||||
if (!responseObj || !responseObj.statusCode == 202) return false;
|
|
||||||
// Node has disconnected from discor
|
|
||||||
// Removing the node connection from the DB
|
|
||||||
const removedConnection = removeNodeConnectionByNodeId(node.id);
|
|
||||||
log.DEBUG("Removed Node Connection: ", removedConnection);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
exports.leaveServerWrapper = leaveServerWrapper;
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('leave')
|
.setName('leave')
|
||||||
@@ -64,7 +35,6 @@ module.exports = {
|
|||||||
log.DEBUG("Client names: ", clinetIds);
|
log.DEBUG("Client names: ", clinetIds);
|
||||||
const clientDiscordId = getKeyByArrayValue(clinetIds, {'name': botName});
|
const clientDiscordId = getKeyByArrayValue(clinetIds, {'name': botName});
|
||||||
log.DEBUG("Selected bot: ", clinetIds[clientDiscordId]);
|
log.DEBUG("Selected bot: ", clinetIds[clientDiscordId]);
|
||||||
// Need to create a table in DB to keep track of what bots have what IDs or an endpoint on the clients to return what ID they are running with
|
|
||||||
await leaveServerWrapper(clinetIds[clientDiscordId]);
|
await leaveServerWrapper(clinetIds[clientDiscordId]);
|
||||||
|
|
||||||
await interaction.editReply(`**${clinetIds[clientDiscordId].name}** has been disconnected`); // This will reply to the initial interaction
|
await interaction.editReply(`**${clinetIds[clientDiscordId].name}** has been disconnected`); // This will reply to the initial interaction
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ require('dotenv').config();
|
|||||||
const { DebugBuilder } = require("../utilities/debugBuilder.js");
|
const { DebugBuilder } = require("../utilities/debugBuilder.js");
|
||||||
const log = new DebugBuilder("server", "adminController");
|
const log = new DebugBuilder("server", "adminController");
|
||||||
// Utilities
|
// Utilities
|
||||||
const mysqlHandler = require("../utilities/mysqlHandler");
|
const { getAllClientIds } = require("../utilities/utils");
|
||||||
const utils = require("../utilities/utils");
|
const { getOnlineNodes, updateNodeInfo, addNodeConnection, getConnectionByNodeId, getNodeInfoFromId, checkNodeConnectionByClientId, removeNodeConnectionByNodeId } = require("../utilities/mysqlHandler");
|
||||||
const requests = require("../utilities/httpRequests");
|
const { requestOptions, sendHttpRequest } = require("../utilities/httpRequests");
|
||||||
const { leaveServerWrapper } = require("../commands/leave");
|
|
||||||
const { joinServerWrapper } = require("../commands/join");
|
|
||||||
|
|
||||||
|
|
||||||
/** Get the presets of all online nodes, can be used for functions
|
/** Get the presets of all online nodes, can be used for functions
|
||||||
*
|
*
|
||||||
@@ -17,15 +14,15 @@ const { joinServerWrapper } = require("../commands/join");
|
|||||||
* @returns {*} A list of the systems online
|
* @returns {*} A list of the systems online
|
||||||
*/
|
*/
|
||||||
async function getPresetsOfOnlineNodes(callback) {
|
async function getPresetsOfOnlineNodes(callback) {
|
||||||
mysqlHandler.getOnlineNodes((onlineNodes) => {
|
getOnlineNodes((onlineNodes) => {
|
||||||
return callback(onlineNodes);
|
return callback(onlineNodes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getNodeBotStatus(nodeId, callback) {
|
async function getNodeBotStatus(nodeId, callback) {
|
||||||
mysqlHandler.getNodeInfoFromId(nodeId, (nodeObject) =>{
|
getNodeInfoFromId(nodeId, (nodeObject) =>{
|
||||||
reqOptions = new requests.requestOptions("/bot/status", "GET", nodeObject.ip, nodeObject.port, undefined, 5);
|
reqOptions = new requestOptions("/bot/status", "GET", nodeObject.ip, nodeObject.port, undefined, 5);
|
||||||
requests.sendHttpRequest(reqOptions, JSON.stringify({}), (responseObject) => {
|
sendHttpRequest(reqOptions, JSON.stringify({}), (responseObject) => {
|
||||||
if (responseObject === false) {
|
if (responseObject === false) {
|
||||||
// Bot is joined
|
// Bot is joined
|
||||||
}
|
}
|
||||||
@@ -73,21 +70,141 @@ exports.joinPreset = async (req, res) => {
|
|||||||
|
|
||||||
const joinedClient = await joinServerWrapper(preset, channelId, clientId, nodeId);
|
const joinedClient = await joinServerWrapper(preset, channelId, clientId, nodeId);
|
||||||
if (!joinedClient) return res.send(400).json("No joined client");
|
if (!joinedClient) return res.send(400).json("No joined client");
|
||||||
return res.send(200).json(joinedClient);
|
return res.status(200).json(joinedClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Request a node to join the server listening to a specific preset
|
/** Request a node to join the server listening to a specific preset
|
||||||
*
|
*
|
||||||
* @param {*} req Express request parameter
|
* @param {*} req Express request parameter
|
||||||
* @param {*} res Express response parameter
|
* @param {*} res Express response parameter
|
||||||
* @var {*} req.body.clientId The ID of the client to disconnect
|
* @var {*} req.body.nodeId The ID of the node to disconnect
|
||||||
*/
|
*/
|
||||||
exports.leaveServer = async (req, res) => {
|
exports.leaveServer = async (req, res) => {
|
||||||
if (!req.body.clientId) return res.status(400).json("No clientID specified");
|
if (!req.body.nodeId) return res.status(400).json("No node ID specified");
|
||||||
|
|
||||||
const clientId = req.body.clientId;
|
const nodeId = req.body.nodeId;
|
||||||
|
const currentConnection = await getConnectionByNodeId(nodeId);
|
||||||
|
log.DEBUG("Current Connection for node: ", currentConnection);
|
||||||
|
|
||||||
await leaveServerWrapper(clientId)
|
await leaveServerWrapper(currentConnection.clientObject)
|
||||||
|
|
||||||
return res.send(200);
|
return res.status(200).json(currentConnection.clientObject.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * This wrapper will check if there is an available node with the requested preset and if so checks for an available client ID to join with
|
||||||
|
*
|
||||||
|
* @param {*} presetName The preset name to listen to on the client
|
||||||
|
* @param {*} channelId The channel ID to join the bot to
|
||||||
|
* @param {*} connections EITHER A collection of clients that are currently connected OR a single discord client ID (NOT dev portal ID) that should be used to join the server with
|
||||||
|
* @param {number} nodeId [OPTIONAL] The node ID to join with (will join with another node if given node is not available)
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function joinServerWrapper(presetName, channelId, connections, nodeId = 0) {
|
||||||
|
// Get nodes online
|
||||||
|
var onlineNodes = await new Promise((recordResolve, recordReject) => {
|
||||||
|
getOnlineNodes((nodeRows) => {
|
||||||
|
recordResolve(nodeRows);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check which nodes have the selected preset
|
||||||
|
onlineNodes = onlineNodes.filter(node => node.presets.includes(presetName));
|
||||||
|
log.DEBUG("Filtered Online Nodes: ", onlineNodes);
|
||||||
|
|
||||||
|
// Check if any nodes with this preset are available
|
||||||
|
var nodesCurrentlyAvailable = [];
|
||||||
|
for (const node of onlineNodes) {
|
||||||
|
const currentConnection = await getConnectionByNodeId(node.id);
|
||||||
|
log.DEBUG("Checking to see if there is a connection for Node: ", node, currentConnection);
|
||||||
|
if(!currentConnection) nodesCurrentlyAvailable.push(node);
|
||||||
|
}
|
||||||
|
log.DEBUG("Nodes Currently Available: ", nodesCurrentlyAvailable);
|
||||||
|
|
||||||
|
// If not, let the user know
|
||||||
|
if (!nodesCurrentlyAvailable.length > 0) return Error("All nodes with this channel are unavailable, consider swapping one of the currently joined bots.");
|
||||||
|
|
||||||
|
// If so, join with the first node
|
||||||
|
var availableClientIds = await getAllClientIds();
|
||||||
|
log.DEBUG("All clients: ", Object.keys(availableClientIds));
|
||||||
|
|
||||||
|
var selectedClientId;
|
||||||
|
if (typeof connections === 'string') {
|
||||||
|
for (const availableClientId of availableClientIds) {
|
||||||
|
if (availableClientId.discordId != connections ) selectedClientId = availableClientId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.DEBUG("Open connections: ", connections);
|
||||||
|
for (const connection of connections) {
|
||||||
|
log.DEBUG("Used Client ID: ", connection);
|
||||||
|
availableClientIds = availableClientIds.filter(cid => cid.discordId != connection.clientObject.discordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.DEBUG("Available Client IDs: ", availableClientIds);
|
||||||
|
|
||||||
|
if (!Object.keys(availableClientIds).length > 0) return log.ERROR("All client ID have been used, consider swapping one of the curretly joined bots or adding more Client IDs to the pool.")
|
||||||
|
selectedClientId = availableClientIds[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
let selectedNode;
|
||||||
|
if (nodeId > 0) {
|
||||||
|
for(const availableNode of nodesCurrentlyAvailable){
|
||||||
|
if (availableNode.id == nodeId) selectedNode = availableNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedNode) selectedNode = nodesCurrentlyAvailable[0];
|
||||||
|
|
||||||
|
const reqOptions = new requestOptions("/bot/join", "POST", selectedNode.ip, selectedNode.port);
|
||||||
|
const postObject = {
|
||||||
|
"channelId": channelId,
|
||||||
|
"clientId": selectedClientId.clientId,
|
||||||
|
"presetName": presetName
|
||||||
|
};
|
||||||
|
log.INFO("Post Object: ", postObject);
|
||||||
|
sendHttpRequest(reqOptions, JSON.stringify(postObject), async (responseObj) => {
|
||||||
|
log.VERBOSE("Response Object from node ", selectedNode, responseObj);
|
||||||
|
if (!responseObj || !responseObj.statusCode == 200) return false;
|
||||||
|
// Node has connected to discord
|
||||||
|
// Updating node Object in DB
|
||||||
|
const updatedNode = await updateNodeInfo(selectedNode);
|
||||||
|
log.DEBUG("Updated Node: ", updatedNode);
|
||||||
|
|
||||||
|
// Adding a new node connection
|
||||||
|
const nodeConnection = await addNodeConnection(selectedNode, selectedClientId);
|
||||||
|
log.DEBUG("Node Connection: ", nodeConnection);
|
||||||
|
});
|
||||||
|
|
||||||
|
return selectedClientId;
|
||||||
|
}
|
||||||
|
exports.joinServerWrapper = joinServerWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} clientIdObject The client ID object for the node to leave the server. Either 'clientId'||'name' can be set.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function leaveServerWrapper(clientIdObject) {
|
||||||
|
if (!clientIdObject.clientId || !clientIdObject.name) return log.ERROR("Tried to leave server without client ID and/or Name");
|
||||||
|
|
||||||
|
const node = await checkNodeConnectionByClientId(clientIdObject);
|
||||||
|
|
||||||
|
reqOptions = new requestOptions("/bot/leave", "POST", node.ip, node.port);
|
||||||
|
|
||||||
|
const responseObj = await new Promise((recordResolve, recordReject) => {
|
||||||
|
sendHttpRequest(reqOptions, JSON.stringify({}), async (responseObj) => {
|
||||||
|
recordResolve(responseObj);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
log.VERBOSE("Response Object from node ", node, responseObj);
|
||||||
|
if (!responseObj || !responseObj.statusCode == 202) return false;
|
||||||
|
// Node has disconnected from discor
|
||||||
|
// Removing the node connection from the DB
|
||||||
|
const removedConnection = removeNodeConnectionByNodeId(node.id);
|
||||||
|
log.DEBUG("Removed Node Connection: ", removedConnection);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
exports.leaveServerWrapper = leaveServerWrapper;
|
||||||
@@ -192,7 +192,8 @@ exports.requestNodeCheckIn = async (req, res) => {
|
|||||||
if (!req.params.nodeId) return res.status(400).json("No Node ID supplied in request");
|
if (!req.params.nodeId) return res.status(400).json("No Node ID supplied in request");
|
||||||
const node = await getNodeInfoFromId(req.params.nodeId);
|
const node = await getNodeInfoFromId(req.params.nodeId);
|
||||||
if (!node) return res.status(400).json("No Node with the ID given");
|
if (!node) return res.status(400).json("No Node with the ID given");
|
||||||
checkInWithNode(node);
|
await checkInWithNode(node);
|
||||||
|
res.sendStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,6 +38,48 @@ function addFrequencyInput(system){
|
|||||||
document.getElementById(`frequencyRow_${system.replaceAll(" ", "_")}`).appendChild(colParent);
|
document.getElementById(`frequencyRow_${system.replaceAll(" ", "_")}`).appendChild(colParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createToast(notificationMessage){
|
||||||
|
const toastTitle = document.createElement('strong');
|
||||||
|
toastTitle.classList.add('me-auto');
|
||||||
|
toastTitle.appendChild(document.createTextNode("Server Notification"));
|
||||||
|
|
||||||
|
const toastTime = document.createElement('small');
|
||||||
|
toastTime.appendChild(document.createTextNode(Date.now().toLocaleString()));
|
||||||
|
|
||||||
|
const toastClose = document.createElement('button');
|
||||||
|
toastClose.type = 'button';
|
||||||
|
toastClose.classList.add('btn-close');
|
||||||
|
toastClose.ariaLabel = 'Close';
|
||||||
|
toastClose.setAttribute('data-bs-dismiss', 'toast');
|
||||||
|
|
||||||
|
const toastHeader = document.createElement('div');
|
||||||
|
toastHeader.classList.add('toast-header');
|
||||||
|
toastHeader.appendChild(toastTitle);
|
||||||
|
toastHeader.appendChild(toastTime);
|
||||||
|
toastHeader.appendChild(toastClose);
|
||||||
|
|
||||||
|
|
||||||
|
const toastMessage = document.createElement('p');
|
||||||
|
toastMessage.classList.add("px-2");
|
||||||
|
toastMessage.appendChild(document.createTextNode(notificationMessage));
|
||||||
|
|
||||||
|
const toastBody = document.createElement('div');
|
||||||
|
toastBody.classList.add('toast-body');
|
||||||
|
toastBody.appendChild(toastMessage);
|
||||||
|
|
||||||
|
const wrapperDiv = document.createElement('div');
|
||||||
|
wrapperDiv.classList.add('toast');
|
||||||
|
wrapperDiv.role ='alert';
|
||||||
|
wrapperDiv.ariaLive = 'assertive';
|
||||||
|
wrapperDiv.ariaAtomic = true;
|
||||||
|
wrapperDiv.appendChild(toastHeader);
|
||||||
|
wrapperDiv.appendChild(toastMessage);
|
||||||
|
|
||||||
|
document.getElementById("toastZone").appendChild(wrapperDiv);
|
||||||
|
|
||||||
|
$('.toast').toast('show');
|
||||||
|
}
|
||||||
|
|
||||||
function checkInByNodeId(nodeId){
|
function checkInByNodeId(nodeId){
|
||||||
const Http = new XMLHttpRequest();
|
const Http = new XMLHttpRequest();
|
||||||
const url='/nodes/'+nodeId;
|
const url='/nodes/'+nodeId;
|
||||||
@@ -46,5 +88,56 @@ function checkInByNodeId(nodeId){
|
|||||||
|
|
||||||
Http.onreadystatechange = (e) => {
|
Http.onreadystatechange = (e) => {
|
||||||
console.log(Http.responseText)
|
console.log(Http.responseText)
|
||||||
|
createToast(Http.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function joinServer(){
|
||||||
|
const preset = document.getElementById("selectRadioPreset").value;
|
||||||
|
const nodeId = document.getElementById("nodeId").value;
|
||||||
|
const clientId = document.getElementById("inputDiscordClientId").value;
|
||||||
|
const channelId = document.getElementById("inputDiscordChannelId").value;
|
||||||
|
|
||||||
|
const reqBody = {
|
||||||
|
'preset': preset,
|
||||||
|
'nodeId': nodeId,
|
||||||
|
'clientId': clientId,
|
||||||
|
'channelId': channelId
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(reqBody);
|
||||||
|
|
||||||
|
const Http = new XMLHttpRequest();
|
||||||
|
const url='/admin/join';
|
||||||
|
Http.open("POST", url);
|
||||||
|
Http.setRequestHeader("Content-Type", "application/json");
|
||||||
|
Http.send(JSON.stringify(reqBody));
|
||||||
|
|
||||||
|
Http.onloadend = (e) => {
|
||||||
|
const responseObject = JSON.parse(Http.responseText)
|
||||||
|
console.log(Http.status);
|
||||||
|
console.log(responseObject);
|
||||||
|
createToast(`${responseObject.name} will join shortly`);
|
||||||
|
$("#joinModal").modal('toggle');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function leaveServer(){
|
||||||
|
const nodeId = document.getElementById("nodeId").value;
|
||||||
|
const reqBody = {
|
||||||
|
'nodeId': nodeId
|
||||||
|
};
|
||||||
|
|
||||||
|
const Http = new XMLHttpRequest();
|
||||||
|
const url='/admin/leave';
|
||||||
|
Http.open("POST", url);
|
||||||
|
Http.setRequestHeader("Content-Type", "application/json");
|
||||||
|
Http.send(JSON.stringify(reqBody));
|
||||||
|
|
||||||
|
Http.onloadend = (e) => {
|
||||||
|
const responseObject = JSON.parse(Http.responseText)
|
||||||
|
console.log(Http.status);
|
||||||
|
console.log(responseObject);
|
||||||
|
createToast(`${responseObject} is leaving`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,8 @@ class nodeObject {
|
|||||||
this.ip = _ip;
|
this.ip = _ip;
|
||||||
this.port = _port;
|
this.port = _port;
|
||||||
this.location = _location;
|
this.location = _location;
|
||||||
this.nearbySystems = _nearbySystems;
|
this.nearbySystems = _nearbySystems;
|
||||||
|
if (this.nearbySystems) this.presets = Object.keys(_nearbySystems);
|
||||||
this.online = _online;
|
this.online = _online;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form>
|
<form>
|
||||||
<div class="row gx-3 mb-3">
|
<div class="row gx-3 mb-3">
|
||||||
<div class="">
|
<div class="">
|
||||||
|
|
||||||
@@ -26,9 +26,9 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
<hr>
|
<hr>
|
||||||
<!-- Join Server button-->
|
<!-- Join Server button-->
|
||||||
<a type="button" class="btn btn-info <% if(!node.online) { %>disabled<% } %>" href="/join/<%=node.id%>">Join Server</a>
|
<a type="button" class="btn btn-info <% if(!node.online) { %>disabled<% } %>" data-bs-toggle="modal" data-bs-target="#joinModal" href="#">Join Server</a>
|
||||||
<!-- Leave Server button -->
|
<!-- Leave Server button -->
|
||||||
<a type="button" class="btn btn-danger <% if(!node.online) { %>disabled<% } %>" href="/leave/<%=node.id%>">Leave Server</a>
|
<a type="button" class="btn btn-danger <% if(!node.online) { %>disabled<% } %>" href="#" onclick="leaveServer()">Leave Server</a>
|
||||||
<!-- Checkin with client button -->
|
<!-- Checkin with client button -->
|
||||||
<a type="button" class="btn btn-secondary" href="#" onclick="checkInByNodeId('<%=node.id%>')">Check-in with Node</a>
|
<a type="button" class="btn btn-secondary" href="#" onclick="checkInByNodeId('<%=node.id%>')">Check-in with Node</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -149,6 +149,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<%- include('partials/joinModal.ejs', {'nearbySystems': node.nearbySystems}) %>
|
||||||
<%- include('partials/bodyEnd.ejs') %>
|
<%- include('partials/bodyEnd.ejs') %>
|
||||||
<script src="/res/js/node.js"></script>
|
<script src="/res/js/node.js"></script>
|
||||||
<%- include('partials/htmlFooter.ejs') %>
|
<%- include('partials/htmlFooter.ejs') %>
|
||||||
@@ -2,5 +2,6 @@
|
|||||||
<html lang="en" data-bs-theme="auto">
|
<html lang="en" data-bs-theme="auto">
|
||||||
<%- include('head.ejs') %>
|
<%- include('head.ejs') %>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="toast-container mx-2" id="toastZone"></div>
|
||||||
<%- include('navbar.ejs') %>
|
<%- include('navbar.ejs') %>
|
||||||
<%- include('sidebar.ejs') %>
|
<%- include('sidebar.ejs') %>
|
||||||
44
Server/views/partials/joinModal.ejs
Normal file
44
Server/views/partials/joinModal.ejs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<div class="modal fade" id="joinModal" tabindex="-1" aria-labelledby="joinModal" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="joinModal">Join Node <%=node.id%> to a Discord Server</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-body">
|
||||||
|
<form>
|
||||||
|
<div class="row gx-3 mb-3">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="small mb-1" for="inputDiscordClientId">Discord Client ID:</label>
|
||||||
|
<input class="form-control" id="inputDiscordClientId" type="text" value="" required></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row gx-3 mb-3">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="small mb-1" for="inputDiscordChannelId">Discord Channel ID:</label>
|
||||||
|
<input class="form-control" id="inputDiscordChannelId" type="text" value="" required></input>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="small mb-1" for="selectRadioPreset">Selected Preset:</label>
|
||||||
|
<select class="custom-select" id="selectRadioPreset">
|
||||||
|
<% for(const system in nearbySystems) { %>
|
||||||
|
<option value="<%=system%>"><%=system%></option>
|
||||||
|
<% } %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="joinServer()">Join</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user