Skip to main content

max / makenotwork

2.3 KB · 78 lines History Blame Raw
1 // Deploy/restart warning banner, ported from mnw.js:578-652. Polls
2 // /api/restart-status; shows a countdown banner when a restart is scheduled.
3
4 /** Start polling for a scheduled restart and render the countdown banner. */
5 export function initRestartBanner(): void {
6 let banner: HTMLElement | null = null;
7 let countdownInterval: ReturnType<typeof setInterval> | null = null;
8 let restartAt: number | null = null;
9
10 function createBanner(): void {
11 if (banner) return;
12 banner = document.createElement('div');
13 banner.id = 'restart-banner';
14 banner.className = 'banner banner--warning';
15 banner.setAttribute('role', 'alert');
16 document.body.prepend(banner);
17 }
18
19 function removeBanner(): void {
20 if (banner) {
21 banner.remove();
22 banner = null;
23 }
24 if (countdownInterval) {
25 clearInterval(countdownInterval);
26 countdownInterval = null;
27 }
28 restartAt = null;
29 }
30
31 function updateCountdown(): void {
32 if (!banner || restartAt === null) return;
33 const remaining = Math.max(0, Math.round(restartAt - Date.now() / 1000));
34 if (remaining > 0) {
35 banner.textContent = 'Update deploying — restarting in ' + remaining + 's';
36 } else {
37 banner.textContent = 'Restarting now...';
38 if (countdownInterval) {
39 clearInterval(countdownInterval);
40 countdownInterval = null;
41 }
42 }
43 }
44
45 function startCountdown(ts: number): void {
46 restartAt = ts;
47 createBanner();
48 updateCountdown();
49 if (countdownInterval) clearInterval(countdownInterval);
50 countdownInterval = setInterval(updateCountdown, 1000);
51 }
52
53 function poll(): void {
54 fetch('/api/restart-status')
55 .then((r) => r.json())
56 .then((data: { restart_at?: number }) => {
57 if (data.restart_at) {
58 if (restartAt === null || restartAt !== data.restart_at) startCountdown(data.restart_at);
59 } else {
60 removeBanner();
61 }
62 })
63 .catch(() => {
64 // Already counting down and the poll failed: assume it's happening now.
65 if (restartAt !== null) {
66 if (banner) banner.textContent = 'Restarting now...';
67 if (countdownInterval) {
68 clearInterval(countdownInterval);
69 countdownInterval = null;
70 }
71 }
72 });
73 }
74
75 setTimeout(poll, 2000);
76 setInterval(poll, 10000);
77 }
78