class ToolFocus extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = `
Ready to Focus
25:00
`; this.timeLeft = 25 * 60; this.timerId = null; this.isRunning = false; this.displayEl = this.shadowRoot.getElementById('display'); this.startBtn = this.shadowRoot.getElementById('startBtn'); this.resetBtn = this.shadowRoot.getElementById('resetBtn'); this.statusEl = this.shadowRoot.getElementById('status'); // Bind events this.startBtn.addEventListener('click', () => this.toggleTimer()); this.resetBtn.addEventListener('click', () => this.resetTimer()); this.updateDisplay(); feather.replace(); } updateDisplay() { const m = Math.floor(this.timeLeft / 60).toString().padStart(2, '0'); const s = (this.timeLeft % 60).toString().padStart(2, '0'); this.displayEl.textContent = `${m}:${s}`; // Update favicon/title dynamically could be a nice touch document.title = this.isRunning ? `(${m}:${s}) Focus` : 'FlowState OS 🌊'; } toggleTimer() { if (this.isRunning) { this.pauseTimer(); } else { this.startTimer(); } } startTimer() { if (this.timeLeft === 0) return; this.isRunning = true; this.statusEl.textContent = 'Focusing...'; this.statusEl.classList.add('active'); this.startBtn.innerHTML = ' Pause'; feather.replace(); this.timerId = setInterval(() => { this.timeLeft--; this.updateDisplay(); if (this.timeLeft <= 0) { this.completeTimer(); } }, 1000); } pauseTimer() { this.isRunning = false; clearInterval(this.timerId); this.statusEl.textContent = 'Paused'; this.statusEl.classList.remove('active'); this.startBtn.innerHTML = ' Resume'; feather.replace(); } resetTimer() { this.pauseTimer(); this.timeLeft = 25 * 60; this.statusEl.textContent = 'Ready to Focus'; this.startBtn.innerHTML = ' Start'; this.updateDisplay(); feather.replace(); } setTimer(minutes) { this.resetTimer(); this.timeLeft = minutes * 60; this.updateDisplay(); } completeTimer() { this.pauseTimer(); this.timeLeft = 0; this.updateDisplay(); this.statusEl.textContent = 'Session Complete! 🎉'; // Simple sound effect simulation via Visual Flash this.shadowRoot.querySelector('.container').style.borderColor = '#10b981'; setTimeout(() => { this.shadowRoot.querySelector('.container').style.borderColor = '#334155'; }, 2000); } } customElements.define('tool-focus', ToolFocus);