/* ===== Task Timer ===== */ window.NAITimer = { startTime: null, timerInterval: null, history: [], // recent task durations for ETA MAX_HISTORY: 10, start() { this.startTime = Date.now(); this._updateDisplay(); this.timerInterval = setInterval(() => this._updateDisplay(), 100); this._showTimer(true); }, stop(completed = true) { if (this.startTime && completed) { const duration = Date.now() - this.startTime; this.history.push(duration); if (this.history.length > this.MAX_HISTORY) this.history.shift(); } clearInterval(this.timerInterval); this.timerInterval = null; this.startTime = null; // Show final time briefly, then hide setTimeout(() => this._showTimer(false), 3000); }, _getAvgDuration() { if (this.history.length === 0) return 0; return this.history.reduce((a, b) => a + b, 0) / this.history.length; }, _formatTime(ms) { const s = Math.floor(ms / 1000); const m = Math.floor(s / 60); const sec = s % 60; const tenths = Math.floor((ms % 1000) / 100); if (m > 0) return `${m}:${String(sec).padStart(2, '0')}.${tenths}`; return `${sec}.${tenths}s`; }, _updateDisplay() { const el = document.getElementById('task-timer'); if (!el || !this.startTime) return; const elapsed = Date.now() - this.startTime; const avg = this._getAvgDuration(); let text = this._formatTime(elapsed); if (avg > 0) { const remaining = Math.max(0, avg - elapsed); if (remaining > 0) { text += ` / 预计 ${this._formatTime(avg)}`; } else { text += ` / 预计 ${this._formatTime(avg)}`; } } el.textContent = text; // Progress bar const bar = document.getElementById('task-timer-bar'); if (bar && avg > 0) { const pct = Math.min(100, (elapsed / avg) * 100); bar.style.width = pct + '%'; bar.className = 'task-timer-bar-fill' + (pct >= 100 ? ' overtime' : ''); } }, _showTimer(show) { const wrap = document.getElementById('task-timer-wrap'); if (wrap) wrap.style.display = show ? 'flex' : 'none'; }, init() { // Create timer UI in header const headerRight = document.querySelector('.header-right'); if (!headerRight) return; const wrap = document.createElement('div'); wrap.id = 'task-timer-wrap'; wrap.className = 'task-timer-wrap'; wrap.style.display = 'none'; wrap.innerHTML = `
`; headerRight.insertBefore(wrap, headerRight.firstChild); }, };