mirror of https://github.com/espruino/BangleApps
143 lines
3.1 KiB
JavaScript
143 lines
3.1 KiB
JavaScript
const BLIND_INTERVAL = 600; // 10 minutes in seconds
|
|
const BLINDSUP_ALERT_DURATION = 10000; // 10 seconds in ms
|
|
|
|
// Convert seconds to mm:ss
|
|
const secondsToMinutes = (s) => {
|
|
const mm = Math.floor(s/60);
|
|
const ss = s - mm * 60;
|
|
return `${mm}:${String(ss).padStart(2,'0')}`;
|
|
};
|
|
|
|
// Format screen
|
|
const fmtDark = () => {
|
|
g.clear();
|
|
g.setFontAlign(0,0);
|
|
g.setBgColor(0,0.5,0);
|
|
g.setColor(1,1,1);
|
|
};
|
|
const fmtLight = () => {
|
|
g.clear();
|
|
g.setFontAlign(0,0);
|
|
g.setBgColor(0.5,1,0.5);
|
|
g.setColor(0,0,0);
|
|
};
|
|
|
|
// Start/stop/pause/resume timer
|
|
const startTimer = () => {
|
|
timer_running = true; tick();
|
|
timer = setInterval(tick, 1000);
|
|
};
|
|
const stopTimer = () => {
|
|
clearInterval(timer);
|
|
timer_running = false;
|
|
};
|
|
const pauseResume = () => {
|
|
if (is_alerting) return;
|
|
if (timer_running) {
|
|
stopTimer();
|
|
g.setFont('Vector',15);
|
|
g.drawString('(PAUSED)',
|
|
g.getWidth()/2, g.getHeight()*7/8);
|
|
}
|
|
else startTimer();
|
|
};
|
|
|
|
// Calculate blinds for a round
|
|
const getBlinds = (i) => {
|
|
let small;
|
|
if (i===0) small = 1;
|
|
else if (i===1) small = 2;
|
|
else if (i===2) small = 4;
|
|
else small = 5*(Math.pow(2,(i-3)));
|
|
return [small, small*2];
|
|
};
|
|
|
|
// Sound the alarm
|
|
const blindsUp = () => {
|
|
is_alerting = true;
|
|
// Display message
|
|
const showMessage = () => {
|
|
g.clear();
|
|
g.setFont('Vector',34);
|
|
g.drawString('Blinds Up!',
|
|
g.getWidth()/2, g.getHeight()/3);
|
|
g.setFont('Vector',40);
|
|
g.drawString(`${blinds[0]}/${blinds[1]}`,
|
|
g.getWidth()/2, g.getHeight()*2/3);
|
|
};
|
|
stopTimer();
|
|
// Increase blinds
|
|
b++;
|
|
// TODO: Kill program between round 25 and 26
|
|
blinds = getBlinds(b);
|
|
console.log(`Blinds for round ${b} are ${blinds[0]} / ${blinds[1]}`);
|
|
// Buzz and light up every second
|
|
const buzzInterval = setInterval(() => {
|
|
Bangle.buzz(500);
|
|
Bangle.setLCDPower(1);
|
|
}, 1000);
|
|
// Invert colors every second
|
|
fmtLight(); showMessage(); let dark = false;
|
|
const flashInterval = setInterval(() => {
|
|
if (dark) {
|
|
fmtLight();
|
|
dark = false;
|
|
} else {
|
|
fmtDark();
|
|
dark = true;
|
|
} showMessage();
|
|
}, 500);
|
|
// Restart timer
|
|
setTimeout(() => {
|
|
is_alerting = false;
|
|
fmtDark(); tick();
|
|
clearInterval(buzzInterval);
|
|
clearInterval(flashInterval);
|
|
time_left = BLIND_INTERVAL + 1;
|
|
startTimer();
|
|
}, BLINDSUP_ALERT_DURATION);
|
|
};
|
|
|
|
// Tick every second
|
|
const tick = () => {
|
|
if (!timer_running) return;
|
|
time_left--;
|
|
// 20-second warning buzz
|
|
if (time_left==20) {
|
|
const buzzInterval = setInterval(Bangle.buzz, 500);
|
|
setTimeout(() => {
|
|
clearInterval(buzzInterval);
|
|
}, 5000);
|
|
}
|
|
if (time_left<=0) blindsUp();
|
|
else {
|
|
g.clear();
|
|
g.setFont('Vector',40);
|
|
g.drawString(
|
|
secondsToMinutes(time_left),
|
|
g.getWidth()/2, g.getHeight()/3);
|
|
g.drawString(
|
|
`${blinds[0]}/${blinds[1]}`,
|
|
g.getWidth()/2, g.getHeight()*2/3);
|
|
}
|
|
return;
|
|
};
|
|
|
|
// button listener
|
|
Bangle.setUI({
|
|
mode: 'custom',
|
|
btn: pauseResume,
|
|
});
|
|
|
|
// RUNTIME
|
|
fmtDark();
|
|
let time_left = BLIND_INTERVAL + 1;
|
|
let b = 0;
|
|
let blinds = getBlinds(b);
|
|
let timer_running = true;
|
|
let is_alerting = false;
|
|
let timer = setInterval(tick, 1000);
|
|
tick();
|
|
// Start paused
|
|
pauseResume();
|