update - add internal SFTP Endpoint
This commit is contained in:
@@ -28,11 +28,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
'enable-status'
|
||||
];
|
||||
|
||||
|
||||
|
||||
const sections = document.querySelectorAll('.section-bg');
|
||||
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry, index) => {
|
||||
if (entry.isIntersecting) {
|
||||
@@ -50,7 +47,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
observer.observe(section);
|
||||
});
|
||||
|
||||
|
||||
function throttle(fn, wait) {
|
||||
let lastTime = 0;
|
||||
return function (...args) {
|
||||
@@ -66,13 +62,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const hamburger = document.querySelector('.hamburger');
|
||||
const mobileNav = document.querySelector('[data-mobile-nav]');
|
||||
const navLinks = mobileNav.querySelectorAll('a');
|
||||
sections.forEach(section => {
|
||||
section.style.transform = 'translateY(30px)';
|
||||
section.style.opacity = '0';
|
||||
section.style.transition = 'transform 0.7s ease-out, opacity 0.7s ease-out';
|
||||
observer.observe(section);
|
||||
});
|
||||
|
||||
|
||||
// Debounce function to prevent rapid clicks
|
||||
function debounce(fn, wait) {
|
||||
@@ -101,6 +90,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
hamburger.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
const elements = {
|
||||
loginPage: document.getElementById('loginPage'),
|
||||
loginApiKey: document.getElementById('loginApiKey'),
|
||||
@@ -459,6 +449,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
fitAddon = null;
|
||||
}
|
||||
}
|
||||
|
||||
function connectWebSocket() {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
return;
|
||||
@@ -485,7 +476,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
'my-sftp-cache',
|
||||
'backup',
|
||||
'sftp-status',
|
||||
'holesail-hashes'
|
||||
'holesail-hashes',
|
||||
'internal-sftp'
|
||||
]
|
||||
}));
|
||||
responseTimeout = setTimeout(() => {
|
||||
@@ -498,6 +490,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
try {
|
||||
clearTimeout(responseTimeout);
|
||||
const message = JSON.parse(event.data);
|
||||
// Handle internal-sftp message immediately to save credentials
|
||||
if (message.type === 'internal-sftp' && message.data?.hostname && message.data?.port && message.data?.user && message.data?.password) {
|
||||
sftpCredentials = {
|
||||
hostname: message.data.hostname,
|
||||
port: message.data.port,
|
||||
user: message.data.user,
|
||||
password: message.data.password
|
||||
};
|
||||
if (!hasAttemptedSftpConnect) {
|
||||
hasAttemptedSftpConnect = true;
|
||||
connectSftp();
|
||||
}
|
||||
}
|
||||
if (message.requestId && pendingRequests.has(message.requestId)) {
|
||||
const { resolve, reject, notification, key } = pendingRequests.get(message.requestId);
|
||||
pendingRequests.delete(message.requestId);
|
||||
@@ -610,39 +615,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function updateDockerUI(message) {
|
||||
if (message.error) {
|
||||
console.log('Docker error detected, setting status to Not Running');
|
||||
if (elements.serverStatus) elements.serverStatus.textContent = 'Not Running';
|
||||
toggleSections('Not Running');
|
||||
return;
|
||||
}
|
||||
|
||||
const memoryPercent = parseFloat(message.data?.memory?.percent) || 0;
|
||||
if (state.memoryPercent !== memoryPercent && elements.memoryPercent && memoryMeter) {
|
||||
memoryMeter.data.datasets[0].data = [memoryPercent, 100 - memoryPercent];
|
||||
memoryMeter.update();
|
||||
elements.memoryPercent.textContent = `${memoryPercent.toFixed(1)}%`;
|
||||
state.memoryPercent = memoryPercent;
|
||||
}
|
||||
|
||||
const cpuPercent = parseFloat(message.data?.cpu) || 0;
|
||||
if (state.cpuPercent !== cpuPercent && elements.cpuPercent && cpuMeter) {
|
||||
const scaledCpuPercent = Math.min((cpuPercent / 600) * 100, 100);
|
||||
cpuMeter.data.datasets[0].data = [scaledCpuPercent, 100 - scaledCpuPercent];
|
||||
cpuMeter.update();
|
||||
elements.cpuPercent.textContent = `${cpuPercent.toFixed(1)}%`;
|
||||
state.cpuPercent = cpuPercent;
|
||||
}
|
||||
|
||||
const status = message.data?.status || 'Unknown';
|
||||
if (elements.serverStatus) {
|
||||
elements.serverStatus.textContent = status;
|
||||
state.serverStatus = status;
|
||||
toggleSections(status);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSections(status) {
|
||||
const sections = document.querySelectorAll('.section-bg');
|
||||
const serverStatusSection = document.querySelector('.section-bg[data-section="server-status"]');
|
||||
@@ -653,7 +625,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const stopBtn = elements.stopBtn;
|
||||
const restartBtn = elements.restartBtn;
|
||||
const sftpBrowserSection = elements.sftpBrowserSection;
|
||||
// Menu items in desktop and mobile nav
|
||||
const refreshBtn = elements.refresh || document.getElementById('refresh');
|
||||
const mobileRefreshBtn = elements.mobileRefresh || document.getElementById('mobileRefresh');
|
||||
const backupBtn = elements.backupBtn;
|
||||
@@ -672,13 +643,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
if (status.toLowerCase() !== 'running') {
|
||||
// Hide all sections except Server Status
|
||||
sections.forEach(section => {
|
||||
if (section !== serverStatusSection) {
|
||||
section.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
// Hide control buttons
|
||||
if (editPropertiesBtn) {
|
||||
editPropertiesBtn.classList.add('hidden');
|
||||
editPropertiesBtn.style.display = 'none';
|
||||
@@ -701,7 +670,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (sftpBrowserSection) {
|
||||
sftpBrowserSection.style.display = 'none';
|
||||
}
|
||||
// Hide Refresh, Backup, and Logout buttons in desktop nav
|
||||
if (refreshBtn) {
|
||||
refreshBtn.classList.add('hidden');
|
||||
refreshBtn.style.display = 'none';
|
||||
@@ -714,7 +682,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
logoutBtn.classList.add('hidden');
|
||||
logoutBtn.style.display = 'none';
|
||||
}
|
||||
// Hide Refresh, Backup, and Logout menu items in mobile nav
|
||||
if (mobileRefreshBtn && mobileRefreshBtn.parentElement) {
|
||||
mobileRefreshBtn.parentElement.classList.add('hidden');
|
||||
}
|
||||
@@ -729,11 +696,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
state.hasShownStartNotification = true;
|
||||
}
|
||||
} else {
|
||||
// Show all sections
|
||||
sections.forEach(section => {
|
||||
section.classList.remove('hidden');
|
||||
});
|
||||
// Show control buttons
|
||||
if (editPropertiesBtn) {
|
||||
editPropertiesBtn.classList.remove('hidden');
|
||||
editPropertiesBtn.style.display = '';
|
||||
@@ -751,12 +716,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
if (restartBtn) {
|
||||
restartBtn.disabled = false;
|
||||
stopBtn.classList.remove('disabled-btn');
|
||||
restartBtn.classList.remove('disabled-btn');
|
||||
}
|
||||
if (sftpBrowserSection) {
|
||||
sftpBrowserSection.style.display = 'block';
|
||||
}
|
||||
// Show Refresh, Backup, and Logout buttons in desktop nav
|
||||
if (refreshBtn) {
|
||||
refreshBtn.classList.remove('hidden');
|
||||
refreshBtn.style.display = '';
|
||||
@@ -769,7 +733,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
logoutBtn.classList.remove('hidden');
|
||||
logoutBtn.style.display = '';
|
||||
}
|
||||
// Show Refresh, Backup, and Logout menu items in mobile nav
|
||||
if (mobileRefreshBtn && mobileRefreshBtn.parentElement) {
|
||||
mobileRefreshBtn.parentElement.classList.remove('hidden');
|
||||
}
|
||||
@@ -840,21 +803,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
function updateSftpCacheUI(message) {
|
||||
if (message.data?.hostname && message.data?.port && message.data?.user && message.data?.password) {
|
||||
sftpCredentials = {
|
||||
hostname: state.user,
|
||||
port: 22,
|
||||
user: message.data.user,
|
||||
password: message.data.password
|
||||
};
|
||||
const sftpLinkText = `${message.data.hostname}:${message.data.port}`;
|
||||
if (state.sftpLink !== sftpLinkText && elements.sftpLink) {
|
||||
elements.sftpLink.textContent = sftpLinkText;
|
||||
state.sftpLink = sftpLinkText;
|
||||
}
|
||||
if (!hasAttemptedSftpConnect) {
|
||||
hasAttemptedSftpConnect = true;
|
||||
connectSftp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -931,12 +884,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
state.currentPlayers = players;
|
||||
const isSinglePlayer = players.length <= 1;
|
||||
|
||||
// Initialize state for tracking action button visibility if not already present
|
||||
state.actionButtonStates = state.actionButtonStates || {};
|
||||
|
||||
const playerListHtml = players.length > 0
|
||||
? players.map(player => {
|
||||
// Default to hidden action buttons unless state says otherwise
|
||||
const isActionButtonsVisible = state.actionButtonStates[player] || false;
|
||||
return `
|
||||
<div class="flex items-center space-x-4 mb-2">
|
||||
@@ -964,7 +915,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
elements.playerList.innerHTML = playerListHtml;
|
||||
state.playerList = playerListHtml;
|
||||
|
||||
// Remove existing event listeners to prevent duplication
|
||||
const toggleButtons = document.querySelectorAll('.toggle-actions');
|
||||
const closeButtons = document.querySelectorAll('.close-actions');
|
||||
toggleButtons.forEach(button => {
|
||||
@@ -974,7 +924,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
button.replaceWith(button.cloneNode(true));
|
||||
});
|
||||
|
||||
// Add event listeners for toggle actions
|
||||
document.querySelectorAll('.toggle-actions').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const player = button.getAttribute('data-player').trim();
|
||||
@@ -982,12 +931,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (actionDiv) {
|
||||
actionDiv.classList.remove('hidden');
|
||||
button.classList.add('hidden');
|
||||
state.actionButtonStates[player] = true; // Update state
|
||||
state.actionButtonStates[player] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Add event listeners for close actions
|
||||
document.querySelectorAll('.close-actions').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const player = button.getAttribute('data-player').trim();
|
||||
@@ -996,7 +944,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (actionDiv && toggleButton) {
|
||||
actionDiv.classList.add('hidden');
|
||||
toggleButton.classList.remove('hidden');
|
||||
state.actionButtonStates[player] = false; // Update state
|
||||
state.actionButtonStates[player] = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1290,7 +1238,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
function showMainContent() {
|
||||
// Check if apiKey exists in localStorage
|
||||
const apiKey = localStorage.getItem('apiKey');
|
||||
if (!apiKey) {
|
||||
console.error('API key not found in localStorage');
|
||||
@@ -1309,7 +1256,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
elements.loginPage.classList.add('hidden');
|
||||
elements.mainContent.classList.remove('hidden');
|
||||
|
||||
// Verify buttons exist
|
||||
const logoutBtn = document.getElementById('logoutBtn');
|
||||
const mobileLogoutBtn = document.getElementById('mobileLogoutBtn');
|
||||
|
||||
@@ -1325,10 +1271,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
console.error('Mobile logout button (#mobileLogoutBtn) not found');
|
||||
}
|
||||
|
||||
// Remove any existing logout listeners to prevent duplicates
|
||||
document.removeEventListener('click', handleLogoutClick);
|
||||
|
||||
// Event delegation for logout buttons
|
||||
function handleLogoutClick(event) {
|
||||
if (event.target.id === 'logoutBtn' || event.target.id === 'mobileLogoutBtn') {
|
||||
console.log(`Logout button clicked: ${event.target.id}`);
|
||||
@@ -1910,6 +1854,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
elements.editPropertiesModal.appendChild(modal);
|
||||
}
|
||||
|
||||
|
||||
function renderPropertiesList(properties, filter = '') {
|
||||
const propertiesList = elements.propertiesFields.querySelector('#propertiesList');
|
||||
propertiesList.innerHTML = '';
|
||||
|
Reference in New Issue
Block a user