Migrate frontend from monolithic app.js to vanilla ES modules
- Delete React files (App.jsx, main.jsx, App.css) - Create modular vanilla JS structure in client/src/: - state.js (global state object) - api.js (all fetch calls) - sse.js (SSE connection management) - ui/auth.js (authentication UI) - ui/downloads.js (downloads rendering) - ui/history.js (history section) - ui/statusPanel.js (status panel) - ui/webhooks.js (webhook management) - ui/filters.js (download client filter) - ui/theme.js (theme switching) - ui/tabs.js (tab navigation) - utils/format.js (formatting utilities) - utils/storage.js (localStorage helpers) - main.js (DOMContentLoaded bootstrap) - Update vite.config.js for vanilla build outputting to ../public/app.js - Build succeeds: 14 modules, 43.88 kB output
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2026 Gordon Bolton. MIT License.
|
||||
|
||||
import { state, SSE_RECONNECT_MS } from './state.js';
|
||||
import { renderDownloads } from './ui/downloads.js';
|
||||
import { hideError, hideLoading } from './ui/auth.js';
|
||||
|
||||
export function startSSE() {
|
||||
stopSSE();
|
||||
const params = state.showAll ? '?showAll=true' : '';
|
||||
const source = new EventSource('/api/dashboard/stream' + params);
|
||||
state.sseSource = source;
|
||||
|
||||
let firstMessage = true;
|
||||
source.onmessage = (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
state.currentUser = data.user;
|
||||
state.isAdmin = !!data.isAdmin;
|
||||
state.downloads = data.downloads;
|
||||
// Store download clients and update filter dropdown
|
||||
if (data.downloadClients) {
|
||||
state.downloadClients = data.downloadClients;
|
||||
// Trigger filter update
|
||||
const filterUpdateEvent = new CustomEvent('downloadClientsUpdated');
|
||||
document.dispatchEvent(filterUpdateEvent);
|
||||
}
|
||||
document.getElementById('currentUser').textContent = state.currentUser || '-';
|
||||
renderDownloads();
|
||||
hideError();
|
||||
if (firstMessage) { firstMessage = false; hideLoading(); }
|
||||
} catch (err) {
|
||||
console.error('[SSE] Failed to parse message:', err);
|
||||
}
|
||||
};
|
||||
|
||||
source.onerror = () => {
|
||||
// EventSource retries automatically; we just log and show a reconnecting indicator
|
||||
console.warn('[SSE] Connection lost, browser will retry...');
|
||||
};
|
||||
|
||||
console.log('[SSE] Stream connected');
|
||||
}
|
||||
|
||||
export function stopSSE() {
|
||||
if (state.sseReconnectTimer) { clearTimeout(state.sseReconnectTimer); state.sseReconnectTimer = null; }
|
||||
if (state.sseSource) {
|
||||
state.sseSource.close();
|
||||
state.sseSource = null;
|
||||
console.log('[SSE] Stream closed');
|
||||
}
|
||||
}
|
||||
|
||||
export function handleShowAllToggle(checked) {
|
||||
state.showAll = checked;
|
||||
// Re-open stream with updated showAll param
|
||||
startSSE();
|
||||
// Trigger history reload with updated showAll param
|
||||
const historyReloadEvent = new CustomEvent('historyReload');
|
||||
document.dispatchEvent(historyReloadEvent);
|
||||
}
|
||||
Reference in New Issue
Block a user