-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
154 lines (142 loc) · 5.05 KB
/
script.js
File metadata and controls
154 lines (142 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
const timeEl = document.getElementById("time");
const dateInput = document.getElementById("alarmDate");
const timeInput = document.getElementById("alarmTime");
const setBtn = document.getElementById("setAlarm");
const alarmsEl = document.getElementById("alarms");
const audio = document.getElementById("alarmAudio");
let alarms = JSON.parse(localStorage.getItem("alarms")) || [];
let alarmTimeouts = [];
const MAX_ALARMS = 5;
// Update live time
function updateTime() {
const now = new Date();
let hrs = now.getHours();
const mins = now.getMinutes().toString().padStart(2, "0");
const secs = now.getSeconds().toString().padStart(2, "0");
const ampm = hrs >= 12 ? "PM" : "AM";
hrs = hrs % 12 || 12;
timeEl.textContent = `${hrs.toString().padStart(2, "0")}:${mins}:${secs} ${ampm}`;
}
// Set min date to today
function setMinDate() {
const today = new Date().toISOString().split("T")[0];
dateInput.min = today;
}
setMinDate();
// Render alarms list
function renderAlarms() {
if (alarms.length === 0) {
alarmsEl.innerHTML = "<small class='text-white-50'>No alarms set</small>";
return;
}
alarmsEl.innerHTML = alarms.map((alarm, idx) => {
const alarmDate = new Date(alarm);
return `
<div class="alarm row align-items-center p-2" data-idx="${idx}">
<div class="col">
<div>${alarmDate.toLocaleString()}</div>
</div>
<div class="col-auto">
<button class="btn btn-outline-danger btn-sm me-1 delete-alarm">Delete</button>
</div>
</div>
`;
}).join("");
addDeleteListeners();
}
// Add delete listeners
function addDeleteListeners() {
document.querySelectorAll(".delete-alarm").forEach(btn => {
btn.addEventListener("click", (e) => {
const idx = parseInt(e.target.closest(".alarm").dataset.idx);
alarms.splice(idx, 1);
localStorage.setItem("alarms", JSON.stringify(alarms));
clearAlarm(idx);
renderAlarms();
});
});
}
// Clear specific alarm timeout
function clearAlarm(idx) {
if (alarmTimeouts[idx]) {
clearTimeout(alarmTimeouts[idx]);
alarmTimeouts[idx] = null;
}
}
// Set alarm
setBtn.addEventListener("click", () => {
const alarmDateTime = new Date(dateInput.value + "T" + timeInput.value);
const now = new Date();
if (alarmDateTime <= now) {
alert("Please select a future date and time.");
return;
}
if (alarms.length >= MAX_ALARMS) {
alert(`Maximum ${MAX_ALARMS} alarms allowed.`);
return;
}
alarms.push(alarmDateTime.toISOString());
localStorage.setItem("alarms", JSON.stringify(alarms));
const timeUntil = alarmDateTime - now;
const idx = alarms.length - 1;
alarmTimeouts[idx] = setTimeout(() => triggerAlarm(idx), timeUntil);
renderAlarms();
dateInput.value = "";
timeInput.value = "";
});
// Trigger alarm with audio and UI feedback
function triggerAlarm(idx) {
const alarmEl = document.querySelector(`[data-idx="${idx}"]`);
if (alarmEl) {
alarmEl.classList.add("alarm-ringing");
}
audio.play().catch(() => console.log("Audio play failed; user interaction needed."));
// Show snooze/stop modal or buttons (simplified with alert + buttons)
const stopBtn = document.createElement("button");
stopBtn.className = "btn btn-danger me-2";
stopBtn.textContent = "Stop";
stopBtn.onclick = () => stopAlarm(idx);
const snoozeBtn = document.createElement("button");
snoozeBtn.className = "btn btn-warning";
snoozeBtn.textContent = "Snooze 10min";
snoozeBtn.onclick = () => snoozeAlarm(idx);
alarmsEl.appendChild(stopBtn);
alarmsEl.appendChild(snoozeBtn);
}
// Stop alarm
function stopAlarm(idx) {
audio.pause();
audio.currentTime = 0;
const alarmEl = document.querySelector(`[data-idx="${idx}"]`);
if (alarmEl) alarmEl.classList.remove("alarm-ringing");
alarms.splice(idx, 1);
localStorage.setItem("alarms", JSON.stringify(alarms));
clearAlarm(idx);
renderAlarms();
}
// Snooze (reschedule 10 min later)
function snoozeAlarm(idx) {
audio.pause();
audio.currentTime = 0;
const alarmDate = new Date(alarms[idx]);
alarmDate.setMinutes(alarmDate.getMinutes() + 10);
alarms[idx] = alarmDate.toISOString();
localStorage.setItem("alarms", JSON.stringify(alarms));
clearAlarm(idx);
const timeUntil = alarmDate - new Date();
alarmTimeouts[idx] = setTimeout(() => triggerAlarm(idx), timeUntil);
renderAlarms();
}
// Init
renderAlarms();
setInterval(updateTime, 1000);
updateTime();
// Re-arm persisted alarms
alarms.forEach((alarmStr, idx) => {
const alarmDate = new Date(alarmStr);
const now = new Date();
if (alarmDate > now) {
const timeUntil = alarmDate - now;
alarmTimeouts[idx] = setTimeout(() => triggerAlarm(idx), timeUntil);
}
});