This PR breaks the large web and player bootstrap files into smaller modules with clearer ownership.

Web changes:

Split shared helpers, bootstrap logic, route groups, and upload-sync behavior out of web.js.
Kept web.js focused on wiring and server startup.
Fixed screen playlist reassignment so changing a screen’s playlist now triggers a refresh.
Fixed single-slide playlist refresh behavior so updates do not get stuck behind the current slide.
Player changes:

Split websocket/runtime handling into runtime.js.
Split playlist assembly and revision hashing into playlist.js.
Split onboarding and player HTTP routes into dedicated modules.
Split render utilities and template loading into render-helpers.js.
Kept player.js mostly as startup/orchestration.
Validation:

Rebuilt both services with Docker Compose.
Smoke-checked web and player routes after the refactor.
Verified get_errors was clean on the touched modules.
This commit is contained in:
2026-07-20 23:58:27 +01:00
parent 480ccdbe9c
commit 2ea8d389fa
321 changed files with 12687 additions and 7080 deletions
+1 -38
View File
@@ -13,44 +13,7 @@ function screenPlayerUrl(slug) {
return `${PLAYER_PUBLIC_BASE_URL}/screen/${encodeURIComponent(slug)}`;
}
function renderAdminShell(active, title, body, message) {
const navItems = [
{ key: 'dashboard', label: 'Dashboard', href: '/admin' },
{ key: 'playlists', label: 'Playlists', href: '/admin/playlists' },
{ key: 'screens', label: 'Screens', href: '/admin/screens' },
{ key: 'slides', label: 'Slides', href: '/admin/slides' },
{ key: 'templates', label: 'Slide templates', href: '/admin/templates' }
].map((item) => `
<a class="nav-item ${active === item.key ? 'active' : ''}" href="${item.href}">${escapeHtml(item.label)}</a>
`).join('');
return `<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>${escapeHtml(title)} - Pulse Signage</title>
<link rel="stylesheet" href="/assets/css/admin.css" />
</head>
<body>
<div class="app">
<aside class="sidebar">
<h1>Pulse Signage</h1>
<nav class="nav">${navItems}</nav>
</aside>
<main class="content">
<div class="page-header">
<h2>${escapeHtml(title)}</h2>
</div>
${body}
</main>
</div>
</body>
</html>`;
}
module.exports = {
escapeHtml,
screenPlayerUrl,
renderAdminShell
screenPlayerUrl
};