From 3c984f1fee70a8af17476a2b751a5c8b128aec36 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Wed, 24 Nov 2021 23:52:28 +0000 Subject: [PATCH 1/8] Cube Scramble: Improved UX and display solve time --- apps.json | 2 +- apps/cubescramble/ChangeLog | 1 + apps/cubescramble/README.md | 3 +-- apps/cubescramble/cube-scramble.js | 29 ++++++++++++++++++++++------- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/apps.json b/apps.json index f83312034..9c10c9dba 100644 --- a/apps.json +++ b/apps.json @@ -551,7 +551,7 @@ { "id": "cubescramble", "name": "Cube Scramble", - "version":"0.03", + "version":"0.04", "description": "A random scramble generator for the 3x3 Rubik's cube", "icon": "cube-scramble.png", "tags": "", diff --git a/apps/cubescramble/ChangeLog b/apps/cubescramble/ChangeLog index 6de5b7211..46852864a 100644 --- a/apps/cubescramble/ChangeLog +++ b/apps/cubescramble/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial Release 0.02: Replace icon with one found on https://icons8.com 0.03: Re-render icon fixing display in settings +0.04: Improved UX and display solve time diff --git a/apps/cubescramble/README.md b/apps/cubescramble/README.md index 779e32489..1c1603372 100644 --- a/apps/cubescramble/README.md +++ b/apps/cubescramble/README.md @@ -1,12 +1,11 @@ # Cube Scramble -A random scramble generator for the 3x3 Rubik's cube +A random scramble generator for the 3x3 Rubik's cube with a basic timer. ## Future features I'm keen to complete this project with -* Add a timer * Add the ability for times to be stored and exported ## Requests diff --git a/apps/cubescramble/cube-scramble.js b/apps/cubescramble/cube-scramble.js index c0b1d11c3..8a7c2eb34 100644 --- a/apps/cubescramble/cube-scramble.js +++ b/apps/cubescramble/cube-scramble.js @@ -1,4 +1,3 @@ - // Scramble code from: https://raw.githubusercontent.com/bjcarlson42/blog-post-sample-code/master/Rubik's%20Cube%20JavaScript%20Scrambler/part_two.js const makeScramble = () => { const options = ["F", "F2", "F'", "R", "R2", "R'", "U", "U2", "U'", "B", "B2", "B'", "L", "L2", "L'", "D", "D2", "D'"]; @@ -59,16 +58,32 @@ const getRandomInt = max => Math.floor(Math.random() * Math.floor(max)); // retu const getRandomIntBetween = (min, max) => Math.floor(Math.random() * (max - min) + min); const presentScramble = () => { - g.clear(); - E.showMessage(makeScramble().join(" ")); + E.showPrompt(makeScramble().join(" "), { + title: "cube scramble", + buttons: {"solve": true, "reset": false} + }).then((v) => { + if (v) { + const start = new Date(); + E.showPrompt(" ", { + title: "cube scramble", + buttons: {"stop": true} + }).then(() => { + const time = parseFloat(((new Date()).getTime() - start.getTime()) / 1000); + E.showPrompt(String(time.toFixed(3)), { + title: "cube scramble", + buttons: {"next": true} + }).then(() => { + presentScramble(); + }); + }); + } else { + presentScramble(); + } + }); }; const init = () => { presentScramble(); - - setWatch(() => { - presentScramble(); - }, BTN1, {repeat:true}); }; init(); From f6c689eeedfa4d349e2f73cdfabbd0a641502735 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Wed, 24 Nov 2021 23:56:47 +0000 Subject: [PATCH 2/8] Amend app description --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 9c10c9dba..b87f96deb 100644 --- a/apps.json +++ b/apps.json @@ -552,7 +552,7 @@ "id": "cubescramble", "name": "Cube Scramble", "version":"0.04", - "description": "A random scramble generator for the 3x3 Rubik's cube", + "description": "A random scramble generator for the 3x3 Rubik's cube with a basic timer", "icon": "cube-scramble.png", "tags": "", "supports" : ["BANGLEJS","BANGLEJS2"], From f175f4c48c149b7b4b6a317db8105790b97a0f6a Mon Sep 17 00:00:00 2001 From: nlisgo Date: Thu, 25 Nov 2021 00:06:02 +0000 Subject: [PATCH 3/8] Update screenshots --- .../bangle1-cube-scramble-screenshot.png | Bin 2924 -> 3848 bytes .../bangle2-cube-scramble-screenshot.png | Bin 2198 -> 2923 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/cubescramble/bangle1-cube-scramble-screenshot.png b/apps/cubescramble/bangle1-cube-scramble-screenshot.png index d75a60e8163639f3c51545a239a6ccfa302e39fa..5a35238e3ffdac883852b6acef915fb2898b7381 100644 GIT binary patch literal 3848 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 diff --git a/apps/cubescramble/bangle2-cube-scramble-screenshot.png b/apps/cubescramble/bangle2-cube-scramble-screenshot.png index b54be04b821bd2fa614715e5b50efd9805004603..ae37b4affbef888d5aeeb69c7272c3b5b0202ee5 100644 GIT binary patch literal 2923 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 literal 2198 zcmeHJ?N`zV8~*td0xT^pD=j1EOlO^^HrG~}pk4ee7+7zb5#I6HWa?98wX3}41z{9p!#Wyag^O|b#<`tDnbJWZxdt3U)HmFn zxQCBv6bVSFcv`JG%7bmg}HJyp(2HsKonY~FyOeK?C~WHv`!)i{;&wa*vPcLzxRW#0BYBef`WtwAh^=LjA~O z%31_W`rWpuCUcmO)@0z!P1A8M-vne}mHY9^k}ck>-;XO3=dzL7^dDHSl9YtAO41U& zohT#NP6f?QOD8aJ=)o;90z*sx6M`dCKol+TXN3mx7x%8)Aj5V+ij8)Xw{oQ@|CeED<6^9&TOS!g%TMyiu+b`HA9Tk z#`ilP%?fOlOv70UTG4&$ognh%k-R$p<(z}6LCZ`^g)nKYP(L~$KMBRxXHxH{7Td>P zUbx|tEc?RVcJ7wpbi^Kzl(adxu^e-Rekbo`lKC`~y{2mL*{TNR?5V8m**5h($33>W6#lbJNVcspgw2@xVEA)09bbxsmP8MY=G6 zHn$&}_TcR(TwsBuoNrf&nr~03=sAwpX4H}NO(``PSq<ql5e(eW01}?1zQ^DJaq9x3+jgQ1FEP@kmH@!g3%;=!oB=@^sv@kC{UDY^WIVC1` zZ{UW8m`^_pCCbohPA!WD!@D@G5DzgGb znb6*I=D759i({Li$r^^TXOuH58$1NRiNTo3C)(BTi`~W{gE!B$eib_^MsBW2Fh5^O zt5HhO&FHhPu&nT>IVp%Ar}P(b2W{Q~#+RZ&Mn8O zQOl5S;Oru`6O|F)v*<7i_sb29PgPm-+L1AHV#}%ng(qL z#iNUlh7c$GxuY}wL*i+vc=;zNC1CtB&38SUk&OIbh@BMAS9%b`7?UB{Yu8_6AP!G* zw_{lMD#k^v_J<(!Vg J;i2^N{{tDZ7$pDz From 9940b38bbd0f53640b4a4ea2e0d70691bae04cea Mon Sep 17 00:00:00 2001 From: nlisgo Date: Thu, 25 Nov 2021 00:13:06 +0000 Subject: [PATCH 4/8] Force LCD on --- apps/cubescramble/cube-scramble.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/cubescramble/cube-scramble.js b/apps/cubescramble/cube-scramble.js index 8a7c2eb34..6fe477031 100644 --- a/apps/cubescramble/cube-scramble.js +++ b/apps/cubescramble/cube-scramble.js @@ -83,6 +83,8 @@ const presentScramble = () => { }; const init = () => { + Bangle.setLCDTimeout(0); + Bangle.setLCDPower(1); presentScramble(); }; From 2b7091bd6b8c12e3c5bc75244e0eba38f9b223e9 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Thu, 25 Nov 2021 11:40:37 +0000 Subject: [PATCH 5/8] Set default title for showPrompt --- apps/cubescramble/cube-scramble.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/cubescramble/cube-scramble.js b/apps/cubescramble/cube-scramble.js index 6fe477031..73c4e95ef 100644 --- a/apps/cubescramble/cube-scramble.js +++ b/apps/cubescramble/cube-scramble.js @@ -58,19 +58,16 @@ const getRandomInt = max => Math.floor(Math.random() * Math.floor(max)); // retu const getRandomIntBetween = (min, max) => Math.floor(Math.random() * (max - min) + min); const presentScramble = () => { - E.showPrompt(makeScramble().join(" "), { - title: "cube scramble", + showPrompt(makeScramble().join(" "), { buttons: {"solve": true, "reset": false} }).then((v) => { if (v) { const start = new Date(); - E.showPrompt(" ", { - title: "cube scramble", + showPrompt(" ", { buttons: {"stop": true} }).then(() => { const time = parseFloat(((new Date()).getTime() - start.getTime()) / 1000); - E.showPrompt(String(time.toFixed(3)), { - title: "cube scramble", + showPrompt(String(time.toFixed(3)), { buttons: {"next": true} }).then(() => { presentScramble(); @@ -82,6 +79,11 @@ const presentScramble = () => { }); }; +const showPrompt = (text, options = {}) => { + options.title = options.title || "cube scramble"; + return E.showPrompt(text, options); +}; + const init = () => { Bangle.setLCDTimeout(0); Bangle.setLCDPower(1); From 6aa6bcf17977e127ef1879cfdb11ce3b972b1772 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 25 Nov 2021 15:12:04 +0000 Subject: [PATCH 6/8] messages 0.06: New messages now go at the start (fix #898) Answering true/false now exits the messages app if no new messages Back now marks a message as read Clicking top-left opens a menu which allows you to delete a message or mark unread --- apps.json | 2 +- apps/messages/ChangeLog | 4 +++ apps/messages/app.js | 71 ++++++++++++++++++++++++++++------------- apps/messages/lib.js | 5 ++- 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/apps.json b/apps.json index f83312034..33c838428 100644 --- a/apps.json +++ b/apps.json @@ -32,7 +32,7 @@ { "id": "messages", "name": "Messages", - "version": "0.05", + "version": "0.06", "description": "App to display notifications from iOS and Gadgetbridge", "icon": "app.png", "type": "app", diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 0c27d5a9b..8d31fcf2a 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -3,3 +3,7 @@ 0.03: Fixes for Bangle.js 1 0.04: Add require("messages").clearAll() 0.05: Handling of message actions (ok/clear) +0.06: New messages now go at the start (fix #898) + Answering true/false now exits the messages app if no new messages + Back now marks a message as read + Clicking top-left opens a menu which allows you to delete a message or mark unread diff --git a/apps/messages/app.js b/apps/messages/app.js index 39a55f135..b3bcbf6de 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -111,7 +111,7 @@ function showMapMessage(msg) { msg.new = false; saveMessages(); layout = undefined; - checkMessages(); + checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1}); }); } @@ -126,7 +126,7 @@ function showMusicMessage(msg) { msg.new = false; saveMessages(); layout = undefined; - checkMessages(); + checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1}); } layout = new Layout({ type:"v", c: [ {type:"h", fillx:1, bgCol:colBg, c: [ @@ -148,6 +148,22 @@ function showMusicMessage(msg) { layout.render(); } +function showMessageSettings(msg) { + E.showMenu({"":{"title":"Message"}, + "< Back" : () => showMessage(msg.id), + "Delete" : () => { + MESSAGES = MESSAGES.filter(m=>m.id!=msg.id); + saveMessages(); + checkMessages({clockIfNoMsg:0,clockIfAllRead:0,showMsgIfUnread:0}); + }, + "Mark Unread" : () => { + msg.new = true; + saveMessages(); + checkMessages({clockIfNoMsg:0,clockIfAllRead:0,showMsgIfUnread:0}); + }, + }); +} + function showMessage(msgid) { var msg = MESSAGES.find(m=>m.id==msgid); if (!msg) return checkMessages(); // go home if no message found @@ -163,30 +179,30 @@ function showMessage(msgid) { title = g.wrapString(title, w).join("\n"); } var buttons = [ - {type:"btn", src:getBackImage(), cb:()=>checkMessages(true)}, // back - msg.new?{type:"btn", src:atob("HRiBAD///8D///wj///Fj//8bj//x3z//Hvx/8/fx/j+/x+Ad/B4AL8Rh+HxwH+PHwf+cf5/+x/n/PH/P8cf+cx5/84HwAB4fgAD5/AAD/8AAD/wAAD/AAAD8A=="), cb:()=>{ + {type:"btn", src:getBackImage(), cb:()=>{ msg.new = false; // read mail saveMessages(); - checkMessages(); - }}:{} + checkMessages({clockIfNoMsg:1,clockIfAllRead:0,showMsgIfUnread:1}); + }} // back ]; if (msg.positive) { buttons.push({type:"btn", src:getPosImage(), cb:()=>{ msg.new = false; saveMessages(); Bangle.messageResponse(msg,true); - checkMessages(); + checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1}); }}); } if (msg.negative) { buttons.push({type:"btn", src:getNegImage(), cb:()=>{ + console.log("Response"); msg.new = false; saveMessages(); - Bangle.messageResponse(msg,true); - checkMessages(); + Bangle.messageResponse(msg,false); + checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1}); }}); } layout = new Layout({ type:"v", c: [ {type:"h", fillx:1, bgCol:colBg, c: [ - { type:"img", src:getMessageImage(msg), pad:2 }, + { type:"btn", src:getMessageImage(msg), cb:()=>showMessageSettings(msg) }, { type:"v", fillx:1, c: [ {type:"txt", font:fontMedium, label:msg.src||"Message", bgCol:colBg, fillx:1, pad:2 }, title?{type:"txt", font:titleFont, label:title, bgCol:colBg, fillx:1, pad:2 }:{}, @@ -199,28 +215,37 @@ function showMessage(msgid) { layout.render(); } -function checkMessages(forceShowMenu) { + +/* options = { + clockIfNoMsg : bool + clockIfAllRead : bool + showMsgIfUnread : bool +} +*/ +function checkMessages(options) { + options=options||{}; // If no messages, just show 'no messages' and return if (!MESSAGES.length) { - if (forceShowMenu) return E.showPrompt("No Messages",{ + if (!options.clockIfNoMsg) return E.showPrompt("No Messages",{ title:"Messages", img:require("heatshrink").decompress(atob("kkk4UBrkc/4AC/tEqtACQkBqtUDg0VqAIGgoZFDYQIIM1sD1QAD4AIBhnqA4WrmAIBhc6BAWs8AIBhXOBAWz0AIC2YIC5wID1gkB1c6BAYFBEQPqBAYXBEQOqBAnDAIQaEnkAngaEEAPDFgo+IKA5iIOhCGIAFb7RqAIGgtUBA0VqobFgNVA")), buttons : {"Ok":1} }).then(() => { load() }); - load(); - return; + return load(); } // we have >0 messages + var newMessages = MESSAGES.filter(m=>m.new); // If we have a new message, show it - if (!forceShowMenu) { - var newMessages = MESSAGES.filter(m=>m.new); - if (newMessages.length) - return showMessage(newMessages[0].id); - } + if (options.showMsgIfUnread && newMessages.length) + return showMessage(newMessages[0].id); + // no new messages - go to clock? + if (options.clockIfAllRead && newMessages.length==0) + return load(); + // Otherwise show a menu E.showScroller({ h : 48, - c : Math.min(MESSAGES.length+1,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) + c : Math.max(MESSAGES.length+1,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) draw : function(idx, r) {"ram" var msg = MESSAGES[idx-1]; if (msg && msg.new) g.setBgColor(colBg); @@ -239,7 +264,7 @@ function checkMessages(forceShowMenu) { x += 50; } var m = msg.title+"\n"+msg.body; - if (msg.src) g.setFontAlign(1,-1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+2); + if (msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); if (body) { g.setFontAlign(-1,-1).setFont("6x8"); @@ -261,4 +286,6 @@ function checkMessages(forceShowMenu) { g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); -checkMessages(true); // force showing a menu +setTimeout(() => { + checkMessages({clockIfNoMsg:0,clockIfAllRead:0,showMsgIfUnread:1}); +},10); // if checkMessages wants to 'load', do that diff --git a/apps/messages/lib.js b/apps/messages/lib.js index 4bda60e65..3094b34e1 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -17,7 +17,10 @@ exports.pushMessage = function(event) { mIdx=-1; } else { // add/modify if (event.t=="add") event.new=true; // new message - if (mIdx<0) mIdx=messages.push(event)-1; + if (mIdx<0) { + mIdx=0; + messages.unshift(event); // add new messages to the beginning + } else Object.assign(messages[mIdx], event); } require("Storage").writeJSON("messages.json",messages); From 5f5ca64cb4d305094907e368d8f0e344b694e304 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 25 Nov 2021 15:21:59 +0000 Subject: [PATCH 7/8] android 0.04: Android icon now goes to settings page with 'find phone' --- apps.json | 3 ++- apps/android/ChangeLog | 1 + apps/android/app.js | 3 +-- apps/android/settings.js | 18 ++++++++++++++++++ apps/gbridge/settings.js | 4 ++-- 5 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 apps/android/settings.js diff --git a/apps.json b/apps.json index 33c838428..be67cbd39 100644 --- a/apps.json +++ b/apps.json @@ -52,7 +52,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "0.03", + "version": "0.04", "description": "(BETA) App to display notifications from Gadgetbridge on Android. This will eventually replace the Gadgetbridge widget.", "icon": "app.png", "tags": "tool,system,messages,notifications", @@ -60,6 +60,7 @@ "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"android.app.js","url":"app.js"}, + {"name":"android.settings.js","url":"settings.js"}, {"name":"android.img","url":"app-icon.js","evaluate":true}, {"name":"android.boot.js","url":"boot.js"} ], diff --git a/apps/android/ChangeLog b/apps/android/ChangeLog index 2deea0c60..35fa0e386 100644 --- a/apps/android/ChangeLog +++ b/apps/android/ChangeLog @@ -2,3 +2,4 @@ 0.02: Remove messages on disconnect Fix music control 0.03: Handling of message actions (ok/clear) +0.04: Android icon now goes to settings page with 'find phone' diff --git a/apps/android/app.js b/apps/android/app.js index b210886fd..a88046c6d 100644 --- a/apps/android/app.js +++ b/apps/android/app.js @@ -1,2 +1 @@ -// Config app not implemented yet -setTimeout(()=>load("messages.app.js"),10); +eval(require("Storage").read("android.settings.js"))(()=>load()); diff --git a/apps/android/settings.js b/apps/android/settings.js new file mode 100644 index 000000000..d241397a4 --- /dev/null +++ b/apps/android/settings.js @@ -0,0 +1,18 @@ +(function(back) { + function gb(j) { + Bluetooth.println(JSON.stringify(j)); + } + var mainmenu = { + "" : { "title" : "Android" }, + "< Back" : back, + "Connected" : { value : NRF.getSecurityStatus().connected?"Yes":"No" }, + "Find Phone" : () => E.showMenu({ + "" : { "title" : "Find Phone" }, + "< Back" : ()=>E.showMenu(mainmenu), + "On" : _=>gb({t:"findPhone",n:true}), + "Off" : _=>gb({t:"findPhone",n:false}), + }), + "Messages" : ()=>load("messages.app.js") + }; + E.showMenu(mainmenu); +}) diff --git a/apps/gbridge/settings.js b/apps/gbridge/settings.js index afd0be4fb..f9c7cde90 100644 --- a/apps/gbridge/settings.js +++ b/apps/gbridge/settings.js @@ -23,6 +23,7 @@ } var mainmenu = { "" : { "title" : "Gadgetbridge" }, + "< Back" : back, "Connected" : { value : NRF.getSecurityStatus().connected?"Yes":"No" }, "Show Icon" : { value: settings().showIcon, @@ -34,8 +35,7 @@ value: !!settings().hrm, format: v => v?"Yes":"No", onchange: v => updateSetting('hrm', v) - }, - "< Back" : back, + } }; var findPhone = { From e8264cc8f8c7cde0e88cef06347c9ca67f8dae9e Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 25 Nov 2021 15:50:07 +0000 Subject: [PATCH 8/8] messages 0.07: Added settings menu with option to choose vibrate pattern and frequency (fix #909) --- apps.json | 5 +++-- apps/android/app.js | 2 ++ apps/messages/ChangeLog | 1 + apps/messages/app.js | 5 ++++- apps/messages/widget.js | 16 ++++++++++++++-- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index be67cbd39..4ef5b157e 100644 --- a/apps.json +++ b/apps.json @@ -32,7 +32,7 @@ { "id": "messages", "name": "Messages", - "version": "0.06", + "version": "0.07", "description": "App to display notifications from iOS and Gadgetbridge", "icon": "app.png", "type": "app", @@ -41,11 +41,12 @@ "readme": "README.md", "storage": [ {"name":"messages.app.js","url":"app.js"}, + {"name":"messages.settings.js","url":"settings.js"}, {"name":"messages.img","url":"app-icon.js","evaluate":true}, {"name":"messages.wid.js","url":"widget.js"}, {"name":"messages","url":"lib.js"} ], - "data": [{"name":"messages.json"}], + "data": [{"name":"messages.json"},{"name":"messages.settings.json"}], "sortorder": -9 }, { diff --git a/apps/android/app.js b/apps/android/app.js index a88046c6d..9464d1b8b 100644 --- a/apps/android/app.js +++ b/apps/android/app.js @@ -1 +1,3 @@ +Bangle.loadWidgets(); +Bangle.drawWidgets(); eval(require("Storage").read("android.settings.js"))(()=>load()); diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 8d31fcf2a..87094a091 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -7,3 +7,4 @@ Answering true/false now exits the messages app if no new messages Back now marks a message as read Clicking top-left opens a menu which allows you to delete a message or mark unread +0.07: Added settings menu with option to choose vibrate pattern and frequency (fix #909) diff --git a/apps/messages/app.js b/apps/messages/app.js index b3bcbf6de..cb2b5c2cd 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -46,7 +46,10 @@ var MESSAGES = require("Storage").readJSON("messages.json",1)||[]; if (!Array.isArray(MESSAGES)) MESSAGES=[]; var onMessagesModified = function(msg) { // TODO: if new, show this new one - if (msg.new) Bangle.buzz(); + if (msg.new) { + if (WIDGETS["messages"]) WIDGETS["messages"].buzz(); + else Bangle.buzz(); + } showMessage(msg.id); }; function saveMessages() { diff --git a/apps/messages/widget.js b/apps/messages/widget.js index c40e9aa05..3a22b40fd 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -1,3 +1,4 @@ + WIDGETS["messages"]={area:"tl",width:0,draw:function() { if (!this.width) return; var c = (Date.now()-this.t)/1000; @@ -5,9 +6,11 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() { g.clearRect(this.x,this.y,this.x+this.width,this.y+23); g.setFont("6x8:1x2").setFontAlign(0,0).drawString("MESSAGES", this.x+this.width/2, this.y+12); //if (c<60) Bangle.setLCDPower(1); // keep LCD on for 1 minute - if (c<120 && (Date.now()-this.l)>4000) { + let settings = require('Storage').readJSON("messages.settings.json", true) || {}; + if (settings.repeat===undefined) settings.repeat = 4; + if (c<120 && (Date.now()-this.l)>settings.repeat*1000) { this.l = Date.now(); - Bangle.buzz(); // buzz every 4 seconds + WIDGETS["messages"].buzz(); // buzz every 4 seconds } setTimeout(()=>WIDGETS["messages"].draw(), 1000); },show:function() { @@ -21,4 +24,13 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() { delete WIDGETS["messages"].l; WIDGETS["messages"].width=0; Bangle.drawWidgets(); +},buzz:function() { + let v = (require('Storage').readJSON("messages.settings.json", true) || {}).vibrate || "."; + function b() { + var c = v[0]; + v = v.substr(1); + if (c==".") Bangle.buzz().then(()=>setTimeout(b,100)); + if (c=="-") Bangle.buzz(500).then(()=>setTimeout(b,100)); + } + b(); }};