diff --git a/apps.json b/apps.json index ebc0d7fa7..4553eaab5 100644 --- a/apps.json +++ b/apps.json @@ -1090,5 +1090,17 @@ {"name":"minionclk.app.js","url":"app.js"}, {"name":"minionclk.img","url":"app-icon.js","evaluate":true} ] + }, + { "id": "tabata", + "name": "Tabata", + "shortName": "Tabata - Control High-Intensity Interval Training", + "icon": "tabata.png", + "version":"0.01", + "description": "Control high-intensity interval training (according to tabata: https://en.wikipedia.org/wiki/Tabata_method).", + "tags": "workout,health", + "storage": [ + {"name":"tabata.app.js","url":"tabata.js"}, + {"name":"tabata.img","url":"tabata-icon.js","evaluate":true} + ] } ] diff --git a/apps/tabata/tabata-icon.js b/apps/tabata/tabata-icon.js new file mode 100644 index 000000000..93783b607 --- /dev/null +++ b/apps/tabata/tabata-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwg96iOZzORgMZAYMQCxsBCwIAGDBsZyIDCCYQyBBAQuLEwWZCYYJBFx8BL4ITDjJILBgcJDYIGEyBCHFYQoGC4Y2BRBAJBC4wrDC4w9BiC6BC6Q6DAYIXpCIcJC/4X/C/4X/C50BjITCjOZD4IXOhOZCYMBAYIwEC52QC7QMDC/4XCzBH/C/4X/C5OQa6INBC4WRyIvQC5IOBC5YTBAYILByAECBAIXLA4IwBAYITBgMZDYIXGHgZICEAWRAYQfEAgIXIFAIIBiERCwYKCCQQOBBIQAvA")); \ No newline at end of file diff --git a/apps/tabata/tabata.js b/apps/tabata/tabata.js new file mode 100644 index 000000000..603cf96ee --- /dev/null +++ b/apps/tabata/tabata.js @@ -0,0 +1,130 @@ +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +var settings = require("Storage").readJSON("tabata.json",1)||{}; +settings.pause = settings.pause || 10; +settings.training = settings.training || 20; +settings.rounds = settings.rounds || 8; + +const MAX_SECONDS = 100; + +function debounce(callback, ms) { + var timer; + return () => { + if (timer) clearTimeout(timer); + timer = setTimeout(callback, ms); + }; +} + +function saveSettings() { + require("Storage").write("tabata.json",JSON.stringify(settings)); +} + +var saveSettingsDebounce = debounce(saveSettings, 250); + +function showMainMenu() { + const menu = { + '': { 'title': 'Tabata Training' }, + '>> Start >>': ()=> { + startTabata(); + }, + 'Pause sec.': { + value: settings.pause, + onchange: function(v){ + if (v<0)v=MAX_SECONDS; + if (v>MAX_SECONDS)v=0; + settings.pause=v; + this.value=v; + saveSettingsDebounce(); + } + }, + 'Trainig sec.': { + value: settings.training, + onchange: function(v){if (v<0)v=MAX_SECONDS;if (v>MAX_SECONDS)v=0;settings.training=v; + this.value=v; + saveSettingsDebounce(); + } + }, + 'Rounds': { + value: settings.rounds, + onchange: function(v){if (v<0)v=MAX_SECONDS;if (v>MAX_SECONDS)v=0;settings.rounds=v;this.value=v; + saveSettingsDebounce(); + } + }, + '< Back': () => load() + }; + menu['< Back'] = ()=>{load();}; + return E.showMenu(menu); +} + +function startTabata() { + g.clear(); + Bangle.setLCDMode("doublebuffered"); + g.flip(); + var pause = settings.pause, + training = settings.training, + round = 1, + active = true, + clearBtn1, clearBtn2, clearBtn3, timer; + Bangle.buzz(1000, 1); + + function exitTraining() { + clearTimeout(timer); + clearWatch(clearBtn1); + clearWatch(clearBtn2); + clearWatch(clearBtn2); + showMainMenu(); + } + + clearBtn1 = setWatch(exitTraining, BTN1); + clearBtn2 = setWatch(exitTraining, BTN2); + clearBtn3 = setWatch(exitTraining, BTN3); + + + timer = setInterval(function() { + if (round > settings.rounds) { + exitTraining(); + return; + } + + if (active) { + drawCountDown(round, training, active); + training--; + } else { + drawCountDown(round, pause, active); + pause--; + if (pause !== 0) { + Bangle.buzz(50, 0.2); + } + } + + if (training === 0) { + training = settings.training; + active = false; + Bangle.buzz(500, 1); + } + if (pause === 0) { + round++; + pause = settings.pause; + active = true; + Bangle.buzz(1000, 1); + } + }, 1000); +} + +function drawCountDown(round, count, active) { + g.clear(); + + g.setFontAlign(0,0); + g.setFont("6x8", 2); + g.drawString("Round " + round + "/" + settings.rounds,120,6); + + g.setFont("6x8", 6); + g.drawString("" + count,120,80); + + g.setFont("6x8",2); + g.drawString(active ? "Training" : "Pause", 120,45); + g.flip(); +} + +showMainMenu(); diff --git a/apps/tabata/tabata.png b/apps/tabata/tabata.png new file mode 100644 index 000000000..f0aaadede Binary files /dev/null and b/apps/tabata/tabata.png differ