diff --git a/apps.json b/apps.json index c03bb89e0..fd2e14e60 100644 --- a/apps.json +++ b/apps.json @@ -1,8 +1,8 @@ [ { "id": "fwupdate", - "name": "Firmware Update (BETA)", - "version": "0.01", + "name": "Firmware Update", + "version": "0.02", "description": "Uploads new Espruino firmwares to Bangle.js 2", "icon": "app.png", "type": "RAM", @@ -16,7 +16,7 @@ { "id": "boot", "name": "Bootloader", - "version": "0.37", + "version": "0.38", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "icon": "bootloader.png", "type": "bootloader", @@ -57,7 +57,7 @@ { "id": "messages", "name": "Messages", - "version": "0.09", + "version": "0.11", "description": "App to display notifications from iOS and Gadgetbridge", "icon": "app.png", "type": "app", @@ -79,7 +79,7 @@ "name": "Android Integration", "shortName": "Android", "version": "0.04", - "description": "(BETA) App to display notifications from Gadgetbridge on Android. This will eventually replace the Gadgetbridge widget.", + "description": "Display notifications/music/etc from Gadgetbridge on Android. This replaces the old Gadgetbridge widget.", "icon": "app.png", "tags": "tool,system,messages,notifications", "dependencies": {"messages":"app"}, @@ -95,8 +95,8 @@ { "id": "ios", "name": "iOS Integration", - "version": "0.04", - "description": "(BETA) App to display notifications from iOS devices", + "version": "0.06", + "description": "Display notifications/music/etc from iOS devices", "icon": "app.png", "tags": "tool,system,ios,apple,messages,notifications", "dependencies": {"messages":"app"}, @@ -146,7 +146,7 @@ { "id": "setting", "name": "Settings", - "version": "0.35", + "version": "0.36", "description": "A menu for setting up Bangle.js", "icon": "settings.png", "tags": "tool,system", @@ -197,7 +197,7 @@ { "id": "locale", "name": "Languages", - "version": "0.11", + "version": "0.13", "description": "Translations for different countries", "icon": "locale.png", "type": "locale", @@ -283,7 +283,7 @@ "id": "gbridge", "name": "Gadgetbridge", "version": "0.24", - "description": "The default notification handler for Gadgetbridge notifications from Android. This will eventually be replaced by the 'Android' app.", + "description": "(NOT RECOMMENDED) Handles Gadgetbridge notifications from Android. This is now replaced by the 'Android' app.", "icon": "app.png", "type": "widget", "tags": "tool,system,android,widget", @@ -727,7 +727,7 @@ { "id": "gpsrec", "name": "GPS Recorder", - "version": "0.26", + "version": "0.27", "description": "Application that allows you to record a GPS track. Can run in background", "icon": "app.png", "tags": "tool,outdoors,gps,widget", @@ -824,7 +824,7 @@ { "id": "weather", "name": "Weather", - "version": "0.11", + "version": "0.12", "description": "Show Gadgetbridge weather report", "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], @@ -1127,7 +1127,7 @@ { "id": "qrcode", "name": "Custom QR Code", - "version": "0.02", + "version": "0.03", "description": "Use this to upload a customised QR code to Bangle.js", "icon": "app.png", "tags": "qrcode", @@ -1755,7 +1755,7 @@ "id": "cliock", "name": "Commandline-Clock", "shortName": "CLI-Clock", - "version": "0.14", + "version": "0.15", "description": "Simple CLI-Styled Clock", "icon": "app.png", "screenshots": [{"url":"screenshot_cli.png"}], @@ -1937,6 +1937,19 @@ {"name":"widmp.wid.js","url":"widget.js"} ] }, + { + "id": "widmpsh", + "name": "Moon Phase Widget Southern Hemisphere", + "version": "0.01", + "description": "Display the current moon phase in blueish for the southern hemisphere in eight phases", + "icon": "widget.png", + "type": "widget", + "tags": "widget,tools", + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"widmpsh.wid.js","url":"widget.js"} + ] + }, { "id": "minionclk", "name": "Minion clock", @@ -2086,12 +2099,12 @@ "id": "numerals", "name": "Numerals Clock", "shortName": "Numerals Clock", - "version": "0.09", + "version": "0.10", "description": "A simple big numerals clock", "icon": "numerals.png", "type": "clock", "tags": "numerals,clock", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, "screenshots": [{"url":"bangle1-numerals-screenshot.png"}], "storage": [ @@ -2393,7 +2406,7 @@ { "id": "calendar", "name": "Calendar", - "version": "0.02", + "version": "0.03", "description": "Simple calendar", "icon": "calendar.png", "screenshots": [{"url":"screenshot_calendar.png"}], @@ -2403,8 +2416,10 @@ "allow_emulator": true, "storage": [ {"name":"calendar.app.js","url":"calendar.js"}, + {"name":"calendar.settings.js","url":"settings.js"}, {"name":"calendar.img","url":"calendar-icon.js","evaluate":true} - ] + ], + "data": [{"name":"calendar.json"}] }, { "id": "hidjoystick", @@ -2642,12 +2657,12 @@ "id": "widviz", "name": "Widget Visibility Widget", "shortName": "Viz Widget", - "version": "0.02", + "version": "0.03", "description": "Swipe left to hide top bar widgets, swipe right to redisplay.", "icon": "eye.png", "type": "widget", "tags": "widget", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"widviz.wid.js","url":"widget.js"} ] @@ -3780,7 +3795,7 @@ "id": "gbmusic", "name": "Gadgetbridge Music Controls", "shortName": "Music Controls", - "version": "0.07", + "version": "0.08", "description": "Control the music on your Gadgetbridge-connected phone", "icon": "icon.png", "screenshots": [{"url":"screenshot_v1.png"},{"url":"screenshot_v2.png"}], @@ -4080,7 +4095,7 @@ {"name":"carcrazy.img","url":"app-icon.js","evaluate":true}, {"name":"carcrazy.settings.js","url":"settings.js"} ], - "data": [{"name":"app.json"}] + "data": [{"name":"CarCrazy.csv"}] }, { "id": "shortcuts", @@ -4387,7 +4402,7 @@ "id": "emojuino", "name": "Emojuino", "shortName": "Emojuino", - "version": "0.02", + "version": "0.03", "description": "Emojis & Espruino: broadcast Unicode emojis via Bluetooth Low Energy.", "icon": "emojuino.png", "screenshots": [ @@ -4409,7 +4424,7 @@ "id": "cliclockJS2Enhanced", "name": "Commandline-Clock JS2 Enhanced", "shortName": "CLI-Clock JS2", - "version": "0.02", + "version": "0.03", "description": "Simple CLI-Styled Clock with enhancements. Modes that are hard to use and unneded are removed (BPM, battery info, memory ect) credit to hughbarney for the original code and design. Also added HID media controlls, just swipe on the clock face to controll the media! Gadgetbride support coming soon(hopefully) Thanks to t0m1o1 for media controls!", "icon": "app.png", "screenshots": [{"url":"screengrab.png"}], @@ -4522,7 +4537,7 @@ {"name":"schoolCalendar.img","url":"app-icon.js","evaluate":true} ], "data": [ - {"name":"app.json"} + {"name":"calendarItems.csv"} ] }, { "id": "timecal", @@ -4575,7 +4590,7 @@ "shortName":"93 Dub", "icon": "93dub.png", "screenshots": [{"url":"screenshot.png"}], - "version":"0.04", + "version":"0.05", "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", @@ -4593,9 +4608,10 @@ "version":"0.01", "description": "Simple app to power off your Bangle.js", "icon": "app.png", - "tags": "poweroff, shutdown", + "tags": "tool, poweroff, shutdown", "supports" : ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", + "allow_emulator": true, "storage": [ {"name":"poweroff.app.js","url":"app.js"}, {"name":"poweroff.img","url":"app-icon.js","evaluate":true} @@ -4605,9 +4621,17 @@ "id": "sensible", "name": "SensiBLE", "shortName": "SensiBLE", - "version": "0.02", + "version": "0.03", "description": "Collect, display and advertise real-time sensor data.", "icon": "sensible.png", + "screenshots": [ + { "url": "screenshot-top.png" }, + { "url": "screenshot-acc.png" }, + { "url": "screenshot-bar.png" }, + { "url": "screenshot-gps.png" }, + { "url": "screenshot-hrm.png" }, + { "url": "screenshot-mag.png" } + ], "type": "app", "tags": "tool,sensors", "supports" : [ "BANGLEJS2" ], @@ -4670,7 +4694,7 @@ "id": "pebble", "name": "Pebble Clock", "shortName": "Pebble", - "version": "0.03", + "version": "0.04", "description": "A pebble style clock to keep the rebellion going", "readme": "README.md", "icon": "pebble.png", @@ -4722,7 +4746,7 @@ { "id": "weatherClock", "name": "Weather Clock", - "version": "0.02", + "version": "0.03", "description": "A clock which displays current weather conditions (requires Gadgetbridge and Weather apps).", "icon": "app.png", "screenshots": [{"url":"screens/screen1.png"}], @@ -4781,5 +4805,57 @@ {"name": "flow.app.js", "url": "app.js" }, {"name": "flow.img", "url": "app-icon.js","evaluate": true } ] - } + }, + { "id": "scribble", + "name": "Scribble", + "shortName":"Scribble", + "version":"0.01", + "type": "app", + "description": "A keyboard on your wrist! Swipe right for space, left for delete.", + "icon": "app.png", + "allow_emulator": true, + "tags": "tools, keyboard, text, scribble", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"scribble.app.js","url":"app.js"}, + {"name":"scribble.img","url":"app-icon.js","evaluate":true} + ], + "screenshots":[ + { "url":"screenshot.png" } + ] + }, + { + "id": "ptlaunch", + "name": "Pattern Launcher", + "shortName": "Pattern Launcher", + "version": "0.02", + "description": "Directly launch apps from the clock screen with custom patterns.", + "icon": "app.png", + "tags": "tools", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + { "name": "ptlaunch.app.js", "url": "app.js" }, + { "name": "ptlaunch.boot.js", "url": "boot.js" }, + { "name": "ptlaunch.img", "url": "app-icon.js", "evaluate": true } + ], + "data": [{"name":"ptlaunch.patterns.json"}] + }, + { "id": "clicompleteclk", + "name": "CLI complete clock", + "shortName":"CLI cmplt clock", + "version":"0.02", + "description": "Command line styled clock with lots of information", + "icon": "app.png", + "allow_emulator": true, + "type": "clock", + "tags": "clock,cli,command,bash,shell,weather,hrt", + "supports" : ["BANGLEJS", "BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"clicompleteclk.app.js","url":"app.js"}, + {"name":"clicompleteclk.img","url":"app-icon.js","evaluate":true} + ] +} ] diff --git a/apps/93dub/ChangeLog b/apps/93dub/ChangeLog index 36859c060..c1b2588bb 100644 --- a/apps/93dub/ChangeLog +++ b/apps/93dub/ChangeLog @@ -2,3 +2,4 @@ 0.02: DiscoMinotaur's adjustments (removed battery and adjusted spacing) 0.03: Code style cleanup 0.04: Set 00:00 to 12:00 for 12 hour time +0.05: Display time, even on Thursday diff --git a/apps/93dub/README.md b/apps/93dub/README.md index 3830ee023..4d1ade582 100644 --- a/apps/93dub/README.md +++ b/apps/93dub/README.md @@ -5,8 +5,8 @@ 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) -Ray Holder (minor 12 hour time rendering adjustment) +* Leer10 +* Orviwan (original watchface and assets) +* Gordon Williams (Bangle.js, watchapps for reference code and documentation) +* DiscoMinotaur (adjustments) +* Ray Holder (minor 12 hour time rendering adjustment, fix Thursdays) diff --git a/apps/93dub/app.js b/apps/93dub/app.js index 8f662a616..1b0f69a94 100644 --- a/apps/93dub/app.js +++ b/apps/93dub/app.js @@ -93,7 +93,7 @@ function draw(){ if (w == 1) {imgW = imgMon;} if (w == 2) {imgW = imgTue;} if (w == 3) {imgW = imgWed;} - if (w == 4) {imgW = imgThr;} + if (w == 4) {imgW = imgThu;} if (w == 5) {imgW = imgFri;} if (w == 6) {imgW = imgSat;} g.drawImage(imgW, 85, 63); diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index ffc2be495..b941a9937 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -41,3 +41,4 @@ Don't set beep vibration up on Bangle.js 2 (built in) 0.36: Add comments to .boot0 to make debugging a bit easier 0.37: Remove Quiet Mode settings: now handled by Quiet Mode Schedule app +0.38: Option to log to file if settings.log==2 diff --git a/apps/boot/bootupdate.js b/apps/boot/bootupdate.js index daf311fe6..3001bb5c1 100644 --- a/apps/boot/bootupdate.js +++ b/apps/boot/bootupdate.js @@ -23,8 +23,14 @@ if (s.ble!==false) { boot += `bleServiceOptions.hid=Bangle.HID;\n`; } } -if (s.blerepl===false) { // If not programmable, force terminal off Bluetooth - if (s.log) boot += `Terminal.setConsole(true);\n`; // if showing debug, force REPL onto terminal +if (s.log==2) { // logging to file + boot += `_DBGLOG=require("Storage").open("log.txt","a"); +`; +} if (s.blerepl===false) { // If not programmable, force terminal off Bluetooth + if (s.log==2) boot += `_DBGLOG=require("Storage").open("log.txt","a"); +LoopbackB.on('data',function(d) {_DBGLOG.write(d);Terminal.write(d);}); +LoopbackA.setConsole(true);\n`; + else if (s.log) boot += `Terminal.setConsole(true);\n`; // if showing debug, force REPL onto terminal else boot += `E.setConsole(null,{force:true});\n`; // on new (2v05+) firmware we have E.setConsole which allows a 'null' console /* If not programmable add our own handler for Bluetooth data to allow Gadgetbridge commands to be received*/ @@ -41,7 +47,10 @@ Bluetooth.on('line',function(l) { try { global.GB(JSON.parse(l.slice(3,-1))); } catch(e) {} });\n`; } else { - if (s.log) boot += `if (!NRF.getSecurityStatus().connected) Terminal.setConsole();\n`; // if showing debug, put REPL on terminal (until connection) + if (s.log==2) boot += `_DBGLOG=require("Storage").open("log.txt","a"); +LoopbackB.on('data',function(d) {_DBGLOG.write(d);Terminal.write(d);}); +if (!NRF.getSecurityStatus().connected) LoopbackA.setConsole();\n`; + else if (s.log) boot += `if (!NRF.getSecurityStatus().connected) Terminal.setConsole();\n`; // if showing debug, put REPL on terminal (until connection) else boot += `Bluetooth.setConsole(true);\n`; // else if no debug, force REPL to Bluetooth } // we just reset, so BLE should be on. diff --git a/apps/calendar/ChangeLog b/apps/calendar/ChangeLog index 8bafff34a..de887bfa7 100644 --- a/apps/calendar/ChangeLog +++ b/apps/calendar/ChangeLog @@ -1,2 +1,3 @@ 0.01: Basic calendar 0.02: Make Bangle 2 compatible +0.03: Add setting to start week on Sunday diff --git a/apps/calendar/README.md b/apps/calendar/README.md index 19a60afc0..e22d06573 100644 --- a/apps/calendar/README.md +++ b/apps/calendar/README.md @@ -6,3 +6,8 @@ Basic calendar - Use `BTN4` (left screen tap) to go to the previous month - Use `BTN5` (right screen tap) to go to the next month + +## Settings + +- Starts on Sunday: whether the calendar should start on Sunday (default is Monday). + diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js index 6f3c33164..5707bd97a 100644 --- a/apps/calendar/calendar.js +++ b/apps/calendar/calendar.js @@ -18,6 +18,10 @@ const gray2 = "#888888"; const gray3 = "#bbbbbb"; const red = "#d41706"; +let settings = require('Storage').readJSON("calendar.json", true) || {}; +if (settings.startOnSun === undefined) + settings.startOnSun = false; + function drawCalendar(date) { g.setBgColor(color4); g.clearRect(0, 0, maxX, maxY); @@ -61,13 +65,18 @@ function drawCalendar(date) { ); g.setFont("6x8", fontSize); - const dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]; + let dowLbls; + if (settings.startOnSun) { + dowLbls = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; + } else { + dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]; + } dowLbls.forEach((lbl, i) => { g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2); }); date.setDate(1); - const dow = date.getDay(); + const dow = date.getDay() + (settings.startOnSun ? 1 : 0); const dowNorm = dow === 0 ? 7 : dow; const monthMaxDayMap = { diff --git a/apps/calendar/settings.js b/apps/calendar/settings.js new file mode 100644 index 000000000..f9c7783a3 --- /dev/null +++ b/apps/calendar/settings.js @@ -0,0 +1,24 @@ +(function(back) { + var FILE = "calendar.json"; + var settings = require('Storage').readJSON(FILE, true) || {}; + if (settings.startOnSun === undefined) + settings.startOnSun = true; + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + + E.showMenu({ + "" : { "title" : "Calendar" }, + "< Back" : () => back(), + 'Start on Sunday': { + value: settings.startOnSun, + format: v => v?"Yes":"No", + onchange: v => { + settings.startOnSun = v; + writeSettings(); + } + }, + }); +}) + diff --git a/apps/cliclockJS2Enhanced/ChangeLog b/apps/cliclockJS2Enhanced/ChangeLog index c7cb9e2c6..f4d146d5f 100644 --- a/apps/cliclockJS2Enhanced/ChangeLog +++ b/apps/cliclockJS2Enhanced/ChangeLog @@ -1,2 +1,3 @@ 0.01: Submitted to App Loader 0.02: Removed unneded code, added HID controlls thanks to t0m1o1 for his code :p +0.03: Load widgets after Bangle.setUI to ensure widgets know if they're on a clock or not (fix #970) diff --git a/apps/cliclockJS2Enhanced/app.js b/apps/cliclockJS2Enhanced/app.js index 70e86f3d6..b6172b497 100644 --- a/apps/cliclockJS2Enhanced/app.js +++ b/apps/cliclockJS2Enhanced/app.js @@ -50,7 +50,7 @@ if (next) { setTimeout(drawApp, 1000); Bangle.setLocked(true); }, BTN1, { edge:"falling",repeat:true,debounce:50}); - Bangle.on('drag', function(e) { + Bangle.on('drag', function(e) { if(!e.b){ console.log(lasty); console.log(lastx); @@ -91,7 +91,7 @@ if (next) { lasty = lasty + e.dy; } }); - + } @@ -144,14 +144,15 @@ function writeLine(str,line){ } g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -drawAll(); + Bangle.on('lcdPower',function(on) { if (on) drawAll(); }); var click = setInterval(updateTime, 1000); // Show launcher when button pressed Bangle.setUI("clockupdown", btn=>{ - drawAll(); + drawAll(); // why do we redraw here?? }); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawAll(); diff --git a/apps/clicompleteclk/ChangeLog b/apps/clicompleteclk/ChangeLog new file mode 100644 index 000000000..ee05bd582 --- /dev/null +++ b/apps/clicompleteclk/ChangeLog @@ -0,0 +1,2 @@ +0.01: New clock! +0.02: Load steps from Health Tracking app (if installed) diff --git a/apps/clicompleteclk/README.md b/apps/clicompleteclk/README.md new file mode 100644 index 000000000..62fdbbc61 --- /dev/null +++ b/apps/clicompleteclk/README.md @@ -0,0 +1,22 @@ +# Command line complete clock + +Command line styled clock with lots of information: + +It can show the following (depending on availability) information: +* Time +* Day of week +* Date +* Weather conditions and temperature (requires app [Weather](https://banglejs.com/apps/#weather)) +* Steps (requires app [Health Tracking](https://banglejs.com/apps/#health%20tracking) or a step widget) +* Heart rate (when screen is on and unlocked) + +## TODO +* Make time font bigger +* Show progress of steps (if any goal is set) +* Show trend of HRM out of history data + +## Creator +Marco ([myxor](https://github.com/myxor)) + +## Icon +Icon taken from [materialdesignicons](https://materialdesignicons.com) under Apache License 2.0 diff --git a/apps/clicompleteclk/app-icon.js b/apps/clicompleteclk/app-icon.js new file mode 100644 index 000000000..b874bb6fa --- /dev/null +++ b/apps/clicompleteclk/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgI/8/4ACAqYv/F/PwAqgA6A==")) diff --git a/apps/clicompleteclk/app.js b/apps/clicompleteclk/app.js new file mode 100644 index 000000000..7fbdabcc1 --- /dev/null +++ b/apps/clicompleteclk/app.js @@ -0,0 +1,195 @@ +const storage = require('Storage'); +const locale = require("locale"); + +const font = "12x20"; +const fontsize = 1; +const fontheight = 19; + +const marginTop = 10; +const marginLeftTopic = 3; // margin of topics +const marginLeftData = 68; // margin of data values + +const topicColor = g.theme.dark ? "#fff" : "#000"; +const textColor = g.theme.dark ? "#0f0" : "#080"; + +let hrtValue; +let hrtValueIsOld = false; +let localTempValue; +let weatherTempString; +let lastHeartRateRowIndex; + +// 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; + drawAll(false); + }, 60000 - (Date.now() % 60000)); +} + +function drawAll(drawInfoToo){ + let now = new Date(); + updateTime(now); + if (drawInfoToo) { + drawInfo(now); + } + queueDraw(); +} + +function updateTime(now){ + if (!Bangle.isLCDOn()) return; + writeLineTopic("TIME", 1); + writeLine(locale.time(now,1),1); + if(now.getMinutes() == 0) + drawInfo(now); +} + +function drawInfo(now) { + if (now == undefined) + now = new Date(); + + let i = 2; + + writeLineTopic("DOWK", i); + writeLine(locale.dow(now),i); + i++; + + writeLineTopic("DATE", i); + writeLine(locale.date(now,1),i); + i++; + + /* + writeLineTopic("BAT", i); + const b = E.getBattery(); + writeLine(b + "%", i); // TODO make bars + i++; + */ + + // weather + const weatherJson = getWeather(); + if(weatherJson && weatherJson.weather){ + const currentWeather = weatherJson.weather; + + const weatherTempValue = locale.temp(currentWeather.temp-273.15); + weatherTempString = weatherTempValue; + writeLineTopic("WTHR", i); + writeLine(currentWeather.txt,i); + i++; + + writeLineTopic("TEMP", i); + writeLine(weatherTempValue,i); + i++; + } + + // steps + const steps = getSteps(); + if (steps != undefined) { + writeLineTopic("STEP", i); + writeLine(steps, i); + i++; + } + + drawHeartRate(i); +} + +function drawHeartRate(i) { + if (i == undefined) + i = lastHeartRateRowIndex; + writeLineTopic("HRTM", i); + if (hrtValue != undefined) { + if (!hrtValueIsOld) + writeLine(hrtValue,i); + else + writeLine(hrtValue,i, topicColor); + } + lastHeartRateRowIndex = i; +} + + +function writeLineTopic(str, line) { + var y = marginTop+line*fontheight; + g.setFont(font,fontsize); + g.setColor(topicColor).setFontAlign(-1,-1); + + g.clearRect(0,y,g.getWidth(),y+fontheight-1); + g.drawString("[" + str + "]",marginLeftTopic,y); +} + +function writeLine(str,line,pColor){ + if (pColor == undefined) + pColor = textColor; + var y = marginTop+line*fontheight; + g.setFont(font,fontsize); + g.setColor(pColor).setFontAlign(-1,-1); + g.drawString(str,marginLeftData,y); +} + + +function getSteps() { + var steps = 0; + let health; + try { + health = require("health"); + } catch (e) { + // Module health not found + } + if (health != undefined) { + health.readDay(new Date(), h=>steps+=h.steps); + } else if (WIDGETS.wpedom !== undefined) { + return WIDGETS.wpedom.getSteps(); + } else if (WIDGETS.activepedom !== undefined) { + return WIDGETS.activepedom.getSteps(); + } + return steps; +} + +function getWeather() { + let jsonWeather = storage.readJSON('weather.json'); + return jsonWeather; +} + +// EVENTS: + +// turn on HRM when the LCD is unlocked +Bangle.on('lock', function(isLocked) { + if (!isLocked) { + Bangle.setHRMPower(1,"clicompleteclk"); + if (hrtValue == undefined) + hrtValue = "..."; + else + hrtValueIsOld = true; + } else { + hrtValueIsOld = true; + Bangle.setHRMPower(0,"clicompleteclk"); + } + drawHeartRate(); +}); + +Bangle.on('lcdPower',function(on) { + if (on) { + drawAll(true); + } else { + hrtValueIsOld = true; + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); + +Bangle.on('HRM', function(hrm) { + //if(hrm.confidence > 90){ + hrtValueIsOld = false; + hrtValue = hrm.bpm; + if (Bangle.isLCDOn()) + drawHeartRate(); + //} else { + // hrtValue = undefined; + //} +}); + +g.clear(); +Bangle.setUI("clock"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawAll(true); diff --git a/apps/clicompleteclk/app.png b/apps/clicompleteclk/app.png new file mode 100644 index 000000000..104e6124a Binary files /dev/null and b/apps/clicompleteclk/app.png differ diff --git a/apps/cliock/ChangeLog b/apps/cliock/ChangeLog index 2a93a0d5f..68249b622 100644 --- a/apps/cliock/ChangeLog +++ b/apps/cliock/ChangeLog @@ -7,3 +7,4 @@ 0.13: Use setUI, work with smaller screens and themes 0.14: Fix BTN1 (fix #853) Add light/dark theme support +0.15: Load widgets after Bangle.setUI to ensure widgets know if they're on a clock or not (fix #970) diff --git a/apps/cliock/app.js b/apps/cliock/app.js index 0fd6ea580..d9271bf15 100644 --- a/apps/cliock/app.js +++ b/apps/cliock/app.js @@ -183,9 +183,6 @@ Bangle.on('HRM', function(hrm) { }); g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -drawAll(); Bangle.on('lcdPower',function(on) { if (on) drawAll(); }); @@ -195,4 +192,7 @@ Bangle.setUI("clockupdown", btn=>{ if (btn<0) changeInfoMode(); if (btn>0) changeFunctionMode(); drawAll(); -}); \ No newline at end of file +}); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawAll(); diff --git a/apps/emojuino/ChangeLog b/apps/emojuino/ChangeLog index 1c99f1970..04367183f 100644 --- a/apps/emojuino/ChangeLog +++ b/apps/emojuino/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! 0.02: Upgraded text to images, added welcome screen and subtitles. +0.03: Advertise app name as Espruino manufacturer data when idle. diff --git a/apps/emojuino/emojuino.js b/apps/emojuino/emojuino.js index 5b7670652..d241063e6 100644 --- a/apps/emojuino/emojuino.js +++ b/apps/emojuino/emojuino.js @@ -32,6 +32,7 @@ const CYCLE_BUZZ_MILLISECONDS = 50; const WELCOME_MESSAGE = 'Emojuino:\r\n\r\n< Swipe >\r\nto select\r\n\r\nTap\r\nto transmit'; // Non-user-configurable constants +const APP_ID = 'emojuino'; const IMAGE_INDEX = 0; const CODE_POINT_INDEX = 1; const EMOJI_PX = 96; @@ -40,12 +41,11 @@ const EMOJI_Y = (g.getHeight() - EMOJI_PX) / 2; const TX_X = 68; const TX_Y = 12; const FONT_SIZE = 24; -const BTN_WATCH_OPTIONS = { repeat: true, debounce: 20, edge: "falling" }; +const ESPRUINO_COMPANY_CODE = 0x0590; const UNICODE_CODE_POINT_ELIDED_UUID = [ 0x49, 0x6f, 0x49, 0x44, 0x55, 0x54, 0x46, 0x2d, 0x33, 0x32 ]; - // Global variables let emojiIndex = 0; let isToggleOn = false; @@ -100,9 +100,22 @@ function transmitEmoji(image, codePoint, duration) { } +// Transmit the app name under the Espruino company code to facilitate discovery +function transmitAppName() { + let options = { + showName: false, + manufacturer: ESPRUINO_COMPANY_CODE, + manufacturerData: JSON.stringify({ name: APP_ID }), + interval: 2000 + } + + NRF.setAdvertising({}, options); +} + + // Terminate the emoji transmission function terminateEmoji(displayIntervalId) { - NRF.setAdvertising({ }); + transmitAppName(); isTransmitting = false; clearInterval(displayIntervalId); drawImage(EMOJIS[emojiIndex][IMAGE_INDEX], false); @@ -169,3 +182,4 @@ g.setFontAlign(0, 0); g.drawString(WELCOME_MESSAGE, g.getWidth() / 2, g.getHeight() / 2); Bangle.on('touch', handleTouch); Bangle.on('drag', handleDrag); +transmitAppName(); diff --git a/apps/fwupdate/ChangeLog b/apps/fwupdate/ChangeLog index ec66c5568..96e7e4e9b 100644 --- a/apps/fwupdate/ChangeLog +++ b/apps/fwupdate/ChangeLog @@ -1 +1,4 @@ 0.01: Initial version +0.02: Add support for ZIPs + Find and download ZIPs direct from the Espruino website + Take 'beta' tag off diff --git a/apps/fwupdate/custom.html b/apps/fwupdate/custom.html index 7230a77a8..b5c79a325 100644 --- a/apps/fwupdate/custom.html +++ b/apps/fwupdate/custom.html @@ -3,29 +3,44 @@
-THIS IS CURRENTLY BETA - PLEASE USE THE NORMAL FIRMWARE UPDATE - INSTRUCTIONS FOR BANGLE.JS 1 AND BANGLE.JS 2
Firmware updates using the App Loader are only possible on +
Firmware updates using the App Loader are only possible on Bangle.js 2. For firmware updates on Bangle.js 1 please - see the Bangle.js 1 instructions
+ see the Bangle.js 1 instructionsYour current firmware version is unknown
+Firmware updates via this tool work differently to the NRF Connect method mentioned on + the Bangle.js page. Firmware + is uploaded to a file on the Bangle. Once complete the Bangle reboots and the bootloader copies + the new firmware into internal Storage.
+ + + diff --git a/apps/gbmusic/ChangeLog b/apps/gbmusic/ChangeLog index 9cebf0a31..316b98a84 100644 --- a/apps/gbmusic/ChangeLog +++ b/apps/gbmusic/ChangeLog @@ -5,3 +5,4 @@ 0.05: Setting to disable double/triple press control, remove touch controls setting, reduce fadeout flicker 0.06: Bangle.js 2 support 0.07: Fix "previous" button image +0.08: Fix scrolling title background color diff --git a/apps/gbmusic/app.js b/apps/gbmusic/app.js index f514dfccd..1bddf70f7 100644 --- a/apps/gbmusic/app.js +++ b/apps/gbmusic/app.js @@ -91,7 +91,7 @@ function rScroller(l) { y = l.y+l.h/2; l.offset = l.offset%w; g.setClipRect(l.x, l.y, l.x+l.w-1, l.y+l.h-1) - .setColor(l.col) + .setColor(l.col).setBgColor(l.bgCol) // need to set colors: iScroll calls this function outside Layout .setFontAlign(-1, 0) // left center .clearRect(l.x, l.y, l.x+l.w-1, l.y+l.h-1) .drawString(l.label, l.x-l.offset+40, y) diff --git a/apps/gpsrec/ChangeLog b/apps/gpsrec/ChangeLog index cb22dd13f..365405846 100644 --- a/apps/gpsrec/ChangeLog +++ b/apps/gpsrec/ChangeLog @@ -28,3 +28,4 @@ 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 +0.27: Map drawing with light theme (fix #1023) diff --git a/apps/gpsrec/app.js b/apps/gpsrec/app.js index df3353930..833a816ea 100644 --- a/apps/gpsrec/app.js +++ b/apps/gpsrec/app.js @@ -197,15 +197,14 @@ function plotTrack(info) { g.setColor(1,0.5,0.5); g.setFont("Vector",16); g.drawString("Track"+info.fn.toString()+" - Loading",10,220); - g.setColor(0,0,0); + g.setColor(g.theme.bg); g.fillRect(0,220,239,239); if (!info.qOSTM) { g.setColor(1, 0, 0); g.fillRect(9,80,11,120); g.fillPoly([9,60,19,80,0,80]); - g.setColor(1,1,1); + g.setColor(g.theme.fg); g.drawString("N",2,40); - g.setColor(1,1,1); } else { osm.lat = info.lat; osm.lon = info.lon; @@ -228,7 +227,7 @@ function plotTrack(info) { g.setColor(0,1,0); g.fillCircle(mp.x,mp.y,5); if (info.qOSTM) g.setColor(1,0,0.55); - else g.setColor(1,1,1); + else g.setColor(g.theme.fg); l = f.readLine(f); while(l!==undefined) { c = l.split(","); @@ -248,11 +247,11 @@ function plotTrack(info) { g.setColor(1,0,0); g.fillCircle(ox,oy,5); if (info.qOSTM) g.setColor(0, 0, 0); - else g.setColor(1,1,1); + else g.setColor(g.theme.fg); g.drawString(require("locale").distance(dist),g.getWidth() / 2, g.getHeight() - 20); g.setFont("6x8",2); g.setFontAlign(0,0,3); - g.drawString("Back",g.getWidth() - 10, g.getHeight() - 40); + g.drawString("Back",g.getWidth() - 10, g.getHeight()/2); setWatch(function() { viewTrack(info.fn, info); }, global.BTN3||BTN1); diff --git a/apps/ios/ChangeLog b/apps/ios/ChangeLog index dd8a3549b..28ad78dec 100644 --- a/apps/ios/ChangeLog +++ b/apps/ios/ChangeLog @@ -2,3 +2,6 @@ 0.02: Remove messages on disconnect 0.03: Handling of message actions (ok/clear) 0.04: Added common bundleId's +0.05: Added more bundleId's (app-id's which can be used to + determine a friendly app name in the notifications) +0.06: Fix (not) popupping up old messages \ No newline at end of file diff --git a/apps/ios/boot.js b/apps/ios/boot.js index 875f00067..d402facbb 100644 --- a/apps/ios/boot.js +++ b/apps/ios/boot.js @@ -26,6 +26,13 @@ E.on('ANCS',msg=>{ function ancsHandler() { var msg = Bangle.ancsMessageQueue[0]; NRF.ancsGetNotificationInfo( msg.uid ).then( info => { + + if(msg.preExisting === true){ + info.new = false; + } else { + info.new = true; + } + E.emit("notify", Object.assign(msg, info)); Bangle.ancsMessageQueue.shift(); if (Bangle.ancsMessageQueue.length) @@ -49,30 +56,47 @@ E.on('notify',msg=>{ "message" : string, "messageSize" : string, "date" : string, + "new" : boolean, "posAction" : string, "negAction" : string, "name" : string, */ var appNames = { - "nl.ah.Appie": "Albert Heijn", + "com.apple.facetime": "FaceTime", "com.apple.mobilecal": "Calendar", "com.apple.mobilemail": "Mail", + "com.apple.MobileSMS": "SMS Message", + "com.apple.Passbook": "iOS Wallet", "com.apple.reminders": "Reminders", "com.apple.shortcuts": "Shortcuts", "com.atebits.Tweetie2": "Twitter", "com.burbn.instagram" : "Instagram", "com.facebook.Facebook": "Facebook", "com.facebook.Messenger": "FB Messenger", + "com.google.Chromecast" : "Google Home", "com.google.Gmail" : "GMail", "com.google.hangouts" : "Hangouts", "com.google.ios.youtube" : "YouTube", + "com.hammerandchisel.discord" : "Discord", + "com.ifttt.ifttt" : "IFTTT", "com.jumbo.app" : "Jumbo", + "com.linkedin.LinkedIn" : "LinkedIn", + "com.nestlabs.jasper.release" : "Nest", "com.netflix.Netflix" : "Netflix", + "com.reddit.Reddit" : "Reddit", "com.skype.skype": "Skype", "com.skype.SkypeForiPad": "Skype", "com.spotify.client": "Spotify", - "net.whatsapp.WhatsApp": "WhatsApp", + "com.tinyspeck.chatlyio": "Slack", + "com.toyopagroup.picaboo": "Snapchat", + "com.ubercab.UberClient": "Uber", + "com.ubercab.UberEats": "UberEats", "com.wordfeud.free": "WordFeud", + "com.zhiliaoapp.musically": "TikTok", + "net.whatsapp.WhatsApp": "WhatsApp", + "nl.ah.Appie": "Albert Heijn", + "nl.postnl.TrackNTrace": "PostNL", + "ph.telegra.Telegraph": "Telegram", // could also use NRF.ancsGetAppInfo(msg.appId) here }; @@ -85,6 +109,7 @@ E.on('notify',msg=>{ t : msg.event, id : msg.uid, src : appNames[msg.appId] || msg.appId, + new : msg.new, title : msg.title&&E.decodeUTF8(msg.title, unicodeRemap, replacer), subject : msg.subtitle&&E.decodeUTF8(msg.subtitle, unicodeRemap, replacer), body : msg.message&&E.decodeUTF8(msg.message, unicodeRemap, replacer) diff --git a/apps/locale/ChangeLog b/apps/locale/ChangeLog index ec74955e9..509d67077 100644 --- a/apps/locale/ChangeLog +++ b/apps/locale/ChangeLog @@ -11,3 +11,5 @@ 0.09: Added New Zealand en_NZ 0.10: Apply 12hour setting to time 0.11: Added translations for nl_NL and changes one formatting +0.12: Fixed nl_NL formatting, because the full months won't fit on the Bangle.js2's screen +0.13: Now use shorter de_DE date format to more closely match other languages for size diff --git a/apps/locale/locales.js b/apps/locale/locales.js index e076b70bd..f4ee1fb43 100644 --- a/apps/locale/locales.js +++ b/apps/locale/locales.js @@ -130,7 +130,7 @@ var locales = { temperature: "°C", ampm: { 0: "", 1: "" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, - datePattern: { 0: "%A, %d. %B %Y", "1": "%d.%m.%Y" }, // Sonntag, 1. März 2020 // 01.01.20 + datePattern: { 0: "%d. %b %Y", "1": "%d.%m.%Y" }, // 1. Mär 2020 // 01.03.20 abmonth: "Jan,Feb,Mär,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez", month: "Januar,Februar,März,April,Mai,Juni,Juli,August,September,Oktober,November,Dezember", abday: "So,Mo,Di,Mi,Do,Fr,Sa", @@ -184,13 +184,30 @@ var locales = { temperature: "°C", ampm: { 0: "", 1: "" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, - datePattern: { 0: "%B %d %Y", 1: "%d.%m.%y" }, // zondag 1 maart 2020 // 01.01.20 + datePattern: { 0: "%d %b %Y", 1: "%d-%m-%Y" }, // 28 feb 2020 // 28-02-2020 abday: "zo,ma,di,wo,do,vr,za", day: "zondag,maandag,dinsdag,woensdag,donderdag,vrijdag,zaterdag", abmonth: "jan,feb,mrt,apr,mei,jun,jul,aug,sep,okt,nov,dec", month: "januari,februari,maart,april,mei,juni,juli,augustus,september,oktober,november,december", trans: { yes: "ja", Yes: "Ja", no: "nee", No: "Nee", ok: "ok", on: "aan", off: "uit", "< Back": "< Terug" } }, + "en_NL": { // English date units with Dutch number, currency and navigation units. + lang: "en_NL", + decimal_point: ",", + thousands_sep: ".", + currency_symbol: "€", + int_curr_symbol: "EUR", + speed: "km/h", + distance: { 0: "m", 1: "km" }, + temperature: "°C", + ampm: { 0: "am", 1: "pm" }, + timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" }, + datePattern: { 0: "%b %d %Y", 1: "%d/%m/%Y" }, // Feb 28 2020" // "01/03/2020"(short) + abmonth: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", + month: "January,February,March,April,May,June,July,August,September,October,November,December", + abday: "Sun,Mon,Tue,Wed,Thu,Fri,Sat", + day: "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday", + }, "en_CA": { lang: "en_CA", decimal_point: ".", diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 196e85107..a3a4f377c 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -12,3 +12,5 @@ buzz on new message (fix #999) 0.09: Message now disappears after 60s if no action taken and clock loads (fix 922) Fix phone icon (#1014) +0.10: Respect the 'new' attribute if it was set from iOS integrations +0.11: Open app when touching the widget (Bangle.js 2 only) \ No newline at end of file diff --git a/apps/messages/lib.js b/apps/messages/lib.js index e93a5e2ba..63f55dd03 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -1,5 +1,5 @@ /* Push a new message onto messages queue, event is: - {t:"add",id:int, src,title,subject,body,sender,tel, important:bool} // add new + {t:"add",id:int, src,title,subject,body,sender,tel, important:bool, new:bool} {t:"add",id:int, id:"music", state, artist, track, etc} // add new {t:"remove-",id:int} // remove {t:"modify",id:int, title:string} // modified @@ -16,7 +16,11 @@ exports.pushMessage = function(event) { if (mIdx>=0) messages.splice(mIdx, 1); // remove item mIdx=-1; } else { // add/modify - if (event.t=="add") event.new=true; // new message + if (event.t=="add"){ + if(event.new === undefined ) { // If 'new' has not been set yet, set it + event.new=true; // Assume it should be new + } + } if (mIdx<0) { mIdx=0; messages.unshift(event); // add new messages to the beginning @@ -27,7 +31,11 @@ exports.pushMessage = function(event) { // if in app, process immediately if (inApp) return onMessagesModified(mIdx<0 ? {id:event.id} : messages[mIdx]); // ok, saved now - we only care if it's new - if (event.t!="add") return; + if (event.t!="add") { + return; + } else if(event.new == false) { + return; + } // otherwise load messages/show widget var loadMessages = Bangle.CLOCK || event.important; // first, buzz diff --git a/apps/messages/widget.js b/apps/messages/widget.js index 245a303fc..6403c6b8d 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -1,4 +1,5 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() { + Bangle.removeListener('touch', this.touch); if (!this.width) return; var c = (Date.now()-this.t)/1000; g.reset().setBgColor((c&1) ? "#0f0" : "#030").setColor((c&1) ? "#000" : "#fff"); @@ -12,6 +13,7 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() { WIDGETS["messages"].buzz(); // buzz every 4 seconds } setTimeout(()=>WIDGETS["messages"].draw(), 1000); + if (process.env.HWVERSION>1) Bangle.on('touch', this.touch); },show:function(quiet) { WIDGETS["messages"].t=Date.now(); // first time WIDGETS["messages"].l=Date.now()-10000; // last buzz @@ -33,6 +35,10 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() { if (c=="-") Bangle.buzz(500).then(()=>setTimeout(b,100)); } b(); +},touch:function(b,c) { + var w=WIDGETS["messages"]; + if (!w||!w.width||c.xTry your QR Code:
+ +Additional options:
+ + + + + + + + + + + +Click
+