/* babies_app/countdown-banner.js */ (() => { const KV_KEY = 'family_date'; const READ_URL = '/api/kv/family_date'; const MS_2H = 2 * 3600_000; // 2 小时自动过期 let plan = null; let timer = null; function fmt(ms) { if (ms <= 0) return 'Time to meet!'; const d = Math.floor(ms / 86400_000); const h = Math.floor((ms % 86400_000) / 3600_000); const m = Math.floor((ms % 3600_000) / 60000); const s = Math.floor((ms % 60000) / 1000); const arr = []; if (d) arr.push(`${d}d`); if (h || d) arr.push(`${h}h`); if (m || h || d) arr.push(`${m}m`); arr.push(`${s}s`); return arr.join(' ') + ' ✨'; } async function fetchPlan() { try { const res = await fetch(READ_URL); if (!res.ok) return null; const txt = await res.text(); const p = txt ? JSON.parse(txt) : null; if (p && p.date && Date.now() - p.date < MS_2H) return p; } catch {} return null; } async function refreshPlan() { plan = await fetchPlan(); render(); } function render() { const banner = document.getElementById('banner'); if (!banner) return; if (plan && plan.date) { const diff = plan.date - Date.now(); banner.textContent = `Family at ${plan.place} – ${plan.day} ${plan.time} | ${fmt(diff)}`; } else { banner.textContent = 'Family Date – no plan yet'; } } function tick() { if (!plan || !plan.date) return; render(); if (plan.date - Date.now() <= 0) { clearInterval(timer); timer = null; } } /* 公共 API */ window.refreshPlan = refreshPlan; /* 初始化 */ refreshPlan().then(() => { if (plan && plan.date) { timer = setInterval(tick, 1000); } document.dispatchEvent(new CustomEvent('planLoaded')); }); })();