正计时 added temporary by AI

This commit is contained in:
2026-10-17 19:58:08 +08:00
parent 972e9a75e5
commit 316331e614
3 changed files with 131 additions and 0 deletions
+116
View File
@@ -36,6 +36,7 @@
_cdModalMode: false, // true = countdown modal, false = alarm modal
_editingCountdown: null,
timezone: 'Asia/Shanghai', // 账户独立时区(来自 /api/display/state)
countUp: { status: 'idle', startedAtMs: null, baseSec: 0, frozenSec: 0 },
};
// ─── DOM refs ─────────────────────────────
@@ -107,6 +108,10 @@
if (name === 'pomodoro') {
fetchPomodoro();
}
// Immediately render count-up when switching back to time panel
if (name === 'time') {
renderCountUpPanel();
}
}
cards.forEach(function (card) {
@@ -1298,6 +1303,108 @@
n.y + '年' + n.mo + '月' + n.d + '日 星期' + days[n.wd];
}
function _calcCountUpElapsed() {
var c = state.countUp;
if (!c) return 0;
if (c.status !== 'running') return c.frozenSec || 0;
try {
if (c.startedAtMs == null) return c.frozenSec || 0;
return (c.baseSec || 0) + Math.floor((Date.now() - c.startedAtMs) / 1000);
} catch (_) {
return c.frozenSec || 0;
}
}
function _formatCountUp(totalSec) {
if (typeof totalSec !== 'number' || !isFinite(totalSec) || totalSec < 0) {
return '00:00:00';
}
var h = Math.floor(totalSec / 3600);
var m = Math.floor((totalSec % 3600) / 60);
var s = totalSec % 60;
return _pad2(h) + ':' + _pad2(m) + ':' + _pad2(s);
}
function renderCountUpPanel() {
try {
var c = state.countUp || {};
var el = $('countup-value');
if (!el) return;
el.textContent = _formatCountUp(_calcCountUpElapsed());
var btnStart = $('countup-start');
var btnStop = $('countup-stop');
var btnReset = $('countup-reset');
var running = c.status === 'running';
if (btnStart) btnStart.style.display = running ? 'none' : '';
if (btnReset) btnReset.style.display = running ? 'none' : '';
if (btnStop) btnStop.style.display = running ? '' : 'none';
} catch (e) {
console.warn('countUp render failed:', e);
}
}
function countUpStart() {
try {
var c = state.countUp;
if (c.status === 'running') return;
c.baseSec = 0;
c.startedAtMs = Date.now();
c.status = 'running';
renderCountUpPanel();
} catch (e) {
console.warn('countUp start failed:', e);
}
}
function countUpStop() {
try {
var c = state.countUp;
if (c.status !== 'running') return;
c.frozenSec = _calcCountUpElapsed();
c.startedAtMs = null;
c.status = 'idle';
renderCountUpPanel();
} catch (e) {
console.warn('countUp stop failed:', e);
}
}
function countUpReset() {
try {
var c = state.countUp;
c.frozenSec = 0;
c.startedAtMs = null;
c.status = 'idle';
renderCountUpPanel();
} catch (e) {
console.warn('countUp reset failed:', e);
}
}
function setupCountUpControls() {
var btnStart = $('countup-start');
var btnStop = $('countup-stop');
var btnReset = $('countup-reset');
if (btnStart) {
btnStart.addEventListener('click', function (e) {
e.stopPropagation();
countUpStart();
});
}
if (btnStop) {
btnStop.addEventListener('click', function (e) {
e.stopPropagation();
countUpStop();
});
}
if (btnReset) {
btnReset.addEventListener('click', function (e) {
e.stopPropagation();
countUpReset();
});
}
}
function renderWeatherPanel() {
var w = state.weather || {};
if (w.temp === undefined) {
@@ -1621,6 +1728,7 @@
renderCountdownCard();
renderPomodoroCard();
if (state.activePanel === 'time') renderTimePanel();
if (state.activePanel === 'time') renderCountUpPanel();
if (state.activePanel === 'pomodoro') renderPomodoro();
if (state.activePanel === 'countdown') renderCountdownPanel();
// Refresh update schedule info every 10s to keep next-update times current
@@ -1648,5 +1756,13 @@
fetchState();
connectSSE();
switchPanel('time');
setupCountUpControls();
document.addEventListener('visibilitychange', function () {
try {
if (document.visibilityState === 'visible' && state.activePanel === 'time') {
renderCountUpPanel();
}
} catch (_) {}
});
})();