diff --git a/apps.json b/apps.json index 7f1783dae..b47a088fd 100644 --- a/apps.json +++ b/apps.json @@ -5098,6 +5098,27 @@ {"name":"ltherm.img","url":"icon.js","evaluate":true} ] }, + { + "id": "teatimer", + "name": "Tea Timer", + "version": "1.00", + "description": "A simple timer. You can easyly set up the time.", + "icon": "teatimer.png", + "type": "app", + "tags": "tool", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"teatimer.app.js","url":"app.js"}, + {"name":"teatimer.img","url":"app-icon.js","evaluate":true} + ], + "screenshots": [ + {"url":"TeatimerStart.jpg"}, + {"url":"TeatimerHelp.jpg"}, + {"url":"TeatimerRun.jpg"}, + {"url":"TeatimerUp.jpg"} + ] + }, { "id": "swp2clk", "name": "Swipe back to the Clock", diff --git a/apps/teatimer/README.md b/apps/teatimer/README.md new file mode 100644 index 000000000..71bec3ea8 --- /dev/null +++ b/apps/teatimer/README.md @@ -0,0 +1,45 @@ +# Tea Timer app + +A simple timer. You can easyly set up the time. The initial time is 2:30 + +On the first screen, you can +- tap to get help +- swipe up/down to change the timer by +/- one minute +- swipe left/right to change the time by +/- 15 seconds +- press Btn1 to start + +Press Btn1 again to stop the timer +- when time is up, your Bangle will buzz for 15 seconds +- and it will count up to 60 seconds and stop after that + +## Images +_1. Startscreen_ + +![](TeatimerStart.jpg) +Current time is displayed below the Title. Initial time is 2:30. + +_2. Help Screen_ + +![](TeatimerHelp.jpg) + +_3. Tea Timer running_ + +![](TeatimerRun.jpg) +Remainig time is shown in big font size. Above the initial time is shown. + +_4. When time is up_ + +![](TeatimerUp.jpg) +When time is up, the watch will buzz for 15 seconds. It will count up to 60 seconds. + +## Requests + +Please mail any issues to thomas.fehling@mailbox.org + +## Creator + +Thomas Fehling + +## Attributions + +Icons used in this app are from https://icons8.com diff --git a/apps/teatimer/TeatimerHelp.jpg b/apps/teatimer/TeatimerHelp.jpg new file mode 100644 index 000000000..e22960c66 Binary files /dev/null and b/apps/teatimer/TeatimerHelp.jpg differ diff --git a/apps/teatimer/TeatimerRun.jpg b/apps/teatimer/TeatimerRun.jpg new file mode 100644 index 000000000..a442d12a5 Binary files /dev/null and b/apps/teatimer/TeatimerRun.jpg differ diff --git a/apps/teatimer/TeatimerStart.jpg b/apps/teatimer/TeatimerStart.jpg new file mode 100644 index 000000000..4fa8f2fc4 Binary files /dev/null and b/apps/teatimer/TeatimerStart.jpg differ diff --git a/apps/teatimer/TeatimerUp.jpg b/apps/teatimer/TeatimerUp.jpg new file mode 100644 index 000000000..80b8c3c8a Binary files /dev/null and b/apps/teatimer/TeatimerUp.jpg differ diff --git a/apps/teatimer/app-icon.js b/apps/teatimer/app-icon.js new file mode 100644 index 000000000..ae91f88d7 --- /dev/null +++ b/apps/teatimer/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AAONjQAoxoutGAYusGAQutABs4qwAUnAwYik4vQAQnEUMTcxqoAOm6Sdm9PAB0TF7sTF90awIAOFz0bxIAOjYv/F/2s1eq5wAI1Wr1gvg4/GABXH1Yvg5wvL5xffjWIMBfH1lkFzwwC1YvJ1eIF0CRC5CNJF0KRK5CNiGBS8BRsQwJ468jAA2JGAJdpF4et1ms1uJF9YADF1GIxIAD1qQoFwgwpLwoADF1jABxJgjLpGt2YwBjYugjaMIF4IwBsgvgsgvMxIwfLxIwC66RhF/ezF9q/B6/XF9xfrLwYvhjWBABGsAAOmwWBFz0Tp4AOiYvdm4vumNVAB0xFrcUnF6ACE4iguYnFWACk4ebwAcxouu/wwsFwIABGFQuCA==")) diff --git a/apps/teatimer/app.js b/apps/teatimer/app.js new file mode 100644 index 000000000..dd7afdadb --- /dev/null +++ b/apps/teatimer/app.js @@ -0,0 +1,233 @@ +// Tea Timer +// Button press stops timer, next press restarts timer +let drag; +var counter = 0; +var counterStart = 150; // 150 seconds +var counterInterval; +const states = { + init: 1, // unused + help: 2, // show help text + start: 4, // show/change initial counter + count: 8, // count down + countUp: 16, // count up after timer finished + stop: 32 // timer stopped +}; +var state = states.start; +E.setTimeZone(1); + +// Title showing current time +function appTitle() { + return "Tea Timer " + currentTime(); +} + +function currentTime() { + min = Date().getMinutes(); + if (min < 10) min = "0" + min; + return Date().getHours() + ":" + min; +} + +function timeFormated(sec) { + var min = Math.floor(sec / 60); + sec = sec % 60; + if (sec < 10) sec = "0" + sec; + return min + ":" + sec; +} + +// initialize timer and show timer value => state: start +function initTimer() { + counter = counterStart; + setState(states.start); + showCounter(true); +} + +// timer value (counter) can be changed in state start +function changeCounter(diff) { + if (state == states.start) { + if (counter + diff > 0) { + counter = counter + diff; + showCounter(true); + } + } +} + +// start or restart timer => state: count +function startTimer() { + counterStart = counter; + setState(states.count); + countDown(); + if (!counterInterval) + counterInterval = setInterval(countDown, 1000); +} + +/* show current counter value at start and while count down + Show + - Title with current time + - initial timer value + - remaining time + - hint for help in state start +*/ +function showCounter(withHint) { + //g.clear(); + E.showMessage("", appTitle()); + g.setFontAlign(0,0); // center font + // draw the current counter value + g.setBgColor(-1).setColor(0,0,1); // blue + g.setFont("Vector",20); // vector font, 20px + g.drawString("Timer: " + timeFormated(counterStart),80,55); + g.setFont("Vector",60); // vector font, 60px + g.drawString(timeFormated(counter),83,100); + if (withHint) { + g.setFont("Vector",20); // vector font, 80px + g.drawString("Tap for help",80,150); + } +} + +// count down and update every second +// when time is up, start counting up +function countDown() { + counter--; + // Out of time + if (counter<=0) { + outOfTime(); + countUp(); + counterInterval = setInterval(countUp, 1000); + return; + } + showCounter(false); +} + +// +function outOfTime() { + E.showMessage("Time is up!",appTitle()); + setState(states.countUp); + resetTimer(); + Bangle.buzz(); + Bangle.buzz(); +} + +/* this counts up (one minute), after time is up + Show + - Title with current time + - initial timer value + - "Time is up!" + - time since timer finished +*/ +function countUp() { + // buzz for 15 seconds + counter++; + if (counter <=15) { + Bangle.buzz(); + } + // stop counting up after 60 seconds + if (counter > 60) { + outOfTime(); + return; + } + g.clear(); + E.showMessage("", appTitle()); + g.setFontAlign(0,0); // center font + g.setBgColor(-1).setColor(0,0,1); // blue + g.setFont("Vector",20); // vector font, 20px + g.drawString("Timer: " + timeFormated(counterStart),80,55); + g.setFont("Vector",30); // vector font, 80px + g.setBgColor(-1).setColor(1,0,0); // red + g.drawString("Time is up!",85,85); + g.setFont("Vector",40); // vector font, 80px + // draw the current counter value + g.drawString(timeFormated(counter),80,130); +} + +// reset when interupted by user oder 60 seconds after timer finished +function resetTimer() { + clearInterval(); + counterInterval = undefined; +} + +// timer is stopped by user => state: stop +function stopTimer() { + resetTimer(); + E.showMessage("Timer stopped!", appTitle()); + setState(states.stop); +} + +// timer is stopped by user while counting up => state: start +function stopTimer2() { + resetTimer(); + initTimer(); +} + + +function setState(st) { + state = st; +} + +function buttonPressed() { + switch(state) { + case states.init: + initTimer(); + break; + case states.help: + initTimer(); + break; + case states.start: + startTimer(); + break; + case states.count: + stopTimer(); + break; + case states.countUp: + stopTimer2(); + break; + case states.stop: + initTimer(); + break; + default: + initTimer(); + break; + } +} + +/* Change initial counter value by swiping + swipe up: +1 minute + swipe down: -1 minute + swipe right: +15 seconds + swipe left: -15 seconds */ +function initDragEvents() { + Bangle.on("drag", e => { + if (state == states.start) { + if (!drag) { // start dragging + drag = {x: e.x, y: e.y}; + } else if (!e.b) { // released + const dx = e.x-drag.x, dy = e.y-drag.y; + drag = null; + if (Math.abs(dx)>Math.abs(dy)+10) { + // horizontal + changeCounter(dx>0 ? 15 : -15); + } else if (Math.abs(dy)>Math.abs(dx)+10) { + // vertical + changeCounter(dy>0 ? -60 : 60); + } + } + } +}); +} + +// show help text while in start state (see initDragEvents()) +function showHelp() { + if (state == states.start) { + state = states.help; + E.showMessage("Swipe up/down\n+/- one minute\n\nSwipe left/right\n+/- 15 seconds\n\nPress Btn1 to start","Tea timer help"); + } + // return to start + else if (state == states.help) { + initTimer(); + } +} + +// drag events in start state (to change counter value) +initDragEvents(); +// Show help test in start state +Bangle.on('touch', function(button, xy) { showHelp(); }); +// event handling for button1 +setWatch(buttonPressed, BTN1, {repeat: true}); +initTimer(); diff --git a/apps/teatimer/teatimer.png b/apps/teatimer/teatimer.png new file mode 100644 index 000000000..29ca58f0e Binary files /dev/null and b/apps/teatimer/teatimer.png differ