diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog index fcafc386f..3f56f4c20 100644 --- a/apps/alarm/ChangeLog +++ b/apps/alarm/ChangeLog @@ -18,3 +18,4 @@ 0.17: Moving alarm internals to 'sched' library 0.18: Cope with >1 identical alarm at once (#1667) 0.19: Ensure rescheduled alarms that already fired have 'last' reset +0.20: Use the new 'sched' factories to initialize new alarms/timers diff --git a/apps/alarm/app.js b/apps/alarm/app.js index b9404358e..1fc32ecb9 100644 --- a/apps/alarm/app.js +++ b/apps/alarm/app.js @@ -1,28 +1,28 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); -var alarms = require("sched").getAlarms(); // An array of alarm objects (see sched/README.md) +let alarms = require("sched").getAlarms(); // time in ms -> { hrs, mins } function decodeTime(t) { - t = 0|t; // sanitise - var hrs = 0|(t/3600000); - return { hrs : hrs, mins : Math.round((t-hrs*3600000)/60000) }; + t = 0 | t; // sanitise + let hrs = 0 | (t / 3600000); + return { hrs: hrs, mins: Math.round((t - hrs * 3600000) / 60000) }; } // time in { hrs, mins } -> ms function encodeTime(o) { - return o.hrs*3600000 + o.mins*60000; + return o.hrs * 3600000 + o.mins * 60000; } function formatTime(t) { - var o = decodeTime(t); - return o.hrs+":"+("0"+o.mins).substr(-2); + let o = decodeTime(t); + return o.hrs + ":" + ("0" + o.mins).substr(-2); } function getCurrentTime() { - var time = new Date(); + let time = new Date(); return ( time.getHours() * 3600000 + time.getMinutes() * 60000 + @@ -39,7 +39,7 @@ function showMainMenu() { // Timer img "\0"+atob("DhKBAP////MDDAwwMGGBzgPwB4AeAPwHOBhgwMMzDez////w") // Alarm img "\0"+atob("FBSBAABgA4YcMPDGP8Zn/mx/48//PP/zD/8A//AP/wD/8A//AP/wH/+D//w//8AAAADwAAYA") const menu = { - '': { 'title': 'Alarm/Timer' }, + '': { 'title': /*LANG*/'Alarms&Timers' }, /*LANG*/'< Back' : ()=>{load();}, /*LANG*/'New Alarm': ()=>editAlarm(-1), /*LANG*/'New Timer': ()=>editTimer(-1) @@ -76,13 +76,13 @@ function showMainMenu() { function editDOW(dow, onchange) { const menu = { '': { 'title': /*LANG*/'Days of Week' }, - '< Back' : () => onchange(dow) + /*LANG*/'< Back' : () => onchange(dow) }; - for (var i = 0; i < 7; i++) (i => { - var dayOfWeek = require("locale").dow({ getDay: () => i }); + for (let i = 0; i < 7; i++) (i => { + let dayOfWeek = require("locale").dow({ getDay: () => i }); menu[dayOfWeek] = { value: !!(dow&(1< v ? "Yes" : "No", + format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", onchange: v => v ? dow |= 1< showMainMenu(), + /*LANG*/'< Back' : () => showMainMenu(), /*LANG*/'Hours': { value: t.hrs, min : 0, max : 23, wrap : true, onchange: v => t.hrs=v @@ -117,23 +109,23 @@ function editAlarm(alarmIndex, alarm) { }, /*LANG*/'Enabled': { value: a.on, - format: v=>v?"On":"Off", + format: v => v ? /*LANG*/"On" : /*LANG*/"Off", onchange: v=>a.on=v }, /*LANG*/'Repeat': { value: a.rp, - format: v=>v?"Yes":"No", - onchange: v=>a.rp=v + format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", + onchange: v => a.rp = v }, /*LANG*/'Days': { value: "SMTWTFS".split("").map((d,n)=>a.dow&(1< editDOW(a.dow, d=>{a.dow=d;editAlarm(alarmIndex,a)}) }, /*LANG*/'Vibrate': require("buzz_menu").pattern(a.vibrate, v => a.vibrate=v ), - /*LANG*/'Auto snooze': { + /*LANG*/'Auto Snooze': { value: a.as, - format: v=>v?"Yes":"No", - onchange: v=>a.as=v + format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", + onchange: v => a.as = v } }; menu[/*LANG*/"Save"] = function() { @@ -155,23 +147,15 @@ function editAlarm(alarmIndex, alarm) { } function editTimer(alarmIndex, alarm) { - var newAlarm = alarmIndex<0; - var a = { - timer : 5*60*1000, // 5 minutes - on : true, - rp : false, - as : false, - dow : 0b1111111, - last : 0, - vibrate : ".." - } + let newAlarm = alarmIndex < 0; + let a = require("sched").newDefaultTimer(); if (!newAlarm) Object.assign(a, alarms[alarmIndex]); if (alarm) Object.assign(a,alarm); - var t = decodeTime(a.timer); + let t = decodeTime(a.timer); const menu = { '': { 'title': /*LANG*/'Timer' }, - '< Back' : () => showMainMenu(), + /*LANG*/'< Back' : () => showMainMenu(), /*LANG*/'Hours': { value: t.hrs, min : 0, max : 23, wrap : true, onchange: v => t.hrs=v @@ -182,8 +166,8 @@ function editTimer(alarmIndex, alarm) { }, /*LANG*/'Enabled': { value: a.on, - format: v=>v?"On":"Off", - onchange: v=>a.on=v + format: v => v ? /*LANG*/"On" : /*LANG*/"Off", + onchange: v => a.on = v }, /*LANG*/'Vibrate': require("buzz_menu").pattern(a.vibrate, v => a.vibrate=v ), }; diff --git a/apps/alarm/metadata.json b/apps/alarm/metadata.json index 9636257ca..db36b3ca9 100644 --- a/apps/alarm/metadata.json +++ b/apps/alarm/metadata.json @@ -1,8 +1,8 @@ { "id": "alarm", - "name": "Alarm & Timer", + "name": "Alarms & Timers", "shortName": "Alarms", - "version": "0.19", + "version": "0.20", "description": "Set alarms and timers on your Bangle", "icon": "app.png", "tags": "tool,alarm,widget", diff --git a/apps/choozi/ChangeLog b/apps/choozi/ChangeLog index 7aabe5c89..03f7ef832 100644 --- a/apps/choozi/ChangeLog +++ b/apps/choozi/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! 0.02: Support Bangle.js 2 +0.03: Fix bug for Bangle.js 2 where g.flip was not being called. diff --git a/apps/choozi/appb2.js b/apps/choozi/appb2.js index d5c542be3..5f217f638 100644 --- a/apps/choozi/appb2.js +++ b/apps/choozi/appb2.js @@ -1,6 +1,3 @@ -//g.setTheme({fg : 0xFFFF, fg2 : 0xFFFF,bg2 : 0x0007,fgH : 0xFFFF,bgH : 0x02F7,dark : true}); - - /* Choozi - Choose people or things at random using Bangle.js. * Inspired by the "Chwazi" Android app * @@ -77,7 +74,7 @@ function arc(minR, maxR, minAngle, maxAngle) { inside.push(centreY+s*minR); outside.unshift(centreY+s*maxR); outside.unshift(centreX+c*maxR); - + var vertices = inside.concat(outside); g.fillPoly(vertices, true); } @@ -133,6 +130,7 @@ function animateChoice(target) { g.fillCircle(x, y, ballSize); oldx=x; oldy=y; + g.flip(); } } @@ -154,7 +152,7 @@ function choose() { // draw the current value of N in the middle of the screen, with // up/down arrows function drawN() { - g.setColor('#000000'); + g.setColor(g.theme.fg); g.setFont("Vector",fontSize); g.drawString(N,centreX-g.stringWidth(N)/2+4,centreY-fontSize/2); if (N < maxN) diff --git a/apps/choozi/metadata.json b/apps/choozi/metadata.json index a10448ed5..79af76fa2 100644 --- a/apps/choozi/metadata.json +++ b/apps/choozi/metadata.json @@ -1,7 +1,7 @@ { "id": "choozi", "name": "Choozi", - "version": "0.02", + "version": "0.03", "description": "Choose people or things at random using Bangle.js.", "icon": "app.png", "tags": "tool", diff --git a/apps/health/ChangeLog b/apps/health/ChangeLog index 1e4864af8..7dbb9c458 100644 --- a/apps/health/ChangeLog +++ b/apps/health/ChangeLog @@ -10,3 +10,4 @@ 0.09: Fix file naming so months are 1-based (not 0) (fix #1119) 0.10: Adds additional 3 minute setting for HRM 0.11: Pre-minified boot&lib - folds constants and saves RAM +0.12: Add setting for Daily Step Goal diff --git a/apps/health/README.md b/apps/health/README.md index f44854e3e..c6b379c0a 100644 --- a/apps/health/README.md +++ b/apps/health/README.md @@ -24,6 +24,7 @@ Stores: * **Off** - Don't turn HRM on, but record heart rate if the HRM was turned on by another app/widget * **10 Min** - Turn HRM on every 10 minutes (for each heath entry) and turn it off after 2 minutes, or when a good reading is found * **Always** - Keep HRM on all the time (more accurate recording, but reduces battery life to ~36 hours) +* **Daily Step Goal** - Default 10000, daily step goal for pedometer apps to use ## Technical Info diff --git a/apps/health/app.js b/apps/health/app.js index 64640603e..e39590e2d 100644 --- a/apps/health/app.js +++ b/apps/health/app.js @@ -2,8 +2,8 @@ function getSettings() { return require("Storage").readJSON("health.json",1)||{}; } -function setSettings(s) { - require("Storage").writeJSON("health.json",s); +function setSettings(healthSettings) { + require("Storage").writeJSON("health.json",healthSettings); } function menuMain() { @@ -22,15 +22,21 @@ function menuMain() { function menuSettings() { swipe_enabled = false; clearButton(); - var s=getSettings(); + var healthSettings=getSettings(); + //print(healthSettings); E.showMenu({ "":{title:"Health Tracking"}, "< Back":()=>menuMain(), "Heart Rt":{ - value : 0|s.hrm, + value : 0|healthSettings.hrm, min : 0, max : 3, format : v=>["Off","3 mins","10 mins","Always"][v], - onchange : v => { s.hrm=v;setSettings(s); } + onchange : v => { healthSettings.hrm=v;setSettings(healthSettings); } + }, + "Daily Step Goal":{ + value : (healthSettings.stepGoal ? healthSettings.stepGoal : 10000), + min : 0, max : 20000, step : 100, + onchange : v => { healthSettings.stepGoal=v;setSettings(healthSettings); } } }); } @@ -199,7 +205,7 @@ function drawBarChart() { for (bar = 1; bar < 10; bar++) { if (bar == 5) { g.setFont('6x8', 2); - g.setFontAlign(0,-1) + g.setFontAlign(0,-1); g.setColor(g.theme.fg); g.drawString(chart_label + " " + (chart_index + bar -1) + " " + chart_data[chart_index + bar - 1], g.getWidth()/2, 150); g.setColor("#00f"); diff --git a/apps/health/metadata.json b/apps/health/metadata.json index 8bb986c57..5d096dc07 100644 --- a/apps/health/metadata.json +++ b/apps/health/metadata.json @@ -1,7 +1,7 @@ { "id": "health", "name": "Health Tracking", - "version": "0.11", + "version": "0.12", "description": "Logs health data and provides an app to view it", "icon": "app.png", "tags": "tool,system,health", diff --git a/apps/launch/ChangeLog b/apps/launch/ChangeLog index b8c198d50..7248f69c3 100644 --- a/apps/launch/ChangeLog +++ b/apps/launch/ChangeLog @@ -12,3 +12,4 @@ 0.11: Merge Bangle.js 1 and 2 launchers, again 0.12: Add an option to hide clocks from the app list (fix #1015) Add /*LANG*/ tags for internationalisation +0.13: Add fullscreen mode diff --git a/apps/launch/app.js b/apps/launch/app.js index 4ceabe751..556e61bfd 100644 --- a/apps/launch/app.js +++ b/apps/launch/app.js @@ -2,7 +2,10 @@ var s = require("Storage"); var scaleval = 1; var vectorval = 20; var font = g.getFonts().includes("12x20") ? "12x20" : "6x8:2"; -let settings = Object.assign({ showClocks: true }, s.readJSON("launch.json", true) || {}); +let settings = Object.assign({ + showClocks: true, + fullscreen: false +}, s.readJSON("launch.json", true) || {}); if ("vectorsize" in settings) { vectorval = parseInt(settings.vectorsize); @@ -44,8 +47,11 @@ function drawApp(i, r) { } g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); + +if (!settings.fullscreen) { + Bangle.loadWidgets(); + Bangle.drawWidgets(); +} E.showScroller({ h : 64*scaleval, c : apps.length, diff --git a/apps/launch/metadata.json b/apps/launch/metadata.json index 96bbf104b..ab218412d 100644 --- a/apps/launch/metadata.json +++ b/apps/launch/metadata.json @@ -2,7 +2,7 @@ "id": "launch", "name": "Launcher", "shortName": "Launcher", - "version": "0.12", + "version": "0.13", "description": "This is needed to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", "icon": "app.png", "type": "launch", diff --git a/apps/launch/settings.js b/apps/launch/settings.js index 60422e75c..5d37e1c1b 100644 --- a/apps/launch/settings.js +++ b/apps/launch/settings.js @@ -1,6 +1,9 @@ // make sure to enclose the function in parentheses (function(back) { - let settings = Object.assign({ showClocks: true }, require("Storage").readJSON("launch.json", true) || {}); + let settings = Object.assign({ + showClocks: true, + fullscreen: false + }, require("Storage").readJSON("launch.json", true) || {}); let fonts = g.getFonts(); function save(key, value) { @@ -8,7 +11,7 @@ require("Storage").write("launch.json",settings); } const appMenu = { - "": {"title": /*LANG*/"Launcher Settings"}, + "": { "title": /*LANG*/"Launcher" }, /*LANG*/"< Back": back, /*LANG*/"Font": { value: fonts.includes(settings.font)? fonts.indexOf(settings.font) : fonts.indexOf("12x20"), @@ -16,15 +19,20 @@ onchange: (m) => {save("font", fonts[m])}, format: v => fonts[v] }, - /*LANG*/"Vector font size": { + /*LANG*/"Vector Font Size": { value: settings.vectorsize || 10, min:10, max: 20,step:1,wrap:true, onchange: (m) => {save("vectorsize", m)} }, - /*LANG*/"Show clocks": { + /*LANG*/"Show Clocks": { value: settings.showClocks == true, format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", - onchange: (m) => {save("showClocks", m)} + onchange: (m) => { save("showClocks", m) } + }, + /*LANG*/"Fullscreen": { + value: settings.fullscreen == true, + format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", + onchange: (m) => { save("fullscreen", m) } } }; E.showMenu(appMenu); diff --git a/apps/lcars/ChangeLog b/apps/lcars/ChangeLog index 4935fe714..e622feb1f 100644 --- a/apps/lcars/ChangeLog +++ b/apps/lcars/ChangeLog @@ -17,4 +17,6 @@ 0.17: Settings for mph/kph and other minor improvements. 0.18: Fullscreen mode can now be enabled or disabled in the settings. 0.19: Alarms can not go bigger than 100. -0.20: Use alarm for alarm functionality instead of own implementation. \ No newline at end of file +0.20: Use alarm for alarm functionality instead of own implementation. +0.21: Add custom theming. +0.22: Fix alarm and add build in function for step counting. \ No newline at end of file diff --git a/apps/lcars/README.md b/apps/lcars/README.md index 7024e8edf..6d4b18b9a 100644 --- a/apps/lcars/README.md +++ b/apps/lcars/README.md @@ -1,8 +1,7 @@ # LCARS clock A simple LCARS inspired clock. -Note: To display the steps, the wpedom app is required. To show weather data -such as temperature, humidity or window you BangleJS must be connected +To show weather data such as temperature, humidity or window you BangleJS must be connected with Gadgetbride and the weather app must be installed. To use the timer the "sched" app must be installed on your device. @@ -19,6 +18,7 @@ the "sched" app must be installed on your device. * Tap on top/bottom of screen 1 to activate an alarm. Depends on widtmr. * The lower orange line indicates the battery level. * Display graphs (day or month) for steps + hrm on the second screen. + * Customizable theming colors in the settings menu of the app. ## Data that can be configured * Steps - Steps loaded via the wpedom app. @@ -43,3 +43,4 @@ Access different screens via tap on the left/ right side of the screen ## Contributors - [Adam Schmalhofer](https://github.com/adamschmalhofer) - [Jon Warrington](https://github.com/BartokW) +- [Ronin Stegner](https://github.com/Ronin0000) diff --git a/apps/lcars/bg_left.png b/apps/lcars/bg_left.png index 91c2bb6f7..3bae5e458 100644 Binary files a/apps/lcars/bg_left.png and b/apps/lcars/bg_left.png differ diff --git a/apps/lcars/bg_left_small.png b/apps/lcars/bg_left_small.png index bfdb110d9..8223a1898 100644 Binary files a/apps/lcars/bg_left_small.png and b/apps/lcars/bg_left_small.png differ diff --git a/apps/lcars/bg_right.png b/apps/lcars/bg_right.png index 6e23a5d6e..a87cf31d1 100644 Binary files a/apps/lcars/bg_right.png and b/apps/lcars/bg_right.png differ diff --git a/apps/lcars/bg_right_small.png b/apps/lcars/bg_right_small.png index df9d32b38..62d9ea651 100644 Binary files a/apps/lcars/bg_right_small.png and b/apps/lcars/bg_right_small.png differ diff --git a/apps/lcars/lcars.app.js b/apps/lcars/lcars.app.js index 577955d2e..07ca51fd9 100644 --- a/apps/lcars/lcars.app.js +++ b/apps/lcars/lcars.app.js @@ -1,14 +1,17 @@ const TIMER_IDX = "lcars"; const SETTINGS_FILE = "lcars.setting.json"; const locale = require('locale'); -const storage = require('Storage'); +const storage = require('Storage') let settings = { alarm: -1, dataRow1: "Steps", - dataRow2: "Temp", + dataRow2: "HRM", dataRow3: "Battery", speed: "kph", fullscreen: false, + themeColor1BG: "#FF9900", + themeColor2BG: "#FF00DC", + themeColor3BG: "#0094FF", }; let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings; for (const key in saved_settings) { @@ -18,9 +21,9 @@ for (const key in saved_settings) { /* * Colors to use */ -let cBlue = "#0094FF"; -let cOrange = "#FF9900"; -let cPurple = "#FF00DC"; +let color1 = settings.themeColor3BG; +let color2 = settings.themeColor1BG; +let color3 = settings.themeColor2BG; let cWhite = "#FFFFFF"; let cBlack = "#000000"; let cGrey = "#424242"; @@ -33,33 +36,77 @@ let lcarsViewPos = 0; var plotMonth = false; -/* - * Requirements and globals - */ +function convert24to16(input) +{ + let RGB888 = parseInt(input.replace(/^#/, ''), 16); + let r = (RGB888 & 0xFF0000) >> 16; + let g = (RGB888 & 0xFF00) >> 8; + let b = RGB888 & 0xFF; + r = (r * 249 + 1014) >> 11; + g = (g * 253 + 505) >> 10; + b = (b * 249 + 1014) >> 11; + let RGB565 = 0; + RGB565 = RGB565 | (r << 11); + RGB565 = RGB565 | (g << 5); + RGB565 = RGB565 | b; + + return "0x"+RGB565.toString(16); +} + +var color1C = convert24to16(color1); +var color2C = convert24to16(color2); +var color3C = convert24to16(color3); + +/* +* Requirements and globals +*/ + +var colorPalette = new Uint16Array([ + 0x0000, // not used + color2C, // second + color3C, // third + 0x0000, // not used + color1C, // first + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000, // not used + 0x0000 // not used +],0,1); var bgLeftFullscreen = { width : 27, height : 176, bpp : 3, transparent : 0, - buffer : require("heatshrink").decompress(atob("AAUM2XLlgCCwAJBBAuy4EAmQIF5cggAIGlmwgYIG2XIF42wF4ImGF4ImHJoQmGJoQdJhZNHNY47CgRNGBIJZHHgRiGBIRQ/KH5QCAFCh/eX5Q/KAwdCAGVbtu27YCCoAJBkuWrNlAQRGCiwRDAQPQBIMJCIYCBsAJBgomEtu0WoQmEy1YBIMBHYttIwQ7FyxQ/KHFlFAQ7F2weCHYplKChRTCCg5TCHw5TMAD0GzVp0wCCBBGaBIMaBAtpwECBA2mwEJBAugDgMmCIwJBF5EABAtoeQQvGCYQdPJoI7LMQzTCLJKAGzAJBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4A==")) + buffer : require("heatshrink").decompress((atob("/4AB+VJkmSAQV///+BAtJn//5IIFkmf/4IGyVP/gIGpMnF41PHIImGF4ImHJoQmGJoIdK8hNHNY47C/JNGBIJZGyYJBQA5GCKH5Q/KAQAoUP7y/KH5QGDoQAy0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkqrCS4xGCWoyDCKH5Q1GShlJChQLCCg5TCHw5TMAD35FAoIIkgJB8hGGv/8Mg8/+QIFp4cB5IRGBIIvI/4IFybyCF4wTCDp5NBHZZiGz4JBLJKAGk4JBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4"))), + palette: colorPalette }; var bgLeftNotFullscreen = { width : 27, height : 152, bpp : 3, transparent : 0, - buffer : require("heatshrink").decompress(atob("AAUM2XLlgCCwAJBBAuy4EAmQIF5cggAIGlmwgYIG2XIF42wF4ImGF4ImHJoQmGJoQdJhZNHNY47CgRNGBIJZHHgRiGBIRQ/KH5QCAGVbtu27YCCoAJBkuWrNlAQRkCiwRDAQPQBIMJCIYCBsAJBgomEtu0WoQmEy1YBIMBHYttIwQ7FyxQ/KHFlFAQ7F2weCHYplKChRTCCg5TCHw5TMAD0GzVp0wCCBBGaBIMaBAtpwECBA2mwEJBAugDgMmCIwJBF5EABAtoeQQvGCYQdPJoI7LMQzTCLJKAGzAJBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4A=")) + buffer : require("heatshrink").decompress((atob("/4AB+VJkmSAQV///+BAtJn//5IIFkmf/4IGyVP/gIGpMnF41PHIImGF4ImHJoQmGJoIdK8hNHNY47C/JNGBIJZGyYJBQA5GCKH5Q/KAQAy0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkqrCS4xGCWoyhCKH5Q1GShlJChQLCCg5TCHw5TMAD35FAoIIkgJB8hGGv/8Mg8/+QIFp4cB5IRGBIIvI/4IFybyCF4wTCDp5NBHZZiGz4JBLJKAGk4JBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4A=="))), + palette: colorPalette }; var bgRightFullscreen = { width : 27, height : 176, bpp : 3, transparent : 0, - buffer : require("heatshrink").decompress(atob("lmy5YCDBIUyBAmy5AJBhYUG2EAhgIFAQMAgQIGCgQABCg4ABEAwUNFI2AKZHAKZEgGRZTGOIUDQxJxGKH5Q/agwAnUP7y/KH4yGeVYAJrdt23bAQVABIMly1ZsoCCMgUWCIYCB6AJBhIRDAQNgBIMFEwlt2i1CEwmWrAJBgI7FtpGCHYuWKH5QxEwpQDlo7F0A7IqBZBEwo7BCIwCBJo53CJoxiCJpIAdgOmzVpAQR/CgAIEAQJ2CBAoCBBIMmCg1oD4QLGFQUCCjQ+CKYw+CKY4JCKYwoCGRMaGREJDoroCgwdFzBlLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJox/CgAA=")) + buffer : require("heatshrink").decompress((atob("yVJkgCCyf/AAPJBAYCBk4JB8gUFyVP//yBAoCB//5BAwUCAAIUHAAIgGChopGv5TIn5TIz4yLKYxxC/iGI/xxGKH5Q/agwAnUP7y/KH4yGeVYAJ0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkp4CS4xGCWoyhCKH5QuDoxQCDpI7GDoJZGHYIRGLIQvGO4QvGMQRNJADv+GIqTC/5PGz4JBJ41JBIPJCg2TD4QLGn4JB/gUaHwRTGHwRTHBIRTGNAQyJ8gyI+QdFp4JB/IdFk5lLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJoyJC/4A=="))), + palette: colorPalette }; var bgRightNotFullscreen = { width : 27, height : 152, bpp : 3, transparent : 0, - buffer : require("heatshrink").decompress(atob("lmy5YCDBIUyBAmy5AJBhYUG2EAhgIFAQMAgQIGCgQABCg4ABEAwUNFI2AKZHAKZEgGRZTGOIUDQxJxGKH5Q/agwAxrdt23bAQVABIMly1ZsoCCMgUWCIYCB6AJBhIRDAQNgBIMFEwlt2i1CEwmWrAJBgI7FtpGCHYuWKH5QxEwpQDlo7F0A7IqBZBEwo7BCIwCBJo53CJoxiCJpIAdgOmzVpAQR/CgAIEAQJ2CBAoCBBIMmCg1oD4QLGFQUCCjQ+CKYw+CKY4JCKYwoCGRMaGREJDoroCgwdFzBlLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJox/CgA=")) + buffer : require("heatshrink").decompress((atob("yVJkgCCyf/AAPJBAYCBk4JB8gUFyVP//yBAoCB//5BAwUCAAIUHAAIgGChopGv5TIn5TIz4yLKYxxC/iGI/xxGKH5Q/agwAx0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkqrCS4xGCWoyhCKH5QuDoxQCDpI7GDoJZGHYIRGLIQvGO4QvGMQRNJADv+GIqTC/5PGz4JBJ41JBIPJCg2TD4QLGn4JB/gUaHwRTGHwRTHBIRTGNAQyJ8gyI+QdFp4JB/IdFk5lLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJoyJC/4A="))), + palette: colorPalette }; var bgLeft = settings.fullscreen ? bgLeftFullscreen : bgLeftNotFullscreen; @@ -191,7 +238,7 @@ function _drawData(key, y, c){ value = E.getAnalogVRef().toFixed(2) + "V"; } else if(key == "HRM"){ - value = Math.round(Bangle.getHealthStatus("day").bpm); + value = Math.round(Bangle.getHealthStatus("last").bpm); } else if (key == "TEMP"){ var weather = getWeather(); @@ -244,9 +291,11 @@ function drawInfo(){ return; } + // Draw Infor is called from different sources so + // we have to ensure that the alignment is always the same. g.setFontAlign(-1, -1, 0); g.setFontAntonioMedium(); - g.setColor(cOrange); + g.setColor(color2); g.clearRect(120, 10, g.getWidth(), 75); g.drawString("LCARS", 128, 13); @@ -256,7 +305,7 @@ function drawInfo(){ g.drawString("NOCON", 128, 33); } if(Bangle.isLocked()){ - g.setColor(cPurple); + g.setColor(color3); g.drawString("LOCK", 128, 53); } } @@ -287,7 +336,7 @@ function drawState(){ g.drawString("STATUS", 23+26, 108); } else { // Alarm within symbol - g.setColor(cOrange); + g.setColor(color2); g.drawString("ALARM", 23+26, 108); g.setColor(cWhite); g.setFontAntonioLarge(); @@ -302,19 +351,19 @@ function drawPosition0(){ // Draw background image var offset = settings.fullscreen ? 0 : 24; g.drawImage(bgLeft, 0, offset); - drawHorizontalBgLine(cBlue, 25, 120, offset, 4); - drawHorizontalBgLine(cBlue, 130, 176, offset, 4); - drawHorizontalBgLine(cPurple, 20, 70, 80, 4); - drawHorizontalBgLine(cPurple, 80, 176, 80, 4); - drawHorizontalBgLine(cOrange, 35, 110, 87, 4); - drawHorizontalBgLine(cOrange, 120, 176, 87, 4); + drawHorizontalBgLine(color1, 25, 120, offset, 4); + drawHorizontalBgLine(color1, 130, 176, offset, 4); + drawHorizontalBgLine(color3, 20, 70, 80, 4); + drawHorizontalBgLine(color3, 80, 176, 80, 4); + drawHorizontalBgLine(color2, 35, 110, 87, 4); + drawHorizontalBgLine(color2, 120, 176, 87, 4); // The last line is a battery indicator too var bat = E.getBattery() / 100.0; var batStart = 19; var batWidth = 172 - batStart; var batX2 = parseInt(batWidth * bat + batStart); - drawHorizontalBgLine(cOrange, batStart, batX2, 171, 5); + drawHorizontalBgLine(color2, batStart, batX2, 171, 5); drawHorizontalBgLine(cGrey, batX2, 172, 171, 5); for(var i=0; i+batStart<=172; i+=parseInt(batWidth/4)){ drawHorizontalBgLine(cBlack, batStart+i, batStart+i+3, 168, 8) @@ -353,9 +402,9 @@ function drawPosition0(){ // Draw data g.setFontAlign(-1, -1, 0); g.setColor(cWhite); - drawData(settings.dataRow1, 97, cOrange); - drawData(settings.dataRow2, 122, cPurple); - drawData(settings.dataRow3, 147, cBlue); + drawData(settings.dataRow1, 97, color2); + drawData(settings.dataRow2, 122, color3); + drawData(settings.dataRow3, 147, color1); // Draw state drawState(); @@ -366,13 +415,13 @@ function drawPosition1(){ var offset = settings.fullscreen ? 0 : 24; g.drawImage(bgRight, 149, offset); if(settings.fullscreen){ - drawHorizontalBgLine(cBlue, 0, 140, offset, 4); + drawHorizontalBgLine(color1, 0, 140, offset, 4); } - drawHorizontalBgLine(cPurple, 0, 80, 80, 4); - drawHorizontalBgLine(cPurple, 90, 150, 80, 4); - drawHorizontalBgLine(cOrange, 0, 50, 87, 4); - drawHorizontalBgLine(cOrange, 60, 140, 87, 4); - drawHorizontalBgLine(cOrange, 0, 150, 171, 5); + drawHorizontalBgLine(color3, 0, 80, 80, 4); + drawHorizontalBgLine(color3, 90, 150, 80, 4); + drawHorizontalBgLine(color2, 0, 50, 87, 4); + drawHorizontalBgLine(color2, 60, 140, 87, 4); + drawHorizontalBgLine(color2, 0, 150, 171, 5); // Draw steps bars g.setColor(cWhite); @@ -511,17 +560,20 @@ function draw(){ * Step counter via widget */ function getSteps() { + var steps = 0; try{ if (WIDGETS.wpedom !== undefined) { - return WIDGETS.wpedom.getSteps(); + steps = WIDGETS.wpedom.getSteps(); } else if (WIDGETS.activepedom !== undefined) { - return WIDGETS.activepedom.getSteps(); + steps = WIDGETS.activepedom.getSteps(); + } else { + steps = Bangle.getHealthStatus("day").steps; } } catch(ex) { // In case we failed, we can only show 0 steps. } - return 0; + return steps; } @@ -530,38 +582,35 @@ function getWeather(){ try { weatherJson = storage.readJSON('weather.json'); + var weather = weatherJson.weather; + + // Temperature + weather.temp = locale.temp(weather.temp-273.15); + + // Humidity + weather.hum = weather.hum + "%"; + + // Wind + const wind = locale.speed(weather.wind).match(/^(\D*\d*)(.*)$/); + var speedFactor = settings.speed == "kph" ? 1.0 : 1.0 / 1.60934; + weather.wind = Math.round(wind[1] * speedFactor); + + return weather + } catch(ex) { // Return default } - if(weatherJson === undefined){ - return { - temp: "-", - hum: "-", - txt: "-", - wind: "-", - wdir: "-", - wrose: "-" - }; - } - - var weather = weatherJson.weather; - - // Temperature - weather.temp = locale.temp(weather.temp-273.15); - - // Humidity - weather.hum = weather.hum + "%"; - - // Wind - const wind = locale.speed(weather.wind).match(/^(\D*\d*)(.*)$/); - var speedFactor = settings.speed == "kph" ? 1.0 : 1.0 / 1.60934; - weather.wind = Math.round(wind[1] * speedFactor); - - return weather + return { + temp: " ? ", + hum: " ? ", + txt: " ? ", + wind: " ? ", + wdir: " ? ", + wrose: " ? " + }; } - /* * Handle alarm */ @@ -594,7 +643,7 @@ function increaseAlarm(){ var minutes = isAlarmEnabled() ? getAlarmMinutes() : 0; var alarm = require('sched') alarm.setAlarm(TIMER_IDX, { - timer : (minutes+5)*60*1000, + timer : (minutes+5)*60*1000, }); alarm.reload(); } catch(ex){ } @@ -609,9 +658,9 @@ function decreaseAlarm(){ alarm.setAlarm(TIMER_IDX, undefined); if(minutes > 0){ - alarm.setAlarm(TIMER_IDX, { - timer : minutes*60*1000, - }); + alarm.setAlarm(TIMER_IDX, { + timer : minutes*60*1000, + }); } alarm.reload(); @@ -642,7 +691,6 @@ Bangle.on('charging',function(charging) { drawState(); }); - function feedback(){ Bangle.buzz(40, 0.3); } diff --git a/apps/lcars/lcars.settings.js b/apps/lcars/lcars.settings.js index 75add1ece..b64feb30e 100644 --- a/apps/lcars/lcars.settings.js +++ b/apps/lcars/lcars.settings.js @@ -5,11 +5,14 @@ const storage = require('Storage') let settings = { alarm: -1, - dataRow1: "Battery", - dataRow2: "Steps", - dataRow3: "Temp", + dataRow1: "Steps", + dataRow2: "HRM", + dataRow3: "Battery", speed: "kph", fullscreen: false, + themeColor1BG: "#FF9900", + themeColor2BG: "#FF00DC", + themeColor3BG: "#0094FF", }; let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings; for (const key in saved_settings) { @@ -20,8 +23,11 @@ storage.write(SETTINGS_FILE, settings) } + var dataOptions = ["Steps", "Battery", "VREF", "HRM", "Temp", "Humidity", "Wind", "Altitude", "CoreT"]; var speedOptions = ["kph", "mph"]; + var color_options = ['Green','Orange','Cyan','Purple','Red','Blue','Yellow','White']; + var bg_code = ['#00ff00','#FF9900','#0094FF','#FF00DC','#ff0000','#0000ff','#ffef00','#FFFFFF']; E.showMenu({ '': { 'title': 'LCARS Clock' }, @@ -69,6 +75,33 @@ settings.speed = speedOptions[v]; save(); }, + }, + 'Theme Color 1': { + value: 0 | bg_code.indexOf(settings.themeColor1BG), + min: 0, max: 7, + format: v => color_options[v], + onchange: v => { + settings.themeColor1BG = bg_code[v]; + save(); + }, + }, + 'Theme Color 2': { + value: 0 | bg_code.indexOf(settings.themeColor2BG), + min: 0, max: 7, + format: v => color_options[v], + onchange: v => { + settings.themeColor2BG = bg_code[v]; + save(); + }, + }, + 'Theme Color 3': { + value: 0 | bg_code.indexOf(settings.themeColor3BG), + min: 0, max: 7, + format: v => color_options[v], + onchange: v => { + settings.themeColor3BG = bg_code[v]; + save(); + }, } }); }) diff --git a/apps/lcars/metadata.json b/apps/lcars/metadata.json index 7155442f8..40da1b37f 100644 --- a/apps/lcars/metadata.json +++ b/apps/lcars/metadata.json @@ -3,7 +3,7 @@ "name": "LCARS Clock", "shortName":"LCARS", "icon": "lcars.png", - "version":"0.20", + "version":"0.22", "readme": "README.md", "supports": ["BANGLEJS2"], "description": "Library Computer Access Retrieval System (LCARS) clock.", diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 3e676c21e..a96f125d3 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -44,3 +44,5 @@ 0.29: Fix message list overwrites on Bangle.js 1 (fix #1642) 0.30: Add new Icons (Youtube, Twitch, MS TODO, Teams, Snapchat, Signal, Post & DHL, Nina, Lieferando, Kalender, Discord, Corona Warn, Bibel) 0.31: Option to disable icon flashing +0.32: Added an option to allow quiet mode to override message auto-open +0.33: Timeout from the message list screen if the message being displayed is removed and there is a timer going diff --git a/apps/messages/app.js b/apps/messages/app.js index 821813108..617801f61 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -470,8 +470,6 @@ function checkMessages(options) { // no new messages - go to clock? if (options.clockIfAllRead && newMessages.length==0) return load(); - // we don't have to time out of this screen... - cancelReloadTimeout(); active = "main"; // Otherwise show a menu E.showScroller({ diff --git a/apps/messages/lib.js b/apps/messages/lib.js index 7d49d4c64..f584c9e93 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -56,9 +56,16 @@ exports.pushMessage = function(event) { } // otherwise load messages/show widget var loadMessages = Bangle.CLOCK || event.important; - // first, buzz var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; - var unlockWatch = (require('Storage').readJSON('messages.settings.json',1)||{}).unlockWatch; + var appSettings = require('Storage').readJSON('messages.settings.json',1)||{}; + var unlockWatch = appSettings.unlockWatch; + var quietNoAutOpn = appSettings.quietNoAutOpn; + delete appSettings; + // don't auto-open messages in quiet mode if quietNoAutOpn is true + if(quiet && quietNoAutOpn) { + loadMessages = false; + } + // first, buzz if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages){ WIDGETS.messages.buzz(); if(unlockWatch != false){ diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index 5c1e67702..228e44d35 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.31", + "version": "0.33", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", diff --git a/apps/messages/settings.js b/apps/messages/settings.js index cc0030ec5..adea36f12 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -53,6 +53,11 @@ format: v => v?/*LANG*/'Yes':/*LANG*/'No', onchange: v => updateSetting("flash", v) }, + /*LANG*/'Quiet mode disables auto-open': { + value: !!settings().quietNoAutOpn, + format: v => v?/*LANG*/'Yes':/*LANG*/'No', + onchange: v => updateSetting("quietNoAutOpn", v) + }, }; E.showMenu(mainmenu); }) diff --git a/apps/sched/ChangeLog b/apps/sched/ChangeLog index a2d6c370f..0f935caf8 100644 --- a/apps/sched/ChangeLog +++ b/apps/sched/ChangeLog @@ -2,3 +2,4 @@ 0.02: Fix scheduling of other alarms if there is a pending alarm from the past (fix #1667) 0.03: Fix `getTimeToAlarm` for a timer already used at same day, don't set `last` for timers. 0.04: Fix `getTimeToAlarm` to check for next dow if alarm.t lower currentTime. +0.05: Export new functions (`newDefaultAlarm/Timer`), add Settings page diff --git a/apps/sched/README.md b/apps/sched/README.md index ed08139eb..47507fc14 100644 --- a/apps/sched/README.md +++ b/apps/sched/README.md @@ -8,8 +8,17 @@ Other apps can use this to provide alarm functionality. App --- -The Alarm app allows you to add/modify any running timers. +The **Alarms & Timers** app allows you to add/modify any running alarms and timers. +Global Settings +--------------- + +- `Unlock at Buzz` - If `Yes` the alarm/timer will unlock the watch +- `Default Auto Snooze` - Default _Auto Snooze_ value for newly created alarms (_Alarms_ only) +- `Default Snooze` - Default _Snooze_ value for newly created alarms/timers +- `Buzz Count` - The number of buzzes before the watch goes silent +- `Buzz Interval` - The interval between one buzz and the next +- `Default Alarm/Timer Pattern` - Default vibration pattern for newly created alarms/timers Internals / Library ------------------- @@ -53,21 +62,27 @@ use too much RAM. It can be used as follows: ``` -// add/update an existing alarm +// Get a new alarm with default values +let alarm = require("sched").newDefaultAlarm(); + +// Get a new timer with default values +let timer = require("sched").newDefaultTimer(); + +// Add/update an existing alarm require("sched").setAlarm("mytimer", { msg : "Wake up", - timer : 10*60*1000, // 10 Minutes + timer : 10 * 60 * 1000 // 10 minutes }); // Ensure the widget and alarm timer updates to schedule the new alarm properly require("sched").reload(); // Get the time to the next alarm for us -var timeToNext = require("sched").getTimeToAlarm(require("sched").getAlarm("mytimer")); -// timeToNext===undefined if no alarm or alarm disabled +let timeToNext = require("sched").getTimeToAlarm(require("sched").getAlarm("mytimer")); +// timeToNext === undefined if no alarm or alarm disabled -// delete an alarm +// Delete an alarm require("sched").setAlarm("mytimer", undefined); -// reload after deleting... +// Reload after deleting require("sched").reload(); // Or add an alarm that runs your own code - in this case @@ -76,12 +91,15 @@ require("sched").reload(); require("sched").setAlarm("customrunner", { appid : "myapp", js : "load('setting.app.js')", - timer : 1*60*1000, // 1 Minute + timer : 1 * 60 * 1000 // 1 minute }); // If you have been specifying `appid` you can also find any alarms that // your app has created with the following: -require("sched").getAlarms().filter(a=>a.appid=="myapp"); +require("sched").getAlarms().filter(a => a.appid == "myapp"); + +// Get the scheduler settings +let settings = require("sched").getSettings(); ``` If your app requires alarms, you can specify that the alarms app needs to diff --git a/apps/sched/lib.js b/apps/sched/lib.js index 48094c86f..bfad1ac2d 100644 --- a/apps/sched/lib.js +++ b/apps/sched/lib.js @@ -52,3 +52,58 @@ exports.reload = function() { Bangle.drawWidgets(); } }; +// Factory that creates a new alarm with default values +exports.newDefaultAlarm = function () { + const settings = exports.getSettings(); + + let alarm = { + t: 12 * 3600000, // Default to 12:00 + on: true, + rp: false, // repeat not the default + as: settings.defaultAutoSnooze || false, + dow: 0b1111111, + last: 0, + vibrate: settings.defaultAlarmPattern, + }; + + delete settings; + + return alarm; +} +// Factory that creates a new timer with default values +exports.newDefaultTimer = function () { + const settings = exports.getSettings(); + + let timer = { + timer: 5 * 60 * 1000, // 5 minutes + on: true, + rp: false, + as: false, + dow: 0b1111111, + last: 0, + vibrate: settings.defaultTimerPattern + } + + delete settings; + + return timer; +}; +// Return the scheduler settings +exports.getSettings = function () { + return Object.assign( + { + unlockAtBuzz: false, + defaultSnoozeMillis: 600000, // 10 minutes + defaultAutoSnooze: false, + buzzCount: 10, + buzzIntervalMillis: 3000, // 3 seconds + defaultAlarmPattern: "..", + defaultTimerPattern: ".." + }, + require("Storage").readJSON("sched.settings.json", true) || {} + ); +} +// Write the updated settings back to storage +exports.setSettings = function(settings) { + require("Storage").writeJSON("sched.settings.json", settings); +}; \ No newline at end of file diff --git a/apps/sched/metadata.json b/apps/sched/metadata.json index ffa346a44..3454d2397 100644 --- a/apps/sched/metadata.json +++ b/apps/sched/metadata.json @@ -1,7 +1,7 @@ { "id": "sched", "name": "Scheduler", - "version": "0.04", + "version": "0.05", "description": "Scheduling library for alarms and timers", "icon": "app.png", "type": "scheduler", @@ -12,7 +12,8 @@ {"name":"sched.boot.js","url":"boot.js"}, {"name":"sched.js","url":"sched.js"}, {"name":"sched.img","url":"app-icon.js","evaluate":true}, - {"name":"sched","url":"lib.js"} + {"name":"sched","url":"lib.js"}, + {"name":"sched.settings.js","url":"settings.js"} ], - "data": [{"name":"sched.json"}] + "data": [{"name":"sched.json"}, {"name":"sched.settings.json"}] } diff --git a/apps/sched/sched.js b/apps/sched/sched.js index 9096fe4bf..83f03ac01 100644 --- a/apps/sched/sched.js +++ b/apps/sched/sched.js @@ -18,7 +18,9 @@ function formatTime(t) { } function showAlarm(alarm) { - var msg = ""; + const settings = require("sched").getSettings(); + + let msg = ""; msg += alarm.timer ? formatTime(alarm.timer) : formatTime(alarm.t); if (alarm.msg) { msg += "\n"+alarm.msg; @@ -28,9 +30,12 @@ function showAlarm(alarm) { else msg = atob("AC0swgF97///RcEpMlVVVVVVf9VVVVVVVVX/9VVf9VVf/1VVV///1Vf9VX///VVX///VWqqlV///1Vf//9aqqqqpf//9V///2qqqqqqn///V///6qqqqqqr///X//+qqoAAKqqv//3//6qoAAAAKqr//3//qqAAAAAAqq//3/+qoAADwAAKqv/3/+qgAADwAACqv/3/aqAAADwAAAqp/19qoAAADwAAAKqfV1qgAAADwAAACqXVWqgAAADwAAACqlVWqAAAADwAAAAqlVWqAAAADwAAAAqlVWqAAAADwAAAAqlVaoAAAADwAAAAKpVaoAAAADwAAAAKpVaoAAAADwAAAAKpVaoAAAAOsAAAAKpVaoAAAAOsAAAAKpVaoAAAAL/AAAAKpVaoAAAAgPwAAAKpVaoAAACAD8AAAKpVWqAAAIAA/AAAqlVWqAAAgAAPwAAqlVWqAACAAADwAAqlVWqgAIAAAAAACqlVVqgAgAAAAAACqVVVqoAAAAAAAAKqVVVaqAAAAAAAAqpVVVWqgAAAAAACqlVVVWqoAAAAAAKqlVVVVqqAAAAAAqqVVVVVaqoAAAAKqpVVVVVeqqoAAKqqtVVVVV/6qqqqqqr/VVVVX/2qqqqqqn/1VVVf/VaqqqqpV/9VVVf9VVWqqlVVf9VVVf1VVVVVVVVX9VQ==")+" "+msg; } + Bangle.loadWidgets(); Bangle.drawWidgets(); - var buzzCount = 10; + + let buzzCount = settings.buzzCount; + E.showPrompt(msg,{ title:alarm.timer ? /*LANG*/"TIMER!" : /*LANG*/"ALARM!", buttons : {/*LANG*/"Snooze":true,/*LANG*/"Ok":false} // default is sleep so it'll come back in 10 mins @@ -38,7 +43,7 @@ function showAlarm(alarm) { buzzCount = 0; if (sleep) { if(alarm.ot===undefined) alarm.ot = alarm.t; - alarm.t += 10*60*1000; // 10 minutes + alarm.t += settings.defaultSnoozeMillis; } else { if (!alarm.timer) alarm.last = (new Date()).getDate(); if (alarm.ot!==undefined) { @@ -51,24 +56,35 @@ function showAlarm(alarm) { require("sched").setAlarms(alarms); load(); }); + function buzz() { - require("buzz").pattern(alarm.vibrate===undefined?"..":alarm.vibrate).then(function() { - if (buzzCount--) - setTimeout(buzz, 3000); - else if(alarm.as) { // auto-snooze - buzzCount = 10; - setTimeout(buzz, 600000); + if (settings.unlockAtBuzz) { + Bangle.setLocked(false); + } + + require("buzz").pattern(alarm.vibrate === undefined ? ".." : alarm.vibrate).then(() => { + if (buzzCount--) { + setTimeout(buzz, settings.buzzIntervalMillis); + } else if (alarm.as) { // auto-snooze + buzzCount = settings.buzzCount; + setTimeout(buzz, settings.defaultSnoozeMillis); } }); } - if ((require('Storage').readJSON('setting.json',1)||{}).quiet>1) return; + + if ((require("Storage").readJSON("setting.json", 1) || {}).quiet > 1) + return; + buzz(); } // Check for alarms -var alarms = require("sched").getAlarms(); -var active = require("sched").getActiveAlarms(alarms); -if (active.length) // if there's an alarm, show it +let alarms = require("sched").getAlarms(); +let active = require("sched").getActiveAlarms(alarms); +if (active.length) { + // if there's an alarm, show it showAlarm(active[0]); -else // otherwise just go back to default app +} else { + // otherwise just go back to default app setTimeout(load, 100); +} diff --git a/apps/sched/settings.js b/apps/sched/settings.js new file mode 100644 index 000000000..642e43b43 --- /dev/null +++ b/apps/sched/settings.js @@ -0,0 +1,72 @@ +(function (back) { + let settings = require("sched").getSettings(); + + E.showMenu({ + "": { "title": /*LANG*/"Scheduler" }, + + /*LANG*/"< Back": () => back(), + + /*LANG*/"Unlock at Buzz": { + value: settings.unlockAtBuzz, + format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", + onchange: v => { + settings.unlockAtBuzz = v; + require("sched").setSettings(settings); + } + }, + + /*LANG*/"Default Auto Snooze": { + value: settings.defaultAutoSnooze, + format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", + onchange: v => { + settings.defaultAutoSnooze = v; + require("sched").setSettings(settings); + } + }, + + /*LANG*/"Default Snooze": { + value: settings.defaultSnoozeMillis / 60000, + min: 5, + max: 30, + step: 5, + format: v => v + /*LANG*/" min", + onchange: v => { + settings.defaultSnoozeMillis = v * 60000; + require("sched").setSettings(settings); + } + }, + + /*LANG*/"Buzz Count": { + value: settings.buzzCount, + min: 5, + max: 15, + step: 1, + onchange: v => { + settings.buzzCount = v; + require("sched").setSettings(settings); + } + }, + + /*LANG*/"Buzz Interval": { + value: settings.buzzIntervalMillis / 1000, + min: 1, + max: 5, + step: 1, + format: v => v + /*LANG*/"s", + onchange: v => { + settings.buzzIntervalMillis = v * 1000; + require("sched").setSettings(settings); + } + }, + + /*LANG*/"Default Alarm Pattern": require("buzz_menu").pattern(settings.defaultAlarmPattern, v => { + settings.defaultAlarmPattern = v; + require("sched").setSettings(settings); + }), + + /*LANG*/"Default Timer Pattern": require("buzz_menu").pattern(settings.defaultTimerPattern, v => { + settings.defaultTimerPattern = v; + require("sched").setSettings(settings); + }) + }); +}); diff --git a/apps/widstep/ChangeLog b/apps/widstep/ChangeLog new file mode 100644 index 000000000..55cda0f21 --- /dev/null +++ b/apps/widstep/ChangeLog @@ -0,0 +1 @@ +0.01: New widget diff --git a/apps/widstep/README.md b/apps/widstep/README.md new file mode 100644 index 000000000..c41b025cd --- /dev/null +++ b/apps/widstep/README.md @@ -0,0 +1,9 @@ +# Step counter widget +This is my step counter. There are many like it, but this one is mine. + +A pedometer widget designed to be as narrow as possible, but still easy to read, by sacrificing accuracy and only showing to the nearest 100 steps (0.1k). +Shows a subtle fill colour in the background for progress to the goal. The goal is picked up from the health tracker settings. + + +![](widstep-light.png) +![](widstep-dark.png) diff --git a/apps/widstep/icons8-winter-boots-48.png b/apps/widstep/icons8-winter-boots-48.png new file mode 100644 index 000000000..7dceceef0 Binary files /dev/null and b/apps/widstep/icons8-winter-boots-48.png differ diff --git a/apps/widstep/metadata.json b/apps/widstep/metadata.json new file mode 100644 index 000000000..ea108e0f1 --- /dev/null +++ b/apps/widstep/metadata.json @@ -0,0 +1,17 @@ +{ + "id": "widstep", + "name": "Step counter widget", + "version": "0.01", + "description": "Step counter widget, narrow but clearly readable", + "readme": "README.md", + "icon": "icons8-winter-boots-48.png", + "screenshots": [{"url":"widstep-light.png"},{"url":"widstep-dark.png"}], + "type": "widget", + "tags": "widget,health", + "supports": ["BANGLEJS","BANGLEJS2"], + "dependencies" : {"health":"app"}, + "allow_emulator":false, + "storage": [ + {"name":"widstep.wid.js","url":"widstep.wid.js"} + ] + } diff --git a/apps/widstep/widstep-dark.png b/apps/widstep/widstep-dark.png new file mode 100644 index 000000000..c8e1a8065 Binary files /dev/null and b/apps/widstep/widstep-dark.png differ diff --git a/apps/widstep/widstep-light.png b/apps/widstep/widstep-light.png new file mode 100644 index 000000000..9cce1e7c2 Binary files /dev/null and b/apps/widstep/widstep-light.png differ diff --git a/apps/widstep/widstep.wid.js b/apps/widstep/widstep.wid.js new file mode 100644 index 000000000..6ad971af7 --- /dev/null +++ b/apps/widstep/widstep.wid.js @@ -0,0 +1,23 @@ +let wsSettingsGoal = (require('Storage').readJSON("health.json", 1) || {}).stepGoal || 10000; + +Bangle.on('step', function(s) { WIDGETS["widstep"].draw(); }); +Bangle.on('lcdPower', function(on) { + if (on) WIDGETS["widstep"].draw(); +}); +WIDGETS["widstep"]={area:"tl", sortorder:-1, width:28, + draw:function() { + if (!Bangle.isLCDOn()) return; // dont redraw if LCD is off + var steps = Bangle.getHealthStatus("day").steps; + g.reset(); + g.setColor(g.theme.bg); + g.fillRect(this.x, this.y, this.x + this.width, this.y + 23); + g.setColor(g.theme.dark ? '#00f' : '#0ff'); + var progress = this.width * Math.min(steps/wsSettingsGoal, 1); + g.fillRect(this.x+1, this.y+1, this.x + progress -1, this.y + 23); + g.setColor(g.theme.fg); + g.setFontAlign(0, -1); + var steps_k = (steps/1000).toFixed(1) + 'k'; + g.setFont('6x15').drawString(steps_k, this.x+this.width/2, this.y + 10); + g.setFont('4x6').drawString('steps', this.x+this.width/2, this.y + 2); + } +}; diff --git a/css/main.css b/css/main.css index a986df22e..f4850babe 100644 --- a/css/main.css +++ b/css/main.css @@ -81,7 +81,7 @@ a.btn.btn-link.dropdown-toggle { min-height: 8em; } -.tile-content { position: relative; word-break: break-all; } +.tile-content { position: relative; } .link-github { position:absolute; top: 36px;