diff --git a/apps.json b/apps.json index c016cdb54..1c614c592 100644 --- a/apps.json +++ b/apps.json @@ -170,7 +170,7 @@ { "id": "locale", "name": "Languages", - "version": "0.09", + "version": "0.10", "description": "Translations for different countries", "icon": "locale.png", "type": "locale", @@ -448,6 +448,27 @@ {"name":"matrixclock.img","url":"matrixclock-icon.js","evaluate":true} ] }, + { + "id": "mandlebrotclock", + "name": "Mandlebrot Clock", + "version": "0.01", + "description": "A mandlebrot set themed clock cool", + "icon": "mandlebrotclock.png", + "screenshots": [{ "url": "screenshot_mandlebrotclock.png" }], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + { "name": "mandlebrotclock.app.js", "url": "mandlebrotclock.js" }, + { + "name": "mandlebrotclock.img", + "url": "mandlebrotclock-icon.js", + "evaluate": true + } + ] + }, { "id": "imgclock", "name": "Image background clock", @@ -664,7 +685,7 @@ { "id": "gpsrec", "name": "GPS Recorder", - "version": "0.25", + "version": "0.26", "description": "Application that allows you to record a GPS track. Can run in background", "icon": "app.png", "tags": "tool,outdoors,gps,widget", @@ -683,7 +704,7 @@ "id": "recorder", "name": "Recorder (BETA)", "shortName": "Recorder", - "version": "0.03", + "version": "0.04", "description": "Record GPS position, heart rate and more in the background, then download to your PC.", "icon": "app.png", "tags": "tool,outdoors,gps,widget", @@ -3893,8 +3914,8 @@ { "id": "thermom", "name": "Thermometer", - "version": "0.02", - "description": "Displays the current temperature, updated every 20 seconds", + "version": "0.03", + "description": "Displays the current temperature in degree Celsius, updated every 20 seconds", "icon": "app.png", "tags": "tool", "supports": ["BANGLEJS"], @@ -4085,7 +4106,7 @@ "id": "pastel", "name": "Pastel Clock", "shortName": "Pastel", - "version": "0.06", + "version": "0.07", "description": "A Configurable clock with custom fonts and background", "icon": "pastel.png", "screenshots": [{"url":"screenshot_pastel.png"}], @@ -4378,7 +4399,7 @@ "shortName":"BinWatch", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], - "version":"0.03", + "version":"0.04", "supports": ["BANGLEJS2"], "readme": "README.md", "allow_emulator":true, @@ -4473,5 +4494,37 @@ {"name":"a_clock_timer.app.js","url":"app.js"}, {"name":"a_clock_timer.img","url":"app-icon.js","evaluate":true} ] + }, + { + "id":"intervalTimer", + "name":"Interval Timer", + "shortName":"Interval Timer", + "icon": "app.png", + "version":"0.01", + "description": "Interval Timer for workouts, HIIT, or whatever else.", + "tags": "timer, interval, hiit, workout", + "readme":"README.md", + "supports":["BANGLEJS2"], + "storage": [ + {"name":"intervalTimer.app.js","url":"app.js"}, + {"name":"intervalTimer.img","url":"app-icon.js","evaluate":true} + ] + }, + { "id": "93dub", + "name": "93 Dub", + "shortName":"93 Dub", + "icon": "93dub.png", + "screenshots": [{"url":"screenshot.png"}], + "version":"0.03", + "description": "Fan recreation of orviwan's 91 Dub app for the Pebble smartwatch. Uses assets from his 91-Dub-v2.0 repo", + "tags": "clock", + "type": "clock", + "supports":["BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + {"name":"93dub.app.js","url":"app.js"}, + {"name":"93dub.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/93dub/93dub.png b/apps/93dub/93dub.png new file mode 100644 index 000000000..59950c895 Binary files /dev/null and b/apps/93dub/93dub.png differ diff --git a/apps/93dub/ChangeLog b/apps/93dub/ChangeLog new file mode 100644 index 000000000..5fbfe4fa3 --- /dev/null +++ b/apps/93dub/ChangeLog @@ -0,0 +1,3 @@ +0.01: Initial version for upload +0.02: DiscoMinotaur's adjustments (removed battery and adjusted spacing) +0.03: Code style cleanup diff --git a/apps/93dub/README.md b/apps/93dub/README.md new file mode 100644 index 000000000..fd24d54d8 --- /dev/null +++ b/apps/93dub/README.md @@ -0,0 +1,11 @@ +# 93 Dub + +![](screenshot.png) + +Uses many portions from Espruino documentation, example watchfaces, and the waveclk app. It also sourced from Jon Barlow's 91 Dub v2.0 source code and resources and adapted for Bangle.js 2's screen. Time, date and the battery display works. It is not pixel perfect to the original. + +Contributors: +Leer10 +Orviwan (original watchface and assets) +Gordon Williams (Bangle.js, watchapps for reference code and documentation) +DiscoMinotaur (adjustments) diff --git a/apps/93dub/app-icon.js b/apps/93dub/app-icon.js new file mode 100644 index 000000000..39d11fd6a --- /dev/null +++ b/apps/93dub/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkBG2XwAgcPC6P/h//AAIDBA4Pwh/w+AGBAgIDBC4oVDAAITBCAIIBAYIBBAgIvHh4YCFgQPBAoIvCCwoAWIQYAQGLgAWI6bQVdQiiDOyAX/C/7+IAIYvSh4RBAYIXLAwJAHC6ZFCF5yn/C7wDBBAJ3EVAKBDC5QLBYAoLFC5nwCgoXlL44vSL653sL4QXBL6DvXC9YCBACIXCZ4YAQFaYAgPAhqCa4SDFLoZpICYIXDQKLyCDIQXVAAKI0AAYA==")) diff --git a/apps/93dub/app.js b/apps/93dub/app.js new file mode 100644 index 000000000..92544304c --- /dev/null +++ b/apps/93dub/app.js @@ -0,0 +1,137 @@ +// get 12 hour status, code from barclock +const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; + +// define background +var imgBg = require("heatshrink").decompress(atob("2GwgJC/AH4A/AH4A/AH4A/AH4A/ACcGAhAV/Cp3gvdug+Gj0AgeABYMBAQMIggVEg/w/9/h/Gn8As3ACpk559zznmseAs0B13nq/Rie+uodCIIUZw9hzFmv+AgcCmco7MRilow1ACpN8gFhwMilFRCoMowgVEIIVhIINhwFg4GiCpfw/dhx/mn4uBCoXRhWktAVFTIVhw9mj8YseDkUnqPEoeuugVEAAlgSgICBACAVC8AUQCQQVSAEsD/4ASeYgA/ACkHNiK5Cj4VR/AVBng+RCQVwCqMOAQPhIKOHgEB44VR8YVBx4VR+eAgOfCqPxwEDCqX5CoKvS/PAgc/YqQVU/gV/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/CsMfCqP4CoOfCqP54EBx4VR+OAgPPCqPzwEA44VR4cAgHhCqMHCoNwAQIAPjwCBngVRvgCBV6XwCoMHCqPAHyIA/AEigEf4IAOkAEDoAPJWAtA+PHv+Al6uPCofAGAgALoHz51/8AVT+IVS+4VPpMR73woH27n/8Eh8+ZmadIqsoyGICofAkMUktJFZAVBzgVBv34YgMhi8RkIVJnGQIIN8/H34FB8kJiIVIkVEyGQkF8/Pj4GBkhBKCoOexEQvHx8fBgMXzMxTJkICoXCVx8AggDGABsD/4AB/AVQAH4APA")); + +// define fonts +// reg number first char 48 28 by 41 +var fontNum = atob("AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//w//j4//A/+P4/8A/4/4AAAAD/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/wAAAAH/H/gH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wB/4AP/4H/4A//4f/4D//5//4P//h//4//+B//4AAAAAAAAAAAAAAAAAf/+AAAB//4gAAD//jgAAD/+PgABj/4/gAHj/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f88AAfx/8wAAfH/8AAAcf/8AAAR//4AAAH//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA4AAAAAD4AAYAAP4AD8AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAHgAH/H/GH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAP//AAAAP//AAAAP//AAAAP/8AAAAP/2AAAAP/eAAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAB/7x/4AH/7H/4Af/4f/4B//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wAAAD//wAAAj//gAADj/+AAAPj/5gAA/j/ngAD/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8AA8f8fwAAx/8fAAAH/8cAAAf/8QAAA//8AAAA//8AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//0//j4//Y/+P4/94/4/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/AAPH/H8AAMf/HwAAB//HAAAH//EAAAH//AAAAH//AAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAGAAAAAAOAAAAAAeAAAAAA+AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB8AAAAADx/4B/4HH/4H/4Mf/4f/4R//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wP/+D//w//4j//z//jj//T/+Pj/9j/4/j/3j/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f+8f8fx/+x/8fH/+H/8cf/+f/8R//4f/8H//gf/8AAAAAAAAAAAAAA//8AAAA//8AAAI//8AAA4//0AAD4//YAAP4/94AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/H/vH/H8f/sf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); +// tiny font for percentage first char 48 6 by 8 +var fontTiny = atob("AH6BgYF+ACFB/wEBAGGDhYlxAEKBkZFuAAx0hP8EAPqRkZGOAH6RkZFOAICHmKDAAG6RkZFuAHKJiYl+AAAAAAAAAAAAAAAA"); +// date font first char 48 12 by 15 +var fontDate = atob("AAAAAfv149wAeADwAeADwAeADvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAPHn9/AAAAAAP0A9wweGDwweGDwweGDvAL8AAAAAAAAAAAgwOGDwweGDwweGDvHp98AAAAA/gB6AAwAGAAwAGAAwAGAPHj9/AAAAAfgF6BwweGDwweGDwweGDgHoB+AAAAAfv169wweGDwweGDwweGDgHoB+AAAAAAAAAAgAGAAwAGAAwAGAAvHh9/AAAAAfv169wweGDwweGDwweGDvHr9+AAAAAfgF6BwweGDwweGDwweGDvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + +// define days of the week images +var imgMon = E.toArrayBuffer(atob("Ig8BgHwfD5AvB8HD8z8wMPzPzMQzM/M/DMz8z8c7f7f7z////3Oz+3+PzPzPw/M/M/D8z8z8PzPzPw/vB8/n/8H3/A==")); +var imgTue = E.toArrayBuffer(atob("Ig8BwDv9wDAOfmgf/5+Z///n5n/5+fmf/n5+Z//fv9oH////Af37/b/+fn5n/5+fmf/n5+Z/+fn5n/5/g+gfn+D8AA==")); +var imgWed = E.toArrayBuffer(atob("Ig8Bf7gHgM/NA9Az8z/z8PzP/Pw/M/8/D8z/z8c7QPf7z+A//3O3/3+MzP/PwzM/8/D8z/z8PzP/PxAtA9A4B4B4DA==")); +var imgThu = E.toArrayBuffer(atob("Ig8BgHf7f6Ac/M/P/z8z8//PzPzz8/M/PPz8z8+/QLf7/+A///v3+3+8/PzPzz8/M/PPz8z88/PzPzz8/vB/P3/8HA==")); +var imgFri = E.toArrayBuffer(atob("Ig8B/wDwP7+geg/P5/5+c/n/n5z+f+fnP5/5+c/oHoF7/AfAf/7/7/+/n/k/z+f+R/P5/5j8/n/nHz+/++PP7//8+A==")); +var imgSat = E.toArrayBuffer(atob("Ig8B4DwDwDgOgXAJ/5+f/n/n5/+f+fn55/5+fnoHoF/fAfAf//+b/f3/5n5+f/mfn5/+Z+fn//n5+eAef358B7//nA==")); +var imgSun = E.toArrayBuffer(atob("Ig8BwHf7D7Ac/MHD/z8wMP/PzMQ/8/M/D/z8z8QPf7f6A/////83+3+/zPzPz/M/M/P8z8z8//PzPwA/B8/oD8H3/A==")); + + + +// define icons +var imgSep = E.toArrayBuffer(atob("BhsBAAAAAA///////////////AAAAAAA")); +var imgPercent = E.toArrayBuffer(atob("BwcBuq7ffbqugA==")); +var img24hr = E.toArrayBuffer(atob("EwgBj7vO53na73tcDtu9uDev7vA93g==")); +var imgPM = E.toArrayBuffer(atob("EwgB+HOfdnPu1X3ar4dV9+q+/bfftg==")); + +//vars +var separator = true; +var is24hr = !is12Hour; +var leadingZero = true; + +//the following 2 sections are used from waveclk to schedule minutely updates +// timeout used to update every minute +var drawTimeout; + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function drawBackground() { + g.setBgColor(0,0,0); + g.setColor(1,1,1); + g.clear(); + g.drawImage(imgBg,0,0); + g.reset(); +} + +function draw(){ + drawBackground(); + var date = new Date(); + var h = date.getHours(), m = date.getMinutes(); + var d = date.getDate(), w = date.getDay(); + g.reset(); + g.setBgColor(0,0,0); + g.setColor(1,1,1); + + //draw 24 hr indicator and 12 hr specific behavior + if (is24hr){ + g.drawImage(img24hr,32, 65); + if (leadingZero){ + h = ("0"+h).substr(-2); + } + } else if (h > 12) { + g.drawImage(imgPM,40, 70); + h = h - 12; + if (leadingZero){ + h = ("0"+h).substr(-2); + } else { + h = " " + h; + } + } + + //draw separator + if (separator){ + g.drawImage(imgSep, 85,98);} + + //draw day of week + var imgW = null; + if (w == 0) {imgW = imgSun;} + if (w == 1) {imgW = imgMon;} + if (w == 2) {imgW = imgTue;} + if (w == 3) {imgW = imgWed;} + if (w == 4) {imgW = imgThr;} + if (w == 5) {imgW = imgFri;} + if (w == 6) {imgW = imgSat;} + g.drawImage(imgW, 85, 63); + + + // draw nums + // draw time + g.setColor(0,0,0); + g.setBgColor(1,1,1); + g.setFontCustom(fontNum, 48, 28, 41); + if (h<10) { + if (leadingZero) { + h = ("0"+h).substr(-2); + } else { + h = " " + h; + } + } + g.drawString(h, 25, 90, true); + g.drawString(("0"+m).substr(-2), 92, 90, true); + // draw date + g.setFontCustom(fontDate, 48, 12, 15); + g.drawString(("0"+d).substr(-2), 123,63, true); + + // widget redraw + Bangle.drawWidgets(); + queueDraw(); +} + + +draw(); + +//the following section is also from waveclk +Bangle.on('lcdPower',on=>{ + if (on) { + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); + +Bangle.setUI("clock"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); diff --git a/apps/93dub/screenshot.png b/apps/93dub/screenshot.png new file mode 100644 index 000000000..197c52c01 Binary files /dev/null and b/apps/93dub/screenshot.png differ diff --git a/apps/gpsrec/ChangeLog b/apps/gpsrec/ChangeLog index ca61643a3..cb22dd13f 100644 --- a/apps/gpsrec/ChangeLog +++ b/apps/gpsrec/ChangeLog @@ -27,3 +27,4 @@ 0.23: Fix issue where tracks wouldn't record when running from OpenStMap if a period hadn't been set up first 0.24: Better support for Bangle.js 2, avoid widget area for Graphs, smooth graphs more 0.25: Fix issue where if Bangle.js 2 got a GPS fix but no reported time, errors could be caused by the widget (fix #935) +0.26: Multiple bugfixes diff --git a/apps/gpsrec/app.js b/apps/gpsrec/app.js index 164124257..df3353930 100644 --- a/apps/gpsrec/app.js +++ b/apps/gpsrec/app.js @@ -249,10 +249,10 @@ function plotTrack(info) { g.fillCircle(ox,oy,5); if (info.qOSTM) g.setColor(0, 0, 0); else g.setColor(1,1,1); - g.drawString(require("locale").distance(dist),120,220); + g.drawString(require("locale").distance(dist),g.getWidth() / 2, g.getHeight() - 20); g.setFont("6x8",2); g.setFontAlign(0,0,3); - g.drawString("Back",230,200); + g.drawString("Back",g.getWidth() - 10, g.getHeight() - 40); setWatch(function() { viewTrack(info.fn, info); }, global.BTN3||BTN1); @@ -330,13 +330,13 @@ function plotGraph(info, style) { height: g.getHeight()-(24+8), axes : true, gridy : grid, - gridx : 50, + gridx : infn.length / 3, title: title, xlabel : x=>Math.round(x*dur/(60*infn.length))+" min" // minutes }); g.setFont("6x8",2); g.setFontAlign(0,0,3); - g.drawString("Back",230,200); + g.drawString("Back",g.getWidth() - 10, g.getHeight() - 40); setWatch(function() { viewTrack(info.fn, info); }, global.BTN3||BTN1); diff --git a/apps/intervalTimer/ChangeLog b/apps/intervalTimer/ChangeLog new file mode 100644 index 000000000..d62860265 --- /dev/null +++ b/apps/intervalTimer/ChangeLog @@ -0,0 +1 @@ +0.01: First Release \ No newline at end of file diff --git a/apps/intervalTimer/README.md b/apps/intervalTimer/README.md new file mode 100644 index 000000000..d57c16e9c --- /dev/null +++ b/apps/intervalTimer/README.md @@ -0,0 +1,34 @@ +# Interval Timer + +An interval timer for workouts and whatever else! + +## Usage + +First set the active time (i.e. the number of seconds to perform exercises). + +![Set Active Time](images/set-active.png) + +Next set the rest time (i.e. number of seconds to rest between exercises). + +![Set Rest Time](images/set-rest.png) + +Finally choose the number of sets to perform. + +![Set Number Sets](images/set-sets.png) + +Active time will be shown in red, rest time in green. The watch will buzz whenever active or rest time gets to 0. + +![Timer (active)](images/timer1.png) +![Timer (rest)](images/timer2.png) + +You can press the physical button during timer countdown to pause the timer. + +![Paused](images/pause.png) + +View after all sets are completed. Press menu to change settings or restart to start timer again with the same settings. + +![Completed view](images/done.png) + +## Creator + +James Gough diff --git a/apps/intervalTimer/app-icon.js b/apps/intervalTimer/app-icon.js new file mode 100644 index 000000000..1ca594050 --- /dev/null +++ b/apps/intervalTimer/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwg96hWq1WgDCgXWxGZzOICqQABC4QABCyIXFDBsICIeJyfznAFBwAWPC4Of///mYYMCwgXBl4XB/4xCFxwABn4XCDAQwICw2ICwf/+YwJxGDHoQXHGARGIn/4C5QwBJAwQDC5QLCIw6GEC5BIGIwQLBJAgXGJAwXEJAgXPHgoXIEYIXFLwRIFC484C4h2DJAoIFPA+Ix4MGAAJoDHYgXKf4QXUJAYJGC5p5CF6hIBO44XNABIXGEw4AIU4rXFC5jvFc5AAHxAXGQwwAHQAIXcPCB2FC4RgOB4IXFJBxGHJB5GHJAYwKFwIXIJAIwKFwJGHGAYYICwIuIGAeImYWFmYJBFxIYEwZjC+YtCCxZJDAA4WMDBIWODIwVRAH4AXA==")) \ No newline at end of file diff --git a/apps/intervalTimer/app.js b/apps/intervalTimer/app.js new file mode 100644 index 000000000..fd57dbe2b --- /dev/null +++ b/apps/intervalTimer/app.js @@ -0,0 +1,306 @@ +/** + +Interval Timer + +An app for the Bangle.js watch + +*/ + +var Layout = require("Layout"); + +// Globals +var timerMode; // 'active' || 'rest' +var numSets = 1; +var activeTime = 20; +var restTime = 10; +var counter; +var setsRemaining; +var counterInterval; +var outOfTimeTimeout; +var timerIsPaused; +var timerLayout; + +/** Called to initialize the timer layout */ +function initTimerLayout() { + timerLayout = new Layout( { + type:"v", c: [ + {type:"txt", font:"40%", pad: 10, label:"00:00", id:"time" }, + {type:"txt", font:"6x8:2", label:"0", id:"set" } + ] + }, {btns: [ + {label: "Stop", cb: l => { + if (timerIsPaused){ + timerIsPaused = false; + resumeTimer(); + } + else{ + timerIsPaused = true; + pauseTimer(); + } + } + } + ] + }); +} + +/** Pauses the timer by clearing the counterInterval */ +function pauseTimer() { + if (counterInterval){ + clearTimeout(counterInterval); + counterInterval = undefined; + } + // update layout to display "Paused" + timerLayout.clear(timerLayout.time); + timerLayout.time.label = "||"; + timerLayout.clear(timerLayout.set); + timerLayout.set.label = "Paused"; + timerLayout.render(); +} + +/** Reumes the timer by setting the counterInterval again */ +function resumeTimer() { + if (!counterInterval){ + counterInterval = setInterval(countDown, 1000); + } + // display the timer values again. + timerLayout.clear(timerLayout.time); + timerLayout.time.label = counter; + timerLayout.clear(timerLayout.set); + timerLayout.set.label = `Sets: ${setsRemaining}`; + timerLayout.render(); +} + +/** Display 'Done' view, called when all sets are completed */ +function outOfTime() { + var stopLayout = new Layout( { + type:"v", c: [ + {type:"txt", font:"30%", label:"Done!", id:"time" }, + ] + }, {btns: [ + // menu button allows user to modify times and sets + {label:"Menu", cb: l=> { + if (outOfTimeTimeout){ + clearTimeout(outOfTimeTimeout); + outOfTimeTimeout = undefined; + } + //stopLayout.remove(); + setup(); + } + }, + // restart button runs timer again with the same settings + {label:"Restart", cb: l=> { + if (outOfTimeTimeout){ + clearTimeout(outOfTimeTimeout); + outOfTimeTimeout = undefined; + } + //stopLayout.remove(); + timerMode = 'active'; + startTimer(); + } + } + ]}); + + if (counterInterval) return; + setsRemaining = numSets; + g.clear(); + stopLayout.render(); + Bangle.buzz(500); + Bangle.beep(200, 4000) + .then(() => new Promise(resolve => setTimeout(resolve,200))) + .then(() => Bangle.beep(200, 3000)); +} + +/** Function called by the counterInterval at each second. + Updates the timer display values. +*/ +function countDown() { + // Out of time + if (counter<=0) { + if(timerMode === 'active'){ + timerMode = 'rest'; + startTimer(); + return; + } + else{ + --setsRemaining; + if (setsRemaining === 0){ + clearInterval(counterInterval); + counterInterval = undefined; + //setWatch(startTimer, (process.env.HWVERSION==2) ? BTN1 : BTN2); + outOfTime(); + return; + } + timerMode = 'active'; + startTimer(); + return; + } + } + + timerLayout.clear(timerLayout.time); + timerLayout.time.label = counter; + timerLayout.render(); + counter--; +} + +/** Start the interval timer. */ +function startTimer() { + timerIsPaused = false; + g.clear(); + if(timerMode === 'active'){ + counter = activeTime; + timerLayout.time.col = '#f00'; + } + else{ + counter = restTime; + timerLayout.time.col = '#0f0'; + } + + timerLayout.clear(timerLayout.set); + timerLayout.set.label = `Sets: ${setsRemaining}`; + timerLayout.render(); + Bangle.buzz(); + countDown(); + if (!counterInterval){ + counterInterval = setInterval(countDown, 1000); + } +} + +/** Menu step in which user sets the number of sets to be performed. */ +function setNumSets(){ + g.clear(); + var menuLayout = new Layout( { + type:"v", c: [ + {type:"txt", font:"6x8:2", label:"Number Sets", id:"title" }, + {type:"txt", font:"30%", pad: 20, label: numSets, id:"value" }, + {type:"btn", font:"6x8:2", label:"Back", cb: l => { + setRestTime(); + } + } + ] + }, {btns: [ + {label:"+", cb: l=> { + incrementNumSets(); + }}, + {label:"Go", cb: l=> { + setsRemaining = numSets; + initTimerLayout(); + startTimer(); + }}, + {label:"-", cb: l=>{ + decrementNumSets(); + }} + ]}); + menuLayout.render(); + + const incrementNumSets = () => { + ++numSets; + menuLayout.clear(menuLayout.numSets); + menuLayout.value.label = numSets; + menuLayout.render(); + }; + + const decrementNumSets = () => { + if(numSets === 1){ + return; + } + --numSets; + menuLayout.clear(menuLayout.numSets); + menuLayout.value.label = numSets; + menuLayout.render(); + }; +} + +/** Menu step in which user sets the number of seconds of rest time for each set. */ +function setRestTime(){ + g.clear(); + var menuLayout = new Layout( { + type:"v", c: [ + {type:"txt", font:"6x8:2", label:"Rest Time", id:"title" }, + {type:"txt", font:"30%", pad: 20, label: restTime, id:"value" }, + {type:"btn", font:"6x8:2", label:"Back", cb: l => { + setActiveTime(); + } + } + ] + }, {btns: [ + {label:"+", cb: l=> { + incrementRestTime(); + }}, + {label:"OK", cb: l=>setNumSets()}, + {label:"-", cb: l=>{ + decrementRestTime(); + }} + ]}); + menuLayout.render(); + + const incrementRestTime = () => { + restTime += 5; + menuLayout.clear(menuLayout.restTime); + menuLayout.value.label = restTime; + menuLayout.render(); + }; + + const decrementRestTime = () => { + if(restTime === 0){ + return; + } + restTime -= 5; + menuLayout.clear(menuLayout.restTime); + menuLayout.value.label = restTime; + menuLayout.render(); + }; +} + +/** Menu step in which user sets the number of seconds of active time for each set. */ +function setActiveTime(){ + g.clear(); + var menuLayout = new Layout( { + type:"v", c: [ + {type:"txt", font:"6x8:2", label:"Active Time", id:"title" }, + {type:"txt", font:"30%", pad: 20, label: activeTime, id:"value" } + ] + }, {btns: [ + {font:"20%", label:"+", fillx:1, cb: l=> { + incrementActiveTime(); + }}, + {label:"OK", cb: l => setRestTime()}, + {type:"btn", font:"20%", label:"-", fillx:1, cb: l=> { + decrementActiveTime(); + } + } + ]}); + menuLayout.render(); + + const incrementActiveTime = () => { + activeTime += 5; + menuLayout.clear(menuLayout.activeTime); + menuLayout.value.label = activeTime; + menuLayout.render(); + }; + + const decrementActiveTime = () => { + if(activeTime === 0){ + return; + } + activeTime -= 5; + menuLayout.clear(menuLayout.activeTime); + menuLayout.value.label = activeTime; + menuLayout.render(); + }; +} + +/** Start the setup menu, walks through setting active time, rest time, and number of sets. */ +function setup(){ + if (timerLayout){ + // remove timerLayout, otherwise it's pause button callback will still be registered + timerLayout.remove(timerLayout); + timerLayout = undefined; + } + Bangle.setUI(); // remove all existing input handlers + timerMode = 'active'; + setActiveTime(); +} + +// this keeps the watch LCD lit up +Bangle.setLCDPower(1); +setup(); \ No newline at end of file diff --git a/apps/intervalTimer/app.png b/apps/intervalTimer/app.png new file mode 100644 index 000000000..782c449b3 Binary files /dev/null and b/apps/intervalTimer/app.png differ diff --git a/apps/intervalTimer/images/done.png b/apps/intervalTimer/images/done.png new file mode 100644 index 000000000..d210540d1 Binary files /dev/null and b/apps/intervalTimer/images/done.png differ diff --git a/apps/intervalTimer/images/pause.png b/apps/intervalTimer/images/pause.png new file mode 100644 index 000000000..727380799 Binary files /dev/null and b/apps/intervalTimer/images/pause.png differ diff --git a/apps/intervalTimer/images/set-active.png b/apps/intervalTimer/images/set-active.png new file mode 100644 index 000000000..75b86150b Binary files /dev/null and b/apps/intervalTimer/images/set-active.png differ diff --git a/apps/intervalTimer/images/set-rest.png b/apps/intervalTimer/images/set-rest.png new file mode 100644 index 000000000..e33c9eb02 Binary files /dev/null and b/apps/intervalTimer/images/set-rest.png differ diff --git a/apps/intervalTimer/images/set-sets.png b/apps/intervalTimer/images/set-sets.png new file mode 100644 index 000000000..3d5a9107f Binary files /dev/null and b/apps/intervalTimer/images/set-sets.png differ diff --git a/apps/intervalTimer/images/timer1.png b/apps/intervalTimer/images/timer1.png new file mode 100644 index 000000000..3d1cb6350 Binary files /dev/null and b/apps/intervalTimer/images/timer1.png differ diff --git a/apps/intervalTimer/images/timer2.png b/apps/intervalTimer/images/timer2.png new file mode 100644 index 000000000..026774ba2 Binary files /dev/null and b/apps/intervalTimer/images/timer2.png differ diff --git a/apps/locale/ChangeLog b/apps/locale/ChangeLog index 3d64cf8d7..288dc6dde 100644 --- a/apps/locale/ChangeLog +++ b/apps/locale/ChangeLog @@ -9,3 +9,4 @@ 0.07: Improve handling of non-ASCII characters (fix #469) 0.08: Added Mavigation units and en_NAV 0.09: Added New Zealand en_NZ +0.10: Apply 12hour setting to time diff --git a/apps/locale/locale.html b/apps/locale/locale.html index 3d806b44b..90a2e8d40 100644 --- a/apps/locale/locale.html +++ b/apps/locale/locale.html @@ -146,7 +146,7 @@ exports = { name : "en_GB", currencySym:"£", "%-m": "d.getMonth()+1", "%d": "('0'+d.getDate()).slice(-2)", "%-d": "d.getDate()", - "%HH": "('0'+d.getHours()).slice(-2)", + "%HH": "('0'+getHours(d)).slice(-2)", "%MM": "('0'+d.getMinutes()).slice(-2)", "%SS": "('0'+d.getSeconds()).slice(-2)", "%A": "day.split(',')[d.getDay()]", @@ -178,6 +178,13 @@ var month = ${js(locale.month + ',' + locale.abmonth)}; function round(n) { return n < 10 ? Math.round(n * 10) / 10 : Math.round(n); } +var is12; +function getHours(d) { + var h = d.getHours(); + if (is12===undefined) is12 = (require('Storage').readJSON('setting.json',1)||{})["12hour"]; + if (!is12) return h; + return (h%12==0) ? 12 : h%12; +} exports = { name: ${js(locale.lang)}, currencySym: ${js(locale.currency_symbol)}, diff --git a/apps/mandlebrotclock/ChangeLog b/apps/mandlebrotclock/ChangeLog new file mode 100644 index 000000000..d7bda0d78 --- /dev/null +++ b/apps/mandlebrotclock/ChangeLog @@ -0,0 +1,2 @@ +0.01: Initial Release + \ No newline at end of file diff --git a/apps/mandlebrotclock/README.md b/apps/mandlebrotclock/README.md new file mode 100644 index 000000000..8628a61d0 --- /dev/null +++ b/apps/mandlebrotclock/README.md @@ -0,0 +1,9 @@ +# Mandlebrot Clock + +A simple clock themed on the mandlebrot set. + +Written by [James Milner](https://www.github.com/jameslmilner) + +![](app.png) + + \ No newline at end of file diff --git a/apps/mandlebrotclock/app.png b/apps/mandlebrotclock/app.png new file mode 100644 index 000000000..95ab99a91 Binary files /dev/null and b/apps/mandlebrotclock/app.png differ diff --git a/apps/mandlebrotclock/mandlebrotclock-icon.js b/apps/mandlebrotclock/mandlebrotclock-icon.js new file mode 100644 index 000000000..a2898e734 --- /dev/null +++ b/apps/mandlebrotclock/mandlebrotclock-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+vdvwMzq8CrGCwVewNRluCxAHBAAOsxAAB1gAD1oBB2fWAAPO1mBGZIvCrECq4bBglYmglBGgIxBFQItDFQQsC2es6/XF4OrwOsqwvIt4vBxFdgder0uwUoLQRXE1oqB1nQ1nW2RbCA4PW6HP52rF5d7KoKNBmcDIYIzBrBaB1vPFAOz2RVB1ml54qB1fQFwQvB5+kwSQJWIQoExAFBRYaBB0pVCQYRiB0wDC1erFoPO5ul02sF5QnBAAYFBwbkF0ul1eIAQOqOwLlBIwL7BGIOkAANvxErF49dF4dYGoJfBLoIwD6AfBEgJbBwIEBqwGBqw4BU4Osvd1uteSBDiEFIKLDdQey6ytBEQNWAQOBwMyKYcrAAILBWIRgIEofQ1mJAoS6B2ez665B5+rLQMrq1WWBAACHwJNBCA5WCbgPQ1pYBFYOl6CMB6vP0prB1l6kguLAAWBJgKPHRIOz03Q6+z2QsBVgOrdgOlvaKBLhhiG6AUGJoJOB6GmMgPPcQLHCdAgtRSYgHFrDKBXYWBLQOk0qlBcgNWBYJdSAAcCC4qOBAILzE62l0mCIYVWvQuVAAMsAokzR4WJ1us2fW6K/BMwMrgErAQIAcq+sGAOtF4Os1vXF4I5B1mlFzSQELwU0xGtAIOzF4LCBBgOrLbYwDwUuwVeYIiRB6ukwLBDF7QwCwVYKgJgBGAOt6PW54vB1i7cq2rVoNYFQJfCMAXW62rM4QWDGoPXMwNWAgIMDAw2B67XDlezwUAgYsCwWJLwK9B1YnBwLSEAwIeCBgXXBoQGDHgMr64vEDIOIwNXSAJfBF4RgB1elfQK+GqweCGIIvBCgJUCF4QHBF4rqBRIS/BxKOC1qPB54wBF4pSDE4IjCcAQ6BGYIPCNYYYCl1SKYI0BMwIvBDoIvBPgR1EDgdWKAINDFwIECFoIABbItRulYMYhfCF4Y8BCoYbBAANWEYJfCZALuCIgi/GveeRoIuBXgOt1uy6HV5+kF4olBAAIeBGIIDCAAILCRQYMCNgWs0uqEQOs2fQ6+y63R0vJ1d7q+IUwgAXNoOl5xeBGAOrdYPW6A5BHQWteAovXwWq569BVoWl0ur0g8BVAMrq2lU4gAVq2m1gvC1gwBSAOrLgSiECgIvZq+CKwPWL4IvBXoPQ0uBXQxiBLzCHCW4ItBxGt2fXMAN71iJGYK8r1jqBF4PXL4QvB62r1a+BF4yXBFytWxGB0us6/XdoWzF4TKBwKPGH4IwULgIoB55eB2YGCXoPQ5xeBq+BvUkOolXGAMBXaOCruCwXQ2es1ovC0vP0ulKoOmwWsSgI2BwV70rKBHQIuORgWkwWl2QvBAAXX1YJBwOrAQOAvYxBHoN65HOBQIIBqyeGFgZEBwJ2BKgIqC1ogC2XW0osB1fQ62k5+qMgJoBC4PQfgLYBEYIABNoNWljjCHgNeBgWr63W2QvBxOJBIWr54uCYgL0BLAIsCBIIKB1T+BVwN8WAJcBNQIABIgQGB1fX2RdBXoOJFQWzSIOz1uzAoIwBFgXX2ZHBOIRDCWAOBRgQtC53P1OB0wlBMgQuBdwQAF1oxBEwI7B1p0CBgIIBAAPP0mBcgNWBYOkBYbfB6wtCxCaFGYQKBAoQvBOQIACHoey2ey6D2D0uC0yIBLIILB0pJBEIU6wU0FQbEBF4hnFA4ZlBNoRhCGAJYBHYSKD1eyEYJfBrxfCAwNeAILVBwZZExIABGATNCGARvBCoIMBFwJzDAIderFYwWJsgyBCoI1BAYIABF4QeBL4IvDOIIvDL4PPBYIuCKQQRBEAWsrE0AocQAQJpBGgRNCIQIECCQQzD6Gr0qMBbwYADJ4ZUBl1YBAVelwpBNIQDBFIImCl2CagIVBAATkC5/WFwhLFFoMtwM0E4MtltevggBgcDwITCrEzxEulz5CDgNkMIer6GyLogsCwWmI4MzrFXGAMEA==")) \ No newline at end of file diff --git a/apps/mandlebrotclock/mandlebrotclock.js b/apps/mandlebrotclock/mandlebrotclock.js new file mode 100644 index 000000000..16cc8dfb8 --- /dev/null +++ b/apps/mandlebrotclock/mandlebrotclock.js @@ -0,0 +1,34 @@ +// MIT License - James Milner 2021 + +const mandlebrotBmp = { + width: 176, + height: 176, + bpp: 8, + transparent: 254, + buffer: require("heatshrink").decompress( + atob( + "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" + ) + ), +}; + +function draw() { + g.drawImage(mandlebrotBmp); + // work out how to display the current time + const d = new Date(); + const h = d.getHours(), + m = d.getMinutes(); + const time = h + ":" + ("0" + m).substr(-2); + + // Reset the state of the graphics library + g.reset(); + g.setColor(1, 1, 1); + g.setFont("Vector", 30); + g.drawString(time, 70, 68, false); +} + +g.clear(); + +// draw immediately at first +draw(); +var secondInterval = setInterval(draw, 1000); diff --git a/apps/mandlebrotclock/mandlebrotclock.png b/apps/mandlebrotclock/mandlebrotclock.png new file mode 100644 index 000000000..19601fe2e Binary files /dev/null and b/apps/mandlebrotclock/mandlebrotclock.png differ diff --git a/apps/mandlebrotclock/screenshot_mandlebrotclock.png b/apps/mandlebrotclock/screenshot_mandlebrotclock.png new file mode 100644 index 000000000..542cff324 Binary files /dev/null and b/apps/mandlebrotclock/screenshot_mandlebrotclock.png differ diff --git a/apps/pomodo/ChangeLog b/apps/pomodo/ChangeLog index 3630ae7b6..2fedc39e3 100644 --- a/apps/pomodo/ChangeLog +++ b/apps/pomodo/ChangeLog @@ -1,2 +1,2 @@ -0.02: Ported to Banglejs2. 0.01: New App! +0.02: Ported to Banglejs2. diff --git a/apps/recorder/ChangeLog b/apps/recorder/ChangeLog index 2ea6e9fa8..40240de64 100644 --- a/apps/recorder/ChangeLog +++ b/apps/recorder/ChangeLog @@ -2,3 +2,4 @@ 0.02: Use 'recorder.log..' rather than 'record.log..' Fix interface.html 0.03: Fix theme and maps/graphing if no GPS +0.04: Multiple bugfixes diff --git a/apps/recorder/app.js b/apps/recorder/app.js index d29959e25..fcd8d6031 100644 --- a/apps/recorder/app.js +++ b/apps/recorder/app.js @@ -304,10 +304,10 @@ function plotTrack(info) { g.fillCircle(ox,oy,5); if (info.qOSTM) g.setColor("#000"); else g.setColor(g.theme.fg); - g.drawString(require("locale").distance(dist),120,220); + g.drawString(require("locale").distance(dist),g.getWidth() / 2, g.getHeight() - 20); g.setFont("6x8",2); g.setFontAlign(0,0,3); - g.drawString("Back",230,200); + g.drawString("Back",g.getWidth() - 10, g.getHeight() - 40); setWatch(function() { viewTrack(info.fn, info); }, global.BTN3||BTN1); @@ -360,6 +360,10 @@ function plotGraph(info, style) { var t,dx,dy,d,lt = c[timeIdx]; while(l!==undefined) { ++nl;c=l.split(","); + l = f.readLine(f); + if (c[latIdx] == "") { + continue; + } t = c[timeIdx]; i = Math.round(80*(t - strt)/dur); p = Bangle.project({lat:c[latIdx],lon:c[lonIdx]}); @@ -372,7 +376,6 @@ function plotGraph(info, style) { } lp = p; lt = t; - l = f.readLine(f); } } else throw new Error("Unknown type "+style); var min=100000,max=-100000; @@ -396,13 +399,15 @@ function plotGraph(info, style) { height: g.getHeight()-(24+8), axes : true, gridy : grid, - gridx : 50, + gridx : infn.length / 3, title: title, + miny: min, + maxy: max, xlabel : x=>Math.round(x*dur/(60*infn.length))+" min" // minutes }); g.setFont("6x8",2); g.setFontAlign(0,0,3); - g.drawString("Back",230,200); + g.drawString("Back",g.getWidth() - 10, g.getHeight() - 40); setWatch(function() { viewTrack(info.filename, info); }, global.BTN3||BTN1); diff --git a/apps/thermom/ChangeLog b/apps/thermom/ChangeLog index 78fed5826..6ab6ba8e5 100644 --- a/apps/thermom/ChangeLog +++ b/apps/thermom/ChangeLog @@ -1 +1,2 @@ 0.02: New App! +0.03: Improved messages and added Celsius sign diff --git a/apps/thermom/app.js b/apps/thermom/app.js index baa38e8ec..7eae9b3d4 100644 --- a/apps/thermom/app.js +++ b/apps/thermom/app.js @@ -3,9 +3,9 @@ function onTemperature(p) { g.setFont("6x8",2).setFontAlign(0,0); var x = g.getWidth()/2; var y = g.getHeight()/2 + 10; - g.drawString("Temperature", x, y - 45); + g.drawString("Temperature:", x, y - 45); g.setFontVector(70).setFontAlign(0,0); - g.drawString(p.temperature.toFixed(1), x, y); + g.drawString(p.temperature.toFixed(1) + " °C", x, y); } function drawTemperature() { @@ -23,6 +23,6 @@ setInterval(function() { drawTemperature(); }, 20000); drawTemperature(); -E.showMessage("Loading..."); +E.showMessage("Reading temperature..."); Bangle.loadWidgets(); -Bangle.drawWidgets(); \ No newline at end of file +Bangle.drawWidgets(); diff --git a/modules/Settings.js b/modules/Settings.js index 8d7fba653..0828b4655 100644 --- a/modules/Settings.js +++ b/modules/Settings.js @@ -7,7 +7,7 @@ Usage: // read a single app setting value = require('Settings').get(appid, key, default); // omit key to read all app settings -value = require('Settings').get(); +value = require('Settings').get(appid); // write a single app setting require('Settings').set(appid, key, value) // omit key and pass an object as values to overwrite all settings