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);