not reload when visible

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-07-11 01:11:35 +02:00
padre 8c8cd61bf8
commit c6b8d812c2
Se han modificado 3 ficheros con 93 adiciones y 16 borrados

Ver fichero

@@ -72,6 +72,7 @@ app.get('/tail/api/files', (req, res) => {
app.get('/tail/api/files/:endpoint', (req, res) => {
const endpoint = path.normalize(req.params.endpoint)
const file = path.join(directory, endpoint)
const isReconnect = req.query.reconnect === 'true'
// Security check - ensure file is within the directory
if (!file.startsWith(path.resolve(directory))) {
@@ -95,14 +96,20 @@ app.get('/tail/api/files/:endpoint', (req, res) => {
}
})
// For reconnections, start from current end, for new connections start from 'end'
const beginAt = isReconnect ? fs.statSync(file).size : 'end'
const stream = ts.createReadStream(file, {
beginAt: 'end',
beginAt: beginAt,
endOnError: true,
detectTruncate: true
})
// Send initial message
res.write(Buffer.from(`data: Tailing ${endpoint}...\n\n`))
const initialMessage = isReconnect
? `Reconnected to ${endpoint}...`
: `Tailing ${endpoint}...`
res.write(Buffer.from(`data: ${initialMessage}\n\n`))
// Handle stream events
stream.on('error', error => {

Ver fichero

@@ -571,6 +571,32 @@ input:checked + .slider:before {
background: rgba(6, 182, 212, 0.1);
}
.log-line.reconnect-message {
border-left-color: var(--warning-color);
background: rgba(245, 158, 11, 0.15);
color: var(--warning-color);
font-style: italic;
text-align: center;
margin: var(--spacing-sm) 0;
}
.log-line.reconnect-message i {
margin-right: var(--spacing-xs);
}
.log-line.reconnect-success {
border-left-color: var(--success-color);
background: rgba(16, 185, 129, 0.15);
color: var(--success-color);
font-style: italic;
text-align: center;
margin: var(--spacing-sm) 0;
}
.log-line.reconnect-success i {
margin-right: var(--spacing-xs);
}
/* Loading states */
.loading {
display: flex;

Ver fichero

@@ -234,7 +234,7 @@ class LogTailMonitor {
/**
* Start tailing a specific file
*/
async startTailing(filename) {
async startTailing(filename, isReconnect = false) {
this.showLoading('Connecting to ' + filename + '...');
// Stop current connection
@@ -254,17 +254,28 @@ class LogTailMonitor {
}
});
// Clear existing logs
// Clear existing logs only if it's not a reconnection
if (!isReconnect) {
this.clearLogs();
} else {
// Add a reconnection indicator to the existing logs
this.addReconnectionMessage();
}
try {
// Start SSE connection
this.eventSource = new EventSource(`api/files/${encodeURIComponent(filename)}`);
// Start SSE connection with reconnect parameter if needed
const url = `api/files/${encodeURIComponent(filename)}${isReconnect ? '?reconnect=true' : ''}`;
this.eventSource = new EventSource(url);
this.eventSource.onopen = () => {
this.hideLoading();
this.setConnectionStatus(true);
console.log('SSE connection established');
// If this is a reconnection, add a success message
if (isReconnect) {
this.addReconnectionSuccessMessage();
}
};
this.eventSource.onmessage = (event) => {
@@ -283,11 +294,11 @@ class LogTailMonitor {
console.log('SSE connection closed');
}
// Auto-reconnect after delay
// Auto-reconnect after delay, but don't clear logs
setTimeout(() => {
if (this.currentFile && this.eventSource.readyState === EventSource.CLOSED) {
console.log('Attempting to reconnect...');
this.startTailing(this.currentFile);
this.startTailing(this.currentFile, true); // true = isReconnect
}
}, 5000);
};
@@ -568,6 +579,36 @@ class LogTailMonitor {
this.elements.loadingOverlay.classList.remove('visible');
}
/**
* Add a reconnection message to the log
*/
addReconnectionMessage() {
const reconnectLine = document.createElement('div');
reconnectLine.className = 'log-line reconnect-message';
reconnectLine.innerHTML = '<i class="fas fa-plug"></i> Reconnecting to log stream...';
this.elements.logOutput.appendChild(reconnectLine);
if (this.autoScroll) {
this.scrollToBottom();
}
}
/**
* Add a successful reconnection message to the log
*/
addReconnectionSuccessMessage() {
const successLine = document.createElement('div');
successLine.className = 'log-line reconnect-success';
successLine.innerHTML = '<i class="fas fa-check-circle"></i> Successfully reconnected - continuing log stream...';
this.elements.logOutput.appendChild(successLine);
if (this.autoScroll) {
this.scrollToBottom();
}
}
/**
* Escape HTML to prevent XSS
*/
@@ -580,15 +621,18 @@ class LogTailMonitor {
// Initialize the application when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
new LogTailMonitor();
window.logMonitor = new LogTailMonitor();
});
// Handle page visibility changes
// Handle page visibility changes - attempt reconnection instead of reload
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
// Refresh connection when page becomes visible
if (document.visibilityState === 'visible' && window.logMonitor) {
// Try to reconnect to current file if connection was lost
if (window.logMonitor.currentFile && (!window.logMonitor.eventSource || window.logMonitor.eventSource.readyState === EventSource.CLOSED)) {
console.log('Page became visible, attempting to reconnect...');
setTimeout(() => {
window.location.reload();
window.logMonitor.startTailing(window.logMonitor.currentFile, true);
}, 1000);
}
}
});