From 326afaf72eaef69906dc8aeda12e851ec078e42f Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Thu, 29 Dec 2022 21:59:23 +0000 Subject: [PATCH 1/6] New widget: bt2 --- apps/widbt2/metadata.json | 14 ++++++++ apps/widbt2/widget.js | 65 ++++++++++++++++++++++++++++++++++++++ apps/widbt2/widget.png | Bin 0 -> 1119 bytes 3 files changed, 79 insertions(+) create mode 100644 apps/widbt2/metadata.json create mode 100644 apps/widbt2/widget.js create mode 100644 apps/widbt2/widget.png diff --git a/apps/widbt2/metadata.json b/apps/widbt2/metadata.json new file mode 100644 index 000000000..af7728958 --- /dev/null +++ b/apps/widbt2/metadata.json @@ -0,0 +1,14 @@ +{ + "id": "widbt2", + "name": "Bluetooth Widget 2", + "version": "0.01", + "description": "If active, shows a white bluetooth icon, if connected, a blue one", + "icon": "widget.png", + "type": "widget", + "tags": "widget,bluetooth,clkinfo", + "provides_widgets" : ["bluetooth"], + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"widbt2.wid.js","url":"widget.js"} + ] +} diff --git a/apps/widbt2/widget.js b/apps/widbt2/widget.js new file mode 100644 index 000000000..8b1fc3ede --- /dev/null +++ b/apps/widbt2/widget.js @@ -0,0 +1,65 @@ +(function(){ + "ram"; + + // 0: asleep, 1: active, 2: connected + let state = NRF.getSecurityStatus().connected + ? 2 + : 0; // could be active, assuming not here + + const width = () => state > 0 ? 15 : 0; + + const update = (newState) => { + state = newState; + WIDGETS.bluetooth.width = width(); + setTimeout(Bangle.drawWidgets, 50); // no need for .bind() + }; + + // { {key: State]: { boolean: string } } + // ^ dark theme + const colours = { + 1: { // active: white + false: "#fff", + true: "#fff", + }, + 2: { // connected: blue + false: "#0ff", + true: "#00f", + }, + }; + + WIDGETS.bluetooth = { + area: "tl", + sortorder: -1, + draw: function() { + if (state == 0) + return; + + g.reset(); + + g.setColor(colours[state][g.theme.dark]); + + g.drawImage( + atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), + this.x + 2, + this.y + 2 + ); + }, + width: width(), + }; + + NRF.on("connect", update.bind(null, 2)); + NRF.on("disconnect", update.bind(null, 1)); + + let origWake = NRF.wake; + let origSleep = NRF.sleep; + + NRF.wake = function() { + update(1); + return origWake.apply(this, arguments); + }; + + NRF.sleep = function() { + update(0); + return origSleep.apply(this, arguments); + }; +})(); diff --git a/apps/widbt2/widget.png b/apps/widbt2/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..1a884a62c1029ae43243f8f58ef9dc3a3327e437 GIT binary patch literal 1119 zcmV-l1fctgP)cE5(396`@Dz$wLqIPzYppJ*B(brZX|I zHChYW;Hm1lL~9feUi^283bm!!Ka0DG`v(zZvk8h?W%2@c?XT zES*ZPJU3a{7h{cB0RRrPTh=dGr*a^!0&xQX?DMczGEQwQ4)Y`c0EQJR_Oa?r)W%5x z0HhI_x1HK2pc0j7k^sKW*iQXQ=2YX6D9n-q_%qO+(!1;R%(3!ggBm9SkZ!j|fYm^E zR%O?(qZ5_=gLo$b@WZ#`wXJ`4=)@t~Y>Yv)Y!7y;OB zeO8rs?l*_RK!7NCKLhRU0}||esEhzCyx)O;I=Y5XtC(@B$NTljy45^tT?SHJ10ruX zOS$(<@@!=?P@`0+S)vnkL!=bB)DOg{Q*}L+GO)XAK;&$g@DSo22n#XlR9!)?07D(! zDxz;SOSunBbNCAVm!5U2c~9jVx@WU3=u3)pJ!ur3cu;sm-)NQ!pM}i;0{{TnZpA^Z ztASvff%b#?JdoF$<=hv8)Q159pyx{LBoBD4SyIzhb(HlW;>}!J+1=AqCDO_A6&XN}=e)0!pcibn z_HtD9d_@BAknp}zDCb9=>MK#y^fmCZ_8GoYkv>KTT7e$nHy?0mXP*UpX*>1PgVgRc z3#Fdn#d~2}5mATky^{qxZ#%U!Ve5AonQN!;&C-!_@cJGbKmk6^xYakqWbkDSU>e?6 zF9=onXw<2mHO=A62q0{DUp*iYB(+@Ja7a-n2aQU$C-1do)^M)j_l7Z`m-DHf;N2WNgeIsEr6@kFmJ z8_YbwGn3bL?QPY+LOBr_TDRcEMmfJ|;s=HR0IQ!ry9xAti1(G5Y&@#1^&${_&Hfi+ z9c`2jUpMuHhg{we{KebpwXs3NLqaRiAr)b6sg!$n>kZxDN)lj0k<-mm?qZatNdeqJ z)Lky+8&Ml40dUjvB)_tlzY&Ld+&A&{bh~wEWib~^c!+ZagoS&X-t=l^d_A@r#J2*U lKABp3ezkHW*6{xc{R@3@kib`1LqGrk002ovPDHLkV1l684mkh- literal 0 HcmV?d00001 From 3808b0bc3cd11337406e955bd8e0746a17524024 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 25 Feb 2023 23:04:41 +0000 Subject: [PATCH 2/6] widbt2: convert to typescript --- apps/widbt2/widget.js | 111 ++++++++++++++++++------------------------ apps/widbt2/widget.ts | 73 +++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 64 deletions(-) create mode 100644 apps/widbt2/widget.ts diff --git a/apps/widbt2/widget.js b/apps/widbt2/widget.js index 8b1fc3ede..441a0a099 100644 --- a/apps/widbt2/widget.js +++ b/apps/widbt2/widget.js @@ -1,65 +1,48 @@ -(function(){ - "ram"; - - // 0: asleep, 1: active, 2: connected - let state = NRF.getSecurityStatus().connected - ? 2 - : 0; // could be active, assuming not here - - const width = () => state > 0 ? 15 : 0; - - const update = (newState) => { - state = newState; - WIDGETS.bluetooth.width = width(); - setTimeout(Bangle.drawWidgets, 50); // no need for .bind() - }; - - // { {key: State]: { boolean: string } } - // ^ dark theme - const colours = { - 1: { // active: white - false: "#fff", - true: "#fff", - }, - 2: { // connected: blue - false: "#0ff", - true: "#00f", - }, - }; - - WIDGETS.bluetooth = { - area: "tl", - sortorder: -1, - draw: function() { - if (state == 0) - return; - - g.reset(); - - g.setColor(colours[state][g.theme.dark]); - - g.drawImage( - atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), - this.x + 2, - this.y + 2 - ); - }, - width: width(), - }; - - NRF.on("connect", update.bind(null, 2)); - NRF.on("disconnect", update.bind(null, 1)); - - let origWake = NRF.wake; - let origSleep = NRF.sleep; - - NRF.wake = function() { - update(1); - return origWake.apply(this, arguments); - }; - - NRF.sleep = function() { - update(0); - return origSleep.apply(this, arguments); - }; +"use strict"; +(function () { + "ram"; + var _a; + var state = NRF.getSecurityStatus().connected + ? 2 + : 0; + var width = function () { return state > 0 ? 15 : 0; }; + var update = function (newState) { + state = newState; + WIDGETS["bluetooth"].width = width(); + setTimeout(Bangle.drawWidgets, 50); + }; + var colours = (_a = {}, + _a[1] = { + false: "#fff", + true: "#fff", + }, + _a[2] = { + false: "#0ff", + true: "#00f", + }, + _a); + WIDGETS["bluetooth"] = { + area: "tl", + sortorder: -1, + draw: function () { + if (state == 0) + return; + g.reset(); + g.setColor(colours[state]["".concat(g.theme.dark)]); + g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), this.x + 2, this.y + 2); + }, + width: width(), + }; + NRF.on("connect", update.bind(null, 2)); + NRF.on("disconnect", update.bind(null, 1)); + var origWake = NRF.wake; + var origSleep = NRF.sleep; + NRF.wake = function () { + update(1); + return origWake.apply(this, arguments); + }; + NRF.sleep = function () { + update(0); + return origSleep.apply(this, arguments); + }; })(); diff --git a/apps/widbt2/widget.ts b/apps/widbt2/widget.ts new file mode 100644 index 000000000..c63d187a5 --- /dev/null +++ b/apps/widbt2/widget.ts @@ -0,0 +1,73 @@ +(() => { + "ram"; + + const enum State { + Asleep, + Active, + Connected + } + + let state: State = NRF.getSecurityStatus().connected + ? State.Connected + : State.Asleep; // could be active, assuming not here + + const width = () => state > State.Asleep ? 15 : 0; + + const update = (newState: State) => { + state = newState; + WIDGETS["bluetooth"]!.width = width(); + setTimeout(Bangle.drawWidgets, 50); // no need for .bind() + }; + + type DarkTheme = `${boolean}`; + const colours: { + [key in State.Active | State.Connected]: { + [key in DarkTheme]: ColorResolvable + } + } = { + [State.Active]: { + false: "#fff", + true: "#fff", + }, + [State.Connected]: { + false: "#0ff", + true: "#00f", + }, + }; + + WIDGETS["bluetooth"] = { + area: "tl", + sortorder: -1, + draw: function() { + if (state == State.Asleep) + return; + + g.reset(); + + g.setColor(colours[state][`${g.theme.dark}`]); + + g.drawImage( + atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), + this.x + 2, + this.y + 2 + ); + }, + width: width(), + }; + + NRF.on("connect", update.bind(null, State.Connected)); + NRF.on("disconnect", update.bind(null, State.Active)); + + const origWake = NRF.wake; + const origSleep = NRF.sleep; + + NRF.wake = function() { + update(State.Active); + return origWake.apply(this, arguments); + }; + + NRF.sleep = function() { + update(State.Asleep); + return origSleep.apply(this, arguments); + }; +})(); From d9dc729abd4c1c25e7489f9de6abac498312abd2 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 6 Mar 2023 11:44:27 +0000 Subject: [PATCH 3/6] Regenerate types - NRF.getSecurityStatus() --- apps/widbt2/widget.ts | 4 ++-- typescript/types/main.d.ts | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apps/widbt2/widget.ts b/apps/widbt2/widget.ts index c63d187a5..d2585f1fb 100644 --- a/apps/widbt2/widget.ts +++ b/apps/widbt2/widget.ts @@ -48,8 +48,8 @@ g.drawImage( atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), - this.x + 2, - this.y + 2 + this.x! + 2, + this.y! + 2 ); }, width: width(), diff --git a/typescript/types/main.d.ts b/typescript/types/main.d.ts index 1223f527d..944d55326 100644 --- a/typescript/types/main.d.ts +++ b/typescript/types/main.d.ts @@ -183,6 +183,23 @@ type NRFFilters = { manufacturerData?: object; }; +type NRFSecurityStatus = { + advertising: boolean, +} & ( + { + connected: true, + encrypted: boolean, + mitm_protected: boolean, + bonded: boolean, + connected_addr?: string, + } | { + connected: false, + encrypted: false, + mitm_protected: false, + bonded: false, + } +); + type ImageObject = { width: number; height: number; @@ -721,7 +738,7 @@ declare class NRF { * @returns {any} An object * @url http://www.espruino.com/Reference#l_NRF_getSecurityStatus */ - static getSecurityStatus(): any; + static getSecurityStatus(): NRFSecurityStatus; /** * @returns {any} An object @@ -1898,6 +1915,7 @@ declare class NRF { * encrypted // Communication on this link is encrypted. * mitm_protected // The encrypted communication is also protected against man-in-the-middle attacks. * bonded // The peer is bonded with us + * advertising // Are we currently advertising? * connected_addr // If connected=true, the MAC address of the currently connected device * } * ``` @@ -1906,7 +1924,7 @@ declare class NRF { * @returns {any} An object * @url http://www.espruino.com/Reference#l_NRF_getSecurityStatus */ - static getSecurityStatus(): any; + static getSecurityStatus(): NRFSecurityStatus; /** * @@ -4553,7 +4571,7 @@ declare class BluetoothRemoteGATTServer { * @returns {any} An object * @url http://www.espruino.com/Reference#l_BluetoothRemoteGATTServer_getSecurityStatus */ - getSecurityStatus(): any; + getSecurityStatus(): NRFSecurityStatus; /** * See `NRF.connect` for usage examples. From 832ec7a7a5eccab3c0e027d42ae7ea7a630c1624 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 6 Mar 2023 12:04:58 +0000 Subject: [PATCH 4/6] Use NRF.getSecurityStatus().advertising for initial state --- apps/widbt2/widget.js | 11 ++++++++--- apps/widbt2/widget.ts | 10 +++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/widbt2/widget.js b/apps/widbt2/widget.js index 441a0a099..1d32e1bc4 100644 --- a/apps/widbt2/widget.js +++ b/apps/widbt2/widget.js @@ -2,9 +2,14 @@ (function () { "ram"; var _a; - var state = NRF.getSecurityStatus().connected - ? 2 - : 0; + var state = (function () { + var status = NRF.getSecurityStatus(); + if (status.connected) + return 2; + if (status.advertising) + return 1; + return 0; + })(); var width = function () { return state > 0 ? 15 : 0; }; var update = function (newState) { state = newState; diff --git a/apps/widbt2/widget.ts b/apps/widbt2/widget.ts index d2585f1fb..8f02c1b8c 100644 --- a/apps/widbt2/widget.ts +++ b/apps/widbt2/widget.ts @@ -7,9 +7,13 @@ Connected } - let state: State = NRF.getSecurityStatus().connected - ? State.Connected - : State.Asleep; // could be active, assuming not here + let state: State = (() => { + const status = NRF.getSecurityStatus(); + + if (status.connected) return State.Connected; + if (status.advertising) return State.Active; + return State.Asleep; + })(); const width = () => state > State.Asleep ? 15 : 0; From c0194f260f99142159d35962ae480427ff026e9e Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 6 Mar 2023 12:14:56 +0000 Subject: [PATCH 5/6] Rename -> widbtstates --- apps/{widbt2 => widbtstates}/metadata.json | 8 ++++---- apps/{widbt2 => widbtstates}/widget.js | 0 apps/{widbt2 => widbtstates}/widget.png | Bin apps/{widbt2 => widbtstates}/widget.ts | 0 4 files changed, 4 insertions(+), 4 deletions(-) rename apps/{widbt2 => widbtstates}/metadata.json (64%) rename apps/{widbt2 => widbtstates}/widget.js (100%) rename apps/{widbt2 => widbtstates}/widget.png (100%) rename apps/{widbt2 => widbtstates}/widget.ts (100%) diff --git a/apps/widbt2/metadata.json b/apps/widbtstates/metadata.json similarity index 64% rename from apps/widbt2/metadata.json rename to apps/widbtstates/metadata.json index af7728958..ada530e1b 100644 --- a/apps/widbt2/metadata.json +++ b/apps/widbtstates/metadata.json @@ -1,14 +1,14 @@ { - "id": "widbt2", - "name": "Bluetooth Widget 2", + "id": "widbtstates", + "name": "Bluetooth States", "version": "0.01", - "description": "If active, shows a white bluetooth icon, if connected, a blue one", + "description": "If active, shows a white bluetooth icon, if connected, a blue one (nothing if sleeping)", "icon": "widget.png", "type": "widget", "tags": "widget,bluetooth,clkinfo", "provides_widgets" : ["bluetooth"], "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ - {"name":"widbt2.wid.js","url":"widget.js"} + {"name":"widbtstates.wid.js","url":"widget.js"} ] } diff --git a/apps/widbt2/widget.js b/apps/widbtstates/widget.js similarity index 100% rename from apps/widbt2/widget.js rename to apps/widbtstates/widget.js diff --git a/apps/widbt2/widget.png b/apps/widbtstates/widget.png similarity index 100% rename from apps/widbt2/widget.png rename to apps/widbtstates/widget.png diff --git a/apps/widbt2/widget.ts b/apps/widbtstates/widget.ts similarity index 100% rename from apps/widbt2/widget.ts rename to apps/widbtstates/widget.ts From a135ba497f6d19f23a788f0a873446c42a5c0547 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 6 Mar 2023 12:15:04 +0000 Subject: [PATCH 6/6] ChangeLog --- apps/widbtstates/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/widbtstates/ChangeLog diff --git a/apps/widbtstates/ChangeLog b/apps/widbtstates/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/widbtstates/ChangeLog @@ -0,0 +1 @@ +0.01: New App!