Добавлен будильник на тренировку с уведомлениями
This commit is contained in:
parent
eebb65e636
commit
093556b600
98
index.html
98
index.html
@ -414,6 +414,18 @@
|
|||||||
<div id="today" class="section active">
|
<div id="today" class="section active">
|
||||||
<h2>🔥 Тренировка на сегодня</h2>
|
<h2>🔥 Тренировка на сегодня</h2>
|
||||||
|
|
||||||
|
<!-- Будильник -->
|
||||||
|
<div style="background: linear-gradient(135deg, rgba(255,107,107,0.2), rgba(254,202,87,0.2)); border: 2px solid rgba(255,107,107,0.4); border-radius: 16px; padding: 25px; margin: 20px 0;">
|
||||||
|
<h3 style="margin-top: 0; color: #feca57;">🔔 Будильник на тренировку</h3>
|
||||||
|
<div style="display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
|
||||||
|
<input type="time" id="alarm-time" value="09:00" style="padding: 12px; border-radius: 10px; border: none; font-size: 18px; background: rgba(255,255,255,0.9); color: #1a1a2e;">
|
||||||
|
<button class="btn" onclick="setAlarm()">⏰ Поставить будильник</button>
|
||||||
|
<button class="btn btn-secondary" onclick="cancelAlarm()">❌ Отмена</button>
|
||||||
|
<span id="alarm-status" style="margin-left: auto; color: #00ff88; font-weight: 600;"></span>
|
||||||
|
</div>
|
||||||
|
<p style="margin-top: 15px; font-size: 14px; opacity: 0.8;">💡 Браузер покажет уведомление в заданное время (разреши уведомления при первом запуске)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Музыкальный плеер -->
|
<!-- Музыкальный плеер -->
|
||||||
<div class="music-player">
|
<div class="music-player">
|
||||||
<h3 style="margin-top:0; color: #00ff88;">🎵 Мотивационная музыка</h3>
|
<h3 style="margin-top:0; color: #00ff88;">🎵 Мотивационная музыка</h3>
|
||||||
@ -589,7 +601,8 @@
|
|||||||
{ type: "Отдых", exercises: [] }
|
{ type: "Отдых", exercises: [] }
|
||||||
];
|
];
|
||||||
|
|
||||||
let progressData = JSON.parse(localStorage.getItem('fitproProgress') || '{"entries":[],"completedDays":[],"water":[],"waterToday":0,"habits":{}}');
|
let progressData = JSON.parse(localStorage.getItem('fitproProgress') || '{"entries":[],"completedDays":[],"water":[],"waterToday":0,"habits":{},"alarm":null}');
|
||||||
|
let alarmTimeout = null;
|
||||||
|
|
||||||
// === ИНИЦИАЛИЗАЦИЯ ===
|
// === ИНИЦИАЛИЗАЦИЯ ===
|
||||||
function init() {
|
function init() {
|
||||||
@ -779,6 +792,89 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
// === БУДИЛЬНИК ===
|
||||||
|
function setAlarm() {
|
||||||
|
const time = document.getElementById('alarm-time').value;
|
||||||
|
if (!time) return alert('Выбери время!');
|
||||||
|
|
||||||
|
progressData.alarm = time;
|
||||||
|
localStorage.setItem('fitproProgress', JSON.stringify(progressData));
|
||||||
|
|
||||||
|
// Запрос разрешений на уведомления
|
||||||
|
if ('Notification' in window && Notification.permission === 'default') {
|
||||||
|
Notification.requestPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAlarm();
|
||||||
|
alert('⏰ Будильник установлен на ' + time + '!');
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelAlarm() {
|
||||||
|
progressData.alarm = null;
|
||||||
|
localStorage.setItem('fitproProgress', JSON.stringify(progressData));
|
||||||
|
if (alarmTimeout) clearTimeout(alarmTimeout);
|
||||||
|
document.getElementById('alarm-status').textContent = '';
|
||||||
|
alert('Будильник отменён');
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkAlarm() {
|
||||||
|
if (!progressData.alarm) return;
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const alarmTime = progressData.alarm;
|
||||||
|
const [hours, minutes] = alarmTime.split(':').map(Number);
|
||||||
|
|
||||||
|
const alarmDate = new Date();
|
||||||
|
alarmDate.setHours(hours, minutes, 0, 0);
|
||||||
|
|
||||||
|
// Если время уже прошло сегодня, ставим на завтра
|
||||||
|
if (alarmDate <= now) {
|
||||||
|
alarmDate.setDate(alarmDate.getDate() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const msUntilAlarm = alarmDate - now;
|
||||||
|
|
||||||
|
document.getElementById('alarm-status').textContent = '⏰ Будильник на ' + alarmTime + ' (через ' + Math.round(msUntilAlarm / 60000) + ' мин)';
|
||||||
|
|
||||||
|
if (alarmTimeout) clearTimeout(alarmTimeout);
|
||||||
|
|
||||||
|
alarmTimeout = setTimeout(() => {
|
||||||
|
triggerAlarm();
|
||||||
|
// Переставить на завтра
|
||||||
|
setTimeout(checkAlarm, 1000);
|
||||||
|
}, msUntilAlarm);
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerAlarm() {
|
||||||
|
// Звук
|
||||||
|
const audio = new Audio('https://actions.google.com/sounds/v1/alarms/beep_short.ogg');
|
||||||
|
audio.play();
|
||||||
|
|
||||||
|
// Уведомление
|
||||||
|
if ('Notification' in window && Notification.permission === 'granted') {
|
||||||
|
new Notification('💪 Пора на тренировку!', {
|
||||||
|
body: 'Твоя тренировка началась! Вперёд к цели! 🔥',
|
||||||
|
icon: 'https://cdn-icons-png.flaticon.com/512/2964/2964536.png'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
alert('💪 ПОРА НА ТРЕНИРОВКУ! 🔥');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Воспроизвести звук ещё раз через 5 минут
|
||||||
|
setTimeout(() => {
|
||||||
|
audio.play();
|
||||||
|
}, 300000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка будильника при загрузке
|
||||||
|
if (progressData.alarm) {
|
||||||
|
document.getElementById('alarm-time').value = progressData.alarm;
|
||||||
|
checkAlarm();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка каждую минуту
|
||||||
|
setInterval(checkAlarm, 60000);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user