'use strict'; // --------------------------------------------------------------------------- // Focus Timer // --------------------------------------------------------------------------- const TIMER_WORK = 25 * 60; const TIMER_BREAK = 5 * 60; let timerSeconds = TIMER_WORK; let timerRunning = false; let timerIsBreak = false; let timerInterval = null; function timerTick() { timerSeconds--; renderTimer(); if (timerSeconds <= 0) { clearInterval(timerInterval); timerInterval = null; timerRunning = false; if (!timerIsBreak) { // work session ended → start break timerIsBreak = true; recordFocusSession(); timerSeconds = TIMER_BREAK; showTimerNotification('Pause! 5 Minuten.'); // auto-pause playback during break if (audio.src && !audio.paused) audio.pause(); } else { // break ended → reset to work timerIsBreak = false; timerSeconds = TIMER_WORK; showTimerNotification('Pause vorbei. Weiter geht’s.'); } renderTimer(); } } function toggleTimer() { if (timerRunning) { clearInterval(timerInterval); timerInterval = null; timerRunning = false; } else { if ('Notification' in window && Notification.permission === 'default') { Notification.requestPermission(); } timerRunning = true; timerInterval = setInterval(timerTick, 1000); } renderTimer(); } function resetTimer() { clearInterval(timerInterval); timerInterval = null; timerRunning = false; timerIsBreak = false; timerSeconds = TIMER_WORK; renderTimer(); } function renderTimer() { const m = String(Math.floor(timerSeconds / 60)).padStart(2, '0'); const s = String(timerSeconds % 60).padStart(2, '0'); const display = $('timer-display'); const btn = $('timer-toggle-btn'); const label = $('timer-phase-label'); if (display) display.textContent = `${m}:${s}`; if (btn) btn.textContent = timerRunning ? '⏸' : '▶'; if (label) label.textContent = timerIsBreak ? 'Pause' : 'Fokus'; // colour the display red when break if (display) display.style.color = timerIsBreak ? '#e63946' : ''; } function showTimerNotification(msg) { if ('Notification' in window && Notification.permission === 'granted') { new Notification('diora', { body: msg }); } // also flash in the timer label const label = $('timer-phase-label'); if (label) { label.textContent = msg; setTimeout(() => renderTimer(), 3000); } } // --------------------------------------------------------------------------- // Focus session recording // --------------------------------------------------------------------------- async function recordFocusSession() { try { await fetch('/radio/focus/record/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCsrfToken() }, body: JSON.stringify({ station_name: currentStation ? currentStation.name : '', duration_minutes: 25, }), }); loadFocusStats(); } catch (e) {} } async function loadFocusStats() { try { const res = await fetch('/radio/focus/stats/'); const data = await res.json(); const widget = document.getElementById('focus-today-widget'); if (widget) { if (data.today_sessions > 0) { widget.textContent = `Heute: ${data.today_sessions} ${data.today_sessions !== 1 ? 'Sitzungen' : 'Sitzung'} · ${data.today_minutes} min`; widget.style.display = ''; } else { widget.style.display = 'none'; } } // populate focus tab const tbody = document.getElementById('focus-tbody'); if (!tbody) return; tbody.innerHTML = ''; if (!data.sessions.length) { tbody.innerHTML = '