Last active
August 17, 2017 06:43
-
-
Save zhirzh/33f160c5b498ed67c7dff13b29df22d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
* { | |
font-family: monospace; | |
box-sizing: border-box; | |
margin: 0; | |
padding: 0; | |
font-size: 52px; | |
color: silver; | |
user-select: none; | |
text-shadow: 2px 2px rgba(0, 0, 0, 0.4); | |
} | |
body { | |
position: relative; | |
height: 100vh; | |
width: 100vw; | |
background: linear-gradient(gray, black); | |
overflow-y: hidden; | |
} | |
table { | |
position: absolute; | |
top: 45%; | |
left: 50%; | |
transform: translate(-50%,-50%); | |
white-space: nowrap; | |
} | |
td:first-of-type { | |
text-align: right; | |
font-family: sans-serif; | |
padding-right: 40px; | |
} | |
input { | |
border: none; | |
background: transparent; | |
width: 1.2em; | |
} | |
::-webkit-inner-spin-button { | |
display: none; | |
} | |
::selection { | |
background: turquoise; | |
color: white; | |
} | |
select { | |
background: transparent; | |
border: none; | |
} | |
</style> | |
<table> | |
<tr> | |
<td>Alarm Time</td> | |
<td> | |
<input type="number" id="hrInput" min="1" max="12" /> | |
: | |
<input type="number" id="minInput" min="0" max="59" /> | |
: | |
<input type="number" value="00" disabled /> | |
<select id="modeInput"> | |
<option id="modeAM" value="AM">AM</option> | |
<option id="modePM" value="PM">PM</option> | |
</select> | |
</td> | |
</tr> | |
<tr> | |
<td>Current Time</td> | |
<td> | |
<span id="timeEl" /> | |
</td> | |
</tr> | |
</table> | |
<audio src="alarm.mp3" id="alarm"></audio> | |
<script> | |
'use strict'; | |
const UPDATE_HR = 'H'; | |
const UPDATE_MIN = 'M'; | |
const UPDATE_MODE = 'D'; | |
const alarmTime = JSON.parse(localStorage.getItem('alarmTime')) || { | |
hr: 8, | |
min: 0, | |
mode: 'AM', | |
}; | |
function pad(x, n) { | |
return (`0${x}`).slice(-1 * n); | |
} | |
function clamp(x, lo, hi) { | |
return Math.max(lo, Math.min(x, hi)); | |
} | |
function updateAlarmTime(action) { | |
switch (action.type) { | |
case UPDATE_HR: { | |
const hr = clamp(Number(action.payload), 1, 12); | |
hrInput.value = (hrInput.value && hrInput.value.length !== 2) ? pad(hr, 2) : hrInput.value; | |
alarmTime.hr = hr; | |
break; | |
} | |
case UPDATE_MIN: { | |
let min = clamp(Number(action.payload), 0, 59); | |
minInput.value = (minInput.value && minInput.value.length !== 2) ? pad(min, 2) : minInput.value; | |
alarmTime.min = min; | |
break; | |
} | |
case UPDATE_MODE: { | |
const mode = action.payload; | |
modeInput.value = mode; | |
alarmTime.mode = mode; | |
break; | |
} | |
} | |
localStorage.setItem('alarmTime', JSON.stringify(alarmTime)); | |
} | |
function checkTime() { | |
const date = new Date(); | |
const time = { | |
hr: date.getHours() % 12, | |
min: date.getMinutes(), | |
sec: date.getSeconds(), | |
mode: date.getHours() < 12 ? 'AM' : 'PM', | |
} | |
timeEl.innerText = `${pad(time.hr, 2)} : ${pad(time.min, 2)} : ${pad(time.sec, 2)} ${time.mode}`; | |
if ( | |
time.hr === alarmTime.hr && | |
time.min === alarmTime.min && | |
time.mode === alarmTime.mode | |
) { | |
alarm.play(); | |
} | |
setTimeout(checkTime, 1000); | |
} | |
(function main() { | |
hrInput.value = pad(alarmTime.hr, 2); | |
minInput.value = pad(alarmTime.min, 2); | |
window[`mode${alarmTime.mode}`].selected = true; | |
hrInput.oninput = (e) => updateAlarmTime({ type: UPDATE_HR, payload: +e.target.value, e }); | |
minInput.oninput = (e) => updateAlarmTime({ type: UPDATE_MIN, payload: +e.target.value }); | |
modeInput.oninput = (e) => updateAlarmTime({ type: UPDATE_MODE, payload: e.target.value }); | |
hrInput.onclick = (e) => e.target.select(); | |
minInput.onclick = (e) => e.target.select(); | |
checkTime(); | |
})(); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment